diff --git a/storage_service/locations/models/package.py b/storage_service/locations/models/package.py index 3835a30ca..e572fa19c 100644 --- a/storage_service/locations/models/package.py +++ b/storage_service/locations/models/package.py @@ -1980,11 +1980,14 @@ def delete_from_storage(self): Returns (True, None) on success, and (False, error_msg) on failure. """ error = None + location = self.current_location + space = location.space + # LOCKSS must notify LOM before deleting - if self.current_location.space.access_protocol == Space.LOM: + if space.access_protocol == Space.LOM: # Notify LOM that files will be deleted if "num_files" in self.misc_attributes: - lom = self.current_location.space.get_child_space() + lom = space.get_child_space() lom.update_service_document() delete_lom_ids = [ lom._download_url(self.uuid, idx + 1) @@ -1992,7 +1995,7 @@ def delete_from_storage(self): ] error = lom._delete_update_lom(self, delete_lom_ids) try: - self.current_location.space.delete_path(self.full_path) + space.delete_path(self.full_path) except (StorageException, NotImplementedError, ValueError) as err: return False, err # If deleted correctly, remove pointer file, and the UUID quad @@ -2014,6 +2017,14 @@ def delete_from_storage(self): ) self.status = self.DELETED self.save() + + # Remove size from location and space used values. Like the initial + # checks and updates, this is not considering race conditions. + space.used -= self.size + space.save() + location.used -= self.size + location.save() + return True, error # REINGEST diff --git a/storage_service/locations/tests/test_package.py b/storage_service/locations/tests/test_package.py index 1d9283078..e17cc4041 100644 --- a/storage_service/locations/tests/test_package.py +++ b/storage_service/locations/tests/test_package.py @@ -48,6 +48,16 @@ def setUp(self): def tearDown(self): shutil.rmtree(self.tmp_dir) + def test_model_delete_from_storage(self): + package = models.Package.objects.get( + uuid="88deec53-c7dc-4828-865c-7356386e9399" + ) + with mock.patch("locations.models.Space.delete_path") as mocked_delete: + package.delete_from_storage() + assert mocked_delete.called + assert package.current_location.used == -package.size + assert package.current_location.space.used == -package.size + def test_view_package_delete(self): self.client.login(username="test", password="test") url = reverse("package_delete", args=["00000000-0000-0000-0000-000000000000"])