1636ae1501
Cover the stdio adapter: local-mode env bootstrap (OAuth off, API-key gate off, per-user audit path), missing-env failure, PAT owner resolution, and dispatch (unknown tool, write-mode policy denial, and the happy path pinning request context to the PAT owner via the shared registry). Tidy the boundary-test assertion so ruff and black agree. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
64 lines
2.2 KiB
Python
64 lines
2.2 KiB
Python
"""Lock the transport-agnostic core boundary.
|
|
|
|
The core (tool registry, Gitea client, policy, audit, config, request context,
|
|
tools) must import cleanly without dragging in the web stack. If a stray
|
|
``import fastapi`` creeps back into a core module, the local stdio package would
|
|
gain a needless heavy dependency and the ``[server]`` extra split would leak.
|
|
|
|
The check runs in a subprocess because, within the pytest process, FastAPI is
|
|
already imported by the server tests — so ``'fastapi' in sys.modules`` would be
|
|
true regardless. A clean interpreter is the only reliable probe.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
import subprocess
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
_SRC = Path(__file__).resolve().parents[1] / "src"
|
|
|
|
# Core modules that must stay free of the web stack.
|
|
_CORE_MODULES = [
|
|
"aegis_gitea_mcp.registry",
|
|
"aegis_gitea_mcp.gitea_client",
|
|
"aegis_gitea_mcp.policy",
|
|
"aegis_gitea_mcp.audit",
|
|
"aegis_gitea_mcp.config",
|
|
"aegis_gitea_mcp.request_context",
|
|
"aegis_gitea_mcp.response_limits",
|
|
"aegis_gitea_mcp.security",
|
|
"aegis_gitea_mcp.cache",
|
|
"aegis_gitea_mcp.logging_utils",
|
|
"aegis_gitea_mcp.mcp_protocol",
|
|
"aegis_gitea_mcp.errors",
|
|
"aegis_gitea_mcp.tools.raw_tools",
|
|
"aegis_gitea_mcp.tools.read_tools",
|
|
"aegis_gitea_mcp.tools.write_tools",
|
|
"aegis_gitea_mcp.tools.repository",
|
|
"aegis_gitea_mcp.tools.arguments",
|
|
]
|
|
|
|
|
|
def test_core_does_not_import_fastapi() -> None:
|
|
"""Importing the core in a clean interpreter must not import FastAPI."""
|
|
imports = "\n".join(f"import {module}" for module in _CORE_MODULES)
|
|
program = (
|
|
f"import sys\n{imports}\n"
|
|
"leaked = [m for m in ('fastapi', 'uvicorn', 'starlette') if m in sys.modules]\n"
|
|
"assert not leaked, f'core leaked web stack: {leaked}'\n"
|
|
"print('ok')\n"
|
|
)
|
|
env = dict(os.environ)
|
|
env["PYTHONPATH"] = str(_SRC)
|
|
result = subprocess.run(
|
|
[sys.executable, "-c", program],
|
|
env=env,
|
|
capture_output=True,
|
|
text=True,
|
|
)
|
|
detail = f"core import boundary violated.\nstdout: {result.stdout}\nstderr: {result.stderr}"
|
|
assert result.returncode == 0, detail
|
|
assert "ok" in result.stdout
|