Esempio n. 1
0
    def setUp(self):
        super().setUp()

        # Populate the cache with three hits:
        for redis_key, timeout in {
            (self._KEY_EXPIRATION, _DEFAULT_TIMEOUT),
            (self._KEY_NO_EXPIRATION, None),
        }:
            cache = CachedOrderedDict(
                redis_client=self.redis,
                redis_key=redis_key,
                dict_keys=('hit1', 'hit2', 'hit3'),
                timeout=timeout,
            )
            cache['hit1'] = 'value1'
            cache['hit2'] = 'value2'
            cache['hit3'] = 'value3'

        # Instantiate the cache again with the three hits and three misses:
        self.cache_expiration = CachedOrderedDict(
            redis_client=self.redis,
            redis_key=self._KEY_EXPIRATION,
            dict_keys=('hit1', 'miss1', 'hit2', 'miss2', 'hit3', 'miss3'),
        )
        self.cache_no_expiration = CachedOrderedDict(
            redis_client=self.redis,
            redis_key=self._KEY_NO_EXPIRATION,
            dict_keys=('hit1', 'miss1', 'hit2', 'miss2', 'hit3', 'miss3'),
            timeout=None,
        )
Esempio n. 2
0
    def test_cachedorderedict(self):
        # Populate the cache with three hits:
        with CachedOrderedDict(
            redis=self.redis,
            key=self._KEY,
            keys=('hit1', 'hit2', 'hit3'),
        ) as cache:
            cache['hit1'] = 'value1'
            cache['hit2'] = 'value2'
            cache['hit3'] = 'value3'

        # Instantiate the cache again with the three hits and three misses:
        cache = CachedOrderedDict(
            redis=self.redis,
            key=self._KEY,
            keys=('hit1', 'miss1', 'hit2', 'miss2', 'hit3', 'miss3'),
        )

        # Ensure that the hits are hits, the misses are misses, and the cache
        # is ordered:
        assert tuple(cache.items()) == (
            ('hit1', 'value1'),
            ('miss1', CachedOrderedDict._SENTINEL),
            ('hit2', 'value2'),
            ('miss2', CachedOrderedDict._SENTINEL),
            ('hit3', 'value3'),
            ('miss3', CachedOrderedDict._SENTINEL),
        )
Esempio n. 3
0
    def setUp(self):
        super().setUp()

        # Populate the cache with three hits:
        cache = CachedOrderedDict(
            redis=self.redis,
            key=self._KEY,
            keys=('hit1', 'hit2', 'hit3'),
        )
        cache['hit1'] = 'value1'
        cache['hit2'] = 'value2'
        cache['hit3'] = 'value3'

        # Instantiate the cache again with the three hits and three misses:
        self.cache = CachedOrderedDict(
            redis=self.redis,
            key=self._KEY,
            keys=('hit1', 'miss1', 'hit2', 'miss2', 'hit3', 'miss3'),
        )
Esempio n. 4
0
 def test_no_keys(self):
     cache = CachedOrderedDict(redis_client=self.redis)
     assert cache == {}
     assert cache.misses() == set()
Esempio n. 5
0
class CachedOrderedDictTests(TestCase):
    _KEY_EXPIRATION = 'cached-ordereddict-expiration'
    _KEY_NO_EXPIRATION = 'cached-ordereddict-no-expiration'

    def setUp(self):
        super().setUp()

        # Populate the cache with three hits:
        for redis_key, timeout in {
            (self._KEY_EXPIRATION, _DEFAULT_TIMEOUT),
            (self._KEY_NO_EXPIRATION, None),
        }:
            cache = CachedOrderedDict(
                redis_client=self.redis,
                redis_key=redis_key,
                dict_keys=('hit1', 'hit2', 'hit3'),
                timeout=timeout,
            )
            cache['hit1'] = 'value1'
            cache['hit2'] = 'value2'
            cache['hit3'] = 'value3'

        # Instantiate the cache again with the three hits and three misses:
        self.cache_expiration = CachedOrderedDict(
            redis_client=self.redis,
            redis_key=self._KEY_EXPIRATION,
            dict_keys=('hit1', 'miss1', 'hit2', 'miss2', 'hit3', 'miss3'),
        )
        self.cache_no_expiration = CachedOrderedDict(
            redis_client=self.redis,
            redis_key=self._KEY_NO_EXPIRATION,
            dict_keys=('hit1', 'miss1', 'hit2', 'miss2', 'hit3', 'miss3'),
            timeout=None,
        )

    def test_setitem(self):
        assert self.cache_expiration == collections.OrderedDict((
            ('hit1', 'value1'),
            ('miss1', CachedOrderedDict._SENTINEL),
            ('hit2', 'value2'),
            ('miss2', CachedOrderedDict._SENTINEL),
            ('hit3', 'value3'),
            ('miss3', CachedOrderedDict._SENTINEL),
        ))
        assert self.cache_expiration._cache == {
            'hit1': 'value1',
            'hit2': 'value2',
            'hit3': 'value3',
        }
        assert self.cache_expiration.misses() == {'miss1', 'miss2', 'miss3'}

        self.cache_expiration['hit4'] = 'value4'
        assert self.cache_expiration == collections.OrderedDict((
            ('hit1', 'value1'),
            ('miss1', CachedOrderedDict._SENTINEL),
            ('hit2', 'value2'),
            ('miss2', CachedOrderedDict._SENTINEL),
            ('hit3', 'value3'),
            ('miss3', CachedOrderedDict._SENTINEL),
            ('hit4', 'value4'),
        ))
        assert self.cache_expiration._cache == {
            'hit1': 'value1',
            'hit2': 'value2',
            'hit3': 'value3',
            'hit4': 'value4',
        }
        assert self.cache_expiration.misses() == {'miss1', 'miss2', 'miss3'}

        self.cache_expiration['miss1'] = 'value1'
        assert self.cache_expiration == collections.OrderedDict((
            ('hit1', 'value1'),
            ('miss1', 'value1'),
            ('hit2', 'value2'),
            ('miss2', CachedOrderedDict._SENTINEL),
            ('hit3', 'value3'),
            ('miss3', CachedOrderedDict._SENTINEL),
            ('hit4', 'value4'),
        ))
        assert self.cache_expiration._cache == {
            'hit1': 'value1',
            'hit2': 'value2',
            'hit3': 'value3',
            'hit4': 'value4',
            'miss1': 'value1',
        }
        assert self.cache_expiration.misses() == {'miss2', 'miss3'}

    def test_setdefault(self):
        'Ensure setdefault() sets the key iff the key does not exist.'
        for default in ('rajiv', 'raj'):
            with self.subTest(default=default):
                self.cache_expiration.setdefault('first', default=default)
                assert self.cache_expiration == collections.OrderedDict((
                    ('hit1', 'value1'),
                    ('miss1', CachedOrderedDict._SENTINEL),
                    ('hit2', 'value2'),
                    ('miss2', CachedOrderedDict._SENTINEL),
                    ('hit3', 'value3'),
                    ('miss3', CachedOrderedDict._SENTINEL),
                    ('first', 'rajiv'),
                ))
                assert self.cache_expiration._cache == {
                    'hit1': 'value1',
                    'hit2': 'value2',
                    'hit3': 'value3',
                    'first': 'rajiv',
                }
                assert self.cache_expiration.misses() == {
                    'miss1',
                    'miss2',
                    'miss3',
                }

        self.cache_expiration.setdefault('miss1', default='value1')
        assert self.cache_expiration == collections.OrderedDict((
            ('hit1', 'value1'),
            ('miss1', 'value1'),
            ('hit2', 'value2'),
            ('miss2', CachedOrderedDict._SENTINEL),
            ('hit3', 'value3'),
            ('miss3', CachedOrderedDict._SENTINEL),
            ('first', 'rajiv'),
        ))
        assert self.cache_expiration._cache == {
            'hit1': 'value1',
            'hit2': 'value2',
            'hit3': 'value3',
            'first': 'rajiv',
            'miss1': 'value1',
        }
        assert self.cache_expiration.misses() == {'miss2', 'miss3'}

    def test_update(self):
        self.cache_expiration.update()
        assert self.cache_expiration == collections.OrderedDict((
            ('hit1', 'value1'),
            ('miss1', CachedOrderedDict._SENTINEL),
            ('hit2', 'value2'),
            ('miss2', CachedOrderedDict._SENTINEL),
            ('hit3', 'value3'),
            ('miss3', CachedOrderedDict._SENTINEL),
        ))
        assert self.cache_expiration._cache == {
            'hit1': 'value1',
            'hit2': 'value2',
            'hit3': 'value3',
        }
        assert self.cache_expiration.misses() == {'miss1', 'miss2', 'miss3'}

        self.cache_expiration.update((
            ('miss1', 'value1'),
            ('miss2', 'value2'),
            ('hit4', 'value4'),
            ('hit5', 'value5'),
        ))
        assert self.cache_expiration == collections.OrderedDict((
            ('hit1', 'value1'),
            ('miss1', 'value1'),
            ('hit2', 'value2'),
            ('miss2', 'value2'),
            ('hit3', 'value3'),
            ('miss3', CachedOrderedDict._SENTINEL),
            ('hit4', 'value4'),
            ('hit5', 'value5'),
        ))
        assert self.cache_expiration._cache == {
            'hit1': 'value1',
            'hit2': 'value2',
            'hit3': 'value3',
            'miss1': 'value1',
            'miss2': 'value2',
            'hit4': 'value4',
            'hit5': 'value5',
        }
        assert self.cache_expiration.misses() == {'miss3'}

        self.cache_expiration.update({'miss3': CachedOrderedDict._SENTINEL})
        assert self.cache_expiration == collections.OrderedDict((
            ('hit1', 'value1'),
            ('miss1', 'value1'),
            ('hit2', 'value2'),
            ('miss2', 'value2'),
            ('hit3', 'value3'),
            ('miss3', CachedOrderedDict._SENTINEL),
            ('hit4', 'value4'),
            ('hit5', 'value5'),
        ))
        assert self.cache_expiration._cache == {
            'hit1': 'value1',
            'hit2': 'value2',
            'hit3': 'value3',
            'miss1': 'value1',
            'miss2': 'value2',
            'hit4': 'value4',
            'hit5': 'value5',
        }
        assert self.cache_expiration.misses() == {'miss3'}

        self.cache_expiration.update(miss3='value3')
        assert self.cache_expiration == collections.OrderedDict((
            ('hit1', 'value1'),
            ('miss1', 'value1'),
            ('hit2', 'value2'),
            ('miss2', 'value2'),
            ('hit3', 'value3'),
            ('miss3', 'value3'),
            ('hit4', 'value4'),
            ('hit5', 'value5'),
        ))
        assert self.cache_expiration._cache == {
            'hit1': 'value1',
            'hit2': 'value2',
            'hit3': 'value3',
            'miss1': 'value1',
            'miss2': 'value2',
            'hit4': 'value4',
            'hit5': 'value5',
            'miss3': 'value3',
        }
        assert self.cache_expiration.misses() == set()

    def test_non_string_keys(self):
        assert self.cache_expiration == collections.OrderedDict((
            ('hit1', 'value1'),
            ('miss1', CachedOrderedDict._SENTINEL),
            ('hit2', 'value2'),
            ('miss2', CachedOrderedDict._SENTINEL),
            ('hit3', 'value3'),
            ('miss3', CachedOrderedDict._SENTINEL),
        ))

        self.cache_expiration[None] = None
        assert self.cache_expiration == collections.OrderedDict((
            ('hit1', 'value1'),
            ('miss1', CachedOrderedDict._SENTINEL),
            ('hit2', 'value2'),
            ('miss2', CachedOrderedDict._SENTINEL),
            ('hit3', 'value3'),
            ('miss3', CachedOrderedDict._SENTINEL),
            (None, None),
        ))

        self.cache_expiration[False] = False
        self.cache_expiration[True] = True
        assert self.cache_expiration == collections.OrderedDict((
            ('hit1', 'value1'),
            ('miss1', CachedOrderedDict._SENTINEL),
            ('hit2', 'value2'),
            ('miss2', CachedOrderedDict._SENTINEL),
            ('hit3', 'value3'),
            ('miss3', CachedOrderedDict._SENTINEL),
            (None, None),
            (False, False),
            (True, True),
        ))

        self.cache_expiration[0] = 0
        assert self.cache_expiration == collections.OrderedDict((
            ('hit1', 'value1'),
            ('miss1', CachedOrderedDict._SENTINEL),
            ('hit2', 'value2'),
            ('miss2', CachedOrderedDict._SENTINEL),
            ('hit3', 'value3'),
            ('miss3', CachedOrderedDict._SENTINEL),
            (None, None),
            (False, False),
            (True, True),
            (0, 0),
        ))

        self.cache_expiration[0.0] = 0.0
        assert self.cache_expiration == collections.OrderedDict((
            ('hit1', 'value1'),
            ('miss1', CachedOrderedDict._SENTINEL),
            ('hit2', 'value2'),
            ('miss2', CachedOrderedDict._SENTINEL),
            ('hit3', 'value3'),
            ('miss3', CachedOrderedDict._SENTINEL),
            (None, None),
            (False, False),
            (True, True),
            (0, 0),
            (0.0, 0.0),
        ))

    def test_no_keys(self):
        cache = CachedOrderedDict(redis_client=self.redis)
        assert cache == {}
        assert cache.misses() == set()

    def test_expiration(self):
        futures = []
        with concurrent.futures.ThreadPoolExecutor() as executor:
            for test_method in {
                    self._test_expiration,
                    self._test_no_expiration,
            }:
                future = executor.submit(test_method)
                futures.append(future)
        for future in futures:
            future.result()

    def _test_expiration(self):
        assert self.redis.ttl(self._KEY_EXPIRATION) == _DEFAULT_TIMEOUT
        time.sleep(1)
        assert self.redis.ttl(self._KEY_EXPIRATION) == _DEFAULT_TIMEOUT - 1
        self.cache_expiration['hit4'] = 'value4'
        assert self.redis.ttl(self._KEY_EXPIRATION) == _DEFAULT_TIMEOUT

    def _test_no_expiration(self):
        assert self.redis.ttl(self._KEY_NO_EXPIRATION) == -1
        time.sleep(1)
        assert self.redis.ttl(self._KEY_NO_EXPIRATION) == -1
        self.cache_no_expiration['hit4'] = 'value4'
        assert self.redis.ttl(self._KEY_NO_EXPIRATION) == -1
Esempio n. 6
0
class CachedOrderedDictTests(TestCase):
    _KEY = '{}cached-ordereddict'.format(TestCase._TEST_KEY_PREFIX)

    def setUp(self):
        super().setUp()

        # Populate the cache with three hits:
        cache = CachedOrderedDict(
            redis=self.redis,
            key=self._KEY,
            keys=('hit1', 'hit2', 'hit3'),
        )
        cache['hit1'] = 'value1'
        cache['hit2'] = 'value2'
        cache['hit3'] = 'value3'

        # Instantiate the cache again with the three hits and three misses:
        self.cache = CachedOrderedDict(
            redis=self.redis,
            key=self._KEY,
            keys=('hit1', 'miss1', 'hit2', 'miss2', 'hit3', 'miss3'),
        )

    def test_setitem(self):
        assert self.cache == collections.OrderedDict((
            ('hit1', 'value1'),
            ('miss1', CachedOrderedDict._SENTINEL),
            ('hit2', 'value2'),
            ('miss2', CachedOrderedDict._SENTINEL),
            ('hit3', 'value3'),
            ('miss3', CachedOrderedDict._SENTINEL),
        ))
        assert self.cache._cache == {
            'hit1': 'value1',
            'hit2': 'value2',
            'hit3': 'value3',
        }
        assert self.cache.misses() == {'miss1', 'miss2', 'miss3'}

        self.cache['hit4'] = 'value4'
        assert self.cache == collections.OrderedDict((
            ('hit1', 'value1'),
            ('miss1', CachedOrderedDict._SENTINEL),
            ('hit2', 'value2'),
            ('miss2', CachedOrderedDict._SENTINEL),
            ('hit3', 'value3'),
            ('miss3', CachedOrderedDict._SENTINEL),
            ('hit4', 'value4'),
        ))
        assert self.cache._cache == {
            'hit1': 'value1',
            'hit2': 'value2',
            'hit3': 'value3',
            'hit4': 'value4',
        }
        assert self.cache.misses() == {'miss1', 'miss2', 'miss3'}

        self.cache['miss1'] = 'value1'
        assert self.cache == collections.OrderedDict((
            ('hit1', 'value1'),
            ('miss1', 'value1'),
            ('hit2', 'value2'),
            ('miss2', CachedOrderedDict._SENTINEL),
            ('hit3', 'value3'),
            ('miss3', CachedOrderedDict._SENTINEL),
            ('hit4', 'value4'),
        ))
        assert self.cache._cache == {
            'hit1': 'value1',
            'hit2': 'value2',
            'hit3': 'value3',
            'hit4': 'value4',
            'miss1': 'value1',
        }
        assert self.cache.misses() == {'miss2', 'miss3'}

    def test_setdefault(self):
        'Ensure setdefault() sets the key iff the key does not exist.'
        for default in ('rajiv', 'raj'):
            with self.subTest(default=default):
                self.cache.setdefault('first', default=default)
                assert self.cache == collections.OrderedDict((
                    ('hit1', 'value1'),
                    ('miss1', CachedOrderedDict._SENTINEL),
                    ('hit2', 'value2'),
                    ('miss2', CachedOrderedDict._SENTINEL),
                    ('hit3', 'value3'),
                    ('miss3', CachedOrderedDict._SENTINEL),
                    ('first', 'rajiv'),
                ))
                assert self.cache._cache == {
                    'hit1': 'value1',
                    'hit2': 'value2',
                    'hit3': 'value3',
                    'first': 'rajiv',
                }
                assert self.cache.misses() == {'miss1', 'miss2', 'miss3'}

        self.cache.setdefault('miss1', default='value1')
        assert self.cache == collections.OrderedDict((
            ('hit1', 'value1'),
            ('miss1', 'value1'),
            ('hit2', 'value2'),
            ('miss2', CachedOrderedDict._SENTINEL),
            ('hit3', 'value3'),
            ('miss3', CachedOrderedDict._SENTINEL),
            ('first', 'rajiv'),
        ))
        assert self.cache._cache == {
            'hit1': 'value1',
            'hit2': 'value2',
            'hit3': 'value3',
            'first': 'rajiv',
            'miss1': 'value1',
        }
        assert self.cache.misses() == {'miss2', 'miss3'}

    def test_update(self):
        self.cache.update()
        assert self.cache == collections.OrderedDict((
            ('hit1', 'value1'),
            ('miss1', CachedOrderedDict._SENTINEL),
            ('hit2', 'value2'),
            ('miss2', CachedOrderedDict._SENTINEL),
            ('hit3', 'value3'),
            ('miss3', CachedOrderedDict._SENTINEL),
        ))
        assert self.cache._cache == {
            'hit1': 'value1',
            'hit2': 'value2',
            'hit3': 'value3',
        }
        assert self.cache.misses() == {'miss1', 'miss2', 'miss3'}

        self.cache.update((
            ('miss1', 'value1'),
            ('miss2', 'value2'),
            ('hit4', 'value4'),
            ('hit5', 'value5'),
        ))
        assert self.cache == collections.OrderedDict((
            ('hit1', 'value1'),
            ('miss1', 'value1'),
            ('hit2', 'value2'),
            ('miss2', 'value2'),
            ('hit3', 'value3'),
            ('miss3', CachedOrderedDict._SENTINEL),
            ('hit4', 'value4'),
            ('hit5', 'value5'),
        ))
        assert self.cache._cache == {
            'hit1': 'value1',
            'hit2': 'value2',
            'hit3': 'value3',
            'miss1': 'value1',
            'miss2': 'value2',
            'hit4': 'value4',
            'hit5': 'value5',
        }
        assert self.cache.misses() == {'miss3'}