Bound /readyz so kubelet probes cannot hang the Service
/readyz walked the hash chain and opened pooled connections with no libpq connect_timeout, so a 2s kubelet probe never saw a response and the pod stayed unready. Informed Decision accept is blocked on that. Probe health() only, under a 1.5s budget, publish last-known tamper_evidence, and fail TCP handshake in 1s. Integrity stays on /v1/integrity. Assistant: grok Assistant-Session: 01a0a182-bab7-7f11-b32b-d06f3af52082
This commit is contained in:
parent
e7e054d8d6
commit
b0e6792cf0
9 changed files with 276 additions and 18 deletions
|
|
@ -1,5 +1,6 @@
|
|||
import io
|
||||
import json
|
||||
import time
|
||||
from datetime import datetime, timezone
|
||||
|
||||
import pytest
|
||||
|
|
@ -502,6 +503,68 @@ def test_readiness_reports_recovery_fields_for_operational_backend():
|
|||
assert "platform-audit-storage" in body["recoverable_source"]
|
||||
|
||||
|
||||
def test_readyz_does_not_wait_on_chain_verification():
|
||||
"""Kubelet timeoutSeconds is 2; walking the hash chain is not a probe."""
|
||||
|
||||
class _ChainWalk(_BrokenBackend):
|
||||
def health(self):
|
||||
return None
|
||||
|
||||
@property
|
||||
def retention_policy(self):
|
||||
time.sleep(5)
|
||||
raise AssertionError("/readyz must not call retention_policy")
|
||||
|
||||
def readiness_policy(self):
|
||||
return RetentionPolicy(
|
||||
custody_class="operational",
|
||||
retention_days=None,
|
||||
immutable=True,
|
||||
tamper_evidence=False,
|
||||
durable=True,
|
||||
recoverable_days=30,
|
||||
recoverable_source="cited",
|
||||
recoverable_basis="measured",
|
||||
)
|
||||
|
||||
started = time.monotonic()
|
||||
status, body = invoke(
|
||||
IngestionApplication(_ChainWalk(), "opaque"),
|
||||
None, path="/readyz", method="GET", body=b"",
|
||||
)
|
||||
assert time.monotonic() - started < 1.0
|
||||
assert status.startswith("200")
|
||||
assert body["durable"] is True
|
||||
assert body["tamper_evidence"] is False
|
||||
|
||||
|
||||
def test_readyz_treats_a_hung_health_check_as_unavailable():
|
||||
class _HungHealth(_BrokenBackend):
|
||||
def health(self):
|
||||
time.sleep(5)
|
||||
|
||||
app = IngestionApplication(_HungHealth(), "opaque")
|
||||
app._ready_budget = 0.05
|
||||
started = time.monotonic()
|
||||
status, body = invoke(app, None, path="/readyz", method="GET", body=b"")
|
||||
assert time.monotonic() - started < 1.0
|
||||
assert status.startswith("503")
|
||||
assert body["status"] == "unavailable"
|
||||
|
||||
|
||||
def test_readyz_unavailable_backend_is_503():
|
||||
class _Down(_BrokenBackend):
|
||||
def health(self):
|
||||
raise BackendUnavailableError("down")
|
||||
|
||||
status, body = invoke(
|
||||
IngestionApplication(_Down(), "opaque"),
|
||||
None, path="/readyz", method="GET", body=b"",
|
||||
)
|
||||
assert status.startswith("503")
|
||||
assert body["status"] == "unavailable"
|
||||
|
||||
|
||||
def test_counters_track_each_outcome(tmp_path):
|
||||
app, _ = bound_app(tmp_path, may_read=True)
|
||||
invoke(app, event()) # accepted
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue