From 2c9011cc87f5fb3c337627133d9cb6ac00bce56e Mon Sep 17 00:00:00 2001 From: Houkime <> Date: Wed, 9 Aug 2023 15:18:20 +0000 Subject: [PATCH] fix(backups): robustness against stale locks: everything else --- selfprivacy_api/backup/backuppers/restic_backupper.py | 10 +++++----- tests/test_graphql/test_backup.py | 9 +++++++++ 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/selfprivacy_api/backup/backuppers/restic_backupper.py b/selfprivacy_api/backup/backuppers/restic_backupper.py index 5db9f11..3a5fc49 100644 --- a/selfprivacy_api/backup/backuppers/restic_backupper.py +++ b/selfprivacy_api/backup/backuppers/restic_backupper.py @@ -345,6 +345,7 @@ class ResticBackupper(AbstractBackupper): except ValueError as error: raise ValueError("cannot restore a snapshot: " + output) from error + @unlocked_repo def restore_from_backup( self, snapshot_id, @@ -406,6 +407,7 @@ class ResticBackupper(AbstractBackupper): output, ) + @unlocked_repo def forget_snapshot(self, snapshot_id) -> None: """ Either removes snapshot or marks it for deletion later, @@ -441,10 +443,7 @@ class ResticBackupper(AbstractBackupper): ) # none should be impossible after communicate if handle.returncode != 0: raise ValueError( - "forget exited with errorcode", - handle.returncode, - ":", - output, + "forget exited with errorcode", handle.returncode, ":", output, err ) def _load_snapshots(self) -> object: @@ -470,8 +469,9 @@ class ResticBackupper(AbstractBackupper): try: return ResticBackupper.parse_json_output(output) except ValueError as error: - raise ValueError("Cannot load snapshots: ") from error + raise ValueError("Cannot load snapshots: ", output) from error + @unlocked_repo def get_snapshots(self) -> List[Snapshot]: """Get all snapshots from the repo""" snapshots = [] diff --git a/tests/test_graphql/test_backup.py b/tests/test_graphql/test_backup.py index 556b72b..1990ef7 100644 --- a/tests/test_graphql/test_backup.py +++ b/tests/test_graphql/test_backup.py @@ -794,6 +794,15 @@ def test_operations_while_locked(backups, dummy_service): Backups.provider().backupper.lock() assert Backups.snapshot_restored_size(snap.id) > 0 + Backups.provider().backupper.lock() + Backups.restore_snapshot(snap) + + Backups.provider().backupper.lock() + Backups.forget_snapshot(snap) + + Backups.provider().backupper.lock() + assert Backups.provider().backupper.get_snapshots() == [] + # check that no locks were left Backups.provider().backupper.lock() Backups.provider().backupper.unlock()