78 lines
3.8 KiB
Python
78 lines
3.8 KiB
Python
"""Check actual Maven reports against A01-A20; no third-party packages or credentials."""
|
|
import argparse
|
|
import hashlib
|
|
import json
|
|
from pathlib import Path
|
|
import re
|
|
import sys
|
|
import xml.etree.ElementTree as ET
|
|
|
|
|
|
def inspect(root, manifest):
|
|
failures, found, totals, environments = [], {}, {"unit": 0, "integration": 0}, set()
|
|
expected = {f"A{i:02}" for i in range(1, 21)}
|
|
if set(manifest) != expected:
|
|
failures.append("Manifest must contain exactly A01-A20")
|
|
for group, folder in (("unit", "surefire-reports"), ("integration", "failsafe-reports")):
|
|
paths = sorted((root / folder).glob("TEST-*.xml"))
|
|
if not paths:
|
|
failures.append(f"Missing {folder}")
|
|
for path in paths:
|
|
suite = ET.parse(path).getroot()
|
|
for flag in ("failures", "errors", "skipped"):
|
|
if int(suite.get(flag, "0")):
|
|
failures.append(f"{suite.get('name')}: {flag}={suite.get(flag)}")
|
|
tests = suite.findall("testcase")
|
|
totals[group] += len(tests)
|
|
if group == "integration":
|
|
external = any(p.get("name") == "migration.test.external" and p.get("value") == "true"
|
|
for p in suite.findall("./properties/property"))
|
|
environments.add("external-postgresql" if external else "testcontainers")
|
|
for test in tests:
|
|
method = re.split(r"[\[(]", test.get("name", ""), maxsplit=1)[0]
|
|
key = test.get("classname", "").rsplit(".", 1)[-1] + "#" + method
|
|
ok = not any(test.find(tag) is not None for tag in ("failure", "error", "skipped"))
|
|
if not ok:
|
|
failures.append(f"Unsuccessful testcase: {key}")
|
|
found.setdefault(key, []).append(ok)
|
|
cases = {}
|
|
for case, references in sorted(manifest.items()):
|
|
if not references:
|
|
failures.append(f"{case}: no test references")
|
|
evidence = {}
|
|
for reference in references:
|
|
runs = found.get(reference, [])
|
|
evidence[reference] = {"executed": len(runs), "passed": sum(runs)}
|
|
if not runs or not all(runs):
|
|
failures.append(f"{case}: missing/failed/skipped {reference}")
|
|
cases[case] = evidence
|
|
if len(environments) != 1:
|
|
failures.append("Missing or mixed integration environments")
|
|
return {"passed": not failures, "environment": sorted(environments), "tests": totals,
|
|
"cases": cases, "failures": failures}
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument("--reports", type=Path, default=Path("target"))
|
|
parser.add_argument("--manifest", type=Path, default=Path("specs/acceptance-cases.json"))
|
|
parser.add_argument("--output", type=Path, default=Path("target/acceptance-report.json"))
|
|
parser.add_argument("--require-testcontainers", action="store_true")
|
|
args = parser.parse_args()
|
|
result = inspect(args.reports, json.loads(args.manifest.read_text(encoding="utf-8-sig")))
|
|
if args.require_testcontainers and result["environment"] != ["testcontainers"]:
|
|
result["passed"] = False
|
|
result["failures"].append("Docker/Testcontainers evidence required; external PostgreSQL is not equivalent")
|
|
result["manifestSha256"] = hashlib.sha256(args.manifest.read_bytes()).hexdigest()
|
|
jar = args.reports / "orquestador-nmp-0.1.0-SNAPSHOT.jar"
|
|
if jar.is_file():
|
|
result["jarSha256"] = hashlib.sha256(jar.read_bytes()).hexdigest()
|
|
args.output.parent.mkdir(parents=True, exist_ok=True)
|
|
args.output.write_text(json.dumps(result, indent=2) + "\n", encoding="utf-8")
|
|
print(json.dumps({k: result[k] for k in ("passed", "environment", "tests", "failures")}))
|
|
return 0 if result["passed"] else 1
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|