Deploy: Health-Check wartet bei neuem Ingress geduldig auf Zertifikat/DNS (bis ~15 min), endet dann mit Warnung statt failed; Zustand wird vor dem Health-Check festgehalten; 'Health erneut prüfen'

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
RubenRWU
2026-10-15 16:24:36 +02:00
parent f33312369f
commit 31a99e31c0
8 changed files with 123 additions and 16 deletions

View File

@@ -511,3 +511,52 @@ def test_http_clients_follow_redirects_and_3xx_is_never_success(monkeypatch):
# Eine nicht gefolgte 308-Weiterleitung (leerer Body) ist ein Fehler, kein „null“
with pytest.raises(DeployError, match="308"):
Mittwald("t", "https://api.test/v2", False, lambda m: None, lambda *a: (308, None, "")).api("GET", "/projects/p/stacks/", write=False)
# ── Health-Check bei neuem Ingress (Zertifikat/DNS dauert) ──────────────────
def test_verify_health_distinguishes_unreachable_from_wrong_version():
from app.services.deploy import HealthTimeout
with pytest.raises(HealthTimeout) as e1:
deploy.verify_health("h", "abcdef1", None, lambda m: None, get=lambda u: (_ for _ in ()).throw(OSError("ssl handshake")), tries=2, delay=0, sleep=lambda s: None)
assert e1.value.answered is False
with pytest.raises(HealthTimeout) as e2:
deploy.verify_health("h", "abcdef1", None, lambda m: None, get=lambda u: (502, {}), tries=2, delay=0, sleep=lambda s: None)
assert e2.value.answered is False # Proxy antwortet, App nicht
with pytest.raises(HealthTimeout) as e3:
deploy.verify_health("h", "abcdef1", None, lambda m: None, get=lambda u: (200, health_body("9999999aaaa")), tries=1)
assert e3.value.answered is True
def test_new_ingress_with_slow_certificate_ends_with_warning_not_failure(client, live_env):
from app.services.deploy import HealthTimeout
_ready(client, "hc1")
mw = FakeMW() # GET /ingresses → [] ⇒ Ingress wird neu angelegt
never = lambda *a, **k: (_ for _ in ()).throw(HealthTimeout("keine Antwort", answered=False)) # noqa: E731
dep = deploy.start("hc1", "deploy", "t", http=mw, health=never, wait=True)
d = client.get(f"/api/deployments/{dep}").json()
assert d["status"] == "warning" and "Zertifikat/DNS" in d["log"] and "Fertig mit Warnung" in d["log"]
with session() as db:
t = db.get(Tenant, "hc1")
assert t.deployed_version == t.current_version and t.deployed_image # Zustand wurde trotzdem festgehalten
# Zertifikat inzwischen da → nachträglicher Check macht den Eintrag grün
r = deploy.recheck_health("hc1", health=lambda *a: None)
assert r["ok"] and client.get(f"/api/deployments/{dep}").json()["status"] == "success"
def test_wrong_version_or_existing_ingress_still_fails(client, live_env):
from app.services.deploy import HealthTimeout
_ready(client, "hc2")
mw = FakeMW()
wrong = lambda *a, **k: (_ for _ in ()).throw(HealthTimeout("Core falsch", answered=True)) # noqa: E731
d = client.get(f"/api/deployments/{deploy.start('hc2', 'deploy', 't', http=mw, health=wrong, wait=True)}").json()
assert d["status"] == "failed" # neuer Ingress, aber echte Antwort mit falscher Version
# bestehender Ingress + keine Antwort ⇒ echter Fehler
class WithIngress(FakeMW):
def __call__(self, method, url, headers, body):
if method == "GET" and "ingresses" in url:
return 200, [{"hostname": "hc2.onyscribe.de", "id": "i1"}], ""
return super().__call__(method, url, headers, body)
never = lambda *a, **k: (_ for _ in ()).throw(HealthTimeout("keine Antwort", answered=False)) # noqa: E731
d2 = client.get(f"/api/deployments/{deploy.start('hc2', 'deploy', 't', http=WithIngress(), health=never, wait=True)}").json()
assert d2["status"] == "failed"