Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fixed #14199 -- Added a missing table creation statement in the db ca…

…che backend cull implementation, and added tests for cache culling. Thanks to Tim for the report.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@13678 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 2a0f4fb5da0ed4224dabe280f7a6aefcb21f9911 1 parent 0de3e7a
Russell Keith-Magee authored August 31, 2010
1  django/core/cache/backends/db.py
@@ -124,6 +124,7 @@ def _cull(self, db, cursor, now):
124 124
         if self._cull_frequency == 0:
125 125
             self.clear()
126 126
         else:
  127
+            table = connections[db].ops.quote_name(self._table)
127 128
             cursor.execute("DELETE FROM %s WHERE expires < %%s" % table,
128 129
                            [connections[db].ops.value_to_db_datetime(now)])
129 130
             cursor.execute("SELECT COUNT(*) FROM %s" % table)
29  tests/regressiontests/cache/tests.py
@@ -352,21 +352,41 @@ def test_long_timeout(self):
352 352
         self.assertEqual(self.cache.get('key3'), 'sausage')
353 353
         self.assertEqual(self.cache.get('key4'), 'lobster bisque')
354 354
 
  355
+    def perform_cull_test(self, initial_count, final_count):
  356
+        """This is implemented as a utility method, because only some of the backends
  357
+        implement culling. The culling algorithm also varies slightly, so the final
  358
+        number of entries will vary between backends"""
  359
+        # Create initial cache key entries. This will overflow the cache, causing a cull
  360
+        for i in range(1, initial_count):
  361
+            self.cache.set('cull%d' % i, 'value', 1000)
  362
+        count = 0
  363
+        # Count how many keys are left in the cache.
  364
+        for i in range(1, initial_count):
  365
+            if self.cache.has_key('cull%d' % i):
  366
+                count = count + 1
  367
+        self.assertEqual(count, final_count)
  368
+
355 369
 class DBCacheTests(unittest.TestCase, BaseCacheTests):
356 370
     def setUp(self):
357 371
         # Spaces are used in the table name to ensure quoting/escaping is working
358 372
         self._table_name = 'test cache table'
359 373
         management.call_command('createcachetable', self._table_name, verbosity=0, interactive=False)
360  
-        self.cache = get_cache('db://%s' % self._table_name)
  374
+        self.cache = get_cache('db://%s?max_entries=30' % self._table_name)
361 375
 
362 376
     def tearDown(self):
363 377
         from django.db import connection
364 378
         cursor = connection.cursor()
365 379
         cursor.execute('DROP TABLE %s' % connection.ops.quote_name(self._table_name))
366 380
 
  381
+    def test_cull(self):
  382
+        self.perform_cull_test(50, 29)
  383
+
367 384
 class LocMemCacheTests(unittest.TestCase, BaseCacheTests):
368 385
     def setUp(self):
369  
-        self.cache = get_cache('locmem://')
  386
+        self.cache = get_cache('locmem://?max_entries=30')
  387
+
  388
+    def test_cull(self):
  389
+        self.perform_cull_test(50, 29)
370 390
 
371 391
 # memcached backend isn't guaranteed to be available.
372 392
 # To check the memcached backend, the test settings file will
@@ -383,7 +403,7 @@ class FileBasedCacheTests(unittest.TestCase, BaseCacheTests):
383 403
     """
384 404
     def setUp(self):
385 405
         self.dirname = tempfile.mkdtemp()
386  
-        self.cache = get_cache('file://%s' % self.dirname)
  406
+        self.cache = get_cache('file://%s?max_entries=30' % self.dirname)
387 407
 
388 408
     def test_hashing(self):
389 409
         """Test that keys are hashed into subdirectories correctly"""
@@ -406,6 +426,9 @@ def test_subdirectory_removal(self):
406 426
         self.assert_(not os.path.exists(os.path.dirname(keypath)))
407 427
         self.assert_(not os.path.exists(os.path.dirname(os.path.dirname(keypath))))
408 428
 
  429
+    def test_cull(self):
  430
+        self.perform_cull_test(50, 28)
  431
+
409 432
 class CacheUtils(unittest.TestCase):
410 433
     """TestCase for django.utils.cache functions."""
411 434
 

0 notes on commit 2a0f4fb

Please sign in to comment.
Something went wrong with that request. Please try again.