Files
hermes-agent/tests/scripts/install/test_pm_desktop_launch_capture.py
ethernet 48c78669b1 test(install-e2e): capture PM desktop launches on macOS through the isolated launcher
PM launchers run python -I, which ignores PYTHONPATH, so the macOS
hermes-desktop-app-update route never loaded the sitecustomize capture hook.
Route PM launchers through pm-launch.py as the Linux driver already does, and
cover the packaged .app shape the macOS route launches.
2026-09-24 11:12:27 -04:00

75 lines
3.0 KiB
Python

"""The installer E2E's capture must survive the installed PM launcher's -I."""
import json
import os
from pathlib import Path
import shlex
import subprocess
import sys
import pytest
@pytest.mark.platforms("posix")
@pytest.mark.parametrize("packaged", [False, True])
def test_isolated_pm_launch_captures_only_final_electron_spawn(tmp_path, packaged):
launch_argv = (
[str(tmp_path / "apps/desktop/release/mac-arm64/Hermes.app/Contents/MacOS/Hermes")]
if packaged else ["npm", "exec", "--", "electron", "."]
)
root = Path(__file__).resolve().parents[3]
helper = root / "tests/install/e2e-assets/launch-capture/pm-launch.py"
launcher = tmp_path / "hermes"
app = tmp_path / "app.py"
app.write_text(
"import os, subprocess, sys\n"
"assert sys.flags.isolated == 1\n"
"assert os.environ.get('PYTHONPATH') is None\n"
"assert sys.argv[1:] == ['desktop']\n"
"subprocess.run(['npm', 'run', 'build'], check=True)\n"
f"subprocess.run({launch_argv!r}, "
"cwd=os.getcwd(), env={**os.environ, 'PRODUCT_SENTINEL': 'present'}, check=True)\n",
encoding="utf-8",
)
# Query emulates the published --print-runtime-command interface. The
# returned command executes under a REAL isolated Python, not a patched
# subprocess; the fake npm command proves builds still pass through.
code = ("import os, runpy; os.environ.pop('PYTHONPATH', None); "
f"runpy.run_path({str(app)!r}, run_name='__main__')")
command = [sys.executable, "-I", "-c", code, "desktop"]
launcher.write_text(
"#!/bin/sh\n"
"[ \"$1\" = --print-runtime-command ] || exit 90\n"
f"printf '%s\\n' {shlex.quote(json.dumps(command))}\n",
encoding="utf-8",
)
launcher.chmod(0o755)
fake_npm = tmp_path / "npm"
fake_npm.write_text(
"#!/bin/sh\n"
"[ \"$1 $2 $3\" = 'run build ' ] || exit 89\n"
f"touch {shlex.quote(str(tmp_path / 'build-ran'))}\n",
encoding="utf-8",
)
fake_npm.chmod(0o755)
evil = tmp_path / "evil"
evil.mkdir()
(evil / "sitecustomize.py").write_text(
f"open({str(tmp_path / 'ambient-hook-ran')!r}, 'w').close()\n", encoding="utf-8",
)
spec = tmp_path / "launch.json"
env = {**os.environ, "PATH": str(tmp_path) + os.pathsep + os.environ["PATH"],
"PYTHONPATH": str(evil)}
result = subprocess.run([sys.executable, "-I", str(helper), str(launcher), str(spec)],
cwd=tmp_path, env=env, capture_output=True, text=True)
assert result.returncode == 0, result.stderr
assert (tmp_path / "build-ran").is_file()
assert not (tmp_path / "ambient-hook-ran").exists()
shape = "packaged" if packaged else "source"
assert spec.with_name(spec.name + ".captured").read_text() == shape
captured = json.loads(spec.read_text())
assert captured["argv"] == launch_argv
assert captured["matchedShape"] == shape
assert captured["cwd"] == str(tmp_path)
assert captured["env"]["PRODUCT_SENTINEL"] == "present"