Skip to content

Commit aca16a7

Browse files
committed
run-tests: refactor worker globals into global WorkerContext value-object
1 parent cda67fb commit aca16a7

File tree

1 file changed

+66
-39
lines changed

1 file changed

+66
-39
lines changed

run-tests.php

Lines changed: 66 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -156,8 +156,10 @@ function main(): void
156156
$test_files, $test_idx, $test_results, $testfile,
157157
$valgrind, $sum_results, $shuffle, $file_cache, $num_repeats,
158158
$show_progress;
159-
// Parallel testing
160-
global $workers, $workerID;
159+
160+
global $workerContext;
161+
$workerContext = new WorkerContext();
162+
161163
global $context_line_count;
162164

163165
// Temporary for the duration of refactoring
@@ -166,9 +168,9 @@ function main(): void
166168

167169
define('IS_WINDOWS', substr(PHP_OS, 0, 3) == "WIN");
168170

169-
$workerID = 0;
171+
$workerContext->workerID = 0;
170172
if (getenv("TEST_PHP_WORKER")) {
171-
$workerID = intval(getenv("TEST_PHP_WORKER"));
173+
$workerContext->workerID = intval(getenv("TEST_PHP_WORKER"));
172174
run_worker();
173175
return;
174176
}
@@ -251,7 +253,7 @@ function main(): void
251253
$DETAILED = 0;
252254
}
253255

254-
$junit = new JUnit($environment, $workerID);
256+
$junit = new JUnit($environment, $workerContext->workerID);
255257

256258
if (getenv('SHOW_ONLY_GROUPS')) {
257259
$SHOW_ONLY_GROUPS = explode(",", getenv('SHOW_ONLY_GROUPS'));
@@ -350,7 +352,7 @@ function main(): void
350352
$file_cache = null;
351353
$shuffle = false;
352354
$bless = false;
353-
$workers = null;
355+
$workerContext->workers = null;
354356
$context_line_count = 3;
355357
$num_repeats = 1;
356358
$show_progress = true;
@@ -421,6 +423,7 @@ function main(): void
421423
if ($workers === 1) {
422424
$workers = null;
423425
}
426+
$workerContext->workers = $workers;
424427
break;
425428
case 'r':
426429
case 'l':
@@ -1229,13 +1232,14 @@ function system_with_timeout(
12291232
proc_close($proc);
12301233
return $data;
12311234
}
1232-
12331235
function run_all_tests(array $test_files, array $env, ?string $redir_tested = null): void
12341236
{
12351237
global $test_results, $failed_tests_file, $result_tests_file, $php, $test_idx, $file_cache;
12361238
global $preload;
1237-
// Parallel testing
1238-
global $PHP_FAILED_TESTS, $workers, $workerID, $workerSock;
1239+
global $PHP_FAILED_TESTS;
1240+
1241+
/** @var WorkerContext $workerContext */
1242+
global $workerContext;
12391243

12401244
if ($file_cache !== null || $preload) {
12411245
/* Automatically skip opcache tests in --file-cache and --preload mode,
@@ -1255,7 +1259,7 @@ function run_all_tests(array $test_files, array $env, ?string $redir_tested = nu
12551259
}
12561260

12571261
/* Ignore -jN if there is only one file to analyze. */
1258-
if ($workers !== null && count($test_files) > 1 && !$workerID) {
1262+
if ($workerContext->workers !== null && count($test_files) > 1 && !$workerContext->workerID) {
12591263
run_all_tests_parallel($test_files, $env, $redir_tested);
12601264
return;
12611265
}
@@ -1274,19 +1278,19 @@ function run_all_tests(array $test_files, array $env, ?string $redir_tested = nu
12741278
}
12751279
$test_idx++;
12761280

1277-
if ($workerID) {
1281+
if ($workerContext->workerID) {
12781282
$PHP_FAILED_TESTS = ['BORKED' => [], 'FAILED' => [], 'WARNED' => [], 'LEAKED' => [], 'XFAILED' => [], 'XLEAKED' => [], 'SLOW' => []];
12791283
ob_start();
12801284
}
12811285

12821286
$result = run_test($php, $name, $env);
1283-
if ($workerID) {
1287+
if ($workerContext->workerID) {
12841288
$resultText = ob_get_clean();
12851289
}
12861290

12871291
if (!is_array($name) && $result != 'REDIR') {
1288-
if ($workerID) {
1289-
send_message($workerSock, [
1292+
if ($workerContext->workerID) {
1293+
send_message($workerContext->workerSock, [
12901294
"type" => "test_result",
12911295
"name" => $name,
12921296
"index" => $index,
@@ -1310,10 +1314,13 @@ function run_all_tests(array $test_files, array $env, ?string $redir_tested = nu
13101314

13111315
function run_all_tests_parallel(array $test_files, array $env, ?string $redir_tested): void
13121316
{
1313-
global $workers, $test_idx, $test_results, $failed_tests_file, $result_tests_file, $PHP_FAILED_TESTS, $shuffle, $valgrind, $show_progress;
1317+
global $test_idx, $test_results, $failed_tests_file, $result_tests_file, $PHP_FAILED_TESTS, $shuffle, $valgrind, $show_progress;
13141318

13151319
global $junit;
13161320

1321+
/** @var WorkerContext $workerContext */
1322+
global $workerContext;
1323+
13171324
// The PHP binary running run-tests.php, and run-tests.php itself
13181325
// This PHP executable is *not* necessarily the same as the tested version
13191326
$thisPHP = PHP_BINARY;
@@ -1367,9 +1374,9 @@ function run_all_tests_parallel(array $test_files, array $env, ?string $redir_te
13671374
}
13681375

13691376
// Don't start more workers than test files.
1370-
$workers = max(1, min($workers, count($test_files)));
1377+
$workerContext->workers = max(1, min($workerContext->workers, count($test_files)));
13711378

1372-
echo "Spawning $workers workers... ";
1379+
echo "Spawning ". $workerContext->workers ." workers... ";
13731380

13741381
// We use sockets rather than STDIN/STDOUT for comms because on Windows,
13751382
// those can't be non-blocking for some reason.
@@ -1386,7 +1393,7 @@ function run_all_tests_parallel(array $test_files, array $env, ?string $redir_te
13861393
$totalFileCount = count($test_files);
13871394

13881395
$startTime = microtime(true);
1389-
for ($i = 1; $i <= $workers; $i++) {
1396+
for ($i = 1; $i <= $workerContext->workers; $i++) {
13901397
$proc = proc_open(
13911398
[$thisPHP, $thisScript],
13921399
[], // Inherit our stdin, stdout and stderr
@@ -1408,7 +1415,7 @@ function run_all_tests_parallel(array $test_files, array $env, ?string $redir_te
14081415
$workerProcs[$i] = $proc;
14091416
}
14101417

1411-
for ($i = 1; $i <= $workers; $i++) {
1418+
for ($i = 1; $i <= $workerContext->workers; $i++) {
14121419
$workerSock = stream_socket_accept($listenSock, 5);
14131420
if ($workerSock === false) {
14141421
kill_children($workerProcs);
@@ -1567,7 +1574,7 @@ function run_all_tests_parallel(array $test_files, array $env, ?string $redir_te
15671574
echo $resultText;
15681575

15691576
if ($show_progress) {
1570-
show_test($test_idx, count($workerProcs) . "/$workers concurrent test workers running");
1577+
show_test($test_idx, count($workerProcs) . "/".$workerContext->workers ." concurrent test workers running");
15711578
}
15721579

15731580
if (!is_array($name) && $result != 'REDIR') {
@@ -1662,6 +1669,9 @@ function safe_fwrite($stream, string $data)
16621669
return $bytes_written;
16631670
}
16641671

1672+
/**
1673+
* @param resource $stream
1674+
*/
16651675
function send_message($stream, array $message): void
16661676
{
16671677
$blocking = stream_get_meta_data($stream)["blocked"];
@@ -1681,23 +1691,24 @@ function kill_children(array $children): void
16811691

16821692
function run_worker(): void
16831693
{
1684-
global $workerID, $workerSock;
1694+
/** @var WorkerContext $workerContext */
1695+
global $workerContext;
16851696

16861697
global $junit;
16871698

16881699
$sockUri = getenv("TEST_PHP_URI");
16891700

1690-
$workerSock = stream_socket_client($sockUri, $_, $_, 5) or error("Couldn't connect to $sockUri");
1701+
$workerContext->workerSock = stream_socket_client($sockUri, $_, $_, 5) or error("Couldn't connect to $sockUri");
16911702

1692-
$greeting = fgets($workerSock);
1703+
$greeting = fgets($workerContext->workerSock);
16931704
$greeting = unserialize(base64_decode($greeting)) or die("Could not decode greeting\n");
16941705
if ($greeting["type"] !== "hello") {
16951706
error("Unexpected greeting of type $greeting[type]");
16961707
}
16971708

1698-
set_error_handler(function (int $errno, string $errstr, string $errfile, int $errline) use ($workerSock): bool {
1709+
set_error_handler(function (int $errno, string $errstr, string $errfile, int $errline) use ($workerContext): bool {
16991710
if (error_reporting() & $errno) {
1700-
send_message($workerSock, compact('errno', 'errstr', 'errfile', 'errline') + [
1711+
send_message($workerContext->workerSock, compact('errno', 'errstr', 'errfile', 'errline') + [
17011712
'type' => 'php_error'
17021713
]);
17031714
}
@@ -1706,37 +1717,37 @@ function run_worker(): void
17061717
});
17071718

17081719
foreach ($greeting["GLOBALS"] as $var => $value) {
1709-
if ($var !== "workerID" && $var !== "workerSock" && $var !== "GLOBALS") {
1720+
if ($var !== "workerContext" && $var !== "GLOBALS") {
17101721
$GLOBALS[$var] = $value;
17111722
}
17121723
}
17131724
foreach ($greeting["constants"] as $const => $value) {
17141725
define($const, $value);
17151726
}
17161727

1717-
send_message($workerSock, [
1728+
send_message($workerContext->workerSock, [
17181729
"type" => "hello_reply",
1719-
"workerID" => $workerID
1730+
"workerID" => $workerContext->workerID
17201731
]);
17211732

1722-
send_message($workerSock, [
1733+
send_message($workerContext->workerSock, [
17231734
"type" => "ready"
17241735
]);
17251736

1726-
while (($command = fgets($workerSock))) {
1737+
while (($command = fgets($workerContext->workerSock))) {
17271738
$command = unserialize(base64_decode($command));
17281739

17291740
switch ($command["type"]) {
17301741
case "run_tests":
17311742
run_all_tests($command["test_files"], $command["env"], $command["redir_tested"]);
1732-
send_message($workerSock, [
1743+
send_message($workerContext->workerSock, [
17331744
"type" => "tests_finished",
17341745
"junit" => $junit->isEnabled() ? $junit : null,
17351746
]);
17361747
$junit->clear();
17371748
break;
17381749
default:
1739-
send_message($workerSock, [
1750+
send_message($workerContext->workerSock, [
17401751
"type" => "error",
17411752
"msg" => "Unrecognised message type: $command[type]"
17421753
]);
@@ -1796,10 +1807,11 @@ function run_test(string $php, $file, array $env): string
17961807
global $slow_min_ms;
17971808
global $preload, $file_cache;
17981809
global $num_repeats;
1799-
// Parallel testing
1800-
global $workerID;
18011810
global $show_progress;
18021811

1812+
/** @var WorkerContext $workerContext */
1813+
global $workerContext;
1814+
18031815
// Temporary
18041816
/** @var JUnit $junit */
18051817
global $junit;
@@ -1913,7 +1925,7 @@ function run_test(string $php, $file, array $env): string
19131925
}
19141926
}
19151927

1916-
if ($show_progress && !$workerID) {
1928+
if ($show_progress && !$workerContext->workerID) {
19171929
show_test($test_idx, $shortname);
19181930
}
19191931

@@ -2004,7 +2016,7 @@ function run_test(string $php, $file, array $env): string
20042016
}
20052017

20062018
// Default ini settings
2007-
$ini_settings = $workerID ? ['opcache.cache_id' => "worker$workerID"] : [];
2019+
$ini_settings = $workerContext->workerID ? ['opcache.cache_id' => "worker".$workerContext->workers] : [];
20082020

20092021
// Additional required extensions
20102022
$extensions = [];
@@ -3217,10 +3229,10 @@ function show_test(int $test_idx, string $shortname): void
32173229
function clear_show_test(): void
32183230
{
32193231
global $line_length;
3220-
// Parallel testing
3221-
global $workerID;
3232+
/** @var WorkerContext $workerContext */
3233+
global $workerContext;
32223234

3223-
if (!$workerID && isset($line_length)) {
3235+
if (!$workerContext->workerID && isset($line_length)) {
32243236
// Write over the last line to avoid random trailing chars on next echo
32253237
echo str_repeat(" ", $line_length), "\r";
32263238
}
@@ -4171,4 +4183,19 @@ public function getDiff(array $diffs): string
41714183
}
41724184
}
41734185

4186+
class WorkerContext {
4187+
/**
4188+
* @var int|null number of workers to use, null for non-parallel testing.
4189+
*/
4190+
public $workers;
4191+
/**
4192+
* @var int
4193+
*/
4194+
public $workerID;
4195+
/**
4196+
* @var resource
4197+
*/
4198+
public $workerSock;
4199+
}
4200+
41744201
main();

0 commit comments

Comments
 (0)