test: identity-guard the serve-debug readiness probe (kill the port-identity flake) - #191
Merged
Merged
Conversation
…lake) test_cli_serve_debug_env flaked when a foreign server held the reused ephemeral port. _free_port() hands out an ephemeral port; under load a DIFFERENT debug-off server (a prior case's child lingering on the reused port) already holds it, and TINA4_NO_TAKEOVER stops our debug-on child evicting it. The old probe hit /__dev directly and trusted the first response -- from the FOREIGN server -> settled 404 for the debug-true case. A 200/404 on the port proves only that SOMETHING listens, not that it is OUR child. Fix: each boot plants a per-boot UNIQUE readiness route (/ready_<token>) that only OUR child serves. Readiness waits for a 200 on THAT (a foreign server 404s it) before polling /__dev, and a contended port that never yields our token times out and retries on a FRESH port (boot_attempts=5). All four assertions unchanged. No mocks: a real child, a real socket. Parity with tina4-ruby (ShutdownProbe identity guard) and tina4-nodejs (loopBlockWatchdog /fast readiness). Verified (py 3.13.11, macOS): 4/4 single, 12/12 under CPU load; gate proof -- a debug-on server lacking the route 404s /ready_<token> while serving /__dev=200, so a foreign server is genuinely rejected. Signed-off-by: Andre van Zuydam <[email protected]> Co-Authored-By: Claude Opus 4.8 <[email protected]> Co-Authored-By: Tina4 <[email protected]>
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.
What
'cli_serve_debug_env'flaked when a foreign server held the reused ephemeral port.Root cause (evidence from a Ruby CI child
serve.log; all frameworks share the pattern)The ephemeral free-port is reused: under load a different, debug-off server (a prior case's child lingering on that port) already holds it, and
TINA4_NO_TAKEOVER=truestops our debug-on child evicting it. The old probe hit/__devdirectly and trusted the first response — from the foreign server → settled 404 for the debug-true case. A 200/404 on the port proves only that something listens, not that it is our child.Fix
Each boot plants a per-boot unique readiness route (
/ready_<token>) that only our child serves. Readiness waits for a 200 on that (a foreign server 404s it) before polling/__dev; a contended port that never yields our token times out and retries on a fresh port (boot_attempts=5). All assertions unchanged. No mocks — a real child, a real socket.Parity
tina4-ruby PR #95 (ShutdownProbe
Server:banner identity guard), tina4-nodejs #111 (loopBlockWatchdog/fastreadiness). Node has no CLI-serve-debug test, so no sibling there.🤖 Generated with Claude Code