Files
hermes-agent/tests/pm/test_runtime_boot_gc.py
ethernet 0db8617633 fix(gateway): restore the PM startup verdict, boot bootstrap and plugin cadence in main()
The reconciliation merge b681f0c50e dropped the branch's gateway startup block:
the daemon never passes through the CLI dispatch, so it takes the same passive
PM verdict (check_runtime), the record-gated boot bootstrap, and the due-gated
plugin update check as a housekeeping chore from its first tick.
2026-09-19 04:11:22 -04:00

56 lines
2.1 KiB
Python

"""A real bootstrap reader pins its generation before GC can select victims."""
import json
import os
import subprocess
import sys
def test_bootstrap_lease_survives_selection_change(tmp_path, monkeypatch):
from pm.environments import install_state_dir, runtime_facts_path, site_packages
from hermes_cli.runtime_state import collect_generations
repo = tmp_path / "repo"
repo.mkdir()
monkeypatch.setenv("HERMES_HOME", str(tmp_path / "home"))
state = install_state_dir(repo)
for name in ("first", "second", "unused"):
venv = state / "environments" / name / "venv"
venv.mkdir(parents=True)
# pyvenv.cfg first: the layout keys its site-packages path off the recorded version.
(venv / "pyvenv.cfg").write_text("version = 3.11")
site_packages(venv).mkdir(parents=True)
(venv.parent / ".lease-managed").touch()
legacy = state / "environments" / "old-unleased"
legacy.mkdir()
def select(name):
environment = state / "environments" / name / "venv"
runtime_facts_path(repo).write_text(json.dumps({"packages": {"venv": {"environment": str(environment)}}}))
return environment
first = select("first")
code = '''
import sys
from pathlib import Path
from pm.environments import activate_dependencies
activate_dependencies(Path(sys.argv[1]))
print("ready", flush=True)
sys.stdin.readline()
'''
child = subprocess.Popen([sys.executable, "-c", code, str(repo)], env=dict(os.environ),
stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
try:
assert child.stdout.readline().strip() == "ready"
select("second")
collect_generations(repo, min_age_seconds=0)
assert first.is_dir()
assert not (state / "environments" / "unused").exists()
assert legacy.is_dir()
finally:
child.communicate("done\n", timeout=15)
assert child.returncode == 0
collect_generations(repo, min_age_seconds=0)
assert not first.exists()
assert (state / "environments" / "second").is_dir()
assert legacy.is_dir()