ariadne/tests/test_hermes_storage_signals.py
codex ca2324ab95
All checks were successful
Tests / Declarative: Post Actions passed: 1251
feat(hermes): reclaim exhausted workspace storage, and stop hung builds
Two real actions, both for failures that interrupted this project while it was
being built, and both backed by code Ariadne already had.

reclaim_workspace_storage closes a gap left open deliberately: 'no space left
on device' was excluded from the transient retry because a rebuild lands on
the same full volume and either fails identically or hides a capacity problem.
Reclaiming first makes the retry meaningful. The reclaim is the existing
scheduled cleanup, with its own deletion budget, so no new capability is
granted - it is only reachable from triage now. Its signature requires both a
storage marker and a workspace hint, because a full disk elsewhere in the
cluster is a different failure that reclaiming Jenkins workspaces would not
address.

Hung-build detection previously filed an issue and left the build running,
holding one of five Jenkins agent slots and starving every other job - the
actual harm. Ariadne now stops it as well, which is reversible: the job can
simply be built again.

The action executors move to their own module. They are the only code in
triage that changes anything outside Ariadne and should be reviewable as one
unit.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-06 20:55:35 -03:00

44 lines
1.5 KiB
Python

"""Tests for recognising Jenkins workspace storage exhaustion."""
from __future__ import annotations
from ariadne.services import hermes_storage_signals as module
def _bundle(*lines: str, tail: str = "") -> dict:
return {"jenkins": {"console_failures": [{"text": "\n".join(lines)}], "console_tail": tail}}
def test_a_full_workspace_volume_is_recognised() -> None:
matched, marker = module.has_storage_exhaustion_signature(
_bundle("cp: error writing '/home/jenkins/agent/workspace/x': No space left on device")
)
assert matched is True
assert marker == "no space left on device"
def test_the_tail_is_searched_too() -> None:
matched, _ = module.has_storage_exhaustion_signature(
_bundle("nothing here", tail="workspace volume full: disk quota exceeded")
)
assert matched is True
def test_a_full_disk_without_a_workspace_hint_is_not_this_failure() -> None:
"""Reclaiming Jenkins workspaces would not address it."""
matched, marker = module.has_storage_exhaustion_signature(
_bundle("etcd: No space left on device")
)
assert (matched, marker) == (False, None)
def test_a_workspace_mention_without_a_storage_marker_does_not_match() -> None:
matched, _ = module.has_storage_exhaustion_signature(_bundle("workspace checkout failed"))
assert matched is False
def test_never_raises_on_hostile_input() -> None:
for bad in (None, 7, {}, {"jenkins": None}, {"jenkins": {"console_failures": "no"}}):
assert module.has_storage_exhaustion_signature(bad) == (False, None)