diff --git a/src/Products/ZCatalog/cache.py b/src/Products/ZCatalog/cache.py index 07df9224..b612759d 100644 --- a/src/Products/ZCatalog/cache.py +++ b/src/Products/ZCatalog/cache.py @@ -126,13 +126,18 @@ def decorator(*args, **kwargs): # Make sure we provide test isolation, works only for ramcache -def _cache_clear(): +def _get_cache(): cache_adapter = ram.store_in_cache(_apply_query_plan_cachekey) if hasattr(cache_adapter, 'ramcache'): - cache_adapter.ramcache.invalidateAll() + return cache_adapter.ramcache else: raise AttributeError('Only ramcache supported for testing') + +def _cache_clear(): + ram_cache = _get_cache() + ram_cache.invalidateAll() + from zope.testing.cleanup import addCleanUp # NOQA addCleanUp(_cache_clear) del addCleanUp diff --git a/src/Products/ZCatalog/tests/test_cache.py b/src/Products/ZCatalog/tests/test_cache.py index 4d3d2348..ce94396b 100644 --- a/src/Products/ZCatalog/tests/test_cache.py +++ b/src/Products/ZCatalog/tests/test_cache.py @@ -25,6 +25,7 @@ from Products.ZCatalog.Catalog import Catalog from Products.ZCatalog.ZCatalog import ZCatalog from Products.ZCatalog.cache import CatalogCacheKey +from Products.ZCatalog.cache import _get_cache class Dummy(object): @@ -88,15 +89,82 @@ def setUp(self): self.zcat = zcat + def _apply_query(self, query): + cache = _get_cache() + + res1 = self.zcat.search(query) + stats = cache.getStatistics() + + hits = stats[0]['hits'] + misses = stats[0]['misses'] + + res2 = self.zcat.search(query) + stats = cache.getStatistics() + + # check if chache hits + self.assertEqual(stats[0]['hits'], hits + 1) + self.assertEqual(stats[0]['misses'], misses) + + # compare result + rset1 = map(lambda x: x.getRID(), res1) + rset2 = map(lambda x: x.getRID(), res2) + self.assertEqual(rset1, rset2) + def _get_cache_key(self, query=None): catalog = self.zcat._catalog + query = catalog.make_query(query) return CatalogCacheKey(catalog, query=query).key def test_make_key(self): query = {'big': True} - key = (('catalog',), frozenset([('big', self.length, (True,))])) + key = (('catalog',), + frozenset([('big', self.length, (True,))])) self.assertEquals(self._get_cache_key(query), key) -#class TestCatalogCaching(unittest.TestCase): -# -# def test_caching + query = {'start': '2013-07-01'} + key = (('catalog',), + frozenset([('start', self.length, ('2013-07-01',))])) + self.assertEquals(self._get_cache_key(query), key) + + query = {'path': '/1', 'date': '2013-07-05', 'numbers': [1, 3]} + key = (('catalog',), + frozenset([('date', 9, ('2013-07-05',)), + ('numbers', 9, (1, 3)), + ('path', 9, ('/1',))])) + self.assertEquals(self._get_cache_key(query), key) + + def test_cache(self): + query = {'big': True} + self._apply_query(query) + + query = {'start': '2013-07-01'} + self._apply_query(query) + + query = {'path': '/1', 'date': '2013-07-05', 'numbers': [1, 3]} + self._apply_query(query) + + def test_cache_invalidate(self): + cache = _get_cache() + query = {'big': False} + + res1 = self.zcat.search(query) + stats = cache.getStatistics() + + hits = stats[0]['hits'] + misses = stats[0]['misses'] + + # catalog new object + obj = Dummy(20) + self.zcat.catalog_object(obj, str(20)) + + res2 = self.zcat.search(query) + stats = cache.getStatistics() + + # check if chache misses + self.assertEqual(stats[0]['hits'], hits) + self.assertEqual(stats[0]['misses'], misses + 1) + + # compare result + rset1 = map(lambda x: x.getRID(), res1) + rset2 = map(lambda x: x.getRID(), res2) + self.assertEqual(rset1, rset2) diff --git a/src/Products/ZCatalog/tests/test_zcatalog.py b/src/Products/ZCatalog/tests/test_zcatalog.py index 5e2bff29..0ace59e3 100644 --- a/src/Products/ZCatalog/tests/test_zcatalog.py +++ b/src/Products/ZCatalog/tests/test_zcatalog.py @@ -12,6 +12,7 @@ ############################################################################## import unittest +from zope.testing import cleanup from AccessControl.SecurityManagement import setSecurityManager from AccessControl.SecurityManagement import noSecurityManager @@ -98,17 +99,18 @@ def validate(self, accessed, container, name, value): raise Unauthorized(name) -class ZCatalogBase(object): +class ZCatalogBase(cleanup.CleanUp): def _makeOne(self): from Products.ZCatalog.ZCatalog import ZCatalog - return ZCatalog('Catalog-%s' % id(self)) + return ZCatalog('Catalog') def _makeOneIndex(self, name): from Products.PluginIndexes.FieldIndex.FieldIndex import FieldIndex return FieldIndex(name) def setUp(self): + cleanup.CleanUp.setUp(self) self._catalog = self._makeOne() def tearDown(self):