Tue Jan 24 20:52:09 GMT 2012 Brian Warner <warner@lothar.com>
authorDaira Hopwood <daira@jacaranda.org>
Thu, 5 Sep 2013 17:14:39 +0000 (18:14 +0100)
committerDaira Hopwood <daira@jacaranda.org>
Thu, 5 Sep 2013 17:14:39 +0000 (18:14 +0100)
  * Add test_verify_mdmf_all_bad_sharedata

  test_verify_mdmf_all_bad_sharedata tests for the regression described
  in ticket 1648. In particular, it will trigger the misplaced assertion
  in the share activation code. It also tests to make sure that
  verification continues with fewer than k shares.

src/allmydata/test/test_mutable.py

index 136701a418cb6789e0f4ba61fa97e310084a5d19..a84c602bb2ee435d19052bd827122703e778c24d 100644 (file)
@@ -1742,6 +1742,33 @@ class Checker(unittest.TestCase, CheckerMixin, PublishMixin):
         d.addCallback(self.check_bad, "test_check_mdmf_all_bad_sig")
         return d
 
+    def test_verify_mdmf_all_bad_sharedata(self):
+        d = self.publish_mdmf()
+        # On 8 of the shares, corrupt the beginning of the share data.
+        # The signature check during the servermap update won't catch this.
+        d.addCallback(lambda ignored:
+            corrupt(None, self._storage, "share_data", range(8)))
+        # On 2 of the shares, corrupt the end of the share data.
+        # The signature check during the servermap update won't catch
+        # this either, and the retrieval process will have to process
+        # all of the segments before it notices.
+        d.addCallback(lambda ignored:
+            # the block hash tree comes right after the share data, so if we
+            # corrupt a little before the block hash tree, we'll corrupt in the
+            # last block of each share.
+            corrupt(None, self._storage, "block_hash_tree", [8, 9], -5))
+        d.addCallback(lambda ignored:
+            self._fn.check(Monitor(), verify=True))
+        # The verifier should flag the file as unhealthy, and should
+        # list all 10 shares as bad.
+        d.addCallback(self.check_bad, "test_verify_mdmf_all_bad_sharedata")
+        def _check_num_bad(r):
+            self.failIf(r.is_recoverable())
+            smap = r.get_servermap()
+            self.failUnlessEqual(len(smap.get_bad_shares()), 10)
+        d.addCallback(_check_num_bad)
+        return d
+
     def test_check_all_bad_blocks(self):
         d = corrupt(None, self._storage, "share_data", [9]) # bad blocks
         # the Checker won't notice this.. it doesn't look at actual data