2014-10-29 11:10:07 +00:00
|
|
|
|
# coding: utf-8
|
|
|
|
|
|
|
|
|
|
|
|
from __future__ import unicode_literals
|
2015-10-05 21:48:48 +00:00
|
|
|
|
from time import time, sleep
|
2015-04-10 23:57:13 +00:00
|
|
|
|
from unittest import skipIf
|
2015-02-21 23:51:47 +00:00
|
|
|
|
|
|
|
|
|
|
from django.conf import settings
|
|
|
|
|
|
from django.contrib.auth.models import User
|
|
|
|
|
|
from django.core.cache import DEFAULT_CACHE_ALIAS
|
|
|
|
|
|
from django.core.management import call_command
|
|
|
|
|
|
from django.db import connection, transaction, DEFAULT_DB_ALIAS
|
2015-10-24 18:26:11 +00:00
|
|
|
|
from django.template import Template, Context
|
2014-10-29 11:10:07 +00:00
|
|
|
|
from django.test import TransactionTestCase
|
|
|
|
|
|
|
|
|
|
|
|
from ..api import *
|
|
|
|
|
|
from .models import Test
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class APITestCase(TransactionTestCase):
|
|
|
|
|
|
def setUp(self):
|
|
|
|
|
|
self.t1 = Test.objects.create(name='test1')
|
2014-10-29 11:34:44 +00:00
|
|
|
|
self.is_sqlite = connection.vendor == 'sqlite'
|
2014-10-29 11:10:07 +00:00
|
|
|
|
|
|
|
|
|
|
def test_invalidate_tables(self):
|
|
|
|
|
|
with self.assertNumQueries(1):
|
|
|
|
|
|
data1 = list(Test.objects.values_list('name', flat=True))
|
|
|
|
|
|
self.assertListEqual(data1, ['test1'])
|
|
|
|
|
|
|
2014-11-04 00:17:35 +00:00
|
|
|
|
with self.settings(CACHALOT_INVALIDATE_RAW=False):
|
2015-04-11 00:04:53 +00:00
|
|
|
|
with connection.cursor() as cursor:
|
|
|
|
|
|
cursor.execute(
|
|
|
|
|
|
"INSERT INTO cachalot_test (name, public) "
|
|
|
|
|
|
"VALUES ('test2', %s);", [1 if self.is_sqlite else 'true'])
|
2014-10-29 11:10:07 +00:00
|
|
|
|
|
|
|
|
|
|
with self.assertNumQueries(0):
|
|
|
|
|
|
data2 = list(Test.objects.values_list('name', flat=True))
|
|
|
|
|
|
self.assertListEqual(data2, ['test1'])
|
|
|
|
|
|
|
2015-10-05 21:48:48 +00:00
|
|
|
|
invalidate('cachalot_test')
|
2014-10-29 11:10:07 +00:00
|
|
|
|
|
|
|
|
|
|
with self.assertNumQueries(1):
|
|
|
|
|
|
data3 = list(Test.objects.values_list('name', flat=True))
|
|
|
|
|
|
self.assertListEqual(data3, ['test1', 'test2'])
|
|
|
|
|
|
|
|
|
|
|
|
def test_invalidate_models(self):
|
|
|
|
|
|
with self.assertNumQueries(1):
|
|
|
|
|
|
data1 = list(Test.objects.values_list('name', flat=True))
|
|
|
|
|
|
self.assertListEqual(data1, ['test1'])
|
|
|
|
|
|
|
2014-11-04 00:17:35 +00:00
|
|
|
|
with self.settings(CACHALOT_INVALIDATE_RAW=False):
|
2015-04-11 00:04:53 +00:00
|
|
|
|
with connection.cursor() as cursor:
|
|
|
|
|
|
cursor.execute(
|
|
|
|
|
|
"INSERT INTO cachalot_test (name, public) "
|
|
|
|
|
|
"VALUES ('test2', %s);", [1 if self.is_sqlite else 'true'])
|
2014-10-29 11:10:07 +00:00
|
|
|
|
|
|
|
|
|
|
with self.assertNumQueries(0):
|
|
|
|
|
|
data2 = list(Test.objects.values_list('name', flat=True))
|
|
|
|
|
|
self.assertListEqual(data2, ['test1'])
|
|
|
|
|
|
|
2015-10-05 21:48:48 +00:00
|
|
|
|
invalidate(Test)
|
2014-10-29 11:10:07 +00:00
|
|
|
|
|
|
|
|
|
|
with self.assertNumQueries(1):
|
|
|
|
|
|
data3 = list(Test.objects.values_list('name', flat=True))
|
|
|
|
|
|
self.assertListEqual(data3, ['test1', 'test2'])
|
|
|
|
|
|
|
2014-11-24 11:33:55 +00:00
|
|
|
|
def test_invalidate_all(self):
|
2014-10-29 11:10:07 +00:00
|
|
|
|
with self.assertNumQueries(1):
|
|
|
|
|
|
Test.objects.get()
|
|
|
|
|
|
|
|
|
|
|
|
with self.assertNumQueries(0):
|
|
|
|
|
|
Test.objects.get()
|
|
|
|
|
|
|
2015-10-05 20:31:47 +00:00
|
|
|
|
invalidate()
|
2014-10-29 11:10:07 +00:00
|
|
|
|
|
|
|
|
|
|
with self.assertNumQueries(1):
|
|
|
|
|
|
Test.objects.get()
|
|
|
|
|
|
|
2014-11-24 11:33:55 +00:00
|
|
|
|
def test_invalidate_all_in_atomic(self):
|
2014-10-29 11:10:07 +00:00
|
|
|
|
with transaction.atomic():
|
|
|
|
|
|
with self.assertNumQueries(1):
|
|
|
|
|
|
Test.objects.get()
|
|
|
|
|
|
|
|
|
|
|
|
with self.assertNumQueries(0):
|
|
|
|
|
|
Test.objects.get()
|
|
|
|
|
|
|
2015-10-05 20:31:47 +00:00
|
|
|
|
invalidate()
|
2014-10-29 11:10:07 +00:00
|
|
|
|
|
|
|
|
|
|
with self.assertNumQueries(1):
|
|
|
|
|
|
Test.objects.get()
|
|
|
|
|
|
|
2014-11-24 18:11:37 +00:00
|
|
|
|
with self.assertNumQueries(1):
|
2014-10-29 11:10:07 +00:00
|
|
|
|
Test.objects.get()
|
2015-02-21 23:51:47 +00:00
|
|
|
|
|
2015-10-05 21:48:48 +00:00
|
|
|
|
def test_get_last_invalidation(self):
|
|
|
|
|
|
invalidate()
|
|
|
|
|
|
timestamp = get_last_invalidation()
|
|
|
|
|
|
self.assertAlmostEqual(timestamp, time(), delta=0.1)
|
|
|
|
|
|
|
|
|
|
|
|
sleep(0.1)
|
|
|
|
|
|
|
|
|
|
|
|
invalidate('cachalot_test')
|
|
|
|
|
|
timestamp = get_last_invalidation('cachalot_test')
|
|
|
|
|
|
self.assertAlmostEqual(timestamp, time(), delta=0.1)
|
|
|
|
|
|
|
|
|
|
|
|
timestamp = get_last_invalidation('cachalot_testparent')
|
|
|
|
|
|
self.assertNotAlmostEqual(timestamp, time(), delta=0.1)
|
|
|
|
|
|
timestamp = get_last_invalidation('cachalot_testparent',
|
|
|
|
|
|
'cachalot_test')
|
|
|
|
|
|
self.assertAlmostEqual(timestamp, time(), delta=0.1)
|
|
|
|
|
|
|
2015-10-24 18:26:11 +00:00
|
|
|
|
def test_get_last_invalidation_template_tag(self):
|
|
|
|
|
|
original_timestamp = Template("{{ timestamp }}").render(Context({
|
|
|
|
|
|
'timestamp': get_last_invalidation('auth.Group', 'cachalot_test')
|
|
|
|
|
|
}))
|
|
|
|
|
|
|
|
|
|
|
|
template = Template("""
|
|
|
|
|
|
{% load cachalot %}
|
|
|
|
|
|
{% get_last_invalidation 'auth.Group' 'cachalot_test' as timestamp %}
|
|
|
|
|
|
{{ timestamp }}
|
|
|
|
|
|
""")
|
|
|
|
|
|
timestamp = template.render(Context()).strip()
|
|
|
|
|
|
|
|
|
|
|
|
self.assertNotEqual(timestamp, '')
|
|
|
|
|
|
self.assertNotEqual(timestamp, '0.0')
|
|
|
|
|
|
self.assertAlmostEqual(float(timestamp), float(original_timestamp),
|
|
|
|
|
|
delta=0.1)
|
|
|
|
|
|
|
|
|
|
|
|
template = Template("""
|
|
|
|
|
|
{% load cachalot cache %}
|
|
|
|
|
|
{% get_last_invalidation 'auth.Group' 'cachalot_test' as timestamp %}
|
|
|
|
|
|
{% cache 10 cache_key_name timestamp %}
|
|
|
|
|
|
{{ content }}
|
|
|
|
|
|
{% endcache %}
|
|
|
|
|
|
""")
|
|
|
|
|
|
content = template.render(Context({'content': 'something'})).strip()
|
|
|
|
|
|
self.assertEqual(content, 'something')
|
|
|
|
|
|
content = template.render(Context({'content': 'anything'})).strip()
|
|
|
|
|
|
self.assertEqual(content, 'something')
|
|
|
|
|
|
invalidate('cachalot_test')
|
|
|
|
|
|
content = template.render(Context({'content': 'yet another'})).strip()
|
|
|
|
|
|
self.assertEqual(content, 'yet another')
|
|
|
|
|
|
|
2015-02-21 23:51:47 +00:00
|
|
|
|
|
|
|
|
|
|
class CommandTestCase(TransactionTestCase):
|
|
|
|
|
|
multi_db = True
|
|
|
|
|
|
|
|
|
|
|
|
def setUp(self):
|
2015-02-22 00:05:12 +00:00
|
|
|
|
self.db_alias2 = next(alias for alias in settings.DATABASES
|
|
|
|
|
|
if alias != DEFAULT_DB_ALIAS)
|
2015-02-21 23:51:47 +00:00
|
|
|
|
|
2015-02-22 00:05:12 +00:00
|
|
|
|
self.cache_alias2 = next(alias for alias in settings.CACHES
|
|
|
|
|
|
if alias != DEFAULT_CACHE_ALIAS)
|
2015-02-21 23:51:47 +00:00
|
|
|
|
|
|
|
|
|
|
self.t1 = Test.objects.create(name='test1')
|
|
|
|
|
|
self.t2 = Test.objects.using(self.db_alias2).create(name='test2')
|
|
|
|
|
|
self.u = User.objects.create_user('test')
|
|
|
|
|
|
|
|
|
|
|
|
def test_invalidate_cachalot(self):
|
|
|
|
|
|
with self.assertNumQueries(1):
|
|
|
|
|
|
self.assertListEqual(list(Test.objects.all()), [self.t1])
|
|
|
|
|
|
call_command('invalidate_cachalot', verbosity=0)
|
|
|
|
|
|
with self.assertNumQueries(1):
|
|
|
|
|
|
self.assertListEqual(list(Test.objects.all()), [self.t1])
|
|
|
|
|
|
|
|
|
|
|
|
call_command('invalidate_cachalot', 'auth', verbosity=0)
|
|
|
|
|
|
with self.assertNumQueries(0):
|
|
|
|
|
|
self.assertListEqual(list(Test.objects.all()), [self.t1])
|
|
|
|
|
|
|
|
|
|
|
|
call_command('invalidate_cachalot', 'cachalot', verbosity=0)
|
|
|
|
|
|
with self.assertNumQueries(1):
|
|
|
|
|
|
self.assertListEqual(list(Test.objects.all()), [self.t1])
|
|
|
|
|
|
|
|
|
|
|
|
call_command('invalidate_cachalot', 'cachalot.testchild', verbosity=0)
|
|
|
|
|
|
with self.assertNumQueries(0):
|
|
|
|
|
|
self.assertListEqual(list(Test.objects.all()), [self.t1])
|
|
|
|
|
|
|
|
|
|
|
|
call_command('invalidate_cachalot', 'cachalot.test', verbosity=0)
|
|
|
|
|
|
with self.assertNumQueries(1):
|
|
|
|
|
|
self.assertListEqual(list(Test.objects.all()), [self.t1])
|
|
|
|
|
|
|
|
|
|
|
|
with self.assertNumQueries(1):
|
|
|
|
|
|
self.assertListEqual(list(User.objects.all()), [self.u])
|
|
|
|
|
|
call_command('invalidate_cachalot', 'cachalot.test', 'auth.user',
|
|
|
|
|
|
verbosity=0)
|
|
|
|
|
|
with self.assertNumQueries(1):
|
|
|
|
|
|
self.assertListEqual(list(Test.objects.all()), [self.t1])
|
|
|
|
|
|
with self.assertNumQueries(1):
|
|
|
|
|
|
self.assertListEqual(list(User.objects.all()), [self.u])
|
|
|
|
|
|
|
|
|
|
|
|
@skipIf(len(settings.DATABASES) == 1,
|
|
|
|
|
|
'We can’t change the DB used since there’s only one configured')
|
|
|
|
|
|
def test_invalidate_cachalot_multi_db(self):
|
|
|
|
|
|
with self.assertNumQueries(1):
|
|
|
|
|
|
self.assertListEqual(list(Test.objects.all()), [self.t1])
|
|
|
|
|
|
call_command('invalidate_cachalot', verbosity=0,
|
|
|
|
|
|
db_alias=self.db_alias2)
|
|
|
|
|
|
with self.assertNumQueries(0):
|
|
|
|
|
|
self.assertListEqual(list(Test.objects.all()), [self.t1])
|
|
|
|
|
|
|
|
|
|
|
|
with self.assertNumQueries(1, using=self.db_alias2):
|
|
|
|
|
|
self.assertListEqual(list(Test.objects.using(self.db_alias2)),
|
|
|
|
|
|
[self.t2])
|
|
|
|
|
|
call_command('invalidate_cachalot', verbosity=0,
|
|
|
|
|
|
db_alias=self.db_alias2)
|
|
|
|
|
|
with self.assertNumQueries(1, using=self.db_alias2):
|
|
|
|
|
|
self.assertListEqual(list(Test.objects.using(self.db_alias2)),
|
|
|
|
|
|
[self.t2])
|
|
|
|
|
|
|
|
|
|
|
|
@skipIf(len(settings.CACHES) == 1,
|
|
|
|
|
|
'We can’t change the cache used since there’s only one configured')
|
|
|
|
|
|
def test_invalidate_cachalot_multi_cache(self):
|
|
|
|
|
|
with self.assertNumQueries(1):
|
|
|
|
|
|
self.assertListEqual(list(Test.objects.all()), [self.t1])
|
|
|
|
|
|
call_command('invalidate_cachalot', verbosity=0,
|
|
|
|
|
|
cache_alias=self.cache_alias2)
|
|
|
|
|
|
with self.assertNumQueries(0):
|
|
|
|
|
|
self.assertListEqual(list(Test.objects.all()), [self.t1])
|
|
|
|
|
|
|
|
|
|
|
|
with self.assertNumQueries(1):
|
|
|
|
|
|
with self.settings(CACHALOT_CACHE=self.cache_alias2):
|
|
|
|
|
|
self.assertListEqual(list(Test.objects.all()), [self.t1])
|
|
|
|
|
|
call_command('invalidate_cachalot', verbosity=0,
|
|
|
|
|
|
cache_alias=self.cache_alias2)
|
|
|
|
|
|
with self.assertNumQueries(1):
|
|
|
|
|
|
with self.settings(CACHALOT_CACHE=self.cache_alias2):
|
|
|
|
|
|
self.assertListEqual(list(Test.objects.all()), [self.t1])
|