Skip to content

Commit 23d062d

Browse files
Rewrite Windows hang test to actually test issue #552
- Remove confusing parametrized tests with cmd.exe - Add simple test that verifies stdio_client doesn't hang on Windows - Add echo server test for more comprehensive verification - Both tests use Python subprocess for cross-version compatibility - Tests focus on the actual issue: stdio_client hanging on Windows
1 parent 0157229 commit 23d062d

File tree

1 file changed

+63
-39
lines changed

1 file changed

+63
-39
lines changed

tests/issues/test_552_windows_hang.py

Lines changed: 63 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,77 @@
11
import sys
2-
32
import anyio
43
import pytest
5-
64
from mcp import ClientSession, StdioServerParameters
75
from mcp.client.stdio import stdio_client
86

97

108
@pytest.mark.skipif(sys.platform != "win32", reason="Windows-specific test")
11-
@pytest.mark.parametrize(
12-
"args,should_fail",
13-
[
14-
(["/C", "echo", '{"jsonrpc": "2.0", "id": 1, "result": null}'], False),
15-
(["dfghfgh"], True),
16-
(["/C", "echo"], False),
17-
],
18-
)
199
@pytest.mark.anyio
20-
async def test_windows_process_creation(args, should_fail):
10+
async def test_windows_stdio_client_no_hang():
2111
"""
22-
Test that directly tests the process creation function that was fixed in issue #552.
23-
This simpler test verifies that Windows process creation works without hanging.
12+
Test for issue #552: stdio_client hangs on Windows 11.
13+
14+
This test verifies that the stdio_client can be created and properly
15+
closed on Windows without hanging. The original issue was that the
16+
client would hang indefinitely during initialization or cleanup.
2417
"""
25-
# Use a simple command that should complete quickly on Windows
18+
# Use Python as a simple subprocess that exits cleanly
2619
params = StdioServerParameters(
27-
command="cmd",
28-
# Echo a valid JSON-RPC response message that will be parsed correctly
29-
args=args,
20+
command=sys.executable,
21+
args=["-c", "import sys; sys.exit(0)"],
3022
)
31-
32-
# Directly test the fixed function that was causing the hanging issue
33-
if should_fail:
34-
# For commands we expect to fail, ensure they fail quickly without hanging
35-
with pytest.raises((TimeoutError, Exception)) as exc_info:
36-
with anyio.fail_after(5):
37-
async with stdio_client(params) as (read, write):
38-
async with ClientSession(read, write) as c:
39-
await c.initialize()
40-
# Verify it failed as expected (timeout or process error)
41-
assert isinstance(exc_info.value, (TimeoutError, Exception))
42-
else:
43-
# For valid commands, they should complete without hanging
23+
24+
# The test passes if we can create and close the client without hanging
25+
# We use a timeout to ensure the test fails if the hang issue persists
26+
with anyio.fail_after(10): # 10 second timeout
4427
try:
45-
with anyio.fail_after(5):
46-
async with stdio_client(params) as (read, write):
47-
async with ClientSession(read, write) as c:
48-
await c.initialize()
49-
except Exception as e:
50-
# These commands might fail due to protocol issues, but shouldn't hang
51-
# The important thing is they complete within the timeout
52-
print(f"Command failed with: {e}")
53-
# As long as it didn't timeout, the test passes (no hang)
28+
async with stdio_client(params) as (read, write):
29+
# Just creating the client successfully is enough
30+
# The original issue was it would hang here
31+
pass
32+
except Exception:
33+
# We expect the subprocess to exit immediately
34+
# Any exception is fine as long as we don't hang
35+
pass
36+
37+
# If we get here without timing out, the hang issue is fixed
38+
assert True
39+
40+
41+
@pytest.mark.skipif(sys.platform != "win32", reason="Windows-specific test")
42+
@pytest.mark.anyio
43+
async def test_windows_stdio_client_with_echo_server():
44+
"""
45+
Test stdio_client with a simple echo server on Windows.
46+
47+
This is a more comprehensive test that creates a subprocess that
48+
echoes stdin to stdout, verifying bidirectional communication works.
49+
"""
50+
# Create a simple Python echo server
51+
echo_script = '''
52+
import sys
53+
while True:
54+
line = sys.stdin.readline()
55+
if not line:
56+
break
57+
sys.stdout.write(line)
58+
sys.stdout.flush()
59+
'''
60+
61+
params = StdioServerParameters(
62+
command=sys.executable,
63+
args=["-c", echo_script],
64+
)
65+
66+
# Test should complete without hanging
67+
with anyio.fail_after(10):
68+
async with stdio_client(params) as (read, write):
69+
# Send a test message
70+
test_message = b"Hello Windows\\n"
71+
await write.send(test_message)
72+
73+
# Read the echo back
74+
response = await read.receive()
75+
assert response == test_message.rstrip()
76+
77+
# Client should close cleanly when exiting context

0 commit comments

Comments
 (0)