def test_multi_tag_kwargs(): r = fakeredis.FakeStrictRedis() r.flushall() cache = RedisCache(conn=r) class A(object): @cache.cached(key_func=kwargs_key_generator, tags=["a:{a}", "b:{b}", "c"]) def add(self, a, b): return a + b + random.randint(1, 10000) add_result1 = A().add(a=5, b=6) add_result2 = A().add(a=5, b=7) add_result3 = A().add(a=1, b=8) add_result4 = A().add(a=1, b=8) add_result5 = A().add(a=2, b=9) A().add.invalidate_tag("a:5") A().add.invalidate_tag("b:8") assert add_result1 != A().add(a=5, b=6) assert add_result2 != A().add(a=5, b=7) assert add_result3 != A().add(a=1, b=8) assert add_result4 != A().add(a=1, b=8) assert add_result5 == A().add(a=2, b=9) A().add.invalidate_tag("c") assert add_result5 != A().add(a=2, b=9)
def test_tag_cache_function(): r = fakeredis.FakeStrictRedis() r.flushall() cache = RedisCache(conn=r) @cache.cached(tags=["add:{0}"]) def add(a, b): return a + b + random.randint(1, 10000) add_result1 = add(5, 6) add_result2 = add(5, 7) add_result3 = add(5, 8) add_result4 = add(6, 8) # cache 生效 assert add(5, 6) == add_result1 assert add(5, 7) == add_result2 assert add(5, 8) == add_result3 assert add(6, 8) == add_result4 # 精确失效 add.invalidate(5, 6) assert add(5, 6) != add_result1 assert add(5, 7) == add_result2 assert add(5, 8) == add_result3 assert add(6, 8) == add_result4 # 批量失效 add.invalidate_tag("add:5") assert add(5, 7) != add_result2 assert add(5, 8) != add_result3 assert add(6, 8) == add_result4
def test_batch_classmethod(): r = fakeredis.FakeStrictRedis() r.flushall() cache = RedisCache(conn=r) class AB(object): count = 0 @cache.batch() @classmethod def list(cls, *ids): result = [] for i in ids: result.append(i + random.randint(1, 100)) return result @cache.batch() @classmethod def list2(cls, *ids): cls.__name__ = 'ABC' result = [] for i in ids: result.append(i + random.randint(1, 100)) return result assert AB.list(3, 4) == AB.list(3, 4) == AB().list(3, 4) assert AB.list2(3, 4) != AB.list2(3, 4)
def test_tag_cache_kwargs_function(): r = fakeredis.FakeStrictRedis() r.flushall() cache = RedisCache(conn=r) @cache.cached(key_func=kwargs_key_generator, tags=["add:{a}"]) def add(a, b): return a + b + random.randint(1, 10000) add_result1 = add(a=5, b=6) add_result2 = add(a=5, b=7) add_result3 = add(a=5, b=8) add_result4 = add(a=6, b=8) # cache 生效 assert add(a=5, b=6) == add_result1 assert add(a=5, b=7) == add_result2 assert add(a=5, b=8) == add_result3 assert add(a=6, b=8) == add_result4 # 精确失效 add.invalidate(a=5, b=6) assert add(a=5, b=6) != add_result1 assert add(a=5, b=7) == add_result2 assert add(a=5, b=8) == add_result3 assert add(a=6, b=8) == add_result4 # 批量失效 add.invalidate_tag("add:5") assert add(a=5, b=7) != add_result2 assert add(a=5, b=8) != add_result3 assert add(a=6, b=8) == add_result4
def test_function_tag_kwargs(): r = fakeredis.FakeStrictRedis() r.flushall() cache = RedisCache(conn=r) @cache.cached( key_func=kwargs_key_generator, tags=[ lambda *args, **kwargs: "add:{0}".format(kwargs['a'] + kwargs['b']) ]) def add(a, b): return a + b + random.randint(1, 10000) add_result1 = add(a=5, b=6) add_result2 = add(a=4, b=7) add_result3 = add(a=5, b=8) # cache 生效 assert add(a=5, b=6) == add_result1 assert add(a=4, b=7) == add_result2 assert add(a=5, b=8) == add_result3 add.invalidate_tag("add:11") assert add(a=5, b=6) != add_result1 assert add(a=4, b=7) != add_result2 assert add(a=5, b=8) == add_result3
def test_batch_function(): r = fakeredis.FakeStrictRedis() r.flushall() cache = RedisCache(conn=r) class A(object): def __init__(self): self.count = 0 @cache.batch() def list(self, *ids): for _id in ids: self.count += 1 return [2 * _id for _id in ids] a = A() assert a.list(1, 2, 3, 4, 5) == [2, 4, 6, 8, 10] assert a.count == 5 assert a.list(1, 2) == [2, 4] assert a.count == 5 assert a.list(5, 6, 7) == [10, 12, 14] assert a.count == 7 assert a.list() == [] assert a.count == 7 a.list.invalidate(5, 7) assert a.list(1, 2, 5, 6, 7) == [2, 4, 10, 12, 14] assert a.count == 9
def test_global_tag(): r = fakeredis.FakeStrictRedis() r.flushall() cache = RedisCache(conn=r) @cache.cached(tags=["add:{0}"]) def add(a, b): return a + b + random.randint(1, 10000) @cache.cached(tags=["add:{0}"]) def add2(a, b): return a + b + random.randint(1, 10000) add_result1 = add(5, 6) add_result2 = add(5, 7) add2_result1 = add2(5, 6) # cache 生效 assert add(5, 6) == add_result1 assert add(5, 7) == add_result2 assert add2(5, 6) == add2_result1 # cache 失效,影响 add2 add.invalidate_tag("add:5") assert add(5, 6) != add_result1 assert add(5, 7) != add_result2 assert add2(5, 6) != add2_result1 # 使用 global invalidate tag add_result1 = add(5, 6) add_result2 = add(5, 7) add2_result1 = add2(5, 6) assert add(5, 6) == add_result1 assert add(5, 7) == add_result2 assert add2(5, 6) == add2_result1 cache.invalidate_tag("add:5") assert add(5, 6) != add_result1 assert add(5, 7) != add_result2 assert add2(5, 6) != add2_result1
def test_cache_staticmethod(): r = fakeredis.FakeStrictRedis() r.flushall() cache = RedisCache(conn=r) class AS(object): count = 0 @cache.cached() @staticmethod def add(a, b): return a + b + random.randint(1, 100) assert AS.add(3, 4) == AS.add(3, 4) == AS().add(3, 4)
def test_batch_staticmethod(): r = fakeredis.FakeStrictRedis() r.flushall() cache = RedisCache(conn=r) class ABS(object): count = 0 @cache.batch() @staticmethod def list(*ids): result = [] for i in ids: result.append(i + random.randint(1, 100)) return result assert ABS.list(3, 4) == ABS.list(3, 4) == ABS().list(3, 4)
def test_cache_method(): r = fakeredis.FakeStrictRedis() r.flushall() cache = RedisCache(conn=r) class A(object): @cache.cached(tags=["add:{0}"]) def add(self, a, b): return a + b + random.randint(1, 10000) @cache.cached(tags=["plus:{0}"]) @classmethod def plus(cls, a, b): return a + b + random.randint(1, 10000) plus_result1 = A.plus(5, 6) assert A.plus(5, 6) == plus_result1 add_result1 = A().add(5, 6) assert A().add(5, 6) == add_result1
def test_not_cache_None(): r = fakeredis.FakeStrictRedis() r.flushall() cache = RedisCache(conn=r) global i i = 0 @cache.cached(should_cache_fn=lambda value: value is not None) def incr(by): global i i += 1 return by incr(None) incr(None) assert i == 2 incr(1) incr(1) assert i == 3
def test_cache_None(): r = fakeredis.FakeStrictRedis() r.flushall() cache = RedisCache(conn=r) global i i = 0 @cache.cached() def incr(): global i i += 1 incr() assert i == 1 incr() assert i == 1 incr.invalidate() incr() assert i == 2
def test_cache_classmethod(): r = fakeredis.FakeStrictRedis() r.flushall() cache = RedisCache(conn=r) class AC(object): count = 0 @cache.cached() @classmethod def add(cls, a, b): return a + b + random.randint(1, 100) @cache.cached() @classmethod def plus(cls, a, b): cls.__name__ = 'AD' return a + b + random.randint(1, 100) assert AC.add(3, 4) == AC.add(3, 4) == AC().add(3, 4) assert AC.plus(3, 4) != AC.plus(3, 4)
def test_function_tag(): r = fakeredis.FakeStrictRedis() r.flushall() cache = RedisCache(conn=r) @cache.cached( tags=[lambda *args, **kwargs: "add:{0}".format(args[0] + args[1])]) def add(a, b): return a + b + random.randint(1, 10000) add_result1 = add(5, 6) add_result2 = add(4, 7) add_result3 = add(5, 8) # cache 生效 assert add(5, 6) == add_result1 assert add(4, 7) == add_result2 assert add(5, 8) == add_result3 add.invalidate_tag("add:11") assert add(5, 6) != add_result1 assert add(4, 7) != add_result2 assert add(5, 8) == add_result3
def test_cache_function(): r = fakeredis.FakeStrictRedis() r.flushall() cache = RedisCache(conn=r) class A: def __init__(self): self.count = 0 @cache.cached() def add(self, a, b): self.count += 1 return a + b + self.count class B: def __init__(self): self.count = 0 @cache.cached('tests.test_redis_cache.A.add|{0}-{1}') def add_explicit(self, a, b): self.count += 1 return a + b + self.count a = A() assert a.add(5, 6) == 12 assert a.add(5, 6) == 12 assert a.count == 1 a.add.invalidate(5, 6) assert a.add(5, 6) == 13 assert a.count == 2 assert a.add.refresh(5, 6) == 14 assert a.count == 3 assert a.add(5, 6) == 14 b = B() assert b.add_explicit(5, 6) == 14
def test_cache_kwargs(): r = fakeredis.FakeStrictRedis() r.flushall() cache = RedisCache(conn=r) class A(object): def __init__(self): self.count = 0 @cache.cached(key_func=kwargs_key_generator) def add(self, a, b): self.count += 1 return a + b + self.count class B(object): def __init__(self): self.count = 0 @cache.cached("tests.test_redis_cache.A.add|('a', {a}),('b', {b})") def add_explicit(self, a, b): self.count += 1 return a + b + self.count a = A() assert a.add(a=5, b=6) == 12 assert a.add(a=5, b=6) == 12 assert a.count == 1 a.add.invalidate(a=5, b=6) assert a.add(a=5, b=6) == 13 assert a.count == 2 assert a.add.refresh(a=5, b=6) == 14 assert a.count == 3 assert a.add(a=5, b=6) == 14 b = B() assert b.add_explicit(a=5, b=6) == 14
def test_multi_tag(): r = fakeredis.FakeStrictRedis() r.flushall() cache = RedisCache(conn=r) class A(object): @cache.cached(tags=["a:{0}", "b:{1}", "c"]) def add(self, a, b): return a + b + random.randint(1, 10000) add_result1 = A().add(5, 6) add_result2 = A().add(5, 7) add_result3 = A().add(1, 8) add_result4 = A().add(1, 8) add_result5 = A().add(2, 9) A().add.invalidate_tag("a:5") A().add.invalidate_tag("b:8") assert add_result1 != A().add(5, 6) assert add_result2 != A().add(5, 7) assert add_result3 != A().add(1, 8) assert add_result4 != A().add(1, 8) assert add_result5 == A().add(2, 9) A().add.invalidate_tag("c") assert add_result5 != A().add(2, 9)
import fakeredis from tache.tache import Tache from tache.utils import key_for_fn def mix_key_generator(namespace, fn, *args, **kwargs): key = key_for_fn(namespace, fn) arg_key = "-".join(map(str, args)) kwargs_key = ','.join(map(str, sorted(kwargs.items(), key=lambda x: x[0]))) return key + "|" + arg_key + "|" + kwargs_key class mTache(Tache): def __init__(self, backend_cls, default_key_generator=mix_key_generator, tag_prefix="tag:", **kwargs): super(mTache, self).__init__(backend_cls, default_key_generator=mix_key_generator, tag_prefix="tag:", **kwargs) self.backend = backend_cls(**kwargs) self.default_key_generator = default_key_generator self.tag_prefix = tag_prefix # RedisCache = functools.partial(mTache, RedisBackend) from tache import RedisCache redis_client = fakeredis.FakeStrictRedis() cache = RedisCache(conn=redis_client, format="PICKLE")