refactor(redis): strengthen shared cache invalidation
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import asyncio
|
||||
import time
|
||||
import unittest
|
||||
from types import SimpleNamespace
|
||||
from unittest.mock import patch
|
||||
@@ -40,6 +41,39 @@ class AsyncTTLCacheSingleflightTests(unittest.IsolatedAsyncioTestCase):
|
||||
self.assertEqual(set_calls, 1)
|
||||
|
||||
|
||||
class AsyncTTLCacheInvalidationTests(unittest.IsolatedAsyncioTestCase):
|
||||
async def test_invalidate_remote_deletes_single_redis_key(self):
|
||||
settings = SimpleNamespace(REDIS_URL="redis://example", REDIS_KEY_PREFIX="test")
|
||||
cache = AsyncTTLCache(ttl_seconds=60, settings=settings, namespace="bench")
|
||||
cache._data["same"] = (time.monotonic() + 60, {"ok": True})
|
||||
deleted = []
|
||||
|
||||
async def fake_delete(_settings, *keys):
|
||||
deleted.extend(keys)
|
||||
|
||||
with patch("bot.infra.redis.cache_delete", new=fake_delete):
|
||||
await cache.invalidate_remote("same")
|
||||
|
||||
self.assertIsNone(cache.get_fresh("same"))
|
||||
self.assertEqual(deleted, ["test:cache:bench:same"])
|
||||
|
||||
async def test_invalidate_remote_deletes_namespace_pattern(self):
|
||||
settings = SimpleNamespace(REDIS_URL="redis://example", REDIS_KEY_PREFIX="test")
|
||||
cache = AsyncTTLCache(ttl_seconds=60, settings=settings, namespace="bench")
|
||||
cache._data["same"] = (time.monotonic() + 60, {"ok": True})
|
||||
patterns = []
|
||||
|
||||
async def fake_delete_pattern(_settings, pattern):
|
||||
patterns.append(pattern)
|
||||
return 1
|
||||
|
||||
with patch("bot.infra.redis.cache_delete_pattern", new=fake_delete_pattern):
|
||||
await cache.invalidate_remote()
|
||||
|
||||
self.assertIsNone(cache.get_fresh("same"))
|
||||
self.assertEqual(patterns, ["test:cache:bench:*"])
|
||||
|
||||
|
||||
class Crypt4LinkCacheTests(unittest.IsolatedAsyncioTestCase):
|
||||
async def asyncTearDown(self):
|
||||
config_link._CRYPT4_LINK_CACHES.clear()
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
import unittest
|
||||
from types import SimpleNamespace
|
||||
from unittest.mock import patch
|
||||
|
||||
import bot.app.web.subscription_webapp # noqa: F401
|
||||
from bot.app.web.webapp import common as common_module
|
||||
|
||||
|
||||
class WebappRedisCacheInvalidationTests(unittest.IsolatedAsyncioTestCase):
|
||||
async def test_invalidate_webapp_user_caches_deletes_me_and_devices_keys(self):
|
||||
settings = SimpleNamespace(REDIS_URL="redis://redis:6379/0", REDIS_KEY_PREFIX="shop")
|
||||
deleted = []
|
||||
|
||||
async def fake_delete(_settings, *keys):
|
||||
deleted.extend(keys)
|
||||
|
||||
with patch.object(common_module, "cache_delete", fake_delete):
|
||||
await common_module._invalidate_webapp_user_caches(
|
||||
settings,
|
||||
42,
|
||||
"42",
|
||||
99,
|
||||
include_devices=True,
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
deleted,
|
||||
[
|
||||
"shop:cache:webapp:me:42",
|
||||
"shop:cache:webapp:devices:42",
|
||||
"shop:cache:webapp:me:99",
|
||||
"shop:cache:webapp:devices:99",
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user