mirror of
https://github.com/python/cpython.git
synced 2025-11-28 14:11:15 +00:00
gh-109276: libregrtest: fix worker working dir (#109313)
Fix Emscripten and WASI: start the test worker process in the Python source code directory, where 'python.js' and 'python.wasm' can be found. Then worker_process() changes to a temporary directory created to run tests. * create_worker_process() uses os_helper.SAVEDCWD as cwd. * worker_process() uses get_temp_dir() as the parent directory for get_work_dir(). * Don't use plural but singual for "test" in "Run 1 test ..." message. * Remove unused imports. * Add WORK_DIR_PREFIX and WORKER_WORK_DIR_PREFIX constants.
This commit is contained in:
parent
8b55adfa8f
commit
d13f782a18
4 changed files with 24 additions and 16 deletions
|
|
@ -297,7 +297,7 @@ class Regrtest:
|
||||||
|
|
||||||
jobs = runtests.get_jobs()
|
jobs = runtests.get_jobs()
|
||||||
if jobs is not None:
|
if jobs is not None:
|
||||||
tests = f'{jobs} tests'
|
tests = count(jobs, 'test')
|
||||||
else:
|
else:
|
||||||
tests = 'tests'
|
tests = 'tests'
|
||||||
msg = f"Run {tests} sequentially"
|
msg = f"Run {tests} sequentially"
|
||||||
|
|
@ -458,7 +458,7 @@ class Regrtest:
|
||||||
|
|
||||||
def run_tests(self, selected: TestTuple, tests: TestList | None) -> int:
|
def run_tests(self, selected: TestTuple, tests: TestList | None) -> int:
|
||||||
os.makedirs(self.tmp_dir, exist_ok=True)
|
os.makedirs(self.tmp_dir, exist_ok=True)
|
||||||
work_dir = get_work_dir(parent_dir=self.tmp_dir)
|
work_dir = get_work_dir(self.tmp_dir)
|
||||||
|
|
||||||
# Put a timeout on Python exit
|
# Put a timeout on Python exit
|
||||||
with exit_timeout():
|
with exit_timeout():
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ import tempfile
|
||||||
import threading
|
import threading
|
||||||
import time
|
import time
|
||||||
import traceback
|
import traceback
|
||||||
from typing import Literal, TextIO
|
from typing import Literal
|
||||||
|
|
||||||
from test import support
|
from test import support
|
||||||
from test.support import os_helper
|
from test.support import os_helper
|
||||||
|
|
@ -21,7 +21,7 @@ from .runtests import RunTests
|
||||||
from .single import PROGRESS_MIN_TIME
|
from .single import PROGRESS_MIN_TIME
|
||||||
from .utils import (
|
from .utils import (
|
||||||
StrPath, StrJSON, TestName, MS_WINDOWS,
|
StrPath, StrJSON, TestName, MS_WINDOWS,
|
||||||
format_duration, print_warning, plural)
|
format_duration, print_warning, count, plural)
|
||||||
from .worker import create_worker_process, USE_PROCESS_GROUP
|
from .worker import create_worker_process, USE_PROCESS_GROUP
|
||||||
|
|
||||||
if MS_WINDOWS:
|
if MS_WINDOWS:
|
||||||
|
|
@ -280,7 +280,7 @@ class WorkerThread(threading.Thread):
|
||||||
if worker_json:
|
if worker_json:
|
||||||
result = TestResult.from_json(worker_json)
|
result = TestResult.from_json(worker_json)
|
||||||
else:
|
else:
|
||||||
err_msg = f"empty JSON"
|
err_msg = "empty JSON"
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
# gh-101634: Catch UnicodeDecodeError if stdout cannot be
|
# gh-101634: Catch UnicodeDecodeError if stdout cannot be
|
||||||
# decoded from encoding
|
# decoded from encoding
|
||||||
|
|
@ -412,7 +412,7 @@ class RunWorkers:
|
||||||
for index in range(1, self.num_workers + 1)]
|
for index in range(1, self.num_workers + 1)]
|
||||||
jobs = self.runtests.get_jobs()
|
jobs = self.runtests.get_jobs()
|
||||||
if jobs is not None:
|
if jobs is not None:
|
||||||
tests = f'{jobs} tests'
|
tests = count(jobs, 'test')
|
||||||
else:
|
else:
|
||||||
tests = 'tests'
|
tests = 'tests'
|
||||||
nworkers = len(self.workers)
|
nworkers = len(self.workers)
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,8 @@ from test.support import threading_helper
|
||||||
|
|
||||||
|
|
||||||
MS_WINDOWS = (sys.platform == 'win32')
|
MS_WINDOWS = (sys.platform == 'win32')
|
||||||
|
WORK_DIR_PREFIX = 'test_python_'
|
||||||
|
WORKER_WORK_DIR_PREFIX = f'{WORK_DIR_PREFIX}worker_'
|
||||||
|
|
||||||
# bpo-38203: Maximum delay in seconds to exit Python (call Py_Finalize()).
|
# bpo-38203: Maximum delay in seconds to exit Python (call Py_Finalize()).
|
||||||
# Used to protect against threading._shutdown() hang.
|
# Used to protect against threading._shutdown() hang.
|
||||||
|
|
@ -346,7 +348,7 @@ def get_build_info():
|
||||||
return build
|
return build
|
||||||
|
|
||||||
|
|
||||||
def get_temp_dir(tmp_dir):
|
def get_temp_dir(tmp_dir: StrPath | None = None) -> StrPath:
|
||||||
if tmp_dir:
|
if tmp_dir:
|
||||||
tmp_dir = os.path.expanduser(tmp_dir)
|
tmp_dir = os.path.expanduser(tmp_dir)
|
||||||
else:
|
else:
|
||||||
|
|
@ -379,7 +381,7 @@ def fix_umask():
|
||||||
os.umask(old_mask)
|
os.umask(old_mask)
|
||||||
|
|
||||||
|
|
||||||
def get_work_dir(*, parent_dir: StrPath = '', worker: bool = False):
|
def get_work_dir(parent_dir: StrPath, worker: bool = False) -> StrPath:
|
||||||
# Define a writable temp dir that will be used as cwd while running
|
# Define a writable temp dir that will be used as cwd while running
|
||||||
# the tests. The name of the dir includes the pid to allow parallel
|
# the tests. The name of the dir includes the pid to allow parallel
|
||||||
# testing (see the -j option).
|
# testing (see the -j option).
|
||||||
|
|
@ -391,11 +393,10 @@ def get_work_dir(*, parent_dir: StrPath = '', worker: bool = False):
|
||||||
nounce = os.getpid()
|
nounce = os.getpid()
|
||||||
|
|
||||||
if worker:
|
if worker:
|
||||||
work_dir = 'test_python_worker_{}'.format(nounce)
|
work_dir = WORK_DIR_PREFIX + str(nounce)
|
||||||
else:
|
else:
|
||||||
work_dir = 'test_python_{}'.format(nounce)
|
work_dir = WORKER_WORK_DIR_PREFIX + str(nounce)
|
||||||
work_dir += os_helper.FS_NONASCII
|
work_dir += os_helper.FS_NONASCII
|
||||||
if parent_dir:
|
|
||||||
work_dir = os.path.join(parent_dir, work_dir)
|
work_dir = os.path.join(parent_dir, work_dir)
|
||||||
return work_dir
|
return work_dir
|
||||||
|
|
||||||
|
|
@ -579,7 +580,7 @@ def display_header():
|
||||||
def cleanup_temp_dir(tmp_dir: StrPath):
|
def cleanup_temp_dir(tmp_dir: StrPath):
|
||||||
import glob
|
import glob
|
||||||
|
|
||||||
path = os.path.join(glob.escape(tmp_dir), 'test_python_*')
|
path = os.path.join(glob.escape(tmp_dir), WORK_DIR_PREFIX + '*')
|
||||||
print("Cleanup %s directory" % tmp_dir)
|
print("Cleanup %s directory" % tmp_dir)
|
||||||
for name in glob.glob(path):
|
for name in glob.glob(path):
|
||||||
if os.path.isdir(name):
|
if os.path.isdir(name):
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
from typing import TextIO, NoReturn
|
from typing import NoReturn
|
||||||
|
|
||||||
from test import support
|
from test import support
|
||||||
from test.support import os_helper
|
from test.support import os_helper
|
||||||
|
|
@ -11,7 +11,7 @@ from .runtests import RunTests
|
||||||
from .single import run_single_test
|
from .single import run_single_test
|
||||||
from .utils import (
|
from .utils import (
|
||||||
StrPath, StrJSON, FilterTuple, MS_WINDOWS,
|
StrPath, StrJSON, FilterTuple, MS_WINDOWS,
|
||||||
get_work_dir, exit_timeout)
|
get_temp_dir, get_work_dir, exit_timeout)
|
||||||
|
|
||||||
|
|
||||||
USE_PROCESS_GROUP = (hasattr(os, "setsid") and hasattr(os, "killpg"))
|
USE_PROCESS_GROUP = (hasattr(os, "setsid") and hasattr(os, "killpg"))
|
||||||
|
|
@ -38,6 +38,11 @@ def create_worker_process(runtests: RunTests,
|
||||||
env['TEMP'] = tmp_dir
|
env['TEMP'] = tmp_dir
|
||||||
env['TMP'] = tmp_dir
|
env['TMP'] = tmp_dir
|
||||||
|
|
||||||
|
# Emscripten and WASI Python must start in the Python source code directory
|
||||||
|
# to get 'python.js' or 'python.wasm' file. Then worker_process() changes
|
||||||
|
# to a temporary directory created to run tests.
|
||||||
|
work_dir = os_helper.SAVEDCWD
|
||||||
|
|
||||||
# Running the child from the same working directory as regrtest's original
|
# Running the child from the same working directory as regrtest's original
|
||||||
# invocation ensures that TEMPDIR for the child is the same when
|
# invocation ensures that TEMPDIR for the child is the same when
|
||||||
# sysconfig.is_python_build() is true. See issue 15300.
|
# sysconfig.is_python_build() is true. See issue 15300.
|
||||||
|
|
@ -48,6 +53,7 @@ def create_worker_process(runtests: RunTests,
|
||||||
stderr=output_fd,
|
stderr=output_fd,
|
||||||
text=True,
|
text=True,
|
||||||
close_fds=True,
|
close_fds=True,
|
||||||
|
cwd=work_dir,
|
||||||
)
|
)
|
||||||
if not MS_WINDOWS:
|
if not MS_WINDOWS:
|
||||||
kwargs['pass_fds'] = [json_fd]
|
kwargs['pass_fds'] = [json_fd]
|
||||||
|
|
@ -102,7 +108,8 @@ def main():
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
worker_json = sys.argv[1]
|
worker_json = sys.argv[1]
|
||||||
|
|
||||||
work_dir = get_work_dir(worker=True)
|
tmp_dir = get_temp_dir()
|
||||||
|
work_dir = get_work_dir(tmp_dir, worker=True)
|
||||||
|
|
||||||
with exit_timeout():
|
with exit_timeout():
|
||||||
with os_helper.temp_cwd(work_dir, quiet=True):
|
with os_helper.temp_cwd(work_dir, quiet=True):
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue