mirror of https://github.com/python/cpython.git
gh-109413: regrtest: add WorkerRunTests class (#112588)
This commit is contained in:
parent
058444308a
commit
f8ff80f635
|
@ -423,7 +423,6 @@ def create_run_tests(self, tests: TestTuple):
|
||||||
python_cmd=self.python_cmd,
|
python_cmd=self.python_cmd,
|
||||||
randomize=self.randomize,
|
randomize=self.randomize,
|
||||||
random_seed=self.random_seed,
|
random_seed=self.random_seed,
|
||||||
json_file=None,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def _run_tests(self, selected: TestTuple, tests: TestList | None) -> int:
|
def _run_tests(self, selected: TestTuple, tests: TestList | None) -> int:
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
from .logger import Logger
|
from .logger import Logger
|
||||||
from .result import TestResult, State
|
from .result import TestResult, State
|
||||||
from .results import TestResults
|
from .results import TestResults
|
||||||
from .runtests import RunTests, JsonFile, JsonFileType
|
from .runtests import RunTests, WorkerRunTests, JsonFile, JsonFileType
|
||||||
from .single import PROGRESS_MIN_TIME
|
from .single import PROGRESS_MIN_TIME
|
||||||
from .utils import (
|
from .utils import (
|
||||||
StrPath, TestName,
|
StrPath, TestName,
|
||||||
|
@ -162,7 +162,7 @@ def stop(self) -> None:
|
||||||
self._stopped = True
|
self._stopped = True
|
||||||
self._kill()
|
self._kill()
|
||||||
|
|
||||||
def _run_process(self, runtests: RunTests, output_fd: int,
|
def _run_process(self, runtests: WorkerRunTests, output_fd: int,
|
||||||
tmp_dir: StrPath | None = None) -> int | None:
|
tmp_dir: StrPath | None = None) -> int | None:
|
||||||
popen = create_worker_process(runtests, output_fd, tmp_dir)
|
popen = create_worker_process(runtests, output_fd, tmp_dir)
|
||||||
self._popen = popen
|
self._popen = popen
|
||||||
|
@ -252,9 +252,7 @@ def create_json_file(self, stack: contextlib.ExitStack) -> tuple[JsonFile, TextI
|
||||||
json_file = JsonFile(json_fd, JsonFileType.UNIX_FD)
|
json_file = JsonFile(json_fd, JsonFileType.UNIX_FD)
|
||||||
return (json_file, json_tmpfile)
|
return (json_file, json_tmpfile)
|
||||||
|
|
||||||
def create_worker_runtests(self, test_name: TestName, json_file: JsonFile) -> RunTests:
|
def create_worker_runtests(self, test_name: TestName, json_file: JsonFile) -> WorkerRunTests:
|
||||||
"""Create the worker RunTests."""
|
|
||||||
|
|
||||||
tests = (test_name,)
|
tests = (test_name,)
|
||||||
if self.runtests.rerun:
|
if self.runtests.rerun:
|
||||||
match_tests = self.runtests.get_match_tests(test_name)
|
match_tests = self.runtests.get_match_tests(test_name)
|
||||||
|
@ -267,12 +265,12 @@ def create_worker_runtests(self, test_name: TestName, json_file: JsonFile) -> Ru
|
||||||
if self.runtests.output_on_failure:
|
if self.runtests.output_on_failure:
|
||||||
kwargs['verbose'] = True
|
kwargs['verbose'] = True
|
||||||
kwargs['output_on_failure'] = False
|
kwargs['output_on_failure'] = False
|
||||||
return self.runtests.copy(
|
return self.runtests.create_worker_runtests(
|
||||||
tests=tests,
|
tests=tests,
|
||||||
json_file=json_file,
|
json_file=json_file,
|
||||||
**kwargs)
|
**kwargs)
|
||||||
|
|
||||||
def run_tmp_files(self, worker_runtests: RunTests,
|
def run_tmp_files(self, worker_runtests: WorkerRunTests,
|
||||||
stdout_fd: int) -> tuple[int | None, list[StrPath]]:
|
stdout_fd: int) -> tuple[int | None, list[StrPath]]:
|
||||||
# gh-93353: Check for leaked temporary files in the parent process,
|
# gh-93353: Check for leaked temporary files in the parent process,
|
||||||
# since the deletion of temporary files can happen late during
|
# since the deletion of temporary files can happen late during
|
||||||
|
|
|
@ -93,13 +93,17 @@ class RunTests:
|
||||||
python_cmd: tuple[str, ...] | None
|
python_cmd: tuple[str, ...] | None
|
||||||
randomize: bool
|
randomize: bool
|
||||||
random_seed: int | str
|
random_seed: int | str
|
||||||
json_file: JsonFile | None
|
|
||||||
|
|
||||||
def copy(self, **override):
|
def copy(self, **override) -> 'RunTests':
|
||||||
state = dataclasses.asdict(self)
|
state = dataclasses.asdict(self)
|
||||||
state.update(override)
|
state.update(override)
|
||||||
return RunTests(**state)
|
return RunTests(**state)
|
||||||
|
|
||||||
|
def create_worker_runtests(self, **override):
|
||||||
|
state = dataclasses.asdict(self)
|
||||||
|
state.update(override)
|
||||||
|
return WorkerRunTests(**state)
|
||||||
|
|
||||||
def get_match_tests(self, test_name) -> FilterTuple | None:
|
def get_match_tests(self, test_name) -> FilterTuple | None:
|
||||||
if self.match_tests_dict is not None:
|
if self.match_tests_dict is not None:
|
||||||
return self.match_tests_dict.get(test_name, None)
|
return self.match_tests_dict.get(test_name, None)
|
||||||
|
@ -120,13 +124,6 @@ def iter_tests(self):
|
||||||
else:
|
else:
|
||||||
yield from self.tests
|
yield from self.tests
|
||||||
|
|
||||||
def as_json(self) -> StrJSON:
|
|
||||||
return json.dumps(self, cls=_EncodeRunTests)
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def from_json(worker_json: StrJSON) -> 'RunTests':
|
|
||||||
return json.loads(worker_json, object_hook=_decode_runtests)
|
|
||||||
|
|
||||||
def json_file_use_stdout(self) -> bool:
|
def json_file_use_stdout(self) -> bool:
|
||||||
# Use STDOUT in two cases:
|
# Use STDOUT in two cases:
|
||||||
#
|
#
|
||||||
|
@ -141,9 +138,21 @@ def json_file_use_stdout(self) -> bool:
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@dataclasses.dataclass(slots=True, frozen=True)
|
||||||
|
class WorkerRunTests(RunTests):
|
||||||
|
json_file: JsonFile
|
||||||
|
|
||||||
|
def as_json(self) -> StrJSON:
|
||||||
|
return json.dumps(self, cls=_EncodeRunTests)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def from_json(worker_json: StrJSON) -> 'WorkerRunTests':
|
||||||
|
return json.loads(worker_json, object_hook=_decode_runtests)
|
||||||
|
|
||||||
|
|
||||||
class _EncodeRunTests(json.JSONEncoder):
|
class _EncodeRunTests(json.JSONEncoder):
|
||||||
def default(self, o: Any) -> dict[str, Any]:
|
def default(self, o: Any) -> dict[str, Any]:
|
||||||
if isinstance(o, RunTests):
|
if isinstance(o, WorkerRunTests):
|
||||||
result = dataclasses.asdict(o)
|
result = dataclasses.asdict(o)
|
||||||
result["__runtests__"] = True
|
result["__runtests__"] = True
|
||||||
return result
|
return result
|
||||||
|
@ -158,6 +167,6 @@ def _decode_runtests(data: dict[str, Any]) -> RunTests | dict[str, Any]:
|
||||||
data['hunt_refleak'] = HuntRefleak(**data['hunt_refleak'])
|
data['hunt_refleak'] = HuntRefleak(**data['hunt_refleak'])
|
||||||
if data['json_file']:
|
if data['json_file']:
|
||||||
data['json_file'] = JsonFile(**data['json_file'])
|
data['json_file'] = JsonFile(**data['json_file'])
|
||||||
return RunTests(**data)
|
return WorkerRunTests(**data)
|
||||||
else:
|
else:
|
||||||
return data
|
return data
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
from test.support import os_helper, Py_DEBUG
|
from test.support import os_helper, Py_DEBUG
|
||||||
|
|
||||||
from .setup import setup_process, setup_test_dir
|
from .setup import setup_process, setup_test_dir
|
||||||
from .runtests import RunTests, JsonFile, JsonFileType
|
from .runtests import WorkerRunTests, JsonFile, JsonFileType
|
||||||
from .single import run_single_test
|
from .single import run_single_test
|
||||||
from .utils import (
|
from .utils import (
|
||||||
StrPath, StrJSON, TestFilter,
|
StrPath, StrJSON, TestFilter,
|
||||||
|
@ -17,7 +17,7 @@
|
||||||
USE_PROCESS_GROUP = (hasattr(os, "setsid") and hasattr(os, "killpg"))
|
USE_PROCESS_GROUP = (hasattr(os, "setsid") and hasattr(os, "killpg"))
|
||||||
|
|
||||||
|
|
||||||
def create_worker_process(runtests: RunTests, output_fd: int,
|
def create_worker_process(runtests: WorkerRunTests, output_fd: int,
|
||||||
tmp_dir: StrPath | None = None) -> subprocess.Popen:
|
tmp_dir: StrPath | None = None) -> subprocess.Popen:
|
||||||
python_cmd = runtests.python_cmd
|
python_cmd = runtests.python_cmd
|
||||||
worker_json = runtests.as_json()
|
worker_json = runtests.as_json()
|
||||||
|
@ -73,7 +73,7 @@ def create_worker_process(runtests: RunTests, output_fd: int,
|
||||||
|
|
||||||
|
|
||||||
def worker_process(worker_json: StrJSON) -> NoReturn:
|
def worker_process(worker_json: StrJSON) -> NoReturn:
|
||||||
runtests = RunTests.from_json(worker_json)
|
runtests = WorkerRunTests.from_json(worker_json)
|
||||||
test_name = runtests.tests[0]
|
test_name = runtests.tests[0]
|
||||||
match_tests: TestFilter = runtests.match_tests
|
match_tests: TestFilter = runtests.match_tests
|
||||||
json_file: JsonFile = runtests.json_file
|
json_file: JsonFile = runtests.json_file
|
||||||
|
|
Loading…
Reference in New Issue