mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-10-28 00:53:45 +08:00
72 lines
3.8 KiB
Python
72 lines
3.8 KiB
Python
"""Account for replay inputs separately from test execution and vehicle qualification."""
|
|
|
|
import json
|
|
from pathlib import Path
|
|
|
|
|
|
REQUIRED_REPLAY_LABELS = frozenset({
|
|
"HYUNDAI", "HYUNDAI2", "TOYOTA", "TOYOTA3", "HONDA", "HONDA2", "CHRYSLER", "RAM",
|
|
"SUBARU", "GM", "NISSAN", "VOLKSWAGEN", "MAZDA", "FORD", "RIVIAN", "TESLA",
|
|
})
|
|
VOLVO_UNRECORDED_PLATFORMS = frozenset({
|
|
"VOLVO_V40", "VOLVO_XC40_RECHARGE", "VOLVO_S60_RECHARGE", "POLESTAR_2",
|
|
})
|
|
VOLVO_REQUIRED_TESTS = {
|
|
"interfaces": ("opendbc_repo/opendbc/car/volvo/tests/test_c1.py",
|
|
"opendbc_repo/opendbc/car/volvo/tests/test_cma.py"),
|
|
"safety-debug": ("opendbc_repo/opendbc/safety/tests/test_volvo_c1.py",
|
|
"opendbc_repo/opendbc/safety/tests/test_volvo_cma.py"),
|
|
"safety-release": ("opendbc_repo/opendbc/safety/tests/test_volvo_c1.py",
|
|
"opendbc_repo/opendbc/safety/tests/test_volvo_cma.py"),
|
|
}
|
|
|
|
|
|
def replay_coverage(active_platforms, labels, suite_targets, *, full_test):
|
|
labels = set(labels)
|
|
recorded_brands = {label.lower() for label in labels}
|
|
errors = []
|
|
gaps = []
|
|
missing = set(active_platforms) - recorded_brands - {"body"}
|
|
if full_test:
|
|
absent_labels = REQUIRED_REPLAY_LABELS - labels
|
|
if absent_labels:
|
|
errors.append(f"Required replay inputs missing: {sorted(absent_labels)}")
|
|
if set(active_platforms.get("volvo", ())) != VOLVO_UNRECORDED_PLATFORMS:
|
|
errors.append("Volvo recording classification requires exactly the four known active platforms; review changed scope")
|
|
if "volvo" not in missing:
|
|
errors.append("Volvo recording classification is stale: Volvo now has a recording or is no longer active")
|
|
for suite, paths in VOLVO_REQUIRED_TESTS.items():
|
|
for path in paths:
|
|
if path not in suite_targets.get(suite, ()):
|
|
errors.append(f"Required Volvo source/native suite no longer selected: {suite}: {path}")
|
|
unaccounted = missing - {"volvo"}
|
|
if unaccounted:
|
|
errors.append(f"Active brands missing unaccounted replay inputs: {sorted(unaccounted)}")
|
|
if "volvo" in missing:
|
|
for platform in sorted(set(active_platforms.get("volvo", ())) & VOLVO_UNRECORDED_PLATFORMS):
|
|
path_index = 0 if platform == "VOLVO_V40" else 1
|
|
gaps.append({"brand": "volvo", "platforms": [platform], "status": "unrecorded",
|
|
"reason": f"No {platform} recording is available in the fixture catalog.",
|
|
"required_source_native_suites": {suite: paths[path_index] for suite, paths in VOLVO_REQUIRED_TESTS.items()}})
|
|
return {"schema_version": 1, "scope": "process_replay_input_inventory", "full_test": full_test,
|
|
"recorded_input_labels": sorted(labels), "active_platforms": active_platforms,
|
|
"unrecorded_gaps": gaps, "errors": errors,
|
|
"evidence_limit": "Input accounting only. Required source/native suites have independent execution results. This does not qualify the fleet."}
|
|
|
|
|
|
def write_coverage(report, destination, summary=None):
|
|
destination = Path(destination)
|
|
destination.parent.mkdir(parents=True, exist_ok=True)
|
|
destination.write_text(json.dumps(report, sort_keys=True, indent=2) + "\n")
|
|
if summary:
|
|
with Path(summary).open("a") as output:
|
|
output.write("\n### Process replay input coverage\n\n")
|
|
output.write(f"Full input inventory: {report['full_test']}; recorded inputs: {len(report['recorded_input_labels'])}.\n\n")
|
|
for gap in report["unrecorded_gaps"]:
|
|
output.write(f"- {gap['brand']} / {', '.join(gap['platforms'])}: **unrecorded**. {gap['reason']}\n")
|
|
for suite, path in gap["required_source_native_suites"].items():
|
|
output.write(f" Required independent source/native check: {suite}: `{path}`.\n")
|
|
for error in report["errors"]:
|
|
output.write(f"- Coverage error: {error}\n")
|
|
output.write(f"\n{report['evidence_limit']}\n")
|