Files
2026-09-14 11:22:03 -03:00

82 lines
2.5 KiB
Python

"""Contract tests connect directly to a domain server -- never through the
Gateway -- because a tool's input/output contract is a property of the
domain server itself (ADR-023: it's "dumb" about authorization, but not
about its own data shape), independent of who is or isn't entitled to call
it. Reuses `RunningServer`/`free_port` from the e2e suite rather than
duplicating them.
"""
from __future__ import annotations
from collections.abc import AsyncIterator
from typing import Any
import mcp_types as types
import pytest
import uvicorn
from mcp.client.session import ClientSession
from mcp.client.streamable_http import ( # type: ignore[attr-defined]
create_mcp_http_client,
streamable_http_client,
)
from tests.e2e.conftest import RunningServer, free_port
async def call_tool_directly(
server_url: str, tool_name: str, arguments: dict[str, Any]
) -> types.CallToolResult:
"""No auth header at all -- these servers are `main()`-unwrapped here
(no `BackendCredentialGate`), matching how the rest of the e2e suite
already constructs them for in-process tests."""
async with (
create_mcp_http_client() as http_client,
streamable_http_client(server_url, http_client=http_client) as (read, write),
ClientSession(read, write) as session,
):
await session.initialize()
result = await session.call_tool(tool_name, arguments)
if not isinstance(result, types.CallToolResult):
raise TypeError(f"Unexpected result type: {type(result)!r}")
return result
@pytest.fixture
async def sales_domain_url() -> AsyncIterator[str]:
import example_mcp_servers.sales_domain.server as sales_module
port = free_port()
server = RunningServer(
uvicorn.Config(
sales_module.server.streamable_http_app(host="127.0.0.1"),
host="127.0.0.1",
port=port,
log_level="warning",
)
)
await server.start()
try:
yield f"http://127.0.0.1:{port}/mcp"
finally:
await server.stop()
@pytest.fixture
async def finance_domain_url() -> AsyncIterator[str]:
import example_mcp_servers.finance_domain.server as finance_module
port = free_port()
server = RunningServer(
uvicorn.Config(
finance_module.server.streamable_http_app(host="127.0.0.1"),
host="127.0.0.1",
port=port,
log_level="warning",
)
)
await server.start()
try:
yield f"http://127.0.0.1:{port}/mcp"
finally:
await server.stop()