Add Phase 0a black-box integration test suite
81 tests across 11 files plus a 5-module harness (load, pg, streams, containers, payloads), covering all eleven Phase 0 goals and all 13 named chaos-flag pathologies. Talks to the system only over HTTP, Postgres, Redis, and the Docker CLI -- no imports of application code. RED-BASELINE.md records the suite failing red against the empty repo before any implementation existed; README.md documents the request-contract fields invented to fill gaps in the spec, measurement methodology, and known-flaky tests. This suite is a frozen contract from this point forward per CLAUDE.md.
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
"""Redis XINFO GROUPS helpers, per phase-0a-test-suite-spec.md §7."""
|
||||
import time
|
||||
|
||||
|
||||
def group_lag(redis_client, stream: str, group: str) -> dict:
|
||||
"""Return the XINFO GROUPS entry for `group` on `stream` as a dict."""
|
||||
groups = redis_client.xinfo_groups(stream)
|
||||
for g in groups:
|
||||
if g.get("name") == group:
|
||||
return g
|
||||
raise ValueError(f"consumer group {group!r} not found on stream {stream!r}: {groups}")
|
||||
|
||||
|
||||
def wait_for_drain(redis_client, stream: str, group: str, timeout: float = 15.0) -> None:
|
||||
"""Block until `group`'s lag and pending count both reach 0, or raise TimeoutError."""
|
||||
deadline = time.monotonic() + timeout
|
||||
last = None
|
||||
while time.monotonic() < deadline:
|
||||
g = group_lag(redis_client, stream, group)
|
||||
lag = g.get("lag") or 0
|
||||
pending = g.get("pending") or 0
|
||||
last = (lag, pending)
|
||||
if lag == 0 and pending == 0:
|
||||
return
|
||||
time.sleep(0.25)
|
||||
raise TimeoutError(
|
||||
f"group {group!r} on {stream!r} did not drain within {timeout}s (last lag/pending={last})"
|
||||
)
|
||||
Reference in New Issue
Block a user