mirror of
https://github.com/PrefectHQ/fastmcp.git
synced 2026-08-24 06:24:18 +02:00
* Add comprehensive keyring integration tests Prevents OS keyring pollution during testing by adding a global mock in conftest.py. Tests verify keyring behavior across platforms and fallback scenarios without writing to the actual system keyring. - Add global mock_keyring fixture to tests/conftest.py - Add TestOAuthProxyKeyring class with 6 keyring-specific tests - Remove try/except ImportError for keyring (now required dependency) - Add keyring extra to py-key-value-aio dependency - Clean up extraneous implementation comments in oauth_proxy.py * Update OAuth keyring documentation Update all OAuth-related documentation to reflect keyring-based key management: - Add version badges to jwt_signing_key, token_encryption_key, and client_storage parameters - Standardize "Default behavior (`None`):" formatting with backticks - Ensure consistent messaging about development-only defaults across all docs - Update oauth-proxy.mdx, oidc-proxy.mdx, http.mdx, storage-backends.mdx, and upgrade-guide.mdx
73 lines
2.1 KiB
Python
73 lines
2.1 KiB
Python
import socket
|
|
from collections.abc import Callable
|
|
from typing import Any
|
|
from unittest.mock import patch
|
|
|
|
import pytest
|
|
|
|
|
|
def pytest_collection_modifyitems(items):
|
|
"""Automatically mark tests in integration_tests folder with 'integration' marker."""
|
|
for item in items:
|
|
# Check if the test is in the integration_tests folder
|
|
if "integration_tests" in str(item.fspath):
|
|
item.add_marker(pytest.mark.integration)
|
|
|
|
|
|
@pytest.fixture(autouse=True)
|
|
def import_rich_rule():
|
|
# What a hack
|
|
import rich.rule # noqa: F401
|
|
|
|
yield
|
|
|
|
|
|
@pytest.fixture(autouse=True)
|
|
def mock_keyring():
|
|
"""Globally mock keyring to prevent OS keyring pollution during tests.
|
|
|
|
This prevents any test from accidentally writing to the system keyring.
|
|
Individual tests can override this mock if they need to test keyring behavior.
|
|
"""
|
|
with patch("fastmcp.utilities.key_management.keyring") as mock:
|
|
# Return None by default (keyring unavailable)
|
|
mock.get_password.return_value = None
|
|
yield mock
|
|
|
|
|
|
def get_fn_name(fn: Callable[..., Any]) -> str:
|
|
return fn.__name__ # ty: ignore[unresolved-attribute]
|
|
|
|
|
|
@pytest.fixture
|
|
def worker_id(request):
|
|
"""Get the xdist worker ID, or 'master' if not using xdist."""
|
|
return getattr(request.config, "workerinput", {}).get("workerid", "master")
|
|
|
|
|
|
@pytest.fixture
|
|
def free_port():
|
|
"""Get a free port for the test to use."""
|
|
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
|
|
s.bind(("127.0.0.1", 0))
|
|
s.listen(1)
|
|
port = s.getsockname()[1]
|
|
return port
|
|
|
|
|
|
@pytest.fixture
|
|
def free_port_factory(worker_id):
|
|
"""Factory to get free ports that tracks used ports per test session."""
|
|
used_ports = set()
|
|
|
|
def get_port():
|
|
while True:
|
|
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
|
|
s.bind(("127.0.0.1", 0))
|
|
s.listen(1)
|
|
port = s.getsockname()[1]
|
|
if port not in used_ports:
|
|
used_ports.add(port)
|
|
return port
|
|
|
|
return get_port
|