diff --git a/src/Util/PHP/DefaultPhpProcess.php b/src/Util/PHP/DefaultPhpProcess.php index e933c24e409..9e0aab31319 100644 --- a/src/Util/PHP/DefaultPhpProcess.php +++ b/src/Util/PHP/DefaultPhpProcess.php @@ -12,12 +12,15 @@ use function array_merge; use function fclose; use function file_put_contents; +use function fread; use function fwrite; use function is_array; use function is_resource; use function proc_close; use function proc_open; -use function stream_get_contents; +use function proc_terminate; +use function sprintf; +use function stream_select; use function sys_get_temp_dir; use function tempnam; use function unlink; @@ -112,16 +115,64 @@ protected function runProcess(string $job, array $settings): array $stderr = $stdout = ''; - if (isset($pipes[1])) { - $stdout = stream_get_contents($pipes[1]); + unset($pipes[0]); + $timeout = 5; - fclose($pipes[1]); - } + while (true) { + $r = $pipes; + $w = null; + $e = null; + + $n = @stream_select($r, $w, $e, $timeout); + + if ($n === false) { + break; + } + + if ($n === 0) { + proc_terminate($process, 9); + + throw new PhpProcessException( + sprintf( + 'Job execution aborted after %d seconds', + $timeout, + ), + ); + } - if (isset($pipes[2])) { - $stderr = stream_get_contents($pipes[2]); + if ($n > 0) { + foreach ($r as $pipe) { + $pipeOffset = 0; - fclose($pipes[2]); + foreach ($pipes as $i => $origPipe) { + if ($pipe === $origPipe) { + $pipeOffset = $i; + + break; + } + } + + if (!$pipeOffset) { + break; + } + + $line = fread($pipe, 8192); + + if ($line === '' || $line === false) { + fclose($pipes[$pipeOffset]); + + unset($pipes[$pipeOffset]); + } elseif ($pipeOffset === 1) { + $stdout .= $line; + } else { + $stderr .= $line; + } + } + + if (empty($pipes)) { + break; + } + } } proc_close($process); diff --git a/tests/end-to-end/regression/5993.phpt b/tests/end-to-end/regression/5993.phpt new file mode 100644 index 00000000000..1b939fd04c0 --- /dev/null +++ b/tests/end-to-end/regression/5993.phpt @@ -0,0 +1,14 @@ +--TEST-- +https://github.com/sebastianbergmann/phpunit/issues/5993 +--FILE-- +run($_SERVER['argv']); +--EXPECTF-- +%A diff --git a/tests/end-to-end/regression/5993/Issue5993Test.php b/tests/end-to-end/regression/5993/Issue5993Test.php new file mode 100644 index 00000000000..5d72aff144a --- /dev/null +++ b/tests/end-to-end/regression/5993/Issue5993Test.php @@ -0,0 +1,29 @@ +--TEST-- +PHPUnit process is blocked when there's a lot of output and a test with separate process +--INI-- +error_reporting=-1 +display_errors=1 +display_startup_errors=1 +memory_limit=-1 +zend.assertions=1 +assert.exception=1 +--SKIPIF-- + +--FILE-- +assertTrue(true); + } +}