test(hermes): cover hung-build detection to the coverage contract

Build 411 failed the per-file coverage contract at 88.89% against the 95%
threshold: the module shipped exercised only indirectly through the tick, so
its defensive branches were never reached. Cover the unreadable, zero,
negative and future timestamps, the disabled cap, the finished build, and
bundle construction from an empty payload. Module now at 100%.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
codex 2026-08-06 05:46:02 -03:00
parent 1b29b56f50
commit e327690077

View File

@ -0,0 +1,96 @@
"""Tests for detecting Jenkins builds that never reach a terminal result."""
from __future__ import annotations
from ariadne.services import hermes_hung_builds as module
NOW = 1_800_000_000.0
_MINUTE_MS = 60_000
def _build(minutes_ago: float, building: bool = True, **overrides): # type: ignore[no-untyped-def]
payload = {
"number": 272,
"building": building,
"timestamp": int((NOW - minutes_ago * 60) * 1000),
"url": "https://ci.example/job/metis/272/",
}
payload.update(overrides)
return payload
def test_elapsed_minutes_measures_from_the_start_timestamp() -> None:
assert module.elapsed_minutes(_build(75), now=NOW) == 75.0
def test_elapsed_minutes_treats_an_unreadable_start_as_zero() -> None:
"""An unreadable timestamp must never look like a hung build."""
assert module.elapsed_minutes({}, now=NOW) == 0.0
assert module.elapsed_minutes({"timestamp": None}, now=NOW) == 0.0
assert module.elapsed_minutes({"timestamp": "not-a-number"}, now=NOW) == 0.0
assert module.elapsed_minutes({"timestamp": 0}, now=NOW) == 0.0
assert module.elapsed_minutes({"timestamp": -5}, now=NOW) == 0.0
def test_elapsed_minutes_never_goes_negative() -> None:
"""A clock skewed into the future must not produce a negative age."""
assert module.elapsed_minutes(_build(-30), now=NOW) == 0.0
def test_elapsed_minutes_defaults_to_the_wall_clock() -> None:
assert module.elapsed_minutes(_build(0.0, timestamp=1)) > 0.0
def test_a_running_build_past_the_cap_is_hung() -> None:
assert module.is_hung(_build(75), 45.0, now=NOW) is True
def test_a_running_build_within_the_cap_is_not_hung() -> None:
assert module.is_hung(_build(10), 45.0, now=NOW) is False
assert module.is_hung(_build(45), 45.0, now=NOW) is False
def test_a_finished_build_is_never_hung() -> None:
"""Terminal builds are the normal path's business, not this one."""
assert module.is_hung(_build(600, building=False), 45.0, now=NOW) is False
assert module.is_hung({"timestamp": 1}, 45.0, now=NOW) is False
def test_a_non_positive_cap_disables_the_check() -> None:
assert module.is_hung(_build(6000), 0.0, now=NOW) is False
assert module.is_hung(_build(6000), -1.0, now=NOW) is False
def test_hung_bundle_carries_only_observed_facts() -> None:
bundle = module.hung_bundle("metis", _build(75), 45.0)
jenkins = bundle["jenkins"]
assert jenkins["job"] == "metis"
assert jenkins["build_number"] == 272
assert jenkins["building"] is True
assert jenkins["cap_minutes"] == 45.0
assert jenkins["console_failures"] == []
assert bundle["log_evidence"] == {"records": []}
assert "has been running for" in jenkins["console_tail"]
assert "holding a Jenkins agent slot" in jenkins["console_tail"]
def test_hung_bundle_survives_a_build_with_nothing_in_it() -> None:
"""Bundle construction must not raise on a sparse Jenkins payload."""
bundle = module.hung_bundle("metis", {}, 45.0)
assert bundle["jenkins"]["build_number"] is None
assert bundle["jenkins"]["url"] == ""
assert bundle["jenkins"]["elapsed_minutes"] == 0.0
def test_reason_and_classification_are_stable_labels() -> None:
"""These land in issue titles and event details, so they are frozen."""
assert module.HUNG_REASON == "hung_build"
assert module.HUNG_CLASSIFICATION == "build_exceeded_time_cap"