from __future__ import annotations import importlib.util import json from pathlib import Path SCRIPT = Path(__file__).parents[2] / "scripts" / "supervise_container_training_loop.py" SPEC = importlib.util.spec_from_file_location("loop_supervisor", SCRIPT) assert SPEC and SPEC.loader MODULE = importlib.util.module_from_spec(SPEC) SPEC.loader.exec_module(MODULE) def test_loop_status_is_fail_closed_and_recognises_completion(tmp_path: Path) -> None: state = tmp_path / "state.json" assert MODULE.read_loop_status(state) is None state.write_text("not-json", encoding="utf-8") assert MODULE.read_loop_status(state) == "invalid" state.write_text(json.dumps({"status": "training_complete"}), encoding="utf-8") assert MODULE.read_loop_status(state) == "training_complete" def test_process_detection_requires_exact_marker(monkeypatch) -> None: class Result: returncode = 0 stdout = "12 python api.py\n13 python run_belgium_building_training_loop.py --output-dir /runs/v37\n" monkeypatch.setattr(MODULE.subprocess, "run", lambda *args, **kwargs: Result()) assert MODULE.process_active("geointel", "run_belgium_building_training_loop.py") assert not MODULE.process_active("geointel", "other_loop.py") def test_write_state_creates_output_directory_atomically(tmp_path: Path) -> None: state_path = tmp_path / "new-run" / "supervisor-state.json" MODULE.write_state(state_path, {"schema_version": 1, "status": "monitoring"}) written = json.loads(state_path.read_text(encoding="utf-8")) assert written["status"] == "monitoring" assert written["updated_at"] assert not state_path.with_suffix(".json.tmp").exists()