Files
StarPilot/tools/ci/run_map_tests.py
T
firestar5683 ab81464bd1 Maps
Add navigation and map matching providers with the vendored map service sources.

Co-authored-by: Daniel Koepping <elkoled@gmail.com>
Co-authored-by: Danny <dannyirwin31@yahoo.com>
Co-authored-by: Prabhaav Pillai <prabhaav@msu.edu>
Co-authored-by: dirwin31 <83434411+dirwin31@users.noreply.github.com>
2026-10-14 19:56:17 -05:00

94 lines
4.6 KiB
Python

#!/usr/bin/env python3
"""Test and build the pinned map provider, with optional isolated shadow IPC tests."""
import argparse
from collections import Counter
import hashlib
import json
import os
from pathlib import Path
import shutil
import subprocess
import time
ROOT = Path(__file__).resolve().parents[2]
SOURCE = ROOT / "mapd_repo"
def source_identity():
files = {path.relative_to(SOURCE).as_posix(): hashlib.sha256(path.read_bytes()).hexdigest()
for path in SOURCE.rglob("*") if path.is_file() and
path.relative_to(SOURCE).parts[0] not in (".git", "build", "media", "offline")}
return {"revision": subprocess.check_output(["git", "rev-parse", "HEAD"], cwd=ROOT, text=True).strip(),
"manifest_sha256": hashlib.sha256((ROOT / "upstream-sync.json").read_bytes()).hexdigest(),
"files": files}
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--go", default="go", help="Go executable; go.mod selects the supported version")
parser.add_argument("--output", type=Path, required=True, help="New directory outside mapd_repo")
args = parser.parse_args()
output = args.output.resolve()
if output == SOURCE or SOURCE in output.parents:
parser.error("Test output must be outside provider source")
if output.exists():
parser.error("Use a fresh evidence directory")
go = shutil.which(args.go)
if go is None:
parser.error("Go is not installed; install the version recorded in mapd_repo/go.mod")
output.mkdir(parents=True)
env = dict(os.environ, GOTOOLCHAIN="local")
before = source_identity()
manifest = json.loads((ROOT / "upstream-sync.json").read_text())
pin = next(entry for entry in manifest["dependencies"] if entry["path"] == "mapd_repo")
report = {"provider": pin, "source_before": before, "commands": [], "tests": []}
report["required_ipc_targets"] = {
"go_to_host": env.get("STARPILOT_SHADOW_IPC_REQUIRED") == "1",
"host_gps_to_shadow_executable": env.get("STARPILOT_SHADOW_EXEC_REQUIRED") == "1",
}
digest = hashlib.sha256(json.dumps(before["files"], sort_keys=True).encode()).hexdigest()
report["source_digest"] = digest
def run(label, arguments):
command = [go, *arguments]
start = time.monotonic()
with (output / f"{label}.stdout").open("w") as stdout, (output / f"{label}.stderr").open("w") as stderr:
result = subprocess.run(command, cwd=SOURCE, env=env, stdout=stdout, stderr=stderr)
report["commands"].append({"label": label, "command": command, "exit_code": result.returncode,
"duration_seconds": time.monotonic() - start})
return result.returncode
run("version", ["version"])
run("test", ["test", "-mod=readonly", "-json", "./..."])
for line in (output / "test.stdout").read_text().splitlines():
record = json.loads(line)
if record.get("Action") in ("pass", "fail", "skip"):
report["tests"].append({key: record[key] for key in ("Action", "Package", "Test", "Elapsed") if key in record})
run("vet", ["vet", "-mod=readonly", "./..."])
binary = output / "mapd"
stamp = f'-X main.sourceRevision={before["revision"]} -X main.upstreamRevision={pin["commit"]} -X main.sourceDigest={digest}'
built = run("build", ["build", "-mod=readonly", "-trimpath", "-buildvcs=true", "-ldflags", stamp, "-o", str(binary), "."])
if built == 0:
built_bytes = binary.read_bytes()
report["binary_sha256"] = hashlib.sha256(built_bytes).hexdigest()
report["embedded_source_stamps"] = all(value.encode() in built_bytes for value in (before["revision"], pin["commit"], digest))
run("build-info", ["version", "-m", str(binary)])
report["source_after"] = source_identity()
report["source_unchanged"] = before == report["source_after"]
report["counts"] = dict(Counter(item["Action"] for item in report["tests"] if "Test" in item))
report["passed"] = report["source_unchanged"] and report.get("embedded_source_stamps", False) and bool(report["counts"].get("pass")) and all(
command["exit_code"] == 0 for command in report["commands"])
report["scope"] = (
"Provider tests and build; the selected executable IPC fixture runs only temporary --shadow with private IPC/Params and synthetic tiles. "
if report["required_ipc_targets"]["host_gps_to_shadow_executable"] else
"Provider tests and build; provider executable not started. "
) + "No installed provider, real maps, route or device qualification."
(output / "results.json").write_text(json.dumps(report, indent=2) + "\n")
print(json.dumps({key: report[key] for key in ("passed", "counts", "source_unchanged", "scope")}))
return int(not report["passed"])
if __name__ == "__main__":
raise SystemExit(main())