@@ -30,74 +30,77 @@ async def test_malformed_initialize_request_does_not_crash_server():
3030 SessionMessage
3131 ](10 )
3232
33- # Create a malformed initialize request (missing required params field)
34- malformed_request = JSONRPCRequest (
35- jsonrpc = "2.0" ,
36- id = "f20fe86132ed4cd197f89a7134de5685" ,
37- method = "initialize" ,
38- # params=None # Missing required params field
39- )
40-
41- # Wrap in session message
42- request_message = SessionMessage (message = JSONRPCMessage (malformed_request ))
43-
44- # Start a server session
45- async with ServerSession (
46- read_stream = read_receive_stream ,
47- write_stream = write_send_stream ,
48- init_options = InitializationOptions (
49- server_name = "test_server" ,
50- server_version = "1.0.0" ,
51- capabilities = ServerCapabilities (),
52- ),
53- ):
54- # Send the malformed request
55- await read_send_stream .send (request_message )
56-
57- # Give the session time to process the request
58- await anyio .sleep (0.1 )
33+ try :
34+ # Create a malformed initialize request (missing required params field)
35+ malformed_request = JSONRPCRequest (
36+ jsonrpc = "2.0" ,
37+ id = "f20fe86132ed4cd197f89a7134de5685" ,
38+ method = "initialize" ,
39+ # params=None # Missing required params field
40+ )
5941
60- # Check that we received an error response instead of a crash
61- try :
62- response_message = write_receive_stream .receive_nowait ()
63- response = response_message .message .root
64-
65- # Verify it's a proper JSON-RPC error response
66- assert isinstance (response , JSONRPCError )
67- assert response .jsonrpc == "2.0"
68- assert response .id == "f20fe86132ed4cd197f89a7134de5685"
69- assert response .error .code == INVALID_PARAMS
70- assert "Invalid request parameters" in response .error .message
71-
72- # Verify the session is still alive and can handle more requests
73- # Send another malformed request to confirm server stability
74- another_malformed_request = JSONRPCRequest (
75- jsonrpc = "2.0" ,
76- id = "test_id_2" ,
77- method = "tools/call" ,
78- # params=None # Missing required params
79- )
80- another_request_message = SessionMessage (
81- message = JSONRPCMessage (another_malformed_request )
82- )
42+ # Wrap in session message
43+ request_message = SessionMessage (message = JSONRPCMessage (malformed_request ))
44+
45+ # Start a server session
46+ async with ServerSession (
47+ read_stream = read_receive_stream ,
48+ write_stream = write_send_stream ,
49+ init_options = InitializationOptions (
50+ server_name = "test_server" ,
51+ server_version = "1.0.0" ,
52+ capabilities = ServerCapabilities (),
53+ ),
54+ ):
55+ # Send the malformed request
56+ await read_send_stream .send (request_message )
8357
84- await read_send_stream . send ( another_request_message )
58+ # Give the session time to process the request
8559 await anyio .sleep (0.1 )
8660
87- # Should get another error response, not a crash
88- second_response_message = write_receive_stream .receive_nowait ()
89- second_response = second_response_message .message .root
90-
91- assert isinstance (second_response , JSONRPCError )
92- assert second_response .id == "test_id_2"
93- assert second_response .error .code == INVALID_PARAMS
94-
95- except anyio .WouldBlock :
96- pytest .fail ("No response received - server likely crashed" )
97-
98- # Close the send streams to signal end of communication
99- await read_send_stream .aclose ()
100- await write_send_stream .aclose ()
61+ # Check that we received an error response instead of a crash
62+ try :
63+ response_message = write_receive_stream .receive_nowait ()
64+ response = response_message .message .root
65+
66+ # Verify it's a proper JSON-RPC error response
67+ assert isinstance (response , JSONRPCError )
68+ assert response .jsonrpc == "2.0"
69+ assert response .id == "f20fe86132ed4cd197f89a7134de5685"
70+ assert response .error .code == INVALID_PARAMS
71+ assert "Invalid request parameters" in response .error .message
72+
73+ # Verify the session is still alive and can handle more requests
74+ # Send another malformed request to confirm server stability
75+ another_malformed_request = JSONRPCRequest (
76+ jsonrpc = "2.0" ,
77+ id = "test_id_2" ,
78+ method = "tools/call" ,
79+ # params=None # Missing required params
80+ )
81+ another_request_message = SessionMessage (
82+ message = JSONRPCMessage (another_malformed_request )
83+ )
84+
85+ await read_send_stream .send (another_request_message )
86+ await anyio .sleep (0.1 )
87+
88+ # Should get another error response, not a crash
89+ second_response_message = write_receive_stream .receive_nowait ()
90+ second_response = second_response_message .message .root
91+
92+ assert isinstance (second_response , JSONRPCError )
93+ assert second_response .id == "test_id_2"
94+ assert second_response .error .code == INVALID_PARAMS
95+
96+ except anyio .WouldBlock :
97+ pytest .fail ("No response received - server likely crashed" )
98+ finally :
99+ # Close all streams to ensure proper cleanup
100+ await read_send_stream .aclose ()
101+ await write_send_stream .aclose ()
102+ await read_receive_stream .aclose ()
103+ await write_receive_stream .aclose ()
101104
102105
103106@pytest .mark .anyio
@@ -113,52 +116,55 @@ async def test_multiple_concurrent_malformed_requests():
113116 SessionMessage
114117 ](100 )
115118
116- # Start a server session
117- async with ServerSession (
118- read_stream = read_receive_stream ,
119- write_stream = write_send_stream ,
120- init_options = InitializationOptions (
121- server_name = "test_server" ,
122- server_version = "1.0.0" ,
123- capabilities = ServerCapabilities (),
124- ),
125- ):
126- # Send multiple malformed requests concurrently
127- malformed_requests = []
128- for i in range (10 ):
129- malformed_request = JSONRPCRequest (
130- jsonrpc = "2.0" ,
131- id = f"malformed_{ i } " ,
132- method = "initialize" ,
133- # params=None # Missing required params
134- )
135- request_message = SessionMessage (message = JSONRPCMessage (malformed_request ))
136- malformed_requests .append (request_message )
137-
138- # Send all requests
139- for request in malformed_requests :
140- await read_send_stream .send (request )
141-
142- # Give time to process
143- await anyio .sleep (0.2 )
144-
145- # Verify we get error responses for all requests
146- error_responses = []
147- try :
148- while True :
149- response_message = write_receive_stream .receive_nowait ()
150- error_responses .append (response_message .message .root )
151- except anyio .WouldBlock :
152- pass # No more messages
153-
154- # Should have received 10 error responses
155- assert len (error_responses ) == 10
156-
157- for i , response in enumerate (error_responses ):
158- assert isinstance (response , JSONRPCError )
159- assert response .id == f"malformed_{ i } "
160- assert response .error .code == INVALID_PARAMS
161-
162- # Close the send streams to signal end of communication
163- await read_send_stream .aclose ()
164- await write_send_stream .aclose ()
119+ try :
120+ # Start a server session
121+ async with ServerSession (
122+ read_stream = read_receive_stream ,
123+ write_stream = write_send_stream ,
124+ init_options = InitializationOptions (
125+ server_name = "test_server" ,
126+ server_version = "1.0.0" ,
127+ capabilities = ServerCapabilities (),
128+ ),
129+ ):
130+ # Send multiple malformed requests concurrently
131+ malformed_requests = []
132+ for i in range (10 ):
133+ malformed_request = JSONRPCRequest (
134+ jsonrpc = "2.0" ,
135+ id = f"malformed_{ i } " ,
136+ method = "initialize" ,
137+ # params=None # Missing required params
138+ )
139+ request_message = SessionMessage (message = JSONRPCMessage (malformed_request ))
140+ malformed_requests .append (request_message )
141+
142+ # Send all requests
143+ for request in malformed_requests :
144+ await read_send_stream .send (request )
145+
146+ # Give time to process
147+ await anyio .sleep (0.2 )
148+
149+ # Verify we get error responses for all requests
150+ error_responses = []
151+ try :
152+ while True :
153+ response_message = write_receive_stream .receive_nowait ()
154+ error_responses .append (response_message .message .root )
155+ except anyio .WouldBlock :
156+ pass # No more messages
157+
158+ # Should have received 10 error responses
159+ assert len (error_responses ) == 10
160+
161+ for i , response in enumerate (error_responses ):
162+ assert isinstance (response , JSONRPCError )
163+ assert response .id == f"malformed_{ i } "
164+ assert response .error .code == INVALID_PARAMS
165+ finally :
166+ # Close all streams to ensure proper cleanup
167+ await read_send_stream .aclose ()
168+ await write_send_stream .aclose ()
169+ await read_receive_stream .aclose ()
170+ await write_receive_stream .aclose ()
0 commit comments