From fed0735eb9bfa76acfec9b931c7342edc52f1dbd Mon Sep 17 00:00:00 2001 From: Kodjo Sossouvi Date: Thu, 23 Jan 2020 17:03:36 +0100 Subject: [PATCH] Added events history --- src/core/sheerka/Sheerka.py | 7 +- src/core/sheerka/SheerkaDump.py | 23 +++++ src/evaluators/PythonEvaluator.py | 1 + src/sdp/sheerkaDataProvider.py | 89 +++++++++++++----- src/sdp/sheerkaSerializer.py | 6 +- tests/sdp/test_sheerkaDataProvider.py | 128 ++++++++++++++++++++------ 6 files changed, 199 insertions(+), 55 deletions(-) diff --git a/src/core/sheerka/Sheerka.py b/src/core/sheerka/Sheerka.py index 8614e14..175cbc2 100644 --- a/src/core/sheerka/Sheerka.py +++ b/src/core/sheerka/Sheerka.py @@ -96,7 +96,7 @@ class Sheerka(Concept): if self.sdp.first_time: self.sdp.set_key(self.USER_CONCEPTS_KEYS, 1000) - event = Event("Initializing Sheerka.") + event = Event("Initializing Sheerka.", user=self.name) self.sdp.save_event(event) exec_context = ExecutionContext(self.key, event, self) @@ -547,6 +547,11 @@ class Sheerka(Concept): return sorted(res, key=lambda i: int(i.id)) + def history(self, page=10, start=0): + """Gets the history of all commands""" + return self.sdp.load_events(page, start) + + def test(self): return f"I have access to Sheerka !" diff --git a/src/core/sheerka/SheerkaDump.py b/src/core/sheerka/SheerkaDump.py index f2abd89..3a55ff3 100644 --- a/src/core/sheerka/SheerkaDump.py +++ b/src/core/sheerka/SheerkaDump.py @@ -42,3 +42,26 @@ class SheerkaDump: self.sheerka.log.info(f"body : {c.body}") self.sheerka.log.info(f"digest : {c.get_digest()}") first = False + + def dump_history(self, page=20, start=0): + count = 0 + resolved_page = page if page > 0 else 50 + page_count = 0 + + while count < page if page > 0 else True: + history = self.sheerka.history(resolved_page, start + page_count * resolved_page) + try: + h = next(history) + except StopIteration: + break + + while True: + try: + if h.user != self.sheerka.name: + self.sheerka.log.info(h) + count += 1 + h = next(history) + except StopIteration: + break + + page_count += 1 diff --git a/src/evaluators/PythonEvaluator.py b/src/evaluators/PythonEvaluator.py index 1ec6206..da17fc9 100644 --- a/src/evaluators/PythonEvaluator.py +++ b/src/evaluators/PythonEvaluator.py @@ -64,6 +64,7 @@ class PythonEvaluator(OneReturnValueEvaluator): "desc": context.sheerka.dump_handler.dump_desc, "concepts": context.sheerka.dump_handler.dump_concepts, "definitions": context.sheerka.dump_handler.dump_definitions, + "history": context.sheerka.dump_handler.dump_history, } if context.obj: context.log(self.verbose_log, diff --git a/src/sdp/sheerkaDataProvider.py b/src/sdp/sheerkaDataProvider.py index 166ea31..ebe61f0 100644 --- a/src/sdp/sheerkaDataProvider.py +++ b/src/sdp/sheerkaDataProvider.py @@ -25,13 +25,17 @@ class Event(object): Class that represents something that modifies the state of the system """ - def __init__(self, message="", user="", date=datetime.now()): + def __init__(self, message="", user="", date=datetime.now(), parents=None): self.version = 1 self.user = user self.date = date self.message = message + self.parents = parents self._digest = None + def __str__(self): + return f"{self.date.strftime('%d/%m/%Y %H:%M:%S')} {self.message}" + def get_digest(self): """ Returns the digest of the event @@ -48,7 +52,8 @@ class Event(object): if not isinstance(self.message, str): raise NotImplementedError - self._digest = hashlib.sha256(f"Event:{self.user}{self.date}{self.message}".encode("utf-8")).hexdigest() + to_hash = f"Event:{self.user}{self.date}{self.message}{self.parents}".encode("utf-8") + self._digest = hashlib.sha256(to_hash).hexdigest() return self._digest def to_dict(self): @@ -58,6 +63,7 @@ class Event(object): self.user = as_dict["user"] self.date = datetime.fromisoformat(as_dict["date"]) self.message = as_dict["message"] + self.parents = as_dict["parents"] class ObjToUpdate: @@ -280,6 +286,7 @@ class SheerkaDataProvider: ObjectsFolder = "objects" CacheFolder = "cache" HeadFile = "HEAD" + LastEventFile = "LAST_EVENT" KeysFile = "keys" REF_PREFIX = "##REF##:" @@ -365,7 +372,7 @@ class SheerkaDataProvider: if is_ref and not isinstance(obj, dict): raise SheerkaDataProviderError("is_ref can only be used with dictionaries", obj) - snapshot = self.get_snapshot() + snapshot = self.get_snapshot(SheerkaDataProvider.HeadFile) state = self.load_state(snapshot) self.log.debug(f"Adding obj '{obj}' in entry '{entry}' (allow_multiple={allow_multiple}, use_ref={use_ref})") @@ -400,7 +407,7 @@ class SheerkaDataProvider: state.update(entry, obj) new_snapshot = self.save_state(state) - self.set_snapshot(new_snapshot) + self.set_snapshot(SheerkaDataProvider.HeadFile, new_snapshot) return entry, key def add_with_auto_key(self, event_digest: str, entry, obj): @@ -419,7 +426,7 @@ class SheerkaDataProvider: def add_unique(self, event_digest: str, entry, obj): """Add an entry and make sure it's unique""" - snapshot = self.get_snapshot() + snapshot = self.get_snapshot(SheerkaDataProvider.HeadFile) state = self.load_state(snapshot) state.parents = [] if snapshot is None else [snapshot] @@ -434,7 +441,7 @@ class SheerkaDataProvider: state.data[entry].add(obj) new_snapshot = self.save_state(state) - self.set_snapshot(new_snapshot) + self.set_snapshot(SheerkaDataProvider.HeadFile, new_snapshot) return (None if already_exist else entry), None def set(self, event_digest, entry, obj, use_ref=False, is_ref=False): @@ -455,7 +462,7 @@ class SheerkaDataProvider: if is_ref and not isinstance(obj, dict): raise SheerkaDataProviderError("is_ref can only be used with dictionaries", obj) - snapshot = self.get_snapshot() + snapshot = self.get_snapshot(SheerkaDataProvider.HeadFile) state = self.load_state(snapshot) state.parents = [] if snapshot is None else [snapshot] @@ -472,7 +479,7 @@ class SheerkaDataProvider: state.data[entry] = obj if key is None else {key: obj} new_snapshot = self.save_state(state) - self.set_snapshot(new_snapshot) + self.set_snapshot(SheerkaDataProvider.HeadFile, new_snapshot) return entry, key def modify(self, event_digest, entry, key, obj): @@ -489,7 +496,7 @@ class SheerkaDataProvider: if key is None: raise SheerkaDataProviderError("Key is mandatory.", None) - snapshot = self.get_snapshot() + snapshot = self.get_snapshot(SheerkaDataProvider.HeadFile) state = self.load_state(snapshot) if entry not in state.data: @@ -517,7 +524,7 @@ class SheerkaDataProvider: state.modify(entry, key, obj, obj_key) new_snapshot = self.save_state(state) - self.set_snapshot(new_snapshot) + self.set_snapshot(SheerkaDataProvider.HeadFile, new_snapshot) return entry, obj_key def list(self, entry, filter=None): @@ -527,7 +534,7 @@ class SheerkaDataProvider: :param filter: filter to use :return: list of elements """ - snapshot = self.get_snapshot() + snapshot = self.get_snapshot(SheerkaDataProvider.HeadFile) state = self.load_state(snapshot) if entry not in state.data: return [] @@ -562,7 +569,7 @@ class SheerkaDataProvider: :return: new sha256 of the state TODO: Remove by key """ - snapshot = self.get_snapshot() + snapshot = self.get_snapshot(SheerkaDataProvider.HeadFile) state = self.load_state(snapshot) if entry not in state.data: @@ -574,7 +581,7 @@ class SheerkaDataProvider: state.remove(entry, filter) new_snapshot = self.save_state(state) - self.set_snapshot(new_snapshot) + self.set_snapshot(SheerkaDataProvider.HeadFile, new_snapshot) return new_snapshot def get(self, entry, key=None, load_origin=True): @@ -582,9 +589,10 @@ class SheerkaDataProvider: Retrieve an element by its key :param entry: :param key: + :param load_origin: if True, adds the origin (parent digest) to the object :return: """ - snapshot = self.get_snapshot() + snapshot = self.get_snapshot(SheerkaDataProvider.HeadFile) state = self.load_state(snapshot) if entry not in state.data: @@ -604,9 +612,10 @@ class SheerkaDataProvider: Retrieve an element by its key. Return None if the element does not exist :param entry: :param key: + :param load_origin: if True, adds the origin (parent digest) to the object :return: """ - snapshot = self.get_snapshot() + snapshot = self.get_snapshot(SheerkaDataProvider.HeadFile) state = self.load_state(snapshot) if entry not in state.data: @@ -629,7 +638,7 @@ class SheerkaDataProvider: :param digest: digest of the object, when several entries share the same key :return: """ - snapshot = self.get_snapshot() + snapshot = self.get_snapshot(SheerkaDataProvider.HeadFile) state = self.load_state(snapshot) exist = entry in state.data @@ -659,25 +668,63 @@ class SheerkaDataProvider: :return: digest of the event """ digest = event.get_digest() + parent = self.get_snapshot(SheerkaDataProvider.LastEventFile) + event.parents = [parent] if parent else None + target_path = self.io.get_obj_path(SheerkaDataProvider.EventFolder, digest) if self.io.exists(target_path): return digest self.io.write_binary(target_path, self.serializer.serialize(event, None).read()) + self.set_snapshot(SheerkaDataProvider.LastEventFile, digest) return digest - def load_event(self, digest): + def load_event(self, digest=None): """ return an event, given its digest :param digest: :return: """ + digest = digest or self.get_snapshot(SheerkaDataProvider.LastEventFile) + if digest is None: + return None + target_path = self.io.get_obj_path(SheerkaDataProvider.EventFolder, digest) with self.io.open(target_path, "rb") as f: return self.serializer.deserialize(f, None) + def load_events(self, page_size, start=0): + """ + Load multiple events in the same command + :param start: + :param page_size: + :return: + """ + + digest = None + if start: + for i in range(start): + event = self.load_event(digest) + if event is None or event.parents is None: + return + digest = event.parents[0] + + count = 0 + while count < page_size: + event = self.load_event(digest) + if event is None: + return + + yield event + + if event.parents is None: + return + + digest = event.parents[0] + count += 1 + def save_result(self, execution_context): """ Save the execution context associated with an event @@ -833,16 +880,16 @@ class SheerkaDataProvider: digest, cache_path = self.get_cache_params(category, key) return self.io.exists(cache_path) - def get_snapshot(self): - head_file = self.io.path_join(SheerkaDataProvider.HeadFile) + def get_snapshot(self, file): + head_file = self.io.path_join(file) if not self.io.exists(head_file): return None return self.io.read_text(head_file) # with open(head_file, "r") as f: # return f.read() - def set_snapshot(self, digest): - head_file = self.io.path_join(SheerkaDataProvider.HeadFile) + def set_snapshot(self, file, digest): + head_file = self.io.path_join(file) return self.io.write_text(head_file, digest) # with open(head_file, "w") as f: # return f.write(digest) diff --git a/src/sdp/sheerkaSerializer.py b/src/sdp/sheerkaSerializer.py index 8c5c9de..c9df1dd 100644 --- a/src/sdp/sheerkaSerializer.py +++ b/src/sdp/sheerkaSerializer.py @@ -29,13 +29,13 @@ def json_default_converter(o): if isinstance(o, Enum): return o.name - raise Exception("Cannot serialize " + o.__class__.__name__) + raise Exception(f"Cannot serialize object '{o}', class='{o.__class__.__name__}'") + # In debug mode, just + # # with open("json_encoding_error.txt", "a") as f: # f.write(o.__class__.__name__ + "\n") - - @dataclass() class SerializerContext: user_name: str = None diff --git a/tests/sdp/test_sheerkaDataProvider.py b/tests/sdp/test_sheerkaDataProvider.py index 1cb5b72..2674673 100644 --- a/tests/sdp/test_sheerkaDataProvider.py +++ b/tests/sdp/test_sheerkaDataProvider.py @@ -219,8 +219,76 @@ def test_i_can_save_and_load_an_event(root): assert evt.date == datetime(year=2007, month=9, day=10) assert evt.user == "kodjo" assert evt.message == "hello world" + assert evt.parents is None assert sdp.io.exists(path.join(sdp.io.root, SheerkaDataProvider.EventFolder, evt_digest[0:24], evt_digest)) + # I can get the last event + evt = sdp.load_event() + assert evt.message == "hello world" + + +@pytest.mark.parametrize("root", [ + ".sheerka", + "mem://" +]) +def test_i_can_get_event_history(root): + sdp = SheerkaDataProvider(root) + event = Event("hello world", date=date(year=2007, month=9, day=10), user="kodjo") + event2 = Event("hello world 2", date=date(year=2007, month=9, day=10), user="kodjo") + + evt_digest1 = sdp.save_event(event) + evt_digest2 = sdp.save_event(event2) + + evt = sdp.load_event(evt_digest2) + assert evt.version == 1 + assert evt.date == datetime(year=2007, month=9, day=10) + assert evt.user == "kodjo" + assert evt.message == "hello world 2" + assert evt.parents == [evt_digest1] + + +@pytest.mark.parametrize("root", [ + ".sheerka", + "mem://" +]) +def test_i_can_load_events(root): + sdp = SheerkaDataProvider(root) + + for i in range(15): + sdp.save_event(Event(f"Hello {i}")) + + events = list(sdp.load_events(10)) + assert len(events) == 10 + assert events[0].message == "Hello 14" + assert events[9].message == "Hello 5" + + events = list(sdp.load_events(10, 5)) + assert len(events) == 10 + assert events[0].message == "Hello 9" + assert events[9].message == "Hello 0" + + events = list(sdp.load_events(20, 10)) + assert len(events) == 5 + assert events[0].message == "Hello 4" + assert events[4].message == "Hello 0" + + events = list(sdp.load_events(1, 20)) + assert len(events) == 0 + + +@pytest.mark.parametrize("root", [ + ".sheerka", + "mem://" +]) +def test_i_can_load_events_when_no_event(root): + sdp = SheerkaDataProvider(root) + + events = list(sdp.load_events(1)) + assert len(events) == 0 + + events = list(sdp.load_events(1, 5)) + assert len(events) == 0 + @pytest.mark.parametrize("root", [ ".sheerka", @@ -231,7 +299,7 @@ def test_i_can_add_an_string(root): obj = "foo => bar" entry, key = sdp.add(evt_digest, "entry", obj) - last_commit = sdp.get_snapshot() + last_commit = sdp.get_snapshot(SheerkaDataProvider.HeadFile) state = sdp.load_state(last_commit) loaded = sdp.get(entry, key) @@ -289,7 +357,7 @@ def test_i_can_add_an_object_with_no_key(root): obj = ObjNoKey("a", "b") entry, key = sdp.add(evt_digest, "entry", obj) - last_commit = sdp.get_snapshot() + last_commit = sdp.get_snapshot(SheerkaDataProvider.HeadFile) state = sdp.load_state(last_commit) loaded = sdp.get(entry, key) @@ -359,7 +427,7 @@ def test_i_can_add_a_dict(root): obj = {"my_key": "my_value"} entry, key = sdp.add(evt_digest, "entry", obj) - last_commit = sdp.get_snapshot() + last_commit = sdp.get_snapshot(SheerkaDataProvider.HeadFile) state = sdp.load_state(last_commit) loaded = sdp.get(entry, key) @@ -456,7 +524,7 @@ def test_i_can_add_obj_with_key(root): entry1, key1 = sdp.add(evt_digest, "entry", obj1) # test when key is taken from obj.get_key() entry2, key2 = sdp.add(evt_digest, "entry2", obj2) # test when key is taken from obj.key - last_commit = sdp.get_snapshot() + last_commit = sdp.get_snapshot(SheerkaDataProvider.HeadFile) state = sdp.load_state(last_commit) loaded1 = sdp.get(entry1, key1) @@ -545,7 +613,7 @@ def test_i_can_add_a_reference(root): sdp.add(evt_digest, "entry", obj2, use_ref=True) sdp.add(evt_digest, "entry_by_value", {obj2.b: obj2.get_digest()}, is_ref=True) - state = sdp.load_state(sdp.get_snapshot()) + state = sdp.load_state(sdp.get_snapshot(SheerkaDataProvider.HeadFile)) assert state.data == { "entry": { "1": '##REF##:' + obj1.get_digest(), @@ -593,7 +661,7 @@ def test_i_can_add_string_using_auto_generated_key(root): entry2, key2 = sdp.add_with_auto_key(evt_digest, "entry1", "bar") entry3, key3 = sdp.add_with_auto_key(evt_digest, "entry2", "baz") - state = sdp.load_state(sdp.get_snapshot()) + state = sdp.load_state(sdp.get_snapshot(SheerkaDataProvider.HeadFile)) assert sdp.io.exists(key_file) assert read_json_file(sdp, key_file) == {"entry1": 2, "entry2": 1} @@ -732,7 +800,7 @@ def test_i_can_add_object_using_auto_generated_key(root): entry1, key1 = sdp.add_with_auto_key(evt_digest, "entry1", ObjNoKey("a", "b")) entry2, key2 = sdp.add_with_auto_key(evt_digest, "entry1", ObjNoKey("a", "b")) - state = sdp.load_state(sdp.get_snapshot()) + state = sdp.load_state(sdp.get_snapshot(SheerkaDataProvider.HeadFile)) assert sdp.io.exists(key_file) assert read_json_file(sdp, key_file) == {"entry1": 2} @@ -754,7 +822,7 @@ def test_object_key_is_updated_when_possible_using_auto_generated_key(root): entry1, key1 = sdp.add_with_auto_key(evt_digest, "entry1", ObjSetKey("foo")) entry2, key2 = sdp.add_with_auto_key(evt_digest, "entry1", ObjSetKey("foo")) - state = sdp.load_state(sdp.get_snapshot()) + state = sdp.load_state(sdp.get_snapshot(SheerkaDataProvider.HeadFile)) assert sdp.io.exists(key_file) assert read_json_file(sdp, key_file) == {"entry1": 2} @@ -774,7 +842,7 @@ def test_i_can_set_objects_with_key(root): sdp.add(evt_digest, "entry", ObjWithKey(1, "foo")) entry, key = sdp.set(evt_digest, "entry", ObjWithKey(2, "foo")) - state = sdp.load_state(sdp.get_snapshot()) + state = sdp.load_state(sdp.get_snapshot(SheerkaDataProvider.HeadFile)) assert state.data == {"entry": {"2": ObjWithKey(2, "foo")}} assert entry == "entry" assert key == "2" @@ -789,7 +857,7 @@ def test_i_can_set_objects_with_no_key(root): sdp.add(evt_digest, "entry", ObjNoKey(1, "foo")) entry, key = sdp.set(evt_digest, "entry", ObjNoKey(2, "foo")) - state = sdp.load_state(sdp.get_snapshot()) + state = sdp.load_state(sdp.get_snapshot(SheerkaDataProvider.HeadFile)) assert state.data == {"entry": ObjNoKey(2, "foo")} assert entry == "entry" assert key is None @@ -804,7 +872,7 @@ def test_i_can_set_from_list_to_dict(root): sdp.set(evt_digest, "entry", [ObjNoKey(1, "foo"), ObjNoKey(2, "foo")]) entry, key = sdp.set(evt_digest, "entry", {"1": ObjNoKey(1, "foo"), "2": ObjNoKey(2, "foo")}) - state = sdp.load_state(sdp.get_snapshot()) + state = sdp.load_state(sdp.get_snapshot(SheerkaDataProvider.HeadFile)) assert state.data == {"entry": {"1": ObjNoKey(1, "foo"), "2": ObjNoKey(2, "foo")}} assert entry == "entry" assert key is None @@ -820,7 +888,7 @@ def test_i_can_set_using_reference(root): sdp.add(evt_digest, "entry", ObjWithKey(1, "foo")) entry, key = sdp.set(evt_digest, "entry", ObjWithKey(2, "foo"), use_ref=True) - state = sdp.load_state(sdp.get_snapshot()) + state = sdp.load_state(sdp.get_snapshot(SheerkaDataProvider.HeadFile)) assert state.data == {"entry": {"2": '##REF##:43f07065c7bad051cdd726bdfa4de7f8d754c31486c65ddb31d6b6548dec3db9'}} assert entry == "entry" assert key == "2" @@ -845,7 +913,7 @@ def test_i_can_set_a_reference(root): sdp.add(evt_digest, "entry", obj, use_ref=True) sdp.set(evt_digest, "entry_by_value", {obj.b: obj.get_digest()}, is_ref=True) - state = sdp.load_state(sdp.get_snapshot()) + state = sdp.load_state(sdp.get_snapshot(SheerkaDataProvider.HeadFile)) assert state.data == { "entry": {"1": '##REF##:' + obj.get_digest()}, "entry_by_value": {"foo": '##REF##:' + obj.get_digest()}, @@ -882,7 +950,7 @@ def test_i_can_add_an_object_with_a_key_as_a_reference(root): sdp.serializer.register(obj_serializer) entry, key = sdp.add(evt_digest, "entry", obj, use_ref=True) - state = sdp.load_state(sdp.get_snapshot()) + state = sdp.load_state(sdp.get_snapshot(SheerkaDataProvider.HeadFile)) digest = state.data["entry"]["my_key"][len(SheerkaDataProvider.REF_PREFIX):] assert key == obj.key @@ -906,7 +974,7 @@ def test_i_can_add_a_dictionary_as_a_reference(root): sdp.serializer.register(obj_serializer) entry, key = sdp.add(evt_digest, "entry", obj, use_ref=True) - state = sdp.load_state(sdp.get_snapshot()) + state = sdp.load_state(sdp.get_snapshot(SheerkaDataProvider.HeadFile)) digest = state.data["entry"][len(SheerkaDataProvider.REF_PREFIX):] assert key is None @@ -937,7 +1005,7 @@ def test_i_can_add_unique(root): entry, key = sdp.add_unique(evt_digest, "entry", ObjNoKey(2, "bar")) assert (entry, key) == (None, None) - state = sdp.load_state(sdp.get_snapshot()) + state = sdp.load_state(sdp.get_snapshot(SheerkaDataProvider.HeadFile)) assert state.data == {"entry": {ObjNoKey(1, "foo"), ObjNoKey(2, "bar")}} @@ -952,13 +1020,13 @@ def test_i_can_keep_state_history(root): event_digest1 = sdp.save_event(event1) obj1 = "foo => bar" sdp.add(event_digest1, "entry1", obj1) - state_digest1 = sdp.get_snapshot() + state_digest1 = sdp.get_snapshot(SheerkaDataProvider.HeadFile) event2 = Event("cmd add 'foo => baz'") event_digest2 = sdp.save_event(event2) obj2 = "foo => baz" sdp.add(event_digest2, "entry2", obj2) - state_digest2 = sdp.get_snapshot() + state_digest2 = sdp.get_snapshot(SheerkaDataProvider.HeadFile) state2 = sdp.load_state(state_digest2) @@ -1269,7 +1337,7 @@ def test_i_can_modify_dict_with_a_key(root): entry, key = sdp.modify(evt_digest, "entry", "key1", "baz") - state = sdp.load_state(sdp.get_snapshot()) + state = sdp.load_state(sdp.get_snapshot(SheerkaDataProvider.HeadFile)) assert state.data == {"entry": {"key1": "baz", "key2": "bar"}} assert entry == "entry" assert key == "key1" @@ -1286,7 +1354,7 @@ def test_i_can_modify_an_object_with_a_key(root): entry, key = sdp.modify(evt_digest, "entry", "key1", ObjWithKey("key1", "baz")) - state = sdp.load_state(sdp.get_snapshot()) + state = sdp.load_state(sdp.get_snapshot(SheerkaDataProvider.HeadFile)) assert state.data == {"entry": {"key1": ObjWithKey("key1", "baz"), "key2": ObjWithKey("key2", "bar")}} assert entry == "entry" assert key == "key1" @@ -1303,7 +1371,7 @@ def test_i_can_modify_an_object_while_changing_the_key(root): entry, key = sdp.modify(evt_digest, "entry", "key1", ObjWithKey("key3", "baz")) - state = sdp.load_state(sdp.get_snapshot()) + state = sdp.load_state(sdp.get_snapshot(SheerkaDataProvider.HeadFile)) assert state.data == {"entry": {"key2": ObjWithKey("key2", "bar"), "key3": ObjWithKey("key3", "baz")}} assert entry == "entry" assert key == "key3" @@ -1320,7 +1388,7 @@ def test_i_can_modify_an_object_while_changing_the_key_to_an_existing_key(root): entry, key = sdp.modify(evt_digest, "entry", "key2", ObjWithKey("key1", "bar")) - state = sdp.load_state(sdp.get_snapshot()) + state = sdp.load_state(sdp.get_snapshot(SheerkaDataProvider.HeadFile)) assert state.data == {"entry": {"key1": [ObjWithKey("key1", "foo"), ObjWithKey("key1", "bar")]}} assert entry == "entry" assert key == "key1" @@ -1348,7 +1416,7 @@ def test_i_can_modify_an_object_while_changing_the_key_to_an_existing_when_list( setattr(new_value, Serializer.ORIGIN, ObjDumpJson("key2", "value21").get_digest()) entry, key = sdp.modify(evt_digest, "entry", "key2", new_value) - state = sdp.load_state(sdp.get_snapshot()) + state = sdp.load_state(sdp.get_snapshot(SheerkaDataProvider.HeadFile)) assert state.data == {"entry": { "key1": [ObjDumpJson("key1", "value11"), ObjDumpJson("key1", "value12"), ObjDumpJson("key1", "value13")], "key2": [ObjDumpJson("key2", "value22")] @@ -1377,7 +1445,7 @@ def test_i_can_modify_an_object_while_changing_the_key_to_an_existing_when_nothi setattr(new_value, Serializer.ORIGIN, ObjDumpJson("key2", "value21").get_digest()) entry, key = sdp.modify(evt_digest, "entry", "key2", new_value) - state = sdp.load_state(sdp.get_snapshot()) + state = sdp.load_state(sdp.get_snapshot(SheerkaDataProvider.HeadFile)) assert state.data == {"entry": { "key1": ObjDumpJson("key1", "value13"), "key2": [ObjDumpJson("key2", "value22")] @@ -1407,7 +1475,7 @@ def test_i_can_modify_an_object_while_changing_the_key_to_an_existing_when_one_i setattr(new_value, Serializer.ORIGIN, ObjDumpJson("key2", "value21").get_digest()) entry, key = sdp.modify(evt_digest, "entry", "key2", new_value) - state = sdp.load_state(sdp.get_snapshot()) + state = sdp.load_state(sdp.get_snapshot(SheerkaDataProvider.HeadFile)) assert state.data == {"entry": { "key1": [ObjDumpJson("key1", "value11"), ObjDumpJson("key1", "value13")], "key2": [ObjDumpJson("key2", "value22")] @@ -1427,7 +1495,7 @@ def test_i_can_modify_a_ref(root): entry, key = sdp.add(evt_digest, "entry", ObjWithKey("key2", "bar"), use_ref=True) sdp.modify(evt_digest, "entry", "key2", ObjWithKey("key2", "baz")) - state = sdp.load_state(sdp.get_snapshot()) + state = sdp.load_state(sdp.get_snapshot(SheerkaDataProvider.HeadFile)) assert state.data == {"entry": { "key1": ObjWithKey("key1", "foo"), "key2": "##REF##:041d3cca905b51bc2c66251e73e56b836aae7b9435ee3d7eb05d44bb67ff575e"}} @@ -1471,7 +1539,7 @@ def test_i_cannot_modify_a_list_when_origin_is_unknown(root): sdp.add(evt_digest, "entry", ObjWithKey("key", "value1")) sdp.add(evt_digest, "entry", ObjWithKey("key", "value2")) # same they - state = sdp.load_state(sdp.get_snapshot()) + state = sdp.load_state(sdp.get_snapshot(SheerkaDataProvider.HeadFile)) with pytest.raises(SheerkaDataProviderError) as error: sdp.modify(evt_digest, "entry", "key", ObjWithKey("key", "value2")) @@ -1495,7 +1563,7 @@ def test_i_can_modify_a_list_when_the_origin_is_known(root): sdp.modify(evt_digest, "entry", "key", new_value) - state = sdp.load_state(sdp.get_snapshot()) + state = sdp.load_state(sdp.get_snapshot(SheerkaDataProvider.HeadFile)) assert state.data == {"entry": {"key": [ObjDumpJson("key", "value3"), ObjDumpJson("key", "value2")]}} @@ -1520,7 +1588,7 @@ def test_i_can_modify_a_list_when_the_origin_is_known_2(root): sdp.modify(evt_digest, "entry", "key", objs[0]) - state = sdp.load_state(sdp.get_snapshot()) + state = sdp.load_state(sdp.get_snapshot(SheerkaDataProvider.HeadFile)) assert state.data == {"entry": {"key": [ "##REF##:621771a3af6a331e9abb3a63fb25e0cac4b13df0b292dfa30db6bd89031bfad0", "##REF##:5fe085e8366d35c5f04a18b2d3dada376128b246e07c66de5872830b00f5f517"]}} @@ -1846,7 +1914,7 @@ def test_i_can_save_and_load_object_ref_with_history(root): assert history2[Serializer.MODIFICATION_DATE] != "" assert history2[Serializer.PARENTS] == [previous_digest] - state = sdp.load_state(sdp.get_snapshot()) + state = sdp.load_state(sdp.get_snapshot(SheerkaDataProvider.HeadFile)) assert state.data == {"entry": { "my_key": '##REF##:e6bf5b56428cfce0f08c94f2c3625dc3b3a8180d7229eaa9f8aa967fb16e5256'}}