def test_change_timeout():
    f = Mock(__name__='f', return_value=SOME_VALUE)
    decorated = cache()(f)  # Cache FOREVER
    decorated()  # Warm cache
    f.return_value = None
    assert decorated() == SOME_VALUE
    assert cache(0)(f)() is None
def test_key_func():
    """
    Test that the provided key function is used.
    """
    f = Mock(__name__='f', return_value=None)
    g = Mock(__name__='g', return_value=None)
    key_func = lambda fn, *args, **kwargs: 'key'
    cache(key_func=key_func)(f)()
    cache(key_func=key_func)(g)()
    assert g.call_count == 0
def test_value():
    """
    Makes sure the cached value is correct.
    """
    f = Mock(__name__='f', return_value=SOME_VALUE)
    decorated = cache()(f)
    assert decorated() == SOME_VALUE
def test_caching():
    """
    Makes sure the cache is actually used.
    """
    f = Mock(__name__='f', return_value=None)
    decorated = cache()(f)
    decorated()
    decorated()
    assert f.call_count == 1
def test_invalidate_args():
    """
    Ensure that invalidate clears the cache for the provided args.
    """
    f = Mock(__name__='f', return_value=None)
    decorated = cache()(f)
    decorated(1)
    decorated.invalidate(1)
    decorated(1)
    assert f.call_count == 2
def test_invalidate():
    """
    Ensure that invalidate clears the cache.
    """
    f = Mock(__name__='f', return_value=None)
    decorated = cache()(f)
    decorated()
    decorated.invalidate()
    decorated()
    assert f.call_count == 2
def test_nocache():
    """
    Makes sure that the cache decorator doesn't cache when it has a 0
    timeout.
    """
    f = Mock(__name__='f', return_value=None)
    decorated = cache(timeout=0)(f)
    decorated()
    decorated()
    assert f.call_count == 2
def test_key_func_nocache():
    """
    Test that returning ``None`` from the key function bypasses the cache.
    """
    f = Mock(__name__='f', return_value=None)
    key_func = lambda fn, *args, **kwargs: None
    decorated = cache(key_func=key_func)(f)
    decorated(1)
    decorated(1)
    assert f.call_count == 2
def test_only_invalidate_args():
    """
    Ensure that invalidate doesn't clear the cache for other args.
    """
    f = Mock(__name__='f', return_value=None)
    decorated = cache()(f)
    decorated(1)
    decorated.invalidate(2)
    decorated(1)
    assert f.call_count == 1
Example #10
0
def test_gh_1():
    """Test that updating the TTL doesn't break backgrounding."""
    cache_backend = get_cache_backend('default')
    mocked = Mock(wraps=cache_backend)
    with patch('throttleandcache.decorators.get_cache_backend') as factory:
        factory.return_value = mocked

        f = Mock(__name__='f', return_value=None)
        key_func = lambda *args, **kwargs: 'key'

        # Prime the cache
        decorated = cache('5s', key_func=key_func, graceful=True)(f)
        decorated()

        ttl = mocked.set.call_args[0][2]
        assert ttl == settings.THROTTLEANDCACHE_MAX_TIMEOUT

        # Now change the cache TTL
        decorated = cache('6s', key_func=key_func, graceful=True)(f)
        decorated()

        ttl = mocked.set.call_args[0][2]
        assert ttl == settings.THROTTLEANDCACHE_MAX_TIMEOUT
def test_graceful():
    def f():
        if f.called:
            f.errored = True
            raise Exception
        f.called = True
        return SOME_VALUE

    f.called = False
    f.errored = False
    decorated = cache('0s', graceful=True)(f)
    decorated()  # Successful call
    value = decorated()  # Unsuccessful, but should be handled gracefully.
    assert f.errored
    assert value == SOME_VALUE
def test_background():
    """
    Test that caching in the background will actually call the celery task.
    """
    f = Mock(__name__='f', return_value=SOME_VALUE)
    with patch('throttleandcache.tasks._get_result.delay') as mocked:
        # Use a zero timeout to make sure that the value is expired for
        # subsequent calls.
        decorated = cache(timeout=0, background=True)(f)

        # With a cold cache, the call should be synchronous.
        decorated()
        assert f.call_count == 1
        assert mocked.call_count == 0

        # After that, the Celery task should be used.
        decorated()
        assert f.call_count == 1
        assert mocked.call_count == 1
def test_none():
    fn = cache()(lambda: None)
    assert fn() is None
        assert f.call_count == 1
        assert mocked.call_count == 1


THE_KEY = 'the_key'


def get_value():
    return None


def key_func(*args, **kwargs):
    return THE_KEY

original_get_value = get_value
get_value = cache('1 day', key_func=key_func, background=True)(get_value)


def test_background_serialization():
    """Make sure that the wrapped function is what's serialized."""

    # Prime the cache
    get_value()

    # Update the set_time to make sure we trigger a background process.
    val = cache_obj.get(THE_KEY)
    val.set_time = datetime(2000, 1, 1)
    cache_obj.set(THE_KEY, val)

    with patch('throttleandcache.tasks._get_result.delay') as mocked:
        get_value()