harden: per-item robustness + deadlines/caps across connectors; layered tests
Mail: _safe_decode + _iter_messages (per-mail try/except) -> eine kaputte Mail (charset x-unknown) bricht die Suche nicht mehr ab, findet so auch uralte Mails. Vollscan + Datum-Sort + MAX_SCAN/DEADLINE_S (Selbstheilung, kein 24h-Haenger mehr). Files: search_files mit SEARCH_DEADLINE_S + SEARCH_MAX_DIRS begrenzt (war unbegrenzte rekursive PROPFIND -> real 35s/449 Calls). Calendar/Contacts: PARSE_DEADLINE_S fuer client-seitiges vobject-Parsen; MAX_RESULTS-Output-Cap in get_events/get_tasks (war 10939 Zeilen bei 6000 Events); search Top-N + Hinweise. Tests: in Schichten getrennt -> Smoke (nightly), Edge + Stress (on-demand). Neu: test_smoke/test_edge/test_stress + conftest-Marker + run_full_tests.sh, nightly laeuft nur Smoke. Kontakt-Foto-Roundtrip-Test, Mail-Edge-Mails (x-unknown, kaputter Header, 2009er Alt-Mail). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
936ebc2f56
commit
c9ccb4392b
@@ -0,0 +1,53 @@
|
||||
#!/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
|
||||
Reference in New Issue
Block a user