Skip to content

Commit

Permalink
pythongh-108834: Refactor Regrtest.main()
Browse files Browse the repository at this point in the history
* main() now calls _parse_args() and pass 'ns' to Regrtest
  constructor.  Remove kwargs argument from Regrtest.main().
* _parse_args() checks ns.huntrleaks.
* set_temp_dir() is now responsible to call expanduser().
* Regrtest.main() sets self.tests earlier.
* Add TestsList type.
  • Loading branch information
vstinner committed Sep 8, 2023
1 parent 1f7e421 commit afbccd6
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 47 deletions.
9 changes: 9 additions & 0 deletions Lib/test/libregrtest/cmdline.py
Original file line number Diff line number Diff line change
Expand Up @@ -448,4 +448,13 @@ def _parse_args(args, **kwargs):
# --forever implies --failfast
ns.failfast = True

if ns.huntrleaks:
warmup, repetitions, _ = ns.huntrleaks
if warmup < 1 or repetitions < 1:
msg = ("Invalid values for the --huntrleaks/-R parameters. The "
"number of warmups and repetitions must be at least 1 "
"each (1:1).")
print(msg, file=sys.stderr, flush=True)
sys.exit(2)

return ns
84 changes: 37 additions & 47 deletions Lib/test/libregrtest/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@
import tempfile
import time
import unittest
from test.libregrtest.cmdline import _parse_args
from test.libregrtest.cmdline import _parse_args, Namespace
from test.libregrtest.runtest import (
findtests, split_test_packages, runtest, abs_module_name,
PROGRESS_MIN_TIME, State, MatchTestsDict, RunTests)
PROGRESS_MIN_TIME, State, MatchTestsDict, RunTests, TestResult)
from test.libregrtest.setup import setup_tests
from test.libregrtest.pgo import setup_pgo_tests
from test.libregrtest.utils import (strip_py_suffix, count, format_duration,
Expand All @@ -35,6 +35,9 @@
EXITCODE_INTERRUPTED = 130


TestsList = list[str]


class Regrtest:
"""Execute a test suite.
Expand All @@ -58,24 +61,24 @@ class Regrtest:
directly to set the values that would normally be set by flags
on the command line.
"""
def __init__(self):
def __init__(self, ns: Namespace):
# Namespace of command line options
self.ns = None
self.ns: Namespace = ns

# tests
self.tests = []
self.selected = []
self.all_runtests: list[RunTests] = []

# test results
self.good: list[str] = []
self.bad: list[str] = []
self.rerun_bad: list[str] = []
self.skipped: list[str] = []
self.resource_denied: list[str] = []
self.environment_changed: list[str] = []
self.run_no_tests: list[str] = []
self.rerun: list[str] = []
self.good: TestsList = []
self.bad: TestsList = []
self.rerun_bad: TestsList = []
self.skipped: TestsList = []
self.resource_denied: TestsList = []
self.environment_changed: TestsList = []
self.run_no_tests: TestsList = []
self.rerun: TestsList = []

self.need_rerun: list[TestResult] = []
self.first_state: str | None = None
Expand Down Expand Up @@ -184,29 +187,7 @@ def display_progress(self, test_index, text):
line = f"{line}/{fails}"
self.log(f"[{line}] {text}")

def parse_args(self, kwargs):
ns = _parse_args(sys.argv[1:], **kwargs)

if ns.xmlpath:
support.junit_xml_list = self.testsuite_xml = []

strip_py_suffix(ns.args)

if ns.huntrleaks:
warmup, repetitions, _ = ns.huntrleaks
if warmup < 1 or repetitions < 1:
msg = ("Invalid values for the --huntrleaks/-R parameters. The "
"number of warmups and repetitions must be at least 1 "
"each (1:1).")
print(msg, file=sys.stderr, flush=True)
sys.exit(2)

if ns.tempdir:
ns.tempdir = os.path.expanduser(ns.tempdir)

self.ns = ns

def find_tests(self, tests):
def find_tests(self):
ns = self.ns
single = ns.single
fromfile = ns.fromfile
Expand All @@ -216,8 +197,6 @@ def find_tests(self, tests):
starting_test = ns.start
randomize = ns.randomize

self.tests = tests

if single:
self.next_single_filename = os.path.join(self.tmp_dir, 'pynexttest')
try:
Expand Down Expand Up @@ -737,8 +716,12 @@ def fix_umask(self):
os.umask(old_mask)

def set_temp_dir(self):
if self.ns.tempdir:
self.tmp_dir = self.ns.tempdir
ns = self.ns
if ns.tempdir:
ns.tempdir = os.path.expanduser(ns.tempdir)

if ns.tempdir:
self.tmp_dir = ns.tempdir

if not self.tmp_dir:
# When tests are run from the Python build directory, it is best practice
Expand Down Expand Up @@ -795,14 +778,20 @@ def cleanup(self):
print("Remove file: %s" % name)
os_helper.unlink(name)

def main(self, tests=None, **kwargs):
self.parse_args(kwargs)
def main(self, tests: TestsList | None = None):
ns = self.ns
self.tests = tests

if ns.xmlpath:
support.junit_xml_list = self.testsuite_xml = []

strip_py_suffix(ns.args)

self.set_temp_dir()

self.fix_umask()

if self.ns.cleanup:
if ns.cleanup:
self.cleanup()
sys.exit(0)

Expand All @@ -817,9 +806,9 @@ def main(self, tests=None, **kwargs):
# When using multiprocessing, worker processes will use test_cwd
# as their parent temporary directory. So when the main process
# exit, it removes also subdirectories of worker processes.
self.ns.tempdir = test_cwd
ns.tempdir = test_cwd

self._main(tests, kwargs)
self._main()
except SystemExit as exc:
# bpo-38203: Python can hang at exit in Py_Finalize(), especially
# on threading._shutdown() call: put a timeout
Expand Down Expand Up @@ -862,7 +851,7 @@ def action_run_tests(self):
self.display_summary()
self.finalize()

def _main(self, tests, kwargs):
def _main(self):
if self.is_worker():
from test.libregrtest.runtest_mp import run_tests_worker
run_tests_worker(self.ns.worker_args)
Expand All @@ -872,7 +861,7 @@ def _main(self, tests, kwargs):
input("Press any key to continue...")

setup_tests(self.ns)
self.find_tests(tests)
self.find_tests()

exitcode = 0
if self.ns.list_tests:
Expand All @@ -888,4 +877,5 @@ def _main(self, tests, kwargs):

def main(tests=None, **kwargs):
"""Run the Python suite."""
Regrtest().main(tests=tests, **kwargs)
ns = _parse_args(sys.argv[1:], **kwargs)
Regrtest(ns).main(tests=tests)

0 comments on commit afbccd6

Please sign in to comment.