Skip to content

Commit acce290

Browse files
committed
change tests
1 parent 998631e commit acce290

File tree

2 files changed

+40
-24
lines changed

2 files changed

+40
-24
lines changed

src/mcp/client/stdio/__init__.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -177,10 +177,14 @@ async def stdin_writer():
177177
yield read_stream, write_stream
178178
finally:
179179
# Clean up process to prevent any dangling orphaned processes
180-
if sys.platform == "win32":
181-
await terminate_windows_process(process)
182-
else:
183-
process.terminate()
180+
try:
181+
if sys.platform == "win32":
182+
await terminate_windows_process(process)
183+
else:
184+
process.terminate()
185+
except ProcessLookupError:
186+
# Process already exited, which is fine
187+
pass
184188
await read_stream.aclose()
185189
await write_stream.aclose()
186190

tests/client/test_stdio.py

Lines changed: 32 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
import shutil
22

33
import pytest
4-
from anyio import fail_after
54

5+
from mcp.client.session import ClientSession
66
from mcp.client.stdio import (
77
StdioServerParameters,
88
stdio_client,
99
)
10+
from mcp.shared.exceptions import McpError
1011
from mcp.shared.message import SessionMessage
11-
from mcp.types import JSONRPCMessage, JSONRPCRequest, JSONRPCResponse
12+
from mcp.types import CONNECTION_CLOSED, JSONRPCMessage, JSONRPCRequest, JSONRPCResponse
1213

1314
tee: str = shutil.which("tee") # type: ignore
14-
uv: str = shutil.which("uv") # type: ignore
15+
python: str = shutil.which("python") # type: ignore
1516

1617

1718
@pytest.mark.anyio
@@ -58,25 +59,36 @@ async def test_stdio_client():
5859

5960

6061
@pytest.mark.anyio
61-
@pytest.mark.skipif(uv is None, reason="could not find uv command")
6262
async def test_stdio_client_bad_path():
6363
"""Check that the connection doesn't hang if process errors."""
64-
server_parameters = StdioServerParameters(
65-
command="uv", args=["run", "non-existent-file.py"]
64+
server_params = StdioServerParameters(
65+
command="python", args=["-c", "non-existent-file.py"]
6666
)
67+
async with stdio_client(server_params) as (read_stream, write_stream):
68+
async with ClientSession(read_stream, write_stream) as session:
69+
# The session should raise an error when the connection closes
70+
with pytest.raises(McpError) as exc_info:
71+
await session.initialize()
6772

73+
# Check that we got a connection closed error
74+
assert exc_info.value.error.code == CONNECTION_CLOSED
75+
assert "Connection closed" in exc_info.value.error.message
76+
77+
78+
@pytest.mark.anyio
79+
async def test_stdio_client_nonexistent_command():
80+
"""Test that stdio_client raises an error for non-existent commands."""
81+
# Create a server with a non-existent command
82+
server_params = StdioServerParameters(
83+
command="/path/to/nonexistent/command",
84+
args=["--help"],
85+
)
86+
87+
# Should raise an error when trying to start the process
6888
with pytest.raises(Exception) as exc_info:
69-
try:
70-
with fail_after(1):
71-
async with stdio_client(server_parameters) as (
72-
read_stream,
73-
_,
74-
):
75-
# Try waiting for read_stream so that we don't exit before the
76-
# process fails.
77-
async with read_stream:
78-
async for message in read_stream:
79-
if isinstance(message, Exception):
80-
raise message
81-
except TimeoutError:
82-
pytest.fail("The connection hung.")
89+
async with stdio_client(server_params) as (_, _):
90+
pass
91+
92+
# The error should indicate the command was not found
93+
error_message = str(exc_info.value)
94+
assert "nonexistent" in error_message or "not found" in error_message.lower()

0 commit comments

Comments
 (0)