128 lines
4.4 KiB
Python
128 lines
4.4 KiB
Python
from __future__ import annotations
|
|
|
|
import importlib.util
|
|
import json
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
PROJECT_ROOT = Path(__file__).parent.parent
|
|
|
|
_spec = importlib.util.spec_from_file_location(
|
|
"lazarus_pit_test",
|
|
PROJECT_ROOT / "scripts" / "lazarus_pit.py",
|
|
)
|
|
_mod = importlib.util.module_from_spec(_spec)
|
|
sys.modules["lazarus_pit_test"] = _mod
|
|
_spec.loader.exec_module(_mod)
|
|
|
|
build_cell_paths = _mod.build_cell_paths
|
|
build_daemon_report = _mod.build_daemon_report
|
|
init_cell = _mod.init_cell
|
|
load_config = _mod.load_config
|
|
scan_mission_cells = _mod.scan_mission_cells
|
|
write_daemon_heartbeat = _mod.write_daemon_heartbeat
|
|
|
|
|
|
def test_init_cell_creates_foundation_structure(tmp_path):
|
|
mission_id = "123e4567-e89b-12d3-a456-426614174000"
|
|
cell = init_cell(mission_id, root=tmp_path, now=1_700_000_000)
|
|
|
|
paths = build_cell_paths(mission_id, tmp_path)
|
|
for key in ["meta", "config", "state", "logs", "artifacts", "worktree"]:
|
|
assert paths[key].is_dir(), f"expected {key} directory to exist"
|
|
|
|
meta = json.loads((paths["meta"] / "mission.json").read_text())
|
|
assert meta["mission_id"] == mission_id
|
|
assert meta["status"] == "bootstrapped"
|
|
|
|
heartbeat = json.loads((paths["state"] / "heartbeat.json").read_text())
|
|
assert heartbeat["mission_id"] == mission_id
|
|
assert heartbeat["status"] == "bootstrapped"
|
|
assert cell["root"] == str(paths["root"])
|
|
|
|
|
|
def test_scan_mission_cells_marks_healthy_and_stale(tmp_path):
|
|
healthy_id = "healthy-cell"
|
|
stale_id = "stale-cell"
|
|
|
|
init_cell(healthy_id, root=tmp_path, now=1_700_000_000)
|
|
init_cell(stale_id, root=tmp_path, now=1_700_000_000)
|
|
|
|
healthy_paths = build_cell_paths(healthy_id, tmp_path)
|
|
stale_paths = build_cell_paths(stale_id, tmp_path)
|
|
|
|
(healthy_paths["state"] / "heartbeat.json").write_text(
|
|
json.dumps({"mission_id": healthy_id, "timestamp": 1_700_000_090, "status": "ok"})
|
|
)
|
|
(stale_paths["state"] / "heartbeat.json").write_text(
|
|
json.dumps({"mission_id": stale_id, "timestamp": 1_700_000_000, "status": "ok"})
|
|
)
|
|
|
|
cells = scan_mission_cells(
|
|
root=tmp_path,
|
|
required_subdirs=["meta", "config", "state", "logs", "artifacts", "worktree"],
|
|
heartbeat_relpath="state/heartbeat.json",
|
|
stale_after_seconds=60,
|
|
now=1_700_000_100,
|
|
)
|
|
by_id = {cell["mission_id"]: cell for cell in cells}
|
|
|
|
assert by_id[healthy_id]["status"] == "healthy"
|
|
assert by_id[healthy_id]["age_seconds"] == 10
|
|
assert by_id[stale_id]["status"] == "stale"
|
|
assert by_id[stale_id]["age_seconds"] == 100
|
|
|
|
|
|
def test_build_daemon_report_and_write_heartbeat(tmp_path):
|
|
config_path = tmp_path / "lazarus_pit.json"
|
|
config_path.write_text(
|
|
json.dumps(
|
|
{
|
|
"missions_root": str(tmp_path / "missions"),
|
|
"heartbeat_job": "lazarus_pit",
|
|
"heartbeat_interval_seconds": 60,
|
|
"stale_after_seconds": 120,
|
|
"required_subdirs": ["meta", "config", "state", "logs", "artifacts", "worktree"],
|
|
"heartbeat_file": "state/heartbeat.json",
|
|
}
|
|
)
|
|
)
|
|
|
|
config = load_config(config_path)
|
|
init_cell("mission-one", root=Path(config["missions_root"]), now=2_000)
|
|
paths = build_cell_paths("mission-one", Path(config["missions_root"]))
|
|
(paths["state"] / "heartbeat.json").write_text(
|
|
json.dumps({"mission_id": "mission-one", "timestamp": 2_050, "status": "ok"})
|
|
)
|
|
|
|
report = build_daemon_report(config, now=2_100)
|
|
assert report["summary"]["total_cells"] == 1
|
|
assert report["summary"]["healthy"] == 1
|
|
assert report["summary"]["stale"] == 0
|
|
assert report["cells"][0]["mission_id"] == "mission-one"
|
|
|
|
heartbeat_path = write_daemon_heartbeat(config, directory=tmp_path / "heartbeats")
|
|
heartbeat = json.loads(heartbeat_path.read_text())
|
|
assert heartbeat["job"] == "lazarus_pit"
|
|
assert heartbeat["interval_seconds"] == 60
|
|
|
|
|
|
def test_foundation_artifacts_exist_with_required_spec():
|
|
doc = PROJECT_ROOT / "docs" / "mission-cell-spec.md"
|
|
config = PROJECT_ROOT / "config" / "lazarus_pit.json"
|
|
|
|
assert doc.exists(), "expected mission cell spec doc"
|
|
assert config.exists(), "expected lazarus pit config"
|
|
|
|
content = doc.read_text()
|
|
for snippet in [
|
|
"/var/missions/<uuid>/",
|
|
"meta/mission.json",
|
|
"config/cell.json",
|
|
"state/heartbeat.json",
|
|
"logs/daemon.log",
|
|
"artifacts/",
|
|
"worktree/",
|
|
]:
|
|
assert snippet in content
|