[Process] Add output / error output incremental getters

This commit is contained in:
Romain Neutron 2012-09-19 02:35:24 +02:00
parent e7b55fcda5
commit b89e413a93
2 changed files with 79 additions and 0 deletions

View File

@ -51,6 +51,8 @@ class Process
private $pipes;
private $process;
private $status = self::STATUS_READY;
private $incrementalOutputOffset;
private $incrementalErrorOutputOffset;
private $fileHandles;
private $readBytes;
@ -205,6 +207,8 @@ class Process
$this->stdout = '';
$this->stderr = '';
$this->incrementalOutputOffset = 0;
$this->incrementalErrorOutputOffset = 0;
$callback = $this->buildCallback($callback);
//Fix for PHP bug #51800: reading from STDOUT pipe hangs forever on Windows if the output is too big.
@ -413,6 +417,24 @@ class Process
return $this->stdout;
}
/**
* Returns the output incrementally.
*
* In comparison with the getOutput method which always return the whole
* output, this one returns the new output since the last call.
*
* @return string The process output since the last call
*/
public function getIncrementalOutput()
{
$data = $this->getOutput();
$latest = substr($data, $this->incrementalOutputOffset);
$this->incrementalOutputOffset = strlen($data);
return $latest;
}
/**
* Returns the current error output of the process (STDERR).
*
@ -427,6 +449,25 @@ class Process
return $this->stderr;
}
/**
* Returns the errorOutput incrementally.
*
* In comparison with the getErrorOutput method which always return the
* whole error output, this one returns the new error output since the last
* call.
*
* @return string The process error output since the last call
*/
public function getIncrementalErrorOutput()
{
$data = $this->getErrorOutput();
$latest = substr($data, $this->incrementalErrorOutputOffset);
$this->incrementalErrorOutputOffset = strlen($data);
return $latest;
}
/**
* Returns the exit code returned by the process.
*

View File

@ -88,6 +88,44 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase
$this->assertTrue($called, 'The callback should be executed with the output');
}
public function testGetErrorOutput()
{
$p = new Process(sprintf('php -r %s', escapeshellarg('ini_set(\'display_errors\',\'on\');$n=0;while($n<3){echo $a;$n++;}')));
$p->run();
$this->assertEquals(3, preg_match_all('/PHP Notice/', $p->getErrorOutput(), $matches));
}
public function testGetIncrementalErrorOutput()
{
$p = new Process(sprintf('php -r %s', escapeshellarg('ini_set(\'display_errors\',\'on\');usleep(50000);$n=0;while($n<3){echo $a;$n++;}')));
$p->start();
while($p->isRunning()) {
$this->assertLessThanOrEqual(1, preg_match_all('/PHP Notice/', $p->getIncrementalOutput(), $matches));
usleep(20000);
}
}
public function testGetOutput()
{
$p = new Process(sprintf('php -r %s', escapeshellarg('$n=0;while($n<3){echo \' foo \';$n++;}')));
$p->run();
$this->assertEquals(3, preg_match_all('/foo/', $p->getOutput(), $matches));
}
public function testGetIncrementalOutput()
{
$p = new Process(sprintf('php -r %s', escapeshellarg('$n=0;while($n<3){echo \' foo \';usleep(50000);$n++;}')));
$p->start();
while($p->isRunning()) {
$this->assertLessThanOrEqual(1, preg_match_all('/foo/', $p->getIncrementalOutput(), $matches));
usleep(20000);
}
}
public function testExitCodeCommandFailed()
{
if (defined('PHP_WINDOWS_VERSION_BUILD')) {