Skip to content

Commit 8c813fa

Browse files
authored
gh-109276: libregrtest: limit number workers (#109288)
Don't spawn more threads than the number of jobs: these worker threads would never get anything to do. * Add the number of tests in "Run ... tests in ..." message. * Add RunTests.get_jobs() method. * Add plural() function. * count() uses f-string.
1 parent a84cb74 commit 8c813fa

File tree

4 files changed

+40
-5
lines changed

4 files changed

+40
-5
lines changed

Lib/test/libregrtest/main.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,12 @@ def run_tests_sequentially(self, runtests):
295295

296296
save_modules = sys.modules.keys()
297297

298-
msg = "Run tests sequentially"
298+
jobs = runtests.get_jobs()
299+
if jobs is not None:
300+
tests = f'{jobs} tests'
301+
else:
302+
tests = 'tests'
303+
msg = f"Run {tests} sequentially"
299304
if runtests.timeout:
300305
msg += " (timeout: %s)" % format_duration(runtests.timeout)
301306
self.log(msg)

Lib/test/libregrtest/run_workers.py

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
from .single import PROGRESS_MIN_TIME
2222
from .utils import (
2323
StrPath, StrJSON, TestName, MS_WINDOWS,
24-
format_duration, print_warning)
24+
format_duration, print_warning, plural)
2525
from .worker import create_worker_process, USE_PROCESS_GROUP
2626

2727
if MS_WINDOWS:
@@ -401,10 +401,24 @@ def __init__(self, num_workers: int, runtests: RunTests,
401401
self.worker_timeout = None
402402
self.workers = None
403403

404+
jobs = self.runtests.get_jobs()
405+
if jobs is not None:
406+
# Don't spawn more threads than the number of jobs:
407+
# these worker threads would never get anything to do.
408+
self.num_workers = min(self.num_workers, jobs)
409+
404410
def start_workers(self) -> None:
405411
self.workers = [WorkerThread(index, self)
406412
for index in range(1, self.num_workers + 1)]
407-
msg = f"Run tests in parallel using {len(self.workers)} child processes"
413+
jobs = self.runtests.get_jobs()
414+
if jobs is not None:
415+
tests = f'{jobs} tests'
416+
else:
417+
tests = 'tests'
418+
nworkers = len(self.workers)
419+
processes = plural(nworkers, "process", "processes")
420+
msg = (f"Run {tests} in parallel using "
421+
f"{nworkers} worker {processes}")
408422
if self.timeout:
409423
msg += (" (timeout: %s, worker timeout: %s)"
410424
% (format_duration(self.timeout),

Lib/test/libregrtest/runtests.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,13 @@ def get_match_tests(self, test_name) -> FilterTuple | None:
5353
else:
5454
return None
5555

56+
def get_jobs(self):
57+
# Number of run_single_test() calls needed to run all tests.
58+
# None means that there is not bound limit (--forever option).
59+
if self.forever:
60+
return None
61+
return len(self.tests)
62+
5663
def iter_tests(self):
5764
if self.forever:
5865
while True:

Lib/test/libregrtest/utils.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,11 +70,20 @@ def strip_py_suffix(names: list[str]):
7070
names[idx] = basename
7171

7272

73+
def plural(n, singular, plural=None):
74+
if n == 1:
75+
return singular
76+
elif plural is not None:
77+
return plural
78+
else:
79+
return singular + 's'
80+
81+
7382
def count(n, word):
7483
if n == 1:
75-
return "%d %s" % (n, word)
84+
return f"{n} {word}"
7685
else:
77-
return "%d %ss" % (n, word)
86+
return f"{n} {word}s"
7887

7988

8089
def printlist(x, width=70, indent=4, file=None):

0 commit comments

Comments
 (0)