import pytest from base import BaseTest from caching.ListIfNeededCache import ListIfNeededCache from common.global_symbols import NotFound, Removed from tests.caching import FakeSdp class TestListIfNeededCache(BaseTest): 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_and_then_put_back(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) # remove all values cache.put("key", "value") assert cache.copy() == {"key": "value"} assert cache.to_remove == set() assert cache.to_add == {"key"} def test_i_can_delete_when_alt_sdp_a_value_from_cache_remaining_one_value(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_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") cache.put("key", "value3") 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', 'value3']} 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_key_from_remote_repository_and_then_put_back(self): 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) # remove all values cache.put("key", "value") assert cache.copy() == {"key": "value"} assert cache.to_remove == set() assert cache.to_add == {"key"} def test_i_can_delete_when_alt_sdp_a_value_from_remote_repository_remaining_one_value(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_and_then_put_back(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) cache.put("key", "value") assert cache.copy() == {"key": "value"} 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_deleting_an_entry_that_does_not_exist_from_a_list_is_not_an_error(self): cache = ListIfNeededCache() cache.put("key", "value1") cache.put("key", "value2") cache.reset_events() cache.delete("key", "value3") assert len(cache) == 2 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() def test_i_can_add_when_alt_sdp_from_a_removed_remote_repository(self): cache = ListIfNeededCache(sdp=FakeSdp(get_value=lambda entry, k: Removed)).auto_configure("cache_name") cache.put("key", "value") assert cache.copy() == {"key": "value"} assert cache.to_remove == set() assert cache.to_add == {"key"} def test_i_can_add_when_alt_sdp_from_a_removed_remote_repository_from_alt_sdp(self): # The key is removed in the sub layers # We can put it back 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.put("key", "value", alt_sdp=alt_sdp) assert cache.copy() == {"key": "value"} assert cache.to_remove == set() assert cache.to_add == {"key"}