Files
kodjo e41094f908 Fixed #8
Fixed #12
Fixed #13
Fixed #14
2023-05-08 17:50:28 +02:00

541 lines
25 KiB
Python

import pytest
from base import BaseTest
from caching.SetCache import SetCache
from common.global_symbols import NotFound, Removed
from tests.caching import FakeSdp
class TestSetCache(BaseTest):
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_and_then_put_back(self):
# There is a value in alt_cache_manager,
# No remaining value in current cache after deletion
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)
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_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_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 = 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))
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_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_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 = 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)
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_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()
def test_i_can_add_when_alt_sdp_from_a_removed_remote_repository(self):
cache = SetCache(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 = 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.put("key", "value", alt_sdp=alt_sdp)
assert cache.copy() == {"key": {"value"}}
assert cache.to_remove == set()
assert cache.to_add == {"key"}