mirror of
https://github.com/kovidgoyal/kitty.git
synced 2026-10-13 01:40:20 +00:00
Test suite: Fix small numbers of Python tests being run in incorrect environment
Some checks are pending
CI / Linux (python=3.14 cc=clang sanitize=1) (push) Waiting to run
CI / Linux (python=3.12 cc=gcc sanitize=0) (push) Waiting to run
CI / Linux (python=3.13 cc=gcc sanitize=1) (push) Waiting to run
CI / Linux package (push) Waiting to run
CI / Bundle test (macos-latest) (push) Waiting to run
CI / Bundle test (ubuntu-latest) (push) Waiting to run
CI / macOS Brew (push) Waiting to run
CI / Test ./dev.sh and benchmark (push) Waiting to run
CodeQL / CodeQL-Build (actions, ubuntu-latest) (push) Waiting to run
CodeQL / CodeQL-Build (c, macos-latest) (push) Waiting to run
CodeQL / CodeQL-Build (c, ubuntu-latest) (push) Waiting to run
CodeQL / CodeQL-Build (go, ubuntu-latest) (push) Waiting to run
CodeQL / CodeQL-Build (python, ubuntu-latest) (push) Waiting to run
Depscan / Scan dependencies for vulnerabilities (push) Waiting to run
Some checks are pending
CI / Linux (python=3.14 cc=clang sanitize=1) (push) Waiting to run
CI / Linux (python=3.12 cc=gcc sanitize=0) (push) Waiting to run
CI / Linux (python=3.13 cc=gcc sanitize=1) (push) Waiting to run
CI / Linux package (push) Waiting to run
CI / Bundle test (macos-latest) (push) Waiting to run
CI / Bundle test (ubuntu-latest) (push) Waiting to run
CI / macOS Brew (push) Waiting to run
CI / Test ./dev.sh and benchmark (push) Waiting to run
CodeQL / CodeQL-Build (actions, ubuntu-latest) (push) Waiting to run
CodeQL / CodeQL-Build (c, macos-latest) (push) Waiting to run
CodeQL / CodeQL-Build (c, ubuntu-latest) (push) Waiting to run
CodeQL / CodeQL-Build (go, ubuntu-latest) (push) Waiting to run
CodeQL / CodeQL-Build (python, ubuntu-latest) (push) Waiting to run
Depscan / Scan dependencies for vulnerabilities (push) Waiting to run
Also fix env reporting. Fixes #10478
This commit is contained in:
parent
e1bdb2c66f
commit
bab67650e2
3 changed files with 49 additions and 17 deletions
|
|
@ -4,3 +4,8 @@
|
|||
import os
|
||||
|
||||
is_ci = os.environ.get('CI') == 'true'
|
||||
|
||||
|
||||
def in_isolated_test_env() -> bool:
|
||||
"""Whether HOME and the XDG dirs point at the throwaway directory created by env_for_python_tests()."""
|
||||
return 'KT_ORIGINAL_HOME' in os.environ
|
||||
|
|
|
|||
|
|
@ -41,9 +41,19 @@ from kitty.utils import (
|
|||
shlex_split_with_positions,
|
||||
)
|
||||
|
||||
from . import in_isolated_test_env
|
||||
from .base import BaseTest, filled_cursor, filled_history_buf, filled_line_buf
|
||||
|
||||
|
||||
def rmtree_in_test_home(path):
|
||||
# Guard against destroying the invoking user's data if the test suite is ever
|
||||
# run without the isolated $HOME set up by env_for_python_tests()
|
||||
if not in_isolated_test_env():
|
||||
raise AssertionError(f'Refusing to delete {path} as the test suite is not running with an isolated HOME')
|
||||
if os.path.exists(path):
|
||||
shutil.rmtree(path)
|
||||
|
||||
|
||||
def create_lbuf(*lines):
|
||||
maxw = max(map(len, lines))
|
||||
ans = LineBuf(len(lines), maxw)
|
||||
|
|
@ -692,8 +702,7 @@ class TestDataTypes(BaseTest):
|
|||
saved = {x: os.environ.get(x) for x in 'KITTY_CONFIG_DIRECTORY XDG_CONFIG_DIRS XDG_CONFIG_HOME'.split()}
|
||||
try:
|
||||
dot_config = os.path.expanduser('~/.config')
|
||||
if os.path.exists(dot_config):
|
||||
shutil.rmtree(dot_config)
|
||||
rmtree_in_test_home(dot_config)
|
||||
with tempfile.TemporaryDirectory() as tdir:
|
||||
with open(tdir + '/macos-launch-services-cmdline', 'w') as f:
|
||||
print('kitty --title from-file', file=f)
|
||||
|
|
@ -736,8 +745,7 @@ class TestDataTypes(BaseTest):
|
|||
os.environ[k] = v
|
||||
self.assertEqual(x[-1], get_config_dir(), str(x))
|
||||
finally:
|
||||
if os.path.exists(dot_config):
|
||||
shutil.rmtree(dot_config)
|
||||
rmtree_in_test_home(dot_config)
|
||||
for k in saved:
|
||||
os.environ.pop(k, None)
|
||||
if saved[k] is not None:
|
||||
|
|
|
|||
|
|
@ -225,21 +225,29 @@ def env_vars(**kw: str) -> Iterator[None]:
|
|||
os.environ[k] = v
|
||||
|
||||
|
||||
@contextmanager
|
||||
def env_for_python_tests(report_env: bool = False) -> Iterator[None]:
|
||||
gohome = os.path.expanduser('~/go')
|
||||
slangc = os.environ.get('SLANGC') or shutil.which('slangc') or 'slangc'
|
||||
def path_for_python_tests() -> str:
|
||||
"""The PATH used by tests: the built launcher dir followed by all entries not under the real home dir."""
|
||||
current_home = os.path.expanduser('~') + os.sep
|
||||
paths = os.environ.get('PATH', '/usr/local/sbin:/usr/local/bin:/usr/bin').split(os.pathsep)
|
||||
path = os.pathsep.join(x for x in paths if not x.startswith(current_home))
|
||||
launcher_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'kitty', 'launcher')
|
||||
path = f'{launcher_dir}{os.pathsep}{path}'
|
||||
if report_env:
|
||||
print('Running under CI:', is_ci)
|
||||
print('Using PATH in test environment:', path)
|
||||
from kitty.fast_data_types import has_avx2, has_avx512, has_sse4_2
|
||||
return f'{launcher_dir}{os.pathsep}{path}'
|
||||
|
||||
print(f'Intrinsics: {has_avx512=} {has_avx2=} {has_sse4_2=}')
|
||||
|
||||
def report_test_env() -> None:
|
||||
"""Print details of the environment tests will run in. Called once in the master process as workers have their stdout captured."""
|
||||
print('Running under CI:', is_ci)
|
||||
print('Using PATH in test environment:', path_for_python_tests())
|
||||
from kitty.fast_data_types import has_avx2, has_avx512, has_sse4_2
|
||||
|
||||
print(f'Intrinsics: {has_avx512=} {has_avx2=} {has_sse4_2=}')
|
||||
|
||||
|
||||
@contextmanager
|
||||
def env_for_python_tests() -> Iterator[None]:
|
||||
gohome = os.path.expanduser('~/go')
|
||||
slangc = os.environ.get('SLANGC') or shutil.which('slangc') or 'slangc'
|
||||
path = path_for_python_tests()
|
||||
with (
|
||||
TemporaryDirectory() as tdir,
|
||||
env_vars(
|
||||
|
|
@ -759,8 +767,11 @@ def run_tests(report_env: bool = False) -> None:
|
|||
if args.name and not tests_list and not has_go:
|
||||
raise SystemExit('No test named %s found' % ' '.join(args.name))
|
||||
|
||||
# Start Python workers before modifying the main-process env; each worker
|
||||
# calls env_for_python_tests independently for full HOME/XDG isolation.
|
||||
if report_env:
|
||||
report_test_env()
|
||||
|
||||
# Start Python workers; each worker calls env_for_python_tests independently
|
||||
# for full HOME/XDG isolation, as does the serial path below.
|
||||
# On macOS fork()+threading is unsafe, so use subprocess workers there.
|
||||
use_parallel = len(tests_list) > PARALLEL_THRESHOLD
|
||||
worker_pids: list[int] = []
|
||||
|
|
@ -795,7 +806,15 @@ def run_tests(report_env: bool = False) -> None:
|
|||
if use_parallel:
|
||||
python_ok, go_ok = collect_worker_results(worker_pids, worker_procs, read_fds, len(tests_list), go_proc=go_proc)
|
||||
elif tests_list:
|
||||
python_ok = run_cli(all_tests, args.verbosity)
|
||||
# we need fonts installed in the user home directory as well, so initialize
|
||||
# fontconfig before nuking $HOME and friends
|
||||
from kitty.fonts.common import all_fonts_map
|
||||
|
||||
all_fonts_map(True)
|
||||
# Tests must never run against the real $HOME, some of them delete
|
||||
# files/directories in it. See run_test_worker() for the parallel equivalent.
|
||||
with env_for_python_tests():
|
||||
python_ok = run_cli(all_tests, args.verbosity)
|
||||
if go_proc is not None:
|
||||
_, go_ok = collect_worker_results([], [], [], 0, go_proc=go_proc)
|
||||
else:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue