From 7c58ed569bdeb9a09def8f27447df7ffce4e4855 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Sat, 19 Oct 2024 14:23:52 +0200 Subject: [PATCH 1/2] Added regression test --- tests/end-to-end/regression/5993.phpt | 14 +++++++++ .../regression/5993/Issue5993Test.php | 29 +++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 tests/end-to-end/regression/5993.phpt create mode 100644 tests/end-to-end/regression/5993/Issue5993Test.php 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..2eb2e2d2c1c --- /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); + } +} From af9d538a0e06c2ada49ee5ec384ffc4d201d3e9e Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Sat, 19 Oct 2024 14:48:02 +0200 Subject: [PATCH 2/2] PHPUnit process is blocked when there's a lot of output and a test with separate process --- src/Util/PHP/DefaultPhpProcess.php | 67 ++++++++++++++++--- .../regression/5993/Issue5993Test.php | 2 +- 2 files changed, 60 insertions(+), 9 deletions(-) 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/Issue5993Test.php b/tests/end-to-end/regression/5993/Issue5993Test.php index 2eb2e2d2c1c..5d72aff144a 100644 --- a/tests/end-to-end/regression/5993/Issue5993Test.php +++ b/tests/end-to-end/regression/5993/Issue5993Test.php @@ -10,7 +10,7 @@ --SKIPIF-- --FILE--