From c0f3dbb9195e51f779ead3b1a8da63d4a3e35c46 Mon Sep 17 00:00:00 2001 From: Kevan Carstensen Date: Sun, 22 Nov 2009 19:20:08 -0700 Subject: [PATCH] Add tests for the behavior described in #834. --- src/allmydata/test/test_encode.py | 6 +- src/allmydata/test/test_upload.py | 107 +++++++++++++++++++++++++++--- 2 files changed, 100 insertions(+), 13 deletions(-) diff --git a/src/allmydata/test/test_encode.py b/src/allmydata/test/test_encode.py index fe765579..d55ba709 100644 --- a/src/allmydata/test/test_encode.py +++ b/src/allmydata/test/test_encode.py @@ -9,7 +9,7 @@ from allmydata.util import hashutil from allmydata.util.assertutil import _assert from allmydata.util.consumer import MemoryConsumer from allmydata.interfaces import IStorageBucketWriter, IStorageBucketReader, \ - NotEnoughSharesError, IStorageBroker + NotEnoughSharesError, IStorageBroker, UploadHappinessError from allmydata.monitor import Monitor import common_util as testutil @@ -791,7 +791,7 @@ class Roundtrip(unittest.TestCase, testutil.ShouldFailMixin): d = self.send_and_recover((4,8,10), bucket_modes=modemap) def _done(res): self.failUnless(isinstance(res, Failure)) - self.failUnless(res.check(NotEnoughSharesError), res) + self.failUnless(res.check(UploadHappinessError), res) d.addBoth(_done) return d @@ -802,6 +802,6 @@ class Roundtrip(unittest.TestCase, testutil.ShouldFailMixin): d = self.send_and_recover((4,8,10), bucket_modes=modemap) def _done(res): self.failUnless(isinstance(res, Failure)) - self.failUnless(res.check(NotEnoughSharesError)) + self.failUnless(res.check(UploadHappinessError)) d.addBoth(_done) return d diff --git a/src/allmydata/test/test_upload.py b/src/allmydata/test/test_upload.py index d6e5b749..27219bf4 100644 --- a/src/allmydata/test/test_upload.py +++ b/src/allmydata/test/test_upload.py @@ -10,8 +10,7 @@ from foolscap.api import fireEventually import allmydata # for __full_version__ from allmydata import uri, monitor, client from allmydata.immutable import upload, encode -from allmydata.interfaces import FileTooLargeError, NoSharesError, \ - NotEnoughSharesError +from allmydata.interfaces import FileTooLargeError, UploadHappinessError from allmydata.util.assertutil import precondition from allmydata.util.deferredutil import DeferredListShouldSucceed from no_network import GridTestMixin @@ -400,7 +399,7 @@ class ServerErrors(unittest.TestCase, ShouldFailMixin, SetDEPMixin): def test_first_error_all(self): self.make_node("first-fail") - d = self.shouldFail(NoSharesError, "first_error_all", + d = self.shouldFail(UploadHappinessError, "first_error_all", "peer selection failed", upload_data, self.u, DATA) def _check((f,)): @@ -432,7 +431,7 @@ class ServerErrors(unittest.TestCase, ShouldFailMixin, SetDEPMixin): def test_second_error_all(self): self.make_node("second-fail") - d = self.shouldFail(NotEnoughSharesError, "second_error_all", + d = self.shouldFail(UploadHappinessError, "second_error_all", "peer selection failed", upload_data, self.u, DATA) def _check((f,)): @@ -450,7 +449,7 @@ class FullServer(unittest.TestCase): self.u.parent = self.node def _should_fail(self, f): - self.failUnless(isinstance(f, Failure) and f.check(NoSharesError), f) + self.failUnless(isinstance(f, Failure) and f.check(UploadHappinessError), f) def test_data_large(self): data = DATA @@ -815,7 +814,7 @@ class EncodingParameters(GridTestMixin, unittest.TestCase, SetDEPMixin, # These parameters are unsatisfiable with the client that we've made # -- we'll use them to test that the semnatics work correctly. self.set_encoding_parameters(k=3, happy=5, n=10) - d = self.shouldFail(NotEnoughSharesError, "test_happy_semantics", + d = self.shouldFail(UploadHappinessError, "test_happy_semantics", "shares could only be placed on 2 servers " "(5 were requested)", self.u.upload, DATA) @@ -886,7 +885,7 @@ class EncodingParameters(GridTestMixin, unittest.TestCase, SetDEPMixin, _prepare()) # Uploading data should fail d.addCallback(lambda client: - self.shouldFail(NotEnoughSharesError, "test_happy_semantics", + self.shouldFail(UploadHappinessError, "test_happy_semantics", "shares could only be placed on 2 servers " "(4 were requested)", client.upload, upload.Data("data" * 10000, @@ -916,7 +915,7 @@ class EncodingParameters(GridTestMixin, unittest.TestCase, SetDEPMixin, d.addCallback(lambda ign: _prepare2()) d.addCallback(lambda client: - self.shouldFail(NotEnoughSharesError, "test_happy_sematics", + self.shouldFail(UploadHappinessError, "test_happy_sematics", "shares could only be placed on 2 servers " "(3 were requested)", client.upload, upload.Data("data" * 10000, @@ -1122,7 +1121,7 @@ class EncodingParameters(GridTestMixin, unittest.TestCase, SetDEPMixin, d.addCallback(_do_server_setup) d.addCallback(_remove_server) d.addCallback(lambda ign: - self.shouldFail(NotEnoughSharesError, + self.shouldFail(UploadHappinessError, "test_dropped_servers_in_encoder", "lost too many servers during upload " "(still have 3, want 4)", @@ -1149,7 +1148,7 @@ class EncodingParameters(GridTestMixin, unittest.TestCase, SetDEPMixin, d.addCallback(_do_server_setup_2) d.addCallback(_remove_server) d.addCallback(lambda ign: - self.shouldFail(NotEnoughSharesError, + self.shouldFail(UploadHappinessError, "test_dropped_servers_in_encoder", "lost too many servers during upload " "(still have 3, want 4)", @@ -1273,6 +1272,94 @@ class EncodingParameters(GridTestMixin, unittest.TestCase, SetDEPMixin, self.failUnless(upload.should_add_server(shares, "server1", 1)) + def test_exception_messages_during_peer_selection(self): + # server 1: readonly, no shares + # server 2: readonly, no shares + # server 3: readonly, no shares + # server 4: readonly, no shares + # server 5: readonly, no shares + # This will fail, but we want to make sure that the log messages + # are informative about why it has failed. + self.basedir = self.mktemp() + d = self._setup_and_upload() + d.addCallback(lambda ign: + self._add_server_with_share(server_number=1, readonly=True)) + d.addCallback(lambda ign: + self._add_server_with_share(server_number=2, readonly=True)) + d.addCallback(lambda ign: + self._add_server_with_share(server_number=3, readonly=True)) + d.addCallback(lambda ign: + self._add_server_with_share(server_number=4, readonly=True)) + d.addCallback(lambda ign: + self._add_server_with_share(server_number=5, readonly=True)) + d.addCallback(lambda ign: + self.g.remove_server(self.g.servers_by_number[0].my_nodeid)) + def _reset_encoding_parameters(ign): + client = self.g.clients[0] + client.DEFAULT_ENCODING_PARAMETERS['happy'] = 4 + return client + d.addCallback(_reset_encoding_parameters) + d.addCallback(lambda client: + self.shouldFail(UploadHappinessError, "test_selection_exceptions", + "peer selection failed for : placed 0 shares out of 10 " + "total (10 homeless), want to place on 4 servers," + " sent 5 queries to 5 peers, 0 queries placed " + "some shares, 5 placed none " + "(of which 5 placed none due to the server being " + "full and 0 placed none due to an error)", + client.upload, + upload.Data("data" * 10000, convergence=""))) + + + # server 1: readonly, no shares + # server 2: broken, no shares + # server 3: readonly, no shares + # server 4: readonly, no shares + # server 5: readonly, no shares + def _reset(ign): + self.basedir = self.mktemp() + d.addCallback(_reset) + d.addCallback(lambda ign: + self._setup_and_upload()) + d.addCallback(lambda ign: + self._add_server_with_share(server_number=1, readonly=True)) + d.addCallback(lambda ign: + self._add_server_with_share(server_number=2)) + def _break_server_2(ign): + server = self.g.servers_by_number[2].my_nodeid + # We have to break the server in servers_by_id, + # because the ones in servers_by_number isn't wrapped, + # and doesn't look at its broken attribute + self.g.servers_by_id[server].broken = True + d.addCallback(_break_server_2) + d.addCallback(lambda ign: + self._add_server_with_share(server_number=3, readonly=True)) + d.addCallback(lambda ign: + self._add_server_with_share(server_number=4, readonly=True)) + d.addCallback(lambda ign: + self._add_server_with_share(server_number=5, readonly=True)) + d.addCallback(lambda ign: + self.g.remove_server(self.g.servers_by_number[0].my_nodeid)) + def _reset_encoding_parameters(ign): + client = self.g.clients[0] + client.DEFAULT_ENCODING_PARAMETERS['happy'] = 4 + return client + d.addCallback(_reset_encoding_parameters) + d.addCallback(lambda client: + self.shouldFail(UploadHappinessError, "test_selection_exceptions", + "peer selection failed for : placed 0 shares out of 10 " + "total (10 homeless), want to place on 4 servers," + " sent 5 queries to 5 peers, 0 queries placed " + "some shares, 5 placed none " + "(of which 4 placed none due to the server being " + "full and 1 placed none due to an error)", + client.upload, + upload.Data("data" * 10000, convergence=""))) + return d + + def _set_up_nodes_extra_config(self, clientdir): cfgfn = os.path.join(clientdir, "tahoe.cfg") oldcfg = open(cfgfn, "r").read() -- 2.45.2