From ca816233bb7578d4768d662e5de2f1a307fd7711 Mon Sep 17 00:00:00 2001 From: Jammy2211 Date: Fri, 17 Jul 2026 07:33:28 +0100 Subject: [PATCH] test_run: carry the report's surface into the sidecar (#83 step 3) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Consumer half of §5.3: PyAutoBuild#164 makes report.json state the surface it measured; the leg now carries that block through to test_run.json, so the verdict can cite its own denominator instead of comparing counts across incomparable runs. Absent on pre-#164 reports -> None, never a crash. Co-Authored-By: Claude Fable 5 --- heart/checks/test_run.py | 4 ++++ tests/test_test_run.py | 25 +++++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/heart/checks/test_run.py b/heart/checks/test_run.py index 7316f68..dd404e5 100644 --- a/heart/checks/test_run.py +++ b/heart/checks/test_run.py @@ -153,6 +153,10 @@ def _from_report(report: dict[str, Any]) -> dict[str, Any]: "run_label": report.get("run_label", ""), "parked_stale_count": len(parked), "parked_stale": parked, + # The surface this report measured (projects/shards/run_types/env + # profile). Carried through so the leg's history is comparable at all: + # a count is only a trend against the same denominator (#83 §5.3). + "surface": report.get("surface"), "source": "report", } diff --git a/tests/test_test_run.py b/tests/test_test_run.py index 3f40ba4..c76864f 100644 --- a/tests/test_test_run.py +++ b/tests/test_test_run.py @@ -228,3 +228,28 @@ def test_run_without_explicit_fetch_never_touches_network(monkeypatch, tmp_path) "ready": True, "summary": {"passed": 1}})) tr.run(results_dir=tmp_path) assert calls == [] + + +def test_surface_is_carried_from_report_to_sidecar(tmp_path): + """The leg must be able to state what the run measured (#83 §5.3).""" + surface = { + "projects": ["autolens", "howtolens"], + "shards": ["autolens/imaging"], + "run_types": ["script"], + "env_profiles": ["env_vars.yaml"], + "script_count": 42, + } + (tmp_path / "report.json").write_text(json.dumps({ + "ready": True, "run_label": "R1", "summary": {"passed": 42}, + "surface": surface, + })) + out = tr.run(results_dir=tmp_path) + assert out["surface"] == surface + + +def test_surface_absent_from_old_report_is_none_not_a_crash(tmp_path): + # Reports predating the surface block must still parse. + (tmp_path / "report.json").write_text(json.dumps({ + "ready": True, "run_label": "old", "summary": {"passed": 1}})) + out = tr.run(results_dir=tmp_path) + assert out["surface"] is None