Skip to content

test: the identity probes wait for an answer, not for a Running pod - #130

Merged
kfeofantov merged 1 commit into
mainfrom
test/identity-e2e-readiness
Sep 18, 2026
Merged

kfeofantov merged 1 commit into
mainfrom
test/identity-e2e-readiness

Conversation

@kfeofantov

Copy link
Copy Markdown
Contributor

The follow-up flagged in #129: make identity-e2e failed on main, and a control run against an image built from b495a1a failed identically, so it was never the toolchain.

The test said what it needed and then did not ask for it

Both tests open with the same comment:

The controller must be answering before a refusal means anything: a connection refused would satisfy "not 200" without proving a thing.

and then called waitDeploymentPod, which returns on Running. The probe reaches the controller through its Service, and the Service carries no endpoint until the pod is Ready — readiness means the informer caches have synced (ADR 0069). Every request inside that window is refused at connect, and wget reports no HTTP status, so three subtests failed on exactly the ambiguity the comment warned about.

The fix is the precondition itself

waitReceiverAnswering sends an unauthenticated probe until the receiver answers with any HTTP status — a refusal is the expected answer, and what is being waited for is the conversation, not the verdict. probeReceiver keeps its fatal verdict and delegates the attempt to tryProbeReceiver, which reports a connect failure as a zero status rather than as a fatal.

This also closes the kube-proxy programming lag that waiting on the pod's Ready condition alone would leave open: what is asserted is that this caller, from this pod, got an answer.

Evidence

make identity-e2e   # PASS, both tests
  identity_test.go:76: the receiver answers: .../v1/node-scope returned 401
                       to an unauthenticated probe

The subtests now run in ~0.05s each, down from ~1.1s — that second was the connect failing.

Same family as #121: an e2e assertion that could not distinguish the thing it tested from the environment it ran in.

🤖 Generated with Claude Code

https://claude.ai/code/session_01KeZECJXTDHL6Nts95eKMJA

Both tests open by naming the precondition — "the controller must be answering
before a refusal means anything: a connection refused would satisfy 'not 200'
without proving a thing" — and then waited for something weaker. The probe
reaches the controller through its Service, which carries no endpoint until the
pod is Ready, and ready means the informer caches have synced (ADR 0069).
Requests inside that window are refused at connect, so three subtests failed on
a refusal the assertions could not tell from a verdict.

The wait is now the precondition itself: an unauthenticated probe, repeated
until the receiver answers with any HTTP status. probeReceiver keeps its
verdict and delegates the attempt to a variant that reports a connect failure
as an answer rather than as a fatal.

Not a regression from the toolchain move: a control run against an image built
from b495a1a failed identically.

  make identity-e2e   # PASS, both tests; the subtests drop from 1.1s
                      # (a failing connect) to 0.05s

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KeZECJXTDHL6Nts95eKMJA
@kfeofantov
kfeofantov merged commit a7a8444 into main Sep 18, 2026
5 checks passed
@kfeofantov
kfeofantov deleted the test/identity-e2e-readiness branch September 18, 2026 09:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant