Files
hermes-agent/tests/tools/test_checkpoint_store_ownership.py
ethernet 6716b72ef2 refactor: separate checkpoint store maintenance from snapshots
Move retention, orphan pruning, status and clear operations into a topical sibling and route callers and tests directly to their defining module. Keep the shared store paths and git execution in checkpoint_manager; shorten the local child-env WHAT docstring.
2026-09-24 01:55:51 -04:00

57 lines
2.4 KiB
Python

"""Maintenance cannot prune objects another checkpoint process has not published."""
from __future__ import annotations
import os
from pathlib import Path
from queue import Queue
import subprocess
import sys
from threading import Thread
import tools.checkpoint_manager as checkpoints
from tools import checkpoint_maintenance
def test_active_snapshot_owns_store_until_its_ref_is_published(tmp_path, monkeypatch):
base = tmp_path / "checkpoints"
monkeypatch.setattr(checkpoints, "CHECKPOINT_BASE", base)
project = tmp_path / "project"
project.mkdir()
(project / "initial.txt").write_text("initial", encoding="utf-8")
manager = checkpoints.CheckpointManager(enabled=True, max_total_size_mb=0)
assert manager.ensure_checkpoint(str(project), "initial")
(project / "concurrent.txt").write_text("new unpublished bytes", encoding="utf-8")
program = '''
import sys
from pathlib import Path
from tools import checkpoint_manager as c
c.CHECKPOINT_BASE = Path(sys.argv[1])
run = c._run_git
def paused(args, *rest, **kwargs):
result = run(args, *rest, **kwargs)
if args[0] == "write-tree" and result[0]:
print("tree-written", flush=True)
sys.stdin.readline()
return result
c._run_git = paused
assert c.CheckpointManager(enabled=True, max_total_size_mb=0).ensure_checkpoint(sys.argv[2], "concurrent")
'''
env = {**os.environ, "PYTHONPATH": str(Path(checkpoints.__file__).resolve().parents[1])}
child = subprocess.Popen([sys.executable, "-u", "-c", program, str(base), str(project)],
cwd=tmp_path, env=env, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, text=True, encoding="utf-8")
ready = Queue()
reader = Thread(target=lambda: ready.put(child.stdout.readline()), daemon=True)
reader.start()
try:
assert ready.get(timeout=20).strip() == "tree-written"
result = checkpoint_maintenance.prune_checkpoints(retention_days=0, checkpoint_base=base)
assert result["errors"] > 0, "maintenance must refuse an active store writer"
assert not checkpoint_maintenance.clear_all(base)["deleted"]
finally:
output, error = child.communicate(input="publish\n", timeout=30)
reader.join(timeout=5)
assert child.returncode == 0, output + error
assert [row["reason"] for row in manager.list_checkpoints(str(project))] == ["concurrent", "initial"]