Flaky test: TestEtcdComponentIntegration port collision
Flaky Test
Test: TestEtcdComponentIntegration in components/etcd/integration_test.go
Seen in: PR #613, attempt 1
Root Cause
The test calls testutils.GetFreePort(t) twice in succession to get a clientPort and peerPort for etcd:
clientPort := testutils.GetFreePort(t)
peerPort := testutils.GetFreePort(t)
GetFreePort works by binding to port 0 to find a free port, then releasing the port before returning the number. Since the first port is released before the second call, the second call can return the same port number (classic TOCTOU race).
In the failing run, both clientPort and peerPort were 36517:
starting etcd with host networking client_port=36517 peer_port=36517 tls=false
Etcd tries to bind both --listen-client-urls and --listen-peer-urls to the same port, fails with:
failed to start etcd error="listen tcp 0.0.0.0:36517: bind: address already in use"
The test then waits 60s for etcd to become ready, times out, and fails with "Condition never satisfied / etcd failed to become ready".
Possible Fixes
- Ensure distinct ports: Have the test verify
clientPort != peerPortand retry if they collide - Hold ports open: Keep the listeners open until passing them to etcd (though this requires etcd to accept pre-bound listeners or a different handoff mechanism)
- Derive peer port: Use
clientPort + 1or similar offset for the peer port instead of callingGetFreePorttwice