Files
hunjing/backend/tests/application/tool_runtime/test_mcp.py
T
2026-08-21 16:00:13 +08:00

75 lines
2.4 KiB
Python

"""MCP 工具转 ToolSpec 测试。"""
import pytest
from app.application.tool_runtime import mcp as mcp_module
from app.application.tool_runtime.mcp import make_mcp_tool_specs
from app.modules.safety.governor import PermissionPolicy
from app.modules.tool_runtime.definition import ToolResult
class _Server:
def __init__(self, name, endpoint_url, auth_token=None):
self.name = name
self.endpoint_url = endpoint_url
self.auth_token = auth_token
def test_make_mcp_tool_specs_basic() -> None:
tools = [{"name": "weather", "description": "查天气", "risk_level": "L1"}]
specs = make_mcp_tool_specs(_Server("srv", "http://mcp.local"), tools, http_client=None)
assert len(specs) == 1
s = specs[0]
assert s.name == "mcp_srv_weather"
assert s.description == "查天气"
assert s.risk_level == "L1"
assert s.permission_policy == PermissionPolicy.allow
def test_make_mcp_tool_specs_default_risk_l2() -> None:
tools = [{"name": "t"}]
specs = make_mcp_tool_specs(_Server("srv", "http://mcp.local"), tools, http_client=None)
assert specs[0].risk_level == "L2"
assert specs[0].permission_policy == PermissionPolicy.ask
def test_make_mcp_tool_specs_skips_unnamed() -> None:
tools = [{"name": "t"}, {"description": "无名"}]
specs = make_mcp_tool_specs(_Server("srv", "http://mcp.local"), tools, http_client=None)
assert len(specs) == 1
@pytest.mark.asyncio
async def test_mcp_executor_calls_call_tool(monkeypatch: pytest.MonkeyPatch) -> None:
captured: dict = {}
async def fake_call_tool(
_http_client, endpoint_url, tool_name, input, auth_token=None, **_kwargs
):
captured.update(tool=tool_name, input=input, endpoint=endpoint_url, auth=auth_token)
return ToolResult(
ok=True,
exit_code=0,
stdout="ok",
stderr="",
duration_ms=1,
timeout=False,
truncated=False,
trace_id="",
)
monkeypatch.setattr(mcp_module, "call_tool", fake_call_tool)
tools = [{"name": "t"}]
specs = make_mcp_tool_specs(
_Server("srv", "http://mcp.local", auth_token="tok"), tools, http_client="HTTP"
)
result = await specs[0].executor({"x": 1}, None)
assert result.ok is True
assert captured == {
"tool": "t",
"input": {"x": 1},
"endpoint": "http://mcp.local",
"auth": "tok",
}