mirror of
https://github.com/openswarm-ai/openswarm.git
synced 2026-09-28 04:24:51 +02:00
[eric] tests: the discover gate refuses tokenless env_vars servers at the route level, spawn provably untouched
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
"""Discovery must refuse to spawn a credential-driven MCP server that has no credentials yet.
|
||||
|
||||
The Slack case: a tokenless `npx slack-mcp-server` dies at boot and the npm wrapper buries the one
|
||||
useful line under a Node crash dump, which is exactly the toast users saw. The right answer is a
|
||||
clean 409 before any spawn, and an untouched spawn path once credentials exist.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import pytest
|
||||
from unittest.mock import patch
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from backend.main import app
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def client():
|
||||
import backend.auth as auth_mod
|
||||
if not auth_mod.TOKEN:
|
||||
import secrets
|
||||
auth_mod.TOKEN = secrets.token_urlsafe(32)
|
||||
return TestClient(app, headers={"Authorization": f"Bearer {auth_mod.TOKEN}"})
|
||||
|
||||
|
||||
def p_create_tool(client: TestClient, credentials: dict) -> str:
|
||||
res = client.post("/api/tools/create", json={
|
||||
"name": "SlackGateTest",
|
||||
"description": "gate test",
|
||||
"command": "",
|
||||
"mcp_config": {"type": "stdio", "command": "npx", "args": ["-y", "slack-mcp-server@1.3.0", "--transport", "stdio"]},
|
||||
"credentials": credentials,
|
||||
"auth_type": "env_vars",
|
||||
"auth_status": "configured",
|
||||
})
|
||||
assert res.status_code == 200
|
||||
return res.json()["tool"]["id"]
|
||||
|
||||
|
||||
def test_credentialless_env_vars_tool_gets_409_and_no_spawn(client):
|
||||
tool_id = p_create_tool(client, credentials={})
|
||||
try:
|
||||
with patch("backend.apps.tools_lib.tools_lib.discover_mcp_tools_stdio") as spawn:
|
||||
res = client.post(f"/api/tools/{tool_id}/discover")
|
||||
assert res.status_code == 409
|
||||
assert "Connect" in res.json()["detail"]
|
||||
spawn.assert_not_called()
|
||||
finally:
|
||||
client.delete(f"/api/tools/{tool_id}")
|
||||
|
||||
|
||||
def test_credentialed_tool_still_reaches_the_spawn_path(client):
|
||||
tool_id = p_create_tool(client, credentials={"SLACK_MCP_XOXC_TOKEN": "xoxc-test", "SLACK_MCP_XOXD_TOKEN": "xoxd-test"})
|
||||
try:
|
||||
async def p_fake_discover(**kwargs):
|
||||
assert kwargs["env"]["SLACK_MCP_XOXC_TOKEN"] == "xoxc-test"
|
||||
return [{"name": "channels_list", "description": "", "inputSchema": None}]
|
||||
with patch("backend.apps.tools_lib.tools_lib.discover_mcp_tools_stdio", side_effect=p_fake_discover):
|
||||
res = client.post(f"/api/tools/{tool_id}/discover")
|
||||
assert res.status_code == 200
|
||||
assert "channels_list" in res.json()["tool"]["tool_permissions"]
|
||||
finally:
|
||||
client.delete(f"/api/tools/{tool_id}")
|
||||
Reference in New Issue
Block a user