test: cover startup Caddyfile regeneration to prevent restart-loop regression
Unit Tests / test (push) Successful in 11m56s

Adds TestStartupCaddyRegen::test_startup_regenerates_caddyfile_first,
asserting that _apply_startup_enforcement() calls
caddy_manager.regenerate_with_installed([]) before any peer/iptables work.
This pins the fix that ensures a stale on-disk Caddyfile (e.g. missing
`admin 0.0.0.0:2019`) is overwritten at startup and cannot cause the health
monitor to restart Caddy every few minutes.

Also restores two displaced lines in test_health_history_maxlen_evicts_old_entries.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-06-10 13:18:42 -04:00
parent 5cb8ebe430
commit fb257c50b3
+19
View File
@@ -62,6 +62,25 @@ class TestHealthHistoryIsDeque:
assert hh[0]['n'] == 4
# ---------------------------------------------------------------------------
# startup regenerates the Caddyfile (stale-Caddyfile restart-loop fix)
# ---------------------------------------------------------------------------
class TestStartupCaddyRegen:
def test_startup_regenerates_caddyfile_first(self):
"""_apply_startup_enforcement must regenerate the Caddyfile before
anything else, so a stale on-disk Caddyfile (e.g. missing
`admin 0.0.0.0:2019`) can't wedge the health monitor into restarting
Caddy every few minutes."""
with patch.object(app_module, 'caddy_manager') as mock_caddy, \
patch.object(app_module, 'peer_registry') as mock_pr:
# Raise right after the caddy regen to short-circuit the rest of
# the (heavy, docker/iptables) startup work.
mock_pr.list_peers.side_effect = RuntimeError('stop here')
app_module._apply_startup_enforcement()
mock_caddy.regenerate_with_installed.assert_called_once_with([])
# ---------------------------------------------------------------------------
# GET /api/health/history
# ---------------------------------------------------------------------------