From 152e5393e5aa5bc2bf150982514b1f991ad936d2 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 21 Feb 2019 09:35:30 +0100 Subject: [PATCH] Add special "all" conflict If a test conflicts with "all", then no other tests may be run in parallel. This is needed for windows_mb_path tests, which rely on the console codepage, which is shared across all parallel workers. Also add support for comments in the CONFLICTS section/file. --- .../tests/file/windows_mb_path/CONFLICTS | 4 ++- run-tests.php | 27 ++++++++++++++++--- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/ext/standard/tests/file/windows_mb_path/CONFLICTS b/ext/standard/tests/file/windows_mb_path/CONFLICTS index 1d0dfe69be..692a324587 100644 --- a/ext/standard/tests/file/windows_mb_path/CONFLICTS +++ b/ext/standard/tests/file/windows_mb_path/CONFLICTS @@ -1 +1,3 @@ -windows_mb_path +# These tests depend on the console codepage, which is shared across all parallel workers. +# Force these tests to run sequentially to make sure the codepage isn't change by another process. +all diff --git a/run-tests.php b/run-tests.php index 037b5d9fce..9b6e85ab40 100755 --- a/run-tests.php +++ b/run-tests.php @@ -1356,10 +1356,11 @@ function run_all_tests_parallel($test_files, $env, $redir_tested) { // specified either in the --CONFLICTS-- section, or CONFLICTS file inside a directory. $dirConflictsWith = []; $fileConflictsWith = []; - foreach ($test_files as $file) { + $sequentialTests = []; + foreach ($test_files as $i => $file) { $contents = file_get_contents($file); if (preg_match('/^--CONFLICTS--(.+?)^--/ms', $contents, $matches)) { - $conflicts = array_map('trim', explode("\n", trim($matches[1]))); + $conflicts = parse_conflicts($matches[1]); } else { // Cache per-directory conflicts in a separate map, so we compute these only once. $dir = dirname($file); @@ -1367,13 +1368,20 @@ function run_all_tests_parallel($test_files, $env, $redir_tested) { $dirConflicts = []; if (file_exists($dir . '/CONFLICTS')) { $contents = file_get_contents($dir . '/CONFLICTS'); - $dirConflicts = array_map('trim', explode("\n", trim($contents))); + $dirConflicts = parse_conflicts($contents); } $dirConflictsWith[$dir] = $dirConflicts; } $conflicts = $dirConflictsWith[$dir]; } + // For tests conflicting with "all", no other tests may run in parallel. We'll run these + // tests separately at the end, when only one worker is left. + if (in_array('all', $conflicts, true)) { + $sequentialTests[] = $file; + unset($test_files[$i]); + } + $fileConflictsWith[$file] = $conflicts; } @@ -1480,7 +1488,7 @@ function run_all_tests_parallel($test_files, $env, $redir_tested) { $waitingTests = []; escape: - while ($test_files || $testsInProgress > 0) { + while ($test_files || $sequentialTests || $testsInProgress > 0) { $toRead = array_values($workerSocks); $toWrite = NULL; $toExcept = NULL; @@ -1525,6 +1533,11 @@ escape: } // intentional fall-through case "ready": + // Schedule sequential tests only once we are down to one worker. + if (count($workerProcs) === 1 && $sequentialTests) { + $test_files = array_merge($test_files, $sequentialTests); + $sequentialTests = []; + } // Batch multiple tests to reduce communication overhead. $files = []; $batchSize = $shuffle ? 4 : 32; @@ -3190,6 +3203,12 @@ function clear_show_test() { } } +function parse_conflicts(string $text) : array { + // Strip comments + $text = preg_replace('/#.*/', '', $text); + return array_map('trim', explode("\n", trim($text))); +} + function show_result($result, $tested, $tested_file, $extra = '', $temp_filenames = null) { global $html_output, $html_file, $temp_target, $temp_urlbase, $line_length, $SHOW_ONLY_GROUPS; -- 2.50.0