Mike Bayer avatar Mike Bayer committed 1a81a45

lets do some tests !

Comments (0)

Files changed (9)

dogpile/cache/__init__.py

-__version__ = '0.1.0'
+__version__ = '0.1.0'
+
+from region import CacheRegion, register_backend

dogpile/cache/api.py

     the backend requires serialization.
     
     """
-    payload = operator.itemgetter(0)
-    metadata = operator.itemgetter(1)
+    payload = property(operator.itemgetter(0))
+    metadata = property(operator.itemgetter(1))
 
     def __new__(cls, payload, metadata):
         return tuple.__new__(cls, (payload, metadata))
     key_mangler = None
     """Key mangling function.  
     
-    May be None.
+    May be None, or otherwise declared
+    as an ordinary instance method.
+
     """
 
     def __init__(self, arguments):

dogpile/cache/backends/__init__.py

 from dogpile.cache.region import register_backend
 
-register_backend("dbm", "dogpile.cache.backends.dbm", "DbmBackend")
+register_backend("dbm", "dogpile.cache.backends.dbm", "DBMBackend")
 register_backend("pylibmc", "dogpile.cache.backends.memcached", "PylibmcBackend")

dogpile/cache/backends/dbm.py

+from dogpile.cache.api import CacheBackend, CachedValue, NO_VALUE
+
+class DBMBackend(CacheBackend):
+    pass

dogpile/cache/backends/memcached.py

+from dogpile.cache.api import CacheBackend, CachedValue, NO_VALUE
+
+class PylibmcBackend(CacheBackend):
+    pass

dogpile/cache/region.py

             )
         else:
             self.backend = backend_cls(arguments)
+        self.expiration_time = expiration_time
         self.dogpile_registry = NameRegistry(self._create_dogpile)
         if self.key_mangler is None:
-            self.key_mangler = backend.key_mangler
+            self.key_mangler = self.backend.key_mangler
         return self
 
     def _create_dogpile(self, identifier):
         return Dogpile(
-                expiration_time, 
+                self.expiration_time, 
                 lock=self.backend.get_mutex(identifier)
             )
 
             return value.payload, value.metadata["creation_time"]
 
         def gen_value():
-            value = CachedValue(
-                        creator(), 
-                        {
+            value = self._value(creator())
+            self.backend.put(key, value)
+            return value
+
+        dogpile = self.dogpile_registry.get(key)
+        with dogpile.acquire(gen_value, value_and_created_fn=get_value) as value:
+            return value
+
+    def _value(self, value):
+        """Return a :class:`.CachedValue` given a value."""
+        return CachedValue(value, {
                             "creation_time":time.time(), 
                             "version":value_version
                         })
-            self.backend.put(key, value)
-            return value
-
-        dogpile = self.dogpile_registry.get(key, lock=self.backend.get_mutex(key))
-        with dogpile.acquire(gen_value, value_and_created_fn=get_value) as value:
-            return value
 
     def put(self, key, value):
         """Place a new value in the cache under the given key."""
 
         if self.key_mangler:
             key = self.key_mangler(key)
-        self.backend.put(key, CachedValue(value))
+        self.backend.put(key, self._value(value))
 
 
     def delete(self, key):
 [upload_docs]
 upload-dir = docs/build/output/html
 
-[nosetests]
-logging-config=nose_logging_config.ini

tests/__init__.py

+import re
+
+def eq_(a, b, msg=None):
+    """Assert a == b, with repr messaging on failure."""
+    assert a == b, msg or "%r != %r" % (a, b)
+
+def ne_(a, b, msg=None):
+    """Assert a != b, with repr messaging on failure."""
+    assert a != b, msg or "%r == %r" % (a, b)
+
+def assert_raises_message(except_cls, msg, callable_, *args, **kwargs):
+    try:
+        callable_(*args, **kwargs)
+        assert False, "Callable did not raise an exception"
+    except except_cls, e:
+        assert re.search(msg, str(e)), "%r !~ %s" % (msg, e)

tests/test_region.py

+from unittest import TestCase
+from dogpile.cache.api import CacheBackend, CachedValue, NO_VALUE
+from dogpile.cache import register_backend, CacheRegion
+from tests import eq_, assert_raises_message
+import time
+import itertools
+
+class MockMutex(object):
+    def __init__(self, key):
+        self.key = key
+    def acquire(self, blocking=True):
+        return True
+    def release(self):
+        return
+
+class MockBackend(CacheBackend):
+    def __init__(self, arguments):
+        self.arguments = arguments
+        self._cache = {}
+    def get_mutex(self, key):
+        return MockMutex(key)
+    def get(self, key):
+        try:
+            return self._cache[key]
+        except KeyError:
+            return NO_VALUE
+    def put(self, key, value):
+        self._cache[key] = value
+    def delete(self, key):
+        self._cache.pop(key, None)
+register_backend("mock", __name__, "MockBackend")
+
+def key_mangler(key):
+    return "HI!" + key
+
+class RegionTest(TestCase):
+
+    def _region(self, init_args={}, config_args={}, backend="mock"):
+        reg = CacheRegion(**init_args)
+        reg.configure(backend, **config_args)
+        return reg
+
+    def test_key_mangler_argument(self):
+        reg = self._region(init_args={"key_mangler":key_mangler})
+        assert reg.key_mangler is key_mangler
+
+        reg = self._region()
+        assert reg.key_mangler is None
+
+        MockBackend.key_mangler = km = lambda self, k: "foo"
+        reg = self._region()
+        eq_(reg.key_mangler("bar"), "foo")
+        MockBackend.key_mangler = None
+
+    def test_key_mangler_impl(self):
+        reg = self._region(init_args={"key_mangler":key_mangler})
+
+        reg.put("some key", "some value")
+        eq_(list(reg.backend._cache), ["HI!some key"])
+        eq_(reg.get("some key"), "some value")
+        eq_(reg.get_or_create("some key", lambda: "some new value"), "some value")
+        reg.delete("some key")
+        eq_(reg.get("some key"), NO_VALUE)
+
+    def test_no_config(self):
+        reg = CacheRegion()
+        assert_raises_message(
+            Exception,
+            "No backend is configured on this region.",
+            getattr, reg, "backend"
+        )
+
+    def test_put_get_value(self):
+        reg = self._region()
+        reg.put("some key", "some value")
+        eq_(reg.get("some key"), "some value")
+
+    def test_put_get_nothing(self):
+        reg = self._region()
+        eq_(reg.get("some key"), NO_VALUE)
+
+    def test_creator(self):
+        reg = self._region()
+        def creator():
+            return "some value"
+        eq_(reg.get_or_create("some key", creator), "some value")
+
+    def test_remove(self):
+        reg = self._region()
+        reg.put("some key", "some value")
+        reg.delete("some key")
+        reg.delete("some key")
+        eq_(reg.get("some key"), NO_VALUE)
+
+    def test_expire(self):
+        reg = self._region(config_args={"expiration_time":1})
+        counter = itertools.count(1)
+        def creator():
+            return "some value %d" % next(counter)
+        eq_(reg.get_or_create("some key", creator), "some value 1")
+        time.sleep(1)
+        eq_(reg.get("some key"), "some value 1")
+        eq_(reg.get_or_create("some key", creator), "some value 2")
+        eq_(reg.get("some key"), "some value 2")
+
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.