From 39f83f9508643bb37ae3ba46a925c2262c590d34 Mon Sep 17 00:00:00 2001 From: Rowan Date: Sun, 26 Jul 2026 15:45:29 -0400 Subject: [PATCH] test: bind ephemeral ports in test_init_and_defaults 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 --- netcode.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/netcode.c b/netcode.c index 8d6065a..9103d6c 100755 --- a/netcode.c +++ b/netcode.c @@ -6942,7 +6942,11 @@ void test_init_and_defaults() struct netcode_client_config_t client_config; memset( &client_config, 0, sizeof( client_config ) ); - struct netcode_client_t * client = netcode_client_create( "127.0.0.1:50000", &client_config, 0.0 ); + // port 0 asks the OS for an ephemeral port. This test only checks that a zeroed + // config yields working defaults -- it never connects -- so a fixed port buys + // nothing and makes the test fail whenever anything else on the machine happens + // to hold that port. Observed on a windows CI runner, 2026-07-26. + struct netcode_client_t * client = netcode_client_create( "127.0.0.1:0", &client_config, 0.0 ); check( client ); @@ -6953,7 +6957,8 @@ void test_init_and_defaults() struct netcode_server_config_t server_config; memset( &server_config, 0, sizeof( server_config ) ); - struct netcode_server_t * server = netcode_server_create( "127.0.0.1:40000", &server_config, 0.0 ); + // ephemeral here too, and for the same reason: nothing connects to this server. + struct netcode_server_t * server = netcode_server_create( "127.0.0.1:0", &server_config, 0.0 ); check( server );