@@ -27,6 +27,10 @@ async def test_notification_validation_error(tmp_path: Path):
2727 2. The server can still handle new requests
2828 3. The client can make new requests
2929 4. No resources are leaked
30+
31+ Uses per-request timeouts to avoid race conditions:
32+ - Fast operations use no timeout (reliable in any environment)
33+ - Slow operations use minimal timeout (10ms) for quick test execution
3034 """
3135
3236 server = Server (name = "test" )
@@ -79,29 +83,29 @@ async def client(
7983 write_stream : MemoryObjectSendStream [SessionMessage ],
8084 scope : anyio .CancelScope ,
8185 ):
82- # Use a timeout that's:
83- # - Long enough for fast operations (>10ms)
84- # - Short enough for slow operations (<200ms)
85- # - Not too short to avoid flakiness
86- async with ClientSession (read_stream , write_stream , read_timeout_seconds = timedelta (milliseconds = 50 )) as session :
86+ # No session-level timeout to avoid race conditions with fast operations
87+ async with ClientSession (read_stream , write_stream ) as session :
8788 await session .initialize ()
8889
89- # First call should work (fast operation)
90- result = await session .call_tool ("fast" )
90+ # First call should work (fast operation, no timeout )
91+ result = await session .call_tool ("fast" , read_timeout_seconds = None )
9192 assert result .content == [TextContent (type = "text" , text = "fast 1" )]
9293 assert not slow_request_lock .is_set ()
9394
94- # Second call should timeout (slow operation)
95+ # Second call should timeout (slow operation with minimal timeout)
96+ # Use 10ms timeout to trigger quickly without waiting
9597 with pytest .raises (McpError ) as exc_info :
96- await session .call_tool ("slow" )
98+ await session .call_tool (
99+ "slow" , read_timeout_seconds = timedelta (microseconds = 1 )
100+ ) # artificial timeout that always fails
97101 assert "Timed out while waiting" in str (exc_info .value )
98102
99103 # release the slow request not to have hanging process
100104 slow_request_lock .set ()
101105
102- # Third call should work (fast operation),
106+ # Third call should work (fast operation, no timeout ),
103107 # proving server is still responsive
104- result = await session .call_tool ("fast" )
108+ result = await session .call_tool ("fast" , read_timeout_seconds = None )
105109 assert result .content == [TextContent (type = "text" , text = "fast 3" )]
106110 scope .cancel ()
107111
0 commit comments