PageRenderTime 133ms CodeModel.GetById 15ms app.highlight 106ms RepoModel.GetById 1ms app.codeStats 1ms

/tests/regressiontests/cache/tests.py

https://code.google.com/p/mango-py/
Python | 1462 lines | 1239 code | 136 blank | 87 comment | 19 complexity | 2345451cc3c4a3510d7cac5f4263a224 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1# -*- coding: utf-8 -*-
   2
   3# Unit tests for cache framework
   4# Uses whatever cache backend is set in the test settings file.
   5
   6import os
   7import re
   8import tempfile
   9import time
  10import warnings
  11
  12from django.conf import settings
  13from django.core import management
  14from django.core.cache import get_cache, DEFAULT_CACHE_ALIAS
  15from django.core.cache.backends.base import CacheKeyWarning
  16from django.http import HttpResponse, HttpRequest, QueryDict
  17from django.middleware.cache import FetchFromCacheMiddleware, UpdateCacheMiddleware, CacheMiddleware
  18from django.test import RequestFactory
  19from django.test.utils import get_warnings_state, restore_warnings_state
  20from django.utils import translation
  21from django.utils import unittest
  22from django.utils.cache import patch_vary_headers, get_cache_key, learn_cache_key, patch_cache_control
  23from django.utils.hashcompat import md5_constructor
  24from django.views.decorators.cache import cache_page
  25
  26from regressiontests.cache.models import Poll, expensive_calculation
  27
  28# functions/classes for complex data type tests
  29def f():
  30    return 42
  31class C:
  32    def m(n):
  33        return 24
  34
  35class DummyCacheTests(unittest.TestCase):
  36    # The Dummy cache backend doesn't really behave like a test backend,
  37    # so it has different test requirements.
  38    def setUp(self):
  39        self.cache = get_cache('django.core.cache.backends.dummy.DummyCache')
  40
  41    def test_simple(self):
  42        "Dummy cache backend ignores cache set calls"
  43        self.cache.set("key", "value")
  44        self.assertEqual(self.cache.get("key"), None)
  45
  46    def test_add(self):
  47        "Add doesn't do anything in dummy cache backend"
  48        self.cache.add("addkey1", "value")
  49        result = self.cache.add("addkey1", "newvalue")
  50        self.assertEqual(result, True)
  51        self.assertEqual(self.cache.get("addkey1"), None)
  52
  53    def test_non_existent(self):
  54        "Non-existent keys aren't found in the dummy cache backend"
  55        self.assertEqual(self.cache.get("does_not_exist"), None)
  56        self.assertEqual(self.cache.get("does_not_exist", "bang!"), "bang!")
  57
  58    def test_get_many(self):
  59        "get_many returns nothing for the dummy cache backend"
  60        self.cache.set('a', 'a')
  61        self.cache.set('b', 'b')
  62        self.cache.set('c', 'c')
  63        self.cache.set('d', 'd')
  64        self.assertEqual(self.cache.get_many(['a', 'c', 'd']), {})
  65        self.assertEqual(self.cache.get_many(['a', 'b', 'e']), {})
  66
  67    def test_delete(self):
  68        "Cache deletion is transparently ignored on the dummy cache backend"
  69        self.cache.set("key1", "spam")
  70        self.cache.set("key2", "eggs")
  71        self.assertEqual(self.cache.get("key1"), None)
  72        self.cache.delete("key1")
  73        self.assertEqual(self.cache.get("key1"), None)
  74        self.assertEqual(self.cache.get("key2"), None)
  75
  76    def test_has_key(self):
  77        "The has_key method doesn't ever return True for the dummy cache backend"
  78        self.cache.set("hello1", "goodbye1")
  79        self.assertEqual(self.cache.has_key("hello1"), False)
  80        self.assertEqual(self.cache.has_key("goodbye1"), False)
  81
  82    def test_in(self):
  83        "The in operator doesn't ever return True for the dummy cache backend"
  84        self.cache.set("hello2", "goodbye2")
  85        self.assertEqual("hello2" in self.cache, False)
  86        self.assertEqual("goodbye2" in self.cache, False)
  87
  88    def test_incr(self):
  89        "Dummy cache values can't be incremented"
  90        self.cache.set('answer', 42)
  91        self.assertRaises(ValueError, self.cache.incr, 'answer')
  92        self.assertRaises(ValueError, self.cache.incr, 'does_not_exist')
  93
  94    def test_decr(self):
  95        "Dummy cache values can't be decremented"
  96        self.cache.set('answer', 42)
  97        self.assertRaises(ValueError, self.cache.decr, 'answer')
  98        self.assertRaises(ValueError, self.cache.decr, 'does_not_exist')
  99
 100    def test_data_types(self):
 101        "All data types are ignored equally by the dummy cache"
 102        stuff = {
 103            'string'    : 'this is a string',
 104            'int'       : 42,
 105            'list'      : [1, 2, 3, 4],
 106            'tuple'     : (1, 2, 3, 4),
 107            'dict'      : {'A': 1, 'B' : 2},
 108            'function'  : f,
 109            'class'     : C,
 110        }
 111        self.cache.set("stuff", stuff)
 112        self.assertEqual(self.cache.get("stuff"), None)
 113
 114    def test_expiration(self):
 115        "Expiration has no effect on the dummy cache"
 116        self.cache.set('expire1', 'very quickly', 1)
 117        self.cache.set('expire2', 'very quickly', 1)
 118        self.cache.set('expire3', 'very quickly', 1)
 119
 120        time.sleep(2)
 121        self.assertEqual(self.cache.get("expire1"), None)
 122
 123        self.cache.add("expire2", "newvalue")
 124        self.assertEqual(self.cache.get("expire2"), None)
 125        self.assertEqual(self.cache.has_key("expire3"), False)
 126
 127    def test_unicode(self):
 128        "Unicode values are ignored by the dummy cache"
 129        stuff = {
 130            u'ascii': u'ascii_value',
 131            u'unicode_ascii': u'Ińtërnâtiônŕlizćtiřn1',
 132            u'Ińtërnâtiônŕlizćtiřn': u'Ińtërnâtiônŕlizćtiřn2',
 133            u'ascii': {u'x' : 1 }
 134            }
 135        for (key, value) in stuff.items():
 136            self.cache.set(key, value)
 137            self.assertEqual(self.cache.get(key), None)
 138
 139    def test_set_many(self):
 140        "set_many does nothing for the dummy cache backend"
 141        self.cache.set_many({'a': 1, 'b': 2})
 142
 143    def test_delete_many(self):
 144        "delete_many does nothing for the dummy cache backend"
 145        self.cache.delete_many(['a', 'b'])
 146
 147    def test_clear(self):
 148        "clear does nothing for the dummy cache backend"
 149        self.cache.clear()
 150
 151    def test_incr_version(self):
 152        "Dummy cache versions can't be incremented"
 153        self.cache.set('answer', 42)
 154        self.assertRaises(ValueError, self.cache.incr_version, 'answer')
 155        self.assertRaises(ValueError, self.cache.incr_version, 'does_not_exist')
 156
 157    def test_decr_version(self):
 158        "Dummy cache versions can't be decremented"
 159        self.cache.set('answer', 42)
 160        self.assertRaises(ValueError, self.cache.decr_version, 'answer')
 161        self.assertRaises(ValueError, self.cache.decr_version, 'does_not_exist')
 162
 163
 164class BaseCacheTests(object):
 165    # A common set of tests to apply to all cache backends
 166
 167    def test_simple(self):
 168        # Simple cache set/get works
 169        self.cache.set("key", "value")
 170        self.assertEqual(self.cache.get("key"), "value")
 171
 172    def test_add(self):
 173        # A key can be added to a cache
 174        self.cache.add("addkey1", "value")
 175        result = self.cache.add("addkey1", "newvalue")
 176        self.assertEqual(result, False)
 177        self.assertEqual(self.cache.get("addkey1"), "value")
 178
 179    def test_prefix(self):
 180        # Test for same cache key conflicts between shared backend
 181        self.cache.set('somekey', 'value')
 182
 183        # should not be set in the prefixed cache
 184        self.assertFalse(self.prefix_cache.has_key('somekey'))
 185
 186        self.prefix_cache.set('somekey', 'value2')
 187
 188        self.assertEqual(self.cache.get('somekey'), 'value')
 189        self.assertEqual(self.prefix_cache.get('somekey'), 'value2')
 190
 191    def test_non_existent(self):
 192        # Non-existent cache keys return as None/default
 193        # get with non-existent keys
 194        self.assertEqual(self.cache.get("does_not_exist"), None)
 195        self.assertEqual(self.cache.get("does_not_exist", "bang!"), "bang!")
 196
 197    def test_get_many(self):
 198        # Multiple cache keys can be returned using get_many
 199        self.cache.set('a', 'a')
 200        self.cache.set('b', 'b')
 201        self.cache.set('c', 'c')
 202        self.cache.set('d', 'd')
 203        self.assertEqual(self.cache.get_many(['a', 'c', 'd']), {'a' : 'a', 'c' : 'c', 'd' : 'd'})
 204        self.assertEqual(self.cache.get_many(['a', 'b', 'e']), {'a' : 'a', 'b' : 'b'})
 205
 206    def test_delete(self):
 207        # Cache keys can be deleted
 208        self.cache.set("key1", "spam")
 209        self.cache.set("key2", "eggs")
 210        self.assertEqual(self.cache.get("key1"), "spam")
 211        self.cache.delete("key1")
 212        self.assertEqual(self.cache.get("key1"), None)
 213        self.assertEqual(self.cache.get("key2"), "eggs")
 214
 215    def test_has_key(self):
 216        # The cache can be inspected for cache keys
 217        self.cache.set("hello1", "goodbye1")
 218        self.assertEqual(self.cache.has_key("hello1"), True)
 219        self.assertEqual(self.cache.has_key("goodbye1"), False)
 220
 221    def test_in(self):
 222        # The in operator can be used to inspet cache contents
 223        self.cache.set("hello2", "goodbye2")
 224        self.assertEqual("hello2" in self.cache, True)
 225        self.assertEqual("goodbye2" in self.cache, False)
 226
 227    def test_incr(self):
 228        # Cache values can be incremented
 229        self.cache.set('answer', 41)
 230        self.assertEqual(self.cache.incr('answer'), 42)
 231        self.assertEqual(self.cache.get('answer'), 42)
 232        self.assertEqual(self.cache.incr('answer', 10), 52)
 233        self.assertEqual(self.cache.get('answer'), 52)
 234        self.assertRaises(ValueError, self.cache.incr, 'does_not_exist')
 235
 236    def test_decr(self):
 237        # Cache values can be decremented
 238        self.cache.set('answer', 43)
 239        self.assertEqual(self.cache.decr('answer'), 42)
 240        self.assertEqual(self.cache.get('answer'), 42)
 241        self.assertEqual(self.cache.decr('answer', 10), 32)
 242        self.assertEqual(self.cache.get('answer'), 32)
 243        self.assertRaises(ValueError, self.cache.decr, 'does_not_exist')
 244
 245    def test_data_types(self):
 246        # Many different data types can be cached
 247        stuff = {
 248            'string'    : 'this is a string',
 249            'int'       : 42,
 250            'list'      : [1, 2, 3, 4],
 251            'tuple'     : (1, 2, 3, 4),
 252            'dict'      : {'A': 1, 'B' : 2},
 253            'function'  : f,
 254            'class'     : C,
 255        }
 256        self.cache.set("stuff", stuff)
 257        self.assertEqual(self.cache.get("stuff"), stuff)
 258
 259    def test_cache_read_for_model_instance(self):
 260        # Don't want fields with callable as default to be called on cache read
 261        expensive_calculation.num_runs = 0
 262        Poll.objects.all().delete()
 263        my_poll = Poll.objects.create(question="Well?")
 264        self.assertEqual(Poll.objects.count(), 1)
 265        pub_date = my_poll.pub_date
 266        self.cache.set('question', my_poll)
 267        cached_poll = self.cache.get('question')
 268        self.assertEqual(cached_poll.pub_date, pub_date)
 269        # We only want the default expensive calculation run once
 270        self.assertEqual(expensive_calculation.num_runs, 1)
 271
 272    def test_cache_write_for_model_instance_with_deferred(self):
 273        # Don't want fields with callable as default to be called on cache write
 274        expensive_calculation.num_runs = 0
 275        Poll.objects.all().delete()
 276        my_poll = Poll.objects.create(question="What?")
 277        self.assertEqual(expensive_calculation.num_runs, 1)
 278        defer_qs = Poll.objects.all().defer('question')
 279        self.assertEqual(defer_qs.count(), 1)
 280        self.assertEqual(expensive_calculation.num_runs, 1)
 281        self.cache.set('deferred_queryset', defer_qs)
 282        # cache set should not re-evaluate default functions
 283        self.assertEqual(expensive_calculation.num_runs, 1)
 284
 285    def test_cache_read_for_model_instance_with_deferred(self):
 286        # Don't want fields with callable as default to be called on cache read
 287        expensive_calculation.num_runs = 0
 288        Poll.objects.all().delete()
 289        my_poll = Poll.objects.create(question="What?")
 290        self.assertEqual(expensive_calculation.num_runs, 1)
 291        defer_qs = Poll.objects.all().defer('question')
 292        self.assertEqual(defer_qs.count(), 1)
 293        self.cache.set('deferred_queryset', defer_qs)
 294        self.assertEqual(expensive_calculation.num_runs, 1)
 295        runs_before_cache_read = expensive_calculation.num_runs
 296        cached_polls = self.cache.get('deferred_queryset')
 297        # We only want the default expensive calculation run on creation and set
 298        self.assertEqual(expensive_calculation.num_runs, runs_before_cache_read)
 299
 300    def test_expiration(self):
 301        # Cache values can be set to expire
 302        self.cache.set('expire1', 'very quickly', 1)
 303        self.cache.set('expire2', 'very quickly', 1)
 304        self.cache.set('expire3', 'very quickly', 1)
 305
 306        time.sleep(2)
 307        self.assertEqual(self.cache.get("expire1"), None)
 308
 309        self.cache.add("expire2", "newvalue")
 310        self.assertEqual(self.cache.get("expire2"), "newvalue")
 311        self.assertEqual(self.cache.has_key("expire3"), False)
 312
 313    def test_unicode(self):
 314        # Unicode values can be cached
 315        stuff = {
 316            u'ascii': u'ascii_value',
 317            u'unicode_ascii': u'Ińtërnâtiônŕlizćtiřn1',
 318            u'Ińtërnâtiônŕlizćtiřn': u'Ińtërnâtiônŕlizćtiřn2',
 319            u'ascii': {u'x' : 1 }
 320            }
 321        # Test `set`
 322        for (key, value) in stuff.items():
 323            self.cache.set(key, value)
 324            self.assertEqual(self.cache.get(key), value)
 325
 326        # Test `add`
 327        for (key, value) in stuff.items():
 328            self.cache.delete(key)
 329            self.cache.add(key, value)
 330            self.assertEqual(self.cache.get(key), value)
 331
 332        # Test `set_many`
 333        for (key, value) in stuff.items():
 334            self.cache.delete(key)
 335        self.cache.set_many(stuff)
 336        for (key, value) in stuff.items():
 337            self.assertEqual(self.cache.get(key), value)
 338
 339    def test_binary_string(self):
 340        # Binary strings should be cachable
 341        from zlib import compress, decompress
 342        value = 'value_to_be_compressed'
 343        compressed_value = compress(value)
 344
 345        # Test set
 346        self.cache.set('binary1', compressed_value)
 347        compressed_result = self.cache.get('binary1')
 348        self.assertEqual(compressed_value, compressed_result)
 349        self.assertEqual(value, decompress(compressed_result))
 350
 351        # Test add
 352        self.cache.add('binary1-add', compressed_value)
 353        compressed_result = self.cache.get('binary1-add')
 354        self.assertEqual(compressed_value, compressed_result)
 355        self.assertEqual(value, decompress(compressed_result))
 356
 357        # Test set_many
 358        self.cache.set_many({'binary1-set_many': compressed_value})
 359        compressed_result = self.cache.get('binary1-set_many')
 360        self.assertEqual(compressed_value, compressed_result)
 361        self.assertEqual(value, decompress(compressed_result))
 362
 363    def test_set_many(self):
 364        # Multiple keys can be set using set_many
 365        self.cache.set_many({"key1": "spam", "key2": "eggs"})
 366        self.assertEqual(self.cache.get("key1"), "spam")
 367        self.assertEqual(self.cache.get("key2"), "eggs")
 368
 369    def test_set_many_expiration(self):
 370        # set_many takes a second ``timeout`` parameter
 371        self.cache.set_many({"key1": "spam", "key2": "eggs"}, 1)
 372        time.sleep(2)
 373        self.assertEqual(self.cache.get("key1"), None)
 374        self.assertEqual(self.cache.get("key2"), None)
 375
 376    def test_delete_many(self):
 377        # Multiple keys can be deleted using delete_many
 378        self.cache.set("key1", "spam")
 379        self.cache.set("key2", "eggs")
 380        self.cache.set("key3", "ham")
 381        self.cache.delete_many(["key1", "key2"])
 382        self.assertEqual(self.cache.get("key1"), None)
 383        self.assertEqual(self.cache.get("key2"), None)
 384        self.assertEqual(self.cache.get("key3"), "ham")
 385
 386    def test_clear(self):
 387        # The cache can be emptied using clear
 388        self.cache.set("key1", "spam")
 389        self.cache.set("key2", "eggs")
 390        self.cache.clear()
 391        self.assertEqual(self.cache.get("key1"), None)
 392        self.assertEqual(self.cache.get("key2"), None)
 393
 394    def test_long_timeout(self):
 395        '''
 396        Using a timeout greater than 30 days makes memcached think
 397        it is an absolute expiration timestamp instead of a relative
 398        offset. Test that we honour this convention. Refs #12399.
 399        '''
 400        self.cache.set('key1', 'eggs', 60*60*24*30 + 1) #30 days + 1 second
 401        self.assertEqual(self.cache.get('key1'), 'eggs')
 402
 403        self.cache.add('key2', 'ham', 60*60*24*30 + 1)
 404        self.assertEqual(self.cache.get('key2'), 'ham')
 405
 406        self.cache.set_many({'key3': 'sausage', 'key4': 'lobster bisque'}, 60*60*24*30 + 1)
 407        self.assertEqual(self.cache.get('key3'), 'sausage')
 408        self.assertEqual(self.cache.get('key4'), 'lobster bisque')
 409
 410    def perform_cull_test(self, initial_count, final_count):
 411        """This is implemented as a utility method, because only some of the backends
 412        implement culling. The culling algorithm also varies slightly, so the final
 413        number of entries will vary between backends"""
 414        # Create initial cache key entries. This will overflow the cache, causing a cull
 415        for i in range(1, initial_count):
 416            self.cache.set('cull%d' % i, 'value', 1000)
 417        count = 0
 418        # Count how many keys are left in the cache.
 419        for i in range(1, initial_count):
 420            if self.cache.has_key('cull%d' % i):
 421                count = count + 1
 422        self.assertEqual(count, final_count)
 423
 424    def test_invalid_keys(self):
 425        """
 426        All the builtin backends (except memcached, see below) should warn on
 427        keys that would be refused by memcached. This encourages portable
 428        caching code without making it too difficult to use production backends
 429        with more liberal key rules. Refs #6447.
 430
 431        """
 432        # mimic custom ``make_key`` method being defined since the default will
 433        # never show the below warnings
 434        def func(key, *args):
 435            return key
 436
 437        old_func = self.cache.key_func
 438        self.cache.key_func = func
 439        # On Python 2.6+ we could use the catch_warnings context
 440        # manager to test this warning nicely. Since we can't do that
 441        # yet, the cleanest option is to temporarily ask for
 442        # CacheKeyWarning to be raised as an exception.
 443        _warnings_state = get_warnings_state()
 444        warnings.simplefilter("error", CacheKeyWarning)
 445
 446        try:
 447            # memcached does not allow whitespace or control characters in keys
 448            self.assertRaises(CacheKeyWarning, self.cache.set, 'key with spaces', 'value')
 449            # memcached limits key length to 250
 450            self.assertRaises(CacheKeyWarning, self.cache.set, 'a' * 251, 'value')
 451        finally:
 452            restore_warnings_state(_warnings_state)
 453            self.cache.key_func = old_func
 454
 455    def test_cache_versioning_get_set(self):
 456        # set, using default version = 1
 457        self.cache.set('answer1', 42)
 458        self.assertEqual(self.cache.get('answer1'), 42)
 459        self.assertEqual(self.cache.get('answer1', version=1), 42)
 460        self.assertEqual(self.cache.get('answer1', version=2), None)
 461
 462        self.assertEqual(self.v2_cache.get('answer1'), None)
 463        self.assertEqual(self.v2_cache.get('answer1', version=1), 42)
 464        self.assertEqual(self.v2_cache.get('answer1', version=2), None)
 465
 466        # set, default version = 1, but manually override version = 2
 467        self.cache.set('answer2', 42, version=2)
 468        self.assertEqual(self.cache.get('answer2'), None)
 469        self.assertEqual(self.cache.get('answer2', version=1), None)
 470        self.assertEqual(self.cache.get('answer2', version=2), 42)
 471
 472        self.assertEqual(self.v2_cache.get('answer2'), 42)
 473        self.assertEqual(self.v2_cache.get('answer2', version=1), None)
 474        self.assertEqual(self.v2_cache.get('answer2', version=2), 42)
 475
 476        # v2 set, using default version = 2
 477        self.v2_cache.set('answer3', 42)
 478        self.assertEqual(self.cache.get('answer3'), None)
 479        self.assertEqual(self.cache.get('answer3', version=1), None)
 480        self.assertEqual(self.cache.get('answer3', version=2), 42)
 481
 482        self.assertEqual(self.v2_cache.get('answer3'), 42)
 483        self.assertEqual(self.v2_cache.get('answer3', version=1), None)
 484        self.assertEqual(self.v2_cache.get('answer3', version=2), 42)
 485
 486        # v2 set, default version = 2, but manually override version = 1
 487        self.v2_cache.set('answer4', 42, version=1)
 488        self.assertEqual(self.cache.get('answer4'), 42)
 489        self.assertEqual(self.cache.get('answer4', version=1), 42)
 490        self.assertEqual(self.cache.get('answer4', version=2), None)
 491
 492        self.assertEqual(self.v2_cache.get('answer4'), None)
 493        self.assertEqual(self.v2_cache.get('answer4', version=1), 42)
 494        self.assertEqual(self.v2_cache.get('answer4', version=2), None)
 495
 496    def test_cache_versioning_add(self):
 497
 498        # add, default version = 1, but manually override version = 2
 499        self.cache.add('answer1', 42, version=2)
 500        self.assertEqual(self.cache.get('answer1', version=1), None)
 501        self.assertEqual(self.cache.get('answer1', version=2), 42)
 502
 503        self.cache.add('answer1', 37, version=2)
 504        self.assertEqual(self.cache.get('answer1', version=1), None)
 505        self.assertEqual(self.cache.get('answer1', version=2), 42)
 506
 507        self.cache.add('answer1', 37, version=1)
 508        self.assertEqual(self.cache.get('answer1', version=1), 37)
 509        self.assertEqual(self.cache.get('answer1', version=2), 42)
 510
 511        # v2 add, using default version = 2
 512        self.v2_cache.add('answer2', 42)
 513        self.assertEqual(self.cache.get('answer2', version=1), None)
 514        self.assertEqual(self.cache.get('answer2', version=2), 42)
 515
 516        self.v2_cache.add('answer2', 37)
 517        self.assertEqual(self.cache.get('answer2', version=1), None)
 518        self.assertEqual(self.cache.get('answer2', version=2), 42)
 519
 520        self.v2_cache.add('answer2', 37, version=1)
 521        self.assertEqual(self.cache.get('answer2', version=1), 37)
 522        self.assertEqual(self.cache.get('answer2', version=2), 42)
 523
 524        # v2 add, default version = 2, but manually override version = 1
 525        self.v2_cache.add('answer3', 42, version=1)
 526        self.assertEqual(self.cache.get('answer3', version=1), 42)
 527        self.assertEqual(self.cache.get('answer3', version=2), None)
 528
 529        self.v2_cache.add('answer3', 37, version=1)
 530        self.assertEqual(self.cache.get('answer3', version=1), 42)
 531        self.assertEqual(self.cache.get('answer3', version=2), None)
 532
 533        self.v2_cache.add('answer3', 37)
 534        self.assertEqual(self.cache.get('answer3', version=1), 42)
 535        self.assertEqual(self.cache.get('answer3', version=2), 37)
 536
 537    def test_cache_versioning_has_key(self):
 538        self.cache.set('answer1', 42)
 539
 540        # has_key
 541        self.assertTrue(self.cache.has_key('answer1'))
 542        self.assertTrue(self.cache.has_key('answer1', version=1))
 543        self.assertFalse(self.cache.has_key('answer1', version=2))
 544
 545        self.assertFalse(self.v2_cache.has_key('answer1'))
 546        self.assertTrue(self.v2_cache.has_key('answer1', version=1))
 547        self.assertFalse(self.v2_cache.has_key('answer1', version=2))
 548
 549    def test_cache_versioning_delete(self):
 550        self.cache.set('answer1', 37, version=1)
 551        self.cache.set('answer1', 42, version=2)
 552        self.cache.delete('answer1')
 553        self.assertEqual(self.cache.get('answer1', version=1), None)
 554        self.assertEqual(self.cache.get('answer1', version=2), 42)
 555
 556        self.cache.set('answer2', 37, version=1)
 557        self.cache.set('answer2', 42, version=2)
 558        self.cache.delete('answer2', version=2)
 559        self.assertEqual(self.cache.get('answer2', version=1), 37)
 560        self.assertEqual(self.cache.get('answer2', version=2), None)
 561
 562        self.cache.set('answer3', 37, version=1)
 563        self.cache.set('answer3', 42, version=2)
 564        self.v2_cache.delete('answer3')
 565        self.assertEqual(self.cache.get('answer3', version=1), 37)
 566        self.assertEqual(self.cache.get('answer3', version=2), None)
 567
 568        self.cache.set('answer4', 37, version=1)
 569        self.cache.set('answer4', 42, version=2)
 570        self.v2_cache.delete('answer4', version=1)
 571        self.assertEqual(self.cache.get('answer4', version=1), None)
 572        self.assertEqual(self.cache.get('answer4', version=2), 42)
 573
 574    def test_cache_versioning_incr_decr(self):
 575        self.cache.set('answer1', 37, version=1)
 576        self.cache.set('answer1', 42, version=2)
 577        self.cache.incr('answer1')
 578        self.assertEqual(self.cache.get('answer1', version=1), 38)
 579        self.assertEqual(self.cache.get('answer1', version=2), 42)
 580        self.cache.decr('answer1')
 581        self.assertEqual(self.cache.get('answer1', version=1), 37)
 582        self.assertEqual(self.cache.get('answer1', version=2), 42)
 583
 584        self.cache.set('answer2', 37, version=1)
 585        self.cache.set('answer2', 42, version=2)
 586        self.cache.incr('answer2', version=2)
 587        self.assertEqual(self.cache.get('answer2', version=1), 37)
 588        self.assertEqual(self.cache.get('answer2', version=2), 43)
 589        self.cache.decr('answer2', version=2)
 590        self.assertEqual(self.cache.get('answer2', version=1), 37)
 591        self.assertEqual(self.cache.get('answer2', version=2), 42)
 592
 593        self.cache.set('answer3', 37, version=1)
 594        self.cache.set('answer3', 42, version=2)
 595        self.v2_cache.incr('answer3')
 596        self.assertEqual(self.cache.get('answer3', version=1), 37)
 597        self.assertEqual(self.cache.get('answer3', version=2), 43)
 598        self.v2_cache.decr('answer3')
 599        self.assertEqual(self.cache.get('answer3', version=1), 37)
 600        self.assertEqual(self.cache.get('answer3', version=2), 42)
 601
 602        self.cache.set('answer4', 37, version=1)
 603        self.cache.set('answer4', 42, version=2)
 604        self.v2_cache.incr('answer4', version=1)
 605        self.assertEqual(self.cache.get('answer4', version=1), 38)
 606        self.assertEqual(self.cache.get('answer4', version=2), 42)
 607        self.v2_cache.decr('answer4', version=1)
 608        self.assertEqual(self.cache.get('answer4', version=1), 37)
 609        self.assertEqual(self.cache.get('answer4', version=2), 42)
 610
 611    def test_cache_versioning_get_set_many(self):
 612        # set, using default version = 1
 613        self.cache.set_many({'ford1': 37, 'arthur1': 42})
 614        self.assertEqual(self.cache.get_many(['ford1','arthur1']),
 615                         {'ford1': 37, 'arthur1': 42})
 616        self.assertEqual(self.cache.get_many(['ford1','arthur1'], version=1),
 617                         {'ford1': 37, 'arthur1': 42})
 618        self.assertEqual(self.cache.get_many(['ford1','arthur1'], version=2), {})
 619
 620        self.assertEqual(self.v2_cache.get_many(['ford1','arthur1']), {})
 621        self.assertEqual(self.v2_cache.get_many(['ford1','arthur1'], version=1),
 622                         {'ford1': 37, 'arthur1': 42})
 623        self.assertEqual(self.v2_cache.get_many(['ford1','arthur1'], version=2), {})
 624
 625        # set, default version = 1, but manually override version = 2
 626        self.cache.set_many({'ford2': 37, 'arthur2': 42}, version=2)
 627        self.assertEqual(self.cache.get_many(['ford2','arthur2']), {})
 628        self.assertEqual(self.cache.get_many(['ford2','arthur2'], version=1), {})
 629        self.assertEqual(self.cache.get_many(['ford2','arthur2'], version=2),
 630                         {'ford2': 37, 'arthur2': 42})
 631
 632        self.assertEqual(self.v2_cache.get_many(['ford2','arthur2']),
 633                         {'ford2': 37, 'arthur2': 42})
 634        self.assertEqual(self.v2_cache.get_many(['ford2','arthur2'], version=1), {})
 635        self.assertEqual(self.v2_cache.get_many(['ford2','arthur2'], version=2),
 636                         {'ford2': 37, 'arthur2': 42})
 637
 638        # v2 set, using default version = 2
 639        self.v2_cache.set_many({'ford3': 37, 'arthur3': 42})
 640        self.assertEqual(self.cache.get_many(['ford3','arthur3']), {})
 641        self.assertEqual(self.cache.get_many(['ford3','arthur3'], version=1), {})
 642        self.assertEqual(self.cache.get_many(['ford3','arthur3'], version=2),
 643                         {'ford3': 37, 'arthur3': 42})
 644
 645        self.assertEqual(self.v2_cache.get_many(['ford3','arthur3']),
 646                         {'ford3': 37, 'arthur3': 42})
 647        self.assertEqual(self.v2_cache.get_many(['ford3','arthur3'], version=1), {})
 648        self.assertEqual(self.v2_cache.get_many(['ford3','arthur3'], version=2),
 649                         {'ford3': 37, 'arthur3': 42})
 650
 651        # v2 set, default version = 2, but manually override version = 1
 652        self.v2_cache.set_many({'ford4': 37, 'arthur4': 42}, version=1)
 653        self.assertEqual(self.cache.get_many(['ford4','arthur4']),
 654                         {'ford4': 37, 'arthur4': 42})
 655        self.assertEqual(self.cache.get_many(['ford4','arthur4'], version=1),
 656                         {'ford4': 37, 'arthur4': 42})
 657        self.assertEqual(self.cache.get_many(['ford4','arthur4'], version=2), {})
 658
 659        self.assertEqual(self.v2_cache.get_many(['ford4','arthur4']), {})
 660        self.assertEqual(self.v2_cache.get_many(['ford4','arthur4'], version=1),
 661                         {'ford4': 37, 'arthur4': 42})
 662        self.assertEqual(self.v2_cache.get_many(['ford4','arthur4'], version=2), {})
 663
 664    def test_incr_version(self):
 665        self.cache.set('answer', 42, version=2)
 666        self.assertEqual(self.cache.get('answer'), None)
 667        self.assertEqual(self.cache.get('answer', version=1), None)
 668        self.assertEqual(self.cache.get('answer', version=2), 42)
 669        self.assertEqual(self.cache.get('answer', version=3), None)
 670
 671        self.assertEqual(self.cache.incr_version('answer', version=2), 3)
 672        self.assertEqual(self.cache.get('answer'), None)
 673        self.assertEqual(self.cache.get('answer', version=1), None)
 674        self.assertEqual(self.cache.get('answer', version=2), None)
 675        self.assertEqual(self.cache.get('answer', version=3), 42)
 676
 677        self.v2_cache.set('answer2', 42)
 678        self.assertEqual(self.v2_cache.get('answer2'), 42)
 679        self.assertEqual(self.v2_cache.get('answer2', version=1), None)
 680        self.assertEqual(self.v2_cache.get('answer2', version=2), 42)
 681        self.assertEqual(self.v2_cache.get('answer2', version=3), None)
 682
 683        self.assertEqual(self.v2_cache.incr_version('answer2'), 3)
 684        self.assertEqual(self.v2_cache.get('answer2'), None)
 685        self.assertEqual(self.v2_cache.get('answer2', version=1), None)
 686        self.assertEqual(self.v2_cache.get('answer2', version=2), None)
 687        self.assertEqual(self.v2_cache.get('answer2', version=3), 42)
 688
 689        self.assertRaises(ValueError, self.cache.incr_version, 'does_not_exist')
 690
 691    def test_decr_version(self):
 692        self.cache.set('answer', 42, version=2)
 693        self.assertEqual(self.cache.get('answer'), None)
 694        self.assertEqual(self.cache.get('answer', version=1), None)
 695        self.assertEqual(self.cache.get('answer', version=2), 42)
 696
 697        self.assertEqual(self.cache.decr_version('answer', version=2), 1)
 698        self.assertEqual(self.cache.get('answer'), 42)
 699        self.assertEqual(self.cache.get('answer', version=1), 42)
 700        self.assertEqual(self.cache.get('answer', version=2), None)
 701
 702        self.v2_cache.set('answer2', 42)
 703        self.assertEqual(self.v2_cache.get('answer2'), 42)
 704        self.assertEqual(self.v2_cache.get('answer2', version=1), None)
 705        self.assertEqual(self.v2_cache.get('answer2', version=2), 42)
 706
 707        self.assertEqual(self.v2_cache.decr_version('answer2'), 1)
 708        self.assertEqual(self.v2_cache.get('answer2'), None)
 709        self.assertEqual(self.v2_cache.get('answer2', version=1), 42)
 710        self.assertEqual(self.v2_cache.get('answer2', version=2), None)
 711
 712        self.assertRaises(ValueError, self.cache.decr_version, 'does_not_exist', version=2)
 713
 714    def test_custom_key_func(self):
 715        # Two caches with different key functions aren't visible to each other
 716        self.cache.set('answer1', 42)
 717        self.assertEqual(self.cache.get('answer1'), 42)
 718        self.assertEqual(self.custom_key_cache.get('answer1'), None)
 719        self.assertEqual(self.custom_key_cache2.get('answer1'), None)
 720
 721        self.custom_key_cache.set('answer2', 42)
 722        self.assertEqual(self.cache.get('answer2'), None)
 723        self.assertEqual(self.custom_key_cache.get('answer2'), 42)
 724        self.assertEqual(self.custom_key_cache2.get('answer2'), 42)
 725
 726def custom_key_func(key, key_prefix, version):
 727    "A customized cache key function"
 728    return 'CUSTOM-' + '-'.join([key_prefix, str(version), key])
 729
 730class DBCacheTests(unittest.TestCase, BaseCacheTests):
 731    def setUp(self):
 732        # Spaces are used in the table name to ensure quoting/escaping is working
 733        self._table_name = 'test cache table'
 734        management.call_command('createcachetable', self._table_name, verbosity=0, interactive=False)
 735        self.cache = get_cache('django.core.cache.backends.db.DatabaseCache', LOCATION=self._table_name, OPTIONS={'MAX_ENTRIES': 30})
 736        self.prefix_cache = get_cache('django.core.cache.backends.db.DatabaseCache', LOCATION=self._table_name, KEY_PREFIX='cacheprefix')
 737        self.v2_cache = get_cache('django.core.cache.backends.db.DatabaseCache', LOCATION=self._table_name, VERSION=2)
 738        self.custom_key_cache = get_cache('django.core.cache.backends.db.DatabaseCache', LOCATION=self._table_name, KEY_FUNCTION=custom_key_func)
 739        self.custom_key_cache2 = get_cache('django.core.cache.backends.db.DatabaseCache', LOCATION=self._table_name, KEY_FUNCTION='regressiontests.cache.tests.custom_key_func')
 740
 741    def tearDown(self):
 742        from django.db import connection
 743        cursor = connection.cursor()
 744        cursor.execute('DROP TABLE %s' % connection.ops.quote_name(self._table_name))
 745
 746    def test_cull(self):
 747        self.perform_cull_test(50, 29)
 748
 749    def test_zero_cull(self):
 750        self.cache = get_cache('django.core.cache.backends.db.DatabaseCache', LOCATION=self._table_name, OPTIONS={'MAX_ENTRIES': 30, 'CULL_FREQUENCY': 0})
 751        self.perform_cull_test(50, 18)
 752
 753    def test_old_initialization(self):
 754        self.cache = get_cache('db://%s?max_entries=30&cull_frequency=0' % self._table_name)
 755        self.perform_cull_test(50, 18)
 756
 757class LocMemCacheTests(unittest.TestCase, BaseCacheTests):
 758    def setUp(self):
 759        self.cache = get_cache('django.core.cache.backends.locmem.LocMemCache', OPTIONS={'MAX_ENTRIES': 30})
 760        self.prefix_cache = get_cache('django.core.cache.backends.locmem.LocMemCache', KEY_PREFIX='cacheprefix')
 761        self.v2_cache = get_cache('django.core.cache.backends.locmem.LocMemCache', VERSION=2)
 762        self.custom_key_cache = get_cache('django.core.cache.backends.locmem.LocMemCache', OPTIONS={'MAX_ENTRIES': 30}, KEY_FUNCTION=custom_key_func)
 763        self.custom_key_cache2 = get_cache('django.core.cache.backends.locmem.LocMemCache', OPTIONS={'MAX_ENTRIES': 30}, KEY_FUNCTION='regressiontests.cache.tests.custom_key_func')
 764
 765        # LocMem requires a hack to make the other caches
 766        # share a data store with the 'normal' cache.
 767        self.prefix_cache._cache = self.cache._cache
 768        self.prefix_cache._expire_info = self.cache._expire_info
 769
 770        self.v2_cache._cache = self.cache._cache
 771        self.v2_cache._expire_info = self.cache._expire_info
 772
 773        self.custom_key_cache._cache = self.cache._cache
 774        self.custom_key_cache._expire_info = self.cache._expire_info
 775
 776        self.custom_key_cache2._cache = self.cache._cache
 777        self.custom_key_cache2._expire_info = self.cache._expire_info
 778
 779    def tearDown(self):
 780        self.cache.clear()
 781
 782    def test_cull(self):
 783        self.perform_cull_test(50, 29)
 784
 785    def test_zero_cull(self):
 786        self.cache = get_cache('django.core.cache.backends.locmem.LocMemCache', OPTIONS={'MAX_ENTRIES': 30, 'CULL_FREQUENCY': 0})
 787        self.perform_cull_test(50, 19)
 788
 789    def test_old_initialization(self):
 790        self.cache = get_cache('locmem://?max_entries=30&cull_frequency=0')
 791        self.perform_cull_test(50, 19)
 792
 793    def test_multiple_caches(self):
 794        "Check that multiple locmem caches are isolated"
 795        mirror_cache = get_cache('django.core.cache.backends.locmem.LocMemCache')
 796        other_cache = get_cache('django.core.cache.backends.locmem.LocMemCache', LOCATION='other')
 797
 798        self.cache.set('value1', 42)
 799        self.assertEqual(mirror_cache.get('value1'), 42)
 800        self.assertEqual(other_cache.get('value1'), None)
 801
 802# memcached backend isn't guaranteed to be available.
 803# To check the memcached backend, the test settings file will
 804# need to contain a cache backend setting that points at
 805# your memcache server.
 806class MemcachedCacheTests(unittest.TestCase, BaseCacheTests):
 807    def setUp(self):
 808        name = settings.CACHES[DEFAULT_CACHE_ALIAS]['LOCATION']
 809        self.cache = get_cache('django.core.cache.backends.memcached.MemcachedCache', LOCATION=name)
 810        self.prefix_cache = get_cache('django.core.cache.backends.memcached.MemcachedCache', LOCATION=name, KEY_PREFIX='cacheprefix')
 811        self.v2_cache = get_cache('django.core.cache.backends.memcached.MemcachedCache', LOCATION=name, VERSION=2)
 812        self.custom_key_cache = get_cache('django.core.cache.backends.memcached.MemcachedCache', LOCATION=name, KEY_FUNCTION=custom_key_func)
 813        self.custom_key_cache2 = get_cache('django.core.cache.backends.memcached.MemcachedCache', LOCATION=name, KEY_FUNCTION='regressiontests.cache.tests.custom_key_func')
 814
 815    def tearDown(self):
 816        self.cache.clear()
 817
 818    def test_invalid_keys(self):
 819        """
 820        On memcached, we don't introduce a duplicate key validation
 821        step (for speed reasons), we just let the memcached API
 822        library raise its own exception on bad keys. Refs #6447.
 823
 824        In order to be memcached-API-library agnostic, we only assert
 825        that a generic exception of some kind is raised.
 826
 827        """
 828        # memcached does not allow whitespace or control characters in keys
 829        self.assertRaises(Exception, self.cache.set, 'key with spaces', 'value')
 830        # memcached limits key length to 250
 831        self.assertRaises(Exception, self.cache.set, 'a' * 251, 'value')
 832
 833MemcachedCacheTests = unittest.skipUnless(settings.CACHES[DEFAULT_CACHE_ALIAS]['BACKEND'].startswith('django.core.cache.backends.memcached.'), "memcached not available")(MemcachedCacheTests)
 834
 835class FileBasedCacheTests(unittest.TestCase, BaseCacheTests):
 836    """
 837    Specific test cases for the file-based cache.
 838    """
 839    def setUp(self):
 840        self.dirname = tempfile.mkdtemp()
 841        self.cache = get_cache('django.core.cache.backends.filebased.FileBasedCache', LOCATION=self.dirname, OPTIONS={'MAX_ENTRIES': 30})
 842        self.prefix_cache = get_cache('django.core.cache.backends.filebased.FileBasedCache', LOCATION=self.dirname, KEY_PREFIX='cacheprefix')
 843        self.v2_cache = get_cache('django.core.cache.backends.filebased.FileBasedCache', LOCATION=self.dirname, VERSION=2)
 844        self.custom_key_cache = get_cache('django.core.cache.backends.filebased.FileBasedCache', LOCATION=self.dirname, KEY_FUNCTION=custom_key_func)
 845        self.custom_key_cache2 = get_cache('django.core.cache.backends.filebased.FileBasedCache', LOCATION=self.dirname, KEY_FUNCTION='regressiontests.cache.tests.custom_key_func')
 846
 847    def tearDown(self):
 848        self.cache.clear()
 849
 850    def test_hashing(self):
 851        """Test that keys are hashed into subdirectories correctly"""
 852        self.cache.set("foo", "bar")
 853        key = self.cache.make_key("foo")
 854        keyhash = md5_constructor(key).hexdigest()
 855        keypath = os.path.join(self.dirname, keyhash[:2], keyhash[2:4], keyhash[4:])
 856        self.assertTrue(os.path.exists(keypath))
 857
 858    def test_subdirectory_removal(self):
 859        """
 860        Make sure that the created subdirectories are correctly removed when empty.
 861        """
 862        self.cache.set("foo", "bar")
 863        key = self.cache.make_key("foo")
 864        keyhash = md5_constructor(key).hexdigest()
 865        keypath = os.path.join(self.dirname, keyhash[:2], keyhash[2:4], keyhash[4:])
 866        self.assertTrue(os.path.exists(keypath))
 867
 868        self.cache.delete("foo")
 869        self.assertTrue(not os.path.exists(keypath))
 870        self.assertTrue(not os.path.exists(os.path.dirname(keypath)))
 871        self.assertTrue(not os.path.exists(os.path.dirname(os.path.dirname(keypath))))
 872
 873    def test_cull(self):
 874        self.perform_cull_test(50, 29)
 875
 876    def test_old_initialization(self):
 877        self.cache = get_cache('file://%s?max_entries=30' % self.dirname)
 878        self.perform_cull_test(50, 29)
 879
 880class CustomCacheKeyValidationTests(unittest.TestCase):
 881    """
 882    Tests for the ability to mixin a custom ``validate_key`` method to
 883    a custom cache backend that otherwise inherits from a builtin
 884    backend, and override the default key validation. Refs #6447.
 885
 886    """
 887    def test_custom_key_validation(self):
 888        cache = get_cache('regressiontests.cache.liberal_backend://')
 889
 890        # this key is both longer than 250 characters, and has spaces
 891        key = 'some key with spaces' * 15
 892        val = 'a value'
 893        cache.set(key, val)
 894        self.assertEqual(cache.get(key), val)
 895
 896class CacheUtils(unittest.TestCase):
 897    """TestCase for django.utils.cache functions."""
 898
 899    def setUp(self):
 900        self.path = '/cache/test/'
 901        self.old_cache_middleware_key_prefix = settings.CACHE_MIDDLEWARE_KEY_PREFIX
 902        self.old_cache_middleware_seconds = settings.CACHE_MIDDLEWARE_SECONDS
 903        self.orig_use_i18n = settings.USE_I18N
 904        settings.CACHE_MIDDLEWARE_KEY_PREFIX = 'settingsprefix'
 905        settings.CACHE_MIDDLEWARE_SECONDS = 1
 906        settings.USE_I18N = False
 907
 908    def tearDown(self):
 909        settings.CACHE_MIDDLEWARE_KEY_PREFIX = self.old_cache_middleware_key_prefix
 910        settings.CACHE_MIDDLEWARE_SECONDS = self.old_cache_middleware_seconds
 911        settings.USE_I18N = self.orig_use_i18n
 912
 913    def _get_request(self, path, method='GET'):
 914        request = HttpRequest()
 915        request.META = {
 916            'SERVER_NAME': 'testserver',
 917            'SERVER_PORT': 80,
 918        }
 919        request.method = method
 920        request.path = request.path_info = "/cache/%s" % path
 921        return request
 922
 923    def test_patch_vary_headers(self):
 924        headers = (
 925            # Initial vary, new headers, resulting vary.
 926            (None, ('Accept-Encoding',), 'Accept-Encoding'),
 927            ('Accept-Encoding', ('accept-encoding',), 'Accept-Encoding'),
 928            ('Accept-Encoding', ('ACCEPT-ENCODING',), 'Accept-Encoding'),
 929            ('Cookie', ('Accept-Encoding',), 'Cookie, Accept-Encoding'),
 930            ('Cookie, Accept-Encoding', ('Accept-Encoding',), 'Cookie, Accept-Encoding'),
 931            ('Cookie, Accept-Encoding', ('Accept-Encoding', 'cookie'), 'Cookie, Accept-Encoding'),
 932            (None, ('Accept-Encoding', 'COOKIE'), 'Accept-Encoding, COOKIE'),
 933            ('Cookie,     Accept-Encoding', ('Accept-Encoding', 'cookie'), 'Cookie, Accept-Encoding'),
 934            ('Cookie    ,     Accept-Encoding', ('Accept-Encoding', 'cookie'), 'Cookie, Accept-Encoding'),
 935        )
 936        for initial_vary, newheaders, resulting_vary in headers:
 937            response = HttpResponse()
 938            if initial_vary is not None:
 939                response['Vary'] = initial_vary
 940            patch_vary_headers(response, newheaders)
 941            self.assertEqual(response['Vary'], resulting_vary)
 942
 943    def test_get_cache_key(self):
 944        request = self._get_request(self.path)
 945        response = HttpResponse()
 946        key_prefix = 'localprefix'
 947        # Expect None if no headers have been set yet.
 948        self.assertEqual(get_cache_key(request), None)
 949        # Set headers to an empty list.
 950        learn_cache_key(request, response)
 951        self.assertEqual(get_cache_key(request), 'views.decorators.cache.cache_page.settingsprefix.GET.a8c87a3d8c44853d7f79474f7ffe4ad5.d41d8cd98f00b204e9800998ecf8427e')
 952        # Verify that a specified key_prefix is taken into account.
 953        learn_cache_key(request, response, key_prefix=key_prefix)
 954        self.assertEqual(get_cache_key(request, key_prefix=key_prefix), 'views.decorators.cache.cache_page.localprefix.GET.a8c87a3d8c44853d7f79474f7ffe4ad5.d41d8cd98f00b204e9800998ecf8427e')
 955
 956    def test_get_cache_key_with_query(self):
 957        request = self._get_request(self.path + '?test=1')
 958        response = HttpResponse()
 959        # Expect None if no headers have been set yet.
 960        self.assertEqual(get_cache_key(request), None)
 961        # Set headers to an empty list.
 962        learn_cache_key(request, response)
 963        # Verify that the querystring is taken into account.
 964        self.assertEqual(get_cache_key(request), 'views.decorators.cache.cache_page.settingsprefix.GET.bd889c5a59603af44333ed21504db3cd.d41d8cd98f00b204e9800998ecf8427e')
 965
 966    def test_learn_cache_key(self):
 967        request = self._get_request(self.path, 'HEAD')
 968        response = HttpResponse()
 969        response['Vary'] = 'Pony'
 970        # Make sure that the Vary header is added to the key hash
 971        learn_cache_key(request, response)
 972        self.assertEqual(get_cache_key(request), 'views.decorators.cache.cache_page.settingsprefix.HEAD.a8c87a3d8c44853d7f79474f7ffe4ad5.d41d8cd98f00b204e9800998ecf8427e')
 973
 974    def test_patch_cache_control(self):
 975        tests = (
 976            # Initial Cache-Control, kwargs to patch_cache_control, expected Cache-Control parts
 977            (None, {'private' : True}, set(['private'])),
 978
 979            # Test whether private/public attributes are mutually exclusive
 980            ('private', {'private' : True}, set(['private'])),
 981            ('private', {'public' : True}, set(['public'])),
 982            ('public', {'public' : True}, set(['public'])),
 983            ('public', {'private' : True}, set(['private'])),
 984            ('must-revalidate,max-age=60,private', {'public' : True}, set(['must-revalidate', 'max-age=60', 'public'])),
 985            ('must-revalidate,max-age=60,public', {'private' : True}, set(['must-revalidate', 'max-age=60', 'private'])),
 986            ('must-revalidate,max-age=60', {'public' : True}, set(['must-revalidate', 'max-age=60', 'public'])),
 987        )
 988
 989        cc_delim_re = re.compile(r'\s*,\s*')
 990
 991        for initial_cc, newheaders, expected_cc in tests:
 992            response = HttpResponse()
 993            if initial_cc is not None:
 994                response['Cache-Control'] = initial_cc
 995            patch_cache_control(response, **newheaders)
 996            parts = set(cc_delim_re.split(response['Cache-Control']))
 997            self.assertEqual(parts, expected_cc)
 998
 999class PrefixedCacheUtils(CacheUtils):
1000    def setUp(self):
1001        super(PrefixedCacheUtils, self).setUp()
1002        self.old_cache_key_prefix = settings.CACHES['default'].get('KEY_PREFIX', None)
1003        settings.CACHES['default']['KEY_PREFIX'] = 'cacheprefix'
1004
1005    def tearDown(self):
1006        super(PrefixedCacheUtils, self).tearDown()
1007        if self.old_cache_key_prefix is None:
1008            del settings.CACHES['default']['KEY_PREFIX']
1009        else:
1010            settings.CACHES['default']['KEY_PREFIX'] = self.old_cache_key_prefix
1011
1012class CacheHEADTest(unittest.TestCase):
1013
1014    def setUp(self):
1015        self.orig_cache_middleware_seconds = settings.CACHE_MIDDLEWARE_SECONDS
1016        self.orig_cache_middleware_key_prefix = settings.CACHE_MIDDLEWARE_KEY_PREFIX
1017        self.orig_caches = settings.CACHES
1018        settings.CACHE_MIDDLEWARE_SECONDS = 60
1019        settings.CACHE_MIDDLEWARE_KEY_PREFIX = 'test'
1020        settings.CACHES = {
1021            'default': {
1022                'BACKEND': 'django.core.cache.backends.locmem.LocMemCache'
1023            }
1024        }
1025        self.path = '/cache/test/'
1026
1027    def tearDown(self):
1028        settings.CACHE_MIDDLEWARE_SECONDS = self.orig_cache_middleware_seconds
1029        settings.CACHE_MIDDLEWARE_KEY_PREFIX = self.orig_cache_middleware_key_prefix
1030        settings.CACHES = self.orig_caches
1031
1032    def _get_request(self, method):
1033        request = HttpRequest()
1034        request.META = {
1035            'SERVER_NAME': 'testserver',
1036            'SERVER_PORT': 80,
1037        }
1038        request.method = method
1039        request.path = request.path_info = self.path
1040        return request
1041
1042    def _get_request_cache(self, method):
1043        request = self._get_request(method)
1044        request._cache_update_cache = True
1045        return request
1046
1047    def _set_cache(self, request, msg):
1048        response = HttpResponse()
1049        response.content = msg
1050        return UpdateCacheMiddleware().process_response(request, response)
1051
1052    def test_head_caches_correctly(self):
1053        test_content = 'test content'
1054
1055        request = self._get_request_cache('HEAD')
1056        self._set_cache(request, test_content)
1057
1058        request = self._get_request('HEAD')
1059        get_cache_data = FetchFromCacheMiddleware().process_request(request)
1060        self.assertNotEqual(get_cache_data, None)
1061        self.assertEqual(test_content, get_cache_data.content)
1062
1063    def test_head_with_cached_get(self):
1064        test_content = 'test content'
1065
1066        request = self._get_request_cache('GET')
1067        self._set_cache(request, test_content)
1068
1069        request = self._get_request('HEAD')
1070        get_cache_data = FetchFromCacheMiddleware().process_request(request)
1071        self.assertNotEqual(get_cache_data, None)
1072        self.assertEqual(test_content, get_cache_data.content)
1073
1074class CacheI18nTest(unittest.TestCase):
1075
1076    def setUp(self):
1077        self.orig_cache_middleware_seconds = settings.CACHE_MIDDLEWARE_SECONDS
1078        self.orig_cache_middleware_key_prefix = settings.CACHE_MIDDLEWARE_KEY_PREFIX
1079        self.orig_caches = settings.CACHES
1080        self.orig_use_i18n = settings.USE_I18N
1081        self.orig_languages =  settings.LANGUAGES
1082        settings.LANGUAGES = (
1083                ('en', 'English'),
1084                ('es', 'Spanish'),
1085        )
1086        settings.CACHE_MIDDLEWARE_KEY_PREFIX = 'settingsprefix'
1087        self.path = '/cache/test/'
1088
1089    def tearDown(self):
1090        settings.CACHE_MIDDLEWARE_SECONDS = self.orig_cache_middleware_seconds
1091        settings.CACHE_MIDDLEWARE_KEY_PREFIX = self.orig_cache_middleware_key_prefix
1092        settings.CACHES = self.orig_caches
1093      

Large files files are truncated, but you can click here to view the full file