"""Opt-in fixtures for the MCP smoke tests. Tests in this directory are marked ``mcp_smoke`` and skipped unless ``AEGIS_INTEGRATION=1``. They reuse the live-Gitea harness from ``tests/integration`` (one disposable Gitea per session, admin token with the ``all`` scope) and drive the server through a real MCP client over stdio and streamable HTTP, from source and (when ``AEGIS_MCP_IMAGE`` is set) from the built image. """ from __future__ import annotations import os import secrets from pathlib import Path import pytest from tests.integration.conftest import ENABLE_ENV, gitea, integration_enabled from tests.integration.harness import GITEA_PORT, GiteaInstance __all__ = ["ENABLE_ENV", "gitea"] _HERE = Path(__file__).parent.resolve() IMAGE_ENV = "AEGIS_MCP_IMAGE" def pytest_configure(config: pytest.Config) -> None: """Register the ``mcp_smoke`` marker (idempotent with pyproject).""" config.addinivalue_line( "markers", "mcp_smoke: MCP client smoke tests, opt-in via AEGIS_INTEGRATION=1" ) def _is_mcp_smoke(item: pytest.Item) -> bool: try: return _HERE in Path(str(item.path)).resolve().parents except (OSError, ValueError): # pragma: no cover - defensive return False def pytest_collection_modifyitems(config: pytest.Config, items: list[pytest.Item]) -> None: """Mark and (unless opted in) skip every test under tests/mcp.""" selected = [item for item in items if _is_mcp_smoke(item)] skip = pytest.mark.skip(reason=f"MCP smoke tests need {ENABLE_ENV}=1 and Docker") for item in selected: item.add_marker(pytest.mark.mcp_smoke) if not integration_enabled(): item.add_marker(skip) if selected and len(selected) == len(items): # A smoke-only run starts the server in subprocesses, so the in-process # coverage gate does not apply. for namespace in (config.option, config.known_args_namespace): if getattr(namespace, "cov_fail_under", None) is not None: namespace.cov_fail_under = 0 @pytest.fixture(scope="session") def gitea_internal_url(gitea: GiteaInstance) -> str: """URL of the Gitea container for other containers on the harness network.""" return f"http://{gitea.container}:{GITEA_PORT}" @pytest.fixture(scope="session") def mcp_image() -> str: """The built image under test; the test is skipped when ``AEGIS_MCP_IMAGE`` is unset.""" image = os.environ.get(IMAGE_ENV, "").strip() if not image: pytest.skip(f"{IMAGE_ENV} is not set; image smoke tests need a built image") return image @pytest.fixture def bearer_token() -> str: """A random 48 character MCP bearer token.""" return secrets.token_urlsafe(36)