Skip to content

test: bind ephemeral ports in test_init_and_defaults - #172

Merged
rowan-claude merged 1 commit into
mainfrom
fix/test-ephemeral-ports
Jul 26, 2026
Merged

test: bind ephemeral ports in test_init_and_defaults#172
rowan-claude merged 1 commit into
mainfrom
fix/test-ephemeral-ports

Conversation

@rowan-claude

Copy link
Copy Markdown
Contributor

windows-2025 Release failed on a documentation-only PR:

check failed: ( client ), function test_init_and_defaults, netcode.c:6947

netcode_client_create returned NULL because something else on the runner held 127.0.0.1:50000. The test does not care which port it gets — it only checks that a zeroed config yields working defaults, and it never connects. So the fixed port buys nothing and costs a flake.

The socket layer already calls getsockname after bind, so the machinery for ephemeral ports existed and was unused: 37 fixed-port sites in the test suite, zero ephemeral.

Reproduced deterministically, not assumed

Holding 127.0.0.1:50000 from another process and running the suite reproduces exactly the CI failure at 6947. With this change, the failure moves past test_init_and_defaults — which is the proof that this test is fixed rather than the symptom being masked.

What this does NOT fix

Stated so the flake is not reported as gone:

  • test_client_create_error needs a fixed port by design — it binds one and asserts a second bind on the same port returns NULL. Ephemeral would make both binds succeed and silently destroy the test. The hermetic version binds :0, reads back the assigned port and re-binds that; it needs an API to read the bound address, and is a bigger change than this one.
  • test_runtime_guards fails the same way if 127.0.0.1:40000 is held.

The suite is still vulnerable to external port contention in two places. This fixes the one that actually broke CI and claims nothing more.

windows-2025 Release failed on a documentation-only PR:

    check failed: ( client ), function test_init_and_defaults, netcode.c:6947

netcode_client_create returned NULL because something else on the runner held
127.0.0.1:50000. The test does not care which port it gets -- it only checks that a
zeroed config yields working defaults, and it never connects -- so the fixed port buys
nothing and costs a flake. Port 0 asks the OS for an ephemeral one. The socket layer
already calls getsockname after bind, so the machinery for this existed and was unused:
37 fixed-port sites in the test suite, zero ephemeral.

REPRODUCED DETERMINISTICALLY rather than assumed. Holding 127.0.0.1:50000 from another
process and running the suite gives exactly the CI failure at 6947. With this change the
failure moves PAST test_init_and_defaults, which is the proof that this test is fixed.

WHAT IS NOT FIXED, stated so the flake is not reported as gone:
- test_client_create_error still needs a fixed port BY DESIGN -- it binds one and asserts
  that a second bind on the same port returns NULL. Ephemeral would make both binds
  succeed and silently destroy the test. The hermetic version binds :0, reads back the
  assigned port, and re-binds that; it needs an API to read the bound address and is a
  bigger change than this one.
- test_runtime_guards fails the same way if 127.0.0.1:40000 is held.

So the suite is still vulnerable to external port contention in two places. This change
fixes the one that actually broke CI and does not claim more.

Verified: clean rebuild, full suite passes normally, and passes test_init_and_defaults
with :50000 held.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@rowan-claude
rowan-claude merged commit bf62063 into main Jul 26, 2026
14 checks passed
@rowan-claude
rowan-claude deleted the fix/test-ephemeral-ports branch July 26, 2026 19:49
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