Fix quota cache mixup (#3539)

Co-authored-by: Richard Schreiber <schreiber@rami.io>
This commit is contained in:
Raphael Michel
2023-08-23 10:09:50 +02:00
committed by GitHub
co-authored by Richard Schreiber
parent 9bd3444aad
commit 0c96f758a8
7 changed files with 126 additions and 15 deletions
+57
View File
@@ -98,6 +98,7 @@ class BaseQuotaTestCase(TestCase):
self.var3 = ItemVariation.objects.create(item=self.item3, value='Fancy')
@pytest.mark.usefixtures("fakeredis_client")
class QuotaTestCase(BaseQuotaTestCase):
@classscope(attr='o')
def test_available(self):
@@ -434,6 +435,62 @@ class QuotaTestCase(BaseQuotaTestCase):
self.assertEqual(self.var1.check_quotas(), (Quota.AVAILABILITY_ORDERED, 0))
self.assertEqual(self.var1.check_quotas(count_waitinglist=False), (Quota.AVAILABILITY_OK, 1))
@classscope(attr='o')
def test_waitinglist_cache_separation(self):
self.quota.items.add(self.item1)
self.quota.size = 1
self.quota.save()
WaitingListEntry.objects.create(
event=self.event, item=self.item1, email='foo@bar.com'
)
# Check that there is no "cache mixup" even across multiple runs
qa = QuotaAvailability(count_waitinglist=False)
qa.queue(self.quota)
qa.compute()
assert qa.results[self.quota] == (Quota.AVAILABILITY_OK, 1)
qa = QuotaAvailability(count_waitinglist=True)
qa.queue(self.quota)
qa.compute(allow_cache=True)
assert qa.results[self.quota] == (Quota.AVAILABILITY_ORDERED, 0)
qa = QuotaAvailability(count_waitinglist=True)
qa.queue(self.quota)
qa.compute(allow_cache=True)
assert qa.results[self.quota] == (Quota.AVAILABILITY_ORDERED, 0)
qa = QuotaAvailability(count_waitinglist=False)
qa.queue(self.quota)
qa.compute()
assert qa.results[self.quota] == (Quota.AVAILABILITY_OK, 1)
# Rebuild cache required
self.quota.size = 5
self.quota.save()
qa = QuotaAvailability(count_waitinglist=True)
qa.queue(self.quota)
qa.compute(allow_cache=True)
assert qa.results[self.quota] == (Quota.AVAILABILITY_ORDERED, 0)
qa = QuotaAvailability(count_waitinglist=False)
qa.queue(self.quota)
qa.compute(allow_cache=True)
assert qa.results[self.quota] == (Quota.AVAILABILITY_OK, 1)
self.quota.rebuild_cache()
qa = QuotaAvailability(count_waitinglist=True)
qa.queue(self.quota)
qa.compute(allow_cache=True)
assert qa.results[self.quota] == (Quota.AVAILABILITY_OK, 4)
qa = QuotaAvailability(count_waitinglist=False)
qa.queue(self.quota)
qa.compute(allow_cache=True)
assert qa.results[self.quota] == (Quota.AVAILABILITY_OK, 5)
@classscope(attr='o')
def test_waitinglist_variation_fulfilled(self):
self.quota.variations.add(self.var1)
+39
View File
@@ -22,10 +22,14 @@
import inspect
import pytest
from django.test import override_settings
from django.utils import translation
from django_scopes import scopes_disabled
from fakeredis import FakeConnection
from xdist.dsession import DSession
from pretix.testutils.mock import get_redis_connection
CRASHED_ITEMS = set()
@@ -74,3 +78,38 @@ def pytest_fixture_setup(fixturedef, request):
@pytest.fixture(autouse=True)
def reset_locale():
translation.activate("en")
@pytest.fixture
def fakeredis_client(monkeypatch):
with override_settings(
HAS_REDIS=True,
REAL_CACHE_USED=True,
CACHES={
'redis': {
'BACKEND': 'django.core.cache.backends.redis.RedisCache',
'LOCATION': 'redis://127.0.0.1',
'OPTIONS': {
'connection_class': FakeConnection
}
},
'redis_session': {
'BACKEND': 'django.core.cache.backends.redis.RedisCache',
'LOCATION': 'redis://127.0.0.1',
'OPTIONS': {
'connection_class': FakeConnection
}
},
'default': {
'BACKEND': 'django.core.cache.backends.redis.RedisCache',
'LOCATION': 'redis://127.0.0.1',
'OPTIONS': {
'connection_class': FakeConnection
}
},
}
):
redis = get_redis_connection("default", True)
redis.flushall()
monkeypatch.setattr('django_redis.get_redis_connection', get_redis_connection, raising=False)
yield redis