Commits

Lukas Linhart committed 63bdbca

Clear cache between tests (fixes #28)

Comments (0)

Files changed (4)

djangosanetesting/cache.py

+"""
+Utility methods for cache clear.
+Used to somehow partially backport http://code.djangoproject.com/ticket/12671
+to Django < 1.2
+"""
+
+from django.core.cache import cache
+from django.db import connection
+
+import shutil
+
+###### clear functions
+
+def clear_db(cache):
+    cursor = connection.cursor()
+    cursor.execute('DELETE FROM %s' % cache._table)
+
+def clear_filebased(cache):
+    try:
+        shutil.rmtree(cache._dir)
+    except (IOError, OSError):
+        pass
+
+def clear_memcached(cache):
+    cache._cache.flush_all()
+
+def clear_locmem(cache):
+    cache._cache.clear()
+    cache._expire_info.clear()
+
+###### end of clear functions
+
+
+# map
+
+BACKEND_CLEAR_MAP = {
+    'db' : clear_db,
+    'dummy' : lambda x: x,
+    'filebased' : clear_filebased,
+    'memcached' : clear_memcached,
+    'locmem' : clear_locmem,
+}
+
+# utility methods
+
+def get_cache_class():
+    return ''
+
+def flush_django_cache():
+    try:
+        cache.clear()
+    except AttributeError:
+        # Django < 1.2, backports
+        backend_name = cache.__module__.split(".")[-1:][0]
+        
+        if backend_name not in BACKEND_CLEAR_MAP:
+            raise ValueError("Don't know how to clear cache for %s backend" % backend_name)
+
+        BACKEND_CLEAR_MAP[backend_name](cache)

djangosanetesting/noseplugins.py

 from django.core.servers.basehttp import  WSGIRequestHandler, AdminMediaHandler, WSGIServerException
 
 import nose
-from nose import SkipTest
 from nose.plugins import Plugin
 
+import djangosanetesting
+import djangosanetesting.cache
+
+#from djagnosanetesting.cache import flush_django_cache
 from djangosanetesting.selenium.driver import selenium
 
 __all__ = ("CherryPyLiveServerPlugin", "DjangoLiveServerPlugin", "DjangoPlugin", "SeleniumPlugin", "SaneTestSelectionPlugin")
         settings.ROOT_URLCONF = case._old_root_urlconf
         clear_url_caches()
 
+def flush_cache(case):
+    from django.contrib.contenttypes.models import ContentType
+    ContentType.objects.clear_cache()
+
+    djangosanetesting.cache.flush_django_cache()
+
+
 def get_test_case_class(nose_test):
     if isinstance(nose_test.test, nose.case.MethodTestCase):
         return nose_test.test.test.im_class
             transaction.leave_transaction_management()
 
         flush_urlconf(self)
+        flush_cache(self)
         
-        from django.contrib.contenttypes.models import ContentType
-        ContentType.objects.clear_cache()
-
 class DjangoTranslationPlugin(Plugin):
     """
     For testcases with selenium_start set to True, connect to Selenium RC.

testproject/settings.py

 
 working_dir = path.dirname(path.abspath(__file__))
 
-from config import *
-
 APPLICATION_ROOT=path.join(path.dirname(path.abspath(__file__)))
 
 # List of callables that know how to import templates from various sources.
 CHERRYPY_TEST_SERVER = True
 
 LANGUAGE_CODE = 'cs'
+
+CACHE_BACKEND = 'locmem://'
+
+from config import *
+

testproject/test/test_unit.py

 # -*- coding: utf-8 -*-
 from djangosanetesting.cases import UnitTestCase
 
+from django.core.cache import cache
+
 from testapp.models import ExampleModel
 
 class TestUnitSimpleMetods(UnitTestCase):
         ExampleModel.objects.create(name="test2")
         self.assert_equals(2, len(ExampleModel.objects.all()))
 
+
+class TestProperCacheClearance(UnitTestCase):
+    """
+    Test cache is cleared, i.e. not preserved between tests
+    We rely that test suite executed methods in this order:
+      (1) test_aaa_inserting_cache
+      (2) test_bbb_cache_retrieval
+
+    This is antipattern and should not be used, but it's hard to test
+    framework from within ;) Better solution would be greatly appreciated.
+    """
+
+    def test_aaa_inserting_model(self):
+        cache.set("test", "pwned")
+        self.assert_equals("pwned", cache.get("test"))
+
+    def test_bbb_inserting_another(self):
+        self.assert_equals(None, cache.get("test"))
+
+
 class TestTranslations(UnitTestCase):
     def test_czech_string_acquired(self):
         """
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.