Skip to content

Commit 94d5e48

Browse files
committed
feat(test): coverage map load/save with freshness metadata
1 parent 216e04c commit 94d5e48

2 files changed

Lines changed: 60 additions & 1 deletion

File tree

toolchain/mfc/test/coverage.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,12 @@
44
docs/superpowers/specs/2026-05-29-coverage-test-selection-design.md.
55
"""
66

7+
import datetime
8+
import gzip
79
import hashlib
810
import json
11+
from pathlib import Path
12+
from typing import Optional, Tuple
913

1014

1115
def param_hash(params: dict) -> str:
@@ -16,3 +20,34 @@ def param_hash(params: dict) -> str:
1620
"""
1721
canonical = json.dumps(params, sort_keys=True, separators=(",", ":"), default=str)
1822
return hashlib.sha256(canonical.encode("utf-8")).hexdigest()[:16]
23+
24+
25+
COVERAGE_MAP_PATH = Path("tests/coverage_map.json.gz")
26+
27+
28+
def save_map(path: Path, entries: dict, *, n_tests: int, git_sha: str, gfortran_version: str) -> None:
29+
payload = dict(entries)
30+
payload["_meta"] = {
31+
"built_at": datetime.datetime.now(datetime.timezone.utc).isoformat(),
32+
"git_sha": git_sha,
33+
"gfortran_version": gfortran_version,
34+
"n_tests": n_tests,
35+
}
36+
path.parent.mkdir(parents=True, exist_ok=True)
37+
with gzip.open(path, "wt", encoding="utf-8") as f:
38+
json.dump(payload, f, indent=2, sort_keys=True)
39+
40+
41+
def load_map(path: Path) -> Tuple[Optional[dict], Optional[dict]]:
42+
"""Return (entries_without_meta, meta), or (None, None) if missing/corrupt."""
43+
if not Path(path).exists():
44+
return None, None
45+
try:
46+
with gzip.open(path, "rt", encoding="utf-8") as f:
47+
data = json.load(f)
48+
except (OSError, gzip.BadGzipFile, json.JSONDecodeError, UnicodeDecodeError):
49+
return None, None
50+
if not isinstance(data, dict) or "_meta" not in data:
51+
return None, None
52+
meta = data.pop("_meta")
53+
return data, meta

toolchain/mfc/test/test_coverage_unit.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
from mfc.test.coverage import param_hash
1+
import tempfile
2+
from pathlib import Path
3+
4+
from mfc.test.coverage import load_map, param_hash, save_map
25

36

47
def test_param_hash_is_order_independent():
@@ -22,3 +25,24 @@ def test_param_hash_nested_order_independent():
2225
a = param_hash({"patch": {"x": 1, "y": 2}})
2326
b = param_hash({"patch": {"y": 2, "x": 1}})
2427
assert a == b
28+
29+
30+
def test_save_then_load_roundtrip():
31+
with tempfile.TemporaryDirectory() as d:
32+
p = Path(d) / "m.json.gz"
33+
save_map(p, {"abc": ["src/simulation/m_rhs.fpp"]}, n_tests=1, git_sha="deadbee", gfortran_version="13")
34+
entries, meta = load_map(p)
35+
assert entries == {"abc": ["src/simulation/m_rhs.fpp"]}
36+
assert meta["n_tests"] == 1 and meta["git_sha"] == "deadbee"
37+
assert "built_at" in meta
38+
39+
40+
def test_load_missing_returns_none():
41+
assert load_map(Path("/nonexistent/m.json.gz")) == (None, None)
42+
43+
44+
def test_load_corrupt_returns_none():
45+
with tempfile.TemporaryDirectory() as d:
46+
p = Path(d) / "m.json.gz"
47+
p.write_bytes(b"not gzip")
48+
assert load_map(p) == (None, None)

0 commit comments

Comments
 (0)