Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Removed all uses of create_cache.

Refactored the cache tests significantly.

Made it safe to override the CACHES setting.
  • Loading branch information...
commit 905a74f52b24a198f802520ff06290a94dedc687 1 parent 35e289f
Aymeric Augustin authored November 23, 2013
4  django/core/management/commands/createcachetable.py
... ...
@@ -1,7 +1,7 @@
1 1
 from optparse import make_option
2 2
 
3 3
 from django.conf import settings
4  
-from django.core.cache import create_cache
  4
+from django.core.cache import caches
5 5
 from django.core.cache.backends.db import BaseDatabaseCache
6 6
 from django.core.management.base import BaseCommand, CommandError
7 7
 from django.db import connections, router, transaction, models, DEFAULT_DB_ALIAS
@@ -30,7 +30,7 @@ def handle(self, *tablenames, **options):
30 30
                 self.create_table(db, tablename)
31 31
         else:
32 32
             for cache_alias in settings.CACHES:
33  
-                cache = create_cache(cache_alias)
  33
+                cache = caches[cache_alias]
34 34
                 if isinstance(cache, BaseDatabaseCache):
35 35
                     self.create_table(db, cache._table)
36 36
 
4  django/middleware/cache.py
@@ -46,7 +46,7 @@
46 46
 import warnings
47 47
 
48 48
 from django.conf import settings
49  
-from django.core.cache import create_cache, caches, DEFAULT_CACHE_ALIAS
  49
+from django.core.cache import caches, DEFAULT_CACHE_ALIAS
50 50
 from django.utils.cache import get_cache_key, learn_cache_key, patch_response_headers, get_max_age
51 51
 
52 52
 
@@ -196,4 +196,4 @@ def __init__(self, cache_timeout=None, cache_anonymous_only=None, **kwargs):
196 196
             msg = "CACHE_MIDDLEWARE_ANONYMOUS_ONLY has been deprecated and will be removed in Django 1.8."
197 197
             warnings.warn(msg, DeprecationWarning, stacklevel=1)
198 198
 
199  
-        self.cache = create_cache(self.cache_alias)
  199
+        self.cache = caches[self.cache_alias]
8  django/test/signals.py
... ...
@@ -1,5 +1,6 @@
1 1
 import os
2 2
 import time
  3
+import threading
3 4
 import warnings
4 5
 
5 6
 from django.conf import settings
@@ -20,6 +21,13 @@
20 21
 
21 22
 
22 23
 @receiver(setting_changed)
  24
+def clear_cache_handlers(**kwargs):
  25
+    if kwargs['setting'] == 'CACHES':
  26
+        from django.core.cache import caches
  27
+        caches._caches = threading.local()
  28
+
  29
+
  30
+@receiver(setting_changed)
23 31
 def update_connections_time_zone(**kwargs):
24 32
     if kwargs['setting'] == 'TIME_ZONE':
25 33
         # Reset process time zone
1,046  tests/cache/tests.py
@@ -8,6 +8,7 @@
8 8
 import pickle
9 9
 import random
10 10
 import re
  11
+import shutil
11 12
 import string
12 13
 import tempfile
13 14
 import threading
@@ -17,9 +18,7 @@
17 18
 
18 19
 from django.conf import settings
19 20
 from django.core import management
20  
-from django.core.cache import create_cache, caches
21  
-from django.core.cache.backends.base import (CacheKeyWarning,
22  
-    InvalidCacheBackendError)
  21
+from django.core.cache import cache, caches, CacheKeyWarning, InvalidCacheBackendError
23 22
 from django.db import connection, router, transaction
24 23
 from django.core.cache.utils import make_template_fragment_key
25 24
 from django.http import HttpResponse, StreamingHttpResponse
@@ -28,7 +27,8 @@
28 27
 from django.template import Template
29 28
 from django.template.response import TemplateResponse
30 29
 from django.test import TestCase, TransactionTestCase, RequestFactory
31  
-from django.test.utils import override_settings, IgnoreDeprecationWarningsMixin
  30
+from django.test.utils import (override_settings, IgnoreDeprecationWarningsMixin,
  31
+    IgnorePendingDeprecationWarningsMixin)
32 32
 from django.utils import six
33 33
 from django.utils import timezone
34 34
 from django.utils import translation
@@ -50,72 +50,73 @@ def m(n):
50 50
         return 24
51 51
 
52 52
 
53  
-class DummyCacheTests(unittest.TestCase):
  53
+@override_settings(CACHES={
  54
+    'default': {
  55
+        'BACKEND': 'django.core.cache.backends.dummy.DummyCache',
  56
+    }
  57
+})
  58
+class DummyCacheTests(TestCase):
54 59
     # The Dummy cache backend doesn't really behave like a test backend,
55  
-    # so it has different test requirements.
56  
-    backend_name = 'django.core.cache.backends.dummy.DummyCache'
57  
-
58  
-    def setUp(self):
59  
-        self.cache = create_cache(self.backend_name)
  60
+    # so it has its own test case.
60 61
 
61 62
     def test_simple(self):
62 63
         "Dummy cache backend ignores cache set calls"
63  
-        self.cache.set("key", "value")
64  
-        self.assertEqual(self.cache.get("key"), None)
  64
+        cache.set("key", "value")
  65
+        self.assertEqual(cache.get("key"), None)
65 66
 
66 67
     def test_add(self):
67 68
         "Add doesn't do anything in dummy cache backend"
68  
-        self.cache.add("addkey1", "value")
69  
-        result = self.cache.add("addkey1", "newvalue")
  69
+        cache.add("addkey1", "value")
  70
+        result = cache.add("addkey1", "newvalue")
70 71
         self.assertEqual(result, True)
71  
-        self.assertEqual(self.cache.get("addkey1"), None)
  72
+        self.assertEqual(cache.get("addkey1"), None)
72 73
 
73 74
     def test_non_existent(self):
74 75
         "Non-existent keys aren't found in the dummy cache backend"
75  
-        self.assertEqual(self.cache.get("does_not_exist"), None)
76  
-        self.assertEqual(self.cache.get("does_not_exist", "bang!"), "bang!")
  76
+        self.assertEqual(cache.get("does_not_exist"), None)
  77
+        self.assertEqual(cache.get("does_not_exist", "bang!"), "bang!")
77 78
 
78 79
     def test_get_many(self):
79 80
         "get_many returns nothing for the dummy cache backend"
80  
-        self.cache.set('a', 'a')
81  
-        self.cache.set('b', 'b')
82  
-        self.cache.set('c', 'c')
83  
-        self.cache.set('d', 'd')
84  
-        self.assertEqual(self.cache.get_many(['a', 'c', 'd']), {})
85  
-        self.assertEqual(self.cache.get_many(['a', 'b', 'e']), {})
  81
+        cache.set('a', 'a')
  82
+        cache.set('b', 'b')
  83
+        cache.set('c', 'c')
  84
+        cache.set('d', 'd')
  85
+        self.assertEqual(cache.get_many(['a', 'c', 'd']), {})
  86
+        self.assertEqual(cache.get_many(['a', 'b', 'e']), {})
86 87
 
87 88
     def test_delete(self):
88 89
         "Cache deletion is transparently ignored on the dummy cache backend"
89  
-        self.cache.set("key1", "spam")
90  
-        self.cache.set("key2", "eggs")
91  
-        self.assertEqual(self.cache.get("key1"), None)
92  
-        self.cache.delete("key1")
93  
-        self.assertEqual(self.cache.get("key1"), None)
94  
-        self.assertEqual(self.cache.get("key2"), None)
  90
+        cache.set("key1", "spam")
  91
+        cache.set("key2", "eggs")
  92
+        self.assertEqual(cache.get("key1"), None)
  93
+        cache.delete("key1")
  94
+        self.assertEqual(cache.get("key1"), None)
  95
+        self.assertEqual(cache.get("key2"), None)
95 96
 
96 97
     def test_has_key(self):
97 98
         "The has_key method doesn't ever return True for the dummy cache backend"
98  
-        self.cache.set("hello1", "goodbye1")
99  
-        self.assertEqual(self.cache.has_key("hello1"), False)
100  
-        self.assertEqual(self.cache.has_key("goodbye1"), False)
  99
+        cache.set("hello1", "goodbye1")
  100
+        self.assertEqual(cache.has_key("hello1"), False)
  101
+        self.assertEqual(cache.has_key("goodbye1"), False)
101 102
 
102 103
     def test_in(self):
103 104
         "The in operator doesn't ever return True for the dummy cache backend"
104  
-        self.cache.set("hello2", "goodbye2")
105  
-        self.assertEqual("hello2" in self.cache, False)
106  
-        self.assertEqual("goodbye2" in self.cache, False)
  105
+        cache.set("hello2", "goodbye2")
  106
+        self.assertEqual("hello2" in cache, False)
  107
+        self.assertEqual("goodbye2" in cache, False)
107 108
 
108 109
     def test_incr(self):
109 110
         "Dummy cache values can't be incremented"
110  
-        self.cache.set('answer', 42)
111  
-        self.assertRaises(ValueError, self.cache.incr, 'answer')
112  
-        self.assertRaises(ValueError, self.cache.incr, 'does_not_exist')
  111
+        cache.set('answer', 42)
  112
+        self.assertRaises(ValueError, cache.incr, 'answer')
  113
+        self.assertRaises(ValueError, cache.incr, 'does_not_exist')
113 114
 
114 115
     def test_decr(self):
115 116
         "Dummy cache values can't be decremented"
116  
-        self.cache.set('answer', 42)
117  
-        self.assertRaises(ValueError, self.cache.decr, 'answer')
118  
-        self.assertRaises(ValueError, self.cache.decr, 'does_not_exist')
  117
+        cache.set('answer', 42)
  118
+        self.assertRaises(ValueError, cache.decr, 'answer')
  119
+        self.assertRaises(ValueError, cache.decr, 'does_not_exist')
119 120
 
120 121
     def test_data_types(self):
121 122
         "All data types are ignored equally by the dummy cache"
@@ -128,21 +129,21 @@ def test_data_types(self):
128 129
             'function': f,
129 130
             'class': C,
130 131
         }
131  
-        self.cache.set("stuff", stuff)
132  
-        self.assertEqual(self.cache.get("stuff"), None)
  132
+        cache.set("stuff", stuff)
  133
+        self.assertEqual(cache.get("stuff"), None)
133 134
 
134 135
     def test_expiration(self):
135 136
         "Expiration has no effect on the dummy cache"
136  
-        self.cache.set('expire1', 'very quickly', 1)
137  
-        self.cache.set('expire2', 'very quickly', 1)
138  
-        self.cache.set('expire3', 'very quickly', 1)
  137
+        cache.set('expire1', 'very quickly', 1)
  138
+        cache.set('expire2', 'very quickly', 1)
  139
+        cache.set('expire3', 'very quickly', 1)
139 140
 
140 141
         time.sleep(2)
141  
-        self.assertEqual(self.cache.get("expire1"), None)
  142
+        self.assertEqual(cache.get("expire1"), None)
142 143
 
143  
-        self.cache.add("expire2", "newvalue")
144  
-        self.assertEqual(self.cache.get("expire2"), None)
145  
-        self.assertEqual(self.cache.has_key("expire3"), False)
  144
+        cache.add("expire2", "newvalue")
  145
+        self.assertEqual(cache.get("expire2"), None)
  146
+        self.assertEqual(cache.has_key("expire3"), False)
146 147
 
147 148
     def test_unicode(self):
148 149
         "Unicode values are ignored by the dummy cache"
@@ -153,33 +154,57 @@ def test_unicode(self):
153 154
             'ascii2': {'x': 1}
154 155
         }
155 156
         for (key, value) in stuff.items():
156  
-            self.cache.set(key, value)
157  
-            self.assertEqual(self.cache.get(key), None)
  157
+            cache.set(key, value)
  158
+            self.assertEqual(cache.get(key), None)
158 159
 
159 160
     def test_set_many(self):
160 161
         "set_many does nothing for the dummy cache backend"
161  
-        self.cache.set_many({'a': 1, 'b': 2})
162  
-        self.cache.set_many({'a': 1, 'b': 2}, timeout=2, version='1')
  162
+        cache.set_many({'a': 1, 'b': 2})
  163
+        cache.set_many({'a': 1, 'b': 2}, timeout=2, version='1')
163 164
 
164 165
     def test_delete_many(self):
165 166
         "delete_many does nothing for the dummy cache backend"
166  
-        self.cache.delete_many(['a', 'b'])
  167
+        cache.delete_many(['a', 'b'])
167 168
 
168 169
     def test_clear(self):
169 170
         "clear does nothing for the dummy cache backend"
170  
-        self.cache.clear()
  171
+        cache.clear()
171 172
 
172 173
     def test_incr_version(self):
173 174
         "Dummy cache versions can't be incremented"
174  
-        self.cache.set('answer', 42)
175  
-        self.assertRaises(ValueError, self.cache.incr_version, 'answer')
176  
-        self.assertRaises(ValueError, self.cache.incr_version, 'does_not_exist')
  175
+        cache.set('answer', 42)
  176
+        self.assertRaises(ValueError, cache.incr_version, 'answer')
  177
+        self.assertRaises(ValueError, cache.incr_version, 'does_not_exist')
177 178
 
178 179
     def test_decr_version(self):
179 180
         "Dummy cache versions can't be decremented"
180  
-        self.cache.set('answer', 42)
181  
-        self.assertRaises(ValueError, self.cache.decr_version, 'answer')
182  
-        self.assertRaises(ValueError, self.cache.decr_version, 'does_not_exist')
  181
+        cache.set('answer', 42)
  182
+        self.assertRaises(ValueError, cache.decr_version, 'answer')
  183
+        self.assertRaises(ValueError, cache.decr_version, 'does_not_exist')
  184
+
  185
+
  186
+def custom_key_func(key, key_prefix, version):
  187
+    "A customized cache key function"
  188
+    return 'CUSTOM-' + '-'.join([key_prefix, str(version), key])
  189
+
  190
+
  191
+_caches_setting_base = {
  192
+    'default': {},
  193
+    'prefix': {'KEY_PREFIX': 'cacheprefix'},
  194
+    'v2': {'VERSION': 2},
  195
+    'custom_key': {'KEY_FUNCTION': custom_key_func},
  196
+    'custom_key2': {'KEY_FUNCTION': 'cache.tests.custom_key_func'},
  197
+    'cull': {'OPTIONS': {'MAX_ENTRIES': 30}},
  198
+    'zero_cull': {'OPTIONS': {'CULL_FREQUENCY': 0, 'MAX_ENTRIES': 30}},
  199
+    'other': {'LOCATION': 'other'},
  200
+}
  201
+
  202
+
  203
+def caches_setting_for_tests(**params):
  204
+    setting = dict((k, v.copy()) for k, v in _caches_setting_base.items())
  205
+    for cache_params in setting.values():
  206
+        cache_params.update(params)
  207
+    return setting
183 208
 
184 209
 
185 210
 class BaseCacheTests(object):
@@ -188,89 +213,92 @@ class BaseCacheTests(object):
188 213
     def setUp(self):
189 214
         self.factory = RequestFactory()
190 215
 
  216
+    def tearDown(self):
  217
+        cache.clear()
  218
+
191 219
     def test_simple(self):
192 220
         # Simple cache set/get works
193  
-        self.cache.set("key", "value")
194  
-        self.assertEqual(self.cache.get("key"), "value")
  221
+        cache.set("key", "value")
  222
+        self.assertEqual(cache.get("key"), "value")
195 223
 
196 224
     def test_add(self):
197 225
         # A key can be added to a cache
198  
-        self.cache.add("addkey1", "value")
199  
-        result = self.cache.add("addkey1", "newvalue")
  226
+        cache.add("addkey1", "value")
  227
+        result = cache.add("addkey1", "newvalue")
200 228
         self.assertEqual(result, False)
201  
-        self.assertEqual(self.cache.get("addkey1"), "value")
  229
+        self.assertEqual(cache.get("addkey1"), "value")
202 230
 
203 231
     def test_prefix(self):
204 232
         # Test for same cache key conflicts between shared backend
205  
-        self.cache.set('somekey', 'value')
  233
+        cache.set('somekey', 'value')
206 234
 
207 235
         # should not be set in the prefixed cache
208  
-        self.assertFalse(self.prefix_cache.has_key('somekey'))
  236
+        self.assertFalse(caches['prefix'].has_key('somekey'))
209 237
 
210  
-        self.prefix_cache.set('somekey', 'value2')
  238
+        caches['prefix'].set('somekey', 'value2')
211 239
 
212  
-        self.assertEqual(self.cache.get('somekey'), 'value')
213  
-        self.assertEqual(self.prefix_cache.get('somekey'), 'value2')
  240
+        self.assertEqual(cache.get('somekey'), 'value')
  241
+        self.assertEqual(caches['prefix'].get('somekey'), 'value2')
214 242
 
215 243
     def test_non_existent(self):
216 244
         # Non-existent cache keys return as None/default
217 245
         # get with non-existent keys
218  
-        self.assertEqual(self.cache.get("does_not_exist"), None)
219  
-        self.assertEqual(self.cache.get("does_not_exist", "bang!"), "bang!")
  246
+        self.assertEqual(cache.get("does_not_exist"), None)
  247
+        self.assertEqual(cache.get("does_not_exist", "bang!"), "bang!")
220 248
 
221 249
     def test_get_many(self):
222 250
         # Multiple cache keys can be returned using get_many
223  
-        self.cache.set('a', 'a')
224  
-        self.cache.set('b', 'b')
225  
-        self.cache.set('c', 'c')
226  
-        self.cache.set('d', 'd')
227  
-        self.assertEqual(self.cache.get_many(['a', 'c', 'd']), {'a': 'a', 'c': 'c', 'd': 'd'})
228  
-        self.assertEqual(self.cache.get_many(['a', 'b', 'e']), {'a': 'a', 'b': 'b'})
  251
+        cache.set('a', 'a')
  252
+        cache.set('b', 'b')
  253
+        cache.set('c', 'c')
  254
+        cache.set('d', 'd')
  255
+        self.assertEqual(cache.get_many(['a', 'c', 'd']), {'a': 'a', 'c': 'c', 'd': 'd'})
  256
+        self.assertEqual(cache.get_many(['a', 'b', 'e']), {'a': 'a', 'b': 'b'})
229 257
 
230 258
     def test_delete(self):
231 259
         # Cache keys can be deleted
232  
-        self.cache.set("key1", "spam")
233  
-        self.cache.set("key2", "eggs")
234  
-        self.assertEqual(self.cache.get("key1"), "spam")
235  
-        self.cache.delete("key1")
236  
-        self.assertEqual(self.cache.get("key1"), None)
237  
-        self.assertEqual(self.cache.get("key2"), "eggs")
  260
+        cache.set("key1", "spam")
  261
+        cache.set("key2", "eggs")
  262
+        self.assertEqual(cache.get("key1"), "spam")
  263
+        cache.delete("key1")
  264
+        self.assertEqual(cache.get("key1"), None)
  265
+        self.assertEqual(cache.get("key2"), "eggs")
238 266
 
239 267
     def test_has_key(self):
240 268
         # The cache can be inspected for cache keys
241  
-        self.cache.set("hello1", "goodbye1")
242  
-        self.assertEqual(self.cache.has_key("hello1"), True)
243  
-        self.assertEqual(self.cache.has_key("goodbye1"), False)
  269
+        cache.set("hello1", "goodbye1")
  270
+        self.assertEqual(cache.has_key("hello1"), True)
  271
+        self.assertEqual(cache.has_key("goodbye1"), False)
244 272
 
245 273
     def test_in(self):
246 274
         # The in operator can be used to inspect cache contents
247  
-        self.cache.set("hello2", "goodbye2")
248  
-        self.assertEqual("hello2" in self.cache, True)
249  
-        self.assertEqual("goodbye2" in self.cache, False)
  275
+        cache.set("hello2", "goodbye2")
  276
+        self.assertEqual("hello2" in cache, True)
  277
+        self.assertEqual("goodbye2" in cache, False)
250 278
 
251 279
     def test_incr(self):
252 280
         # Cache values can be incremented
253  
-        self.cache.set('answer', 41)
254  
-        self.assertEqual(self.cache.incr('answer'), 42)
255  
-        self.assertEqual(self.cache.get('answer'), 42)
256  
-        self.assertEqual(self.cache.incr('answer', 10), 52)
257  
-        self.assertEqual(self.cache.get('answer'), 52)
258  
-        self.assertEqual(self.cache.incr('answer', -10), 42)
259  
-        self.assertRaises(ValueError, self.cache.incr, 'does_not_exist')
  281
+        cache.set('answer', 41)
  282
+        self.assertEqual(cache.incr('answer'), 42)
  283
+        self.assertEqual(cache.get('answer'), 42)
  284
+        self.assertEqual(cache.incr('answer', 10), 52)
  285
+        self.assertEqual(cache.get('answer'), 52)
  286
+        self.assertEqual(cache.incr('answer', -10), 42)
  287
+        self.assertRaises(ValueError, cache.incr, 'does_not_exist')
260 288
 
261 289
     def test_decr(self):
262 290
         # Cache values can be decremented
263  
-        self.cache.set('answer', 43)
264  
-        self.assertEqual(self.cache.decr('answer'), 42)
265  
-        self.assertEqual(self.cache.get('answer'), 42)
266  
-        self.assertEqual(self.cache.decr('answer', 10), 32)
267  
-        self.assertEqual(self.cache.get('answer'), 32)
268  
-        self.assertEqual(self.cache.decr('answer', -10), 42)
269  
-        self.assertRaises(ValueError, self.cache.decr, 'does_not_exist')
  291
+        cache.set('answer', 43)
  292
+        self.assertEqual(cache.decr('answer'), 42)
  293
+        self.assertEqual(cache.get('answer'), 42)
  294
+        self.assertEqual(cache.decr('answer', 10), 32)
  295
+        self.assertEqual(cache.get('answer'), 32)
  296
+        self.assertEqual(cache.decr('answer', -10), 42)
  297
+        self.assertRaises(ValueError, cache.decr, 'does_not_exist')
270 298
 
271 299
     def test_close(self):
272  
-        self.assertTrue(hasattr(self.cache, 'close'))
273  
-        self.cache.close()
  300
+        self.assertTrue(hasattr(cache, 'close'))
  301
+        cache.close()
274 302
 
275 303
     def test_data_types(self):
276 304
         # Many different data types can be cached
@@ -283,8 +311,8 @@ def test_data_types(self):
283 311
             'function': f,
284 312
             'class': C,
285 313
         }
286  
-        self.cache.set("stuff", stuff)
287  
-        self.assertEqual(self.cache.get("stuff"), stuff)
  314
+        cache.set("stuff", stuff)
  315
+        self.assertEqual(cache.get("stuff"), stuff)
288 316
 
289 317
     def test_cache_read_for_model_instance(self):
290 318
         # Don't want fields with callable as default to be called on cache read
@@ -293,8 +321,8 @@ def test_cache_read_for_model_instance(self):
293 321
         my_poll = Poll.objects.create(question="Well?")
294 322
         self.assertEqual(Poll.objects.count(), 1)
295 323
         pub_date = my_poll.pub_date
296  
-        self.cache.set('question', my_poll)
297  
-        cached_poll = self.cache.get('question')
  324
+        cache.set('question', my_poll)
  325
+        cached_poll = cache.get('question')
298 326
         self.assertEqual(cached_poll.pub_date, pub_date)
299 327
         # We only want the default expensive calculation run once
300 328
         self.assertEqual(expensive_calculation.num_runs, 1)
@@ -308,7 +336,7 @@ def test_cache_write_for_model_instance_with_deferred(self):
308 336
         defer_qs = Poll.objects.all().defer('question')
309 337
         self.assertEqual(defer_qs.count(), 1)
310 338
         self.assertEqual(expensive_calculation.num_runs, 1)
311  
-        self.cache.set('deferred_queryset', defer_qs)
  339
+        cache.set('deferred_queryset', defer_qs)
312 340
         # cache set should not re-evaluate default functions
313 341
         self.assertEqual(expensive_calculation.num_runs, 1)
314 342
 
@@ -320,25 +348,25 @@ def test_cache_read_for_model_instance_with_deferred(self):
320 348
         self.assertEqual(expensive_calculation.num_runs, 1)
321 349
         defer_qs = Poll.objects.all().defer('question')
322 350
         self.assertEqual(defer_qs.count(), 1)
323  
-        self.cache.set('deferred_queryset', defer_qs)
  351
+        cache.set('deferred_queryset', defer_qs)
324 352
         self.assertEqual(expensive_calculation.num_runs, 1)
325 353
         runs_before_cache_read = expensive_calculation.num_runs
326  
-        self.cache.get('deferred_queryset')
  354
+        cache.get('deferred_queryset')
327 355
         # We only want the default expensive calculation run on creation and set
328 356
         self.assertEqual(expensive_calculation.num_runs, runs_before_cache_read)
329 357
 
330 358
     def test_expiration(self):
331 359
         # Cache values can be set to expire
332  
-        self.cache.set('expire1', 'very quickly', 1)
333  
-        self.cache.set('expire2', 'very quickly', 1)
334  
-        self.cache.set('expire3', 'very quickly', 1)
  360
+        cache.set('expire1', 'very quickly', 1)
  361
+        cache.set('expire2', 'very quickly', 1)
  362
+        cache.set('expire3', 'very quickly', 1)
335 363
 
336 364
         time.sleep(2)
337  
-        self.assertEqual(self.cache.get("expire1"), None)
  365
+        self.assertEqual(cache.get("expire1"), None)
338 366
 
339  
-        self.cache.add("expire2", "newvalue")
340  
-        self.assertEqual(self.cache.get("expire2"), "newvalue")
341  
-        self.assertEqual(self.cache.has_key("expire3"), False)
  367
+        cache.add("expire2", "newvalue")
  368
+        self.assertEqual(cache.get("expire2"), "newvalue")
  369
+        self.assertEqual(cache.has_key("expire3"), False)
342 370
 
343 371
     def test_unicode(self):
344 372
         # Unicode values can be cached
@@ -350,21 +378,21 @@ def test_unicode(self):
350 378
         }
351 379
         # Test `set`
352 380
         for (key, value) in stuff.items():
353  
-            self.cache.set(key, value)
354  
-            self.assertEqual(self.cache.get(key), value)
  381
+            cache.set(key, value)
  382
+            self.assertEqual(cache.get(key), value)
355 383
 
356 384
         # Test `add`
357 385
         for (key, value) in stuff.items():
358  
-            self.cache.delete(key)
359  
-            self.cache.add(key, value)
360  
-            self.assertEqual(self.cache.get(key), value)
  386
+            cache.delete(key)
  387
+            cache.add(key, value)
  388
+            self.assertEqual(cache.get(key), value)
361 389
 
362 390
         # Test `set_many`
363 391
         for (key, value) in stuff.items():
364  
-            self.cache.delete(key)
365  
-        self.cache.set_many(stuff)
  392
+            cache.delete(key)
  393
+        cache.set_many(stuff)
366 394
         for (key, value) in stuff.items():
367  
-            self.assertEqual(self.cache.get(key), value)
  395
+            self.assertEqual(cache.get(key), value)
368 396
 
369 397
     def test_binary_string(self):
370 398
         # Binary strings should be cacheable
@@ -373,53 +401,53 @@ def test_binary_string(self):
373 401
         compressed_value = compress(value.encode())
374 402
 
375 403
         # Test set
376  
-        self.cache.set('binary1', compressed_value)
377  
-        compressed_result = self.cache.get('binary1')
  404
+        cache.set('binary1', compressed_value)
  405
+        compressed_result = cache.get('binary1')
378 406
         self.assertEqual(compressed_value, compressed_result)
379 407
         self.assertEqual(value, decompress(compressed_result).decode())
380 408
 
381 409
         # Test add
382  
-        self.cache.add('binary1-add', compressed_value)
383  
-        compressed_result = self.cache.get('binary1-add')
  410
+        cache.add('binary1-add', compressed_value)
  411
+        compressed_result = cache.get('binary1-add')
384 412
         self.assertEqual(compressed_value, compressed_result)
385 413
         self.assertEqual(value, decompress(compressed_result).decode())
386 414
 
387 415
         # Test set_many
388  
-        self.cache.set_many({'binary1-set_many': compressed_value})
389  
-        compressed_result = self.cache.get('binary1-set_many')
  416
+        cache.set_many({'binary1-set_many': compressed_value})
  417
+        compressed_result = cache.get('binary1-set_many')
390 418
         self.assertEqual(compressed_value, compressed_result)
391 419
         self.assertEqual(value, decompress(compressed_result).decode())
392 420
 
393 421
     def test_set_many(self):
394 422
         # Multiple keys can be set using set_many
395  
-        self.cache.set_many({"key1": "spam", "key2": "eggs"})
396  
-        self.assertEqual(self.cache.get("key1"), "spam")
397  
-        self.assertEqual(self.cache.get("key2"), "eggs")
  423
+        cache.set_many({"key1": "spam", "key2": "eggs"})
  424
+        self.assertEqual(cache.get("key1"), "spam")
  425
+        self.assertEqual(cache.get("key2"), "eggs")
398 426
 
399 427
     def test_set_many_expiration(self):
400 428
         # set_many takes a second ``timeout`` parameter
401  
-        self.cache.set_many({"key1": "spam", "key2": "eggs"}, 1)
  429
+        cache.set_many({"key1": "spam", "key2": "eggs"}, 1)
402 430
         time.sleep(2)
403  
-        self.assertEqual(self.cache.get("key1"), None)
404  
-        self.assertEqual(self.cache.get("key2"), None)
  431
+        self.assertEqual(cache.get("key1"), None)
  432
+        self.assertEqual(cache.get("key2"), None)
405 433
 
406 434
     def test_delete_many(self):
407 435
         # Multiple keys can be deleted using delete_many
408  
-        self.cache.set("key1", "spam")
409  
-        self.cache.set("key2", "eggs")
410  
-        self.cache.set("key3", "ham")
411  
-        self.cache.delete_many(["key1", "key2"])
412  
-        self.assertEqual(self.cache.get("key1"), None)
413  
-        self.assertEqual(self.cache.get("key2"), None)
414  
-        self.assertEqual(self.cache.get("key3"), "ham")
  436
+        cache.set("key1", "spam")
  437
+        cache.set("key2", "eggs")
  438
+        cache.set("key3", "ham")
  439
+        cache.delete_many(["key1", "key2"])
  440
+        self.assertEqual(cache.get("key1"), None)
  441
+        self.assertEqual(cache.get("key2"), None)
  442
+        self.assertEqual(cache.get("key3"), "ham")
415 443
 
416 444
     def test_clear(self):
417 445
         # The cache can be emptied using clear
418  
-        self.cache.set("key1", "spam")
419  
-        self.cache.set("key2", "eggs")
420  
-        self.cache.clear()
421  
-        self.assertEqual(self.cache.get("key1"), None)
422  
-        self.assertEqual(self.cache.get("key2"), None)
  446
+        cache.set("key1", "spam")
  447
+        cache.set("key2", "eggs")
  448
+        cache.clear()
  449
+        self.assertEqual(cache.get("key1"), None)
  450
+        self.assertEqual(cache.get("key2"), None)
423 451
 
424 452
     def test_long_timeout(self):
425 453
         '''
@@ -427,63 +455,67 @@ def test_long_timeout(self):
427 455
         it is an absolute expiration timestamp instead of a relative
428 456
         offset. Test that we honour this convention. Refs #12399.
429 457
         '''
430  
-        self.cache.set('key1', 'eggs', 60 * 60 * 24 * 30 + 1)  # 30 days + 1 second
431  
-        self.assertEqual(self.cache.get('key1'), 'eggs')
  458
+        cache.set('key1', 'eggs', 60 * 60 * 24 * 30 + 1)  # 30 days + 1 second
  459
+        self.assertEqual(cache.get('key1'), 'eggs')
432 460
 
433  
-        self.cache.add('key2', 'ham', 60 * 60 * 24 * 30 + 1)
434  
-        self.assertEqual(self.cache.get('key2'), 'ham')
  461
+        cache.add('key2', 'ham', 60 * 60 * 24 * 30 + 1)
  462
+        self.assertEqual(cache.get('key2'), 'ham')
435 463
 
436  
-        self.cache.set_many({'key3': 'sausage', 'key4': 'lobster bisque'}, 60 * 60 * 24 * 30 + 1)
437  
-        self.assertEqual(self.cache.get('key3'), 'sausage')
438  
-        self.assertEqual(self.cache.get('key4'), 'lobster bisque')
  464
+        cache.set_many({'key3': 'sausage', 'key4': 'lobster bisque'}, 60 * 60 * 24 * 30 + 1)
  465
+        self.assertEqual(cache.get('key3'), 'sausage')
  466
+        self.assertEqual(cache.get('key4'), 'lobster bisque')
439 467
 
440 468
     def test_forever_timeout(self):
441 469
         '''
442 470
         Passing in None into timeout results in a value that is cached forever
443 471
         '''
444  
-        self.cache.set('key1', 'eggs', None)
445  
-        self.assertEqual(self.cache.get('key1'), 'eggs')
  472
+        cache.set('key1', 'eggs', None)
  473
+        self.assertEqual(cache.get('key1'), 'eggs')
446 474
 
447  
-        self.cache.add('key2', 'ham', None)
448  
-        self.assertEqual(self.cache.get('key2'), 'ham')
  475
+        cache.add('key2', 'ham', None)
  476
+        self.assertEqual(cache.get('key2'), 'ham')
449 477
 
450  
-        self.cache.set_many({'key3': 'sausage', 'key4': 'lobster bisque'}, None)
451  
-        self.assertEqual(self.cache.get('key3'), 'sausage')
452  
-        self.assertEqual(self.cache.get('key4'), 'lobster bisque')
  478
+        cache.set_many({'key3': 'sausage', 'key4': 'lobster bisque'}, None)
  479
+        self.assertEqual(cache.get('key3'), 'sausage')
  480
+        self.assertEqual(cache.get('key4'), 'lobster bisque')
453 481
 
454 482
     def test_zero_timeout(self):
455 483
         '''
456 484
         Passing in None into timeout results in a value that is cached forever
457 485
         '''
458  
-        self.cache.set('key1', 'eggs', 0)
459  
-        self.assertEqual(self.cache.get('key1'), None)
  486
+        cache.set('key1', 'eggs', 0)
  487
+        self.assertEqual(cache.get('key1'), None)
460 488
 
461  
-        self.cache.add('key2', 'ham', 0)
462  
-        self.assertEqual(self.cache.get('key2'), None)
  489
+        cache.add('key2', 'ham', 0)
  490
+        self.assertEqual(cache.get('key2'), None)
463 491
 
464  
-        self.cache.set_many({'key3': 'sausage', 'key4': 'lobster bisque'}, 0)
465  
-        self.assertEqual(self.cache.get('key3'), None)
466  
-        self.assertEqual(self.cache.get('key4'), None)
  492
+        cache.set_many({'key3': 'sausage', 'key4': 'lobster bisque'}, 0)
  493
+        self.assertEqual(cache.get('key3'), None)
  494
+        self.assertEqual(cache.get('key4'), None)
467 495
 
468 496
     def test_float_timeout(self):
469 497
         # Make sure a timeout given as a float doesn't crash anything.
470  
-        self.cache.set("key1", "spam", 100.2)
471  
-        self.assertEqual(self.cache.get("key1"), "spam")
472  
-
473  
-    def perform_cull_test(self, initial_count, final_count):
474  
-        """This is implemented as a utility method, because only some of the backends
475  
-        implement culling. The culling algorithm also varies slightly, so the final
476  
-        number of entries will vary between backends"""
477  
-        # Create initial cache key entries. This will overflow the cache, causing a cull
  498
+        cache.set("key1", "spam", 100.2)
  499
+        self.assertEqual(cache.get("key1"), "spam")
  500
+
  501
+    def _perform_cull_test(self, cull_cache, initial_count, final_count):
  502
+        # Create initial cache key entries. This will overflow the cache,
  503
+        # causing a cull.
478 504
         for i in range(1, initial_count):
479  
-            self.cache.set('cull%d' % i, 'value', 1000)
  505
+            cull_cache.set('cull%d' % i, 'value', 1000)
480 506
         count = 0
481 507
         # Count how many keys are left in the cache.
482 508
         for i in range(1, initial_count):
483  
-            if self.cache.has_key('cull%d' % i):
  509
+            if cull_cache.has_key('cull%d' % i):
484 510
                 count = count + 1
485 511
         self.assertEqual(count, final_count)
486 512
 
  513
+    def test_cull(self):
  514
+        self._perform_cull_test(caches['cull'], 50, 29)
  515
+
  516
+    def test_zero_cull(self):
  517
+        self._perform_cull_test(caches['zero_cull'], 50, 19)
  518
+
487 519
     def test_invalid_keys(self):
488 520
         """
489 521
         All the builtin backends (except memcached, see below) should warn on
@@ -497,302 +529,302 @@ def test_invalid_keys(self):
497 529
         def func(key, *args):
498 530
             return key
499 531
 
500  
-        old_func = self.cache.key_func
501  
-        self.cache.key_func = func
  532
+        old_func = cache.key_func
  533
+        cache.key_func = func
502 534
 
503 535
         try:
504 536
             with warnings.catch_warnings(record=True) as w:
505 537
                 warnings.simplefilter("always")
506 538
                 # memcached does not allow whitespace or control characters in keys
507  
-                self.cache.set('key with spaces', 'value')
  539
+                cache.set('key with spaces', 'value')
508 540
                 self.assertEqual(len(w), 2)
509 541
                 self.assertIsInstance(w[0].message, CacheKeyWarning)
510 542
             with warnings.catch_warnings(record=True) as w:
511 543
                 warnings.simplefilter("always")
512 544
                 # memcached limits key length to 250
513  
-                self.cache.set('a' * 251, 'value')
  545
+                cache.set('a' * 251, 'value')
514 546
                 self.assertEqual(len(w), 1)
515 547
                 self.assertIsInstance(w[0].message, CacheKeyWarning)
516 548
         finally:
517  
-            self.cache.key_func = old_func
  549
+            cache.key_func = old_func
518 550
 
519 551
     def test_cache_versioning_get_set(self):
520 552
         # set, using default version = 1
521  
-        self.cache.set('answer1', 42)
522  
-        self.assertEqual(self.cache.get('answer1'), 42)
523  
-        self.assertEqual(self.cache.get('answer1', version=1), 42)
524  
-        self.assertEqual(self.cache.get('answer1', version=2), None)
  553
+        cache.set('answer1', 42)
  554
+        self.assertEqual(cache.get('answer1'), 42)
  555
+        self.assertEqual(cache.get('answer1', version=1), 42)
  556
+        self.assertEqual(cache.get('answer1', version=2), None)
525 557
 
526  
-        self.assertEqual(self.v2_cache.get('answer1'), None)
527  
-        self.assertEqual(self.v2_cache.get('answer1', version=1), 42)
528  
-        self.assertEqual(self.v2_cache.get('answer1', version=2), None)
  558
+        self.assertEqual(caches['v2'].get('answer1'), None)
  559
+        self.assertEqual(caches['v2'].get('answer1', version=1), 42)
  560
+        self.assertEqual(caches['v2'].get('answer1', version=2), None)
529 561
 
530 562
         # set, default version = 1, but manually override version = 2
531  
-        self.cache.set('answer2', 42, version=2)
532  
-        self.assertEqual(self.cache.get('answer2'), None)
533  
-        self.assertEqual(self.cache.get('answer2', version=1), None)
534  
-        self.assertEqual(self.cache.get('answer2', version=2), 42)
  563
+        cache.set('answer2', 42, version=2)
  564
+        self.assertEqual(cache.get('answer2'), None)
  565
+        self.assertEqual(cache.get('answer2', version=1), None)
  566
+        self.assertEqual(cache.get('answer2', version=2), 42)
535 567
 
536  
-        self.assertEqual(self.v2_cache.get('answer2'), 42)
537  
-        self.assertEqual(self.v2_cache.get('answer2', version=1), None)
538  
-        self.assertEqual(self.v2_cache.get('answer2', version=2), 42)
  568
+        self.assertEqual(caches['v2'].get('answer2'), 42)
  569
+        self.assertEqual(caches['v2'].get('answer2', version=1), None)
  570
+        self.assertEqual(caches['v2'].get('answer2', version=2), 42)
539 571
 
540 572
         # v2 set, using default version = 2
541  
-        self.v2_cache.set('answer3', 42)
542  
-        self.assertEqual(self.cache.get('answer3'), None)
543  
-        self.assertEqual(self.cache.get('answer3', version=1), None)
544  
-        self.assertEqual(self.cache.get('answer3', version=2), 42)
  573
+        caches['v2'].set('answer3', 42)
  574
+        self.assertEqual(cache.get('answer3'), None)
  575
+        self.assertEqual(cache.get('answer3', version=1), None)
  576
+        self.assertEqual(cache.get('answer3', version=2), 42)
545 577
 
546  
-        self.assertEqual(self.v2_cache.get('answer3'), 42)
547  
-        self.assertEqual(self.v2_cache.get('answer3', version=1), None)
548  
-        self.assertEqual(self.v2_cache.get('answer3', version=2), 42)
  578
+        self.assertEqual(caches['v2'].get('answer3'), 42)
  579
+        self.assertEqual(caches['v2'].get('answer3', version=1), None)
  580
+        self.assertEqual(caches['v2'].get('answer3', version=2), 42)
549 581
 
550 582
         # v2 set, default version = 2, but manually override version = 1
551  
-        self.v2_cache.set('answer4', 42, version=1)
552  
-        self.assertEqual(self.cache.get('answer4'), 42)
553  
-        self.assertEqual(self.cache.get('answer4', version=1), 42)
554  
-        self.assertEqual(self.cache.get('answer4', version=2), None)
  583
+        caches['v2'].set('answer4', 42, version=1)
  584
+        self.assertEqual(cache.get('answer4'), 42)
  585
+        self.assertEqual(cache.get('answer4', version=1), 42)
  586
+        self.assertEqual(cache.get('answer4', version=2), None)
555 587
 
556  
-        self.assertEqual(self.v2_cache.get('answer4'), None)
557  
-        self.assertEqual(self.v2_cache.get('answer4', version=1), 42)
558  
-        self.assertEqual(self.v2_cache.get('answer4', version=2), None)
  588
+        self.assertEqual(caches['v2'].get('answer4'), None)
  589
+        self.assertEqual(caches['v2'].get('answer4', version=1), 42)
  590
+        self.assertEqual(caches['v2'].get('answer4', version=2), None)
559 591
 
560 592
     def test_cache_versioning_add(self):
561 593
 
562 594
         # add, default version = 1, but manually override version = 2
563  
-        self.cache.add('answer1', 42, version=2)
564  
-        self.assertEqual(self.cache.get('answer1', version=1), None)
565  
-        self.assertEqual(self.cache.get('answer1', version=2), 42)
  595
+        cache.add('answer1', 42, version=2)
  596
+        self.assertEqual(cache.get('answer1', version=1), None)
  597
+        self.assertEqual(cache.get('answer1', version=2), 42)
566 598
 
567  
-        self.cache.add('answer1', 37, version=2)
568  
-        self.assertEqual(self.cache.get('answer1', version=1), None)
569  
-        self.assertEqual(self.cache.get('answer1', version=2), 42)
  599
+        cache.add('answer1', 37, version=2)
  600
+        self.assertEqual(cache.get('answer1', version=1), None)
  601
+        self.assertEqual(cache.get('answer1', version=2), 42)
570 602
 
571  
-        self.cache.add('answer1', 37, version=1)
572  
-        self.assertEqual(self.cache.get('answer1', version=1), 37)
573  
-        self.assertEqual(self.cache.get('answer1', version=2), 42)
  603
+        cache.add('answer1', 37, version=1)
  604
+        self.assertEqual(cache.get('answer1', version=1), 37)
  605
+        self.assertEqual(cache.get('answer1', version=2), 42)
574 606
 
575 607
         # v2 add, using default version = 2
576  
-        self.v2_cache.add('answer2', 42)
577  
-        self.assertEqual(self.cache.get('answer2', version=1), None)
578  
-        self.assertEqual(self.cache.get('answer2', version=2), 42)
  608
+        caches['v2'].add('answer2', 42)
  609
+        self.assertEqual(cache.get('answer2', version=1), None)
  610
+        self.assertEqual(cache.get('answer2', version=2), 42)
579 611
 
580  
-        self.v2_cache.add('answer2', 37)
581  
-        self.assertEqual(self.cache.get('answer2', version=1), None)
582  
-        self.assertEqual(self.cache.get('answer2', version=2), 42)
  612
+        caches['v2'].add('answer2', 37)
  613
+        self.assertEqual(cache.get('answer2', version=1), None)
  614
+        self.assertEqual(cache.get('answer2', version=2), 42)
583 615
 
584  
-        self.v2_cache.add('answer2', 37, version=1)
585  
-        self.assertEqual(self.cache.get('answer2', version=1), 37)
586  
-        self.assertEqual(self.cache.get('answer2', version=2), 42)
  616
+        caches['v2'].add('answer2', 37, version=1)
  617
+        self.assertEqual(cache.get('answer2', version=1), 37)
  618
+        self.assertEqual(cache.get('answer2', version=2), 42)
587 619
 
588 620
         # v2 add, default version = 2, but manually override version = 1
589  
-        self.v2_cache.add('answer3', 42, version=1)
590  
-        self.assertEqual(self.cache.get('answer3', version=1), 42)
591  
-        self.assertEqual(self.cache.get('answer3', version=2), None)
  621
+        caches['v2'].add('answer3', 42, version=1)
  622
+        self.assertEqual(cache.get('answer3', version=1), 42)
  623
+        self.assertEqual(cache.get('answer3', version=2), None)
592 624
 
593  
-        self.v2_cache.add('answer3', 37, version=1)
594  
-        self.assertEqual(self.cache.get('answer3', version=1), 42)
595  
-        self.assertEqual(self.cache.get('answer3', version=2), None)
  625
+        caches['v2'].add('answer3', 37, version=1)
  626
+        self.assertEqual(cache.get('answer3', version=1), 42)
  627
+        self.assertEqual(cache.get('answer3', version=2), None)
596 628
 
597  
-        self.v2_cache.add('answer3', 37)
598  
-        self.assertEqual(self.cache.get('answer3', version=1), 42)
599  
-        self.assertEqual(self.cache.get('answer3', version=2), 37)
  629
+        caches['v2'].add('answer3', 37)
  630
+        self.assertEqual(cache.get('answer3', version=1), 42)
  631
+        self.assertEqual(cache.get('answer3', version=2), 37)
600 632
 
601 633
     def test_cache_versioning_has_key(self):
602  
-        self.cache.set('answer1', 42)
  634
+        cache.set('answer1', 42)
603 635
 
604 636
         # has_key
605  
-        self.assertTrue(self.cache.has_key('answer1'))
606  
-        self.assertTrue(self.cache.has_key('answer1', version=1))
607  
-        self.assertFalse(self.cache.has_key('answer1', version=2))
  637
+        self.assertTrue(cache.has_key('answer1'))
  638
+        self.assertTrue(cache.has_key('answer1', version=1))
  639
+        self.assertFalse(cache.has_key('answer1', version=2))
608 640
 
609  
-        self.assertFalse(self.v2_cache.has_key('answer1'))
610  
-        self.assertTrue(self.v2_cache.has_key('answer1', version=1))
611  
-        self.assertFalse(self.v2_cache.has_key('answer1', version=2))
  641
+        self.assertFalse(caches['v2'].has_key('answer1'))
  642
+        self.assertTrue(caches['v2'].has_key('answer1', version=1))
  643
+        self.assertFalse(caches['v2'].has_key('answer1', version=2))
612 644
 
613 645
     def test_cache_versioning_delete(self):
614  
-        self.cache.set('answer1', 37, version=1)
615  
-        self.cache.set('answer1', 42, version=2)
616  
-        self.cache.delete('answer1')
617  
-        self.assertEqual(self.cache.get('answer1', version=1), None)
618  
-        self.assertEqual(self.cache.get('answer1', version=2), 42)
619  
-
620  
-        self.cache.set('answer2', 37, version=1)
621  
-        self.cache.set('answer2', 42, version=2)
622  
-        self.cache.delete('answer2', version=2)
623  
-        self.assertEqual(self.cache.get('answer2', version=1), 37)
624  
-        self.assertEqual(self.cache.get('answer2', version=2), None)
625  
-
626  
-        self.cache.set('answer3', 37, version=1)
627  
-        self.cache.set('answer3', 42, version=2)
628  
-        self.v2_cache.delete('answer3')
629  
-        self.assertEqual(self.cache.get('answer3', version=1), 37)
630  
-        self.assertEqual(self.cache.get('answer3', version=2), None)
631  
-
632  
-        self.cache.set('answer4', 37, version=1)
633  
-        self.cache.set('answer4', 42, version=2)
634  
-        self.v2_cache.delete('answer4', version=1)
635  
-        self.assertEqual(self.cache.get('answer4', version=1), None)
636  
-        self.assertEqual(self.cache.get('answer4', version=2), 42)
  646
+        cache.set('answer1', 37, version=1)
  647
+        cache.set('answer1', 42, version=2)
  648
+        cache.delete('answer1')
  649
+        self.assertEqual(cache.get('answer1', version=1), None)
  650
+        self.assertEqual(cache.get('answer1', version=2), 42)
  651
+
  652
+        cache.set('answer2', 37, version=1)
  653
+        cache.set('answer2', 42, version=2)
  654
+        cache.delete('answer2', version=2)
  655
+        self.assertEqual(cache.get('answer2', version=1), 37)
  656
+        self.assertEqual(cache.get('answer2', version=2), None)
  657
+
  658
+        cache.set('answer3', 37, version=1)
  659
+        cache.set('answer3', 42, version=2)
  660
+        caches['v2'].delete('answer3')
  661
+        self.assertEqual(cache.get('answer3', version=1), 37)
  662
+        self.assertEqual(cache.get('answer3', version=2), None)
  663
+
  664
+        cache.set('answer4', 37, version=1)
  665
+        cache.set('answer4', 42, version=2)
  666
+        caches['v2'].delete('answer4', version=1)
  667
+        self.assertEqual(cache.get('answer4', version=1), None)
  668
+        self.assertEqual(cache.get('answer4', version=2), 42)
637 669
 
638 670
     def test_cache_versioning_incr_decr(self):
639  
-        self.cache.set('answer1', 37, version=1)
640  
-        self.cache.set('answer1', 42, version=2)
641  
-        self.cache.incr('answer1')
642  
-        self.assertEqual(self.cache.get('answer1', version=1), 38)
643  
-        self.assertEqual(self.cache.get('answer1', version=2), 42)
644  
-        self.cache.decr('answer1')
645  
-        self.assertEqual(self.cache.get('answer1', version=1), 37)
646  
-        self.assertEqual(self.cache.get('answer1', version=2), 42)
647  
-
648  
-        self.cache.set('answer2', 37, version=1)
649  
-        self.cache.set('answer2', 42, version=2)
650  
-        self.cache.incr('answer2', version=2)
651  
-        self.assertEqual(self.cache.get('answer2', version=1), 37)
652  
-        self.assertEqual(self.cache.get('answer2', version=2), 43)
653  
-        self.cache.decr('answer2', version=2)
654  
-        self.assertEqual(self.cache.get('answer2', version=1), 37)
655  
-        self.assertEqual(self.cache.get('answer2', version=2), 42)
656  
-
657  
-        self.cache.set('answer3', 37, version=1)
658  
-        self.cache.set('answer3', 42, version=2)
659  
-        self.v2_cache.incr('answer3')
660  
-        self.assertEqual(self.cache.get('answer3', version=1), 37)
661  
-        self.assertEqual(self.cache.get('answer3', version=2), 43)
662  
-        self.v2_cache.decr('answer3')
663  
-        self.assertEqual(self.cache.get('answer3', version=1), 37)
664  
-        self.assertEqual(self.cache.get('answer3', version=2), 42)
665  
-
666  
-        self.cache.set('answer4', 37, version=1)
667  
-        self.cache.set('answer4', 42, version=2)
668  
-        self.v2_cache.incr('answer4', version=1)
669  
-        self.assertEqual(self.cache.get('answer4', version=1), 38)
670  
-        self.assertEqual(self.cache.get('answer4', version=2), 42)
671  
-        self.v2_cache.decr('answer4', version=1)
672  
-        self.assertEqual(self.cache.get('answer4', version=1), 37)
673  
-        self.assertEqual(self.cache.get('answer4', version=2), 42)
  671
+        cache.set('answer1', 37, version=1)
  672
+        cache.set('answer1', 42, version=2)
  673
+        cache.incr('answer1')
  674
+        self.assertEqual(cache.get('answer1', version=1), 38)
  675
+        self.assertEqual(cache.get('answer1', version=2), 42)
  676
+        cache.decr('answer1')
  677
+        self.assertEqual(cache.get('answer1', version=1), 37)
  678
+        self.assertEqual(cache.get('answer1', version=2), 42)
  679
+
  680
+        cache.set('answer2', 37, version=1)
  681
+        cache.set('answer2', 42, version=2)
  682
+        cache.incr('answer2', version=2)
  683
+        self.assertEqual(cache.get('answer2', version=1), 37)
  684
+        self.assertEqual(cache.get('answer2', version=2), 43)
  685
+        cache.decr('answer2', version=2)
  686
+        self.assertEqual(cache.get('answer2', version=1), 37)
  687
+        self.assertEqual(cache.get('answer2', version=2), 42)
  688
+
  689
+        cache.set('answer3', 37, version=1)
  690
+        cache.set('answer3', 42, version=2)
  691
+        caches['v2'].incr('answer3')
  692
+        self.assertEqual(cache.get('answer3', version=1), 37)
  693
+        self.assertEqual(cache.get('answer3', version=2), 43)
  694
+        caches['v2'].decr('answer3')
  695
+        self.assertEqual(cache.get('answer3', version=1), 37)
  696
+        self.assertEqual(cache.get('answer3', version=2), 42)
  697
+
  698
+        cache.set('answer4', 37, version=1)
  699
+        cache.set('answer4', 42, version=2)
  700
+        caches['v2'].incr('answer4', version=1)
  701
+        self.assertEqual(cache.get('answer4', version=1), 38)
  702
+        self.assertEqual(cache.get('answer4', version=2), 42)
  703
+        caches['v2'].decr('answer4', version=1)
  704
+        self.assertEqual(cache.get('answer4', version=1), 37)
  705
+        self.assertEqual(cache.get('answer4', version=2), 42)
674 706
 
675 707
     def test_cache_versioning_get_set_many(self):
676 708
         # set, using default version = 1
677  
-        self.cache.set_many({'ford1': 37, 'arthur1': 42})
678  
-        self.assertEqual(self.cache.get_many(['ford1', 'arthur1']),
  709
+        cache.set_many({'ford1': 37, 'arthur1': 42})
  710
+        self.assertEqual(cache.get_many(['ford1', 'arthur1']),
679 711
                          {'ford1': 37, 'arthur1': 42})
680  
-        self.assertEqual(self.cache.get_many(['ford1', 'arthur1'], version=1),
  712
+        self.assertEqual(cache.get_many(['ford1', 'arthur1'], version=1),
681 713
                          {'ford1': 37, 'arthur1': 42})
682  
-        self.assertEqual(self.cache.get_many(['ford1', 'arthur1'], version=2), {})
  714
+        self.assertEqual(cache.get_many(['ford1', 'arthur1'], version=2), {})
683 715
 
684  
-        self.assertEqual(self.v2_cache.get_many(['ford1', 'arthur1']), {})
685  
-        self.assertEqual(self.v2_cache.get_many(['ford1', 'arthur1'], version=1),
  716
+        self.assertEqual(caches['v2'].get_many(['ford1', 'arthur1']), {})
  717
+        self.assertEqual(caches['v2'].get_many(['ford1', 'arthur1'], version=1),
686 718
                          {'ford1': 37, 'arthur1': 42})
687  
-        self.assertEqual(self.v2_cache.get_many(['ford1', 'arthur1'], version=2), {})
  719
+        self.assertEqual(caches['v2'].get_many(['ford1', 'arthur1'], version=2), {})
688 720
 
689 721
         # set, default version = 1, but manually override version = 2
690  
-        self.cache.set_many({'ford2': 37, 'arthur2': 42}, version=2)
691  
-        self.assertEqual(self.cache.get_many(['ford2', 'arthur2']), {})
692  
-        self.assertEqual(self.cache.get_many(['ford2', 'arthur2'], version=1), {})
693  
-        self.assertEqual(self.cache.get_many(['ford2', 'arthur2'], version=2),
  722
+        cache.set_many({'ford2': 37, 'arthur2': 42}, version=2)
  723
+        self.assertEqual(cache.get_many(['ford2', 'arthur2']), {})
  724
+        self.assertEqual(cache.get_many(['ford2', 'arthur2'], version=1), {})
  725
+        self.assertEqual(cache.get_many(['ford2', 'arthur2'], version=2),
694 726
                          {'ford2': 37, 'arthur2': 42})
695 727
 
696  
-        self.assertEqual(self.v2_cache.get_many(['ford2', 'arthur2']),
  728
+        self.assertEqual(caches['v2'].get_many(['ford2', 'arthur2']),
697 729
                          {'ford2': 37, 'arthur2': 42})
698  
-        self.assertEqual(self.v2_cache.get_many(['ford2', 'arthur2'], version=1), {})
699  
-        self.assertEqual(self.v2_cache.get_many(['ford2', 'arthur2'], version=2),
  730
+        self.assertEqual(caches['v2'].get_many(['ford2', 'arthur2'], version=1), {})
  731
+        self.assertEqual(caches['v2'].get_many(['ford2', 'arthur2'], version=2),
700 732
                          {'ford2': 37, 'arthur2': 42})
701 733
 
702 734
         # v2 set, using default version = 2
703  
-        self.v2_cache.set_many({'ford3': 37, 'arthur3': 42})
704  
-        self.assertEqual(self.cache.get_many(['ford3', 'arthur3']), {})
705  
-        self.assertEqual(self.cache.get_many(['ford3', 'arthur3'], version=1), {})
706  
-        self.assertEqual(self.cache.get_many(['ford3', 'arthur3'], version=2),
  735
+        caches['v2'].set_many({'ford3': 37, 'arthur3': 42})
  736
+        self.assertEqual(cache.get_many(['ford3', 'arthur3']), {})
  737
+        self.assertEqual(cache.get_many(['ford3', 'arthur3'], version=1), {})
  738
+        self.assertEqual(cache.get_many(['ford3', 'arthur3'], version=2),
707 739
                          {'ford3': 37, 'arthur3': 42})
708 740
 
709  
-        self.assertEqual(self.v2_cache.get_many(['ford3', 'arthur3']),
  741
+        self.assertEqual(caches['v2'].get_many(['ford3', 'arthur3']),
710 742
                          {'ford3': 37, 'arthur3': 42})
711  
-        self.assertEqual(self.v2_cache.get_many(['ford3', 'arthur3'], version=1), {})
712  
-        self.assertEqual(self.v2_cache.get_many(['ford3', 'arthur3'], version=2),
  743
+        self.assertEqual(caches['v2'].get_many(['ford3', 'arthur3'], version=1), {})
  744
+        self.assertEqual(caches['v2'].get_many(['ford3', 'arthur3'], version=2),
713 745
                          {'ford3': 37, 'arthur3': 42})
714 746
 
715 747
         # v2 set, default version = 2, but manually override version = 1
716  
-        self.v2_cache.set_many({'ford4': 37, 'arthur4': 42}, version=1)
717  
-        self.assertEqual(self.cache.get_many(['ford4', 'arthur4']),
  748
+        caches['v2'].set_many({'ford4': 37, 'arthur4': 42}, version=1)
  749
+        self.assertEqual(cache.get_many(['ford4', 'arthur4']),
718 750
                          {'ford4': 37, 'arthur4': 42})
719  
-        self.assertEqual(self.cache.get_many(['ford4', 'arthur4'], version=1),
  751
+        self.assertEqual(cache.get_many(['ford4', 'arthur4'], version=1),
720 752
                          {'ford4': 37, 'arthur4': 42})
721  
-        self.assertEqual(self.cache.get_many(['ford4', 'arthur4'], version=2), {})
  753
+        self.assertEqual(cache.get_many(['ford4', 'arthur4'], version=2), {})
722 754
 
723  
-        self.assertEqual(self.v2_cache.get_many(['ford4', 'arthur4']), {})
724  
-        self.assertEqual(self.v2_cache.get_many(['ford4', 'arthur4'], version=1),
  755
+        self.assertEqual(caches['v2'].get_many(['ford4', 'arthur4']), {})
  756
+        self.assertEqual(caches['v2'].get_many(['ford4', 'arthur4'], version=1),
725 757
                          {'ford4': 37, 'arthur4': 42})
726  
-        self.assertEqual(self.v2_cache.get_many(['ford4', 'arthur4'], version=2), {})
  758
+        self.assertEqual(caches['v2'].get_many(['ford4', 'arthur4'], version=2), {})
727 759
 
728 760
     def test_incr_version(self):
729  
-        self.cache.set('answer', 42, version=2)
730  
-        self.assertEqual(self.cache.get('answer'), None)
731  
-        self.assertEqual(self.cache.get('answer', version=1), None)
732  
-        self.assertEqual(self.cache.get('answer', version=2), 42)
733  
-        self.assertEqual(self.cache.get('answer', version=3), None)
734  
-
735  
-        self.assertEqual(self.cache.incr_version('answer', version=2), 3)
736  
-        self.assertEqual(self.cache.get('answer'), None)
737  
-        self.assertEqual(self.cache.get('answer', version=1), None)
738  
-        self.assertEqual(self.cache.get('answer', version=2), None)
739  
-        self.assertEqual(self.cache.get('answer', version=3), 42)
740  
-
741  
-        self.v2_cache.set('answer2', 42)
742  
-        self.assertEqual(self.v2_cache.get('answer2'), 42)
743  
-        self.assertEqual(self.v2_cache.get('answer2', version=1), None)
744  
-        self.assertEqual(self.v2_cache.get('answer2', version=2), 42)
745  
-        self.assertEqual(self.v2_cache.get('answer2', version=3), None)
746  
-
747  
-        self.assertEqual(self.v2_cache.incr_version('answer2'), 3)
748  
-        self.assertEqual(self.v2_cache.get('answer2'), None)
749  
-        self.assertEqual(self.v2_cache.get('answer2', version=1), None)
750  
-        self.assertEqual(self.v2_cache.get('answer2', version=2), None)
751  
-        self.assertEqual(self.v2_cache.get('answer2', version=3), 42)
752  
-
753  
-        self.assertRaises(ValueError, self.cache.incr_version, 'does_not_exist')
  761
+        cache.set('answer', 42, version=2)
  762
+        self.assertEqual(cache.get('answer'), None)
  763
+        self.assertEqual(cache.get('answer', version=1), None)
  764
+        self.assertEqual(cache.get('answer', version=2), 42)
  765
+        self.assertEqual(cache.get('answer', version=3), None)
  766
+
  767
+        self.assertEqual(cache.incr_version('answer', version=2), 3)
  768
+        self.assertEqual(cache.get('answer'), None)
  769
+        self.assertEqual(cache.get('answer', version=1), None)
  770
+        self.assertEqual(cache.get('answer', version=2), None)
  771
+        self.assertEqual(cache.get('answer', version=3), 42)
  772
+
  773
+        caches['v2'].set('answer2', 42)
  774
+        self.assertEqual(caches['v2'].get('answer2'), 42)
  775
+        self.assertEqual(caches['v2'].get('answer2', version=1), None)
  776
+        self.assertEqual(caches['v2'].get('answer2', version=2), 42)
  777
+        self.assertEqual(caches['v2'].get('answer2', version=3), None)
  778
+
  779
+        self.assertEqual(caches['v2'].incr_version('answer2'), 3)
  780
+        self.assertEqual(caches['v2'].get('answer2'), None)
  781
+        self.assertEqual(caches['v2'].get('answer2', version=1), None)
  782
+        self.assertEqual(caches['v2'].get('answer2', version=2), None)
  783
+        self.assertEqual(caches['v2'].get('answer2', version=3), 42)
  784
+
  785
+        self.assertRaises(ValueError, cache.incr_version, 'does_not_exist')
754