011 fix redis

This commit is contained in:
Раис Юсупалиев
2026-03-08 22:06:40 +03:00
parent 299a8e69ea
commit 81e484d7d1
8 changed files with 161 additions and 16 deletions
+69 -2
View File
@@ -1,8 +1,16 @@
import asyncio
from collections.abc import Callable
import sys
import types
import app.config as app_config
import pytest
from app.config import Settings
from app.repositories.cache.redis_cache import PriceCache
from app.repositories.cache.redis_cache import (
PriceCache,
PriceCacheRepositoryError,
_default_redis_client_factory,
)
class InMemoryRedisClient:
@@ -39,6 +47,28 @@ class InMemoryRedisClient:
return self._storage[key][0]
class FailingGetRedisClient:
async def get(self, key: str) -> bytes | None: # noqa: ARG002
raise RuntimeError("redis get failed")
async def set(self, key: str, value: str, ex: int | None = None) -> bool: # noqa: ARG002
return True
async def delete(self, key: str) -> int: # noqa: ARG002
return 1
class FailingSetRedisClient:
async def get(self, key: str) -> bytes | None: # noqa: ARG002
return None
async def set(self, key: str, value: str, ex: int | None = None) -> bool: # noqa: ARG002
raise RuntimeError("redis set failed")
async def delete(self, key: str) -> int: # noqa: ARG002
return 1
def test_cache_miss_returns_none() -> None:
cache = PriceCache(InMemoryRedisClient(), ttl_seconds=120)
@@ -130,7 +160,7 @@ repository:
""".strip(),
encoding="utf-8",
)
monkeypatch.setenv("G2S_CONFIG_FILE", str(config_file))
monkeypatch.setattr(app_config, "_resolve_runtime_config_file", lambda: str(config_file))
settings = Settings()
redis_client = InMemoryRedisClient()
@@ -153,3 +183,40 @@ repository:
assert seen_dsns == ["redis://redis.internal:6380/5"]
assert redis_client.last_set == ("config-key", '{"ok":true}', 123)
assert result == {"ok": True}
def test_default_client_factory_uses_aioredis_from_url(monkeypatch) -> None:
seen: dict[str, object] = {}
expected_client = object()
def fake_from_url(redis_dsn: str, *, encoding: str, decode_responses: bool) -> object:
seen["redis_dsn"] = redis_dsn
seen["encoding"] = encoding
seen["decode_responses"] = decode_responses
return expected_client
fake_aioredis_module = types.SimpleNamespace(from_url=fake_from_url)
monkeypatch.setitem(sys.modules, "aioredis", fake_aioredis_module)
actual_client = _default_redis_client_factory("redis://cache.internal:6381/9")
assert actual_client is expected_client
assert seen == {
"redis_dsn": "redis://cache.internal:6381/9",
"encoding": "utf-8",
"decode_responses": False,
}
def test_get_raises_deterministic_repository_error_on_redis_failure() -> None:
cache = PriceCache(FailingGetRedisClient(), ttl_seconds=10)
with pytest.raises(PriceCacheRepositoryError, match="Redis cache read failed."):
asyncio.run(cache.get("key"))
def test_set_raises_deterministic_repository_error_on_redis_failure() -> None:
cache = PriceCache(FailingSetRedisClient(), ttl_seconds=10)
with pytest.raises(PriceCacheRepositoryError, match="Redis cache write failed."):
asyncio.run(cache.set("key", {"v": 1}))