Skip to content

fix(httpfs): disable SO_REUSEPORT in the test http server (flaky headCount under ctest -j) - #75

Merged
adsharma merged 1 commit into
mainfrom
fix/880-flaky-head-count-test
Sep 1, 2026
Merged

fix(httpfs): disable SO_REUSEPORT in the test http server (flaky headCount under ctest -j)#75
adsharma merged 1 commit into
mainfrom
fix/880-flaky-head-count-test

Conversation

@adsharma

@adsharma adsharma commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Follow-up to #73 (the #880 fix). HttpFileSystemTest.RepeatOpenDoesNotIssueSecondHead failed flakily in the ladybug repo CI with headCount()==0 under ctest -j10.

Root cause

The vendored httplib enables SO_REUSEPORT by default on Linux (default_socket_options in third_party/httplib/httplib.h), which allows multiple sockets to bind the same address:port and makes the kernel load-balance connections between them.

gtest_discover_tests runs each gtest case in its own process, so with ctest -j10 the two httpfs test processes start a few ms apart and both successfully bound 127.0.0.1:18123. Incoming connections were then distributed between the two servers by the kernel, so the process running the HEAD-count test could have some or all of its requests served by the other process's server (both serve the same fixture directory). Instrumented local repro showed exactly that: two processes both reporting bound port=18123, and the failing process observing headCount 0 or 2.

Fix

LocalHttpServer now overrides the server socket options to set only SO_REUSEADDR, so a second bind of the same port fails with EADDRINUSE and the existing port-scan loop picks a genuinely free port. Each test process then owns its port exclusively.

Verification

  • Without the fix: ~25% of ctest -j10 runs fail locally (2-3 of 10).
  • With the fix: 20 consecutive ctest -j10 runs, 0 failures.
  • Serial runs and the existing httpfs_xetfs_test keep passing.

RepeatOpenDoesNotIssueSecondHead failed flakily in the ladybug repo CI
(headCount()==0) under `ctest -j10`.

The vendored httplib enables SO_REUSEPORT by default on Linux, which
lets multiple sockets bind the same port and load-balances connections
between them. ctest runs each gtest case in its own process, so two
concurrent test processes both successfully bound 127.0.0.1:18123 and
the kernel routed some requests to the other process's server - the
HEAD-count assertion then observed requests that never reached the
server it was checking (reproduced locally: two concurrent processes
both bound 18123, and the failing process saw headCount 0 or 2).

Override the server socket options to set only SO_REUSEADDR so a second
bind of the same port fails with EADDRINUSE and the existing port scan
falls through to a genuinely free port. 20 consecutive `ctest -j10`
runs pass with this change; without it ~25% of runs failed.
@adsharma
adsharma force-pushed the fix/880-flaky-head-count-test branch from f33f6f6 to d115950 Compare September 1, 2026 16:59
@adsharma
adsharma merged commit 371e608 into main Sep 1, 2026
2 checks passed
@adsharma
adsharma deleted the fix/880-flaky-head-count-test branch September 1, 2026 17:12
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