From e330abc3c3151dd11b0b3755817ac987c959aa06 Mon Sep 17 00:00:00 2001
From: Brian Warner <warner@lothar.com>
Date: Tue, 30 Jun 2009 18:13:43 -0700
Subject: [PATCH] mutable repairer: skip repair of readcaps instead of throwing
 an exception. This should improve the behavior of #625 a bit: at least all
 the files will get repaired.

---
 src/allmydata/mutable/checker.py   |  5 +++++
 src/allmydata/test/test_mutable.py | 24 +++++++++++++++++++++++-
 2 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/src/allmydata/mutable/checker.py b/src/allmydata/mutable/checker.py
index 7adb17ab..1913c612 100644
--- a/src/allmydata/mutable/checker.py
+++ b/src/allmydata/mutable/checker.py
@@ -297,6 +297,11 @@ class MutableCheckAndRepairer(MutableChecker):
         if not self.need_repair:
             self.cr_results.post_repair_results = self.results
             return
+        if self._node.is_readonly():
+            # ticket #625: we cannot yet repair read-only mutable files
+            self.cr_results.post_repair_results = self.results
+            self.cr_results.repair_attempted = False
+            return
         self.cr_results.repair_attempted = True
         d = self._node.repair(self.results)
         def _repair_finished(repair_results):
diff --git a/src/allmydata/test/test_mutable.py b/src/allmydata/test/test_mutable.py
index 879fdb89..91765fe0 100644
--- a/src/allmydata/test/test_mutable.py
+++ b/src/allmydata/test/test_mutable.py
@@ -12,7 +12,7 @@ from allmydata.util.idlib import shortnodeid_b2a
 from allmydata.util.hashutil import tagged_hash
 from allmydata.util.fileutil import make_dirs
 from allmydata.interfaces import IURI, IMutableFileURI, IUploadable, \
-     NotEnoughSharesError, IRepairResults
+     NotEnoughSharesError, IRepairResults, ICheckAndRepairResults
 from allmydata.monitor import Monitor
 from allmydata.test.common import ShouldFailMixin
 from foolscap.api import eventually, fireEventually
@@ -1465,6 +1465,28 @@ class Repair(unittest.TestCase, PublishMixin, ShouldFailMixin):
                           unpack_header(share)
                 return root_hash
 
+    def test_check_and_repair_readcap(self):
+        # we can't currently repair from a mutable readcap: #625
+        self.old_shares = []
+        d = self.publish_one()
+        d.addCallback(self.copy_shares)
+        def _get_readcap(res):
+            self._fn3 = self._fn.get_readonly()
+            # also delete some shares
+            for peerid,shares in self._storage._peers.items():
+                shares.pop(0, None)
+        d.addCallback(_get_readcap)
+        d.addCallback(lambda res: self._fn3.check_and_repair(Monitor()))
+        def _check_results(crr):
+            self.failUnless(ICheckAndRepairResults.providedBy(crr))
+            # we should detect the unhealthy, but skip over mutable-readcap
+            # repairs until #625 is fixed
+            self.failIf(crr.get_pre_repair_results().is_healthy())
+            self.failIf(crr.get_repair_attempted())
+            self.failIf(crr.get_post_repair_results().is_healthy())
+        d.addCallback(_check_results)
+        return d
+
 class MultipleEncodings(unittest.TestCase):
     def setUp(self):
         self.CONTENTS = "New contents go here"
-- 
2.45.2