1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798 |
- from random import Random
- from typing import List
- from django.core.cache import cache
- from sentry.hybridcloud.rpc.services.caching import back_with_silo_cache, region_caching_service
- from sentry.hybridcloud.rpc.services.caching.impl import CacheBackend
- from sentry.services.hybrid_cloud.user import RpcUser
- from sentry.services.hybrid_cloud.user.service import user_service
- from sentry.silo import SiloMode
- from sentry.testutils.factories import Factories
- from sentry.testutils.pytest.fixtures import django_db_all
- from sentry.testutils.silo import assume_test_silo_mode, no_silo_test, region_silo_test
- from sentry.types.region import get_local_region
- @django_db_all(transaction=True)
- @region_silo_test(stable=True)
- def test_caching_function():
- cache.clear()
- @back_with_silo_cache(base_key="my-test-key", silo_mode=SiloMode.REGION, t=RpcUser)
- def get_user(user_id: int) -> RpcUser:
- return user_service.get_many(filter=dict(user_ids=[user_id]))[0]
- users = [Factories.create_user() for _ in range(3)]
- old: List[RpcUser] = []
- for u in users:
- next_user = get_user(u.id)
- assert next_user == get_user.cb(u.id)
- old.append(next_user)
- for user in users:
- with assume_test_silo_mode(SiloMode.CONTROL):
- user.update(username=user.username + "moocow")
- # Does not include updates
- for u in old:
- next_user = get_user(u.id)
- assert next_user == u
- region_caching_service.clear_key(
- region_name=get_local_region().name, key=get_user.key_from(u.id)
- )
- for u, cached in zip(users, get_user.get_many([u.id for u in users])):
- assert cached.username == u.username
- @django_db_all(transaction=True)
- @no_silo_test(stable=True)
- def test_cache_versioning():
- cache.clear()
- shared_key = "my-key"
- true_value = "a"
- def reader():
- nonlocal true_value
- last_length = 0
- while True:
- results = yield from CacheBackend.get_cache([shared_key], SiloMode.REGION)
- value = next(iter(results.values()))
- if isinstance(value, str):
- assert (
- len(value) >= last_length
- ), "Read after write broken -- never read a more stale value than has been observed written"
- assert all(c == "a" for c in value)
- else:
- version = value
- copied_local_value = true_value
- yield
- yield from CacheBackend.set_cache(shared_key, copied_local_value, version)
- last_length = len(copied_local_value)
- def writer():
- nonlocal true_value
- while True:
- for i in range(5):
- yield
- true_value += "a"
- yield from CacheBackend.delete_cache(shared_key, SiloMode.REGION)
- def cache_death_event():
- while True:
- for i in range(20):
- yield
- cache.clear()
- reader1 = reader()
- reader2 = reader()
- writer1 = writer()
- cache_death = cache_death_event()
- random = Random(84716393)
- for i in range(10000):
- next(random.choice([reader1, reader2, writer1, cache_death]))
|