From b89e413a93682a6ce8f6cb3e5d533c7e945172a0 Mon Sep 17 00:00:00 2001 From: Romain Neutron Date: Wed, 19 Sep 2012 02:35:24 +0200 Subject: [PATCH] [Process] Add output / error output incremental getters --- src/Symfony/Component/Process/Process.php | 41 +++++++++++++++++++ .../Process/Tests/AbstractProcessTest.php | 38 +++++++++++++++++ 2 files changed, 79 insertions(+) diff --git a/src/Symfony/Component/Process/Process.php b/src/Symfony/Component/Process/Process.php index 699e2647c8..83155d80b1 100644 --- a/src/Symfony/Component/Process/Process.php +++ b/src/Symfony/Component/Process/Process.php @@ -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. * diff --git a/src/Symfony/Component/Process/Tests/AbstractProcessTest.php b/src/Symfony/Component/Process/Tests/AbstractProcessTest.php index 1b443502bd..a9b5009dd6 100644 --- a/src/Symfony/Component/Process/Tests/AbstractProcessTest.php +++ b/src/Symfony/Component/Process/Tests/AbstractProcessTest.php @@ -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')) {