From 1662c7870244fc0344cd947f99ed242ecbc6e198 Mon Sep 17 00:00:00 2001 From: ethernet Date: Sat, 12 Sep 2026 19:07:01 -0400 Subject: [PATCH] Migrate stale sidecar and private uv tests to PM's current interface --- tests/pm/test_workspace_output_encoding.py | 26 ++++++++++++++++++++-- tests/test_pm_bionic.py | 12 +++++----- 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/tests/pm/test_workspace_output_encoding.py b/tests/pm/test_workspace_output_encoding.py index 0563f52f4a..7802ee14c0 100644 --- a/tests/pm/test_workspace_output_encoding.py +++ b/tests/pm/test_workspace_output_encoding.py @@ -9,8 +9,9 @@ import sys import pytest +import pm import pm.workspace as ws -from pm.package import InstallError +from pm.package import InstallError, Runner @pytest.fixture @@ -87,14 +88,35 @@ def test_node_sidecar_retains_output_and_exit_status( diagnostic = "🔍 node-gyp: build toolchain unavailable" raw = diagnostic.encode("utf-8") + b"\xff\n" completed = [] + npm_dir = tmp_path / "pm-bin" + npm_dir.mkdir() + npm = npm_dir / ("npm.cmd" if os.name == "nt" else "npm") + npm.write_text("process boundary fixture", encoding="utf-8") + npm.chmod(0o755) + context = Runner("npm", dict(os.environ, PATH=str(npm_dir))) + acquisitions = [] + + def acquire(name, **kwargs): + acquisitions.append((name, kwargs)) + return context def run_npm(cmd, **kwargs): + assert cmd == [str(npm), install_cmd, "--no-audit", "--no-fund"] + assert kwargs["env"] == context.env + assert kwargs["cwd"] == str(tmp_path) + # Keep the real Runner and decoding path; only replace npm's process + # with a Python child that emits controlled bytes and an exit status. result = legacy_locale_child(**{stream: raw}, returncode=returncode, **kwargs) completed.append(result) return result - error = ws.install_node_sidecar(tmp_path, npm_bin=sys.executable, runner=run_npm) + monkeypatch.setattr(pm, "ensure", acquire) + monkeypatch.setattr("pm.package.subprocess.run", run_npm) + error = ws.install_node_sidecar(tmp_path) + assert acquisitions == [("npm", {"explicit": False})] + assert len(completed) == 1 + assert completed[0].returncode == returncode expected = diagnostic + "�" if returncode: assert error == f"npm {install_cmd} exited {returncode}: {expected}" diff --git a/tests/test_pm_bionic.py b/tests/test_pm_bionic.py index 85599a36dd..2e90ee4459 100644 --- a/tests/test_pm_bionic.py +++ b/tests/test_pm_bionic.py @@ -174,9 +174,8 @@ def test_bionic_verify_is_file_evidence(tmp_path: Path, monkeypatch, name): def test_bionic_binary_and_env_contract(tmp_path: Path): - """On bionic, _BionicDebArm.binary() must return the staged deb's main - binary path (file evidence, no exec), so the base Package.env contract - exposes the tool through PATH like every other pm package.""" + """Bionic binaries retain their staged paths, but only on_path packages + expose them in the environment; internal uv stays private to PM.""" from pm.registry import get_package for name in ("uv", "python", "node"): @@ -190,9 +189,12 @@ def test_bionic_binary_and_env_contract(tmp_path: Path): assert binary == main, f"{name}.binary() on bionic: {binary}" env = pkg.env(entry, "linux-arm64-bionic") - assert env.get("PATH") == [str(main.parent)], ( - f"{name}.env() on bionic does not follow the Package.env PATH contract" + expected_path = [str(main.parent)] if pkg.on_path else None + assert env.get("PATH") == expected_path, ( + f"{name}.env() on bionic does not follow its on_path declaration" ) + if pkg.internal: + assert "PATH" not in env, f"internal {name} must not leak into public PATH" def test_stage_only_does_not_record_host_facts(tmp_path, monkeypatch):