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:
@@ -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)"
|
||||||
)
|
)
|
||||||
Reference in New Issue
Block a user