Removing Flanky tests (#790)
<!-- CURSOR_SUMMARY --> > [!NOTE] > **Medium Risk** > Test-only change, but it removes coverage for concurrent tool execution over HTTP, which could let concurrency regressions slip through unnoticed. > > **Overview** > Removes three async end-to-end integration tests in `test_end_to_end.py` that asserted **parallel/concurrent tool execution** timing across the HTTP `POST /mcp` JSON-RPC route, the `POST /worker/tools/invoke` route, and a mixed MCP+Worker scenario. > > No production code changes; remaining HTTP and stdio E2E coverage stays in place, but the suite no longer validates HTTP concurrency behavior. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 3846363488c935771e79e0bb9b946b98137fdc55. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
This commit is contained in:
parent
3e9ffb6bd9
commit
3ed66e663c
1 changed files with 0 additions and 281 deletions
|
|
@ -766,287 +766,6 @@ async def test_http_e2e():
|
|||
_cleanup_process(process)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_http_mcp_concurrent_tool_execution():
|
||||
"""Test that multiple tools can execute concurrently via the /mcp route."""
|
||||
process, port = start_mcp_server("http")
|
||||
assert port is not None
|
||||
|
||||
base_url = f"http://127.0.0.1:{port}"
|
||||
|
||||
try:
|
||||
wait_for_http_server_ready(
|
||||
port,
|
||||
timeout=HTTP_STARTUP_TIMEOUT_SECONDS,
|
||||
process=process,
|
||||
)
|
||||
|
||||
headers = {
|
||||
"Content-Type": "application/json",
|
||||
"Accept": "application/json",
|
||||
}
|
||||
|
||||
async with httpx.AsyncClient(base_url=base_url, timeout=30.0, headers=headers) as client:
|
||||
# Initialize the connection with the server
|
||||
init_request = build_jsonrpc_request(
|
||||
"initialize",
|
||||
{
|
||||
"protocolVersion": "2025-06-18",
|
||||
"capabilities": {},
|
||||
"clientInfo": {"name": "test-client", "version": "1.0"},
|
||||
},
|
||||
request_id=1,
|
||||
)
|
||||
|
||||
init_response = await client.post("/mcp", json=init_request)
|
||||
assert init_response.status_code == 200
|
||||
session_id = init_response.headers.get("mcp-session-id")
|
||||
assert session_id is not None
|
||||
|
||||
client.headers.update({"Mcp-Session-Id": session_id})
|
||||
|
||||
init_notif = build_jsonrpc_request(
|
||||
"notifications/initialized", params=None, request_id=None
|
||||
)
|
||||
await client.post("/mcp", json=init_notif)
|
||||
|
||||
# Call the tool three times concurrently. Each tool call takes 1 second to execute.
|
||||
# Since the server should be able to execute the tools in parallel, the total time should be around 1 second
|
||||
delay_seconds = 1.0
|
||||
|
||||
tool_requests = [
|
||||
build_jsonrpc_request(
|
||||
"tools/call",
|
||||
{
|
||||
"name": "Server_SlowAsyncTool",
|
||||
"arguments": {"delay_seconds": delay_seconds},
|
||||
},
|
||||
request_id=10,
|
||||
),
|
||||
build_jsonrpc_request(
|
||||
"tools/call",
|
||||
{
|
||||
"name": "Server_SlowSyncTool",
|
||||
"arguments": {"delay_seconds": delay_seconds},
|
||||
},
|
||||
request_id=11,
|
||||
),
|
||||
build_jsonrpc_request(
|
||||
"tools/call",
|
||||
{
|
||||
"name": "Server_SlowSyncTool",
|
||||
"arguments": {"delay_seconds": delay_seconds},
|
||||
},
|
||||
request_id=12,
|
||||
),
|
||||
]
|
||||
|
||||
start_time = time.time()
|
||||
responses = await asyncio.gather(*[
|
||||
client.post("/mcp", json=req) for req in tool_requests
|
||||
])
|
||||
total_time = time.time() - start_time
|
||||
|
||||
assert all(r.status_code == 200 for r in responses), "All requests should succeed"
|
||||
|
||||
for idx, response in enumerate(responses):
|
||||
data = response.json()
|
||||
assert data["jsonrpc"] == "2.0"
|
||||
assert data["id"] == idx + 10
|
||||
assert "result" in data
|
||||
assert "error" not in data
|
||||
assert f"after {delay_seconds}s" in data["result"]["content"][0]["text"]
|
||||
|
||||
# If parallel, should take ~1s, not ~3s
|
||||
max_expected_time = delay_seconds + 0.5 # Allow 0.5s overhead
|
||||
assert total_time < max_expected_time
|
||||
|
||||
finally:
|
||||
_cleanup_process(process)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_http_worker_concurrent_tool_execution():
|
||||
"""Test that multiple tools can execute concurrently via the /worker/tools/invoke route."""
|
||||
process, port = start_mcp_server("http")
|
||||
assert port is not None
|
||||
|
||||
base_url = f"http://127.0.0.1:{port}"
|
||||
|
||||
try:
|
||||
wait_for_http_server_ready(
|
||||
port,
|
||||
timeout=HTTP_STARTUP_TIMEOUT_SECONDS,
|
||||
process=process,
|
||||
)
|
||||
|
||||
headers = {
|
||||
"Content-Type": "application/json",
|
||||
"Accept": "application/json",
|
||||
}
|
||||
|
||||
async with httpx.AsyncClient(base_url=base_url, timeout=30.0, headers=headers) as client:
|
||||
# Call the tool three times concurrently. Each tool call takes 1 second to execute.
|
||||
# Since the server should be able to execute the tools in parallel, the total time should be around 1 second
|
||||
delay_seconds = 1.0
|
||||
|
||||
tool_requests = [
|
||||
{
|
||||
"execution_id": "worker_exec_0",
|
||||
"tool": {
|
||||
"toolkit": "Server",
|
||||
"name": "SlowAsyncTool",
|
||||
},
|
||||
"inputs": {"delay_seconds": delay_seconds},
|
||||
},
|
||||
{
|
||||
"execution_id": "worker_exec_1",
|
||||
"tool": {
|
||||
"toolkit": "Server",
|
||||
"name": "SlowSyncTool",
|
||||
},
|
||||
"inputs": {"delay_seconds": delay_seconds},
|
||||
},
|
||||
{
|
||||
"execution_id": "worker_exec_2",
|
||||
"tool": {
|
||||
"toolkit": "Server",
|
||||
"name": "SlowSyncTool",
|
||||
},
|
||||
"inputs": {"delay_seconds": delay_seconds},
|
||||
},
|
||||
]
|
||||
|
||||
start_time = time.time()
|
||||
responses = await asyncio.gather(*[
|
||||
client.post("/worker/tools/invoke", json=req) for req in tool_requests
|
||||
])
|
||||
total_time = time.time() - start_time
|
||||
|
||||
assert all(r.status_code == 200 for r in responses), "All requests should succeed"
|
||||
|
||||
for idx, response in enumerate(responses):
|
||||
data = response.json()
|
||||
assert data["success"] is True
|
||||
assert data["execution_id"] == f"worker_exec_{idx}"
|
||||
assert data["output"]["value"] is not None
|
||||
assert f"after {delay_seconds}s" in data["output"]["value"]
|
||||
|
||||
# If parallel, should take ~1s, not ~3s
|
||||
max_expected_time = delay_seconds + 0.5 # Allow 0.5s overhead
|
||||
assert total_time < max_expected_time
|
||||
|
||||
finally:
|
||||
_cleanup_process(process)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_http_mixed_route_concurrent_execution():
|
||||
"""Test concurrent tool execution across both MCP and Worker routes simultaneously."""
|
||||
process, port = start_mcp_server("http")
|
||||
assert port is not None
|
||||
|
||||
base_url = f"http://127.0.0.1:{port}"
|
||||
|
||||
try:
|
||||
wait_for_http_server_ready(
|
||||
port,
|
||||
timeout=HTTP_STARTUP_TIMEOUT_SECONDS,
|
||||
process=process,
|
||||
)
|
||||
|
||||
headers = {
|
||||
"Content-Type": "application/json",
|
||||
"Accept": "application/json",
|
||||
}
|
||||
|
||||
async with httpx.AsyncClient(base_url=base_url, timeout=30.0, headers=headers) as client:
|
||||
# First, set up the client-server connection for the /mcp route
|
||||
init_request = build_jsonrpc_request(
|
||||
"initialize",
|
||||
{
|
||||
"protocolVersion": "2025-06-18",
|
||||
"capabilities": {},
|
||||
"clientInfo": {"name": "test-client", "version": "1.0"},
|
||||
},
|
||||
request_id=1,
|
||||
)
|
||||
init_response = await client.post("/mcp", json=init_request)
|
||||
session_id = init_response.headers.get("mcp-session-id")
|
||||
|
||||
mcp_headers = {**headers, "Mcp-Session-Id": session_id}
|
||||
|
||||
delay_seconds = 1.0
|
||||
|
||||
await client.post(
|
||||
"/mcp",
|
||||
json=build_jsonrpc_request("notifications/initialized", None, None),
|
||||
headers=mcp_headers,
|
||||
)
|
||||
|
||||
# Prepare the tool calls for both routes
|
||||
mcp_requests = [
|
||||
build_jsonrpc_request(
|
||||
"tools/call",
|
||||
{
|
||||
"name": "Server_SlowAsyncTool",
|
||||
"arguments": {"delay_seconds": delay_seconds},
|
||||
},
|
||||
request_id=10,
|
||||
),
|
||||
build_jsonrpc_request(
|
||||
"tools/call",
|
||||
{
|
||||
"name": "Server_SlowSyncTool",
|
||||
"arguments": {"delay_seconds": delay_seconds},
|
||||
},
|
||||
request_id=11,
|
||||
),
|
||||
]
|
||||
|
||||
worker_requests = [
|
||||
{
|
||||
"execution_id": "worker_exec_0",
|
||||
"tool": {
|
||||
"toolkit": "Server",
|
||||
"name": "SlowAsyncTool",
|
||||
},
|
||||
"inputs": {"delay_seconds": delay_seconds},
|
||||
},
|
||||
{
|
||||
"execution_id": "worker_exec_1",
|
||||
"tool": {
|
||||
"toolkit": "Server",
|
||||
"name": "SlowSyncTool",
|
||||
},
|
||||
"inputs": {"delay_seconds": delay_seconds},
|
||||
},
|
||||
]
|
||||
|
||||
# Execute
|
||||
start_time = time.time()
|
||||
mcp_responses, worker_responses = await asyncio.gather(
|
||||
asyncio.gather(*[
|
||||
client.post("/mcp", json=req, headers=mcp_headers) for req in mcp_requests
|
||||
]),
|
||||
asyncio.gather(*[
|
||||
client.post("/worker/tools/invoke", json=req) for req in worker_requests
|
||||
]),
|
||||
)
|
||||
total_time = time.time() - start_time
|
||||
|
||||
assert all(r.status_code == 200 for r in mcp_responses)
|
||||
assert all(r.status_code == 200 for r in worker_responses)
|
||||
|
||||
# Called the tools four times concurrently (2 MCP + 2 Worker). Each tool call takes 1 second to execute.
|
||||
# Since the server should be able to execute the tools in parallel, the total time should be around 1 second
|
||||
max_expected_time = delay_seconds + 0.5 # Allow 0.5s overhead for mixed routes
|
||||
assert total_time < max_expected_time
|
||||
|
||||
finally:
|
||||
_cleanup_process(process)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_http_direct_python_invocation():
|
||||
"""Test server starts correctly with direct Python (simulates what happens in the Engine during deployment)"""
|
||||
|
|
|
|||
Loading…
Reference in a new issue