From 80728abfe2becdbaba3bc89f4f54642f152428cf Mon Sep 17 00:00:00 2001 From: sun Date: Wed, 23 Jul 2014 04:03:19 +0200 Subject: [PATCH 1/4] Added regression test for #1340. Child process must produce > 4096 bytes on STDERR (e.g., a large PHP backtrace). --- tests/Regression/GitHub/1340.phpt | 43 ++++++++++++ .../Regression/GitHub/1340/Issue1340Test.php | 69 +++++++++++++++++++ 2 files changed, 112 insertions(+) create mode 100644 tests/Regression/GitHub/1340.phpt create mode 100644 tests/Regression/GitHub/1340/Issue1340Test.php diff --git a/tests/Regression/GitHub/1340.phpt b/tests/Regression/GitHub/1340.phpt new file mode 100644 index 00000000000..6d0897be0dd --- /dev/null +++ b/tests/Regression/GitHub/1340.phpt @@ -0,0 +1,43 @@ +--TEST-- +GH-1340: Process isolation blocks infinitely upon fatal error +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann. + +.E.EE + +Time: %s, Memory: %sMb + +There were 3 errors: + +1) Issue1340Test::testLargeStderrOutputDoesNotBlockInIsolation +PHPUnit_Framework_Exception: testLargeStderrOutputDoesNotBlockInIsolation: stderr:%d + +%a + +2) Issue1340Test::testPhpNoticeWithStderrOutputIsAnError +PHPUnit_Framework_Exception: shutdown: stderr:%d + +%a + +3) Issue1340Test::testFatalErrorDoesNotPass +PHPUnit_Framework_Exception: Fatal error: Call to undefined function undefined_function() in %s on line %d + +Call Stack: +%a + +shutdown: stderr:%d + +%a + +FAILURES! +Tests: 5, Assertions: 3, Errors: 3. \ No newline at end of file diff --git a/tests/Regression/GitHub/1340/Issue1340Test.php b/tests/Regression/GitHub/1340/Issue1340Test.php new file mode 100644 index 00000000000..580d98ab293 --- /dev/null +++ b/tests/Regression/GitHub/1340/Issue1340Test.php @@ -0,0 +1,69 @@ +assertTrue(true); + } + + /** + * @runInSeparateProcess + */ + public function testLargeStderrOutputDoesNotBlockInIsolation() + { + error_log("\n" . __FUNCTION__ . ": stderr:" . self::get4KB() . "\n"); + $this->assertTrue(true); + } + + /** + * @runInSeparateProcess + * @expectedException \PHPUnit_Framework_Error_Notice + * @expectedExceptionMessage Undefined variable: foo + */ + public function testPhpNoticeIsCaught() + { + $bar = $foo['foo']; + } + + /** + * @runInSeparateProcess + * @expectedException \PHPUnit_Framework_Error_Notice + * @expectedExceptionMessage Undefined variable: foo + */ + public function testPhpNoticeWithStderrOutputIsAnError() + { + register_shutdown_function(__CLASS__ . '::onShutdown'); + $bar = $foo['foo']; + } + + /** + * @runInSeparateProcess + */ + public function testFatalErrorDoesNotPass() + { + register_shutdown_function(__CLASS__ . '::onShutdown'); + $undefined = 'undefined_function'; + $undefined(); + } + + public static function onShutdown() { + echo "\nshutdown: stdout:", self::get4KB(), "\n"; + error_log("\nshutdown: stderr:" . self::get4KB()); + } +} From d59669e8a88aea316556cad55ccd95b4ddc119ea Mon Sep 17 00:00:00 2001 From: sun Date: Wed, 23 Jul 2014 17:57:55 +0200 Subject: [PATCH 2/4] Fixed #1340: Reading from STDOUT or STDERR hangs forever on Windows if the output is too large. See https://bugs.php.net/bug.php?id=51800 --- src/Util/PHP/Windows.php | 53 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/src/Util/PHP/Windows.php b/src/Util/PHP/Windows.php index 17d97687563..d9b6ffc7be3 100644 --- a/src/Util/PHP/Windows.php +++ b/src/Util/PHP/Windows.php @@ -43,6 +43,8 @@ * @since File available since Release 3.5.12 */ +use SebastianBergmann\Environment\Runtime; + /** * Windows utility for PHP sub-processes. * @@ -61,6 +63,57 @@ class PHPUnit_Util_PHP_Windows extends PHPUnit_Util_PHP_Default */ private $tempFile; + /** + * {@inheritdoc} + * + * Reading from STDOUT or STDERR hangs forever on Windows if the output is + * too large. + * + * @see https://bugs.php.net/bug.php?id=51800 + */ + public function runJob($job, array $settings = array()) + { + $runtime = new Runtime; + + if (false === $stdout_handle = tmpfile()) { + throw new PHPUnit_Framework_Exception( + 'A temporary file could not be created; verify that your TEMP environment variable is writable' + ); + } + + $process = proc_open( + $runtime->getBinary() . $this->settingsToParameters($settings), + array( + 0 => array('pipe', 'r'), + 1 => $stdout_handle, + 2 => array('pipe', 'w') + ), + $pipes + ); + + if (!is_resource($process)) { + throw new PHPUnit_Framework_Exception( + 'Unable to spawn worker process' + ); + } + + $this->process($pipes[0], $job); + fclose($pipes[0]); + + $stderr = stream_get_contents($pipes[2]); + fclose($pipes[2]); + + proc_close($process); + + rewind($stdout_handle); + $stdout = stream_get_contents($stdout_handle); + fclose($stdout_handle); + + $this->cleanup(); + + return array('stdout' => $stdout, 'stderr' => $stderr); + } + /** * @param resource $pipe * @param string $job From 9bed4ae8e82e28cb7f440623381b12dc67abf75f Mon Sep 17 00:00:00 2001 From: sun Date: Wed, 23 Jul 2014 19:51:18 +0200 Subject: [PATCH 3/4] Ignore irrelevant test result differences. --- tests/Regression/GitHub/1340.phpt | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/tests/Regression/GitHub/1340.phpt b/tests/Regression/GitHub/1340.phpt index 6d0897be0dd..728ece87950 100644 --- a/tests/Regression/GitHub/1340.phpt +++ b/tests/Regression/GitHub/1340.phpt @@ -21,14 +21,10 @@ There were 3 errors: 1) Issue1340Test::testLargeStderrOutputDoesNotBlockInIsolation PHPUnit_Framework_Exception: testLargeStderrOutputDoesNotBlockInIsolation: stderr:%d - -%a - +%A 2) Issue1340Test::testPhpNoticeWithStderrOutputIsAnError PHPUnit_Framework_Exception: shutdown: stderr:%d - -%a - +%A 3) Issue1340Test::testFatalErrorDoesNotPass PHPUnit_Framework_Exception: Fatal error: Call to undefined function undefined_function() in %s on line %d @@ -36,8 +32,6 @@ Call Stack: %a shutdown: stderr:%d - -%a - +%A FAILURES! Tests: 5, Assertions: 3, Errors: 3. \ No newline at end of file From 3945b0fd6d6518e4036a7a6502cbc8fad5e6ba7f Mon Sep 17 00:00:00 2001 From: sun Date: Wed, 23 Jul 2014 20:34:57 +0200 Subject: [PATCH 4/4] Ignore irrelevant test result differences on HHVM. --- tests/Regression/GitHub/1340.phpt | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/tests/Regression/GitHub/1340.phpt b/tests/Regression/GitHub/1340.phpt index 728ece87950..4e1cd1fe466 100644 --- a/tests/Regression/GitHub/1340.phpt +++ b/tests/Regression/GitHub/1340.phpt @@ -12,7 +12,7 @@ PHPUnit_TextUI_Command::main(); ?> --EXPECTF-- PHPUnit %s by Sebastian Bergmann. - +%A .E.EE Time: %s, Memory: %sMb @@ -27,10 +27,7 @@ PHPUnit_Framework_Exception: shutdown: stderr:%d %A 3) Issue1340Test::testFatalErrorDoesNotPass PHPUnit_Framework_Exception: Fatal error: Call to undefined function undefined_function() in %s on line %d - -Call Stack: -%a - +%A shutdown: stderr:%d %A FAILURES!