Skip to content

Commit 2342188

Browse files
BabyChrist666claude
andcommitted
Revert wait_for_server HTTP check; also remove dead code in test_ws.py
The HTTP health check in wait_for_server() caused false-positive readiness signals for mounted Starlette apps (404 from root vs 404 from uninitialized routes are indistinguishable). Revert to TCP-only polling which matches the original behavior. Also remove the same dead-code pattern from test_ws.py (unreachable loop after blocking server.run()). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent ad87cfa commit 2342188

File tree

2 files changed

+7
-37
lines changed

2 files changed

+7
-37
lines changed

tests/shared/test_ws.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import multiprocessing
22
import socket
3-
import time
43
from collections.abc import AsyncGenerator, Generator
54
from urllib.parse import urlparse
65

@@ -114,11 +113,6 @@ def run_server(server_port: int) -> None: # pragma: no cover
114113
print(f"starting server on {server_port}")
115114
server.run()
116115

117-
# Give server time to start
118-
while not server.started:
119-
print("waiting for server to start")
120-
time.sleep(0.5)
121-
122116

123117
@pytest.fixture()
124118
def server(server_port: int) -> Generator[None, None, None]:

tests/test_helpers.py

Lines changed: 7 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2,54 +2,30 @@
22

33
import socket
44
import time
5-
import urllib.error
6-
import urllib.request
75

86

97
def wait_for_server(port: int, timeout: float = 20.0) -> None:
108
"""Wait for server to be ready to accept connections.
119
12-
First polls until the TCP port accepts connections, then verifies the
13-
HTTP server is actually ready to handle requests. This two-stage check
14-
prevents race conditions where the port is open but the ASGI app hasn't
15-
finished initializing.
10+
Polls the server port until it accepts connections or timeout is reached.
11+
This eliminates race conditions without arbitrary sleeps.
1612
1713
Args:
1814
port: The port number to check
19-
timeout: Maximum time to wait in seconds (default 20.0)
15+
timeout: Maximum time to wait in seconds (default 5.0)
2016
2117
Raises:
2218
TimeoutError: If server doesn't start within the timeout period
2319
"""
2420
start_time = time.time()
25-
26-
# Stage 1: Wait for TCP port to accept connections
2721
while time.time() - start_time < timeout:
2822
try:
2923
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
3024
s.settimeout(0.1)
3125
s.connect(("127.0.0.1", port))
32-
break # Port is open, move to stage 2
26+
# Server is ready
27+
return
3328
except (ConnectionRefusedError, OSError):
29+
# Server not ready yet, retry quickly
3430
time.sleep(0.01)
35-
else:
36-
raise TimeoutError(f"Server on port {port} did not start within {timeout} seconds") # pragma: no cover
37-
38-
# Stage 2: Verify HTTP server is ready by making a request.
39-
# A non-existent path returns 404/405 if the app is ready, or
40-
# raises an error if the ASGI app hasn't finished initializing.
41-
while time.time() - start_time < timeout:
42-
try:
43-
req = urllib.request.Request(
44-
f"http://127.0.0.1:{port}/healthz",
45-
method="GET",
46-
)
47-
with urllib.request.urlopen(req, timeout=1):
48-
return # Any successful response means server is ready
49-
except urllib.error.HTTPError:
50-
# 404/405/etc means the server IS handling requests
51-
return
52-
except (urllib.error.URLError, ConnectionError, OSError):
53-
# Server not ready for HTTP yet
54-
time.sleep(0.05)
55-
raise TimeoutError(f"Server on port {port} did not become HTTP-ready within {timeout} seconds") # pragma: no cover
31+
raise TimeoutError(f"Server on port {port} did not start within {timeout} seconds") # pragma: no cover

0 commit comments

Comments
 (0)