Implemented SheerkaOntology
This commit is contained in:
Vendored
+18
@@ -0,0 +1,18 @@
|
||||
class FakeSdp:
|
||||
def __init__(self, /, get_value=None, extend_exists=None, get_alt_value=None, populate=None):
|
||||
self.get_value = get_value
|
||||
self.extend_exists = extend_exists
|
||||
self.populate_function = populate
|
||||
self.get_alt_value = get_alt_value
|
||||
|
||||
def get(self, cache_name, key):
|
||||
return self.get_value(cache_name, key)
|
||||
|
||||
def exists(self, cache_name, key):
|
||||
return self.extend_exists(cache_name, key)
|
||||
|
||||
def alt_get(self, cache_name, key):
|
||||
return self.get_alt_value(cache_name, key)
|
||||
|
||||
def populate(self):
|
||||
return self.populate_function() if callable(self.populate_function) else self.populate_function
|
||||
|
||||
Vendored
+224
@@ -0,0 +1,224 @@
|
||||
import pytest
|
||||
from cache.Cache import Cache
|
||||
from cache.CacheManager import CacheManager, ConceptNotFound
|
||||
from cache.DictionaryCache import DictionaryCache
|
||||
from cache.ListCache import ListCache
|
||||
from cache.ListIfNeededCache import ListIfNeededCache
|
||||
from core.concept import Concept
|
||||
from core.global_symbols import NotFound
|
||||
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
from tests.cache import FakeSdp
|
||||
|
||||
|
||||
class TestCacheManager(TestUsingMemoryBasedSheerka):
|
||||
def test_i_do_not_push_into_sdp_when_cache_only_is_true(self):
|
||||
sheerka, context = self.init_test().unpack()
|
||||
|
||||
cache_manager = CacheManager(True)
|
||||
cache_manager.register_cache("test", Cache(), persist=True)
|
||||
cache_manager.put("test", "key", "value")
|
||||
|
||||
cache_manager.commit(context)
|
||||
assert not sheerka.om.current_cache_manager().sdp.exists("test", "key")
|
||||
|
||||
def test_i_do_not_get_value_from_sdp_when_cache_only_is_true(self):
|
||||
sheerka, context = self.init_test().unpack()
|
||||
|
||||
sdp = sheerka.om.get_sdp()
|
||||
with sdp.get_transaction(context.event) as transaction:
|
||||
transaction.add("test", "key", "value")
|
||||
|
||||
cache = Cache(default=lambda k: sdp.get("test", k))
|
||||
|
||||
cache_manager = CacheManager(True)
|
||||
cache_manager.register_cache("test", cache, persist=True)
|
||||
|
||||
assert cache_manager.get("test", "key") is NotFound
|
||||
|
||||
def test_i_do_not_get_value_from_inner_sdp_when_cache_only_is_true(self):
|
||||
sheerka, context = self.init_test().unpack()
|
||||
|
||||
cache_manager = CacheManager(True, sdp=sheerka.om.get_sdp("test"))
|
||||
cache = Cache(default=lambda _sdp, k: _sdp.get("test", k))
|
||||
cache_manager.register_cache("test", cache, persist=True)
|
||||
|
||||
with cache_manager.sdp.get_transaction(context.event) as transaction:
|
||||
transaction.add("test", "key", "value")
|
||||
|
||||
assert cache_manager.get("test", "key") is NotFound
|
||||
|
||||
def test_i_can_get_value_from_sdp_when_cache_only_is_false(self):
|
||||
sheerka, context = self.init_test().unpack()
|
||||
|
||||
sdp = sheerka.om.get_sdp()
|
||||
with sdp.get_transaction(context.event) as transaction:
|
||||
transaction.add("test", "key", "value")
|
||||
|
||||
cache_manager = CacheManager(False)
|
||||
cache = Cache(default=lambda k: sdp.get("test", k))
|
||||
cache_manager.register_cache("test", cache, persist=True)
|
||||
|
||||
assert cache_manager.get("test", "key") == "value"
|
||||
|
||||
def test_i_can_get_value_from_inner_sdp_when_cache_only_is_false(self):
|
||||
sheerka, context = self.init_test().unpack()
|
||||
|
||||
cache_manager = CacheManager(False, sdp=sheerka.om.get_sdp("test"))
|
||||
cache = Cache(default=lambda _sdp, k: _sdp.get("test", k))
|
||||
cache_manager.register_cache("test", cache, persist=True)
|
||||
|
||||
with cache_manager.sdp.get_transaction(context.event) as transaction:
|
||||
transaction.add("test", "key", "value")
|
||||
|
||||
assert cache_manager.get("test", "key") == "value"
|
||||
|
||||
def test_i_can_get_value_from_alt_sdp_when_cache_only_is_true(self):
|
||||
sheerka, context = self.init_test().unpack()
|
||||
|
||||
cache_manager = CacheManager(cache_only=True, sdp=sheerka.om.get_sdp("test"))
|
||||
cache_manager.register_cache("test", Cache().auto_configure("test"), persist=True)
|
||||
|
||||
alt_sdp = FakeSdp(get_alt_value=lambda cache_name, key: "value found !")
|
||||
assert cache_manager.get("test", "key", alt_sdp=alt_sdp) is "value found !"
|
||||
|
||||
def test_i_can_commit_simple_cache(self):
|
||||
sheerka, context = self.init_test().unpack()
|
||||
|
||||
cache_manager = CacheManager(False, sheerka.om.get_sdp("test"))
|
||||
cache_manager.register_cache("test", Cache(), persist=True)
|
||||
cache = cache_manager.caches["test"].cache
|
||||
|
||||
cache_manager.put("test", "key", "value")
|
||||
|
||||
cache_manager.commit(context)
|
||||
assert cache_manager.sdp.get("test", "key") == "value"
|
||||
|
||||
cache.update("key", "value", "key", "another_value")
|
||||
cache_manager.commit(context)
|
||||
assert cache_manager.sdp.get("test", "key") == "another_value"
|
||||
|
||||
cache.update("key", "another_value", "key2", "another_value")
|
||||
cache_manager.commit(context)
|
||||
assert cache_manager.sdp.get("test", "key") is NotFound
|
||||
assert cache_manager.sdp.get("test", "key2") == "another_value"
|
||||
|
||||
# sanity check
|
||||
# sdp 'test' has value, but sdp '__default__' does not
|
||||
assert cache_manager.sdp.name == "test"
|
||||
assert cache_manager.sdp.state.data == {'test': {'key2': 'another_value'}}
|
||||
|
||||
default_sdp = sheerka.om.ontologies[-1].cache_manager.sdp
|
||||
assert default_sdp.name == "__default__"
|
||||
assert "test" not in default_sdp.state.data
|
||||
|
||||
def test_i_can_commit_list_cache(self):
|
||||
sheerka, context = self.init_test().unpack()
|
||||
|
||||
cache_manager = CacheManager(False, sheerka.om.get_sdp("test"))
|
||||
cache_manager.register_cache("test", ListCache(), persist=True)
|
||||
cache = cache_manager.caches["test"].cache
|
||||
|
||||
cache.put("key", "value")
|
||||
cache_manager.commit(context)
|
||||
assert cache_manager.sdp.get("test", "key") == ["value"]
|
||||
|
||||
cache.put("key", "value2")
|
||||
cache_manager.commit(context)
|
||||
assert cache_manager.sdp.get("test", "key") == ["value", "value2"]
|
||||
|
||||
cache.update("key", "value2", "key2", "value2")
|
||||
cache_manager.commit(context)
|
||||
assert cache_manager.sdp.get("test", "key") == ["value"]
|
||||
assert cache_manager.sdp.get("test", "key2") == ["value2"]
|
||||
|
||||
cache.update("key2", "value2", "key3", "value2")
|
||||
cache_manager.commit(context)
|
||||
assert cache_manager.sdp.get("test", "key") == ["value"]
|
||||
assert cache_manager.sdp.get("test", "key2") is NotFound
|
||||
assert cache_manager.sdp.get("test", "key3") == ["value2"]
|
||||
|
||||
def test_i_can_commit_dictionary_cache(self):
|
||||
sheerka, context = self.init_test().unpack()
|
||||
|
||||
cache_manager = CacheManager(False, sheerka.om.get_sdp("test"))
|
||||
cache_manager.register_cache("test", DictionaryCache(), persist=True)
|
||||
cache = cache_manager.caches["test"].cache
|
||||
|
||||
cache.put(False, {"key": "value", "key2": "value2"})
|
||||
cache_manager.commit(context)
|
||||
assert cache_manager.sdp.get("test") == {"key": "value", "key2": "value2"}
|
||||
assert cache_manager.sdp.get("test", "key") == "value"
|
||||
|
||||
cache.put(False, {"key": "value", "key2": "value2", "key3": "value3"})
|
||||
cache_manager.commit(context)
|
||||
assert cache_manager.sdp.get("test") == {"key": "value", "key2": "value2", "key3": "value3"}
|
||||
|
||||
def test_i_can_get_value_from_sdp_when_dictionary_cache(self):
|
||||
sheerka, context = self.init_test().unpack()
|
||||
|
||||
cache_manager = CacheManager(False, sheerka.om.get_sdp("cache_name"))
|
||||
cache_manager.register_cache("cache_name", DictionaryCache().auto_configure("cache_name"), persist=True)
|
||||
|
||||
with cache_manager.sdp.get_transaction(context.event) as transaction:
|
||||
transaction.add("cache_name", None, {"key1": "value1", "key2": "value2"})
|
||||
|
||||
assert cache_manager.get("cache_name", "key3") is NotFound
|
||||
|
||||
# make sure that the first call retrieves the whole remote repository
|
||||
assert cache_manager.caches["cache_name"].cache.copy() == {"key1": "value1", "key2": "value2"}
|
||||
|
||||
assert cache_manager.get("cache_name", "key1") == "value1"
|
||||
assert cache_manager.get("cache_name", "key2") == "value2"
|
||||
|
||||
def test_i_can_remove_a_concept_from_concepts_caches(self):
|
||||
cache_manager = CacheManager(True)
|
||||
cache_manager.register_concept_cache("id", Cache(), lambda c: c.id, True)
|
||||
cache_manager.register_concept_cache("key", ListIfNeededCache(), lambda c: c.key, True)
|
||||
|
||||
sheerka, context, one, two, three, two_bis = self.init_concepts("one", "two", "three", Concept("two", body="2"))
|
||||
|
||||
for concept in [one, two, three, two_bis]:
|
||||
cache_manager.add_concept(concept)
|
||||
|
||||
# sanity check before removing
|
||||
cache_def = cache_manager.caches["id"]
|
||||
assert cache_def.cache.copy() == {one.id: one, two.id: two, three.id: three, two_bis.id: two_bis}
|
||||
cache_def = cache_manager.caches["key"]
|
||||
assert cache_def.cache.copy() == {one.key: one, two.key: [two, two_bis], three.key: three}
|
||||
|
||||
for cache_name in cache_manager.concept_caches:
|
||||
cache_manager.caches[cache_name].cache.reset_events()
|
||||
|
||||
cache_manager.remove_concept(sheerka.new(("two", two_bis.id)))
|
||||
|
||||
cache_def = cache_manager.caches["id"]
|
||||
assert cache_def.cache.copy() == {one.id: one, two.id: two, three.id: three}
|
||||
assert cache_def.cache.to_remove == {two_bis.id}
|
||||
assert cache_def.cache.to_add == set()
|
||||
assert len(cache_def.cache) == 3
|
||||
|
||||
cache_def = cache_manager.caches["key"]
|
||||
assert cache_def.cache.copy() == {one.key: one, two.key: two, three.key: three}
|
||||
assert cache_def.cache.to_remove == set()
|
||||
assert cache_def.cache.to_add == {"two"}
|
||||
assert len(cache_def.cache) == 3
|
||||
|
||||
def test_i_cannot_remove_a_concept_that_does_not_exists(self):
|
||||
cache_manager = CacheManager(True)
|
||||
cache_manager.register_concept_cache("id", Cache(), lambda c: c.id, True)
|
||||
cache_manager.register_concept_cache("key", ListIfNeededCache(), lambda c: c.key, True)
|
||||
|
||||
with pytest.raises(ConceptNotFound) as ex:
|
||||
cache_manager.remove_concept(Concept("foo", id="1001"))
|
||||
|
||||
assert ex.value.concept == Concept("foo", id="1001")
|
||||
|
||||
def test_i_can_configure_a_cache_with_internal_sdp(self):
|
||||
cache_manager = CacheManager(cache_only=False,
|
||||
sdp=FakeSdp(get_value=lambda cache_name, key: key + "_not_found"))
|
||||
cache = Cache(default=lambda sdp, key: sdp.get("cache_name", key))
|
||||
cache_manager.register_cache("test", cache)
|
||||
|
||||
assert cache.get("key") == "key_not_found"
|
||||
assert cache_manager.get("test", "key") == "key_not_found"
|
||||
Vendored
+162
@@ -0,0 +1,162 @@
|
||||
import pytest
|
||||
|
||||
from cache.DictionaryCache import DictionaryCache
|
||||
from core.global_symbols import NotFound
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
from tests.cache import FakeSdp
|
||||
|
||||
|
||||
class TestDictionaryCache(TestUsingMemoryBasedSheerka):
|
||||
def test_i_can_put_and_retrieve_value_from_dictionary_cache(self):
|
||||
cache = DictionaryCache()
|
||||
|
||||
# key must be None
|
||||
with pytest.raises(KeyError):
|
||||
cache.put("key", None)
|
||||
|
||||
# value must be a dictionary
|
||||
with pytest.raises(ValueError):
|
||||
cache.put(True, "value")
|
||||
|
||||
entry = {"key": "value", "key2": ["value21", "value22"]}
|
||||
cache.put(False, entry)
|
||||
assert len(cache) == 3
|
||||
assert id(cache._cache) == id(entry)
|
||||
assert cache.get("key") == "value"
|
||||
assert cache.get("key2") == ["value21", "value22"]
|
||||
|
||||
# I can append values
|
||||
cache.put(True, {"key": "another_value", "key3": "value3"})
|
||||
assert len(cache) == 4
|
||||
assert cache.get("key") == "another_value"
|
||||
assert cache.get("key2") == ["value21", "value22"]
|
||||
assert cache.get("key3") == "value3"
|
||||
|
||||
# I can reset
|
||||
entry = {"key": "value", "key2": ["value21", "value22"]}
|
||||
cache.put(False, entry)
|
||||
assert len(cache) == 3
|
||||
assert id(cache._cache) == id(entry)
|
||||
assert cache.get("key") == "value"
|
||||
assert cache.get("key2") == ["value21", "value22"]
|
||||
|
||||
assert cache.copy() == {'key': 'value', 'key2': ['value21', 'value22']}
|
||||
|
||||
@pytest.mark.parametrize("key", [
|
||||
None,
|
||||
"something"
|
||||
])
|
||||
def test_keys_have_constraints_when_dictionary_cache(self, key):
|
||||
cache = DictionaryCache()
|
||||
with pytest.raises(KeyError):
|
||||
cache.put(key, None)
|
||||
|
||||
def test_i_can_sync_with_remote_repository(self):
|
||||
cache = DictionaryCache()
|
||||
|
||||
entry = {"key": "value", "key2": ["value21", "value22"]}
|
||||
cache.put(False, entry)
|
||||
|
||||
assert len(cache) == 3
|
||||
assert id(cache._cache) == id(entry)
|
||||
assert cache.get("key") == "value"
|
||||
assert cache.get("key2") == ["value21", "value22"]
|
||||
|
||||
def test_i_can_get_a_value_that_does_not_exist_without_compromising_the_cache(self):
|
||||
cache = DictionaryCache()
|
||||
cache.put(False, {"key": "value"})
|
||||
|
||||
assert cache.get("key2") is NotFound
|
||||
assert cache.copy() == {"key": "value"}
|
||||
|
||||
@pytest.mark.parametrize("value", [
|
||||
None,
|
||||
"something"
|
||||
])
|
||||
def test_values_have_constraints_when_dictionary_cache(self, value):
|
||||
cache = DictionaryCache()
|
||||
with pytest.raises(ValueError):
|
||||
cache.put(True, value)
|
||||
|
||||
def test_i_can_append_to_a_dictionary_cache_even_if_it_is_new(self):
|
||||
cache = DictionaryCache()
|
||||
|
||||
entry = {"key": "value", "key2": ["value21", "value22"]}
|
||||
cache.put(True, entry)
|
||||
assert len(cache) == 3
|
||||
assert id(cache._cache) != id(entry)
|
||||
assert cache.get("key") == "value"
|
||||
assert cache.get("key2") == ["value21", "value22"]
|
||||
|
||||
def test_exists_in_dictionary_cache(self):
|
||||
cache = DictionaryCache()
|
||||
assert not cache.exists("key")
|
||||
|
||||
cache.put(True, {"key": "value"})
|
||||
assert cache.exists("key")
|
||||
|
||||
def test_default_for_dictionary_cache(self):
|
||||
cache = DictionaryCache(default={"key": "value", "key2": "value2"})
|
||||
|
||||
# cache is fully set when the value is found
|
||||
assert cache.get("key") == "value"
|
||||
assert cache.copy() == {"key": "value", "key2": "value2"}
|
||||
|
||||
# cache is fully set when the value is not found
|
||||
cache.test_only_reset()
|
||||
assert cache.get("key3") is NotFound
|
||||
assert cache.copy() == {"key": "value", "key2": "value2"}
|
||||
|
||||
# cache is not corrupted when value is found
|
||||
cache.put(True, {"key3": "value3", "key4": "value4"})
|
||||
assert cache.get("key3") == "value3"
|
||||
assert cache.copy() == {"key": "value", "key2": "value2", "key3": "value3", "key4": "value4"}
|
||||
|
||||
# cache is not corrupted when value is not found
|
||||
cache._cache["key"] = "another value" # operation that is normally not possible
|
||||
assert cache.get("key5") is NotFound
|
||||
assert cache.copy() == {"key": "value", "key2": "value2", "key3": "value3", "key4": "value4"}
|
||||
|
||||
def test_default_callable_for_dictionary_cache(self):
|
||||
cache = DictionaryCache(default=lambda k: {"key": "value", "key2": "value2"})
|
||||
|
||||
assert cache.get("key") == "value"
|
||||
assert "key2" in cache
|
||||
assert len(cache) == 2
|
||||
|
||||
cache.clear()
|
||||
assert cache.get("key3") is NotFound
|
||||
assert len(cache) == 2
|
||||
assert "key" in cache
|
||||
assert "key2" in cache
|
||||
|
||||
def test_default_callable_with_internal_sdp_for_dictionary_cache(self):
|
||||
cache = DictionaryCache(default=lambda sdp, key: sdp.get("cache_name", key),
|
||||
sdp=FakeSdp(lambda entry, k: {"key": "value", "key2": "value2"}))
|
||||
|
||||
assert cache.get("key") == "value"
|
||||
assert "key2" in cache
|
||||
assert len(cache) == 2
|
||||
|
||||
cache.clear()
|
||||
assert cache.get("key3") is NotFound
|
||||
assert len(cache) == 2
|
||||
assert "key" in cache
|
||||
assert "key2" in cache
|
||||
|
||||
def test_dictionary_cache_cannot_be_null(self):
|
||||
cache = DictionaryCache(default=lambda k: NotFound)
|
||||
assert cache.get("key") is NotFound
|
||||
assert cache._cache == {}
|
||||
|
||||
cache = DictionaryCache(default=NotFound)
|
||||
assert cache.get("key") is NotFound
|
||||
assert cache._cache == {}
|
||||
|
||||
cache = DictionaryCache(default=lambda k: None)
|
||||
assert cache.get("key") is NotFound
|
||||
assert cache._cache == {}
|
||||
|
||||
cache = DictionaryCache(default=None)
|
||||
assert cache.get("key") is NotFound
|
||||
assert cache._cache == {}
|
||||
Vendored
+13
-1
@@ -1,4 +1,5 @@
|
||||
from cache.FastCache import FastCache
|
||||
from core.global_symbols import NotFound
|
||||
|
||||
|
||||
def test_i_can_put_an_retrieve_values():
|
||||
@@ -47,7 +48,7 @@ def test_i_can_put_the_same_key_several_times():
|
||||
|
||||
def test_none_is_returned_when_not_found():
|
||||
cache = FastCache()
|
||||
assert cache.get("foo") is None
|
||||
assert cache.get("foo") is NotFound
|
||||
|
||||
|
||||
def test_i_can_evict_by_key():
|
||||
@@ -65,3 +66,14 @@ def test_i_can_evict_by_key():
|
||||
"to_keep3": "to_keep_value3"}
|
||||
|
||||
assert cache.lru == ["to_keep1", "to_keep2", "to_keep3"]
|
||||
|
||||
|
||||
def test_i_can_get_default_value():
|
||||
cache = FastCache(max_size=3, default=lambda key: key + 1)
|
||||
|
||||
assert cache.get(1) == 2
|
||||
assert cache.get(2) == 3
|
||||
assert cache.get(3) == 4
|
||||
assert cache.get(4) == 5
|
||||
|
||||
assert cache.cache == {2: 3, 3: 4, 4: 5} # only 3 values
|
||||
|
||||
Vendored
+84
@@ -0,0 +1,84 @@
|
||||
from cache.IncCache import IncCache
|
||||
from core.global_symbols import NotFound, Removed
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
from tests.cache import FakeSdp
|
||||
|
||||
|
||||
class FakeIncSdp:
|
||||
def __init__(self, init_value1, init_value2):
|
||||
self.internals = [IncCache(), IncCache()]
|
||||
if init_value1:
|
||||
self.internals[0].put("key", init_value1)
|
||||
|
||||
if init_value2:
|
||||
self.internals[1].put("key", init_value2)
|
||||
|
||||
def alt_get(self, cache_name, key):
|
||||
for cache in self.internals:
|
||||
value = cache.alt_get(key)
|
||||
if value is not NotFound:
|
||||
return value
|
||||
|
||||
return NotFound
|
||||
|
||||
|
||||
class TestIncCache(TestUsingMemoryBasedSheerka):
|
||||
def test_i_can_put_and_retrieve_values_from_inc_cache(self):
|
||||
cache = IncCache()
|
||||
|
||||
assert cache.get("key") == 1
|
||||
assert cache.get("key") == 2
|
||||
assert cache.get("key") == 3
|
||||
assert cache.get("key2") == 1
|
||||
assert cache.get("key2") == 2
|
||||
|
||||
cache.put("key", 100)
|
||||
assert cache.get("key") == 101
|
||||
|
||||
assert cache.copy() == {'key': 101, 'key2': 2}
|
||||
|
||||
def test_i_can_alt_get(self):
|
||||
cache = IncCache()
|
||||
|
||||
assert cache.get("key") == 1
|
||||
assert cache.get("key") == 2
|
||||
assert cache.alt_get("key") == 2
|
||||
assert cache.alt_get("key") == 2
|
||||
assert cache.get("key") == 3
|
||||
|
||||
def test_current_cache_takes_precedence_over_alt_sdp(self):
|
||||
cache = IncCache(sdp=FakeSdp(get_value=lambda cache_name, key: NotFound)).auto_configure("cache_name")
|
||||
|
||||
assert cache.get("key") == 1
|
||||
|
||||
alt_sdp = FakeSdp(get_alt_value=lambda cache_name, key: 10)
|
||||
assert cache.get("key", alt_sdp=alt_sdp) == 2
|
||||
|
||||
def test_remote_repository_takes_precedence_over_alt_sdp(self):
|
||||
cache = IncCache(sdp=FakeSdp(get_value=lambda cache_name, key: 5)).auto_configure("cache_name")
|
||||
|
||||
alt_sdp = FakeSdp(get_alt_value=lambda cache_name, key: 10)
|
||||
assert cache.get("key", alt_sdp=alt_sdp) == 6
|
||||
assert cache.get("key", alt_sdp=alt_sdp) == 7 # then we use the value from the cache
|
||||
|
||||
def test_i_can_take_value_from_alt_sdp(self):
|
||||
cache = IncCache(sdp=FakeSdp(get_value=lambda cache_name, key: NotFound)).auto_configure("cache_name")
|
||||
|
||||
alt_sdp = FakeIncSdp(10, NotFound)
|
||||
assert cache.get("key", alt_sdp=alt_sdp) == 11
|
||||
assert cache.get("key", alt_sdp=alt_sdp) == 12 # then we use the value from the cache
|
||||
|
||||
def test_i_can_get_when_alt_sdp_and_cache_is_cleared(self):
|
||||
cache = IncCache(sdp=FakeSdp(get_value=lambda cache_name, key: NotFound)).auto_configure("cache_name")
|
||||
cache.clear()
|
||||
|
||||
alt_sdp = FakeIncSdp(10, NotFound)
|
||||
assert cache.get("key", alt_sdp=alt_sdp) == 1
|
||||
assert cache.get("key", alt_sdp=alt_sdp) == 2 # then we use the value from the cache
|
||||
|
||||
def test_i_can_manage_when_the_value_from_alt_sdp_is_removed(self):
|
||||
cache = IncCache(sdp=FakeSdp(get_value=lambda cache_name, key: NotFound)).auto_configure("cache_name")
|
||||
|
||||
alt_sdp = FakeIncSdp(Removed, 10)
|
||||
assert cache.get("key", alt_sdp=alt_sdp) == 1
|
||||
assert cache.get("key", alt_sdp=alt_sdp) == 2 # then we use the value from the cache
|
||||
Vendored
+274
@@ -0,0 +1,274 @@
|
||||
import pytest
|
||||
|
||||
from cache.ListCache import ListCache
|
||||
from core.global_symbols import NotFound, Removed
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
from tests.cache import FakeSdp
|
||||
|
||||
|
||||
class TestListIfNeededCache(TestUsingMemoryBasedSheerka):
|
||||
def test_i_can_put_and_retrieve_value_from_list_cache(self):
|
||||
cache = ListCache()
|
||||
|
||||
cache.put("key", "value")
|
||||
assert cache.get("key") == ["value"]
|
||||
assert len(cache) == 1
|
||||
|
||||
cache.put("key", "value2") # we can append to this list
|
||||
assert cache.get("key") == ["value", "value2"]
|
||||
assert len(cache) == 2
|
||||
|
||||
cache.put("key2", "value")
|
||||
assert cache.get("key2") == ["value"]
|
||||
assert len(cache) == 3
|
||||
|
||||
# duplicates are allowed
|
||||
cache.put("key", "value")
|
||||
assert cache.get("key") == ["value", "value2", "value"]
|
||||
assert len(cache) == 4
|
||||
|
||||
assert cache.copy() == {'key': ['value', 'value2', 'value'], 'key2': ['value']}
|
||||
|
||||
def test_i_can_put_in_list_cache_when_alt_sdp_returns_values(self):
|
||||
cache = ListCache(sdp=FakeSdp(get_value=lambda cache_name, key: NotFound)).auto_configure("cache_name")
|
||||
|
||||
cache.put("key", "value2", alt_sdp=FakeSdp(get_alt_value=lambda cache_name, key: ["value1"]))
|
||||
assert cache.get("key") == ["value1", "value2"]
|
||||
|
||||
cache.put("key3", "value1", alt_sdp=FakeSdp(get_alt_value=lambda cache_name, key: Removed))
|
||||
assert cache.get("key3") == ["value1"]
|
||||
|
||||
def test_i_can_put_in_list_cache_when_alt_sdp_returns_values_and_cache_is_cleared(self):
|
||||
cache = ListCache(sdp=FakeSdp(get_value=lambda cache_name, key: NotFound)).auto_configure("cache_name")
|
||||
cache.clear()
|
||||
|
||||
cache.put("key", "value2", alt_sdp=FakeSdp(get_alt_value=lambda cache_name, key: ["value1"]))
|
||||
assert cache.get("key") == ["value2"]
|
||||
|
||||
cache.put("key3", "value1", alt_sdp=FakeSdp(get_alt_value=lambda cache_name, key: Removed))
|
||||
assert cache.get("key3") == ["value1"]
|
||||
|
||||
def test_current_cache_take_precedence_over_alt_sdp_when_i_put_data_in_list_cache(self):
|
||||
cache = ListCache(sdp=FakeSdp(get_value=lambda cache_name, key: NotFound)).auto_configure("cache_name")
|
||||
|
||||
cache.put("key", "value1")
|
||||
cache.put("key", "value2", alt_sdp=FakeSdp(get_alt_value=lambda cache_name, key: "xxx"))
|
||||
assert cache.get("key") == ["value1", "value2"]
|
||||
|
||||
def test_current_sdp_take_precedence_over_alt_sdp_when_i_put_data_in_list_cache(self):
|
||||
cache = ListCache(sdp=FakeSdp(get_value=lambda cache_name, key: ["value1"])).auto_configure("cache_name")
|
||||
|
||||
cache.put("key", "value2", alt_sdp=FakeSdp(get_alt_value=lambda cache_name, key: "xxx"))
|
||||
assert cache.get("key") == ["value1", "value2"]
|
||||
|
||||
def test_i_can_update_from_list_cache(self):
|
||||
cache = ListCache()
|
||||
|
||||
cache.put("key", "value")
|
||||
cache.put("key", "value2")
|
||||
cache.put("key", "value")
|
||||
cache.update("key", "value", "key", "another value")
|
||||
|
||||
assert len(cache._cache) == 1
|
||||
assert len(cache) == 3
|
||||
assert cache.get("key") == ["another value", "value2", "value"] # only the first one is affected
|
||||
|
||||
cache.update("key", "value2", "key2", "value2")
|
||||
assert len(cache._cache) == 2
|
||||
assert len(cache) == 3
|
||||
assert cache.get("key") == ["another value", "value"]
|
||||
assert cache.get("key2") == ["value2"]
|
||||
|
||||
cache.update("key2", "value2", "key3", "value2")
|
||||
assert len(cache._cache) == 2
|
||||
assert len(cache) == 3
|
||||
assert cache.get("key") == ["another value", "value"]
|
||||
assert cache.get("key3") == ["value2"]
|
||||
assert cache.get("key2") is NotFound
|
||||
|
||||
with pytest.raises(KeyError):
|
||||
cache.update("wrong key", "value", "key", "value")
|
||||
|
||||
def test_i_can_update_when_alt_sdp_from_cache_keys_are_the_same(self):
|
||||
cache = ListCache(default=lambda sdp, key: sdp.get("cache_name", key),
|
||||
extend_exists=lambda sdp, key: sdp.exists("cache_name", key),
|
||||
sdp=FakeSdp(get_value=lambda cache_name, key: NotFound))
|
||||
|
||||
cache.put("key", "value")
|
||||
cache.update("key", "value", "key", "new_value", FakeSdp(extend_exists=lambda cache_name, key: True))
|
||||
|
||||
assert cache.get("key") == ["new_value"]
|
||||
|
||||
def test_i_can_update_when_alt_sdp_from_cache_keys_are_the_same_but_nothing_in_cache(self):
|
||||
# There is nothing in cache or remote repository.
|
||||
# We must ust the value from alt_sdp
|
||||
cache = ListCache(sdp=FakeSdp(get_value=lambda cache_name, key: NotFound)).auto_configure("cache_name")
|
||||
|
||||
previous_value = ["old_1", "old_2", "value"]
|
||||
alt_sdp = FakeSdp(extend_exists=lambda cache_name, key: True,
|
||||
get_alt_value=lambda cache_name, key: previous_value)
|
||||
cache.update("key", "value", "key", "new_value", alt_sdp=alt_sdp)
|
||||
assert cache.get("key") == ["old_1", "old_2", "new_value"]
|
||||
assert previous_value == ["old_1", "old_2", "value"]
|
||||
|
||||
def test_i_can_update_when_alt_sdp_from_cache_keys_are_different(self):
|
||||
# keys are different
|
||||
# make sure that current cache take precedence over alt_sdp
|
||||
# In this test, the values from alt_sdp are never used
|
||||
cache = ListCache(sdp=FakeSdp(get_value=lambda cache_name, key: NotFound)).auto_configure("cache_name")
|
||||
|
||||
alt_sdp = FakeSdp(extend_exists=lambda cache_name, key: key == "key1",
|
||||
get_alt_value=lambda cache_name, key: ["xxx1"] if key == "key1" else NotFound)
|
||||
|
||||
# one values in 'key1'
|
||||
cache.put("key1", "old_1")
|
||||
|
||||
cache.update("key1", "old_1", "key2", "new_value", alt_sdp=alt_sdp)
|
||||
assert cache.get("key1") == Removed
|
||||
assert cache.get("key2") == ["new_value"]
|
||||
assert cache.to_add == {"key2", "key1"}
|
||||
assert cache.to_remove == set()
|
||||
|
||||
# Multiple values in 'key1'
|
||||
cache.clear()
|
||||
cache.put("key1", "old_1")
|
||||
cache.put("key1", "old_2")
|
||||
|
||||
cache.update("key1", "old_1", "key2", "new_value", alt_sdp=alt_sdp)
|
||||
assert cache.get("key1") == ["old_2"]
|
||||
assert cache.get("key2") == ["new_value"]
|
||||
assert cache.to_add == {"key2", "key1"}
|
||||
assert cache.to_remove == set()
|
||||
|
||||
def test_i_can_update_when_alt_sdp_from_repository_keys_are_different(self):
|
||||
# keys are different
|
||||
# make sure that current repo take precedence over alt_sdp
|
||||
remote = FakeSdp(get_value=lambda cache_name, key: ["old_1"] if key == "key1" else NotFound)
|
||||
cache = ListCache(sdp=remote).auto_configure("cache_name")
|
||||
|
||||
alt_sdp = FakeSdp(extend_exists=lambda cache_name, key: key == "key1",
|
||||
get_alt_value=lambda cache_name, key: ["xxx1"] if key == "key1" else NotFound)
|
||||
|
||||
cache.update("key1", "old_1", "key2", "new_value", alt_sdp=alt_sdp)
|
||||
assert cache.get("key1") == Removed
|
||||
assert cache.get("key2") == ["new_value"]
|
||||
assert cache.to_add == {"key2", "key1"}
|
||||
assert cache.to_remove == set()
|
||||
|
||||
# Multiple values in 'key1'
|
||||
remote = FakeSdp(get_value=lambda cache_name, key: ["old_1", "old_2"] if key == "key1" else NotFound)
|
||||
cache = ListCache(sdp=remote).auto_configure("cache_name")
|
||||
cache.update("key1", "old_1", "key2", "new_value", alt_sdp=alt_sdp)
|
||||
assert cache.get("key1") == ["old_2"]
|
||||
assert cache.get("key2") == ["new_value"]
|
||||
assert cache.to_add == {"key2", "key1"}
|
||||
assert cache.to_remove == set()
|
||||
|
||||
def test_i_can_update_when_alt_sdp_from_alt_sdp_keys_are_different_one_value(self):
|
||||
# keys are different
|
||||
# No value found in cache or remote repository,
|
||||
# Will use values from alt_sdp
|
||||
# The old key is the same, so it has to be marked as Removed
|
||||
cache = ListCache(sdp=FakeSdp(get_value=lambda cache_name, key: NotFound)).auto_configure("cache_name")
|
||||
|
||||
# one values in 'key1'
|
||||
alt_sdp = FakeSdp(extend_exists=lambda cache_name, key: key == "key1",
|
||||
get_alt_value=lambda cache_name, key: ["old_1"] if key == "key1" else NotFound)
|
||||
|
||||
cache.update("key1", "old_1", "key2", "new_value", alt_sdp=alt_sdp)
|
||||
assert cache.get("key1") == Removed
|
||||
assert cache.get("key2") == ["new_value"]
|
||||
assert cache.to_add == {"key2", "key1"}
|
||||
assert cache.to_remove == set()
|
||||
|
||||
# Multiple values in 'key1'
|
||||
cache.test_only_reset()
|
||||
old_values = ["old_1", "old_2"]
|
||||
alt_sdp = FakeSdp(extend_exists=lambda cache_name, key: key == "key1",
|
||||
get_alt_value=lambda cache_name, key: old_values if key == "key1" else NotFound)
|
||||
cache.update("key1", "old_1", "key2", "new_value", alt_sdp=alt_sdp)
|
||||
assert cache.get("key1") == ["old_2"]
|
||||
assert cache.get("key2") == ["new_value"]
|
||||
assert cache.to_add == {"key2", "key1"}
|
||||
assert cache.to_remove == set()
|
||||
assert old_values == ["old_1", "old_2"] # not modified
|
||||
|
||||
def test_i_can_update_when_alt_sdp_cache_take_precedence_for_destination_key(self):
|
||||
# If a value exists in destination key, either in local cache or remote repository
|
||||
# It take precedence
|
||||
# If no value is found, we must use the value from alt_sdp
|
||||
cache = ListCache(sdp=FakeSdp(get_value=lambda cache_name, key: NotFound)).auto_configure("cache_name")
|
||||
|
||||
alt_sdp = FakeSdp(extend_exists=lambda cache_name, key: key == "key2",
|
||||
get_alt_value=lambda cache_name, key: ["xxx2"] if key == "key2" else NotFound)
|
||||
cache.put("key1", "source_value")
|
||||
cache.put("key2", "old_value")
|
||||
cache.update("key1", "source_value", "key2", "new_value", alt_sdp=alt_sdp)
|
||||
assert cache.get("key1") == NotFound
|
||||
assert cache.get("key2") == ['old_value', 'new_value']
|
||||
assert cache.to_add == {"key2"}
|
||||
assert cache.to_remove == {"key1"}
|
||||
|
||||
def test_i_can_update_when_alt_sdp_repository_take_precedence_for_destination_key(self):
|
||||
# If a value exists in destination key, either in local cache or remote repository
|
||||
# It take precedence
|
||||
# If no value is found, we must use the value from alt_sdp
|
||||
remote_repo = FakeSdp(get_value=lambda cache_name, key: ["old_value"] if key == "key2" else NotFound)
|
||||
cache = ListCache(sdp=remote_repo).auto_configure("cache_name")
|
||||
|
||||
alt_sdp = FakeSdp(extend_exists=lambda cache_name, key: key == "key2",
|
||||
get_alt_value=lambda cache_name, key: ["xxx2"] if key == "key2" else NotFound)
|
||||
cache.put("key1", "source_value")
|
||||
cache.update("key1", "source_value", "key2", "new_value", alt_sdp=alt_sdp)
|
||||
assert cache.get("key1") == NotFound
|
||||
assert cache.get("key2") == ['old_value', 'new_value']
|
||||
assert cache.to_add == {"key2"}
|
||||
assert cache.to_remove == {"key1"}
|
||||
|
||||
def test_i_can_update_when_alt_sdp_use_alt_sdp_when_no_destination_value_found(self):
|
||||
# If a value exists in destination key, either in local cache or remote repository
|
||||
# It take precedence
|
||||
# If no value is found, we must use the value from alt_sdp
|
||||
cache = ListCache(sdp=FakeSdp(get_value=lambda cache_name, key: NotFound)).auto_configure("cache_name")
|
||||
|
||||
cache.put("key1", "source_value")
|
||||
previous_values = ["old_1", "old_2"]
|
||||
alt_sdp = FakeSdp(extend_exists=lambda cache_name, key: key == "key2",
|
||||
get_alt_value=lambda cache_name, key: previous_values if key == "key2" else NotFound)
|
||||
|
||||
cache.update("key1", "source_value", "key2", "new_value", alt_sdp=alt_sdp)
|
||||
assert cache.get("key1") == NotFound
|
||||
assert cache.get("key2") == ["old_1", "old_2", 'new_value']
|
||||
assert cache.to_add == {"key2"}
|
||||
assert cache.to_remove == {"key1"}
|
||||
assert previous_values == ["old_1", "old_2"] # not modified
|
||||
|
||||
def test_i_can_update_when_alt_sdp_and_cache_is_cleared(self):
|
||||
cache = ListCache(sdp=FakeSdp(get_value=lambda cache_name, key: NotFound)).auto_configure("cache_name")
|
||||
alt_sdp = FakeSdp(get_alt_value=lambda cache_name, key: ["value1"])
|
||||
cache.clear()
|
||||
|
||||
with pytest.raises(KeyError):
|
||||
cache.update("key", "value1", "key", "value2", alt_sdp=alt_sdp)
|
||||
|
||||
with pytest.raises(KeyError):
|
||||
cache.update("key", "value1", "key2", "value2", alt_sdp=alt_sdp)
|
||||
|
||||
def test_default_is_called_before_updating_list_cache(self):
|
||||
cache = ListCache(default=lambda k: NotFound)
|
||||
with pytest.raises(KeyError):
|
||||
cache.update("old_key", "old_value", "new_key", "new_value")
|
||||
|
||||
cache = ListCache(default=lambda k: ["old_value", "other old value"])
|
||||
cache.update("old_key", "old_value", "old_key", "new_value")
|
||||
assert cache.get("old_key") == ["new_value", "other old value"]
|
||||
|
||||
cache = ListCache(default=lambda k: ["old_value", "other old value"] if k == "old_key" else NotFound)
|
||||
cache.update("old_key", "old_value", "new_key", "new_value")
|
||||
assert cache.get("old_key") == ["other old value"]
|
||||
assert cache.get("new_key") == ["new_value"]
|
||||
|
||||
cache = ListCache(default=lambda k: ["old_value", "other old value"] if k == "old_key" else ["other new"])
|
||||
cache.update("old_key", "old_value", "new_key", "new_value")
|
||||
assert cache.get("old_key") == ["other old value"]
|
||||
assert cache.get("new_key") == ["other new", "new_value"]
|
||||
+569
@@ -0,0 +1,569 @@
|
||||
import pytest
|
||||
|
||||
from cache.ListIfNeededCache import ListIfNeededCache
|
||||
from core.global_symbols import NotFound, Removed
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
from tests.cache import FakeSdp
|
||||
|
||||
|
||||
class TestListIfNeededCache(TestUsingMemoryBasedSheerka):
|
||||
def test_i_can_put_and_retrieve_value_from_list_if_needed_cache(self):
|
||||
cache = ListIfNeededCache()
|
||||
|
||||
cache.put("key", "value")
|
||||
assert cache.get("key") == "value"
|
||||
|
||||
# second time with the same key creates a list
|
||||
cache.put("key", "value2")
|
||||
assert cache.get("key") == ["value", "value2"]
|
||||
assert len(cache) == 2
|
||||
|
||||
# third time, we now have a list
|
||||
cache.put("key", "value3")
|
||||
assert cache.get("key") == ["value", "value2", "value3"]
|
||||
assert len(cache) == 3
|
||||
|
||||
# other keys are not affected
|
||||
cache.put("key2", "value")
|
||||
assert cache.get("key2") == "value"
|
||||
assert len(cache) == 4
|
||||
|
||||
# duplicates are allowed
|
||||
cache.put("key", "value")
|
||||
assert cache.get("key") == ["value", "value2", "value3", "value"]
|
||||
assert len(cache) == 5
|
||||
|
||||
def test_i_can_put_in_list_if_need_cache_when_alt_sdp_returns_values(self):
|
||||
cache = ListIfNeededCache(sdp=FakeSdp(get_value=lambda cache_name, key: NotFound)).auto_configure("cache_name")
|
||||
|
||||
cache.put("key", "value2", alt_sdp=FakeSdp(get_alt_value=lambda cache_name, key: "value1"))
|
||||
assert cache.get("key") == ["value1", "value2"]
|
||||
|
||||
cache.put("key2", "value3", alt_sdp=FakeSdp(get_alt_value=lambda cache_name, key: ["value1", "value2"]))
|
||||
assert cache.get("key2") == ["value1", "value2", "value3"]
|
||||
|
||||
cache.put("key3", "value1", alt_sdp=FakeSdp(get_alt_value=lambda cache_name, key: Removed))
|
||||
assert cache.get("key3") == "value1"
|
||||
|
||||
def test_i_can_put_in_list_if_need__cache_when_alt_sdp_returns_values_and_cache_is_cleared(self):
|
||||
cache = ListIfNeededCache(sdp=FakeSdp(get_value=lambda cache_name, key: NotFound)).auto_configure("cache_name")
|
||||
cache.clear()
|
||||
|
||||
cache.put("key", "value2", alt_sdp=FakeSdp(get_alt_value=lambda cache_name, key: "value1"))
|
||||
assert cache.get("key") == "value2"
|
||||
|
||||
cache.put("key3", "value1", alt_sdp=FakeSdp(get_alt_value=lambda cache_name, key: Removed))
|
||||
assert cache.get("key3") == "value1"
|
||||
|
||||
def test_current_cache_take_precedence_over_alt_sdp_when_i_put_data_in_list_if_needed_cache(self):
|
||||
cache = ListIfNeededCache(sdp=FakeSdp(get_value=lambda cache_name, key: NotFound)).auto_configure("cache_name")
|
||||
|
||||
cache.put("key", "value1")
|
||||
cache.put("key", "value2", alt_sdp=FakeSdp(get_alt_value=lambda cache_name, key: "xxx"))
|
||||
assert cache.get("key") == ["value1", "value2"]
|
||||
|
||||
def test_current_sdp_take_precedence_over_alt_sdp_when_i_put_data_in_list_if_needed_cache(self):
|
||||
cache = ListIfNeededCache(sdp=FakeSdp(get_value=lambda cache_name, key: "value1")).auto_configure("cache_name")
|
||||
|
||||
cache.put("key", "value2", alt_sdp=FakeSdp(get_alt_value=lambda cache_name, key: "xxx"))
|
||||
assert cache.get("key") == ["value1", "value2"]
|
||||
|
||||
def test_i_can_update_from_list_if_needed_cache(self):
|
||||
cache = ListIfNeededCache()
|
||||
|
||||
cache.put("key", "value")
|
||||
cache.put("key", "value2")
|
||||
cache.put("key", "value")
|
||||
|
||||
# only the first 'value' is affected
|
||||
cache.update("key", "value", "key", "another value")
|
||||
assert len(cache._cache) == 1
|
||||
assert len(cache) == 3
|
||||
assert cache.get("key") == ["another value", "value2", "value"]
|
||||
|
||||
# change the key
|
||||
cache.update("key", "value2", "key2", "value2")
|
||||
assert len(cache._cache) == 2
|
||||
assert len(cache) == 3
|
||||
assert cache.get("key") == ["another value", "value"]
|
||||
assert cache.get("key2") == "value2"
|
||||
|
||||
# rename the newly created key
|
||||
cache.update("key2", "value2", "key3", "value2")
|
||||
assert len(cache._cache) == 2
|
||||
assert len(cache) == 3
|
||||
assert cache.get("key") == ["another value", "value"]
|
||||
assert cache.get("key3") == "value2"
|
||||
assert cache.get("key2") is NotFound
|
||||
|
||||
# from list to single item and vice versa
|
||||
cache.update("key", "value", "key3", "value")
|
||||
assert len(cache._cache) == 2
|
||||
assert len(cache) == 3
|
||||
assert cache.get("key") == "another value" # 'key' is no longer a list
|
||||
assert cache.get("key3") == ["value2", "value"] # 'key3' is now a list
|
||||
assert cache.get("key2") is NotFound
|
||||
|
||||
with pytest.raises(KeyError):
|
||||
cache.update("wrong key", "value", "key", "value")
|
||||
|
||||
def test_i_can_update_when_alt_sdp_from_cache_keys_are_the_same(self):
|
||||
cache = ListIfNeededCache(sdp=FakeSdp(get_value=lambda cache_name, key: NotFound)).auto_configure("cache_name")
|
||||
|
||||
cache.put("key", "value")
|
||||
cache.update("key", "value", "key", "new_value", FakeSdp(extend_exists=lambda cache_name, key: True))
|
||||
|
||||
assert cache.get("key") == "new_value"
|
||||
|
||||
def test_i_can_update_when_alt_sdp_from_cache_keys_are_the_same_but_nothing_in_cache(self):
|
||||
cache = ListIfNeededCache(sdp=FakeSdp(get_value=lambda cache_name, key: NotFound)).auto_configure("cache_name")
|
||||
|
||||
# one value in alt_sdp
|
||||
alt_sdp = FakeSdp(extend_exists=lambda cache_name, key: True,
|
||||
get_alt_value=lambda cache_name, key: "old_value")
|
||||
cache.update("key", "value", "key", "new_value", alt_sdp=alt_sdp)
|
||||
assert cache.get("key") == "new_value"
|
||||
|
||||
# multiple values in alt_sdp
|
||||
cache.test_only_reset()
|
||||
previous_value = ["old_1", "old_2", "value"]
|
||||
alt_sdp = FakeSdp(extend_exists=lambda cache_name, key: True,
|
||||
get_alt_value=lambda cache_name, key: previous_value)
|
||||
cache.update("key", "value", "key", "new_value", alt_sdp=alt_sdp)
|
||||
assert cache.get("key") == ["old_1", "old_2", "new_value"]
|
||||
assert previous_value == ["old_1", "old_2", "value"]
|
||||
|
||||
def test_i_can_update_when_alt_sdp_from_cache_keys_are_different(self):
|
||||
# keys are different
|
||||
# make sure that current cache take precedence over alt_sdp
|
||||
# In this test, the values from alt_sdp are never used
|
||||
cache = ListIfNeededCache(sdp=FakeSdp(get_value=lambda cache_name, key: NotFound)).auto_configure("cache_name")
|
||||
|
||||
alt_sdp = FakeSdp(extend_exists=lambda cache_name, key: key == "key1",
|
||||
get_alt_value=lambda cache_name, key: "xxx1" if key == "key1" else NotFound)
|
||||
|
||||
# one values in 'key1'
|
||||
cache.put("key1", "old_1")
|
||||
|
||||
cache.update("key1", "old_1", "key2", "new_value", alt_sdp=alt_sdp)
|
||||
assert cache.get("key1") == Removed
|
||||
assert cache.get("key2") == "new_value"
|
||||
assert cache.to_add == {"key2", "key1"}
|
||||
assert cache.to_remove == set()
|
||||
|
||||
# Multiple values in 'key1'
|
||||
cache.clear()
|
||||
cache.put("key1", "old_1")
|
||||
cache.put("key1", "old_2")
|
||||
|
||||
cache.update("key1", "old_1", "key2", "new_value", alt_sdp=alt_sdp)
|
||||
assert cache.get("key1") == "old_2"
|
||||
assert cache.get("key2") == "new_value"
|
||||
assert cache.to_add == {"key2", "key1"}
|
||||
assert cache.to_remove == set()
|
||||
|
||||
# List of values in 'key1'
|
||||
cache.clear()
|
||||
cache.put("key1", "old_1")
|
||||
cache.put("key1", "old_2")
|
||||
cache.put("key1", "old_3")
|
||||
|
||||
cache.update("key1", "old_1", "key2", "new_value", alt_sdp=alt_sdp)
|
||||
assert cache.get("key1") == ["old_2", "old_3"]
|
||||
assert cache.get("key2") == "new_value"
|
||||
assert cache.to_add == {"key2", "key1"}
|
||||
assert cache.to_remove == set()
|
||||
|
||||
def test_i_can_update_when_alt_sdp_from_repository_keys_are_different(self):
|
||||
# keys are different
|
||||
# make sure that current repo take precedence over alt_sdp
|
||||
remote = FakeSdp(get_value=lambda cache_name, key: "old_1" if key == "key1" else NotFound)
|
||||
cache = ListIfNeededCache(sdp=remote).auto_configure("cache_name")
|
||||
|
||||
alt_sdp = FakeSdp(extend_exists=lambda cache_name, key: key == "key1",
|
||||
get_alt_value=lambda cache_name, key: "xxx1" if key == "key1" else NotFound)
|
||||
|
||||
cache.update("key1", "old_1", "key2", "new_value", alt_sdp=alt_sdp)
|
||||
assert cache.get("key1") == Removed
|
||||
assert cache.get("key2") == "new_value"
|
||||
assert cache.to_add == {"key2", "key1"}
|
||||
assert cache.to_remove == set()
|
||||
|
||||
# Multiple values in 'key1'
|
||||
remote = FakeSdp(get_value=lambda cache_name, key: ["old_1", "old_2"] if key == "key1" else NotFound)
|
||||
cache = ListIfNeededCache(sdp=remote).auto_configure("cache_name")
|
||||
cache.update("key1", "old_1", "key2", "new_value", alt_sdp=alt_sdp)
|
||||
assert cache.get("key1") == "old_2"
|
||||
assert cache.get("key2") == "new_value"
|
||||
assert cache.to_add == {"key2", "key1"}
|
||||
assert cache.to_remove == set()
|
||||
|
||||
# List of values in 'key1'
|
||||
remote = FakeSdp(get_value=lambda cache_name, key: ["old_1", "old_2", "old_3"] if key == "key1" else NotFound)
|
||||
cache = ListIfNeededCache(sdp=remote).auto_configure("cache_name")
|
||||
cache.update("key1", "old_1", "key2", "new_value", alt_sdp=alt_sdp)
|
||||
assert cache.get("key1") == ["old_2", "old_3"]
|
||||
assert cache.get("key2") == "new_value"
|
||||
assert cache.to_add == {"key2", "key1"}
|
||||
assert cache.to_remove == set()
|
||||
|
||||
def test_i_can_update_when_alt_sdp_from_alt_sdp_keys_are_different_one_value(self):
|
||||
# keys are different
|
||||
# No value found in cache or remote repository,
|
||||
# Will use values from alt_sdp
|
||||
# The old key is the same, so it has to be marked as Removed
|
||||
cache = ListIfNeededCache(sdp=FakeSdp(get_value=lambda cache_name, key: NotFound)).auto_configure("cache_name")
|
||||
|
||||
# one values in 'key1'
|
||||
alt_sdp = FakeSdp(extend_exists=lambda cache_name, key: key == "key1",
|
||||
get_alt_value=lambda cache_name, key: "old_1" if key == "key1" else NotFound)
|
||||
|
||||
cache.update("key1", "old_1", "key2", "new_value", alt_sdp=alt_sdp)
|
||||
assert cache.get("key1") == Removed
|
||||
assert cache.get("key2") == "new_value"
|
||||
assert cache.to_add == {"key2", "key1"}
|
||||
assert cache.to_remove == set()
|
||||
|
||||
# Multiple values in 'key1'
|
||||
cache.test_only_reset()
|
||||
old_values = ["old_1", "old_2"]
|
||||
alt_sdp = FakeSdp(extend_exists=lambda cache_name, key: key == "key1",
|
||||
get_alt_value=lambda cache_name, key: old_values if key == "key1" else NotFound)
|
||||
cache.update("key1", "old_1", "key2", "new_value", alt_sdp=alt_sdp)
|
||||
assert cache.get("key1") == "old_2"
|
||||
assert cache.get("key2") == "new_value"
|
||||
assert cache.to_add == {"key2", "key1"}
|
||||
assert cache.to_remove == set()
|
||||
assert old_values == ["old_1", "old_2"] # not modified
|
||||
|
||||
# List of values in 'key1'
|
||||
cache.test_only_reset()
|
||||
old_values = ["old_1", "old_2", "old_3"]
|
||||
alt_sdp = FakeSdp(extend_exists=lambda cache_name, key: key == "key1",
|
||||
get_alt_value=lambda cache_name, key: old_values if key == "key1" else NotFound)
|
||||
cache.update("key1", "old_1", "key2", "new_value", alt_sdp=alt_sdp)
|
||||
assert cache.get("key1") == ["old_2", "old_3"]
|
||||
assert cache.get("key2") == "new_value"
|
||||
assert cache.to_add == {"key2", "key1"}
|
||||
assert cache.to_remove == set()
|
||||
assert old_values == ["old_1", "old_2", "old_3"] # not modified
|
||||
|
||||
def test_i_can_update_when_alt_sdp_cache_take_precedence_for_destination_key(self):
|
||||
# If a value exists in destination key, either in local cache or remote repository
|
||||
# It take precedence
|
||||
# If no value is found, we must use the value from alt_sdp
|
||||
|
||||
cache = ListIfNeededCache(sdp=FakeSdp(get_value=lambda cache_name, key: NotFound)).auto_configure("cache_name")
|
||||
|
||||
alt_sdp = FakeSdp(extend_exists=lambda cache_name, key: key == "key2",
|
||||
get_alt_value=lambda cache_name, key: "xxx2" if key == "key2" else NotFound)
|
||||
cache.put("key1", "source_value")
|
||||
cache.put("key2", "old_value")
|
||||
cache.update("key1", "source_value", "key2", "new_value", alt_sdp=alt_sdp)
|
||||
assert cache.get("key1") == NotFound
|
||||
assert cache.get("key2") == ['old_value', 'new_value']
|
||||
assert cache.to_add == {"key2"}
|
||||
assert cache.to_remove == {"key1"}
|
||||
|
||||
def test_i_can_update_when_alt_sdp_repository_take_precedence_for_destination_key(self):
|
||||
# If a value exists in destination key, either in local cache or remote repository
|
||||
# It take precedence
|
||||
# If no value is found, we must use the value from alt_sdp
|
||||
remote_repo = FakeSdp(get_value=lambda cache_name, key: "old_value" if key == "key2" else NotFound)
|
||||
cache = ListIfNeededCache(sdp=remote_repo).auto_configure("cache_name")
|
||||
|
||||
alt_sdp = FakeSdp(extend_exists=lambda cache_name, key: key == "key2",
|
||||
get_alt_value=lambda cache_name, key: "xxx2" if key == "key2" else NotFound)
|
||||
cache.put("key1", "source_value")
|
||||
cache.update("key1", "source_value", "key2", "new_value", alt_sdp=alt_sdp)
|
||||
assert cache.get("key1") == NotFound
|
||||
assert cache.get("key2") == ['old_value', 'new_value']
|
||||
assert cache.to_add == {"key2"}
|
||||
assert cache.to_remove == {"key1"}
|
||||
|
||||
def test_i_can_update_when_alt_sdp_use_alt_sdp_when_no_destination_value_found(self):
|
||||
# If a value exists in destination key, either in local cache or remote repository
|
||||
# It take precedence
|
||||
# If no value is found, we must use the value from alt_sdp
|
||||
cache = ListIfNeededCache(sdp=FakeSdp(get_value=lambda cache_name, key: NotFound)).auto_configure("cache_name")
|
||||
# one value in 'key2'
|
||||
cache.put("key1", "source_value")
|
||||
alt_sdp = FakeSdp(extend_exists=lambda cache_name, key: key == "key2",
|
||||
get_alt_value=lambda cache_name, key: "old_value" if key == "key2" else NotFound)
|
||||
|
||||
cache.update("key1", "source_value", "key2", "new_value", alt_sdp=alt_sdp)
|
||||
assert cache.get("key1") == NotFound
|
||||
assert cache.get("key2") == ['old_value', 'new_value']
|
||||
assert cache.to_add == {"key2"}
|
||||
assert cache.to_remove == {"key1"}
|
||||
|
||||
# Multiple values in 'key2'
|
||||
cache.test_only_reset()
|
||||
cache.put("key1", "source_value")
|
||||
previous_values = ["old_1", "old_2"]
|
||||
alt_sdp = FakeSdp(extend_exists=lambda cache_name, key: key == "key2",
|
||||
get_alt_value=lambda cache_name, key: previous_values if key == "key2" else NotFound)
|
||||
|
||||
cache.update("key1", "source_value", "key2", "new_value", alt_sdp=alt_sdp)
|
||||
assert cache.get("key1") == NotFound
|
||||
assert cache.get("key2") == ["old_1", "old_2", 'new_value']
|
||||
assert cache.to_add == {"key2"}
|
||||
assert cache.to_remove == {"key1"}
|
||||
assert previous_values == ["old_1", "old_2"] # not modified
|
||||
|
||||
def test_i_can_update_when_alt_sdp_and_cache_is_cleared(self):
|
||||
cache = ListIfNeededCache(sdp=FakeSdp(get_value=lambda cache_name, key: NotFound)).auto_configure("cache_name")
|
||||
alt_sdp = FakeSdp(get_alt_value=lambda cache_name, key: "value1")
|
||||
cache.clear()
|
||||
|
||||
with pytest.raises(KeyError):
|
||||
cache.update("key", "value1", "key", "value2", alt_sdp=alt_sdp)
|
||||
|
||||
with pytest.raises(KeyError):
|
||||
cache.update("key", "value1", "key2", "value2", alt_sdp=alt_sdp)
|
||||
|
||||
def test_default_is_called_before_updating_list_if_needed_cache(self):
|
||||
cache = ListIfNeededCache(default=lambda k: NotFound)
|
||||
with pytest.raises(KeyError):
|
||||
cache.update("old_key", "old_value", "new_key", "new_value")
|
||||
|
||||
cache = ListIfNeededCache(default=lambda k: "old_value")
|
||||
cache.update("old_key", "old_value", "old_key", "new_value")
|
||||
assert cache.get("old_key") == "new_value"
|
||||
|
||||
cache = ListIfNeededCache(default=lambda k: ["old_value", "other old value"])
|
||||
cache.update("old_key", "old_value", "old_key", "new_value")
|
||||
assert cache.get("old_key") == ["new_value", "other old value"]
|
||||
|
||||
cache = ListIfNeededCache(default=lambda k: ["old_value", "other old value"] if k == "old_key" else NotFound)
|
||||
cache.update("old_key", "old_value", "new_key", "new_value")
|
||||
assert cache.get("old_key") == "other old value"
|
||||
assert cache.get("new_key") == "new_value"
|
||||
|
||||
def test_i_can_delete_key_and_values(self):
|
||||
cache = ListIfNeededCache()
|
||||
cache.put("key", "value1")
|
||||
cache.put("key", "value11")
|
||||
cache.put("key2", "value2")
|
||||
cache.put("key2", "value22")
|
||||
cache.put("key2", "value222")
|
||||
cache.put("key3", "value3")
|
||||
cache.put("key3", "value33")
|
||||
cache.put("key4", "value4")
|
||||
cache.reset_events()
|
||||
|
||||
assert len(cache) == 8
|
||||
|
||||
# I can remove a whole key
|
||||
cache.delete("key")
|
||||
assert cache.get("key") is NotFound
|
||||
assert len(cache) == 6
|
||||
assert cache.to_remove == {"key"}
|
||||
assert cache.to_add == set()
|
||||
|
||||
# I can remove an element while a list is remaining
|
||||
cache.reset_events()
|
||||
cache.delete("key2", "value22")
|
||||
assert cache.get("key2") == ["value2", "value222"]
|
||||
assert len(cache) == 5
|
||||
assert cache.to_add == {"key2"}
|
||||
assert cache.to_remove == set()
|
||||
|
||||
# I can remove an element while a single element is remaining
|
||||
cache.reset_events()
|
||||
cache.delete("key3", "value33")
|
||||
assert cache.get("key3") == "value3"
|
||||
assert len(cache) == 4
|
||||
assert cache.to_add == {"key3"}
|
||||
assert cache.to_remove == set()
|
||||
|
||||
# I can remove an element while nothing remains
|
||||
cache.reset_events()
|
||||
cache.delete("key4", "value4")
|
||||
assert cache.get("key4") is NotFound
|
||||
assert len(cache) == 3
|
||||
assert cache.to_remove == {"key4"}
|
||||
assert cache.to_add == set()
|
||||
|
||||
# I do not remove when the value is not the same
|
||||
cache.reset_events()
|
||||
cache.delete("key3", "value33") # value33 was already remove
|
||||
assert cache.get("key3") == "value3"
|
||||
assert len(cache) == 3
|
||||
assert cache.to_add == set()
|
||||
assert cache.to_remove == set()
|
||||
|
||||
def test_i_can_delete_when_alt_sdp_a_key_from_cache(self):
|
||||
# There is a value in alt_cache_manager,
|
||||
# No remaining value in current cache after deletion
|
||||
# The key must be flagged as Removed
|
||||
cache = ListIfNeededCache(sdp=FakeSdp(get_value=lambda cache_name, key: NotFound)).auto_configure("cache_name")
|
||||
cache.put("key", "value")
|
||||
|
||||
cache.delete("key", value=None, alt_sdp=FakeSdp(extend_exists=lambda cache_name, key: True))
|
||||
assert cache.copy() == {"key": Removed}
|
||||
assert cache.to_add == {"key"}
|
||||
assert cache.to_remove == set()
|
||||
|
||||
def test_i_can_delete_when_alt_sdp_a_value_from_cache(self):
|
||||
# There is a value in alt_cache_manager,
|
||||
# No remaining value in current cache after deletion
|
||||
# The key must be flagged as Removed
|
||||
cache = ListIfNeededCache(sdp=FakeSdp(get_value=lambda entry, k: NotFound)).auto_configure("cache_name")
|
||||
cache.put("key", "value")
|
||||
|
||||
alt_sdp = FakeSdp(get_alt_value=lambda cache_name, key: "xxx", extend_exists=lambda cache_name, key: True)
|
||||
cache.delete("key", value="value", alt_sdp=alt_sdp)
|
||||
assert cache.copy() == {"key": Removed}
|
||||
assert cache.to_remove == set()
|
||||
assert cache.to_add == {"key"}
|
||||
|
||||
def test_i_can_delete_when_alt_sdp_a_value_from_cache_remaining_values(self):
|
||||
# There is a value in alt_cache_manager,
|
||||
# But this, there are remaining values in current cache after deletion
|
||||
cache = ListIfNeededCache(sdp=FakeSdp(get_value=lambda entry, k: NotFound)).auto_configure("cache_name")
|
||||
cache.put("key", "value")
|
||||
cache.put("key", "value2")
|
||||
|
||||
alt_sdp = FakeSdp(get_alt_value=lambda cache_name, key: "xxx", extend_exists=lambda cache_name, key: True)
|
||||
cache.delete("key", value="value", alt_sdp=alt_sdp)
|
||||
assert cache.copy() == {"key": "value2"}
|
||||
assert cache.to_remove == set()
|
||||
assert cache.to_add == {"key"}
|
||||
|
||||
def test_i_can_delete_when_alt_sdp_a_key_from_remote_repository(self):
|
||||
# There is a value in alt_cache_manager,
|
||||
# No remaining value in current cache after deletion
|
||||
# The key must be flagged as Removed
|
||||
cache = ListIfNeededCache(sdp=FakeSdp(get_value=lambda entry, k: ["value1", "value2"])).auto_configure("cache_name")
|
||||
|
||||
alt_sdp = FakeSdp(get_alt_value=lambda cache_name, key: "xxx", extend_exists=lambda cache_name, key: True)
|
||||
cache.delete("key", value=None, alt_sdp=alt_sdp)
|
||||
assert cache.copy() == {"key": Removed}
|
||||
assert cache.to_remove == set()
|
||||
assert cache.to_add == {"key"}
|
||||
|
||||
def test_i_can_delete_when_alt_sdp_a_value_from_remote_repository(self):
|
||||
# There is a value in alt_cache_manager,
|
||||
# No remaining value in current cache after deletion
|
||||
# The key must be flagged as Removed
|
||||
cache = ListIfNeededCache(sdp=FakeSdp(get_value=lambda entry, k: "value")).auto_configure("cache_name")
|
||||
|
||||
alt_sdp = FakeSdp(get_alt_value=lambda cache_name, key: "xxx", extend_exists=lambda cache_name, key: True)
|
||||
cache.delete("key", value="value", alt_sdp=alt_sdp)
|
||||
assert cache.copy() == {"key": Removed}
|
||||
assert cache.to_remove == set()
|
||||
assert cache.to_add == {"key"}
|
||||
|
||||
def test_i_can_delete_when_alt_sdp_a_value_from_remote_repository_remaining_values(self):
|
||||
# There is a value in alt_cache_manager,
|
||||
# But this, there are remaining values in current cache after deletion
|
||||
cache = ListIfNeededCache(sdp=FakeSdp(get_value=lambda entry, k: ["value1", "value2"])).auto_configure("cache_name")
|
||||
|
||||
alt_sdp = FakeSdp(get_alt_value=lambda cache_name, key: "xxx", extend_exists=lambda cache_name, key: True)
|
||||
cache.delete("key", value="value1", alt_sdp=alt_sdp)
|
||||
assert cache.copy() == {"key": "value2"}
|
||||
assert cache.to_remove == set()
|
||||
assert cache.to_add == {"key"}
|
||||
|
||||
def test_i_can_delete_when_alt_sdp_a_key_from_alt_sdp(self):
|
||||
# alt_cache_manager is used because no value in cache or in remote repository
|
||||
# After value deletion, the key is empty
|
||||
cache = ListIfNeededCache(sdp=FakeSdp(get_value=lambda entry, k: NotFound)).auto_configure("cache_name")
|
||||
|
||||
alt_sdp = FakeSdp(get_alt_value=lambda cache_name, key: ["value1, value2"],
|
||||
extend_exists=lambda cache_name, key: True)
|
||||
|
||||
cache.delete("key", value=None, alt_sdp=alt_sdp)
|
||||
assert cache.copy() == {"key": Removed}
|
||||
assert cache.to_add == {"key"}
|
||||
assert cache.to_remove == set()
|
||||
|
||||
def test_i_can_delete_when_alt_sdp_a_value_from_alt_sdp(self):
|
||||
# alt_cache_manager is used because no value in cache or in remote repository
|
||||
# After value deletion, the key is empty
|
||||
cache = ListIfNeededCache(sdp=FakeSdp(get_value=lambda entry, k: NotFound)).auto_configure("cache_name")
|
||||
|
||||
alt_sdp = FakeSdp(get_alt_value=lambda cache_name, key: "value1",
|
||||
extend_exists=lambda cache_name, key: True)
|
||||
|
||||
cache.delete("key", value="value1", alt_sdp=alt_sdp)
|
||||
assert cache.copy() == {"key": Removed}
|
||||
assert cache.to_add == {"key"}
|
||||
assert cache.to_remove == set()
|
||||
|
||||
def test_i_can_delete_when_alt_sdp_a_value_from_alt_sdp_one_value_remaining(self):
|
||||
# alt_cache_manager is used because no value in cache or in remote repository
|
||||
# After value deletion, one value remains in the cache
|
||||
cache = ListIfNeededCache(sdp=FakeSdp(get_value=lambda entry, k: NotFound)).auto_configure("cache_name")
|
||||
|
||||
alt_sdp = FakeSdp(get_alt_value=lambda cache_name, key: ["value1", "value2"],
|
||||
extend_exists=lambda cache_name, key: True)
|
||||
|
||||
cache.delete("key", value="value1", alt_sdp=alt_sdp)
|
||||
assert cache.copy() == {"key": "value2"}
|
||||
assert cache.to_add == {"key"}
|
||||
assert cache.to_remove == set()
|
||||
|
||||
def test_i_can_delete_when_alt_sdp_a_value_from_alt_sdp_multiple_values_remaining(self):
|
||||
# alt_cache_manager is used because no value in cache or in remote repository
|
||||
# After value deletion, one value remains in the cache
|
||||
cache = ListIfNeededCache(sdp=FakeSdp(get_value=lambda entry, k: NotFound)).auto_configure("cache_name")
|
||||
|
||||
alt_sdp = FakeSdp(get_alt_value=lambda cache_name, key: ["value1", "value2", "value3"],
|
||||
extend_exists=lambda cache_name, key: True)
|
||||
|
||||
cache.delete("key", value="value1", alt_sdp=alt_sdp)
|
||||
assert cache.copy() == {"key": ["value2", "value3"]}
|
||||
assert cache.to_add == {"key"}
|
||||
assert cache.to_remove == set()
|
||||
|
||||
def test_i_can_delete_when_alt_sdp_an_already_removed_value_from_alt_sdp(self):
|
||||
# alt_cache_manager is used because no value in cache or in remote repository
|
||||
# But the alternate sdp returns Removed, which means that previous value was deleted
|
||||
# It's like there is nothing to delete
|
||||
cache = ListIfNeededCache(sdp=FakeSdp(get_value=lambda entry, k: NotFound)).auto_configure("cache_name")
|
||||
|
||||
alt_sdp = FakeSdp(get_alt_value=lambda cache_name, key: Removed,
|
||||
extend_exists=lambda cache_name, key: False)
|
||||
|
||||
cache.delete("key", value="value1", alt_sdp=alt_sdp)
|
||||
assert cache.copy() == {}
|
||||
assert cache.to_add == set()
|
||||
assert cache.to_remove == set()
|
||||
|
||||
def test_deleting_an_entry_that_does_not_exist_is_not_an_error(self):
|
||||
cache = ListIfNeededCache()
|
||||
cache.put("key", "value1")
|
||||
|
||||
cache.reset_events()
|
||||
cache.delete("key3")
|
||||
assert len(cache) == 1
|
||||
assert cache.to_add == set()
|
||||
assert cache.to_remove == set()
|
||||
|
||||
cache.delete("key3", "value")
|
||||
assert len(cache) == 1
|
||||
assert cache.to_add == set()
|
||||
assert cache.to_remove == set()
|
||||
|
||||
cache.delete("key", "value2")
|
||||
assert len(cache) == 1
|
||||
assert cache.to_add == set()
|
||||
assert cache.to_remove == set()
|
||||
|
||||
def test_i_can_delete_when_alt_sdp_and_cache_is_cleared(self):
|
||||
cache = ListIfNeededCache(sdp=FakeSdp(get_value=lambda entry, k: NotFound)).auto_configure("cache_name")
|
||||
alt_sdp = FakeSdp(get_alt_value=lambda cache_name, key: "value",
|
||||
extend_exists=lambda cache_name, key: True)
|
||||
|
||||
cache.clear()
|
||||
cache.delete("key", value=None, alt_sdp=alt_sdp)
|
||||
assert cache.copy() == {}
|
||||
assert cache.to_add == set()
|
||||
assert cache.to_remove == set()
|
||||
|
||||
cache.delete("key", value="value", alt_sdp=alt_sdp)
|
||||
assert cache.copy() == {}
|
||||
assert cache.to_add == set()
|
||||
assert cache.to_remove == set()
|
||||
Vendored
+477
@@ -0,0 +1,477 @@
|
||||
import pytest
|
||||
|
||||
from cache.SetCache import SetCache
|
||||
from core.global_symbols import NotFound, Removed
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
from tests.cache import FakeSdp
|
||||
|
||||
|
||||
class TestSetCache(TestUsingMemoryBasedSheerka):
|
||||
|
||||
def test_i_can_put_and_retrieve_values_from_set_cache(self):
|
||||
cache = SetCache()
|
||||
|
||||
cache.put("key", "value")
|
||||
assert cache.get("key") == {"value"}
|
||||
assert len(cache) == 1
|
||||
|
||||
# we can add to this set
|
||||
cache.put("key", "value2")
|
||||
assert cache.get("key") == {"value", "value2"}
|
||||
assert len(cache) == 2
|
||||
|
||||
# other keys are not affected
|
||||
cache.put("key2", "value")
|
||||
assert cache.get("key2") == {"value"}
|
||||
assert len(cache) == 3
|
||||
|
||||
# duplicates are removed
|
||||
cache.put("key", "value")
|
||||
assert cache.get("key") == {"value", "value2"}
|
||||
assert len(cache) == 3
|
||||
|
||||
assert cache.copy() == {'key': {'value', 'value2'}, 'key2': {'value'}}
|
||||
|
||||
def test_i_can_put_in_set_cache_when_alt_sdp_returns_values(self):
|
||||
cache = SetCache(sdp=FakeSdp(get_value=lambda cache_name, key: NotFound)).auto_configure("cache_name")
|
||||
|
||||
cache.put("key", "value2", alt_sdp=FakeSdp(get_alt_value=lambda cache_name, key: {"value1"}))
|
||||
assert cache.get("key") == {"value1", "value2"}
|
||||
|
||||
cache.put("key3", "value1", alt_sdp=FakeSdp(get_alt_value=lambda cache_name, key: Removed))
|
||||
assert cache.get("key3") == {"value1"}
|
||||
|
||||
def test_i_can_put_in_set_cache_when_alt_sdp_returns_values_and_cache_is_cleared(self):
|
||||
cache = SetCache(sdp=FakeSdp(get_value=lambda cache_name, key: NotFound)).auto_configure("cache_name")
|
||||
cache.clear()
|
||||
|
||||
cache.put("key", "value2", alt_sdp=FakeSdp(get_alt_value=lambda cache_name, key: {"value1"}))
|
||||
assert cache.get("key") == {"value2"}
|
||||
|
||||
cache.put("key3", "value1", alt_sdp=FakeSdp(get_alt_value=lambda cache_name, key: Removed))
|
||||
assert cache.get("key3") == {"value1"}
|
||||
|
||||
def test_current_cache_take_precedence_over_alt_sdp_when_i_put_data_in_set_cache(self):
|
||||
cache = SetCache(sdp=FakeSdp(get_value=lambda cache_name, key: NotFound)).auto_configure("cache_name")
|
||||
|
||||
cache.put("key", "value1")
|
||||
cache.put("key", "value2", alt_sdp=FakeSdp(get_alt_value=lambda cache_name, key: "xxx"))
|
||||
assert cache.get("key") == {"value1", "value2"}
|
||||
|
||||
def test_current_sdp_take_precedence_over_alt_sdp_when_i_put_data_in_set_cache(self):
|
||||
cache = SetCache(sdp=FakeSdp(get_value=lambda cache_name, key: {"value1"})).auto_configure("cache_name")
|
||||
|
||||
cache.put("key", "value2", alt_sdp=FakeSdp(get_alt_value=lambda cache_name, key: "xxx"))
|
||||
assert cache.get("key") == {"value1", "value2"}
|
||||
|
||||
def test_i_can_update_from_set_cache(self):
|
||||
cache = SetCache()
|
||||
|
||||
cache.put("key", "value")
|
||||
cache.put("key", "value2")
|
||||
cache.update("key", "value", "key", "another value")
|
||||
|
||||
assert len(cache._cache) == 1
|
||||
assert len(cache) == 2
|
||||
assert cache.get("key") == {"another value", "value2"}
|
||||
|
||||
cache.update("key", "value2", "key2", "value2")
|
||||
assert len(cache._cache) == 2
|
||||
assert len(cache) == 2
|
||||
assert cache.get("key") == {"another value"}
|
||||
assert cache.get("key2") == {"value2"}
|
||||
|
||||
cache.update("key", "another value", "key3", "another value")
|
||||
assert len(cache._cache) == 2
|
||||
assert len(cache) == 2
|
||||
assert cache.get("key") is NotFound
|
||||
assert cache.get("key2") == {"value2"}
|
||||
assert cache.get("key3") == {"another value"}
|
||||
|
||||
with pytest.raises(KeyError):
|
||||
cache.update("wrong key", "value", "key", "value")
|
||||
|
||||
def test_i_can_update_when_alt_sdp_from_cache_keys_are_the_same(self):
|
||||
cache = SetCache(sdp=FakeSdp(get_value=lambda cache_name, key: NotFound)).auto_configure("cache_name")
|
||||
|
||||
cache.put("key", "value")
|
||||
cache.update("key", "value", "key", "new_value", alt_sdp=FakeSdp(extend_exists=lambda cache_name, key: True))
|
||||
|
||||
assert cache.get("key") == {"new_value"}
|
||||
|
||||
def test_i_can_update_when_alt_sdp_from_cache_keys_are_the_same_but_nothing_in_cache(self):
|
||||
# There is nothing in cache or remote repository.
|
||||
# We must ust the value from alt_sdp
|
||||
cache = SetCache(sdp=FakeSdp(get_value=lambda cache_name, key: NotFound)).auto_configure("cache_name")
|
||||
|
||||
previous_value = {"old_1", "old_2", "value"}
|
||||
alt_sdp = FakeSdp(extend_exists=lambda cache_name, key: True,
|
||||
get_alt_value=lambda cache_name, key: previous_value)
|
||||
cache.update("key", "value", "key", "new_value", alt_sdp=alt_sdp)
|
||||
assert cache.get("key") == {"old_1", "old_2", "new_value"}
|
||||
assert previous_value == {"old_1", "old_2", "value"}
|
||||
|
||||
def test_i_can_update_when_alt_sdp_from_cache_keys_are_different(self):
|
||||
# keys are different
|
||||
# make sure that current cache take precedence over alt_sdp
|
||||
# In this test, the values from alt_sdp are never used
|
||||
cache = SetCache(sdp=FakeSdp(get_value=lambda cache_name, key: NotFound)).auto_configure("cache_name")
|
||||
|
||||
alt_sdp = FakeSdp(extend_exists=lambda cache_name, key: key == "key1",
|
||||
get_alt_value=lambda cache_name, key: {"xxx1"} if key == "key1" else NotFound)
|
||||
|
||||
# one values in 'key1'
|
||||
cache.put("key1", "old_1")
|
||||
|
||||
cache.update("key1", "old_1", "key2", "new_value", alt_sdp=alt_sdp)
|
||||
assert cache.get("key1") == Removed
|
||||
assert cache.get("key2") == {"new_value"}
|
||||
assert cache.to_add == {"key2", "key1"}
|
||||
assert cache.to_remove == set()
|
||||
|
||||
# Multiple values in 'key1'
|
||||
cache.clear()
|
||||
cache.put("key1", "old_1")
|
||||
cache.put("key1", "old_2")
|
||||
|
||||
cache.update("key1", "old_1", "key2", "new_value", alt_sdp=alt_sdp)
|
||||
assert cache.get("key1") == {"old_2"}
|
||||
assert cache.get("key2") == {"new_value"}
|
||||
assert cache.to_add == {"key2", "key1"}
|
||||
assert cache.to_remove == set()
|
||||
|
||||
def test_i_can_update_when_alt_sdp_from_repository_keys_are_different(self):
|
||||
# keys are different
|
||||
# make sure that current repo take precedence over alt_sdp
|
||||
remote = FakeSdp(get_value=lambda cache_name, key: {"old_1"} if key == "key1" else NotFound)
|
||||
cache = SetCache(sdp=remote).auto_configure("cache_name")
|
||||
|
||||
alt_sdp = FakeSdp(extend_exists=lambda cache_name, key: key == "key1",
|
||||
get_alt_value=lambda cache_name, key: {"xxx1"} if key == "key1" else NotFound)
|
||||
|
||||
cache.update("key1", "old_1", "key2", "new_value", alt_sdp=alt_sdp)
|
||||
assert cache.get("key1") == Removed
|
||||
assert cache.get("key2") == {"new_value"}
|
||||
assert cache.to_add == {"key2", "key1"}
|
||||
assert cache.to_remove == set()
|
||||
|
||||
# Multiple values in 'key1'
|
||||
remote = FakeSdp(get_value=lambda cache_name, key: {"old_1", "old_2"} if key == "key1" else NotFound)
|
||||
cache = SetCache(sdp=remote).auto_configure("cache_name")
|
||||
cache.update("key1", "old_1", "key2", "new_value", alt_sdp=alt_sdp)
|
||||
assert cache.get("key1") == {"old_2"}
|
||||
assert cache.get("key2") == {"new_value"}
|
||||
assert cache.to_add == {"key2", "key1"}
|
||||
assert cache.to_remove == set()
|
||||
|
||||
def test_i_can_update_when_alt_sdp_from_alt_sdp_keys_are_different_one_value(self):
|
||||
# keys are different
|
||||
# No value found in cache or remote repository,
|
||||
# Will use values from alt_sdp
|
||||
# The old key is the same, so it has to be marked as Removed
|
||||
cache = SetCache(sdp=FakeSdp(get_value=lambda cache_name, key: NotFound)).auto_configure("cache_name")
|
||||
|
||||
# one values in 'key1'
|
||||
alt_sdp = FakeSdp(extend_exists=lambda cache_name, key: key == "key1",
|
||||
get_alt_value=lambda cache_name, key: {"old_1"} if key == "key1" else NotFound)
|
||||
|
||||
cache.update("key1", "old_1", "key2", "new_value", alt_sdp=alt_sdp)
|
||||
assert cache.get("key1") == Removed
|
||||
assert cache.get("key2") == {"new_value"}
|
||||
assert cache.to_add == {"key2", "key1"}
|
||||
assert cache.to_remove == set()
|
||||
|
||||
# Multiple values in 'key1'
|
||||
cache.test_only_reset()
|
||||
old_values = {"old_1", "old_2"}
|
||||
alt_sdp = FakeSdp(extend_exists=lambda cache_name, key: key == "key1",
|
||||
get_alt_value=lambda cache_name, key: old_values if key == "key1" else NotFound)
|
||||
cache.update("key1", "old_1", "key2", "new_value", alt_sdp=alt_sdp)
|
||||
assert cache.get("key1") == {"old_2"}
|
||||
assert cache.get("key2") == {"new_value"}
|
||||
assert cache.to_add == {"key2", "key1"}
|
||||
assert cache.to_remove == set()
|
||||
assert old_values == {"old_1", "old_2"} # not modified
|
||||
|
||||
def test_i_can_update_when_alt_sdp_cache_take_precedence_for_destination_key(self):
|
||||
# If a value exists in destination key, either in local cache or remote repository
|
||||
# It take precedence
|
||||
# If no value is found, we must use the value from alt_sdp
|
||||
cache = SetCache(sdp=FakeSdp(get_value=lambda cache_name, key: NotFound)).auto_configure("cache_name")
|
||||
|
||||
alt_sdp = FakeSdp(extend_exists=lambda cache_name, key: key == "key2",
|
||||
get_alt_value=lambda cache_name, key: {"xxx2"} if key == "key2" else NotFound)
|
||||
cache.put("key1", "source_value")
|
||||
cache.put("key2", "old_value")
|
||||
cache.update("key1", "source_value", "key2", "new_value", alt_sdp=alt_sdp)
|
||||
assert cache.get("key1") == NotFound
|
||||
assert cache.get("key2") == {'old_value', 'new_value'}
|
||||
assert cache.to_add == {"key2"}
|
||||
assert cache.to_remove == {"key1"}
|
||||
|
||||
def test_i_can_update_when_alt_sdp_repository_take_precedence_for_destination_key(self):
|
||||
# If a value exists in destination key, either in local cache or remote repository
|
||||
# It take precedence
|
||||
# If no value is found, we must use the value from alt_sdp
|
||||
remote_repo = FakeSdp(get_value=lambda cache_name, key: {"old_value"} if key == "key2" else NotFound)
|
||||
cache = SetCache(sdp=remote_repo).auto_configure("cache_name")
|
||||
|
||||
alt_sdp = FakeSdp(extend_exists=lambda cache_name, key: key == "key2",
|
||||
get_alt_value=lambda cache_name, key: "xxx2" if key == "key2" else NotFound)
|
||||
cache.put("key1", "source_value")
|
||||
cache.update("key1", "source_value", "key2", "new_value", alt_sdp=alt_sdp)
|
||||
assert cache.get("key1") == NotFound
|
||||
assert cache.get("key2") == {'old_value', 'new_value'}
|
||||
assert cache.to_add == {"key2"}
|
||||
assert cache.to_remove == {"key1"}
|
||||
|
||||
def test_i_can_update_when_alt_sdp_use_alt_sdp_when_no_destination_value_found(self):
|
||||
# If a value exists in destination key, either in local cache or remote repository
|
||||
# It take precedence
|
||||
# If no value is found, we must use the value from alt_sdp
|
||||
cache = SetCache(sdp=FakeSdp(get_value=lambda cache_name, key: NotFound)).auto_configure("cache_name")
|
||||
|
||||
cache.put("key1", "source_value")
|
||||
previous_values = {"old_1", "old_2"}
|
||||
alt_sdp = FakeSdp(extend_exists=lambda cache_name, key: key == "key2",
|
||||
get_alt_value=lambda cache_name, key: previous_values if key == "key2" else NotFound)
|
||||
|
||||
cache.update("key1", "source_value", "key2", "new_value", alt_sdp=alt_sdp)
|
||||
assert cache.get("key1") == NotFound
|
||||
assert cache.get("key2") == {"old_1", "old_2", 'new_value'}
|
||||
assert cache.to_add == {"key2"}
|
||||
assert cache.to_remove == {"key1"}
|
||||
assert previous_values == {"old_1", "old_2"} # not modified
|
||||
|
||||
def test_i_can_update_when_alt_sdp_and_cache_is_cleared(self):
|
||||
cache = SetCache(sdp=FakeSdp(get_value=lambda cache_name, key: NotFound)).auto_configure("cache_name")
|
||||
alt_sdp = FakeSdp(get_alt_value=lambda cache_name, key: ["value1"])
|
||||
cache.clear()
|
||||
|
||||
with pytest.raises(KeyError):
|
||||
cache.update("key", "value1", "key", "value2", alt_sdp=alt_sdp)
|
||||
|
||||
with pytest.raises(KeyError):
|
||||
cache.update("key", "value1", "key2", "value2", alt_sdp=alt_sdp)
|
||||
|
||||
def test_default_is_called_before_updating_set_cache(self):
|
||||
cache = SetCache(default=lambda k: NotFound)
|
||||
with pytest.raises(KeyError):
|
||||
cache.update("old_key", "old_value", "new_key", "new_value")
|
||||
|
||||
cache = SetCache(default=lambda k: {"old_value", "other old value"})
|
||||
cache.update("old_key", "old_value", "old_key", "new_value")
|
||||
assert cache.get("old_key") == {"new_value", "other old value"}
|
||||
|
||||
cache = SetCache(default=lambda k: {"old_value", "other old value"} if k == "old_key" else NotFound)
|
||||
cache.update("old_key", "old_value", "new_key", "new_value")
|
||||
assert cache.get("old_key") == {"other old value"}
|
||||
assert cache.get("new_key") == {"new_value"}
|
||||
|
||||
cache = SetCache(default=lambda k: {"old_value", "other old value"} if k == "old_key" else {"other new"})
|
||||
cache.update("old_key", "old_value", "new_key", "new_value")
|
||||
assert cache.get("old_key") == {"other old value"}
|
||||
assert cache.get("new_key") == {"other new", "new_value"}
|
||||
|
||||
def test_i_can_delete_values_from_set_cache(self):
|
||||
cache = SetCache()
|
||||
cache.put("key", "value1")
|
||||
cache.put("key", "value2")
|
||||
cache.reset_events()
|
||||
|
||||
cache.delete("key", "fake_value")
|
||||
assert cache.get("key") == {"value1", "value2"}
|
||||
assert len(cache) == 2
|
||||
assert cache.to_add == set()
|
||||
assert cache.to_remove == set()
|
||||
|
||||
cache.delete("key", "value1")
|
||||
assert cache.get("key") == {"value2"}
|
||||
assert cache.to_add == {"key"}
|
||||
assert len(cache) == 1
|
||||
|
||||
cache.delete("key", "value2")
|
||||
assert cache.get("key") is NotFound
|
||||
assert cache.to_remove == {"key"}
|
||||
assert len(cache) == 0
|
||||
|
||||
def test_i_can_delete_key_from_set_cache(self):
|
||||
cache = SetCache()
|
||||
cache.put("key", "value1")
|
||||
cache.put("key", "value2")
|
||||
|
||||
cache.delete("key")
|
||||
assert cache.get("key") is NotFound
|
||||
assert cache.to_remove == {"key"}
|
||||
assert len(cache) == 0
|
||||
|
||||
def test_i_can_delete_a_key_that_does_not_exists(self):
|
||||
cache = SetCache()
|
||||
cache.delete("key")
|
||||
|
||||
assert cache.to_add == set()
|
||||
assert cache.to_remove == set()
|
||||
|
||||
def test_i_can_delete_when_alt_sdp_a_key_from_cache(self):
|
||||
# There is a value in alt_cache_manager,
|
||||
# No remaining value in current cache after deletion
|
||||
# The key must be flagged as Removed
|
||||
cache = SetCache(sdp=FakeSdp(get_value=lambda entry, k: NotFound)).auto_configure("cache_name")
|
||||
cache.put("key", "value")
|
||||
|
||||
cache.delete("key", value=None, alt_sdp=FakeSdp(extend_exists=lambda cache_name, key: True))
|
||||
assert cache.copy() == {"key": Removed}
|
||||
assert cache.to_remove == set()
|
||||
assert cache.to_add == {"key"}
|
||||
|
||||
def test_i_can_delete_when_alt_sdp_a_value_from_cache(self):
|
||||
# There is a value in alt_cache_manager,
|
||||
# No remaining value in current cache after deletion
|
||||
# The key must be flagged as Removed
|
||||
cache = SetCache(sdp=FakeSdp(get_value=lambda entry, k: NotFound)).auto_configure("cache_name")
|
||||
cache.put("key", "value")
|
||||
|
||||
alt_sdp = FakeSdp(get_alt_value=lambda cache_name, key: "xxx", extend_exists=lambda cache_name, key: True)
|
||||
cache.delete("key", value="value", alt_sdp=alt_sdp)
|
||||
assert cache.copy() == {"key": Removed}
|
||||
assert cache.to_remove == set()
|
||||
assert cache.to_add == {"key"}
|
||||
|
||||
def test_i_can_delete_when_alt_sdp_a_value_from_cache_remaining_values(self):
|
||||
# There is a value in alt_cache_manager,
|
||||
# But there is a value in the current cache after deletion
|
||||
cache = SetCache(sdp=FakeSdp(get_value=lambda entry, k: NotFound)).auto_configure("cache_name")
|
||||
cache.put("key", "value1")
|
||||
cache.put("key", "value2")
|
||||
|
||||
cache.delete("key", value="value1", alt_sdp=FakeSdp(extend_exists=lambda cache_name, key: True))
|
||||
assert cache.copy() == {"key": {"value2"}}
|
||||
assert cache.to_remove == set()
|
||||
assert cache.to_add == {"key"}
|
||||
|
||||
def test_i_can_delete_when_alt_sdp_a_key_from_remote_repository(self):
|
||||
# There is a value in alt_cache_manager,
|
||||
# No remaining value in current cache after deletion
|
||||
# The key must be flagged as Removed
|
||||
cache = SetCache(sdp=FakeSdp(get_value=lambda entry, k: {"value1", "value2"})).auto_configure("cache_name")
|
||||
|
||||
cache.delete("key", value=None, alt_sdp=FakeSdp(extend_exists=lambda cache_name, key: True))
|
||||
assert cache.copy() == {"key": Removed}
|
||||
assert cache.to_remove == set()
|
||||
assert cache.to_add == {"key"}
|
||||
|
||||
def test_i_can_delete_when_alt_sdp_a_value_from_remote_repository(self):
|
||||
# There is a value in alt_cache_manager,
|
||||
# No remaining value in current cache after deletion
|
||||
# The key must be flagged as Removed
|
||||
cache = SetCache(sdp=FakeSdp(get_value=lambda entry, k: {"value"})).auto_configure("cache_name")
|
||||
|
||||
cache.delete("key", value="value", alt_sdp=FakeSdp(extend_exists=lambda cache_name, key: True))
|
||||
assert cache.copy() == {"key": Removed}
|
||||
assert cache.to_remove == set()
|
||||
assert cache.to_add == {"key"}
|
||||
|
||||
def test_i_can_delete_when_alt_sdp_a_value_from_remote_repository_remaining_values(self):
|
||||
# There is a value in alt_cache_manager,
|
||||
# But there is a value in the current cache after deletion
|
||||
cache = SetCache(sdp=FakeSdp(get_value=lambda entry, k: {"value1", "value2"})).auto_configure("cache_name")
|
||||
|
||||
cache.delete("key", value="value1", alt_sdp=FakeSdp(extend_exists=lambda cache_name, key: True))
|
||||
assert cache.copy() == {"key": {"value2"}}
|
||||
assert cache.to_remove == set()
|
||||
assert cache.to_add == {"key"}
|
||||
|
||||
def test_i_can_delete_when_alt_sdp_a_key_from_alt_sdp(self):
|
||||
# alt_cache_manager is used because no value in cache or in remote repository
|
||||
# After value deletion, the key is empty
|
||||
cache = SetCache(sdp=FakeSdp(get_value=lambda entry, k: NotFound)).auto_configure("cache_name")
|
||||
|
||||
alt_sdp = FakeSdp(get_alt_value=lambda cache_name, key: {"value1, value2"},
|
||||
extend_exists=lambda cache_name, key: True)
|
||||
|
||||
cache.delete("key", value=None, alt_sdp=alt_sdp)
|
||||
assert cache.copy() == {"key": Removed}
|
||||
assert cache.to_add == {"key"}
|
||||
assert cache.to_remove == set()
|
||||
|
||||
def test_i_can_delete_when_alt_sdp_a_value_from_alt_sdp(self):
|
||||
# alt_cache_manager is used because no value in cache or in remote repository
|
||||
# After value deletion, the key is empty
|
||||
cache = SetCache(sdp=FakeSdp(get_value=lambda entry, k: NotFound)).auto_configure("cache_name")
|
||||
|
||||
alt_sdp = FakeSdp(get_alt_value=lambda cache_name, key: {"value1"},
|
||||
extend_exists=lambda cache_name, key: True)
|
||||
|
||||
cache.delete("key", value="value1", alt_sdp=alt_sdp)
|
||||
assert cache.copy() == {"key": Removed}
|
||||
assert cache.to_add == {"key"}
|
||||
assert cache.to_remove == set()
|
||||
|
||||
def test_i_can_delete_when_alt_sdp_a_value_from_alt_sdp_one_value_remaining(self):
|
||||
# alt_cache_manager is used because no value in cache or in remote repository
|
||||
# After value deletion, the key is empty
|
||||
cache = SetCache(sdp=FakeSdp(get_value=lambda entry, k: NotFound)).auto_configure("cache_name")
|
||||
|
||||
alt_sdp = FakeSdp(get_alt_value=lambda cache_name, key: {"value1", "value2"},
|
||||
extend_exists=lambda cache_name, key: True)
|
||||
|
||||
cache.delete("key", value="value1", alt_sdp=alt_sdp)
|
||||
assert cache.copy() == {"key": {"value2"}}
|
||||
assert cache.to_add == {"key"}
|
||||
assert cache.to_remove == set()
|
||||
|
||||
def test_i_can_delete_when_alt_sdp_a_key_that_does_not_exist_from_alt_sdp(self):
|
||||
# alt_cache_manager is used because no value in cache or in remote repository
|
||||
# After value deletion, the key is empty
|
||||
cache = SetCache(sdp=FakeSdp(get_value=lambda entry, k: NotFound)).auto_configure("cache_name")
|
||||
|
||||
alt_sdp = FakeSdp(get_alt_value=(lambda cache_name, key: {"value1", "value2"} if key == "key" else NotFound),
|
||||
extend_exists=lambda cache_name, key: key == "key")
|
||||
|
||||
cache.delete("key2", value=None, alt_sdp=alt_sdp)
|
||||
assert cache.copy() == {}
|
||||
assert cache.to_add == set()
|
||||
assert cache.to_remove == set()
|
||||
|
||||
def test_i_can_delete_when_alt_sdp_a_value_that_does_not_exist_from_alt_sdp(self):
|
||||
# alt_cache_manager is used because no value in cache or in remote repository
|
||||
# After value deletion, the key is empty
|
||||
cache = SetCache(sdp=FakeSdp(get_value=lambda entry, k: NotFound)).auto_configure("cache_name")
|
||||
|
||||
alt_sdp = FakeSdp(get_alt_value=lambda cache_name, key: {"value1", "value2"},
|
||||
extend_exists=lambda cache_name, key: True)
|
||||
|
||||
cache.delete("key", value="value4", alt_sdp=alt_sdp)
|
||||
assert cache.copy() == {}
|
||||
assert cache.to_add == set()
|
||||
assert cache.to_remove == set()
|
||||
|
||||
def test_i_can_delete_when_alt_sdp_an_already_removed_value_from_alt_sdp(self):
|
||||
# alt_cache_manager is used because no value in cache or in remote repository
|
||||
# But the alternate sdp returns Removed, which means that previous value was deleted
|
||||
# It's like there is nothing to delete
|
||||
cache = SetCache(sdp=FakeSdp(get_value=lambda entry, k: NotFound)).auto_configure("cache_name")
|
||||
|
||||
alt_sdp = FakeSdp(get_alt_value=lambda cache_name, key: Removed,
|
||||
extend_exists=lambda cache_name, key: False)
|
||||
|
||||
cache.delete("key", value="value1", alt_sdp=alt_sdp)
|
||||
assert cache.copy() == {}
|
||||
assert cache.to_add == set()
|
||||
assert cache.to_remove == set()
|
||||
|
||||
def test_i_can_delete_when_alt_sdp_and_cache_is_cleared(self):
|
||||
cache = SetCache(sdp=FakeSdp(get_value=lambda entry, k: NotFound)).auto_configure("cache_name")
|
||||
alt_sdp = FakeSdp(get_alt_value=lambda cache_name, key: {"value"},
|
||||
extend_exists=lambda cache_name, key: True)
|
||||
|
||||
cache.clear()
|
||||
cache.delete("key", value=None, alt_sdp=alt_sdp)
|
||||
assert cache.copy() == {}
|
||||
assert cache.to_add == set()
|
||||
assert cache.to_remove == set()
|
||||
|
||||
cache.delete("key", value="value", alt_sdp=alt_sdp)
|
||||
assert cache.copy() == {}
|
||||
assert cache.to_add == set()
|
||||
assert cache.to_remove == set()
|
||||
Vendored
+224
-431
@@ -8,11 +8,48 @@ from cache.ListCache import ListCache
|
||||
from cache.ListIfNeededCache import ListIfNeededCache
|
||||
from cache.SetCache import SetCache
|
||||
from core.concept import Concept
|
||||
from core.global_symbols import NotFound, Removed
|
||||
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
from tests.cache import FakeSdp
|
||||
|
||||
|
||||
class TestCache(TestUsingMemoryBasedSheerka):
|
||||
def test_i_can_configure(self):
|
||||
cache = Cache()
|
||||
cache.configure(max_size=256,
|
||||
default="default_delegate",
|
||||
extend_exists="extend_exists_delegate",
|
||||
alt_sdp_get="alt_sdp_delegate",
|
||||
sdp=FakeSdp())
|
||||
|
||||
# Caution, in this test, I initialize default, extend_exists and alt_get_delegate with string
|
||||
# to simplify the test, but it real usage, they are lambda
|
||||
# default = lambda sdp, key: sdp.get(cache_name, key) or lambda key: func(key)
|
||||
# extend_exists = lambda sdp, key: sdp.exists(cache_name, key) or lambda key: func(key)
|
||||
# alt_sdp_get = lambda sdp, key: sdp.alt_get(cache_name, key)
|
||||
|
||||
assert cache._max_size == 256
|
||||
assert cache._default == "default_delegate"
|
||||
assert cache._extend_exists == "extend_exists_delegate"
|
||||
assert cache._alt_sdp_get == "alt_sdp_delegate"
|
||||
assert cache._sdp is not None
|
||||
|
||||
def test_i_can_auto_configure(self):
|
||||
sdp = FakeSdp(get_value=lambda cache_name, key: key + 1 if cache_name == "cache_name" else NotFound,
|
||||
extend_exists=lambda cache_name, key: True if cache_name == "cache_name" else False,
|
||||
get_alt_value=lambda cache_name, key: key + 2 if cache_name == "cache_name" else NotFound)
|
||||
|
||||
cache = Cache(sdp=sdp).auto_configure("cache_name")
|
||||
assert cache._default(cache._sdp, 10) == 11
|
||||
assert cache._extend_exists(cache._sdp, 10) == True
|
||||
assert cache._alt_sdp_get(cache._sdp, 10) == 12
|
||||
|
||||
cache = Cache(sdp=sdp).auto_configure("another_cache")
|
||||
assert cache._default(cache._sdp, 10) == NotFound
|
||||
assert cache._extend_exists(cache._sdp, 10) == False
|
||||
assert cache._alt_sdp_get(cache._sdp, 10) == NotFound
|
||||
|
||||
def test_i_can_get_an_retrieve_value_from_cache(self):
|
||||
cache = Cache()
|
||||
cache.put("key", "value")
|
||||
@@ -44,9 +81,26 @@ class TestCache(TestUsingMemoryBasedSheerka):
|
||||
assert len(cache) == maxsize
|
||||
assert not cache.has(key - maxsize)
|
||||
|
||||
def test_i_can_get_a_value_from_alt_sdp(self):
|
||||
cache = Cache(sdp=FakeSdp(get_value=lambda cache_name, key: NotFound)).auto_configure("cache_name")
|
||||
|
||||
alt_sdp = FakeSdp(get_alt_value=lambda cache_name, key: "value found !")
|
||||
assert cache.get("key", alt_sdp=alt_sdp) == "value found !"
|
||||
|
||||
# The value is now in cache
|
||||
assert cache.copy() == {'key': 'value found !'}
|
||||
|
||||
def test_i_cannot_get_a_value_from_alt_sdp_when_cache_is_cleared(self):
|
||||
cache = Cache(sdp=FakeSdp(get_value=lambda cache_name, key: NotFound)).auto_configure("cache_name")
|
||||
cache.clear()
|
||||
|
||||
alt_sdp = FakeSdp(get_alt_value=lambda cache_name, key: "value found !")
|
||||
assert cache.get("key", alt_sdp=alt_sdp) is NotFound
|
||||
assert cache.copy() == {}
|
||||
|
||||
def test_i_can_get_default_value_from_simple_cache(self):
|
||||
cache = Cache()
|
||||
assert cache.get("key") is None
|
||||
assert cache.get("key") is NotFound
|
||||
|
||||
cache = Cache(default=10)
|
||||
assert cache.get("key") == 10
|
||||
@@ -56,7 +110,12 @@ class TestCache(TestUsingMemoryBasedSheerka):
|
||||
assert cache.get("key") == "key_not_found"
|
||||
assert "key" in cache # default callable are put in cache
|
||||
|
||||
def test_i_dont_ask_the_remote_repository_twice(self):
|
||||
cache = Cache(default=lambda sdp, key: sdp.get("cache_name", key),
|
||||
sdp=FakeSdp(get_value=lambda entry, key: key + "_not_found"))
|
||||
assert cache.get("key") == "key_not_found"
|
||||
assert "key" in cache # default callable are put in cache
|
||||
|
||||
def test_i_do_not_ask_the_remote_repository_twice(self):
|
||||
nb_request = []
|
||||
|
||||
cache = Cache(default=lambda key: nb_request.append("requested"))
|
||||
@@ -64,155 +123,6 @@ class TestCache(TestUsingMemoryBasedSheerka):
|
||||
assert cache.get("key") is None
|
||||
assert len(nb_request) == 1
|
||||
|
||||
def test_i_can_put_and_retrieve_value_from_list_cache(self):
|
||||
cache = ListCache()
|
||||
|
||||
cache.put("key", "value")
|
||||
assert cache.get("key") == ["value"]
|
||||
assert len(cache) == 1
|
||||
|
||||
cache.put("key", "value2") # we can append to this list
|
||||
assert cache.get("key") == ["value", "value2"]
|
||||
assert len(cache) == 2
|
||||
|
||||
cache.put("key2", "value")
|
||||
assert cache.get("key2") == ["value"]
|
||||
assert len(cache) == 3
|
||||
|
||||
# duplicates are allowed
|
||||
cache.put("key", "value")
|
||||
assert cache.get("key") == ["value", "value2", "value"]
|
||||
assert len(cache) == 4
|
||||
|
||||
assert cache.copy() == {'key': ['value', 'value2', 'value'], 'key2': ['value']}
|
||||
|
||||
def test_i_can_put_and_retrieve_value_from_list_if_needed_cache(self):
|
||||
cache = ListIfNeededCache()
|
||||
|
||||
cache.put("key", "value")
|
||||
assert cache.get("key") == "value"
|
||||
|
||||
# second time with the same key creates a list
|
||||
cache.put("key", "value2")
|
||||
assert cache.get("key") == ["value", "value2"]
|
||||
assert len(cache) == 2
|
||||
|
||||
# third time, we now have a list
|
||||
cache.put("key", "value3")
|
||||
assert cache.get("key") == ["value", "value2", "value3"]
|
||||
assert len(cache) == 3
|
||||
|
||||
# other keys are not affected
|
||||
cache.put("key2", "value")
|
||||
assert cache.get("key2") == "value"
|
||||
assert len(cache) == 4
|
||||
|
||||
# duplicates are allowed
|
||||
cache.put("key", "value")
|
||||
assert cache.get("key") == ["value", "value2", "value3", "value"]
|
||||
assert len(cache) == 5
|
||||
|
||||
def test_i_can_put_and_retrieve_values_from_set_cache(self):
|
||||
cache = SetCache()
|
||||
|
||||
cache.put("key", "value")
|
||||
assert cache.get("key") == {"value"}
|
||||
assert len(cache) == 1
|
||||
|
||||
# we can add to this set
|
||||
cache.put("key", "value2")
|
||||
assert cache.get("key") == {"value", "value2"}
|
||||
assert len(cache) == 2
|
||||
|
||||
# other keys are not affected
|
||||
cache.put("key2", "value")
|
||||
assert cache.get("key2") == {"value"}
|
||||
assert len(cache) == 3
|
||||
|
||||
# duplicates are removed
|
||||
cache.put("key", "value")
|
||||
assert cache.get("key") == {"value", "value2"}
|
||||
assert len(cache) == 3
|
||||
|
||||
assert cache.copy() == {'key': {'value', 'value2'}, 'key2': {'value'}}
|
||||
|
||||
def test_i_can_put_and_retrieve_value_from_dictionary_cache(self):
|
||||
cache = DictionaryCache()
|
||||
|
||||
# # key must be None
|
||||
# with pytest.raises(KeyError):
|
||||
# cache.put("key", None)
|
||||
#
|
||||
# # value must be a dictionary
|
||||
# with pytest.raises(ValueError):
|
||||
# cache.put(True, "value")
|
||||
|
||||
entry = {"key": "value", "key2": ["value21", "value22"]}
|
||||
cache.put(False, entry)
|
||||
assert len(cache) == 3
|
||||
assert id(cache._cache) == id(entry)
|
||||
assert cache.get("key") == "value"
|
||||
assert cache.get("key2") == ["value21", "value22"]
|
||||
|
||||
# I can append values
|
||||
cache.put(True, {"key": "another_value", "key3": "value3"})
|
||||
assert len(cache) == 4
|
||||
assert cache.get("key") == "another_value"
|
||||
assert cache.get("key2") == ["value21", "value22"]
|
||||
assert cache.get("key3") == "value3"
|
||||
|
||||
# I can reset
|
||||
entry = {"key": "value", "key2": ["value21", "value22"]}
|
||||
cache.put(False, entry)
|
||||
assert len(cache) == 3
|
||||
assert id(cache._cache) == id(entry)
|
||||
assert cache.get("key") == "value"
|
||||
assert cache.get("key2") == ["value21", "value22"]
|
||||
|
||||
assert cache.copy() == {'key': 'value', 'key2': ['value21', 'value22']}
|
||||
|
||||
def test_i_can_put_and_retrieve_values_from_inc_cache(self):
|
||||
cache = IncCache()
|
||||
|
||||
assert cache.get("key") == 1
|
||||
assert cache.get("key") == 2
|
||||
assert cache.get("key") == 3
|
||||
assert cache.get("key2") == 1
|
||||
assert cache.get("key2") == 2
|
||||
|
||||
cache.put("key", 100)
|
||||
assert cache.get("key") == 101
|
||||
|
||||
assert cache.copy() == {'key': 101, 'key2': 2}
|
||||
|
||||
@pytest.mark.parametrize("key", [
|
||||
None,
|
||||
"something"
|
||||
])
|
||||
def test_keys_have_constraints_when_dictionary_cache(self, key):
|
||||
cache = DictionaryCache()
|
||||
with pytest.raises(KeyError):
|
||||
cache.put(key, None)
|
||||
|
||||
@pytest.mark.parametrize("value", [
|
||||
None,
|
||||
"something"
|
||||
])
|
||||
def test_values_have_constraints_when_dictionary_cache(self, value):
|
||||
cache = DictionaryCache()
|
||||
with pytest.raises(ValueError):
|
||||
cache.put(True, value)
|
||||
|
||||
def test_i_can_append_to_a_dictionary_cache_even_if_it_s_new(self):
|
||||
cache = DictionaryCache()
|
||||
|
||||
entry = {"key": "value", "key2": ["value21", "value22"]}
|
||||
cache.put(True, entry)
|
||||
assert len(cache) == 3
|
||||
assert id(cache._cache) != id(entry)
|
||||
assert cache.get("key") == "value"
|
||||
assert cache.get("key2") == ["value21", "value22"]
|
||||
|
||||
def test_i_can_update_from_simple_cache(self):
|
||||
cache = Cache()
|
||||
cache.put("key", "value")
|
||||
@@ -221,98 +131,43 @@ class TestCache(TestUsingMemoryBasedSheerka):
|
||||
assert len(cache._cache) == 1
|
||||
assert len(cache) == 1
|
||||
assert cache.get("key") == "new_value"
|
||||
assert cache.to_add == {"key"}
|
||||
assert cache.to_remove == set()
|
||||
|
||||
cache.reset_events()
|
||||
cache.update("key", "new_value", "another_key", "another_value")
|
||||
assert len(cache._cache) == 1
|
||||
assert len(cache) == 1
|
||||
assert cache.get("key") is None
|
||||
assert cache.get("key") is NotFound
|
||||
assert cache.get("another_key") == "another_value"
|
||||
assert cache.to_add == {"another_key"}
|
||||
assert cache.to_remove == {"key"}
|
||||
|
||||
with pytest.raises(KeyError):
|
||||
cache.update("wrong key", "value", "key", "value")
|
||||
|
||||
def test_i_can_update_from_list_cache(self):
|
||||
cache = ListCache()
|
||||
def test_i_can_update_when_alt_sdp_same_keys(self):
|
||||
cache = Cache(default=lambda sdp, key: sdp.get("cache_name", key),
|
||||
extend_exists=lambda sdp, key: sdp.exists("cache_name", key),
|
||||
sdp=FakeSdp(get_value=lambda cache_name, key: NotFound))
|
||||
|
||||
cache.put("key", "value")
|
||||
cache.put("key", "value2")
|
||||
cache.put("key", "value")
|
||||
cache.update("key", "value", "key", "another value")
|
||||
cache.update("key", "value", "key", "new_value", FakeSdp(extend_exists=lambda cache_name, key: True))
|
||||
|
||||
assert len(cache._cache) == 1
|
||||
assert len(cache) == 3
|
||||
assert cache.get("key") == ["another value", "value2", "value"] # only the first one is affected
|
||||
assert cache.get("key") == "new_value"
|
||||
|
||||
cache.update("key", "value2", "key2", "value2")
|
||||
assert len(cache._cache) == 2
|
||||
assert len(cache) == 3
|
||||
assert cache.get("key") == ["another value", "value"]
|
||||
assert cache.get("key2") == ["value2"]
|
||||
|
||||
cache.update("key2", "value2", "key3", "value2")
|
||||
assert len(cache._cache) == 2
|
||||
assert len(cache) == 3
|
||||
assert cache.get("key") == ["another value", "value"]
|
||||
assert cache.get("key3") == ["value2"]
|
||||
assert cache.get("key2") is None
|
||||
|
||||
with pytest.raises(KeyError):
|
||||
cache.update("wrong key", "value", "key", "value")
|
||||
|
||||
def test_i_can_update_from_list_if_needed_cache(self):
|
||||
cache = ListIfNeededCache()
|
||||
def test_i_can_update_when_alt_sdp_different_keys(self):
|
||||
cache = Cache(default=lambda sdp, key: sdp.get("cache_name", key),
|
||||
extend_exists=lambda sdp, key: sdp.exists("cache_name", key),
|
||||
sdp=FakeSdp(get_value=lambda cache_name, key: NotFound))
|
||||
|
||||
cache.put("key", "value")
|
||||
cache.put("key", "value2")
|
||||
cache.put("key", "value")
|
||||
cache.update("key", "value", "key", "another value")
|
||||
cache.update("key", "value", "key2", "value2", FakeSdp(extend_exists=lambda cache_name, key: True))
|
||||
|
||||
assert len(cache._cache) == 1
|
||||
assert len(cache) == 3
|
||||
assert cache.get("key") == ["another value", "value2", "value"] # only the first one is affected
|
||||
|
||||
cache.update("key", "value2", "key2", "value2")
|
||||
assert len(cache._cache) == 2
|
||||
assert len(cache) == 3
|
||||
assert cache.get("key") == ["another value", "value"]
|
||||
assert cache.get("key2") == "value2"
|
||||
|
||||
cache.update("key2", "value2", "key3", "value2")
|
||||
assert len(cache._cache) == 2
|
||||
assert len(cache) == 3
|
||||
assert cache.get("key") == ["another value", "value"]
|
||||
assert cache.get("key3") == "value2"
|
||||
assert cache.get("key2") is None
|
||||
|
||||
with pytest.raises(KeyError):
|
||||
cache.update("wrong key", "value", "key", "value")
|
||||
|
||||
def test_i_can_update_from_set_cache(self):
|
||||
cache = SetCache()
|
||||
|
||||
cache.put("key", "value")
|
||||
cache.put("key", "value2")
|
||||
cache.update("key", "value", "key", "another value")
|
||||
|
||||
assert len(cache._cache) == 1
|
||||
assert len(cache) == 2
|
||||
assert cache.get("key") == {"another value", "value2"}
|
||||
|
||||
cache.update("key", "value2", "key2", "value2")
|
||||
assert len(cache._cache) == 2
|
||||
assert len(cache) == 2
|
||||
assert cache.get("key") == {"another value"}
|
||||
assert cache.get("key2") == {"value2"}
|
||||
|
||||
cache.update("key", "another value", "key3", "another value")
|
||||
assert len(cache._cache) == 2
|
||||
assert len(cache) == 2
|
||||
assert cache.get("key") is None
|
||||
assert cache.get("key2") == {"value2"}
|
||||
assert cache.get("key3") == {"another value"}
|
||||
|
||||
with pytest.raises(KeyError):
|
||||
cache.update("wrong key", "value", "key", "value")
|
||||
assert cache.get("key") == Removed
|
||||
assert cache.to_add == {"key", "key2"}
|
||||
assert cache.to_remove == set()
|
||||
|
||||
@pytest.mark.parametrize("cache", [
|
||||
Cache(), ListCache(), ListIfNeededCache(), SetCache(), IncCache()
|
||||
@@ -365,21 +220,19 @@ class TestCache(TestUsingMemoryBasedSheerka):
|
||||
cache.put("key", "value")
|
||||
assert cache.exists("key")
|
||||
|
||||
def test_exists_in_dictionary_cache(self):
|
||||
cache = DictionaryCache()
|
||||
assert not cache.exists("key")
|
||||
|
||||
cache.put(True, {"key": "value"})
|
||||
assert cache.exists("key")
|
||||
|
||||
def test_exists_extend(self):
|
||||
cache = Cache(extend_exists=lambda k: True if k == "special_key" else False)
|
||||
assert not cache.exists("key")
|
||||
assert cache.exists("special_key")
|
||||
|
||||
def test_i_can_extend_exists_when_internal_sdp(self):
|
||||
cache = Cache(extend_exists=lambda sdp, k: True if k == "special_key" else False, sdp=FakeSdp)
|
||||
assert not cache.exists("key")
|
||||
assert cache.exists("special_key")
|
||||
|
||||
def test_add_concept_fills_all_dependent_caches(self):
|
||||
sheerka, context, one, two, two_2, three = self.init_concepts("one", "two", Concept("two"), "three")
|
||||
cache_manager = CacheManager(None)
|
||||
cache_manager = CacheManager(cache_only=True, sdp=None)
|
||||
|
||||
cache_manager.register_concept_cache("by_id", Cache(), lambda obj: obj.id, True)
|
||||
cache_manager.register_concept_cache("by_name", ListCache(), lambda obj: obj.name, True)
|
||||
@@ -412,53 +265,13 @@ class TestCache(TestUsingMemoryBasedSheerka):
|
||||
assert cache_manager.get("by_name", "two") == [two, two_2]
|
||||
assert cache_manager.get("by_name2", "two") == [two, two_2]
|
||||
|
||||
def test_default_for_dictionary_cache(self):
|
||||
cache = DictionaryCache(default={"key": "value", "key2": "value2"})
|
||||
|
||||
assert cache.get("key") == "value"
|
||||
assert "key2" in cache
|
||||
assert len(cache) == 2
|
||||
|
||||
cache.clear()
|
||||
assert cache.get("key3") is None
|
||||
assert len(cache) == 2
|
||||
assert "key" in cache
|
||||
assert "key2" in cache
|
||||
|
||||
# default is not modified
|
||||
cache._cache["key"] = "another value" # operation that is normally not possible
|
||||
cache.clear()
|
||||
assert cache.get("key") == "value"
|
||||
|
||||
def test_default_callable_for_dictionary_cache(self):
|
||||
cache = DictionaryCache(default=lambda k: {"key": "value", "key2": "value2"})
|
||||
|
||||
assert cache.get("key") == "value"
|
||||
assert "key2" in cache
|
||||
assert len(cache) == 2
|
||||
|
||||
cache.clear()
|
||||
assert cache.get("key3") is None
|
||||
assert len(cache) == 2
|
||||
assert "key" in cache
|
||||
assert "key2" in cache
|
||||
|
||||
def test_dictionary_cache_cannot_be_null(self):
|
||||
cache = DictionaryCache(default=lambda k: None)
|
||||
assert cache.get("key") is None
|
||||
assert cache._cache == {}
|
||||
|
||||
cache = DictionaryCache(default=None)
|
||||
assert cache.get("key") is None
|
||||
assert cache._cache == {}
|
||||
|
||||
@pytest.mark.parametrize("cache, default, new_value, expected", [
|
||||
(ListCache(), lambda k: None, "value", ["value"]),
|
||||
(ListCache(), lambda k: NotFound, "value", ["value"]),
|
||||
(ListCache(), lambda k: ["value"], "value", ["value", "value"]),
|
||||
(ListIfNeededCache(), lambda k: None, "value", "value"),
|
||||
(ListIfNeededCache(), lambda k: NotFound, "value", "value"),
|
||||
(ListIfNeededCache(), lambda k: "value", "value1", ["value", "value1"]),
|
||||
(ListIfNeededCache(), lambda k: ["value1", "value2"], "value1", ["value1", "value2", "value1"]),
|
||||
(SetCache(), lambda k: None, "value", {"value"}),
|
||||
(SetCache(), lambda k: NotFound, "value", {"value"}),
|
||||
(SetCache(), lambda k: {"value"}, "value", {"value"}),
|
||||
(SetCache(), lambda k: {"value1"}, "value2", {"value1", "value2"}),
|
||||
])
|
||||
@@ -469,7 +282,7 @@ class TestCache(TestUsingMemoryBasedSheerka):
|
||||
assert cache.get("key") == expected
|
||||
|
||||
def test_default_is_called_before_updating_simple_cache(self):
|
||||
cache = Cache(default=lambda k: None)
|
||||
cache = Cache(default=lambda k: NotFound)
|
||||
with pytest.raises(KeyError):
|
||||
cache.update("old_key", "old_value", "new_key", "new_value")
|
||||
|
||||
@@ -477,180 +290,70 @@ class TestCache(TestUsingMemoryBasedSheerka):
|
||||
cache.update("old_key", "old_value", "new_key", "new_value")
|
||||
assert cache.get("new_key") == "new_value"
|
||||
|
||||
def test_default_is_called_before_updating_list_cache(self):
|
||||
cache = ListCache(default=lambda k: None)
|
||||
with pytest.raises(KeyError):
|
||||
cache.update("old_key", "old_value", "new_key", "new_value")
|
||||
|
||||
cache = ListCache(default=lambda k: ["old_value", "other old value"])
|
||||
cache.update("old_key", "old_value", "old_key", "new_value")
|
||||
assert cache.get("old_key") == ["new_value", "other old value"]
|
||||
|
||||
cache = ListCache(default=lambda k: ["old_value", "other old value"] if k == "old_key" else None)
|
||||
cache.update("old_key", "old_value", "new_key", "new_value")
|
||||
assert cache.get("old_key") == ["other old value"]
|
||||
assert cache.get("new_key") == ["new_value"]
|
||||
|
||||
cache = ListCache(default=lambda k: ["old_value", "other old value"] if k == "old_key" else ["other new"])
|
||||
cache.update("old_key", "old_value", "new_key", "new_value")
|
||||
assert cache.get("old_key") == ["other old value"]
|
||||
assert cache.get("new_key") == ["other new", "new_value"]
|
||||
|
||||
def test_default_is_called_before_updating_list_if_needed_cache(self):
|
||||
cache = ListIfNeededCache(default=lambda k: None)
|
||||
with pytest.raises(KeyError):
|
||||
cache.update("old_key", "old_value", "new_key", "new_value")
|
||||
|
||||
cache = ListIfNeededCache(default=lambda k: "old_value")
|
||||
cache.update("old_key", "old_value", "old_key", "new_value")
|
||||
assert cache.get("old_key") == "new_value"
|
||||
|
||||
cache = ListIfNeededCache(default=lambda k: ["old_value", "other old value"])
|
||||
cache.update("old_key", "old_value", "old_key", "new_value")
|
||||
assert cache.get("old_key") == ["new_value", "other old value"]
|
||||
|
||||
cache = ListIfNeededCache(default=lambda k: ["old_value", "other old value"] if k == "old_key" else None)
|
||||
cache.update("old_key", "old_value", "new_key", "new_value")
|
||||
assert cache.get("old_key") == ["other old value"]
|
||||
assert cache.get("new_key") == "new_value"
|
||||
|
||||
def test_default_is_called_before_updating_set_cache(self):
|
||||
cache = SetCache(default=lambda k: None)
|
||||
with pytest.raises(KeyError):
|
||||
cache.update("old_key", "old_value", "new_key", "new_value")
|
||||
|
||||
cache = SetCache(default=lambda k: {"old_value", "other old value"})
|
||||
cache.update("old_key", "old_value", "old_key", "new_value")
|
||||
assert cache.get("old_key") == {"new_value", "other old value"}
|
||||
|
||||
cache = SetCache(default=lambda k: {"old_value", "other old value"} if k == "old_key" else None)
|
||||
cache.update("old_key", "old_value", "new_key", "new_value")
|
||||
assert cache.get("old_key") == {"other old value"}
|
||||
assert cache.get("new_key") == {"new_value"}
|
||||
|
||||
cache = SetCache(default=lambda k: {"old_value", "other old value"} if k == "old_key" else {"other new"})
|
||||
cache.update("old_key", "old_value", "new_key", "new_value")
|
||||
assert cache.get("old_key") == {"other old value"}
|
||||
assert cache.get("new_key") == {"other new", "new_value"}
|
||||
|
||||
def test_i_can_delete_an_entry_from_cache(self):
|
||||
cache = Cache()
|
||||
cache.put("key", "value")
|
||||
|
||||
assert cache.get("key") == "value"
|
||||
cache.delete("key")
|
||||
assert cache.get("key") is None
|
||||
assert cache.get("key") is NotFound
|
||||
assert cache.to_remove == {"key"}
|
||||
|
||||
def test_i_can_delete_values_from_set_cache(self):
|
||||
cache = SetCache()
|
||||
cache.put("key", "value1")
|
||||
cache.put("key", "value2")
|
||||
cache.reset_events()
|
||||
def test_i_can_delete_when_entry_is_only_in_db(self):
|
||||
cache = Cache(default=lambda k: "value" if k == 'key' else NotFound)
|
||||
|
||||
cache.delete("key", "fake_value")
|
||||
assert cache.get("key") == {"value1", "value2"}
|
||||
assert len(cache) == 2
|
||||
cache.delete("another_key")
|
||||
assert cache.copy() == {}
|
||||
assert cache.to_add == set()
|
||||
assert cache.to_remove == set()
|
||||
|
||||
cache.delete("key", "value1")
|
||||
assert cache.get("key") == {"value2"}
|
||||
cache.delete("key")
|
||||
assert cache.copy() == {}
|
||||
assert cache.to_add == set()
|
||||
assert cache.to_remove == {"key"}
|
||||
|
||||
def test_i_can_delete_an_entry_from_cache_when_alt_sdp_and_value_in_cache(self):
|
||||
# There is a value in alt_cache_manager,
|
||||
# No remaining value in current cache after deletion
|
||||
# The key must be flagged as Removed
|
||||
cache = Cache(extend_exists=lambda sdp, k: sdp.exists("cache_name", k))
|
||||
cache.put("key", "value")
|
||||
|
||||
cache.delete("key", value=None, alt_sdp=FakeSdp(extend_exists=lambda cache_name, key: True))
|
||||
assert cache.copy() == {"key": Removed}
|
||||
assert cache.to_add == {"key"}
|
||||
assert len(cache) == 1
|
||||
|
||||
cache.delete("key", "value2")
|
||||
assert cache.get("key") is None
|
||||
assert cache.to_remove == {"key"}
|
||||
assert len(cache) == 0
|
||||
|
||||
def test_i_can_delete_key_from_set_cache(self):
|
||||
cache = SetCache()
|
||||
cache.put("key", "value1")
|
||||
cache.put("key", "value2")
|
||||
|
||||
cache.delete("key")
|
||||
assert cache.get("key") is None
|
||||
assert cache.to_remove == {"key"}
|
||||
assert len(cache) == 0
|
||||
|
||||
def test_i_can_delete_a_key_that_does_not_exists(self):
|
||||
cache = SetCache()
|
||||
cache.delete("key")
|
||||
|
||||
assert cache.to_add == set()
|
||||
assert cache.to_remove == set()
|
||||
|
||||
def test_i_can_delete_from_a_key_from_list_id_needed(self):
|
||||
cache = ListIfNeededCache()
|
||||
cache.put("key", "value1")
|
||||
cache.put("key", "value11")
|
||||
cache.put("key2", "value2")
|
||||
cache.put("key2", "value22")
|
||||
cache.put("key2", "value222")
|
||||
cache.put("key3", "value3")
|
||||
cache.put("key3", "value33")
|
||||
cache.put("key4", "value4")
|
||||
cache.reset_events()
|
||||
def test_i_can_delete_an_entry_from_cache_when_alt_sdp_when_in_remote_repository(self):
|
||||
# There is a value in alt_cache_manager,
|
||||
# No remaining value in current cache after deletion
|
||||
# The key must be flagged as Removed
|
||||
cache = Cache(default=lambda k: "value", extend_exists=lambda sdp, k: sdp.exists("cache_name", k))
|
||||
|
||||
assert len(cache) == 8
|
||||
|
||||
# I can remove a whole key
|
||||
cache.delete("key")
|
||||
assert cache.get("key") is None
|
||||
assert len(cache) == 6
|
||||
assert cache.to_remove == {"key"}
|
||||
assert cache.to_add == set()
|
||||
|
||||
# I can remove an element while a list is remaining
|
||||
cache.reset_events()
|
||||
cache.delete("key2", "value22")
|
||||
assert cache.get("key2") == ["value2", "value222"]
|
||||
assert len(cache) == 5
|
||||
assert cache.to_add == {"key2"}
|
||||
cache.delete("key", value=None, alt_sdp=FakeSdp(extend_exists=lambda cache_name, key: True))
|
||||
assert cache.copy() == {"key": Removed}
|
||||
assert cache.to_add == {"key"}
|
||||
assert cache.to_remove == set()
|
||||
|
||||
# I can remove an element while a single element is remaining
|
||||
cache.reset_events()
|
||||
cache.delete("key3", "value33")
|
||||
assert cache.get("key3") == "value3"
|
||||
assert len(cache) == 4
|
||||
assert cache.to_add == {"key3"}
|
||||
def test_i_can_delete_an_entry_from_cache_when_alt_sdp_and_no_value_in_cache_or_remote_repository(self):
|
||||
# alt_cache_manager is used when no value found
|
||||
cache = Cache(default=lambda sdp, k: sdp.get("cache_name", k),
|
||||
extend_exists=lambda sdp, k: sdp.exists("cache_name", k),
|
||||
sdp=FakeSdp(get_value=lambda entry, k: NotFound))
|
||||
|
||||
cache.delete("key", value=None, alt_sdp=FakeSdp(extend_exists=lambda cache_name, key: True))
|
||||
assert cache.copy() == {"key": Removed}
|
||||
assert cache.to_add == {"key"}
|
||||
assert cache.to_remove == set()
|
||||
|
||||
# I can remove an element while nothing remains
|
||||
cache.reset_events()
|
||||
cache.delete("key4", "value4")
|
||||
assert cache.get("key4") is None
|
||||
assert len(cache) == 3
|
||||
assert cache.to_remove == {"key4"}
|
||||
assert cache.to_add == set()
|
||||
def test_no_error_when_deleting_a_key_that_does_not_exists_when_alt_sdp(self):
|
||||
# alt_cache_manager is used when no value found
|
||||
cache = Cache(default=lambda sdp, k: sdp.get("cache_name", k),
|
||||
extend_exists=lambda sdp, k: sdp.exists("cache_name", k),
|
||||
sdp=FakeSdp(get_value=lambda entry, k: NotFound))
|
||||
|
||||
# I do not remove when the value is not the same
|
||||
cache.reset_events()
|
||||
cache.delete("key3", "value33") # value33 was already remove
|
||||
assert cache.get("key3") == "value3"
|
||||
assert len(cache) == 3
|
||||
assert cache.to_add == set()
|
||||
assert cache.to_remove == set()
|
||||
|
||||
def test_deleting_a_list_if_need_entry_that_does_not_exist_is_not_an_error(self):
|
||||
cache = ListIfNeededCache()
|
||||
cache.put("key", "value1")
|
||||
|
||||
cache.reset_events()
|
||||
cache.delete("key3")
|
||||
assert len(cache) == 1
|
||||
assert cache.to_add == set()
|
||||
assert cache.to_remove == set()
|
||||
|
||||
cache.delete("key3", "value")
|
||||
assert len(cache) == 1
|
||||
assert cache.to_add == set()
|
||||
assert cache.to_remove == set()
|
||||
|
||||
cache.delete("key", "value2")
|
||||
assert len(cache) == 1
|
||||
cache.delete("key", value=None, alt_sdp=FakeSdp(extend_exists=lambda cache_name, key: False))
|
||||
assert cache.copy() == {}
|
||||
assert cache.to_add == set()
|
||||
assert cache.to_remove == set()
|
||||
|
||||
@@ -689,6 +392,38 @@ class TestCache(TestUsingMemoryBasedSheerka):
|
||||
assert cache.get("2") == ("2", "2")
|
||||
assert cache.get("3") == ("3", "3")
|
||||
|
||||
assert cache.to_add == {"1", "2", "3"}
|
||||
assert cache.to_remove == set()
|
||||
|
||||
def test_i_can_populate_using_internal_sdp(self):
|
||||
items = [("1", "1"), ("2", "2"), ("3", "3")]
|
||||
cache = Cache(sdp=FakeSdp(populate=items))
|
||||
|
||||
cache.populate(lambda sdp: sdp.populate(), lambda item: item[0])
|
||||
|
||||
assert len(cache) == 3
|
||||
assert cache.get("1") == ("1", "1")
|
||||
assert cache.get("2") == ("2", "2")
|
||||
assert cache.get("3") == ("3", "3")
|
||||
|
||||
assert cache.to_add == {"1", "2", "3"}
|
||||
assert cache.to_remove == set()
|
||||
|
||||
def test_i_can_reset_the_event_after_populate(self):
|
||||
items = [("1", "1"), ("2", "2"), ("3", "3")]
|
||||
cache = Cache()
|
||||
cache.to_add = {"some_value"}
|
||||
cache.to_remove = {"some_other_value"}
|
||||
|
||||
cache.populate(lambda: items, lambda item: item[0], reset_events=True)
|
||||
|
||||
assert len(cache) == 3
|
||||
assert cache.copy() == {"1": ("1", "1"),
|
||||
"2": ("2", "2"),
|
||||
"3": ("3", "3")}
|
||||
assert cache.to_add == {"some_value"}
|
||||
assert cache.to_remove == {"some_other_value"}
|
||||
|
||||
def test_max_size_is_respected_when_populate(self):
|
||||
items = [("1", "1"), ("2", "2"), ("3", "3"), ("4", "4"), ("5", "5")]
|
||||
cache = Cache(max_size=3)
|
||||
@@ -709,3 +444,61 @@ class TestCache(TestUsingMemoryBasedSheerka):
|
||||
res = cache.get_all()
|
||||
assert len(res) == 3
|
||||
assert list(res) == [('1', '1'), ('2', '2'), ('3', '3')]
|
||||
|
||||
def test_i_can_clone_cache(self):
|
||||
cache = Cache(max_size=256,
|
||||
default=lambda sdp, key: sdp.get("cache_name", key),
|
||||
extend_exists=False,
|
||||
alt_sdp_get=lambda sdp, key: sdp.alt_get("cache_name", key),
|
||||
sdp=FakeSdp(get_value=lambda entry, key: key + "_not_found"))
|
||||
cache.put("key1", "value1")
|
||||
cache.put("key2", "value2")
|
||||
|
||||
clone = cache.clone()
|
||||
assert type(cache) == type(clone)
|
||||
assert clone._max_size == cache._max_size
|
||||
assert clone._default == cache._default
|
||||
assert clone._extend_exists == cache._extend_exists
|
||||
assert clone._alt_sdp_get == cache._alt_sdp_get
|
||||
assert clone._sdp == cache._sdp
|
||||
assert clone._cache == {} # value are not copied
|
||||
assert clone._initialized_keys == set()
|
||||
assert clone._current_size == 0
|
||||
assert clone.to_add == set()
|
||||
assert clone.to_remove == set()
|
||||
|
||||
clone.configure(sdp=FakeSdp(lambda entry, key: key + " found !"))
|
||||
|
||||
assert cache.get("key3") == "key3_not_found"
|
||||
assert clone.get("key3") == "key3 found !"
|
||||
|
||||
@pytest.mark.parametrize("cache", [
|
||||
Cache(),
|
||||
DictionaryCache(),
|
||||
IncCache(),
|
||||
ListCache(),
|
||||
ListIfNeededCache()
|
||||
])
|
||||
def test_i_can_clone_all_caches(self, cache):
|
||||
clone = cache.clone()
|
||||
assert type(clone) == type(cache)
|
||||
|
||||
def test_sanity_check_on_list_if_needed_cache(self):
|
||||
cache = ListIfNeededCache()
|
||||
clone = cache.clone()
|
||||
|
||||
clone.put("key", "value1")
|
||||
clone.put("key", "value2")
|
||||
|
||||
assert clone.get("key") == ["value1", "value2"]
|
||||
|
||||
def test_i_can_clear_when_alt_sdp(self):
|
||||
cache = Cache().auto_configure("cache_name")
|
||||
|
||||
cache.put("key1", "value1")
|
||||
cache.put("key2", "value2")
|
||||
|
||||
cache.clear()
|
||||
|
||||
assert cache.copy() == {}
|
||||
assert cache._is_cleared
|
||||
|
||||
Vendored
-157
@@ -1,157 +0,0 @@
|
||||
import pytest
|
||||
from cache.Cache import Cache
|
||||
from cache.CacheManager import CacheManager, ConceptNotFound
|
||||
from cache.DictionaryCache import DictionaryCache
|
||||
from cache.ListCache import ListCache
|
||||
from cache.ListIfNeededCache import ListIfNeededCache
|
||||
from core.concept import Concept
|
||||
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
|
||||
|
||||
class TestCacheManager(TestUsingMemoryBasedSheerka):
|
||||
def test_i_do_not_push_into_sdp_when_cache_only(self):
|
||||
sheerka = self.get_sheerka()
|
||||
context = self.get_context(sheerka)
|
||||
|
||||
cache_manager = CacheManager(True)
|
||||
cache_manager.register_cache("test", Cache(), persist=True)
|
||||
cache_manager.put("test", "key", "value")
|
||||
|
||||
cache_manager.commit(context)
|
||||
assert not sheerka.sdp.exists("test", "key")
|
||||
|
||||
def test_i_do_not_get_value_from_sdp_when_cache_only_is_true(self):
|
||||
sheerka = self.get_sheerka()
|
||||
context = self.get_context(sheerka)
|
||||
with sheerka.sdp.get_transaction(context.event) as transaction:
|
||||
transaction.add("test", "key", "value")
|
||||
|
||||
cache = Cache(default=lambda k: sheerka.sdp.get("test", k))
|
||||
|
||||
cache_manager = CacheManager(True)
|
||||
cache_manager.register_cache("test", cache, persist=True)
|
||||
|
||||
assert cache_manager.get("test", "key") is None
|
||||
|
||||
def test_i_can_get_value_from_sdp_when_cache_only_is_false(self):
|
||||
sheerka = self.get_sheerka()
|
||||
context = self.get_context(sheerka)
|
||||
with sheerka.sdp.get_transaction(context.event) as transaction:
|
||||
transaction.add("test", "key", "value")
|
||||
|
||||
cache = Cache(default=lambda k: sheerka.sdp.get("test", k))
|
||||
|
||||
cache_manager = CacheManager(False)
|
||||
cache_manager.register_cache("test", cache, persist=True)
|
||||
|
||||
assert cache_manager.get("test", "key") == "value"
|
||||
|
||||
def test_i_can_commit_simple_cache(self):
|
||||
sheerka = self.get_sheerka()
|
||||
context = self.get_context(sheerka)
|
||||
|
||||
cache_manager = CacheManager(False)
|
||||
cache_manager.register_cache("test", Cache(), persist=True)
|
||||
cache = cache_manager.caches["test"].cache
|
||||
|
||||
cache_manager.put("test", "key", "value")
|
||||
|
||||
cache_manager.commit(context)
|
||||
assert sheerka.sdp.get("test", "key") == "value"
|
||||
|
||||
cache.update("key", "value", "key", "another_value")
|
||||
cache_manager.commit(context)
|
||||
assert sheerka.sdp.get("test", "key") == "another_value"
|
||||
|
||||
cache.update("key", "another_value", "key2", "another_value")
|
||||
cache_manager.commit(context)
|
||||
assert sheerka.sdp.get("test", "key") is None
|
||||
assert sheerka.sdp.get("test", "key2") == "another_value"
|
||||
|
||||
def test_i_can_commit_list_cache(self):
|
||||
sheerka = self.get_sheerka()
|
||||
context = self.get_context(sheerka)
|
||||
|
||||
cache_manager = CacheManager(False)
|
||||
cache_manager.register_cache("test", ListCache(), persist=True)
|
||||
cache = cache_manager.caches["test"].cache
|
||||
|
||||
cache.put("key", "value")
|
||||
cache_manager.commit(context)
|
||||
assert sheerka.sdp.get("test", "key") == ["value"]
|
||||
|
||||
cache.put("key", "value2")
|
||||
cache_manager.commit(context)
|
||||
assert sheerka.sdp.get("test", "key") == ["value", "value2"]
|
||||
|
||||
cache.update("key", "value2", "key2", "value2")
|
||||
cache_manager.commit(context)
|
||||
assert sheerka.sdp.get("test", "key") == ["value"]
|
||||
assert sheerka.sdp.get("test", "key2") == ["value2"]
|
||||
|
||||
cache.update("key2", "value2", "key3", "value2")
|
||||
cache_manager.commit(context)
|
||||
assert sheerka.sdp.get("test", "key") == ["value"]
|
||||
assert sheerka.sdp.get("test", "key2") is None
|
||||
assert sheerka.sdp.get("test", "key3") == ["value2"]
|
||||
|
||||
def test_i_can_commit_dictionary_cache(self):
|
||||
sheerka = self.get_sheerka()
|
||||
context = self.get_context(sheerka)
|
||||
|
||||
cache_manager = CacheManager(False)
|
||||
cache_manager.register_cache("test", DictionaryCache(), persist=True)
|
||||
cache = cache_manager.caches["test"].cache
|
||||
|
||||
cache.put(False, {"key": "value", "key2": "value2"})
|
||||
cache_manager.commit(context)
|
||||
assert sheerka.sdp.get("test") == {"key": "value", "key2": "value2"}
|
||||
assert sheerka.sdp.get("test", "key") == "value"
|
||||
|
||||
cache.put(False, {"key": "value", "key2": "value2", "key3": "value3"})
|
||||
cache_manager.commit(context)
|
||||
assert sheerka.sdp.get("test") == {"key": "value", "key2": "value2", "key3": "value3"}
|
||||
|
||||
def test_i_can_remove_a_concept_from_concepts_caches(self):
|
||||
cache_manager = CacheManager(True)
|
||||
cache_manager.register_concept_cache("id", Cache(), lambda c: c.id, True)
|
||||
cache_manager.register_concept_cache("key", ListIfNeededCache(), lambda c: c.key, True)
|
||||
|
||||
sheerka, context, one, two, three, two_bis = self.init_concepts("one", "two", "three", Concept("two", body="2"))
|
||||
|
||||
for concept in [one, two, three, two_bis]:
|
||||
cache_manager.add_concept(concept)
|
||||
|
||||
# sanity check
|
||||
cache_def = cache_manager.caches["id"]
|
||||
assert cache_def.cache.copy() == {one.id: one, two.id: two, three.id: three, two_bis.id: two_bis}
|
||||
cache_def = cache_manager.caches["key"]
|
||||
assert cache_def.cache.copy() == {one.key: one, two.key: [two, two_bis], three.key: three}
|
||||
|
||||
for cache_name in cache_manager.concept_caches:
|
||||
cache_manager.caches[cache_name].cache.reset_events()
|
||||
|
||||
cache_manager.remove_concept(sheerka.new(("two", two_bis.id)))
|
||||
|
||||
cache_def = cache_manager.caches["id"]
|
||||
assert cache_def.cache.copy() == {one.id: one, two.id: two, three.id: three}
|
||||
assert cache_def.cache.to_remove == {two_bis.id}
|
||||
assert cache_def.cache.to_add == set()
|
||||
assert len(cache_def.cache) == 3
|
||||
|
||||
cache_def = cache_manager.caches["key"]
|
||||
assert cache_def.cache.copy() == {one.key: one, two.key: two, three.key: three}
|
||||
assert cache_def.cache.to_remove == set()
|
||||
assert cache_def.cache.to_add == {"two"}
|
||||
assert len(cache_def.cache) == 3
|
||||
|
||||
def test_i_cannot_remove_a_concept_that_does_not_exists(self):
|
||||
cache_manager = CacheManager(True)
|
||||
cache_manager.register_concept_cache("id", Cache(), lambda c: c.id, True)
|
||||
cache_manager.register_concept_cache("key", ListIfNeededCache(), lambda c: c.key, True)
|
||||
|
||||
with pytest.raises(ConceptNotFound) as ex:
|
||||
cache_manager.remove_concept(Concept("foo", id="1001"))
|
||||
|
||||
assert ex.value.concept == Concept("foo", id="1001")
|
||||
Reference in New Issue
Block a user