Skip to content

Commit 04dc39b

Browse files
committed
fix: Replace fixed sleep with active server readiness check in SSE tests
The test_sse_security_wildcard_ports test was flaky due to a race condition where the test tried to connect before uvicorn was ready to accept connections. The original code used time.sleep(1) which was: - Sometimes too short (causing flaky CI failures) - Always wasteful when server started quickly - Non-deterministic This change replaces the arbitrary sleep with wait_for_server() which: - Actively polls the server port until it accepts connections - Returns immediately when ready (faster in most cases) - Has a clear 5-second timeout for true failures - Eliminates the race condition entirely The fix makes the tests deterministic and often faster than before.
1 parent 7ac40af commit 04dc39b

File tree

1 file changed

+22
-2
lines changed

1 file changed

+22
-2
lines changed

tests/server/test_sse_security.py

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,12 +66,32 @@ async def handle_sse(request: Request):
6666
uvicorn.run(starlette_app, host="127.0.0.1", port=port, log_level="error")
6767

6868

69+
def wait_for_server(port: int, timeout: float = 5.0) -> None:
70+
"""Wait for server to be ready to accept connections.
71+
72+
Polls the server port until it accepts connections or timeout is reached.
73+
This eliminates race conditions without arbitrary sleeps.
74+
"""
75+
start_time = time.time()
76+
while time.time() - start_time < timeout:
77+
try:
78+
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
79+
s.settimeout(0.1)
80+
s.connect(("127.0.0.1", port))
81+
# Server is ready
82+
return
83+
except (ConnectionRefusedError, OSError):
84+
# Server not ready yet, retry quickly
85+
time.sleep(0.01)
86+
raise TimeoutError(f"Server on port {port} did not start within {timeout} seconds")
87+
88+
6989
def start_server_process(port: int, security_settings: TransportSecuritySettings | None = None):
7090
"""Start server in a separate process."""
7191
process = multiprocessing.Process(target=run_server_with_settings, args=(port, security_settings))
7292
process.start()
73-
# Give server time to start
74-
time.sleep(1)
93+
# Wait for server to be ready to accept connections
94+
wait_for_server(port)
7595
return process
7696

7797

0 commit comments

Comments
 (0)