From ec4f87a98c034daca5597423762ba01c3b084d0d Mon Sep 17 00:00:00 2001
From: Kevan Carstensen <kevan@isnotajoke.com>
Date: Mon, 27 Sep 2010 13:01:02 -0700
Subject: [PATCH] immutable/repairer.py: don't use the default happiness
 setting when repairing

---
 src/allmydata/immutable/repairer.py |  4 +++-
 src/allmydata/test/test_repairer.py | 35 +++++++++++++++++++++++++++++
 2 files changed, 38 insertions(+), 1 deletion(-)

diff --git a/src/allmydata/immutable/repairer.py b/src/allmydata/immutable/repairer.py
index 64fb9a19..320dbd8c 100644
--- a/src/allmydata/immutable/repairer.py
+++ b/src/allmydata/immutable/repairer.py
@@ -57,7 +57,9 @@ class Repairer(log.PrefixingLogMixin):
             vcap = self._filenode.get_verify_cap()
             k = vcap.needed_shares
             N = vcap.total_shares
-            happy = upload.BaseUploadable.default_encoding_param_happy
+            # Per ticket #1212
+            # (http://tahoe-lafs.org/trac/tahoe-lafs/ticket/1212)
+            happy = 0
             self._encodingparams = (k, happy, N, segsize)
             ul = upload.CHKUploader(self._storage_broker, self._secret_holder)
             return ul.start(self) # I am the IEncryptedUploadable
diff --git a/src/allmydata/test/test_repairer.py b/src/allmydata/test/test_repairer.py
index bb30cc45..49c4cff0 100644
--- a/src/allmydata/test/test_repairer.py
+++ b/src/allmydata/test/test_repairer.py
@@ -516,6 +516,41 @@ class Repairer(GridTestMixin, unittest.TestCase, RepairTestMixin,
                       self.failUnlessEqual(newdata, common.TEST_DATA))
         return d
 
+    def test_repairer_servers_of_happiness(self):
+        # The repairer is supposed to generate and place as many of the
+        # missing shares as possible without caring about how they are
+        # distributed.
+        self.basedir = "repairer/Repairer/repairer_servers_of_happiness"
+        self.set_up_grid(num_clients=2, num_servers=10)
+        d = self.upload_and_stash()
+        # Now delete some servers. We want to leave 3 servers, which
+        # will allow us to restore the file to a healthy state without
+        # distributing the shares widely enough to satisfy the default
+        # happiness setting.
+        def _delete_some_servers(ignored):
+            for i in xrange(7):
+                self.g.remove_server(self.g.servers_by_number[i].my_nodeid)
+
+            assert len(self.g.servers_by_number) == 3
+
+        d.addCallback(_delete_some_servers)
+        # Now try to repair the file.
+        d.addCallback(lambda ignored:
+            self.c0_filenode.check_and_repair(Monitor(), verify=False))
+        def _check_results(crr):
+            self.failUnlessIsInstance(crr,
+                                      check_results.CheckAndRepairResults)
+            pre = crr.get_pre_repair_results()
+            post = crr.get_post_repair_results()
+            for p in (pre, post):
+                self.failUnlessIsInstance(p, check_results.CheckResults)
+
+            self.failIf(pre.is_healthy())
+            self.failUnless(post.is_healthy())
+
+        d.addCallback(_check_results)
+        return d
+
     # why is test_repair_from_corruption_of_1 disabled? Read on:
     #
     # As recently documented in NEWS for the 1.3.0 release, the current
-- 
2.45.2