~rodrigo-moya/ubuntuone-client/remove-share-with

« back to all changes in this revision

Viewing changes to tests/syncdaemon/test_action_queue.py

  • Committer: Tarmac
  • Author(s): facundo at com
  • Date: 2010-04-12 17:15:45 UTC
  • mfrom: (476.3.8 aqc_errors)
  • Revision ID: dobey@wayofthemonkey.com-20100412171545-auw165nwbf15o1d3
Make ActionQueueCommand to handle errors by their type, not message.

Show diffs side-by-side

added added

removed removed

Lines of Context:
33
33
from functools import wraps
34
34
from StringIO import StringIO
35
35
from twisted.internet import defer, threads, reactor
 
36
from twisted.internet import error as twisted_error
36
37
from twisted.python.failure import DefaultException, Failure
37
38
from twisted.web import server
38
39
 
784
785
        self.assertTrue(res is None)
785
786
 
786
787
 
 
788
class ActionQueueCommandErrors(ConnectedBaseTestCase):
 
789
    """Test the error handling in ActionQueueCommand."""
 
790
 
 
791
    def setUp(self):
 
792
        res = super(ActionQueueCommandErrors, self).setUp()
 
793
 
 
794
        self.deferred = defer.Deferred()
 
795
 
 
796
        class MyLogger(object):
 
797
            """Fake logger that just stores error and warning calls."""
 
798
            def __init__(self):
 
799
                self.logged = None
 
800
 
 
801
            def error(self, *a):
 
802
                """Mark that this method was called."""
 
803
                self.logged = "error"
 
804
 
 
805
            def warn(self, *a):
 
806
                """Mark that this method was called."""
 
807
                self.logged = "warn"
 
808
 
 
809
            def debug(self, *a):
 
810
                """Nothing."""
 
811
 
 
812
        class MyCommand(ActionQueueCommand):
 
813
            """Inherit ACQ to provide a retry signaller and a custom log."""
 
814
            # class-closure, cannot use self, pylint: disable-msg=E0213
 
815
            def __init__(innerself, request_queue):
 
816
                super(MyCommand, innerself).__init__(request_queue)
 
817
                innerself.log = MyLogger()
 
818
 
 
819
            def retry(innerself):
 
820
                """Signal the retry."""
 
821
                self.deferred.callback(True)
 
822
 
 
823
        self.rq = RequestQueue(name='foo', action_queue=self.action_queue)
 
824
        self.command = MyCommand(self.rq)
 
825
        return res
 
826
 
 
827
    def test_suppressed_yes_knownerrors(self):
 
828
        """Check that the log is in warning for the known errors."""
 
829
        def send_failure_and_check(errnum, exception_class):
 
830
            """Send the failure."""
 
831
            # prepare what to send
 
832
            protocol_msg = protocol_pb2.Message()
 
833
            protocol_msg.type = protocol_pb2.Message.ERROR
 
834
            protocol_msg.error.type = errnum
 
835
            err = exception_class("request", protocol_msg)
 
836
 
 
837
            # set up and test
 
838
            self.command.log.logged = None
 
839
            self.command.end_errback(failure=Failure(err))
 
840
            self.assertEqual(self.command.log.logged, "warn",
 
841
                             "Bad log in exception %s" % (exception_class,))
 
842
 
 
843
        known_errors = [x for x in errors._error_mapping.items()
 
844
                        if x[1] != errors.InternalError]
 
845
        for errnum, exception_class in known_errors:
 
846
            send_failure_and_check(errnum, exception_class)
 
847
 
 
848
    def test_suppressed_no_internalerror(self):
 
849
        """Check that the log is in error for InternalError."""
 
850
        # prepare what to send
 
851
        protocol_msg = protocol_pb2.Message()
 
852
        protocol_msg.type = protocol_pb2.Message.ERROR
 
853
        protocol_msg.error.type = protocol_pb2.Error.INTERNAL_ERROR
 
854
        err = errors.InternalError("request", protocol_msg)
 
855
 
 
856
        # set up and test
 
857
        self.command.end_errback(failure=Failure(err))
 
858
        self.assertEqual(self.command.log.logged, "error")
 
859
 
 
860
    def test_suppressed_yes_cancelled(self):
 
861
        """Check that the log is in warning for Cancelled."""
 
862
        err = errors.RequestCancelledError("CANCELLED")
 
863
        self.command.end_errback(failure=Failure(err))
 
864
        self.assertEqual(self.command.log.logged, "warn")
 
865
 
 
866
    def test_suppressed_yes_and_retry_when_connectiondone(self):
 
867
        """Check that the log is in warning and retries for ConnectionDone."""
 
868
        self.command.running = True
 
869
        err = twisted_error.ConnectionDone()
 
870
        self.command.end_errback(failure=Failure(err))
 
871
        self.assertEqual(self.command.log.logged, "warn")
 
872
        return self.deferred
 
873
 
 
874
    def test_retry_connectionlost(self):
 
875
        """Check that it retries when ConnectionLost."""
 
876
        self.command.running = True
 
877
        err = twisted_error.ConnectionLost()
 
878
        self.command.end_errback(failure=Failure(err))
 
879
        return self.deferred
 
880
 
 
881
    def test_retry_tryagain(self):
 
882
        """Check that it retries when TryAgain."""
 
883
        # prepare what to send
 
884
        self.command.running = True
 
885
        protocol_msg = protocol_pb2.Message()
 
886
        protocol_msg.type = protocol_pb2.Message.ERROR
 
887
        protocol_msg.error.type = protocol_pb2.Error.TRY_AGAIN
 
888
        err = errors.TryAgainError("request", protocol_msg)
 
889
 
 
890
        # set up and test
 
891
        self.command.end_errback(failure=Failure(err))
 
892
        return self.deferred
 
893
 
 
894
 
787
895
class ListVolumesTestCase(ConnectedBaseTestCase):
788
896
    """Test for ListVolumes ActionQueueCommand."""
789
897
 
1171
1279
 
1172
1280
    def test_failure_with_CANCELLED(self):
1173
1281
        """AQ_DOWNLOAD_CANCELLED is pushed."""
1174
 
        msg = 'CANCELLED'
1175
 
        failure = Failure(DefaultException(msg))
1176
 
        res = self.command.handle_failure(failure=failure)
 
1282
        err = errors.RequestCancelledError("CANCELLED")
 
1283
        res = self.command.handle_failure(failure=Failure(err))
1177
1284
        kwargs = dict(share_id='a_share_id', node_id='a_node_id',
1178
1285
                      server_hash='a_server_hash')
1179
1286
        events = [('AQ_DOWNLOAD_CANCELLED', (), kwargs)]
1193
1300
 
1194
1301
    def test_failure_with_DOES_NOT_EXIST(self):
1195
1302
        """AQ_DOWNLOAD_DOES_NOT_EXIST is pushed."""
1196
 
        msg = 'DOES_NOT_EXIST'
1197
 
        failure = Failure(DefaultException(msg))
1198
 
        res = self.command.handle_failure(failure=failure)
 
1303
        protocol_msg = protocol_pb2.Message()
 
1304
        protocol_msg.type = protocol_pb2.Message.ERROR
 
1305
        protocol_msg.error.type = protocol_pb2.Error.DOES_NOT_EXIST
 
1306
        err = errors.DoesNotExistError("request", protocol_msg)
 
1307
        res = self.command.handle_failure(failure=Failure(err))
1199
1308
        kwargs = dict(share_id='a_share_id', node_id='a_node_id')
1200
1309
        events = [('AQ_DOWNLOAD_DOES_NOT_EXIST', (), kwargs)]
1201
1310
        self.assertEquals(events, self.command.action_queue.event_queue.events)
1224
1333
 
1225
1334
    def setUp(self):
1226
1335
        """Init."""
1227
 
        res = super(UploadTestCase, self).setUp()
 
1336
        super(UploadTestCase, self).setUp()
1228
1337
 
1229
 
        request_queue = RequestQueue(name='FOO', action_queue=self.action_queue)
 
1338
        self.rq = request_queue = RequestQueue(name='FOO',
 
1339
                                               action_queue=self.action_queue)
1230
1340
        self.command = Upload(request_queue, share_id='a_share_id',
1231
1341
                              node_id='a_node_id', previous_hash='prev_hash',
1232
1342
                              hash='yadda', crc32=0, size=0,
1234
1344
                              tempfile_factory=lambda: None)
1235
1345
        self.command.start_unqueued() # create the logger
1236
1346
 
1237
 
        return res
 
1347
    def test_upload_in_progress(self):
 
1348
        """Test Upload retries on UploadInProgress."""
 
1349
        # monkeypatching is not allowed, let's do inheritance
 
1350
        d = defer.Deferred()
 
1351
        class MyUpload(Upload):
 
1352
            """Just to redefine retry."""
 
1353
            def retry(self):
 
1354
                """Detect retry was called."""
 
1355
                d.callback(True)
 
1356
 
 
1357
        # set up the command
 
1358
        command = MyUpload(self.rq, 'share', 'bode', 'prvhash', 'currhash',
 
1359
                           0, 0, lambda: None, lambda: None)
 
1360
        command.start_unqueued() # create log in the instance
 
1361
        command.running = True
 
1362
 
 
1363
        # send the failure
 
1364
        protocol_msg = protocol_pb2.Message()
 
1365
        protocol_msg.type = protocol_pb2.Message.ERROR
 
1366
        protocol_msg.error.type = protocol_pb2.Error.UPLOAD_IN_PROGRESS
 
1367
        err = errors.UploadInProgressError("request", protocol_msg)
 
1368
        command.end_errback(failure=Failure(err))
 
1369
        return d
1238
1370
 
1239
1371
    def test_handle_success_push_event(self):
1240
1372
        """Test AQ_UPLOAD_FINISHED is pushed on success."""