[php-src] master: Fix redirected-test progress accounting in parallel runs (#22952)
NickSdot via GitHub <[email protected]> Mon, 3 Aug 2026 16:22:09 +0000
| Newsgroups | gmane.comp.php.cvs.general |
|---|---|
| Message-ID | <[email protected]> |
Author: NickSdot (NickSdot)
Committer: GitHub (web-flow)
Pusher: arnaud-lb
Date: 2026-08-03T18:22:06+02:00
Commit: https://github.com/php/php-src/commit/7785159f7ee21f64bcd3b68ffaac58f8fdbe244e
Raw diff: https://github.com/php/php-src/commit/7785159f7ee21f64bcd3b68ffaac58f8fdbe244e.diff
Fix redirected-test progress accounting in parallel runs (#22952)
Changed paths:
A tests/run-test/redirected_parallel.phpt
M run-tests.php
Diff:
diff --git a/run-tests.php b/run-tests.php
index 703dd643ca7c..89bd8ffb797c 100755
--- a/run-tests.php
+++ b/run-tests.php
@@ -1351,7 +1351,8 @@ function run_all_tests(array $test_files, array $env, ?string $redir_tested = nu
}
/* Ignore -jN if there is only one file to analyze. */
- if ($workers !== null && count($test_files) > 1 && !$workerID) {
+ if ($workers !== null && count($test_files) > 1 && !$workerID
+ && $redir_tested === null) {
run_all_tests_parallel($test_files, $env, $redir_tested);
return;
}
@@ -1406,7 +1407,7 @@ function run_all_tests(array $test_files, array $env, ?string $redir_tested = nu
function run_all_tests_parallel(array $test_files, array $env, ?string $redir_tested): void
{
- global $workers, $test_idx, $test_results, $failed_tests_file, $result_tests_file, $PHP_FAILED_TESTS, $shuffle, $valgrind, $show_progress;
+ global $workers, $test_cnt, $test_idx, $test_results, $failed_tests_file, $result_tests_file, $PHP_FAILED_TESTS, $shuffle, $valgrind, $show_progress;
global $junit;
@@ -1588,6 +1589,9 @@ function run_all_tests_parallel(array $test_files, array $env, ?string $redir_te
}
switch ($message["type"]) {
+ case "test_count_delta":
+ $test_cnt += $message["delta"];
+ break;
case "tests_finished":
$testsInProgress--;
foreach ($activeConflicts as $key => $workerId) {
@@ -1890,7 +1894,7 @@ function run_test(string $php, $file, array $env): string
global $preload, $file_cache;
global $num_repeats;
// Parallel testing
- global $workerID;
+ global $workerID, $workerSock;
global $show_progress;
// Temporary
@@ -2326,7 +2330,14 @@ function run_test(string $php, $file, array $env): string
$test_files[] = [$f, $file];
}
}
- $test_cnt += count($test_files) - 1;
+ $test_count_delta = count($test_files) - 1;
+ $test_cnt += $test_count_delta;
+ if ($workerID && $test_count_delta !== 0) {
+ send_message($workerSock, [
+ "type" => "test_count_delta",
+ "delta" => $test_count_delta,
+ ]);
+ }
$test_idx--;
show_redirect_start($IN_REDIRECT['TESTS'], $tested, $tested_file);
diff --git a/tests/run-test/redirected_parallel.phpt b/tests/run-test/redirected_parallel.phpt
new file mode 100644
index 000000000000..47830f341253
--- /dev/null
+++ b/tests/run-test/redirected_parallel.phpt
@@ -0,0 +1,111 @@
+--TEST--
+Redirected tests work in parallel runs and update the progress total
+--ENV--
+TEST_PHP_FORK_SERVER=0
+--FILE--
+<?php
+function writeRedirectedTest(string $file, string $name): void
+{
+ file_put_contents($file, <<<PHPT
+ --TEST--
+ $name
+ --FILE--
+ <?php echo "ok\\n"; ?>
+ --EXPECT--
+ ok
+ PHPT);
+}
+
+function runRedirectedTests(array $testFiles): array
+{
+ $command = [
+ getenv('TEST_PHP_EXECUTABLE'),
+ '-n',
+ dirname(__DIR__, 2) . '/run-tests.php',
+ '-n',
+ '-q',
+ '-j2',
+ '--progress',
+ ...$testFiles,
+ ];
+ $environment = [
+ 'PATH' => getenv('PATH'),
+ 'TEST_PHP_EXECUTABLE' => getenv('TEST_PHP_EXECUTABLE'),
+ 'TEST_PHP_FORK_SERVER' => '0',
+ ];
+ foreach (['SystemRoot', 'TEMP', 'TMPDIR'] as $name) {
+ if (($value = getenv($name)) !== false) {
+ $environment[$name] = $value;
+ }
+ }
+
+ $process = proc_open(
+ $command,
+ [
+ 0 => ['pipe', 'r'],
+ 1 => ['pipe', 'w'],
+ 2 => ['redirect', 1],
+ ],
+ $pipes,
+ null,
+ $environment,
+ );
+ fclose($pipes[0]);
+ $output = stream_get_contents($pipes[1]);
+ fclose($pipes[1]);
+ return [proc_close($process), str_replace("\r", "\n", $output)];
+}
+
+$root = __DIR__ . '/redirected_parallel_' . getmypid();
+$targets = $root . '/targets';
+mkdir($targets, recursive: true);
+
+writeRedirectedTest($targets . '/one.phpt', 'redirected one');
+writeRedirectedTest($targets . '/two.phpt', 'redirected two');
+
+$targetExpression = var_export($targets, true);
+$redirect = $root . '/redirect.phpt';
+file_put_contents($redirect, <<<PHPT
+ --TEST--
+ redirect wrapper
+ --REDIRECTTEST--
+ return ['ENV' => [], 'TESTS' => $targetExpression];
+ PHPT);
+writeRedirectedTest($root . '/companion.phpt', 'companion');
+
+[$singleExitCode, $singleOutput] = runRedirectedTests([$redirect]);
+if ($singleExitCode !== 0) {
+ echo $singleOutput;
+}
+var_dump($singleExitCode);
+var_dump(str_contains($singleOutput, 'Fatal error'));
+
+[$parallelExitCode, $parallelOutput] = runRedirectedTests([
+ $redirect,
+ $root . '/companion.phpt',
+]);
+if ($parallelExitCode !== 0) {
+ echo $parallelOutput;
+}
+var_dump($parallelExitCode);
+var_dump(str_contains($parallelOutput, 'TEST 3/3'));
+var_dump(str_contains($parallelOutput, 'TEST 3/2'));
+?>
+--CLEAN--
+<?php
+foreach (glob(__DIR__ . '/redirected_parallel_*') ?: [] as $root) {
+ foreach (glob($root . '/targets/*') ?: [] as $file) {
+ unlink($file);
+ }
+ @rmdir($root . '/targets');
+ @unlink($root . '/redirect.phpt');
+ @unlink($root . '/companion.phpt');
+ @rmdir($root);
+}
+?>
+--EXPECT--
+int(0)
+bool(false)
+int(0)
+bool(true)
+bool(false)