From a80d46606e53d383a8534412f16978fe8c3c1c71 Mon Sep 17 00:00:00 2001 From: Brad Stein Date: Fri, 10 Apr 2026 06:24:22 -0300 Subject: [PATCH] ci: fix backend pytest import path and publish junit test counts --- Jenkinsfile | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/Jenkinsfile b/Jenkinsfile index 979e006..5e83b25 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -173,6 +173,7 @@ spec: sh ''' set -euo pipefail mkdir -p build + export PYTHONPATH="${WORKSPACE}/backend:${PYTHONPATH:-}" python -m pip install --no-cache-dir -r backend/requirements.txt pytest pytest-mock python -m pytest backend/tests -q --junitxml=build/junit-backend.xml ''' @@ -227,6 +228,8 @@ spec: import os import re import urllib.request +import xml.etree.ElementTree as ET +from pathlib import Path suite = os.environ.get("SUITE_NAME", "bstein-home") status = os.environ.get("QUALITY_STATUS", "failed") @@ -247,10 +250,30 @@ if status == "ok": ok += 1 else: failed += 1 + +totals = {"tests": 0, "failures": 0, "errors": 0, "skipped": 0} +junit_path = Path("build/junit-backend.xml") +if junit_path.exists(): + root = ET.parse(junit_path).getroot() + suites = [root] if root.tag == "testsuite" else list(root.findall("testsuite")) if root.tag == "testsuites" else [] + for node in suites: + for key in totals: + raw = node.attrib.get(key) or "0" + try: + totals[key] += int(float(raw)) + except ValueError: + pass +passed = max(totals["tests"] - totals["failures"] - totals["errors"] - totals["skipped"], 0) + payload = ( "# TYPE platform_quality_gate_runs_total counter\\n" f'platform_quality_gate_runs_total{{suite="{suite}",status="ok"}} {int(ok)}\\n' f'platform_quality_gate_runs_total{{suite="{suite}",status="failed"}} {int(failed)}\\n' + "# TYPE bstein_home_quality_gate_tests_total gauge\\n" + f'bstein_home_quality_gate_tests_total{{suite="{suite}",result="passed"}} {passed}\\n' + f'bstein_home_quality_gate_tests_total{{suite="{suite}",result="failed"}} {totals["failures"]}\\n' + f'bstein_home_quality_gate_tests_total{{suite="{suite}",result="error"}} {totals["errors"]}\\n' + f'bstein_home_quality_gate_tests_total{{suite="{suite}",result="skipped"}} {totals["skipped"]}\\n' ) req = urllib.request.Request( f"{gateway}/metrics/job/platform-quality-ci/suite/{suite}", @@ -272,6 +295,8 @@ PY import os import re import urllib.request +import xml.etree.ElementTree as ET +from pathlib import Path suite = os.environ.get("SUITE_NAME", "bstein-home") status = os.environ.get("QUALITY_STATUS", "failed") @@ -292,10 +317,30 @@ if status == "ok": ok += 1 else: failed += 1 + +totals = {"tests": 0, "failures": 0, "errors": 0, "skipped": 0} +junit_path = Path("build/junit-backend.xml") +if junit_path.exists(): + root = ET.parse(junit_path).getroot() + suites = [root] if root.tag == "testsuite" else list(root.findall("testsuite")) if root.tag == "testsuites" else [] + for node in suites: + for key in totals: + raw = node.attrib.get(key) or "0" + try: + totals[key] += int(float(raw)) + except ValueError: + pass +passed = max(totals["tests"] - totals["failures"] - totals["errors"] - totals["skipped"], 0) + payload = ( "# TYPE platform_quality_gate_runs_total counter\\n" f'platform_quality_gate_runs_total{{suite="{suite}",status="ok"}} {int(ok)}\\n' f'platform_quality_gate_runs_total{{suite="{suite}",status="failed"}} {int(failed)}\\n' + "# TYPE bstein_home_quality_gate_tests_total gauge\\n" + f'bstein_home_quality_gate_tests_total{{suite="{suite}",result="passed"}} {passed}\\n' + f'bstein_home_quality_gate_tests_total{{suite="{suite}",result="failed"}} {totals["failures"]}\\n' + f'bstein_home_quality_gate_tests_total{{suite="{suite}",result="error"}} {totals["errors"]}\\n' + f'bstein_home_quality_gate_tests_total{{suite="{suite}",result="skipped"}} {totals["skipped"]}\\n' ) req = urllib.request.Request( f"{gateway}/metrics/job/platform-quality-ci/suite/{suite}",