16
16
from test .support import os_helper
17
17
from test .support import TestStats
18
18
19
- from test .libregrtest .cmdline import Namespace
20
19
from test .libregrtest .main import Regrtest
21
20
from test .libregrtest .runtest import (
22
21
run_single_test , TestResult , State , PROGRESS_MIN_TIME ,
@@ -150,14 +149,13 @@ class ExitThread(Exception):
150
149
pass
151
150
152
151
153
- class TestWorkerProcess (threading .Thread ):
154
- def __init__ (self , worker_id : int , runner : "MultiprocessTestRunner " ) -> None :
152
+ class WorkerThread (threading .Thread ):
153
+ def __init__ (self , worker_id : int , runner : "RunWorkers " ) -> None :
155
154
super ().__init__ ()
156
155
self .worker_id = worker_id
157
156
self .runtests = runner .runtests
158
157
self .pending = runner .pending
159
158
self .output = runner .output
160
- self .ns = runner .ns
161
159
self .timeout = runner .worker_timeout
162
160
self .regrtest = runner .regrtest
163
161
self .current_test_name = None
@@ -167,7 +165,7 @@ def __init__(self, worker_id: int, runner: "MultiprocessTestRunner") -> None:
167
165
self ._stopped = False
168
166
169
167
def __repr__ (self ) -> str :
170
- info = [f'TestWorkerProcess #{ self .worker_id } ' ]
168
+ info = [f'WorkerThread #{ self .worker_id } ' ]
171
169
if self .is_alive ():
172
170
info .append ("running" )
173
171
else :
@@ -203,7 +201,7 @@ def _kill(self) -> None:
203
201
else :
204
202
popen .kill ()
205
203
except ProcessLookupError :
206
- # popen.kill(): the process completed, the TestWorkerProcess thread
204
+ # popen.kill(): the process completed, the WorkerThread thread
207
205
# read its exit status, but Popen.send_signal() read the returncode
208
206
# just before Popen.wait() set returncode.
209
207
pass
@@ -362,7 +360,7 @@ def _runtest(self, test_name: str) -> MultiprocessResult:
362
360
363
361
def run (self ) -> None :
364
362
fail_fast = self .runtests .fail_fast
365
- fail_env_changed = self .ns .fail_env_changed
363
+ fail_env_changed = self .runtests .fail_env_changed
366
364
while not self ._stopped :
367
365
try :
368
366
try :
@@ -394,10 +392,10 @@ def _wait_completed(self) -> None:
394
392
f"{ exc !r} " )
395
393
396
394
def wait_stopped (self , start_time : float ) -> None :
397
- # bpo-38207: MultiprocessTestRunner .stop_workers() called self.stop()
395
+ # bpo-38207: RunWorkers .stop_workers() called self.stop()
398
396
# which killed the process. Sometimes, killing the process from the
399
397
# main thread does not interrupt popen.communicate() in
400
- # TestWorkerProcess thread. This loop with a timeout is a workaround
398
+ # WorkerThread thread. This loop with a timeout is a workaround
401
399
# for that.
402
400
#
403
401
# Moreover, if this method fails to join the thread, it is likely
@@ -417,7 +415,7 @@ def wait_stopped(self, start_time: float) -> None:
417
415
break
418
416
419
417
420
- def get_running (workers : list [TestWorkerProcess ]) -> list [TestWorkerProcess ]:
418
+ def get_running (workers : list [WorkerThread ]) -> list [str ]:
421
419
running = []
422
420
for worker in workers :
423
421
current_test_name = worker .current_test_name
@@ -427,18 +425,17 @@ def get_running(workers: list[TestWorkerProcess]) -> list[TestWorkerProcess]:
427
425
if dt >= PROGRESS_MIN_TIME :
428
426
text = '%s (%s)' % (current_test_name , format_duration (dt ))
429
427
running .append (text )
430
- return running
428
+ if not running :
429
+ return None
430
+ return f"running ({ len (running )} ): { ', ' .join (running )} "
431
431
432
432
433
- class MultiprocessTestRunner :
434
- def __init__ (self , regrtest : Regrtest , runtests : RunTests ) -> None :
435
- ns = regrtest .ns
436
-
433
+ class RunWorkers :
434
+ def __init__ (self , regrtest : Regrtest , runtests : RunTests , num_workers : int ) -> None :
437
435
self .regrtest = regrtest
436
+ self .log = regrtest .log
437
+ self .num_workers = num_workers
438
438
self .runtests = runtests
439
- self .rerun = runtests .rerun
440
- self .log = self .regrtest .log
441
- self .ns = ns
442
439
self .output : queue .Queue [QueueOutput ] = queue .Queue ()
443
440
tests_iter = runtests .iter_tests ()
444
441
self .pending = MultiprocessIterator (tests_iter )
@@ -453,9 +450,8 @@ def __init__(self, regrtest: Regrtest, runtests: RunTests) -> None:
453
450
self .workers = None
454
451
455
452
def start_workers (self ) -> None :
456
- use_mp = self .ns .use_mp
457
- self .workers = [TestWorkerProcess (index , self )
458
- for index in range (1 , use_mp + 1 )]
453
+ self .workers = [WorkerThread (index , self )
454
+ for index in range (1 , self .num_workers + 1 )]
459
455
msg = f"Run tests in parallel using { len (self .workers )} child processes"
460
456
if self .timeout :
461
457
msg += (" (timeout: %s, worker timeout: %s)"
@@ -489,10 +485,11 @@ def _get_result(self) -> QueueOutput | None:
489
485
except queue .Empty :
490
486
pass
491
487
492
- # display progress
493
- running = get_running (self .workers )
494
- if running and not pgo :
495
- self .log ('running: %s' % ', ' .join (running ))
488
+ if not pgo :
489
+ # display progress
490
+ running = get_running (self .workers )
491
+ if running :
492
+ self .log (running )
496
493
497
494
# all worker threads are done: consume pending results
498
495
try :
@@ -510,9 +507,10 @@ def display_result(self, mp_result: MultiprocessResult) -> None:
510
507
text += ' (%s)' % mp_result .err_msg
511
508
elif (result .duration >= PROGRESS_MIN_TIME and not pgo ):
512
509
text += ' (%s)' % format_duration (result .duration )
513
- running = get_running (self .workers )
514
- if running and not pgo :
515
- text += ' -- running: %s' % ', ' .join (running )
510
+ if not pgo :
511
+ running = get_running (self .workers )
512
+ if running :
513
+ text += f' -- { running } '
516
514
self .regrtest .display_progress (self .test_index , text )
517
515
518
516
def _process_result (self , item : QueueOutput ) -> bool :
@@ -537,9 +535,9 @@ def _process_result(self, item: QueueOutput) -> bool:
537
535
538
536
return result
539
537
540
- def run_tests (self ) -> None :
538
+ def run (self ) -> None :
541
539
fail_fast = self .runtests .fail_fast
542
- fail_env_changed = self .ns .fail_env_changed
540
+ fail_env_changed = self .runtests .fail_env_changed
543
541
544
542
self .start_workers ()
545
543
@@ -566,10 +564,6 @@ def run_tests(self) -> None:
566
564
self .stop_workers ()
567
565
568
566
569
- def run_tests_multiprocess (regrtest : Regrtest , runtests : RunTests ) -> None :
570
- MultiprocessTestRunner (regrtest , runtests ).run_tests ()
571
-
572
-
573
567
class EncodeTestResult (json .JSONEncoder ):
574
568
"""Encode a TestResult (sub)class object into a JSON dict."""
575
569
0 commit comments