Update libregrtest

This commit is contained in:
ShaharNaveh committed 2026-06-14 10:44:18 +03:00
1 parent 7731724637
commit cc3456b466
8 files changed
+75 -60

No files matched your search

-1
View File
@@ -1 +0,0 @@
+31 -23
View File
@@ -130,6 +130,13 @@ resources to test. Currently only the following are defined:
tzdata - Run tests that require timezone data.
xpickle - Test pickle and _pickle against Python 3.6, 3.7, 3.8
and 3.9 to test backwards compatibility. These tests
may take very long to complete.
wantobjects - Allows to run Tkinter tests with the specified value of
tkinter.wantobjects.
To enable all resources except one, use '-uall,-<resource>'. For
example, to run all the tests except for the gui tests, give the
option '-uall,-gui'.
@@ -158,7 +165,7 @@ class Namespace(argparse.Namespace):
self.randomize = False
self.fromfile = None
self.fail_env_changed = False
self.use_resources: list[str] = []
self.use_resources: dict[str, str | None] = {}
self.trace = False
self.coverdir = 'coverage'
self.runleaks = False
@@ -305,7 +312,7 @@ def _create_parser():
group.add_argument('-G', '--failfast', action='store_true',
help='fail as soon as a test fails (only with -v or -W)')
group.add_argument('-u', '--use', metavar='RES1,RES2,...',
action='append', type=resources_list,
action='extend', type=resources_list,
help='specify which special resource intensive tests '
'to run.' + more_details)
group.add_argument('-M', '--memlimit', metavar='LIMIT',
@@ -410,11 +417,18 @@ def huntrleaks(string):
def resources_list(string):
u = [x.lower() for x in string.split(',')]
for r in u:
u = []
for x in string.split(','):
r, eq, v = x.partition('=')
r = r.lower()
u.append((r, v if eq else None))
if r == 'all' or r == 'none':
if eq:
raise argparse.ArgumentTypeError('invalid resource: ' + x)
continue
if r[0] == '-':
if eq:
raise argparse.ArgumentTypeError('invalid resource: ' + x)
r = r[1:]
if r not in RESOURCE_NAMES:
raise argparse.ArgumentTypeError('invalid resource: ' + r)
@@ -482,14 +496,14 @@ def _parse_args(args, **kwargs):
# Similar to: -u "all" --timeout=1200
if ns.use is None:
ns.use = []
ns.use.insert(0, ['all'])
ns.use[:0] = [('all', None)]
if ns.timeout is None:
ns.timeout = 1200 # 20 minutes
elif ns.fast_ci:
# Similar to: -u "all,-cpu" --timeout=600
if ns.use is None:
ns.use = []
ns.use.insert(0, ['all', '-cpu'])
ns.use[:0] = [('all', None), ('-cpu', None)]
if ns.timeout is None:
ns.timeout = 600 # 10 minutes
@@ -527,23 +541,17 @@ def _parse_args(args, **kwargs):
if ns.timeout <= 0:
ns.timeout = None
if ns.use:
for a in ns.use:
for r in a:
if r == 'all':
ns.use_resources[:] = ALL_RESOURCES
continue
if r == 'none':
del ns.use_resources[:]
continue
remove = False
if r[0] == '-':
remove = True
r = r[1:]
if remove:
if r in ns.use_resources:
ns.use_resources.remove(r)
elif r not in ns.use_resources:
ns.use_resources.append(r)
for r, v in ns.use:
if r == 'all':
for r in ALL_RESOURCES:
ns.use_resources[r] = None
elif r == 'none':
ns.use_resources.clear()
elif r[0] == '-':
r = r[1:]
ns.use_resources.pop(r, None)
else:
ns.use_resources[r] = v
if ns.random_seed is not None:
ns.randomize = True
if ns.no_randomize:
+1 -1
View File
@@ -118,7 +118,7 @@ class Regrtest:
self.junit_filename: StrPath | None = ns.xmlpath
self.memory_limit: str | None = ns.memlimit
self.gc_threshold: int | None = ns.threshold
self.use_resources: tuple[str, ...] = tuple(ns.use_resources)
self.use_resources: dict[str, str | None] = dict(ns.use_resources)
if ns.python:
self.python_cmd: tuple[str, ...] | None = tuple(ns.python)
else:
+9 -2
View File
@@ -96,7 +96,7 @@ class RunTests:
coverage: bool
memory_limit: str | None
gc_threshold: int | None
use_resources: tuple[str, ...]
use_resources: dict[str, str | None]
python_cmd: tuple[str, ...] | None
randomize: bool
random_seed: int | str
@@ -179,7 +179,14 @@ class RunTests:
if self.gc_threshold:
args.append(f"--threshold={self.gc_threshold}")
if self.use_resources:
args.extend(("-u", ','.join(self.use_resources)))
simple = ','.join(resource
for resource, value in self.use_resources.items()
if value is None)
if simple:
args.extend(("-u", simple))
for resource, value in self.use_resources.items():
if value is not None:
args.extend(("-u", f"{resource}={value}"))
if self.python_cmd:
cmd = shlex.join(self.python_cmd)
args.extend(("--python", cmd))
+2 -6
View File
@@ -227,9 +227,7 @@ class saved_test_environment:
# to track reference leaks.
def get_threading__dangling(self):
# This copies the weakrefs without making any strong reference
# XXX: RUSTPYTHON - filter out dead threads since gc doesn't clean WeakSet. Revert this line when we have a GC
# return threading._dangling.copy()
return {t for t in threading._dangling if t.is_alive()}
return threading._dangling.copy()
def restore_threading__dangling(self, saved):
threading._dangling.clear()
threading._dangling.update(saved)
@@ -240,9 +238,7 @@ class saved_test_environment:
# Unjoined process objects can survive after process exits
multiprocessing_process._cleanup()
# This copies the weakrefs without making any strong reference
# TODO: RUSTPYTHON - filter out dead processes since gc doesn't clean WeakSet. Revert this line when we have a GC
# return multiprocessing_process._dangling.copy()
return {p for p in multiprocessing_process._dangling if p.is_alive()}
return multiprocessing_process._dangling.copy()
def restore_multiprocessing_process__dangling(self, saved):
multiprocessing_process = self.get_module('multiprocessing.process')
multiprocessing_process._dangling.clear()
+9 -10
View File
@@ -145,7 +145,7 @@ def regrtest_runner(result: TestResult, test_func, runtests: RunTests) -> None:
# Storage of uncollectable GC objects (gc.garbage)
GC_GARBAGE = []
GC_GARBAGE: list[object] = []
def _load_run_test(result: TestResult, runtests: RunTests) -> None:
@@ -172,16 +172,15 @@ def _load_run_test(result: TestResult, runtests: RunTests) -> None:
remove_testfn(test_name, runtests.verbose)
# XXX: RUSTPYTHON, build a functional garbage collector into the interpreter
# if gc.garbage:
# support.environment_altered = True
# print_warning(f"{test_name} created {len(gc.garbage)} "
# f"uncollectable object(s)")
if gc.garbage:
support.environment_altered = True
print_warning(f"{test_name} created {len(gc.garbage)} "
f"uncollectable object(s)")
# # move the uncollectable objects somewhere,
# # so we don't see them again
# GC_GARBAGE.extend(gc.garbage)
# gc.garbage.clear()
# move the uncollectable objects somewhere,
# so we don't see them again
GC_GARBAGE.extend(gc.garbage)
gc.garbage.clear()
support.reap_children()
+20 -17
View File
@@ -12,7 +12,7 @@ import sys
import sysconfig
import tempfile
import textwrap
from collections.abc import Callable, Iterable
from collections.abc import Callable
from test import support
from test.support import os_helper
@@ -41,7 +41,7 @@ ALL_RESOURCES = ('audio', 'console', 'curses', 'largefile', 'network',
# - tzdata: while needed to validate fully test_datetime, it makes
# test_datetime too slow (15-20 min on some buildbots) and so is disabled by
# default (see bpo-30822).
RESOURCE_NAMES = ALL_RESOURCES + ('extralargefile', 'tzdata')
RESOURCE_NAMES = ALL_RESOURCES + ('extralargefile', 'tzdata', 'xpickle', 'wantobjects')
# Types for types hints
@@ -150,7 +150,7 @@ def setup_unraisable_hook() -> None:
sys.unraisablehook = regrtest_unraisable_hook
orig_threading_excepthook: Callable[..., None] | None = None
orig_threading_excepthook: Callable[..., object] | None = None
def regrtest_threading_excepthook(args) -> None:
@@ -433,12 +433,6 @@ def get_temp_dir(tmp_dir: StrPath | None = None) -> StrPath:
f"unexpectedly returned {tmp_dir!r} on WASI"
)
tmp_dir = os.path.join(tmp_dir, 'build')
# When get_temp_dir() is called in a worker process,
# get_temp_dir() path is different than in the parent process
# which is not a WASI process. So the parent does not create
# the same "tmp_dir" than the test worker process.
os.makedirs(tmp_dir, exist_ok=True)
else:
tmp_dir = tempfile.gettempdir()
@@ -588,21 +582,30 @@ def is_cross_compiled() -> bool:
return ('_PYTHON_HOST_PLATFORM' in os.environ)
def format_resources(use_resources: Iterable[str]) -> str:
use_resources = set(use_resources)
def format_resources(use_resources: dict[str, str | None]) -> str:
all_resources = set(ALL_RESOURCES)
values = []
for name in sorted(use_resources):
if use_resources[name] is not None:
values.append(f'{name}={use_resources[name]}')
# Express resources relative to "all"
relative_all = ['all']
for name in sorted(all_resources - use_resources):
for name in sorted(all_resources - set(use_resources)):
relative_all.append(f'-{name}')
for name in sorted(use_resources - all_resources):
relative_all.append(f'{name}')
all_text = ','.join(relative_all)
for name in sorted(set(use_resources) - all_resources):
if use_resources[name] is None:
relative_all.append(name)
all_text = ','.join(relative_all + values)
all_text = f"resources: {all_text}"
# List of enabled resources
text = ','.join(sorted(use_resources))
resources = []
for name in sorted(use_resources):
if use_resources[name] is None:
resources.append(name)
text = ','.join(resources + values)
text = f"resources ({len(use_resources)}): {text}"
# Pick the shortest string (prefer relative to all if lengths are equal)
@@ -612,7 +615,7 @@ def format_resources(use_resources: Iterable[str]) -> str:
return text
def display_header(use_resources: tuple[str, ...],
def display_header(use_resources: dict[str, str | None],
python_cmd: tuple[str, ...] | None) -> None:
# Print basic platform information
print("==", platform.python_implementation(), *sys.version.split())
+3
View File
@@ -127,6 +127,9 @@ def main() -> NoReturn:
worker_json = sys.argv[1]
tmp_dir = get_temp_dir()
# get_temp_dir() can be different in the worker and the parent process.
# For example, if --tempdir option is used.
os.makedirs(tmp_dir, exist_ok=True)
work_dir = get_work_dir(tmp_dir, worker=True)
with exit_timeout():