bug #18023 [Process] getIncrementalOutput should work without calling getOutput (romainneutron)

This PR was merged into the 2.7 branch.

Discussion
----------

[Process] getIncrementalOutput should work without calling getOutput

| Q             | A
| ------------- | ---
| Branch        | 2.7
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #17937
| License       | MIT

Commits
-------

37d8695 [Process] getIncrementalOutput should work without calling getOutput
This commit is contained in:
Nicolas Grekas 2016-03-17 09:31:46 +01:00
commit 8cd9138938
2 changed files with 47 additions and 24 deletions

View File

@ -462,13 +462,7 @@ class Process
*/
public function getOutput()
{
if ($this->outputDisabled) {
throw new LogicException('Output has been disabled.');
}
$this->requireProcessIsStarted(__FUNCTION__);
$this->readPipes(false, '\\' === DIRECTORY_SEPARATOR ? !$this->processInformation['running'] : true);
$this->readPipesForOutput(__FUNCTION__);
if (false === $ret = stream_get_contents($this->stdout, -1, 0)) {
return '';
@ -490,11 +484,7 @@ class Process
*/
public function getIncrementalOutput()
{
if ($this->outputDisabled) {
throw new LogicException('Output has been disabled.');
}
$this->requireProcessIsStarted(__FUNCTION__);
$this->readPipesForOutput(__FUNCTION__);
$latest = stream_get_contents($this->stdout, -1, $this->incrementalOutputOffset);
$this->incrementalOutputOffset = ftell($this->stdout);
@ -530,13 +520,7 @@ class Process
*/
public function getErrorOutput()
{
if ($this->outputDisabled) {
throw new LogicException('Output has been disabled.');
}
$this->requireProcessIsStarted(__FUNCTION__);
$this->readPipes(false, '\\' === DIRECTORY_SEPARATOR ? !$this->processInformation['running'] : true);
$this->readPipesForOutput(__FUNCTION__);
if (false === $ret = stream_get_contents($this->stderr, -1, 0)) {
return '';
@ -559,11 +543,7 @@ class Process
*/
public function getIncrementalErrorOutput()
{
if ($this->outputDisabled) {
throw new LogicException('Output has been disabled.');
}
$this->requireProcessIsStarted(__FUNCTION__);
$this->readPipesForOutput(__FUNCTION__);
$latest = stream_get_contents($this->stderr, -1, $this->incrementalErrorOutputOffset);
$this->incrementalErrorOutputOffset = ftell($this->stderr);
@ -1328,6 +1308,24 @@ class Process
return self::$sigchild = false !== strpos(ob_get_clean(), '--enable-sigchild');
}
/**
* Reads pipes for the freshest output.
*
* @param $caller The name of the method that needs fresh outputs
*
* @throw LogicException in case output has been disabled or process is not started
*/
private function readPipesForOutput($caller)
{
if ($this->outputDisabled) {
throw new LogicException('Output has been disabled.');
}
$this->requireProcessIsStarted($caller);
$this->updateStatus(false);
}
/**
* Validates and returns the filtered timeout.
*

View File

@ -1159,6 +1159,31 @@ class ProcessTest extends \PHPUnit_Framework_TestCase
return $codes;
}
/**
* @dataProvider provideVariousIncrementals
*/
public function testIncrementalOutputDoesNotRequireAnotherCall($stream, $method) {
$process = new Process(self::$phpBin.' -r '.escapeshellarg('$n = 0; while ($n < 3) { file_put_contents(\''.$stream.'\', $n, 1); $n++; usleep(1000); }'), null, null, null, null);
$process->start();
$result = '';
$limit = microtime(true) + 3;
$expected = '012';
while ($result !== $expected && microtime(true) < $limit) {
$result .= $process->$method();
}
$this->assertSame($expected, $result);
$process->stop();
}
public function provideVariousIncrementals() {
return array(
array('php://stdout', 'getIncrementalOutput'),
array('php://stderr', 'getIncrementalErrorOutput'),
);
}
/**
* provides default method names for simple getter/setter.
*/