#!/usr/bin/env python3 """Run Engine contract coverage via Pulumi Automation API and write HTML report.""" from __future__ import annotations import json import os import subprocess import sys from pathlib import Path from pulumi import automation as auto WORK_DIR = Path(__file__).resolve().parent ROOT = WORK_DIR.parent def main() -> int: os.environ.setdefault("PULUMI_CONFIG_PASSPHRASE", "ovirt-lab") state_dir = WORK_DIR / ".pulumi-state" state_dir.mkdir(parents=True, exist_ok=True) backend = os.environ.setdefault("PULUMI_BACKEND_URL", f"file://{state_dir}") report_dir = Path(os.environ.setdefault("REPORT_DIR", str(ROOT / "reports"))) report_dir.mkdir(parents=True, exist_ok=True) pythonpath = os.environ.get("PYTHONPATH", "") parts = [str(ROOT), str(WORK_DIR)] os.environ["PYTHONPATH"] = os.pathsep.join(parts + ([pythonpath] if pythonpath else [])) if str(ROOT) not in sys.path: sys.path.insert(0, str(ROOT)) if str(WORK_DIR) not in sys.path: sys.path.insert(0, str(WORK_DIR)) from coverage.executor import _FULL_RUN_METHODS, report_to_dict, run_coverage from coverage.report import write_reports from shared.config import SuiteConfig print("Running Engine contract coverage…", flush=True) cfg = SuiteConfig.from_env() report = run_coverage(cfg) payload = report_to_dict(report) json_path, html_path = write_reports(payload, report_dir) totals = payload["totals"] methods = payload.get("methods") or {} series_names = [s["series"] for s in payload["series"]] summary_path = report_dir / "pulumi-stack-summary.json" summary_path.write_text( json.dumps( { "total": totals["total"], "passed": totals["passed"], "failed": totals["failed"], "skipped": totals["skipped"], "coverage": payload.get("coverage"), "methods": methods, "series": series_names, "report_json": str(json_path), "report_html": str(html_path), }, indent=2, ) + "\n", encoding="utf-8", ) subprocess.check_call(["pulumi", "login", backend], cwd=str(WORK_DIR)) def pulumi_program() -> None: import pulumi data = json.loads(summary_path.read_text(encoding="utf-8")) for key, value in data.items(): pulumi.export(key, value) stack_name = os.environ.get("PULUMI_STACK", "dev") stack = auto.create_or_select_stack( stack_name=stack_name, project_name="ovirt-contract-coverage", program=pulumi_program, ) print(f"Publishing results to Pulumi stack {stack_name}…", flush=True) result = stack.up(on_output=print) outputs = {k: v.value for k, v in result.outputs.items()} print(json.dumps({"outputs": outputs}, indent=2), flush=True) failed = int(outputs.get("failed") or totals["failed"]) total = int(outputs.get("total") or totals["total"]) passed = int(outputs.get("passed") or totals["passed"]) coverage = payload.get("coverage") or {} declared = int(coverage.get("declared") or total) probed = int(coverage.get("probed") or (passed + failed + int(totals.get("skipped") or 0))) critical = int(coverage.get("critical") or failed) print(f"SUMMARY total={total} passed={passed} failed={failed}", flush=True) print(f"COVERAGE {probed}/{declared} (critical={critical})", flush=True) print(f"METHODS {json.dumps(methods, sort_keys=True)}", flush=True) print(f"HTML report: {html_path}", flush=True) full_run = not cfg.smoke_only and not cfg.methods_filter missing_methods = sorted(_FULL_RUN_METHODS - set(methods)) if full_run else [] if missing_methods: print(f"MISSING METHODS on full run: {', '.join(missing_methods)}", flush=True) if probed != declared: print(f"COVERAGE MISMATCH probed={probed} declared={declared}", flush=True) if failed or missing_methods or critical or probed != declared: return 1 return 0 if __name__ == "__main__": raise SystemExit(main())