Skip to content

Commit

Permalink
Improve event log reader code
Browse files Browse the repository at this point in the history
  • Loading branch information
amolenaar committed May 31, 2024
1 parent 7fcb3c0 commit bfd5861
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 13 deletions.
35 changes: 24 additions & 11 deletions gaphor/storage/recovery.py
Original file line number Diff line number Diff line change
Expand Up @@ -228,25 +228,34 @@ def write(self, event):

def read(self):
self.close()
checksum_failed = False
filename = self._filename or self._template
if not filename:
return

try:
with self._log_name.open(mode="r", encoding="utf-8") as f:
preamble_line = f.readline()
preamble = ast.literal_eval(preamble_line)
if not isinstance(preamble, dict):
raise ChecksumFailed()

filename = (
self._template if preamble.get("template") else self._filename
)
if not filename or sha256sum(filename) != preamble.get("sha256"):
raise ChecksumFailed()

for line in f:
events = ast.literal_eval(line.rstrip("\r\n"))
if (
isinstance(events, dict)
and self._filename
and sha256sum(self._filename) != events.get("sha256")
):
checksum_failed = True
break
yield events
if checksum_failed:
log.info("Recovery file hash does not match.")
self.move_aside()

except FileNotFoundError:
# Log does not exist, no problem
pass
except ChecksumFailed:
# Move file after it's closed.
log.info("Recovery file hash does not match.")
self.move_aside()

def close(self):
if self._file:
Expand All @@ -258,6 +267,10 @@ def move_aside(self):
_move_aside(self._log_name)


class ChecksumFailed(Exception):
pass


def _move_aside(path: Path):
backup = path.with_suffix(".recovery.bak")
path.rename(backup)
Expand Down
5 changes: 3 additions & 2 deletions tests/test_session_recovery.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,8 @@ def test_broken_recovery_log(
assert "Could not recover model changes" in caplog.text


def test_recover_from_session_files(application: Application, test_models):
@pytest.mark.parametrize("template", [True, False])
def test_recover_from_session_files(application: Application, test_models, template):
session_id = "1234"
class_id = "9876"

Expand All @@ -186,7 +187,7 @@ def test_recover_from_session_files(application: Application, test_models):
{
"path": str(test_models / "all-elements.gaphor"),
"sha256": sha256sum(test_models / "all-elements.gaphor"),
"template": True,
"template": template,
},
[("c", "Class", class_id, None)],
)
Expand Down

0 comments on commit bfd5861

Please sign in to comment.