Commits

inklesspen committed 2b7b368

Redis backend now supports a password, as well as configuration via url instead of separate host/port/db params.

Comments (0)

Files changed (3)

dogpile/cache/backends/redis.py

 
     Arguments accepted in the arguments dictionary:
 
+    :param url: string. If provided, will override separate host/port/db params.
+
     :param host: string, default is ``localhost``.
 
+    :param password: string, default is no password.
+
     :param port: integer, default is ``6379``.
 
     :param db: integer, default is ``0``.
 
     def __init__(self, arguments):
         self._imports()
+        self.url = arguments.pop('url', None)
         self.host = arguments.pop('host', 'localhost')
+        self.password = arguments.pop('password', None)
         self.port = arguments.pop('port', 6379)
         self.db = arguments.pop('db', 0)
         self.distributed_lock = arguments.get('distributed_lock', False)
 
     def _create_client(self):
         # creates client instace (so test harness can test connection)
-        return redis.StrictRedis(host=self.host, port=self.port, db=self.db)
+        if self.url is not None:
+            return redis.StrictRedis.from_url(url=self.url)
+        return redis.StrictRedis(host=self.host, password=self.password, port=self.port, db=self.db)
 
     def get_mutex(self, key):
         if self.distributed_lock:
       zip_safe=False,
       install_requires=['dogpile.core>=0.4.0'],
       test_suite='nose.collector',
-      tests_require=['nose'],
+      tests_require=['nose', 'mock'],
 )

tests/cache/test_redis_backend.py

+from dogpile.cache.region import _backend_loader
 from ._fixtures import _GenericBackendTest, _GenericMutexTest
+from unittest import TestCase
 from nose import SkipTest
+from mock import patch
 
 class _TestRedisConn(object):
     @classmethod
             'distributed_lock':True,
             }
     }
+
+@patch('redis.StrictRedis', autospec=True)
+class RedisConnectionTest(TestCase):
+    @classmethod
+    def setup_class(cls):
+        try:
+            global redis
+            import redis
+        except ImportError:
+            raise SkipTest("Redis library not installed")
+
+        cls.backend_cls = _backend_loader.load('dogpile.cache.redis')
+
+    def _test_helper(self, mock_obj, expected_args, connection_args=None):
+        if connection_args is None:
+            # The redis backend pops items from the dict, so we copy
+            connection_args = expected_args.copy()
+
+        backend = self.backend_cls(connection_args)
+        mock_obj.assert_called_once_with(**expected_args)
+
+    def test_connect_with_defaults(self, MockStrictRedis):
+        # The defaults, used if keys are missing from the arguments dict.
+        arguments = {
+            'host': 'localhost',
+            'password': None,
+            'port': 6379,
+            'db': 0,
+            }
+        self._test_helper(MockStrictRedis, arguments, {})
+
+    def test_connect_with_basics(self, MockStrictRedis):
+        arguments = {
+            'host': '127.0.0.1',
+            'password': None,
+            'port': 6379,
+            'db': 0,
+            }
+        self._test_helper(MockStrictRedis, arguments)
+
+    def test_connect_with_password(self, MockStrictRedis):
+        arguments = {
+            'host': '127.0.0.1',
+            'password': 'some password',
+            'port': 6379,
+            'db': 0,
+            }
+        self._test_helper(MockStrictRedis, arguments)
+        
+    def test_connect_with_url(self, MockStrictRedis):
+        arguments = {
+            'url': 'redis://redis:password@127.0.0.1:6379/0'
+        }
+        self._test_helper(MockStrictRedis.from_url, arguments)