From 16f102f5d4a8ae25b5effa20a9d2805ae486f3e2 Mon Sep 17 00:00:00 2001 From: Lalit Maganti Date: Wed, 16 Sep 2026 15:17:05 +0100 Subject: [PATCH] tests: record build systems with a plain toolchain The build-system diff tests inherited the whole environment, so a compiler launcher on PATH ran as part of the build and appeared in the recording. That was fine until installing ccache for the wrapper loop test put /usr/lib/ccache in front of cc on the CI runner, and every expectation grew a ccache node. The expectations describe a plain toolchain, so record with one: take the launcher directories off PATH. Tests that want a launcher put one there themselves. --- tests/conformance/conftest.py | 18 ++++++++++++++++++ tests/conformance/test_build_systems.py | 11 ++++++----- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/tests/conformance/conftest.py b/tests/conformance/conftest.py index 43219b2..80bf0ea 100644 --- a/tests/conformance/conftest.py +++ b/tests/conformance/conftest.py @@ -13,6 +13,24 @@ ROOT = Path(__file__).resolve().parents[2] +# A compiler launcher in front of the toolchain runs as part of the build and +# lands in the recording, so a diff test would describe whichever launcher the +# machine happens to have installed. Tests that want one put it on PATH +# themselves. +LAUNCHERS = frozenset({"ccache", "distcc", "icecc", "sccache"}) + + +@pytest.fixture +def plain_environment() -> dict[str, str]: + """The environment with any compiler launcher taken off `PATH`.""" + directories = [ + directory + for directory in os.environ.get("PATH", "").split(os.pathsep) + if not LAUNCHERS & set(Path(directory).parts) + ] + return dict(os.environ, LC_ALL="C", PATH=os.pathsep.join(directories)) + + def pytest_addoption(parser: pytest.Parser) -> None: parser.addoption( "--update-expectations", diff --git a/tests/conformance/test_build_systems.py b/tests/conformance/test_build_systems.py index 2ead5e9..7fe5d12 100644 --- a/tests/conformance/test_build_systems.py +++ b/tests/conformance/test_build_systems.py @@ -200,7 +200,9 @@ def tool_of(pid: int) -> str: @pytest.mark.parametrize("case", sorted(CASES)) -def test_build_system(case, buildprof: Path, tmp_path: Path, request): +def test_build_system( + case, buildprof: Path, tmp_path: Path, request, plain_environment: dict +): for tool in REQUIRED_TOOLS[case]: if shutil.which(tool) is None: message = f"{tool} is not installed in this environment" @@ -214,14 +216,13 @@ def test_build_system(case, buildprof: Path, tmp_path: Path, request): command = build(project) trace = tmp_path / f"{case}.pftrace" - env = dict(os.environ, LC_ALL="C") result = subprocess.run( [str(buildprof), "-o", str(trace), "--", *command], cwd=project, text=True, capture_output=True, timeout=300, - env=env, + env=plain_environment, ) assert result.returncode == 0, f"{case} build failed:\n{result.stdout}{result.stderr}" assert trace.is_file(), f"{case} produced no trace" @@ -241,7 +242,7 @@ def test_build_system(case, buildprof: Path, tmp_path: Path, request): ) -def test_npm_build(buildprof: Path, tmp_path: Path): +def test_npm_build(buildprof: Path, tmp_path: Path, plain_environment: dict): for tool in ("npm", "node"): if shutil.which(tool) is None: message = f"{tool} is not installed in this environment" @@ -254,7 +255,7 @@ def test_npm_build(buildprof: Path, tmp_path: Path): result = subprocess.run( [str(buildprof), "--no-open", "-o", str(trace), "--", *command], cwd=tmp_path, - env=dict(os.environ, LC_ALL="C", npm_config_cache=str(tmp_path / ".npm")), + env=dict(plain_environment, npm_config_cache=str(tmp_path / ".npm")), text=True, capture_output=True, timeout=60,