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:
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user