mirror of
https://github.com/mcloh/Enterprise-MCP-Service-Bus.git
synced 2026-11-06 06:24:12 +00:00
M4 implementada e backlog validado
This commit is contained in:
81
RI/tests/contract/conftest.py
Normal file
81
RI/tests/contract/conftest.py
Normal file
@@ -0,0 +1,81 @@
|
||||
"""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()
|
||||
Reference in New Issue
Block a user