From b185e34c8d8460ea73ad642d68a86937dfbcad2f Mon Sep 17 00:00:00 2001 From: Jean-Paul Calderone <exarkun@twistedmatrix.com> Date: Fri, 5 Jul 2019 13:40:00 -0400 Subject: [PATCH] advise_corrupt_share --- .../_storage_client.py | 14 +++++ .../_storage_server.py | 3 ++ .../tests/test_storage_protocol.py | 53 +++++++++++++++++-- 3 files changed, 66 insertions(+), 4 deletions(-) diff --git a/src/_secureaccesstokenauthorizer/_storage_client.py b/src/_secureaccesstokenauthorizer/_storage_client.py index bfdf7b9..9a77fbc 100644 --- a/src/_secureaccesstokenauthorizer/_storage_client.py +++ b/src/_secureaccesstokenauthorizer/_storage_client.py @@ -103,3 +103,17 @@ class SecureAccessTokenAuthorizerStorageClient(object): renew_secret, ) + def advise_corrupt_share( + self, + share_type, + storage_index, + shnum, + reason, + ): + return self._rref.callRemote( + "advise_corrupt_share", + share_type, + storage_index, + shnum, + reason, + ) diff --git a/src/_secureaccesstokenauthorizer/_storage_server.py b/src/_secureaccesstokenauthorizer/_storage_server.py index 0943681..6264b31 100644 --- a/src/_secureaccesstokenauthorizer/_storage_server.py +++ b/src/_secureaccesstokenauthorizer/_storage_server.py @@ -123,6 +123,9 @@ class SecureAccessTokenAuthorizerStorageServer(Referenceable): self._validate_tokens(tokens) return self._original.remote_renew_lease(*a, **kw) + def remote_advise_corrupt_share(self, *a, **kw): + return self._original.remote_advise_corrupt_share(*a, **kw) + # I don't understand why this is required. # SecureAccessTokenAuthorizerStorageServer is-a Referenceable. It seems like # the built in adapter should take care of this case. diff --git a/src/_secureaccesstokenauthorizer/tests/test_storage_protocol.py b/src/_secureaccesstokenauthorizer/tests/test_storage_protocol.py index 35bd82d..b4f341b 100644 --- a/src/_secureaccesstokenauthorizer/tests/test_storage_protocol.py +++ b/src/_secureaccesstokenauthorizer/tests/test_storage_protocol.py @@ -275,6 +275,47 @@ class ImmutableTests(TestCase): Equals(int(now + RENEW_INTERVAL)), ) + @given( + storage_index=storage_indexes(), + renew_secret=lease_renew_secrets(), + cancel_secret=lease_cancel_secrets(), + sharenum=sharenums(), + size=sizes(), + ) + def test_advise_corrupt_share(self, storage_index, renew_secret, cancel_secret, sharenum, size): + """ + An advisory of corruption in a share can be sent to the server. + """ + # Hypothesis causes our storage server to be used many times. Clean + # up between iterations. + cleanup_storage_server(self.anonymous_storage_server) + + # Create a share we can toy with. + _, allocated = self.anonymous_storage_server.remote_allocate_buckets( + storage_index, + renew_secret, + cancel_secret, + {sharenum}, + size, + canary=self.canary, + ) + [(_, writer)] = allocated.items() + writer.remote_write(0, bytes_for_share(sharenum, size)) + writer.remote_close() + + extract_result( + self.client.advise_corrupt_share( + u"immutable", + storage_index, + sharenum, + u"the bits look bad", + ), + ) + self.assertThat( + FilePath(self.anonymous_storage_server.corruption_advisory_dir).children(), + HasLength(1), + ) + def get_leases(storage_server, storage_index): """ @@ -304,7 +345,11 @@ def cleanup_storage_server(storage_server): :param allmydata.storage.server.StorageServer storage_server: The storage server with some on-disk shares to delete. """ - start = FilePath(storage_server.sharedir) - for p in start.walk(): - if p is not start: - p.remove() + starts = [ + FilePath(storage_server.sharedir), + FilePath(storage_server.corruption_advisory_dir), + ] + for start in starts: + for p in start.walk(): + if p is not start: + p.remove() -- GitLab