diff --git a/Lib/test/libregrtest/main.py b/Lib/test/libregrtest/main.py index f52deac329d..a89e3c6a498 100644 --- a/Lib/test/libregrtest/main.py +++ b/Lib/test/libregrtest/main.py @@ -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) diff --git a/Lib/test/libregrtest/run_workers.py b/Lib/test/libregrtest/run_workers.py index 5c665abfeb5..cfa36f78009 100644 --- a/Lib/test/libregrtest/run_workers.py +++ b/Lib/test/libregrtest/run_workers.py @@ -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), diff --git a/Lib/test/libregrtest/runtests.py b/Lib/test/libregrtest/runtests.py index 656958fa713..5c68df126e2 100644 --- a/Lib/test/libregrtest/runtests.py +++ b/Lib/test/libregrtest/runtests.py @@ -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: diff --git a/Lib/test/libregrtest/utils.py b/Lib/test/libregrtest/utils.py index b46cec6f0ee..ce1b1088127 100644 --- a/Lib/test/libregrtest/utils.py +++ b/Lib/test/libregrtest/utils.py @@ -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):