Skip to content

Commit b68232c

Browse files
committed
gh-109276: libregrtest: limit number workers
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 9363769 commit b68232c

File tree

4 files changed

+40
-5
lines changed

4 files changed

+40
-5
lines changed

Lib/test/libregrtest/main.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,12 @@ def run_tests_sequentially(self, runtests):
292292

293293
save_modules = sys.modules.keys()
294294

295-
msg = "Run tests sequentially"
295+
jobs = runtests.get_jobs()
296+
if jobs is not None:
297+
tests = f'{jobs} tests'
298+
else:
299+
tests = 'tests'
300+
msg = f"Run {tests} sequentially"
296301
if runtests.timeout:
297302
msg += " (timeout: %s)" % format_duration(runtests.timeout)
298303
self.log(msg)

Lib/test/libregrtest/run_workers.py

+16-2
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

+7
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,13 @@ def get_match_tests(self, test_name) -> FilterTuple | None:
5151
else:
5252
return None
5353

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

Lib/test/libregrtest/utils.py

+11-2
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)