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.
50 lines
1.8 KiB
Python
50 lines
1.8 KiB
Python
"""Superseded and aborted PM runtime generations are collected; running workers are not."""
|
|
import json
|
|
from pathlib import Path
|
|
|
|
from pm.runtime import collect_runtime_generations
|
|
|
|
|
|
def _generation(root: Path, name: str, *, published: bool = True, leased: bool = True) -> Path:
|
|
generation = root / "generations" / name
|
|
generation.mkdir(parents=True)
|
|
if leased:
|
|
(generation / ".lease-managed").touch()
|
|
if published:
|
|
(generation / "pm-runtime.json").write_text(json.dumps({"inputs": name}), encoding="utf-8")
|
|
return generation
|
|
|
|
|
|
def test_collector_keeps_selected_leased_and_pre_lease_generations(tmp_path):
|
|
from hermes_cli.runtime_state import lease_directory
|
|
|
|
root = tmp_path / "pm-runtime"
|
|
selected = _generation(root, "selected")
|
|
busy = _generation(root, "busy")
|
|
idle = _generation(root, "idle")
|
|
legacy = _generation(root, "legacy", leased=False)
|
|
aborted = _generation(root, "aborted", published=False)
|
|
(root / "selected.json").write_text(json.dumps({"generation": "generations/selected"}), encoding="utf-8")
|
|
release = lease_directory(busy)
|
|
lease_directory(idle)()
|
|
|
|
removed = collect_runtime_generations(root)
|
|
|
|
assert set(removed) == {idle, aborted}
|
|
assert selected.is_dir() and busy.is_dir() and legacy.is_dir()
|
|
release()
|
|
assert collect_runtime_generations(root) == [busy]
|
|
|
|
|
|
def test_collector_yields_to_an_in_flight_stage(tmp_path):
|
|
from pm.filesystem import lock_fd
|
|
|
|
root = tmp_path / "pm-runtime"
|
|
aborted = _generation(root, "aborted", published=False)
|
|
root.mkdir(exist_ok=True)
|
|
with (root / ".prepare.lock").open("a+b") as lock:
|
|
assert lock_fd(lock.fileno(), wait=False)
|
|
assert collect_runtime_generations(root) == []
|
|
assert aborted.is_dir()
|
|
assert collect_runtime_generations(root) == [aborted]
|