import pytest

from mock import patch

from data.cache import InMemoryDataModelCache, NoopDataModelCache, MemcachedModelCache
from data.cache.cache_key import CacheKey


class MockClient(object):
    def __init__(self, server, **kwargs):
        self.data = {}

    def get(self, key, default=None):
        return self.data.get(key, default)

    def set(self, key, value, expire=None):
        self.data[key] = value


@pytest.mark.parametrize("cache_type", [(NoopDataModelCache), (InMemoryDataModelCache),])
def test_caching(cache_type):
    key = CacheKey("foo", "60m")
    cache = cache_type()

    # Perform two retrievals, and make sure both return.
    assert cache.retrieve(key, lambda: {"a": 1234}) == {"a": 1234}
    assert cache.retrieve(key, lambda: {"a": 1234}) == {"a": 1234}


def test_memcache():
    key = CacheKey("foo", "60m")
    with patch("data.cache.impl.Client", MockClient):
        cache = MemcachedModelCache(("127.0.0.1", "-1"))
        assert cache.retrieve(key, lambda: {"a": 1234}) == {"a": 1234}
        assert cache.retrieve(key, lambda: {"a": 1234}) == {"a": 1234}


def test_memcache_should_cache():
    key = CacheKey("foo", None)

    def sc(value):
        return value["a"] != 1234

    with patch("data.cache.impl.Client", MockClient):
        cache = MemcachedModelCache(("127.0.0.1", "-1"))
        assert cache.retrieve(key, lambda: {"a": 1234}, should_cache=sc) == {"a": 1234}

        # Ensure not cached since it was `1234`.
        assert cache._get_client().get(key.key) is None

        # Ensure cached.
        assert cache.retrieve(key, lambda: {"a": 2345}, should_cache=sc) == {"a": 2345}
        assert cache._get_client().get(key.key) is not None
        assert cache.retrieve(key, lambda: {"a": 2345}, should_cache=sc) == {"a": 2345}

[((422, 509), 'pytest.mark.parametrize', 'pytest.mark.parametrize', (['"""cache_type"""', '[NoopDataModelCache, InMemoryDataModelCache]'], {}), "('cache_type', [NoopDataModelCache,\n    InMemoryDataModelCache])\n", (445, 509), False, 'import pytest\n'), ((551, 573), 'data.cache.cache_key.CacheKey', 'CacheKey', (['"""foo"""', '"""60m"""'], {}), "('foo', '60m')\n", (559, 573), False, 'from data.cache.cache_key import CacheKey\n'), ((824, 846), 'data.cache.cache_key.CacheKey', 'CacheKey', (['"""foo"""', '"""60m"""'], {}), "('foo', '60m')\n", (832, 846), False, 'from data.cache.cache_key import CacheKey\n'), ((1146, 1167), 'data.cache.cache_key.CacheKey', 'CacheKey', (['"""foo"""', 'None'], {}), "('foo', None)\n", (1154, 1167), False, 'from data.cache.cache_key import CacheKey\n'), ((856, 899), 'mock.patch', 'patch', (['"""data.cache.impl.Client"""', 'MockClient'], {}), "('data.cache.impl.Client', MockClient)\n", (861, 899), False, 'from mock import patch\n'), ((917, 957), 'data.cache.MemcachedModelCache', 'MemcachedModelCache', (["('127.0.0.1', '-1')"], {}), "(('127.0.0.1', '-1'))\n", (936, 957), False, 'from data.cache import InMemoryDataModelCache, NoopDataModelCache, MemcachedModelCache\n'), ((1232, 1275), 'mock.patch', 'patch', (['"""data.cache.impl.Client"""', 'MockClient'], {}), "('data.cache.impl.Client', MockClient)\n", (1237, 1275), False, 'from mock import patch\n'), ((1293, 1333), 'data.cache.MemcachedModelCache', 'MemcachedModelCache', (["('127.0.0.1', '-1')"], {}), "(('127.0.0.1', '-1'))\n", (1312, 1333), False, 'from data.cache import InMemoryDataModelCache, NoopDataModelCache, MemcachedModelCache\n')]