- Remove all RFC 8693 token exchange tests (integration, manual, keycloak) since Nextcloud doesn't support bearer tokens without upstream patches - Remove manual impersonation/ADR-004 scripts and their docs - Clean up token_exchange singleton from integration conftest - Improve logging in _complete_login_flow_v2_as_user with step-by-step [username] prefixed messages matching _complete_login_flow_v2 style - Remove unnecessary time staggering from all_login_flow_user_tokens; concurrent token acquisition works without artificial delays Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
115 lines
4.1 KiB
Python
115 lines
4.1 KiB
Python
"""Pytest configuration for integration tests.
|
|
|
|
This conftest.py provides hooks and fixtures specific to integration tests,
|
|
including the --provider flag for RAG tests.
|
|
"""
|
|
|
|
import logging
|
|
|
|
import pytest
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
# Valid provider names
|
|
VALID_PROVIDERS = ["openai", "ollama", "anthropic", "bedrock"]
|
|
|
|
|
|
def pytest_addoption(parser):
|
|
"""Add --provider command line option for RAG tests."""
|
|
parser.addoption(
|
|
"--provider",
|
|
action="store",
|
|
default=None,
|
|
choices=VALID_PROVIDERS,
|
|
help="LLM provider for RAG tests: openai, ollama, anthropic, bedrock",
|
|
)
|
|
|
|
|
|
def pytest_configure(config):
|
|
"""Configure custom markers."""
|
|
config.addinivalue_line(
|
|
"markers", "rag: mark test as RAG integration test (requires --provider flag)"
|
|
)
|
|
|
|
|
|
@pytest.fixture(autouse=True, scope="module")
|
|
async def reset_all_singletons():
|
|
"""Reset ALL global singletons between test modules.
|
|
|
|
Prevents anyio.WouldBlock errors caused by stale singleton state
|
|
from previous test modules holding references to dead event loops
|
|
or closed memory streams.
|
|
"""
|
|
# Import all modules with singletons
|
|
import nextcloud_mcp_server.app as app_module
|
|
import nextcloud_mcp_server.auth.client_registry as client_registry_module
|
|
import nextcloud_mcp_server.embedding.service as embedding_module
|
|
import nextcloud_mcp_server.observability.tracing as tracing_module
|
|
import nextcloud_mcp_server.providers.registry as registry_module
|
|
import nextcloud_mcp_server.vector.qdrant_client as qdrant_module
|
|
|
|
# Store originals for restoration after test
|
|
originals = {
|
|
"qdrant_client": qdrant_module._qdrant_client,
|
|
"embedding_service": embedding_module._embedding_service,
|
|
"bm25_service": embedding_module._bm25_service,
|
|
"provider": registry_module._provider,
|
|
"vector_sync_state": (
|
|
app_module._vector_sync_state.document_send_stream,
|
|
app_module._vector_sync_state.document_receive_stream,
|
|
app_module._vector_sync_state.shutdown_event,
|
|
app_module._vector_sync_state.scanner_wake_event,
|
|
),
|
|
"tracer": tracing_module._tracer,
|
|
"registry": client_registry_module._registry,
|
|
}
|
|
|
|
# Close any open memory streams before reset
|
|
if app_module._vector_sync_state.document_send_stream is not None:
|
|
try:
|
|
await app_module._vector_sync_state.document_send_stream.aclose()
|
|
except Exception:
|
|
pass
|
|
if app_module._vector_sync_state.document_receive_stream is not None:
|
|
try:
|
|
await app_module._vector_sync_state.document_receive_stream.aclose()
|
|
except Exception:
|
|
pass
|
|
|
|
# Reset all singletons to None/fresh state
|
|
qdrant_module._qdrant_client = None
|
|
embedding_module._embedding_service = None
|
|
embedding_module._bm25_service = None
|
|
registry_module._provider = None
|
|
app_module._vector_sync_state.document_send_stream = None
|
|
app_module._vector_sync_state.document_receive_stream = None
|
|
app_module._vector_sync_state.shutdown_event = None
|
|
app_module._vector_sync_state.scanner_wake_event = None
|
|
tracing_module._tracer = None
|
|
client_registry_module._registry = None
|
|
|
|
logger.debug("All singletons reset for test module")
|
|
|
|
yield
|
|
|
|
# Cleanup: Close async resources created during test
|
|
if qdrant_module._qdrant_client is not None:
|
|
try:
|
|
await qdrant_module._qdrant_client.close()
|
|
except Exception:
|
|
pass
|
|
|
|
# Restore originals
|
|
qdrant_module._qdrant_client = originals["qdrant_client"]
|
|
embedding_module._embedding_service = originals["embedding_service"]
|
|
embedding_module._bm25_service = originals["bm25_service"]
|
|
registry_module._provider = originals["provider"]
|
|
(
|
|
app_module._vector_sync_state.document_send_stream,
|
|
app_module._vector_sync_state.document_receive_stream,
|
|
app_module._vector_sync_state.shutdown_event,
|
|
app_module._vector_sync_state.scanner_wake_event,
|
|
) = originals["vector_sync_state"]
|
|
tracing_module._tracer = originals["tracer"]
|
|
client_registry_module._registry = originals["registry"]
|