#!/usr/bin/env python3 """MCP Smoke-Tests — NIGHTLY. Minimal, schnell, read-only. Pro Connector: Server erreichbar, OAuth ok, tools/list ok, ein billiger Read-Call. Faengt Totalausfaelle (Server down, Auth kaputt, Backend weg) ueber Nacht ab, ohne Last zu erzeugen oder Testdaten zu schreiben. Lauf: /opt/mcp-servers/venv/bin/python -m pytest test_smoke.py -q """ import pytest from test_all import SERVERS, get_token, mcp_call, tool_call pytestmark = pytest.mark.smoke @pytest.mark.parametrize("svc,port", list(SERVERS.items())) def test_server_up_auth_tools(svc, port): """Server erreichbar + OAuth (client_credentials) + tools/list liefert Tools.""" token = get_token(port) assert token, f"{svc}: kein Token" res = mcp_call(port, token, "tools/list") assert res and res.get("result", {}).get("tools"), f"{svc}: tools/list leer" # --- ein billiger Read-Call pro Connector (read-only, kein Schreiben) --- def test_mail_read(): assert "mcp-test-mail" in tool_call(SERVERS["mail"], get_token(SERVERS["mail"]), "list_accounts") def test_calendar_read(): text = tool_call(SERVERS["calendar"], get_token(SERVERS["calendar"]), "list_calendars") assert "calendar-test" in text or "MCP Test" in text def test_contacts_read(): # read-only Suche; Treffer egal, Hauptsache der Call kommt sauber durch text = tool_call(SERVERS["contacts"], get_token(SERVERS["contacts"]), "search_contacts", {"query": "Mustermann", "limit": 1}) assert isinstance(text, str) and len(text) >= 0 def test_files_read(): text = tool_call(SERVERS["files"], get_token(SERVERS["files"]), "list_files", {"path": "/"}) assert "DIR" in text or "/" in text def test_notes_read(): text = tool_call(SERVERS["notes"], get_token(SERVERS["notes"]), "list_notebooks") assert "id:" in text