"""Contracts for Hermes' Jenkins build-evidence reader boundary.""" from __future__ import annotations import importlib.util import sys from pathlib import Path import pytest ROOT = Path(__file__).parents[2] HERMES = ROOT / "services" / "hermes" SCRIPTS = HERMES / "scripts" SCM_SCRIPTS = HERMES / "scm-common" / "scripts" if str(SCRIPTS) not in sys.path: sys.path.insert(0, str(SCRIPTS)) if str(SCM_SCRIPTS) not in sys.path: sys.path.insert(0, str(SCM_SCRIPTS)) def _load(name: str): root = SCM_SCRIPTS if name == "gitea_api" else SCRIPTS spec = importlib.util.spec_from_file_location(name, root / f"{name}.py") assert spec and spec.loader module = importlib.util.module_from_spec(spec) sys.modules[spec.name] = module spec.loader.exec_module(module) return module def test_jenkins_evidence_ignores_nested_execution_result(): evidence_reader = _load("jenkins_build_evidence") evidence = evidence_reader.parse_build_xml( """ abc123 10000 SUCCESS """, job="demo", branch="master", number=15, ) assert evidence.revision == "abc123" assert evidence.result is None assert evidence.building is True def test_jenkins_evidence_reads_only_top_level_terminal_result(): evidence_reader = _load("jenkins_build_evidence") evidence = evidence_reader.parse_build_xml( """ abc123 1000250 FAILURE SUCCESS """, job="demo", branch=None, number=4, ) assert evidence.result == "FAILURE" assert evidence.building is False assert evidence.duration_ms == 250 def test_jenkins_evidence_removes_hidden_links_and_ansi_control_sequences(): evidence_reader = _load("jenkins_build_evidence") value = ( "before\n\x1b[8mha:////private-jenkins-payload\x1b[0m[Pipeline] sh\n" "\x1b[31m5 passed\x1b[0m\n" ) assert evidence_reader.sanitize_log(value) == "before\n[Pipeline] sh\n5 passed\n" def test_jenkins_evidence_falls_back_to_multibranch_suffix(monkeypatch): evidence_reader = _load("jenkins_build_evidence") calls = [] def fake_find(job, branch, commit, log_lines): calls.append((job, branch, commit, log_lines)) if job == "demo": raise ValueError("not a multibranch job") return "evidence" monkeypatch.setattr(evidence_reader, "_find_build_for_job", fake_find) assert evidence_reader.find_build("demo", "master", "abc", 20) == "evidence" assert [call[0] for call in calls] == ["demo", "demo-branches"] @pytest.mark.parametrize("branch", ["../master", "/master", "feature//unsafe"]) def test_jenkins_evidence_rejects_unsafe_branch_paths(branch: str): evidence_reader = _load("jenkins_build_evidence") with pytest.raises(ValueError): evidence_reader._validate_branch(branch)