test: gate healthy-gating on TCP, not the postgres unix socket#57
Merged
Conversation
The scenario's healthcheck was `pg_isready -U postgres` -- no -h, so it probes the unix socket -- while the dependent runs `pg_isready -h 127.0.0.1`, i.e. TCP. The postgres image runs initdb, then a temporary server that listens on the unix socket ONLY and announces "database system is ready to accept connections", then shuts it down and restarts on TCP. So the healthcheck can pass while no IPv4 listener exists at all, opening the gate before the dependent can connect. Proven from the image's own logs; the window is ~220ms locally and wider on a slower CI runner, which is why it flaked only there. Probing TCP makes the gate assert exactly what the dependent needs: the temp server cannot satisfy it, because nothing is listening on TCP to satisfy it against. Deterministic, not a widened timeout. compose2pod itself is unchanged -- it gated faithfully on the healthcheck it was handed. The defect was in the scenario's compose document.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes the intermittent
tests/integration/test_healthy_gating.pyfailure that has cost two CI reruns. Design:planning/changes/2026-07-14.04-healthy-gating-flake.md.Not flaky infrastructure — a real defect in the scenario. The gate was asserting a different transport from the one the dependent uses.
db's healthcheck:pg_isready -U postgres— no-h, so it probes the Unix socketapp:pg_isready -h 127.0.0.1 -p 5432— TCPThe mechanism, from the postgres image's own logs
The image runs
initdb, then a temporary server to execute its init scripts. That server listens on the Unix socket only — and announces itself as ready:There is no IPv4 listener at all during init. So the healthcheck reports healthy,
wait_healthyreturns 0, the gate opens — andapp's TCP probe cannot possibly succeed. The window is ~220ms locally (21.697 → 21.917), and wider on a slower, contended CI runner. That is precisely why it failed only in CI and never locally.Why this fix is deterministic
Probing TCP makes the gate assert exactly what the dependent needs. The temporary server cannot satisfy a TCP healthcheck, because there is nothing listening on TCP to satisfy it against. This is not a widened timeout or a retry — it removes the failure mode by construction.
It also makes the scenario a stricter test of compose2pod: the pod's shared-namespace
127.0.0.1now has to work for the healthcheck as well as for the target.Scope
compose2poditself is unchanged. The tool gated faithfully on the healthcheck it was handed; the defect was in the scenario's compose document.The 120-second wait budget is untouched and was never relevant — the gate was not timing out, it was opening on the wrong signal.
Integration suite green (10/10) against real podman 6.0.1.
🤖 Generated with Claude Code