Swap Redis limiters for in-memory in test fixture
The conftest was setting rate_limit_redis_enabled=False but the
rate_limit module's _redis_client and the RedisSlidingWindow limiters
are constructed at module import. Flipping the setting inside the
fixture doesn't undo that, so the Redis client was still being
constructed and torn down at the end of the test event loop, raising
RuntimeError('Event loop is closed').
This swaps the limiters directly on the module in the fixture setup
and restores the originals in teardown. Local: 164 passed, 7
skipped.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+29
-1
@@ -18,6 +18,7 @@ from sqlalchemy.types import CHAR
|
|||||||
from cartsnitch_api.config import settings as cartsnitch_settings
|
from cartsnitch_api.config import settings as cartsnitch_settings
|
||||||
from cartsnitch_api.database import get_db
|
from cartsnitch_api.database import get_db
|
||||||
from cartsnitch_api.main import create_app
|
from cartsnitch_api.main import create_app
|
||||||
|
from cartsnitch_api.middleware import rate_limit as _rate_limit_module
|
||||||
from cartsnitch_api.models import Base
|
from cartsnitch_api.models import Base
|
||||||
|
|
||||||
|
|
||||||
@@ -140,12 +141,39 @@ TEST_DATABASE_URL = "sqlite+aiosqlite:///:memory:"
|
|||||||
|
|
||||||
@pytest.fixture(autouse=True)
|
@pytest.fixture(autouse=True)
|
||||||
def disable_rate_limiting():
|
def disable_rate_limiting():
|
||||||
"""Disable rate limiting for all tests to prevent 429 interference."""
|
"""Disable rate limiting for all tests to prevent 429 interference.
|
||||||
|
|
||||||
|
The rate_limit module creates its Redis client at import time when
|
||||||
|
``settings.rate_limit_redis_enabled`` is true. We can't undo that by
|
||||||
|
flipping the setting inside the fixture — the client and the
|
||||||
|
Redis-backed limiters are already constructed. So we swap them out
|
||||||
|
for the in-memory limiters directly on the module, which also
|
||||||
|
prevents "Event loop is closed" errors when the redis client tries
|
||||||
|
to disconnect after the test event loop ends.
|
||||||
|
"""
|
||||||
cartsnitch_settings.rate_limit_enabled = False
|
cartsnitch_settings.rate_limit_enabled = False
|
||||||
cartsnitch_settings.rate_limit_redis_enabled = False
|
cartsnitch_settings.rate_limit_redis_enabled = False
|
||||||
|
original_public = _rate_limit_module._public_limiter
|
||||||
|
original_auth = _rate_limit_module._auth_limiter
|
||||||
|
original_auth_strict = _rate_limit_module._auth_strict_limiter
|
||||||
|
_rate_limit_module._redis_client = None
|
||||||
|
_rate_limit_module._use_redis = False
|
||||||
|
_rate_limit_module._public_limiter = _rate_limit_module.InMemorySlidingWindow(
|
||||||
|
cartsnitch_settings.rate_limit_requests, cartsnitch_settings.rate_limit_window_seconds
|
||||||
|
)
|
||||||
|
_rate_limit_module._auth_limiter = _rate_limit_module.InMemorySlidingWindow(
|
||||||
|
cartsnitch_settings.rate_limit_requests * 5, cartsnitch_settings.rate_limit_window_seconds
|
||||||
|
)
|
||||||
|
_rate_limit_module._auth_strict_limiter = _rate_limit_module.InMemorySlidingWindow(
|
||||||
|
cartsnitch_settings.rate_limit_auth_requests,
|
||||||
|
cartsnitch_settings.rate_limit_auth_window_seconds,
|
||||||
|
)
|
||||||
yield
|
yield
|
||||||
cartsnitch_settings.rate_limit_enabled = True
|
cartsnitch_settings.rate_limit_enabled = True
|
||||||
cartsnitch_settings.rate_limit_redis_enabled = True
|
cartsnitch_settings.rate_limit_redis_enabled = True
|
||||||
|
_rate_limit_module._public_limiter = original_public
|
||||||
|
_rate_limit_module._auth_limiter = original_auth
|
||||||
|
_rate_limit_module._auth_strict_limiter = original_auth_strict
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
|
|||||||
Reference in New Issue
Block a user