From a594008d9e6c4d37ff6fd698395cd318d7ec3300 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Langa?= Date: Fri, 18 Apr 2025 15:56:44 +0200 Subject: gh-132678: Add --prioritize to regrtest (GH-132679) This is an option that allows the user to specify, which selected tests should execute first, even if the order is otherwise randomized. This is particularly useful for tests that run the longest. --- Lib/test/libregrtest/cmdline.py | 32 ++++++++++++++++++---- Lib/test/libregrtest/main.py | 11 ++++++++ .../2025-04-18-14-00-38.gh-issue-132678.j_ZKf2.rst | 3 ++ 3 files changed, 41 insertions(+), 5 deletions(-) create mode 100644 Misc/NEWS.d/next/Tests/2025-04-18-14-00-38.gh-issue-132678.j_ZKf2.rst diff --git a/Lib/test/libregrtest/cmdline.py b/Lib/test/libregrtest/cmdline.py index 81c7106..07681d7 100644 --- a/Lib/test/libregrtest/cmdline.py +++ b/Lib/test/libregrtest/cmdline.py @@ -44,11 +44,19 @@ is possible to single step through the test files. This is useful when doing memory analysis on the Python interpreter, which process tends to consume too many resources to run the full regression test non-stop. --S is used to continue running tests after an aborted run. It will -maintain the order a standard run (ie, this assumes -r is not used). +-S is used to resume running tests after an interrupted run. It will +maintain the order a standard run (i.e. it assumes -r is not used). This is useful after the tests have prematurely stopped for some external -reason and you want to start running from where you left off rather -than starting from the beginning. +reason and you want to resume the run from where you left off rather +than starting from the beginning. Note: this is different from --prioritize. + +--prioritize is used to influence the order of selected tests, such that +the tests listed as an argument are executed first. This is especially +useful when combined with -j and -r to pin the longest-running tests +to start at the beginning of a test run. Pass --prioritize=test_a,test_b +to make test_a run first, followed by test_b, and then the other tests. +If test_a wasn't selected for execution by regular means, --prioritize will +not make it execute. -f reads the names of tests from the file given as f's argument, one or more test names per line. Whitespace is ignored. Blank lines and @@ -236,7 +244,7 @@ def _create_parser(): help='wait for user input, e.g., allow a debugger ' 'to be attached') group.add_argument('-S', '--start', metavar='START', - help='the name of the test at which to start.' + + help='resume an interrupted run at the following test.' + more_details) group.add_argument('-p', '--python', metavar='PYTHON', help='Command to run Python test subprocesses with.') @@ -263,6 +271,10 @@ def _create_parser(): group = parser.add_argument_group('Selecting tests') group.add_argument('-r', '--randomize', action='store_true', help='randomize test execution order.' + more_details) + group.add_argument('--prioritize', metavar='TEST1,TEST2,...', + action='append', type=priority_list, + help='select these tests first, even if the order is' + ' randomized.' + more_details) group.add_argument('-f', '--fromfile', metavar='FILE', help='read names of tests to run from a file.' + more_details) @@ -406,6 +418,10 @@ def resources_list(string): return u +def priority_list(string): + return string.split(",") + + def _parse_args(args, **kwargs): # Defaults ns = Namespace() @@ -551,4 +567,10 @@ def _parse_args(args, **kwargs): print(msg, file=sys.stderr, flush=True) sys.exit(2) + ns.prioritize = [ + test + for test_list in (ns.prioritize or ()) + for test in test_list + ] + return ns diff --git a/Lib/test/libregrtest/main.py b/Lib/test/libregrtest/main.py index 19beb29..713cbed 100644 --- a/Lib/test/libregrtest/main.py +++ b/Lib/test/libregrtest/main.py @@ -142,6 +142,7 @@ class Regrtest: self.random_seed = random.getrandbits(32) else: self.random_seed = ns.random_seed + self.prioritize_tests: tuple[str, ...] = tuple(ns.prioritize) self.parallel_threads = ns.parallel_threads @@ -237,6 +238,16 @@ class Regrtest: if self.randomize: random.shuffle(selected) + for priority_test in reversed(self.prioritize_tests): + try: + selected.remove(priority_test) + except ValueError: + print(f"warning: --prioritize={priority_test} used" + f" but test not actually selected") + continue + else: + selected.insert(0, priority_test) + return (tuple(selected), tests) @staticmethod diff --git a/Misc/NEWS.d/next/Tests/2025-04-18-14-00-38.gh-issue-132678.j_ZKf2.rst b/Misc/NEWS.d/next/Tests/2025-04-18-14-00-38.gh-issue-132678.j_ZKf2.rst new file mode 100644 index 0000000..e079cd4 --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2025-04-18-14-00-38.gh-issue-132678.j_ZKf2.rst @@ -0,0 +1,3 @@ +Add ``--prioritize`` to ``-m test``. This option allows the user to specify +which selected tests should execute first, even if the order is otherwise +randomized. This is particularly useful for tests that run the longest. -- cgit v0.12