135 lines
5.5 KiB
Python
135 lines
5.5 KiB
Python
"""Unit tests for test-case path parsing and fallback metric labeling behavior."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
from pathlib import Path
|
|
|
|
from ci.scripts import publish_test_metrics
|
|
|
|
|
|
def test_collect_junit_cases_handles_missing_files_and_multiple_root_shapes(tmp_path: Path, monkeypatch):
|
|
missing = tmp_path / "missing.xml"
|
|
testsuites_path = tmp_path / "suite-cases.xml"
|
|
testsuites_path.write_text(
|
|
(
|
|
"<testsuites>"
|
|
'<testsuite tests="3">'
|
|
'<testcase classname="alpha" name="ok_case" />'
|
|
'<testcase classname="alpha" name="skip_case"><skipped /></testcase>'
|
|
'<testcase classname="alpha"><failure /></testcase>'
|
|
"</testsuite>"
|
|
"</testsuites>"
|
|
),
|
|
encoding="utf-8",
|
|
)
|
|
unknown_root_path = tmp_path / "unknown-root.xml"
|
|
unknown_root_path.write_text("<root><testcase classname='x' name='ignored' /></root>", encoding="utf-8")
|
|
|
|
monkeypatch.setattr(
|
|
publish_test_metrics,
|
|
"glob",
|
|
lambda _pattern: [str(missing), str(testsuites_path), str(unknown_root_path)],
|
|
)
|
|
|
|
cases = publish_test_metrics._collect_junit_cases("ignored-glob")
|
|
|
|
assert ("alpha.ok_case", "passed") in cases
|
|
assert ("alpha.skip_case", "skipped") in cases
|
|
assert not any(name.endswith("ignored") for name, _ in cases)
|
|
|
|
|
|
def test_build_payload_includes_explicit_test_case_series():
|
|
payload = publish_test_metrics._build_payload(
|
|
suite="titan-iac",
|
|
status="ok",
|
|
tests={"tests": 2, "failures": 1, "errors": 0, "skipped": 0},
|
|
test_cases=[("alpha::case_one", "failed"), ("beta::case_two", "passed")],
|
|
ok_count=3,
|
|
failed_count=1,
|
|
branch="main",
|
|
build_number="5",
|
|
workspace_line_coverage_percent=95.0,
|
|
source_lines_over_500=0,
|
|
check_statuses={"tests": "failed"},
|
|
)
|
|
|
|
assert 'platform_quality_gate_test_case_result{suite="titan-iac",test="alpha::case_one",status="failed"} 1' in payload
|
|
assert 'platform_quality_gate_test_case_result{suite="titan-iac",test="beta::case_two",status="passed"} 1' in payload
|
|
|
|
|
|
def test_main_uses_reported_coverage_and_loc_without_fallback(tmp_path: Path, monkeypatch, capsys):
|
|
build_dir = tmp_path / "build"
|
|
build_dir.mkdir()
|
|
(build_dir / "junit.xml").write_text(
|
|
'<testsuite tests="1" failures="0" errors="0" skipped="0" />',
|
|
encoding="utf-8",
|
|
)
|
|
(build_dir / "quality-gate.rc").write_text("0\n", encoding="utf-8")
|
|
(build_dir / "quality-gate-summary.json").write_text(
|
|
json.dumps(
|
|
{
|
|
"workspace_line_coverage_percent": 99.5,
|
|
"source_lines_over_500": 2,
|
|
"results": [],
|
|
}
|
|
),
|
|
encoding="utf-8",
|
|
)
|
|
|
|
monkeypatch.setenv("JUNIT_GLOB", str(build_dir / "*.xml"))
|
|
monkeypatch.setenv("QUALITY_GATE_EXIT_CODE_PATH", str(build_dir / "quality-gate.rc"))
|
|
monkeypatch.setenv("QUALITY_GATE_SUMMARY_PATH", str(build_dir / "quality-gate-summary.json"))
|
|
monkeypatch.setattr(publish_test_metrics, "_fetch_existing_counter", lambda *args, **kwargs: 0)
|
|
monkeypatch.setattr(publish_test_metrics, "_post_text", lambda *args, **kwargs: None)
|
|
monkeypatch.setattr(
|
|
publish_test_metrics,
|
|
"_infer_workspace_coverage_percent",
|
|
lambda *args, **kwargs: (_ for _ in ()).throw(AssertionError("should not infer coverage")),
|
|
)
|
|
monkeypatch.setattr(
|
|
publish_test_metrics,
|
|
"_infer_source_lines_over_500",
|
|
lambda *args, **kwargs: (_ for _ in ()).throw(AssertionError("should not infer loc")),
|
|
)
|
|
|
|
rc = publish_test_metrics.main()
|
|
|
|
summary = json.loads(capsys.readouterr().out)
|
|
assert rc == 0
|
|
assert summary["workspace_line_coverage_percent"] == 99.5
|
|
assert summary["source_lines_over_500"] == 2
|
|
|
|
|
|
def test_main_falls_back_to_inferred_coverage_and_loc(tmp_path: Path, monkeypatch, capsys):
|
|
build_dir = tmp_path / "build"
|
|
build_dir.mkdir()
|
|
(build_dir / "junit.xml").write_text(
|
|
'<testsuite tests="1" failures="0" errors="0" skipped="0" />',
|
|
encoding="utf-8",
|
|
)
|
|
(build_dir / "quality-gate.rc").write_text("1\n", encoding="utf-8")
|
|
(build_dir / "quality-gate-summary.json").write_text(
|
|
json.dumps({"workspace_line_coverage_percent": 0.0, "source_lines_over_500": 0, "results": []}),
|
|
encoding="utf-8",
|
|
)
|
|
|
|
posted = {}
|
|
monkeypatch.setenv("JUNIT_GLOB", str(build_dir / "*.xml"))
|
|
monkeypatch.setenv("QUALITY_GATE_EXIT_CODE_PATH", str(build_dir / "quality-gate.rc"))
|
|
monkeypatch.setenv("QUALITY_GATE_SUMMARY_PATH", str(build_dir / "quality-gate-summary.json"))
|
|
monkeypatch.setattr(publish_test_metrics, "_fetch_existing_counter", lambda *args, **kwargs: 0)
|
|
monkeypatch.setattr(publish_test_metrics, "_post_text", lambda url, payload: posted.update({"url": url, "payload": payload}))
|
|
monkeypatch.setattr(publish_test_metrics, "_infer_workspace_coverage_percent", lambda *args, **kwargs: 96.4)
|
|
monkeypatch.setattr(publish_test_metrics, "_infer_source_lines_over_500", lambda *args, **kwargs: 7)
|
|
|
|
rc = publish_test_metrics.main()
|
|
|
|
summary = json.loads(capsys.readouterr().out)
|
|
assert rc == 0
|
|
assert summary["status"] == "failed"
|
|
assert summary["workspace_line_coverage_percent"] == 96.4
|
|
assert summary["source_lines_over_500"] == 7
|
|
assert 'platform_quality_gate_workspace_line_coverage_percent{suite="titan_iac"} 96.400' in posted["payload"]
|
|
assert 'platform_quality_gate_source_lines_over_500_total{suite="titan_iac"} 7' in posted["payload"]
|