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.
This commit is contained in:
Victor Stinner 2023-09-12 05:47:04 +02:00 committed by GitHub
parent a84cb74d42
commit 8c813faf86
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 40 additions and 5 deletions

View File

@ -295,7 +295,12 @@ class Regrtest:
save_modules = sys.modules.keys()
msg = "Run tests sequentially"
jobs = runtests.get_jobs()
if jobs is not None:
tests = f'{jobs} tests'
else:
tests = 'tests'
msg = f"Run {tests} sequentially"
if runtests.timeout:
msg += " (timeout: %s)" % format_duration(runtests.timeout)
self.log(msg)

View File

@ -21,7 +21,7 @@ from .runtests import RunTests
from .single import PROGRESS_MIN_TIME
from .utils import (
StrPath, StrJSON, TestName, MS_WINDOWS,
format_duration, print_warning)
format_duration, print_warning, plural)
from .worker import create_worker_process, USE_PROCESS_GROUP
if MS_WINDOWS:
@ -401,10 +401,24 @@ class RunWorkers:
self.worker_timeout = None
self.workers = None
jobs = self.runtests.get_jobs()
if jobs is not None:
# Don't spawn more threads than the number of jobs:
# these worker threads would never get anything to do.
self.num_workers = min(self.num_workers, jobs)
def start_workers(self) -> None:
self.workers = [WorkerThread(index, self)
for index in range(1, self.num_workers + 1)]
msg = f"Run tests in parallel using {len(self.workers)} child processes"
jobs = self.runtests.get_jobs()
if jobs is not None:
tests = f'{jobs} tests'
else:
tests = 'tests'
nworkers = len(self.workers)
processes = plural(nworkers, "process", "processes")
msg = (f"Run {tests} in parallel using "
f"{nworkers} worker {processes}")
if self.timeout:
msg += (" (timeout: %s, worker timeout: %s)"
% (format_duration(self.timeout),

View File

@ -53,6 +53,13 @@ class RunTests:
else:
return None
def get_jobs(self):
# Number of run_single_test() calls needed to run all tests.
# None means that there is not bound limit (--forever option).
if self.forever:
return None
return len(self.tests)
def iter_tests(self):
if self.forever:
while True:

View File

@ -70,11 +70,20 @@ def strip_py_suffix(names: list[str]):
names[idx] = basename
def plural(n, singular, plural=None):
if n == 1:
return singular
elif plural is not None:
return plural
else:
return singular + 's'
def count(n, word):
if n == 1:
return "%d %s" % (n, word)
return f"{n} {word}"
else:
return "%d %ss" % (n, word)
return f"{n} {word}s"
def printlist(x, width=70, indent=4, file=None):