diff --git a/scripts/publish_test_metrics.py b/scripts/publish_test_metrics.py index 6b1c52b..3834c90 100644 --- a/scripts/publish_test_metrics.py +++ b/scripts/publish_test_metrics.py @@ -6,6 +6,7 @@ from __future__ import annotations import json import os from pathlib import Path +import urllib.error import urllib.request import xml.etree.ElementTree as ET @@ -88,6 +89,20 @@ def _load_junit_cases(path: str) -> list[tuple[str, str]]: return cases +def _dedupe_test_cases(test_cases: list[tuple[str, str]]) -> list[tuple[str, str]]: + """Return one sample per Prometheus test/status labelset.""" + + seen: set[tuple[str, str]] = set() + deduped: list[tuple[str, str]] = [] + for test_id, status in test_cases: + key = (test_id, status) + if key in seen: + continue + seen.add(key) + deduped.append(key) + return deduped + + def _load_exit_code(path: str) -> int | None: if not path or not os.path.exists(path): return None @@ -108,9 +123,14 @@ def _post_text(url: str, payload: str) -> None: method="PUT", headers={"Content-Type": "text/plain"}, ) - with urllib.request.urlopen(req, timeout=10) as resp: - if resp.status >= 400: - raise RuntimeError(f"metrics push failed status={resp.status}") + try: + with urllib.request.urlopen(req, timeout=10) as resp: + if resp.status >= 400: + raise RuntimeError(f"metrics push failed status={resp.status}") + except urllib.error.HTTPError as exc: + body = exc.read().decode("utf-8", errors="replace").strip() + detail = f": {body}" if body else "" + raise RuntimeError(f"metrics push failed status={exc.code}{detail}") from exc def _read_http(url: str) -> str: @@ -248,7 +268,7 @@ def main() -> int: coverage = _load_coverage(coverage_path) totals = _load_junit(junit_path) - test_cases = _load_junit_cases(junit_path) + test_cases = _dedupe_test_cases(_load_junit_cases(junit_path)) test_exit_code = _load_exit_code(test_exit_code_path) docs_exit_code = _load_exit_code(docs_exit_code_path) source_files_total = _count_source_files(repo_root)