@@ -156,8 +156,10 @@ function main(): void
156
156
$ test_files , $ test_idx , $ test_results , $ testfile ,
157
157
$ valgrind , $ sum_results , $ shuffle , $ file_cache , $ num_repeats ,
158
158
$ show_progress ;
159
- // Parallel testing
160
- global $ workers , $ workerID ;
159
+
160
+ global $ workerContext ;
161
+ $ workerContext = new WorkerContext ();
162
+
161
163
global $ context_line_count ;
162
164
163
165
// Temporary for the duration of refactoring
@@ -166,9 +168,9 @@ function main(): void
166
168
167
169
define ('IS_WINDOWS ' , substr (PHP_OS , 0 , 3 ) == "WIN " );
168
170
169
- $ workerID = 0 ;
171
+ $ workerContext -> workerID = 0 ;
170
172
if (getenv ("TEST_PHP_WORKER " )) {
171
- $ workerID = intval (getenv ("TEST_PHP_WORKER " ));
173
+ $ workerContext -> workerID = intval (getenv ("TEST_PHP_WORKER " ));
172
174
run_worker ();
173
175
return ;
174
176
}
@@ -251,7 +253,7 @@ function main(): void
251
253
$ DETAILED = 0 ;
252
254
}
253
255
254
- $ junit = new JUnit ($ environment , $ workerID );
256
+ $ junit = new JUnit ($ environment , $ workerContext -> workerID );
255
257
256
258
if (getenv ('SHOW_ONLY_GROUPS ' )) {
257
259
$ SHOW_ONLY_GROUPS = explode (", " , getenv ('SHOW_ONLY_GROUPS ' ));
@@ -350,7 +352,7 @@ function main(): void
350
352
$ file_cache = null ;
351
353
$ shuffle = false ;
352
354
$ bless = false ;
353
- $ workers = null ;
355
+ $ workerContext -> workers = null ;
354
356
$ context_line_count = 3 ;
355
357
$ num_repeats = 1 ;
356
358
$ show_progress = true ;
@@ -421,6 +423,7 @@ function main(): void
421
423
if ($ workers === 1 ) {
422
424
$ workers = null ;
423
425
}
426
+ $ workerContext ->workers = $ workers ;
424
427
break ;
425
428
case 'r ' :
426
429
case 'l ' :
@@ -1229,13 +1232,15 @@ function system_with_timeout(
1229
1232
proc_close ($ proc );
1230
1233
return $ data ;
1231
1234
}
1232
-
1233
1235
function run_all_tests (array $ test_files , array $ env , ?string $ redir_tested = null ): void
1234
1236
{
1235
1237
global $ test_results , $ failed_tests_file , $ result_tests_file , $ php , $ test_idx , $ file_cache ;
1236
1238
global $ preload ;
1237
1239
// Parallel testing
1238
- global $ PHP_FAILED_TESTS , $ workers , $ workerID , $ workerSock ;
1240
+ global $ PHP_FAILED_TESTS ;
1241
+
1242
+ /** @var WorkerContext $workerContext */
1243
+ global $ workerContext ;
1239
1244
1240
1245
if ($ file_cache !== null || $ preload ) {
1241
1246
/* Automatically skip opcache tests in --file-cache and --preload mode,
@@ -1255,7 +1260,7 @@ function run_all_tests(array $test_files, array $env, ?string $redir_tested = nu
1255
1260
}
1256
1261
1257
1262
/* Ignore -jN if there is only one file to analyze. */
1258
- if ($ workers !== null && count ($ test_files ) > 1 && !$ workerID ) {
1263
+ if ($ workerContext -> workers !== null && count ($ test_files ) > 1 && !$ workerContext -> workerID ) {
1259
1264
run_all_tests_parallel ($ test_files , $ env , $ redir_tested );
1260
1265
return ;
1261
1266
}
@@ -1274,19 +1279,19 @@ function run_all_tests(array $test_files, array $env, ?string $redir_tested = nu
1274
1279
}
1275
1280
$ test_idx ++;
1276
1281
1277
- if ($ workerID ) {
1282
+ if ($ workerContext -> workerID ) {
1278
1283
$ PHP_FAILED_TESTS = ['BORKED ' => [], 'FAILED ' => [], 'WARNED ' => [], 'LEAKED ' => [], 'XFAILED ' => [], 'XLEAKED ' => [], 'SLOW ' => []];
1279
1284
ob_start ();
1280
1285
}
1281
1286
1282
1287
$ result = run_test ($ php , $ name , $ env );
1283
- if ($ workerID ) {
1288
+ if ($ workerContext -> workerID ) {
1284
1289
$ resultText = ob_get_clean ();
1285
1290
}
1286
1291
1287
1292
if (!is_array ($ name ) && $ result != 'REDIR ' ) {
1288
- if ($ workerID ) {
1289
- send_message ($ workerSock , [
1293
+ if ($ workerContext -> workerID ) {
1294
+ send_message ($ workerContext -> workerSock , [
1290
1295
"type " => "test_result " ,
1291
1296
"name " => $ name ,
1292
1297
"index " => $ index ,
@@ -1310,10 +1315,13 @@ function run_all_tests(array $test_files, array $env, ?string $redir_tested = nu
1310
1315
1311
1316
function run_all_tests_parallel (array $ test_files , array $ env , ?string $ redir_tested ): void
1312
1317
{
1313
- global $ workers , $ test_idx , $ test_results , $ failed_tests_file , $ result_tests_file , $ PHP_FAILED_TESTS , $ shuffle , $ valgrind , $ show_progress ;
1318
+ global $ test_idx , $ test_results , $ failed_tests_file , $ result_tests_file , $ PHP_FAILED_TESTS , $ shuffle , $ valgrind , $ show_progress ;
1314
1319
1315
1320
global $ junit ;
1316
1321
1322
+ /** @var WorkerContext $workerContext */
1323
+ global $ workerContext ;
1324
+
1317
1325
// The PHP binary running run-tests.php, and run-tests.php itself
1318
1326
// This PHP executable is *not* necessarily the same as the tested version
1319
1327
$ thisPHP = PHP_BINARY ;
@@ -1367,9 +1375,9 @@ function run_all_tests_parallel(array $test_files, array $env, ?string $redir_te
1367
1375
}
1368
1376
1369
1377
// Don't start more workers than test files.
1370
- $ workers = max (1 , min ($ workers , count ($ test_files )));
1378
+ $ workerContext -> workers = max (1 , min ($ workerContext -> workers , count ($ test_files )));
1371
1379
1372
- echo "Spawning $ workers workers... " ;
1380
+ echo "Spawning " . $ workerContext -> workers . " workers... " ;
1373
1381
1374
1382
// We use sockets rather than STDIN/STDOUT for comms because on Windows,
1375
1383
// those can't be non-blocking for some reason.
@@ -1386,7 +1394,7 @@ function run_all_tests_parallel(array $test_files, array $env, ?string $redir_te
1386
1394
$ totalFileCount = count ($ test_files );
1387
1395
1388
1396
$ startTime = microtime (true );
1389
- for ($ i = 1 ; $ i <= $ workers ; $ i ++) {
1397
+ for ($ i = 1 ; $ i <= $ workerContext -> workers ; $ i ++) {
1390
1398
$ proc = proc_open (
1391
1399
[$ thisPHP , $ thisScript ],
1392
1400
[], // Inherit our stdin, stdout and stderr
@@ -1408,7 +1416,7 @@ function run_all_tests_parallel(array $test_files, array $env, ?string $redir_te
1408
1416
$ workerProcs [$ i ] = $ proc ;
1409
1417
}
1410
1418
1411
- for ($ i = 1 ; $ i <= $ workers ; $ i ++) {
1419
+ for ($ i = 1 ; $ i <= $ workerContext -> workers ; $ i ++) {
1412
1420
$ workerSock = stream_socket_accept ($ listenSock , 5 );
1413
1421
if ($ workerSock === false ) {
1414
1422
kill_children ($ workerProcs );
@@ -1567,7 +1575,7 @@ function run_all_tests_parallel(array $test_files, array $env, ?string $redir_te
1567
1575
echo $ resultText ;
1568
1576
1569
1577
if ($ show_progress ) {
1570
- show_test ($ test_idx , count ($ workerProcs ) . "/ $ workers concurrent test workers running " );
1578
+ show_test ($ test_idx , count ($ workerProcs ) . "/ " . $ workerContext -> workers . " concurrent test workers running " );
1571
1579
}
1572
1580
1573
1581
if (!is_array ($ name ) && $ result != 'REDIR ' ) {
@@ -1662,6 +1670,9 @@ function safe_fwrite($stream, string $data)
1662
1670
return $ bytes_written ;
1663
1671
}
1664
1672
1673
+ /**
1674
+ * @param resource $stream
1675
+ */
1665
1676
function send_message ($ stream , array $ message ): void
1666
1677
{
1667
1678
$ blocking = stream_get_meta_data ($ stream )["blocked " ];
@@ -1681,23 +1692,24 @@ function kill_children(array $children): void
1681
1692
1682
1693
function run_worker (): void
1683
1694
{
1684
- global $ workerID , $ workerSock ;
1695
+ /** @var WorkerContext $workerContext */
1696
+ global $ workerContext ;
1685
1697
1686
1698
global $ junit ;
1687
1699
1688
1700
$ sockUri = getenv ("TEST_PHP_URI " );
1689
1701
1690
- $ workerSock = stream_socket_client ($ sockUri , $ _ , $ _ , 5 ) or error ("Couldn't connect to $ sockUri " );
1702
+ $ workerContext -> workerSock = stream_socket_client ($ sockUri , $ _ , $ _ , 5 ) or error ("Couldn't connect to $ sockUri " );
1691
1703
1692
- $ greeting = fgets ($ workerSock );
1704
+ $ greeting = fgets ($ workerContext -> workerSock );
1693
1705
$ greeting = unserialize (base64_decode ($ greeting )) or die ("Could not decode greeting \n" );
1694
1706
if ($ greeting ["type " ] !== "hello " ) {
1695
1707
error ("Unexpected greeting of type $ greeting [type]" );
1696
1708
}
1697
1709
1698
- set_error_handler (function (int $ errno , string $ errstr , string $ errfile , int $ errline ) use ($ workerSock ): bool {
1710
+ set_error_handler (function (int $ errno , string $ errstr , string $ errfile , int $ errline ) use ($ workerContext ): bool {
1699
1711
if (error_reporting () & $ errno ) {
1700
- send_message ($ workerSock , compact ('errno ' , 'errstr ' , 'errfile ' , 'errline ' ) + [
1712
+ send_message ($ workerContext -> workerSock , compact ('errno ' , 'errstr ' , 'errfile ' , 'errline ' ) + [
1701
1713
'type ' => 'php_error '
1702
1714
]);
1703
1715
}
@@ -1706,37 +1718,37 @@ function run_worker(): void
1706
1718
});
1707
1719
1708
1720
foreach ($ greeting ["GLOBALS " ] as $ var => $ value ) {
1709
- if ($ var !== "workerID " && $ var !== " workerSock " && $ var !== "GLOBALS " ) {
1721
+ if ($ var !== "workerContext " && $ var !== "GLOBALS " ) {
1710
1722
$ GLOBALS [$ var ] = $ value ;
1711
1723
}
1712
1724
}
1713
1725
foreach ($ greeting ["constants " ] as $ const => $ value ) {
1714
1726
define ($ const , $ value );
1715
1727
}
1716
1728
1717
- send_message ($ workerSock , [
1729
+ send_message ($ workerContext -> workerSock , [
1718
1730
"type " => "hello_reply " ,
1719
- "workerID " => $ workerID
1731
+ "workerID " => $ workerContext -> workerID
1720
1732
]);
1721
1733
1722
- send_message ($ workerSock , [
1734
+ send_message ($ workerContext -> workerSock , [
1723
1735
"type " => "ready "
1724
1736
]);
1725
1737
1726
- while (($ command = fgets ($ workerSock ))) {
1738
+ while (($ command = fgets ($ workerContext -> workerSock ))) {
1727
1739
$ command = unserialize (base64_decode ($ command ));
1728
1740
1729
1741
switch ($ command ["type " ]) {
1730
1742
case "run_tests " :
1731
1743
run_all_tests ($ command ["test_files " ], $ command ["env " ], $ command ["redir_tested " ]);
1732
- send_message ($ workerSock , [
1744
+ send_message ($ workerContext -> workerSock , [
1733
1745
"type " => "tests_finished " ,
1734
1746
"junit " => $ junit ->isEnabled () ? $ junit : null ,
1735
1747
]);
1736
1748
$ junit ->clear ();
1737
1749
break ;
1738
1750
default :
1739
- send_message ($ workerSock , [
1751
+ send_message ($ workerContext -> workerSock , [
1740
1752
"type " => "error " ,
1741
1753
"msg " => "Unrecognised message type: $ command [type]"
1742
1754
]);
@@ -1796,10 +1808,11 @@ function run_test(string $php, $file, array $env): string
1796
1808
global $ slow_min_ms ;
1797
1809
global $ preload , $ file_cache ;
1798
1810
global $ num_repeats ;
1799
- // Parallel testing
1800
- global $ workerID ;
1801
1811
global $ show_progress ;
1802
1812
1813
+ /** @var WorkerContext $workerContext */
1814
+ global $ workerContext ;
1815
+
1803
1816
// Temporary
1804
1817
/** @var JUnit $junit */
1805
1818
global $ junit ;
@@ -1913,7 +1926,7 @@ function run_test(string $php, $file, array $env): string
1913
1926
}
1914
1927
}
1915
1928
1916
- if ($ show_progress && !$ workerID ) {
1929
+ if ($ show_progress && !$ workerContext -> workerID ) {
1917
1930
show_test ($ test_idx , $ shortname );
1918
1931
}
1919
1932
@@ -2004,7 +2017,7 @@ function run_test(string $php, $file, array $env): string
2004
2017
}
2005
2018
2006
2019
// Default ini settings
2007
- $ ini_settings = $ workerID ? ['opcache.cache_id ' => "worker $ workerID " ] : [];
2020
+ $ ini_settings = $ workerContext -> workerID ? ['opcache.cache_id ' => "worker " . $ workerContext -> workers ] : [];
2008
2021
2009
2022
// Additional required extensions
2010
2023
$ extensions = [];
@@ -3217,10 +3230,10 @@ function show_test(int $test_idx, string $shortname): void
3217
3230
function clear_show_test (): void
3218
3231
{
3219
3232
global $ line_length ;
3220
- // Parallel testing
3221
- global $ workerID ;
3233
+ /** @var WorkerContext $workerContext */
3234
+ global $ workerContext ;
3222
3235
3223
- if (!$ workerID && isset ($ line_length )) {
3236
+ if (!$ workerContext -> workerID && isset ($ line_length )) {
3224
3237
// Write over the last line to avoid random trailing chars on next echo
3225
3238
echo str_repeat (" " , $ line_length ), "\r" ;
3226
3239
}
@@ -4171,4 +4184,19 @@ public function getDiff(array $diffs): string
4171
4184
}
4172
4185
}
4173
4186
4187
+ class WorkerContext {
4188
+ /**
4189
+ * @var int|null number of workers to use, null for non-parallel testing.
4190
+ */
4191
+ public $ workers ;
4192
+ /**
4193
+ * @var int
4194
+ */
4195
+ public $ workerID ;
4196
+ /**
4197
+ * @var resource
4198
+ */
4199
+ public $ workerSock ;
4200
+ }
4201
+
4174
4202
main ();
0 commit comments