Enforce Gate 3 test quality budgets

This commit is contained in:
Joseph Magly
2026-08-15 04:33:15 -04:00
parent 8456e52bf8
commit 753c53d07f
16 changed files with 919 additions and 17 deletions
+47 -2
View File
@@ -97,14 +97,40 @@ def junit_snapshot(path: Path) -> dict[str, Any]:
failures: list[str] = []
errors: list[str] = []
skipped: list[str] = []
durations: list[dict[str, str | float]] = []
durations: list[dict[str, Any]] = []
marker_totals: dict[str, dict[str, int | float]] = {}
missing_marker_nodeids: list[str] = []
for case in cases:
nodeid = f"{case.attrib.get('classname', '<unknown>')}::{case.attrib.get('name', '<unknown>')}"
try:
duration = float(case.attrib.get("time", "0"))
except ValueError as exc:
raise ValueError(f"JUnit testcase {nodeid} has invalid time") from exc
durations.append({"nodeid": nodeid, "seconds": duration})
if not math.isfinite(duration) or duration < 0:
raise ValueError(f"JUnit testcase {nodeid} has invalid time")
marker_property = None
properties = case.find("properties")
if properties is not None:
values = [
item.attrib.get("value", "")
for item in properties.findall("property")
if item.attrib.get("name") == "duration_markers"
]
if len(values) > 1:
raise ValueError(f"JUnit testcase {nodeid} repeats duration_markers")
marker_property = values[0] if values else None
if marker_property is None:
missing_marker_nodeids.append(nodeid)
markers = sorted({
marker.strip()
for marker in (marker_property or "unmarked").split(",")
if marker.strip()
})
durations.append({"nodeid": nodeid, "seconds": duration, "markers": markers})
for marker in markers:
summary = marker_totals.setdefault(marker, {"tests": 0, "duration_seconds": 0.0})
summary["tests"] = int(summary["tests"]) + 1
summary["duration_seconds"] = float(summary["duration_seconds"]) + duration
if case.find("failure") is not None:
failures.append(nodeid)
if case.find("error") is not None:
@@ -113,6 +139,20 @@ def junit_snapshot(path: Path) -> dict[str, Any]:
skipped.append(nodeid)
failed = set(failures) | set(errors) | set(skipped)
durations.sort(key=lambda item: (-float(item["seconds"]), str(item["nodeid"])))
suites = list(root.iter("testsuite"))
raw_suite_duration = suites[0].attrib.get("time") if suites else None
try:
suite_duration = (
float(raw_suite_duration)
if raw_suite_duration is not None
else sum(float(item["seconds"]) for item in durations)
)
except ValueError as exc:
raise ValueError("JUnit testsuite has invalid time") from exc
if not math.isfinite(suite_duration) or suite_duration < 0:
raise ValueError("JUnit testsuite has invalid time")
for summary in marker_totals.values():
summary["duration_seconds"] = round(float(summary["duration_seconds"]), 3)
return {
"total": len(cases),
"passed": len(cases) - len(failed),
@@ -120,6 +160,11 @@ def junit_snapshot(path: Path) -> dict[str, Any]:
"errors": errors,
"skipped": skipped,
"duration_seconds": round(sum(float(item["seconds"]) for item in durations), 3),
"suite_duration_seconds": round(suite_duration, 3),
"durations": durations,
"marker_durations": dict(sorted(marker_totals.items())),
"marker_metadata_complete": not missing_marker_nodeids,
"missing_marker_nodeids": missing_marker_nodeids,
"slowest": durations[:20],
}