"""tools/ledger.py: runs as git-tracked JSON with fixed states.""" import json import pytest from tools import ledger def test_new_set_metrics_render_check(tmp_path): run = ledger.new_run("dataset/2026-10-02_alc", "yolo26n-seg.pt", "alc", note="first", root=tmp_path) assert run["status"] == "exported" and run["id"].endswith("_alc") assert (tmp_path / "runs" / run["id"] / "run.json").exists() ledger.set_status(run["id"], "training", kv={"host": "spark"}, root=tmp_path) again = ledger.load(run["id"], root=tmp_path) assert again["status"] == "training" and again["host"] == "spark" and len(again["history"]) == 2 m = tmp_path / "m.json" m.write_text(json.dumps({"overall": {"f1": 0.91, "mean_mask_iou": 0.8}, "gate": {"pass": True, "baseline": "b"}})) ledger.record_metrics(run["id"], m, root=tmp_path) ledger.set_status(run["id"], "gate_passed", root=tmp_path) again = ledger.load(run["id"], root=tmp_path) assert again["metrics"]["f1"] == 0.91 and again["metrics"]["gate_pass"] is True assert (tmp_path / "runs" / run["id"] / "metrics.json").exists() readme = ledger.render(root=tmp_path) text = readme.read_text() assert run["id"] in text and "gate_passed" in text and "0.910" in text assert ledger.check(root=tmp_path) == [] assert run["id"] in ledger.table(root=tmp_path) def test_second_run_same_day_gets_a_suffix(tmp_path): a = ledger.new_run("dataset/x", "yolo26n-seg.pt", "alc", root=tmp_path) b = ledger.new_run("dataset/x", "yolo26n-seg.pt", "alc", root=tmp_path) assert b["id"] == a["id"] + "-2" def test_unknown_state_and_check_problems(tmp_path): run = ledger.new_run("dataset/x", "yolo26n-seg.pt", "t", root=tmp_path) with pytest.raises(SystemExit): ledger.set_status(run["id"], "done", root=tmp_path) # measured without a metrics.json is a problem the CI check reports p = tmp_path / "runs" / run["id"] / "run.json" d = json.loads(p.read_text()); d["status"] = "measured"; p.write_text(json.dumps(d)) problems = ledger.check(root=tmp_path) assert any("no metrics.json" in x for x in problems) assert ledger.main(["--root", str(tmp_path), "check"]) == 1