/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_remote.py

  • Committer: John Arbash Meinel
  • Date: 2008-09-05 03:11:40 UTC
  • mfrom: (3691 +trunk)
  • mto: (3697.7.4 1.7)
  • mto: This revision was merged to the branch mainline in revision 3748.
  • Revision ID: john@arbash-meinel.com-20080905031140-hj0adlcf30l7i99v
Merge in bzr.dev 3691

Show diffs side-by-side

added added

removed removed

Lines of Context:
541
541
        client.add_success_response('ok')
542
542
 
543
543
        bzrdir = RemoteBzrDir(transport, _client=False)
544
 
        branch = RemoteBranch(bzrdir, None, _client=client)
 
544
        repo = RemoteRepository(bzrdir, None, _client=client)
 
545
        branch = RemoteBranch(bzrdir, repo, _client=client)
545
546
        branch._ensure_real = lambda: None
546
547
        branch.lock_write()
547
548
        client._calls = []
550
551
            errors.NoSuchRevision, branch.set_revision_history, ['rev-id'])
551
552
        branch.unlock()
552
553
 
 
554
    def test_tip_change_rejected(self):
 
555
        """TipChangeRejected responses cause a TipChangeRejected exception to
 
556
        be raised.
 
557
        """
 
558
        transport = MemoryTransport()
 
559
        transport.mkdir('branch')
 
560
        transport = transport.clone('branch')
 
561
        client = FakeClient(transport.base)
 
562
        # lock_write
 
563
        client.add_success_response('ok', 'branch token', 'repo token')
 
564
        # set_last_revision
 
565
        rejection_msg_unicode = u'rejection message\N{INTERROBANG}'
 
566
        rejection_msg_utf8 = rejection_msg_unicode.encode('utf8')
 
567
        client.add_error_response('TipChangeRejected', rejection_msg_utf8)
 
568
        # unlock
 
569
        client.add_success_response('ok')
 
570
 
 
571
        bzrdir = RemoteBzrDir(transport, _client=False)
 
572
        repo = RemoteRepository(bzrdir, None, _client=client)
 
573
        branch = RemoteBranch(bzrdir, repo, _client=client)
 
574
        branch._ensure_real = lambda: None
 
575
        branch.lock_write()
 
576
        self.addCleanup(branch.unlock)
 
577
        client._calls = []
 
578
 
 
579
        # The 'TipChangeRejected' error response triggered by calling
 
580
        # set_revision_history causes a TipChangeRejected exception.
 
581
        err = self.assertRaises(
 
582
            errors.TipChangeRejected, branch.set_revision_history, ['rev-id'])
 
583
        # The UTF-8 message from the response has been decoded into a unicode
 
584
        # object.
 
585
        self.assertIsInstance(err.msg, unicode)
 
586
        self.assertEqual(rejection_msg_unicode, err.msg)
 
587
 
553
588
 
554
589
class TestBranchSetLastRevisionInfo(tests.TestCase):
555
590
 
597
632
        client.add_success_response('ok')
598
633
 
599
634
        bzrdir = RemoteBzrDir(transport, _client=False)
600
 
        branch = RemoteBranch(bzrdir, None, _client=client)
 
635
        repo = RemoteRepository(bzrdir, None, _client=client)
 
636
        branch = RemoteBranch(bzrdir, repo, _client=client)
601
637
        # This is a hack to work around the problem that RemoteBranch currently
602
638
        # unnecessarily invokes _ensure_real upon a call to lock_write.
603
639
        branch._ensure_real = lambda: None
672
708
        client.add_success_response('ok')
673
709
 
674
710
        bzrdir = RemoteBzrDir(transport, _client=False)
675
 
        branch = RemoteBranch(bzrdir, None, _client=client)
 
711
        repo = RemoteRepository(bzrdir, None, _client=client)
 
712
        branch = RemoteBranch(bzrdir, repo, _client=client)
676
713
        # This is a hack to work around the problem that RemoteBranch currently
677
714
        # unnecessarily invokes _ensure_real upon a call to lock_write.
678
715
        branch._ensure_real = lambda: None
686
723
        self.assertEqual(('UnexpectedError',), err.error_tuple)
687
724
        branch.unlock()
688
725
 
 
726
    def test_tip_change_rejected(self):
 
727
        """TipChangeRejected responses cause a TipChangeRejected exception to
 
728
        be raised.
 
729
        """
 
730
        transport = MemoryTransport()
 
731
        transport.mkdir('branch')
 
732
        transport = transport.clone('branch')
 
733
        client = FakeClient(transport.base)
 
734
        # lock_write
 
735
        client.add_success_response('ok', 'branch token', 'repo token')
 
736
        # set_last_revision
 
737
        client.add_error_response('TipChangeRejected', 'rejection message')
 
738
        # unlock
 
739
        client.add_success_response('ok')
 
740
 
 
741
        bzrdir = RemoteBzrDir(transport, _client=False)
 
742
        repo = RemoteRepository(bzrdir, None, _client=client)
 
743
        branch = RemoteBranch(bzrdir, repo, _client=client)
 
744
        # This is a hack to work around the problem that RemoteBranch currently
 
745
        # unnecessarily invokes _ensure_real upon a call to lock_write.
 
746
        branch._ensure_real = lambda: None
 
747
        # Lock the branch, reset the record of remote calls.
 
748
        branch.lock_write()
 
749
        self.addCleanup(branch.unlock)
 
750
        client._calls = []
 
751
 
 
752
        # The 'TipChangeRejected' error response triggered by calling
 
753
        # set_last_revision_info causes a TipChangeRejected exception.
 
754
        err = self.assertRaises(
 
755
            errors.TipChangeRejected,
 
756
            branch.set_last_revision_info, 123, 'revid')
 
757
        self.assertEqual('rejection message', err.msg)
 
758
 
689
759
 
690
760
class TestBranchControlGetBranchConf(tests.TestCaseWithMemoryTransport):
691
761
    """Getting the branch configuration should use an abstract method not vfs.
723
793
        transport = transport.clone('quack')
724
794
        # we do not want bzrdir to make any remote calls
725
795
        bzrdir = RemoteBzrDir(transport, _client=False)
726
 
        branch = RemoteBranch(bzrdir, None, _client=client)
 
796
        repo = RemoteRepository(bzrdir, None, _client=client)
 
797
        branch = RemoteBranch(bzrdir, repo, _client=client)
727
798
        self.assertRaises(errors.UnlockableTransport, branch.lock_write)
728
799
        self.assertEqual(
729
800
            [('call', 'Branch.lock_write', ('quack/', '', ''))],
1182
1253
        self.assertFalse(isinstance(dest_repo, RemoteRepository))
1183
1254
        self.assertTrue(isinstance(src_repo, RemoteRepository))
1184
1255
        src_repo.copy_content_into(dest_repo)
 
1256
 
 
1257
 
 
1258
class TestErrorTranslationBase(tests.TestCaseWithMemoryTransport):
 
1259
    """Base class for unit tests for bzrlib.remote._translate_error."""
 
1260
 
 
1261
    def translateTuple(self, error_tuple, **context):
 
1262
        """Call _translate_error with an ErrorFromSmartServer built from the
 
1263
        given error_tuple.
 
1264
 
 
1265
        :param error_tuple: A tuple of a smart server response, as would be
 
1266
            passed to an ErrorFromSmartServer.
 
1267
        :kwargs context: context items to call _translate_error with.
 
1268
 
 
1269
        :returns: The error raised by _translate_error.
 
1270
        """
 
1271
        # Raise the ErrorFromSmartServer before passing it as an argument,
 
1272
        # because _translate_error may need to re-raise it with a bare 'raise'
 
1273
        # statement.
 
1274
        server_error = errors.ErrorFromSmartServer(error_tuple)
 
1275
        translated_error = self.translateErrorFromSmartServer(
 
1276
            server_error, **context)
 
1277
        return translated_error
 
1278
 
 
1279
    def translateErrorFromSmartServer(self, error_object, **context):
 
1280
        """Like translateTuple, but takes an already constructed
 
1281
        ErrorFromSmartServer rather than a tuple.
 
1282
        """
 
1283
        try:
 
1284
            raise error_object
 
1285
        except errors.ErrorFromSmartServer, server_error:
 
1286
            translated_error = self.assertRaises(
 
1287
                errors.BzrError, remote._translate_error, server_error,
 
1288
                **context)
 
1289
        return translated_error
 
1290
 
 
1291
    
 
1292
class TestErrorTranslationSuccess(TestErrorTranslationBase):
 
1293
    """Unit tests for bzrlib.remote._translate_error.
 
1294
    
 
1295
    Given an ErrorFromSmartServer (which has an error tuple from a smart
 
1296
    server) and some context, _translate_error raises more specific errors from
 
1297
    bzrlib.errors.
 
1298
 
 
1299
    This test case covers the cases where _translate_error succeeds in
 
1300
    translating an ErrorFromSmartServer to something better.  See
 
1301
    TestErrorTranslationRobustness for other cases.
 
1302
    """
 
1303
 
 
1304
    def test_NoSuchRevision(self):
 
1305
        branch = self.make_branch('')
 
1306
        revid = 'revid'
 
1307
        translated_error = self.translateTuple(
 
1308
            ('NoSuchRevision', revid), branch=branch)
 
1309
        expected_error = errors.NoSuchRevision(branch, revid)
 
1310
        self.assertEqual(expected_error, translated_error)
 
1311
 
 
1312
    def test_nosuchrevision(self):
 
1313
        repository = self.make_repository('')
 
1314
        revid = 'revid'
 
1315
        translated_error = self.translateTuple(
 
1316
            ('nosuchrevision', revid), repository=repository)
 
1317
        expected_error = errors.NoSuchRevision(repository, revid)
 
1318
        self.assertEqual(expected_error, translated_error)
 
1319
 
 
1320
    def test_nobranch(self):
 
1321
        bzrdir = self.make_bzrdir('')
 
1322
        translated_error = self.translateTuple(('nobranch',), bzrdir=bzrdir)
 
1323
        expected_error = errors.NotBranchError(path=bzrdir.root_transport.base)
 
1324
        self.assertEqual(expected_error, translated_error)
 
1325
 
 
1326
    def test_LockContention(self):
 
1327
        translated_error = self.translateTuple(('LockContention',))
 
1328
        expected_error = errors.LockContention('(remote lock)')
 
1329
        self.assertEqual(expected_error, translated_error)
 
1330
 
 
1331
    def test_UnlockableTransport(self):
 
1332
        bzrdir = self.make_bzrdir('')
 
1333
        translated_error = self.translateTuple(
 
1334
            ('UnlockableTransport',), bzrdir=bzrdir)
 
1335
        expected_error = errors.UnlockableTransport(bzrdir.root_transport)
 
1336
        self.assertEqual(expected_error, translated_error)
 
1337
 
 
1338
    def test_LockFailed(self):
 
1339
        lock = 'str() of a server lock'
 
1340
        why = 'str() of why'
 
1341
        translated_error = self.translateTuple(('LockFailed', lock, why))
 
1342
        expected_error = errors.LockFailed(lock, why)
 
1343
        self.assertEqual(expected_error, translated_error)
 
1344
 
 
1345
    def test_TokenMismatch(self):
 
1346
        token = 'a lock token'
 
1347
        translated_error = self.translateTuple(('TokenMismatch',), token=token)
 
1348
        expected_error = errors.TokenMismatch(token, '(remote token)')
 
1349
        self.assertEqual(expected_error, translated_error)
 
1350
 
 
1351
    def test_Diverged(self):
 
1352
        branch = self.make_branch('a')
 
1353
        other_branch = self.make_branch('b')
 
1354
        translated_error = self.translateTuple(
 
1355
            ('Diverged',), branch=branch, other_branch=other_branch)
 
1356
        expected_error = errors.DivergedBranches(branch, other_branch)
 
1357
        self.assertEqual(expected_error, translated_error)
 
1358
 
 
1359
 
 
1360
class TestErrorTranslationRobustness(TestErrorTranslationBase):
 
1361
    """Unit tests for bzrlib.remote._translate_error's robustness.
 
1362
    
 
1363
    TestErrorTranslationSuccess is for cases where _translate_error can
 
1364
    translate successfully.  This class about how _translate_err behaves when
 
1365
    it fails to translate: it re-raises the original error.
 
1366
    """
 
1367
 
 
1368
    def test_unrecognised_server_error(self):
 
1369
        """If the error code from the server is not recognised, the original
 
1370
        ErrorFromSmartServer is propagated unmodified.
 
1371
        """
 
1372
        error_tuple = ('An unknown error tuple',)
 
1373
        server_error = errors.ErrorFromSmartServer(error_tuple)
 
1374
        translated_error = self.translateErrorFromSmartServer(server_error)
 
1375
        self.assertEqual(server_error, translated_error)
 
1376
 
 
1377
    def test_context_missing_a_key(self):
 
1378
        """In case of a bug in the client, or perhaps an unexpected response
 
1379
        from a server, _translate_error returns the original error tuple from
 
1380
        the server and mutters a warning.
 
1381
        """
 
1382
        # To translate a NoSuchRevision error _translate_error needs a 'branch'
 
1383
        # in the context dict.  So let's give it an empty context dict instead
 
1384
        # to exercise its error recovery.
 
1385
        empty_context = {}
 
1386
        error_tuple = ('NoSuchRevision', 'revid')
 
1387
        server_error = errors.ErrorFromSmartServer(error_tuple)
 
1388
        translated_error = self.translateErrorFromSmartServer(server_error)
 
1389
        self.assertEqual(server_error, translated_error)
 
1390
        # In addition to re-raising ErrorFromSmartServer, some debug info has
 
1391
        # been muttered to the log file for developer to look at.
 
1392
        self.assertContainsRe(
 
1393
            self._get_log(keep_log_file=True),
 
1394
            "Missing key 'branch' in context")
 
1395