Skip to content

Commit cd4bf78

Browse files
committed
gh-110152: regrtest handles cross compilation and HOSTRUNNER
* _add_python_opts() now handles cross compilation and HOSTRUNNER. * display_header() now tells if Python is cross-compiled, display HOSTRUNNER, and get the host platform. * Remove Tools/scripts/run_tests.py script. * Remove "make hostrunnertest": use "make buildbottest" or "make test" instead.
1 parent 0def8c7 commit cd4bf78

File tree

6 files changed

+126
-110
lines changed

6 files changed

+126
-110
lines changed

Lib/test/libregrtest/main.py

Lines changed: 83 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import re
44
import shlex
55
import sys
6+
import sysconfig
67
import time
78

89
from test import support
@@ -22,6 +23,7 @@
2223
strip_py_suffix, count, format_duration,
2324
printlist, get_temp_dir, get_work_dir, exit_timeout,
2425
display_header, cleanup_temp_dir, print_warning,
26+
is_cross_compiled, get_host_runner,
2527
MS_WINDOWS, EXIT_TIMEOUT)
2628

2729

@@ -71,10 +73,9 @@ def __init__(self, ns: Namespace, _add_python_opts: bool = False):
7173
self.want_rerun: bool = ns.rerun
7274
self.want_run_leaks: bool = ns.runleaks
7375

74-
ci_mode = (ns.fast_ci or ns.slow_ci)
76+
self.ci_mode: bool = (ns.fast_ci or ns.slow_ci)
7577
self.want_add_python_opts: bool = (_add_python_opts
76-
and ns._add_python_opts
77-
and ci_mode)
78+
and ns._add_python_opts)
7879

7980
# Select tests
8081
if ns.match_tests:
@@ -431,7 +432,7 @@ def _run_tests(self, selected: TestTuple, tests: TestList | None) -> int:
431432
if (self.want_header
432433
or not(self.pgo or self.quiet or self.single_test_run
433434
or tests or self.cmdline_args)):
434-
display_header(self.use_resources)
435+
display_header(self.use_resources, self.python_cmd)
435436

436437
if self.randomize:
437438
print("Using random seed", self.random_seed)
@@ -489,8 +490,56 @@ def run_tests(self, selected: TestTuple, tests: TestList | None) -> int:
489490
# processes.
490491
return self._run_tests(selected, tests)
491492

492-
def _add_python_opts(self):
493-
python_opts = []
493+
def _add_cross_compile_opts(self, regrtest_opts):
494+
# WASM/WASI buildbot builders pass multiple PYTHON environment
495+
# variables such as PYTHONPATH and _PYTHON_HOSTRUNNER.
496+
keep_environ = bool(self.python_cmd)
497+
environ = None
498+
499+
# Are we using cross-compilation?
500+
cross_compile = is_cross_compiled()
501+
502+
# Get HOSTRUNNER
503+
hostrunner = get_host_runner()
504+
505+
if cross_compile:
506+
# emulate -E, but keep PYTHONPATH + cross compile env vars,
507+
# so test executable can load correct sysconfigdata file.
508+
keep = {
509+
'_PYTHON_PROJECT_BASE',
510+
'_PYTHON_HOST_PLATFORM',
511+
'_PYTHON_SYSCONFIGDATA_NAME',
512+
'PYTHONPATH'
513+
}
514+
old_environ = os.environ
515+
new_environ = {
516+
name: value for name, value in os.environ.items()
517+
if not name.startswith(('PYTHON', '_PYTHON')) or name in keep
518+
}
519+
# Only set environ if at least one variable was removed
520+
if new_environ != old_environ:
521+
environ = new_environ
522+
keep_environ = True
523+
524+
if cross_compile and hostrunner:
525+
if self.num_workers == 0:
526+
# For now use only two cores for cross-compiled builds;
527+
# hostrunner can be expensive.
528+
regrtest_opts.extend(['-j', '2'])
529+
530+
# If HOSTRUNNER is set and -p/--python option is not given, then
531+
# use hostrunner to execute python binary for tests.
532+
if not self.python_cmd:
533+
buildpython = sysconfig.get_config_var("BUILDPYTHON")
534+
python_cmd = f"{hostrunner} {buildpython}"
535+
regrtest_opts.extend(["--python", python_cmd])
536+
keep_environ = True
537+
538+
return (environ, keep_environ)
539+
540+
def _add_ci_python_opts(self, python_opts, keep_environ):
541+
# --fast-ci and --slow-ci add options to Python:
542+
# "-u -W default -bb -E"
494543

495544
# Unbuffered stdout and stderr
496545
if not sys.stdout.write_through:
@@ -504,32 +553,27 @@ def _add_python_opts(self):
504553
if sys.flags.bytes_warning < 2:
505554
python_opts.append('-bb')
506555

507-
# WASM/WASI buildbot builders pass multiple PYTHON environment
508-
# variables such as PYTHONPATH and _PYTHON_HOSTRUNNER.
509-
if not self.python_cmd:
556+
if not keep_environ:
510557
# Ignore PYTHON* environment variables
511558
if not sys.flags.ignore_environment:
512559
python_opts.append('-E')
513560

514-
if not python_opts:
515-
return
516-
517-
cmd = [*sys.orig_argv, "--dont-add-python-opts"]
518-
cmd[1:1] = python_opts
519-
561+
def _execute_python(self, cmd, environ):
520562
# Make sure that messages before execv() are logged
521563
sys.stdout.flush()
522564
sys.stderr.flush()
523565

524566
cmd_text = shlex.join(cmd)
525567
try:
568+
print(f"+ {cmd_text}", flush=True)
569+
526570
if hasattr(os, 'execv') and not MS_WINDOWS:
527571
os.execv(cmd[0], cmd)
528572
# On success, execv() do no return.
529573
# On error, it raises an OSError.
530574
else:
531575
import subprocess
532-
with subprocess.Popen(cmd) as proc:
576+
with subprocess.Popen(cmd, env=environ) as proc:
533577
try:
534578
proc.wait()
535579
except KeyboardInterrupt:
@@ -548,6 +592,29 @@ def _add_python_opts(self):
548592
f"Command: {cmd_text}")
549593
# continue executing main()
550594

595+
def _add_python_opts(self):
596+
python_opts = []
597+
regrtest_opts = []
598+
599+
environ, keep_environ = self._add_cross_compile_opts(regrtest_opts)
600+
if self.ci_mode:
601+
self._add_ci_python_opts(python_opts, keep_environ)
602+
603+
if (not python_opts) and (not regrtest_opts) and (environ is None):
604+
# Nothing changed: nothing to do
605+
print("NOTHING TO DO")
606+
return
607+
608+
# Create new command line
609+
cmd = list(sys.orig_argv)
610+
if python_opts:
611+
cmd[1:1] = python_opts
612+
if regrtest_opts:
613+
cmd.extend(regrtest_opts)
614+
cmd.append("--dont-add-python-opts")
615+
616+
self._execute_python(cmd, environ)
617+
551618
def _init(self):
552619
# Set sys.stdout encoder error handler to backslashreplace,
553620
# similar to sys.stderr error handler, to avoid UnicodeEncodeError

Lib/test/libregrtest/utils.py

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
import os.path
66
import platform
77
import random
8+
import shlex
9+
import subprocess
810
import sys
911
import sysconfig
1012
import tempfile
@@ -522,7 +524,18 @@ def adjust_rlimit_nofile():
522524
f"{new_fd_limit}: {err}.")
523525

524526

525-
def display_header(use_resources: tuple[str, ...]):
527+
def get_host_runner():
528+
if (hostrunner := os.environ.get("_PYTHON_HOSTRUNNER")) is None:
529+
hostrunner = sysconfig.get_config_var("HOSTRUNNER")
530+
return hostrunner
531+
532+
533+
def is_cross_compiled():
534+
return ('_PYTHON_HOST_PLATFORM' in os.environ)
535+
536+
537+
def display_header(use_resources: tuple[str, ...],
538+
python_cmd: tuple[str, ...] | None):
526539
# Print basic platform information
527540
print("==", platform.python_implementation(), *sys.version.split())
528541
print("==", platform.platform(aliased=True),
@@ -536,13 +549,35 @@ def display_header(use_resources: tuple[str, ...]):
536549
print("== encodings: locale=%s, FS=%s"
537550
% (locale.getencoding(), sys.getfilesystemencoding()))
538551

539-
540552
if use_resources:
541553
print(f"== resources ({len(use_resources)}): "
542554
f"{', '.join(sorted(use_resources))}")
543555
else:
544556
print("== resources: (all disabled, use -u option)")
545557

558+
cross_compile = is_cross_compiled()
559+
if cross_compile:
560+
print("== cross compiled: Yes")
561+
if python_cmd:
562+
cmd = shlex.join(python_cmd)
563+
print(f"== host python: {cmd}")
564+
565+
get_cmd = [*python_cmd, '-m', 'platform']
566+
proc = subprocess.run(
567+
get_cmd,
568+
stdout=subprocess.PIPE,
569+
text=True,
570+
cwd=os_helper.SAVEDCWD)
571+
stdout = proc.stdout.replace('\n', ' ').strip()
572+
if stdout:
573+
print(f"== host platform: {stdout}")
574+
elif proc.returncode:
575+
print(f"== host platform: <command failed with exit code {proc.returncode}>")
576+
else:
577+
hostrunner = get_host_runner()
578+
if hostrunner:
579+
print(f"== host runner: {hostrunner}")
580+
546581
# This makes it easier to remember what to set in your local
547582
# environment when trying to reproduce a sanitizer failure.
548583
asan = support.check_sanitizer(address=True)

Lib/test/test_regrtest.py

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -787,14 +787,6 @@ def test_script_autotest(self):
787787
args = [*self.python_args, script, *self.regrtest_args, *self.tests]
788788
self.run_tests(args)
789789

790-
@unittest.skipUnless(sysconfig.is_python_build(),
791-
'run_tests.py script is not installed')
792-
def test_tools_script_run_tests(self):
793-
# Tools/scripts/run_tests.py
794-
script = os.path.join(ROOT_DIR, 'Tools', 'scripts', 'run_tests.py')
795-
args = [script, *self.regrtest_args, *self.tests]
796-
self.run_tests(args)
797-
798790
def run_batch(self, *args):
799791
proc = self.run_command(args)
800792
self.check_output(proc.stdout)

Makefile.pre.in

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1837,7 +1837,7 @@ $(LIBRARY_OBJS) $(MODOBJS) Programs/python.o: $(PYTHON_HEADERS)
18371837

18381838
TESTOPTS= $(EXTRATESTOPTS)
18391839
TESTPYTHON= $(RUNSHARED) $(PYTHON_FOR_BUILD) $(TESTPYTHONOPTS)
1840-
TESTRUNNER= $(TESTPYTHON) $(srcdir)/Tools/scripts/run_tests.py
1840+
TESTRUNNER= $(TESTPYTHON) -m test
18411841
TESTTIMEOUT=
18421842

18431843
# Remove "test_python_*" directories of previous failed test jobs.
@@ -1875,11 +1875,6 @@ buildbottest: all
18751875
fi
18761876
$(TESTRUNNER) --slow-ci --timeout=$(TESTTIMEOUT) $(TESTOPTS)
18771877

1878-
# Like buildbottest, but run Python tests with HOSTRUNNER directly.
1879-
.PHONY: hostrunnertest
1880-
hostrunnertest: all
1881-
$(RUNSHARED) $(HOSTRUNNER) ./$(BUILDPYTHON) -m test --slow-ci --timeout=$(TESTTIMEOUT) $(TESTOPTS)
1882-
18831878
.PHONY: pythoninfo
18841879
pythoninfo: all
18851880
$(RUNSHARED) $(HOSTRUNNER) ./$(BUILDPYTHON) -m test.pythoninfo
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Remove ``Tools/scripts/run_tests.py`` and ``make hostrunnertest``. Just run
2+
``./python -m test --slow-ci``, ``make buildbottest`` or ``make test`` instead.
3+
Python test runner (regrtest) now handles cross-compilation and HOSTRUNNER. It
4+
also adds options to Python such fast ``-u -E -W default -bb`` when
5+
``--fast-ci`` or ``--slow-ci`` option is used. Patch by Victor Stinner.

Tools/scripts/run_tests.py

Lines changed: 0 additions & 78 deletions
This file was deleted.

0 commit comments

Comments
 (0)