test: enforce Wave A quality lock

This commit is contained in:
Joseph Magly
2026-08-14 19:47:46 -04:00
parent 57523ab483
commit 9746c21b63
18 changed files with 1712 additions and 44 deletions
+149
View File
@@ -0,0 +1,149 @@
#!/usr/bin/env python3
"""Validate the source-to-test risk map and conditional coverage graph."""
from __future__ import annotations
import argparse
import json
from pathlib import Path
from typing import Any
RISK_CLASSES = {"cpu-contract", "mixed-runtime", "conditional-runtime"}
def _load_object(path: Path, label: str, errors: list[str]) -> dict[str, Any]:
try:
value = json.loads(path.read_text(encoding="utf-8"))
except (OSError, json.JSONDecodeError) as exc:
errors.append(f"cannot read {label}: {exc}")
return {}
if not isinstance(value, dict):
errors.append(f"{label} root must be an object")
return {}
return value
def validate(risk_path: Path, quality_path: Path, conditional_path: Path) -> list[str]:
"""Return structural and cross-policy failures for the risk map."""
errors: list[str] = []
risk = _load_object(risk_path, "test risk map", errors)
quality = _load_object(quality_path, "quality policy", errors)
conditional = _load_object(conditional_path, "conditional policy", errors)
if errors:
return errors
if risk.get("schema_version") != 1:
errors.append("test risk map schema_version must be 1")
if not isinstance(risk.get("owner"), str) or not risk["owner"].strip():
errors.append("test risk map requires a non-empty owner")
gates = conditional.get("gates")
gate_by_id = {
gate.get("id"): gate
for gate in gates if isinstance(gate, dict) and isinstance(gate.get("id"), str)
} if isinstance(gates, list) else {}
modules = risk.get("modules")
if not isinstance(modules, list) or not modules:
return errors + ["test risk map modules must be a non-empty list"]
module_by_path: dict[str, dict[str, Any]] = {}
for index, module in enumerate(modules):
label = f"risk module {index}"
if not isinstance(module, dict):
errors.append(f"{label} must be an object")
continue
path = module.get("path")
if not isinstance(path, str) or not path:
errors.append(f"{label} requires a non-empty path")
continue
if path in module_by_path:
errors.append(f"duplicate risk module path: {path}")
module_by_path[path] = module
if not Path(path).is_file():
errors.append(f"risk module maps missing source path: {path}")
if module.get("risk_class") not in RISK_CLASSES:
errors.append(f"risk module {path} has invalid risk_class")
if not isinstance(module.get("risk"), str) or not module["risk"].strip():
errors.append(f"risk module {path} requires a non-empty risk")
tests = module.get("required_tests")
if not isinstance(tests, list) or not tests:
errors.append(f"risk module {path} requires at least one test")
else:
for test_path in tests:
if not isinstance(test_path, str) or not test_path.startswith("tests/"):
errors.append(f"risk module {path} has invalid test path: {test_path!r}")
elif not Path(test_path).is_file():
errors.append(f"risk module {path} maps missing test path: {test_path}")
module_gates = module.get("conditional_gates")
if not isinstance(module_gates, list):
errors.append(f"risk module {path} conditional_gates must be a list")
continue
if len(module_gates) != len(set(module_gates)):
errors.append(f"risk module {path} has duplicate conditional gates")
for gate_id in module_gates:
gate = gate_by_id.get(gate_id)
if gate is None:
errors.append(f"risk module {path} references unknown gate {gate_id}")
elif path not in gate.get("coverage_paths", []):
errors.append(f"risk module {path} is not covered by gate {gate_id}")
exclusions = quality.get("mature_cpu_scope", {}).get("exclusions", [])
if not isinstance(exclusions, list):
errors.append("quality policy exclusions must be a list")
exclusions = []
for exclusion in exclusions:
if not isinstance(exclusion, dict):
errors.append("quality policy exclusion must be an object")
continue
path = exclusion.get("path")
gate_id = exclusion.get("conditional_gate")
module = module_by_path.get(path)
if module is None:
errors.append(f"CPU exclusion is missing from test risk map: {path}")
elif gate_id not in module.get("conditional_gates", []):
errors.append(f"CPU exclusion {path} is missing conditional gate {gate_id}")
critical_paths = quality.get("critical_cpu_paths", [])
if not isinstance(critical_paths, list):
errors.append("quality policy critical_cpu_paths must be a list")
critical_paths = []
for path in critical_paths:
if path not in module_by_path:
errors.append(f"critical CPU path is missing from test risk map: {path}")
for gate_id, gate in gate_by_id.items():
for path in gate.get("coverage_paths", []):
module = module_by_path.get(path)
if module is None:
errors.append(f"conditional path is missing from test risk map: {path}")
elif gate_id not in module.get("conditional_gates", []):
errors.append(f"risk module {path} is missing conditional gate {gate_id}")
return errors
def main() -> int:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--risk-map", type=Path, default=Path("ci/test-risk-map.json"))
parser.add_argument("--quality", type=Path, default=Path("ci/test-quality-policy.json"))
parser.add_argument(
"--conditional",
type=Path,
default=Path("ci/conditional-test-policy.json"),
)
args = parser.parse_args()
errors = validate(args.risk_map, args.quality, args.conditional)
if errors:
for error in errors:
print(f"ERROR: {error}")
return 1
print("test risk map: valid")
return 0
if __name__ == "__main__":
raise SystemExit(main())