Files
hermes-agent/tests/hermes_cli/test_launcher_runtime_selection.py
ethernet b728fdd627 refactor(pm): own the lock/atomic-write primitives in pm.filesystem
pm imported runtime_state's private helpers (_lock, _atomic_bytes, _bytes,
_digest) at a dozen sites while runtime_state imports pm.environments at
module top. The primitives are pm's: move them into the stdlib-only
pm.filesystem as lock_fd, durable_write_bytes, read_bytes_or_none and
file_digest, and repoint every pm caller.

runtime_state keeps the private names only as import aliases: it still
calls them through its own globals, and pre-PM updaters load them by these
names mid-swap (tests/compat/old_updater_surface.json).

Boot-subset test fixtures now copy pm/filesystem.py, since runtime_state
imports it at process boot; worker-injection tests patch the name
pm.publication now reads.
2026-09-24 14:08:03 -04:00

66 lines
2.8 KiB
Python

"""Launch-time dependency selection survives a change after launcher minting."""
import json
import os
from pathlib import Path
import subprocess
import sys
import pytest
from hermes_cli import _launchers
from pm.environments import install_state_dir, site_packages
@pytest.mark.platforms("windows")
def test_minted_launcher_reads_current_selection_and_editable_members(tmp_path, monkeypatch):
from pm import environments as runtime_paths
from hermes_cli import runtime_state
import hermes_constants
root = tmp_path / "repo"
package = root / "hermes_cli"
package.mkdir(parents=True)
(package / "__init__.py").write_text("")
pm_package = root / "pm"
pm_package.mkdir()
(pm_package / "__init__.py").write_text("")
# Real selection code, with a fixture entry point rather than a live CLI.
(pm_package / "environments.py").write_bytes(Path(runtime_paths.__file__).read_bytes())
(pm_package / "filesystem.py").write_bytes((Path(runtime_paths.__file__).parent / "filesystem.py").read_bytes())
(package / "runtime_state.py").write_bytes(Path(runtime_state.__file__).read_bytes())
(root / "hermes_constants.py").write_bytes(Path(hermes_constants.__file__).read_bytes())
(root / "hermes_bootstrap.py").write_text(
"from pathlib import Path\nfrom pm.environments import activate_dependencies\n"
"activate_dependencies(Path(__file__).resolve().parent)\n"
)
(package / "main.py").write_text(
"import selection_probe, editable_probe\n"
"def main():\n print(selection_probe.VALUE, editable_probe.VALUE)\n return 0\n"
)
base = site_packages(root / "venv")
base.mkdir(parents=True)
(base / "selection_probe.py").write_text("VALUE = 'base'\n")
monkeypatch.setenv("HERMES_HOME", str(tmp_path / "home"))
state = install_state_dir(root)
out = tmp_path / "bin"
out.mkdir()
launcher = _launchers.mint_launcher("hermes", root, out, Path(sys.executable), base)
assert launcher is not None
selected = state / "environments" / "selected" / "venv"
site = site_packages(selected)
site.mkdir(parents=True)
(selected / "pyvenv.cfg").write_text("home = fixture\n")
(site / "selection_probe.py").write_text("VALUE = 'selected'\n")
editable = tmp_path / "editable"
editable.mkdir()
(editable / "editable_probe.py").write_text("VALUE = 'editable'\n")
(site / "member.pth").write_text(str(editable) + "\n")
(state / "facts.json").write_text(json.dumps({"packages": {"venv": {"environment": str(selected)}}}))
env = dict(os.environ)
env.pop("PYTHONPATH", None)
env.pop("PYTHONHOME", None)
result = subprocess.run([str(launcher)], cwd=tmp_path, env=env, capture_output=True, text=True, timeout=30)
assert result.returncode == 0, result.stdout + result.stderr
assert result.stdout.strip() == "selected editable"