Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions Lib/test/libregrtest/cmdline.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ def __init__(self, **kwargs) -> None:
self.tempdir = None
self._add_python_opts = True
self.xmlpath = None
self.sequentially = False

super().__init__(**kwargs)

Expand Down Expand Up @@ -307,6 +308,10 @@ def _create_parser():
group.add_argument('-j', '--multiprocess', metavar='PROCESSES',
dest='use_mp', type=int,
help='run PROCESSES processes at once')
group.add_argument('--sequentially', action='store_true',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can also implement it as action='store_const', dest='use_mp', const=None.

help='always run all tests sequentially, '
'ignore -jN option, '
'and failed tests are also rerun sequentially')
group.add_argument('-T', '--coverage', action='store_true',
dest='trace',
help='turn on code coverage tracing using the trace '
Expand Down
20 changes: 15 additions & 5 deletions Lib/test/libregrtest/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,10 @@ def __init__(self, ns: Namespace, _add_python_opts: bool = False):
self.cmdline_args: TestList = ns.args

# Workers
if ns.use_mp is None:
self.sequentially: bool = ns.sequentially
if self.sequentially:
num_workers = 0 # run sequentially
elif ns.use_mp is None:
num_workers = 0 # run sequentially
elif ns.use_mp <= 0:
num_workers = -1 # use the number of CPUs
Expand Down Expand Up @@ -236,7 +239,7 @@ def list_tests(tests: TestTuple):

def _rerun_failed_tests(self, runtests: RunTests):
# Configure the runner to re-run tests
if self.num_workers == 0:
if self.num_workers == 0 and not self.sequentially:
# Always run tests in fresh processes to have more deterministic
# initial state. Don't re-run tests in parallel but limit to a
# single worker process to have side effects (on the system load
Expand All @@ -246,7 +249,6 @@ def _rerun_failed_tests(self, runtests: RunTests):
tests, match_tests_dict = self.results.prepare_rerun()

# Re-run failed tests
self.log(f"Re-running {len(tests)} failed tests in verbose mode in subprocesses")
runtests = runtests.copy(
tests=tests,
rerun=True,
Expand All @@ -256,7 +258,15 @@ def _rerun_failed_tests(self, runtests: RunTests):
match_tests_dict=match_tests_dict,
output_on_failure=False)
self.logger.set_tests(runtests)
self._run_tests_mp(runtests, self.num_workers)

msg = f"Re-running {len(tests)} failed tests in verbose mode"
if not self.sequentially:
msg = f"{msg} in subprocesses"
self.log(msg)
self._run_tests_mp(runtests, self.num_workers)
else:
self.log(msg)
self.run_tests_sequentially(runtests)
return runtests

def rerun_failed_tests(self, runtests: RunTests):
Expand Down Expand Up @@ -599,7 +609,7 @@ def _add_cross_compile_opts(self, regrtest_opts):
keep_environ = True

if cross_compile and hostrunner:
if self.num_workers == 0:
if self.num_workers == 0 and not self.sequentially:
# For now use only two cores for cross-compiled builds;
# hostrunner can be expensive.
regrtest_opts.extend(['-j', '2'])
Expand Down
6 changes: 3 additions & 3 deletions Lib/test/libregrtest/worker.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@


USE_PROCESS_GROUP = (hasattr(os, "setsid") and hasattr(os, "killpg"))
NEED_TTY = set('''
test_ioctl
'''.split())
NEED_TTY = {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not related.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, it's a follow-up of a previous PR. I didn't want to write a dedicated PR for that.

'test_ioctl',
}


def create_worker_process(runtests: WorkerRunTests, output_fd: int,
Expand Down
7 changes: 7 additions & 0 deletions Lib/test/test_regrtest.py
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,13 @@ def test_verbose3_huntrleaks(self):
self.assertEqual(regrtest.hunt_refleak.runs, 10)
self.assertFalse(regrtest.output_on_failure)

def test_sequentially(self):
args = ['-j2', '--sequentially']
with support.captured_stderr():
regrtest = self.create_regrtest(args)
self.assertEqual(regrtest.num_workers, 0)
self.assertTrue(regrtest.sequentially)


@dataclasses.dataclass(slots=True)
class Rerun:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Add ``--sequentially`` command line option to Python test runner (regrtest).
Patch by Victor Stinner.