Private
Public Access
0
0

test(baseline): add 3 Phase 2 invariant tests (audit gate baseline)

TIER-2 READ conductor/code_styleguides/error_handling.md end-to-end before Phase 2.

Phase 2 tests assert the BASELINE state:
1. test_phase2_baseline_audit_runs: audit --include-baseline --json exits 0
2. test_phase2_all_3_targets_have_migration_sites: each baseline file has >0 MIG
3. test_phase2_per_file_baseline_counts_match_inventory: counts = 46/33/9

Total: 7 tests pass (4 Phase 1 + 3 Phase 2).
This commit is contained in:
2026-06-20 08:18:37 -04:00
parent d06c4fdb52
commit 4d391fd42f
+56 -8
View File
@@ -1,11 +1,11 @@
"""Phase 1 invariant tests for result_migration_baseline_cleanup_20260620. """Phase 1 + Phase 2 invariant tests for result_migration_baseline_cleanup_20260620.
Asserts: Phase 1: 4 tests assert the audit + inventory docs match expected counts.
1. The 3 baseline files have the expected site counts (audit per-file totals) Phase 2: 3 tests assert the BASELINE state is correct (88 migration-target sites
2. Migration-target total = 88 (46 + 33 + 9) in 3 files; the migration is starting from this exact state).
3. PHASE1_AUDIT_BASELINE.json + 3 inventory docs exist and have correct counts
""" """
import json import json
import subprocess
from collections import Counter from collections import Counter
from pathlib import Path from pathlib import Path
@@ -23,8 +23,15 @@ EXPECTED = {
"src\\ai_client.py": (17, 9, 0, 7, 0, 33), "src\\ai_client.py": (17, 9, 0, 7, 0, 33),
"src\\rag_engine.py": (5, 1, 0, 3, 0, 9), "src\\rag_engine.py": (5, 1, 0, 3, 0, 9),
} }
TARGETS = ("src\\mcp_client.py", "src\\ai_client.py", "src\\rag_engine.py")
def _load_audit():
return json.loads(AUDIT_PATH.read_text(encoding="utf-8"))
# ============ Phase 1 tests (4) ============
def test_phase1_audit_json_exists(): def test_phase1_audit_json_exists():
assert AUDIT_PATH.exists(), f"missing audit json at {AUDIT_PATH}" assert AUDIT_PATH.exists(), f"missing audit json at {AUDIT_PATH}"
@@ -32,12 +39,11 @@ def test_phase1_audit_json_exists():
def test_phase1_inventory_docs_exist(): def test_phase1_inventory_docs_exist():
for p in [INV_MCP, INV_AI, INV_RAG]: for p in [INV_MCP, INV_AI, INV_RAG]:
assert p.exists(), f"missing inventory doc at {p}" assert p.exists(), f"missing inventory doc at {p}"
# Each inventory doc should have at least 1 KB of content
assert p.stat().st_size > 500, f"inventory doc {p} too small" assert p.stat().st_size > 500, f"inventory doc {p} too small"
def test_phase1_total_migration_target_is_88(): def test_phase1_total_migration_target_is_88():
data = json.loads(AUDIT_PATH.read_text(encoding="utf-8")) data = _load_audit()
files = {f["filename"]: f for f in data["files"]} files = {f["filename"]: f for f in data["files"]}
total = 0 total = 0
for key in EXPECTED: for key in EXPECTED:
@@ -49,7 +55,7 @@ def test_phase1_total_migration_target_is_88():
def test_phase1_per_file_site_counts(): def test_phase1_per_file_site_counts():
"""mcp=46, ai=33, rag=9 = (BC, SS, OPT, RETHROW, UNCLEAR, total)""" """mcp=46, ai=33, rag=9 = (BC, SS, OPT, RETHROW, UNCLEAR, total)"""
data = json.loads(AUDIT_PATH.read_text(encoding="utf-8")) data = _load_audit()
files = {f["filename"]: f for f in data["files"]} files = {f["filename"]: f for f in data["files"]}
for key, expected in EXPECTED.items(): for key, expected in EXPECTED.items():
findings = files[key]["findings"] findings = files[key]["findings"]
@@ -64,4 +70,46 @@ def test_phase1_per_file_site_counts():
f"{key}: expected BC={expected[0]} SS={expected[1]} OPT={expected[2]} " f"{key}: expected BC={expected[0]} SS={expected[1]} OPT={expected[2]} "
f"RETHROW={expected[3]} UNCLEAR={expected[4]} MIG={expected[5]}, " f"RETHROW={expected[3]} UNCLEAR={expected[4]} MIG={expected[5]}, "
f"got BC={bc} SS={ss} OPT={opt} RETHROW={rethrow} UNCLEAR={unclear} MIG={mig}" f"got BC={bc} SS={ss} OPT={opt} RETHROW={rethrow} UNCLEAR={unclear} MIG={mig}"
)
# ============ Phase 2 tests (3) ============
def test_phase2_baseline_audit_runs():
"""The audit --include-baseline --json command exits 0."""
r = subprocess.run(
["uv", "run", "python", "scripts/audit_exception_handling.py",
"--include-baseline", "--json"],
capture_output=True, text=True
)
assert r.returncode == 0, f"audit failed: {r.stderr[:500]}"
data = json.loads(r.stdout)
assert "files" in data
assert len(data["files"]) >= 40, f"expected 40+ files, got {len(data['files'])}"
def test_phase2_all_3_targets_have_migration_sites():
"""Each of the 3 baseline files has at least 1 migration-target site."""
data = _load_audit()
files = {f["filename"]: f for f in data["files"]}
for target in TARGETS:
assert target in files, f"missing target file: {target}"
mig = [f for f in files[target]["findings"] if f["category"] in MIG]
assert len(mig) > 0, f"{target} has 0 migration-target sites (expected >0)"
def test_phase2_per_file_baseline_counts_match_inventory():
"""The baseline per-file counts match the Phase 1 inventory docs."""
data = _load_audit()
files = {f["filename"]: f for f in data["files"]}
BASELINE = {
"src\\mcp_client.py": 46,
"src\\ai_client.py": 33,
"src\\rag_engine.py": 9,
}
for target, expected in BASELINE.items():
mig = [f for f in files[target]["findings"] if f["category"] in MIG]
assert len(mig) == expected, (
f"{target}: baseline expected {expected}, got {len(mig)} "
f"(a previous phase may have introduced a violation)"
) )