/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: Martin Pool
  • Date: 2009-03-03 03:01:49 UTC
  • mfrom: (4070 +trunk)
  • mto: This revision was merged to the branch mainline in revision 4073.
  • Revision ID: mbp@sourcefrog.net-20090303030149-8p8o8hszdtqa7w8f
merge trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
 
19
19
These are proxy objects which act on remote objects by sending messages
20
20
through a smart client.  The proxies are to be created when attempting to open
21
 
the object given a transport that supports smartserver rpc operations. 
 
21
the object given a transport that supports smartserver rpc operations.
22
22
 
23
23
These tests correspond to tests.test_smart, which exercises the server side.
24
24
"""
34
34
    pack,
35
35
    remote,
36
36
    repository,
 
37
    smart,
37
38
    tests,
38
39
    urlutils,
39
40
    )
138
139
 
139
140
class FakeClient(_SmartClient):
140
141
    """Lookalike for _SmartClient allowing testing."""
141
 
    
 
142
 
142
143
    def __init__(self, fake_medium_base='fake base'):
143
144
        """Create a FakeClient."""
144
145
        self.responses = []
259
260
        self.assertTrue(result)
260
261
 
261
262
 
 
263
class TestRemote(tests.TestCaseWithMemoryTransport):
 
264
 
 
265
    def get_repo_format(self):
 
266
        reference_bzrdir_format = bzrdir.format_registry.get('default')()
 
267
        return reference_bzrdir_format.repository_format
 
268
 
 
269
    def disable_verb(self, verb):
 
270
        """Disable a verb for one test."""
 
271
        request_handlers = smart.request.request_handlers
 
272
        orig_method = request_handlers.get(verb)
 
273
        request_handlers.remove(verb)
 
274
        def restoreVerb():
 
275
            request_handlers.register(verb, orig_method)
 
276
        self.addCleanup(restoreVerb)
 
277
 
 
278
 
262
279
class Test_ClientMedium_remote_path_from_transport(tests.TestCase):
263
280
    """Tests for the behaviour of client_medium.remote_path_from_transport."""
264
281
 
291
308
        cloned_transport = base_transport.clone(relpath)
292
309
        result = client_medium.remote_path_from_transport(cloned_transport)
293
310
        self.assertEqual(expected, result)
294
 
        
 
311
 
295
312
    def test_remote_path_from_transport_http(self):
296
313
        """Remote paths for HTTP transports are calculated differently to other
297
314
        transports.  They are just relative to the client base, not the root
313
330
        """
314
331
        client_medium = medium.SmartClientMedium('dummy base')
315
332
        self.assertFalse(client_medium._is_remote_before((99, 99)))
316
 
    
 
333
 
317
334
    def test__remember_remote_is_before(self):
318
335
        """Calling _remember_remote_is_before ratchets down the known remote
319
336
        version.
332
349
            AssertionError, client_medium._remember_remote_is_before, (1, 9))
333
350
 
334
351
 
335
 
class TestBzrDirOpenBranch(tests.TestCase):
 
352
class TestBzrDirOpenBranch(TestRemote):
336
353
 
337
354
    def test_branch_present(self):
 
355
        reference_format = self.get_repo_format()
 
356
        network_name = reference_format.network_name()
338
357
        transport = MemoryTransport()
339
358
        transport.mkdir('quack')
340
359
        transport = transport.clone('quack')
343
362
            'BzrDir.open_branch', ('quack/',),
344
363
            'success', ('ok', ''))
345
364
        client.add_expected_call(
346
 
            'BzrDir.find_repositoryV2', ('quack/',),
347
 
            'success', ('ok', '', 'no', 'no', 'no'))
 
365
            'BzrDir.find_repositoryV3', ('quack/',),
 
366
            'success', ('ok', '', 'no', 'no', 'no', network_name))
348
367
        client.add_expected_call(
349
368
            'Branch.get_stacked_on_url', ('quack/',),
350
369
            'error', ('NotStacked',))
391
410
        # transmitted as "~", not "%7E".
392
411
        transport = RemoteTCPTransport('bzr://localhost/~hello/')
393
412
        client = FakeClient(transport.base)
 
413
        reference_format = self.get_repo_format()
 
414
        network_name = reference_format.network_name()
394
415
        client.add_expected_call(
395
416
            'BzrDir.open_branch', ('~hello/',),
396
417
            'success', ('ok', ''))
397
418
        client.add_expected_call(
398
 
            'BzrDir.find_repositoryV2', ('~hello/',),
399
 
            'success', ('ok', '', 'no', 'no', 'no'))
 
419
            'BzrDir.find_repositoryV3', ('~hello/',),
 
420
            'success', ('ok', '', 'no', 'no', 'no', network_name))
400
421
        client.add_expected_call(
401
422
            'Branch.get_stacked_on_url', ('~hello/',),
402
423
            'error', ('NotStacked',))
406
427
        client.finished_test()
407
428
 
408
429
    def check_open_repository(self, rich_root, subtrees, external_lookup='no'):
 
430
        reference_format = self.get_repo_format()
 
431
        network_name = reference_format.network_name()
409
432
        transport = MemoryTransport()
410
433
        transport.mkdir('quack')
411
434
        transport = transport.clone('quack')
419
442
            subtree_response = 'no'
420
443
        client = FakeClient(transport.base)
421
444
        client.add_success_response(
422
 
            'ok', '', rich_response, subtree_response, external_lookup)
 
445
            'ok', '', rich_response, subtree_response, external_lookup,
 
446
            network_name)
423
447
        bzrdir = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
424
448
            _client=client)
425
449
        result = bzrdir.open_repository()
426
450
        self.assertEqual(
427
 
            [('call', 'BzrDir.find_repositoryV2', ('quack/',))],
 
451
            [('call', 'BzrDir.find_repositoryV3', ('quack/',))],
428
452
            client._calls)
429
453
        self.assertIsInstance(result, RemoteRepository)
430
454
        self.assertEqual(bzrdir, result.bzrdir)
446
470
            RemoteBzrDirFormat.probe_transport, OldServerTransport())
447
471
 
448
472
 
449
 
class TestBzrDirOpenRepository(tests.TestCase):
450
 
 
451
 
    def test_backwards_compat_1_2(self):
452
 
        transport = MemoryTransport()
453
 
        transport.mkdir('quack')
454
 
        transport = transport.clone('quack')
455
 
        client = FakeClient(transport.base)
456
 
        client.add_unknown_method_response('RemoteRepository.find_repositoryV2')
 
473
class TestBzrDirCreateBranch(TestRemote):
 
474
 
 
475
    def test_backwards_compat(self):
 
476
        self.setup_smart_server_with_call_log()
 
477
        repo = self.make_repository('.')
 
478
        self.reset_smart_call_log()
 
479
        self.disable_verb('BzrDir.create_branch')
 
480
        branch = repo.bzrdir.create_branch()
 
481
        create_branch_call_count = len([call for call in self.hpss_calls if
 
482
            call[0].method == 'BzrDir.create_branch'])
 
483
        self.assertEqual(1, create_branch_call_count)
 
484
 
 
485
    def test_current_server(self):
 
486
        transport = self.get_transport('.')
 
487
        transport = transport.clone('quack')
 
488
        self.make_repository('quack')
 
489
        client = FakeClient(transport.base)
 
490
        reference_bzrdir_format = bzrdir.format_registry.get('default')()
 
491
        reference_format = reference_bzrdir_format.get_branch_format()
 
492
        network_name = reference_format.network_name()
 
493
        reference_repo_fmt = reference_bzrdir_format.repository_format
 
494
        reference_repo_name = reference_repo_fmt.network_name()
 
495
        client.add_expected_call(
 
496
            'BzrDir.create_branch', ('quack/', network_name),
 
497
            'success', ('ok', network_name, '', 'no', 'no', 'yes',
 
498
            reference_repo_name))
 
499
        a_bzrdir = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
 
500
            _client=client)
 
501
        branch = a_bzrdir.create_branch()
 
502
        # We should have got a remote branch
 
503
        self.assertIsInstance(branch, remote.RemoteBranch)
 
504
        # its format should have the settings from the response
 
505
        format = branch._format
 
506
        self.assertEqual(network_name, format.network_name())
 
507
 
 
508
 
 
509
class TestBzrDirCreateRepository(TestRemote):
 
510
 
 
511
    def test_backwards_compat(self):
 
512
        self.setup_smart_server_with_call_log()
 
513
        bzrdir = self.make_bzrdir('.')
 
514
        self.reset_smart_call_log()
 
515
        self.disable_verb('BzrDir.create_repository')
 
516
        repo = bzrdir.create_repository()
 
517
        create_repo_call_count = len([call for call in self.hpss_calls if
 
518
            call[0].method == 'BzrDir.create_repository'])
 
519
        self.assertEqual(1, create_repo_call_count)
 
520
 
 
521
    def test_current_server(self):
 
522
        transport = self.get_transport('.')
 
523
        transport = transport.clone('quack')
 
524
        self.make_bzrdir('quack')
 
525
        client = FakeClient(transport.base)
 
526
        reference_bzrdir_format = bzrdir.format_registry.get('default')()
 
527
        reference_format = reference_bzrdir_format.repository_format
 
528
        network_name = reference_format.network_name()
 
529
        client.add_expected_call(
 
530
            'BzrDir.create_repository', ('quack/',
 
531
                'Bazaar pack repository format 1 (needs bzr 0.92)\n', 'False'),
 
532
            'success', ('ok', 'no', 'no', 'no', network_name))
 
533
        a_bzrdir = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
 
534
            _client=client)
 
535
        repo = a_bzrdir.create_repository()
 
536
        # We should have got a remote repository
 
537
        self.assertIsInstance(repo, remote.RemoteRepository)
 
538
        # its format should have the settings from the response
 
539
        format = repo._format
 
540
        self.assertFalse(format.rich_root_data)
 
541
        self.assertFalse(format.supports_tree_reference)
 
542
        self.assertFalse(format.supports_external_lookups)
 
543
        self.assertEqual(network_name, format.network_name())
 
544
 
 
545
 
 
546
class TestBzrDirOpenRepository(TestRemote):
 
547
 
 
548
    def test_backwards_compat_1_2_3(self):
 
549
        # fallback all the way to the first version.
 
550
        reference_format = self.get_repo_format()
 
551
        network_name = reference_format.network_name()
 
552
        client = FakeClient('bzr://example.com/')
 
553
        client.add_unknown_method_response('BzrDir.find_repositoryV3')
 
554
        client.add_unknown_method_response('BzrDir.find_repositoryV2')
457
555
        client.add_success_response('ok', '', 'no', 'no')
 
556
        # A real repository instance will be created to determine the network
 
557
        # name.
 
558
        client.add_success_response_with_body(
 
559
            "Bazaar-NG meta directory, format 1\n", 'ok')
 
560
        client.add_success_response_with_body(
 
561
            reference_format.get_format_string(), 'ok')
 
562
        # PackRepository wants to do a stat
 
563
        client.add_success_response('stat', '0', '65535')
 
564
        remote_transport = RemoteTransport('bzr://example.com/quack/', medium=False,
 
565
            _client=client)
 
566
        bzrdir = RemoteBzrDir(remote_transport, remote.RemoteBzrDirFormat(),
 
567
            _client=client)
 
568
        repo = bzrdir.open_repository()
 
569
        self.assertEqual(
 
570
            [('call', 'BzrDir.find_repositoryV3', ('quack/',)),
 
571
             ('call', 'BzrDir.find_repositoryV2', ('quack/',)),
 
572
             ('call', 'BzrDir.find_repository', ('quack/',)),
 
573
             ('call_expecting_body', 'get', ('/quack/.bzr/branch-format',)),
 
574
             ('call_expecting_body', 'get', ('/quack/.bzr/repository/format',)),
 
575
             ('call', 'stat', ('/quack/.bzr/repository',)),
 
576
             ],
 
577
            client._calls)
 
578
        self.assertEqual(network_name, repo._format.network_name())
 
579
 
 
580
    def test_backwards_compat_2(self):
 
581
        # fallback to find_repositoryV2
 
582
        reference_format = self.get_repo_format()
 
583
        network_name = reference_format.network_name()
 
584
        client = FakeClient('bzr://example.com/')
 
585
        client.add_unknown_method_response('BzrDir.find_repositoryV3')
 
586
        client.add_success_response('ok', '', 'no', 'no', 'no')
 
587
        # A real repository instance will be created to determine the network
 
588
        # name.
 
589
        client.add_success_response_with_body(
 
590
            "Bazaar-NG meta directory, format 1\n", 'ok')
 
591
        client.add_success_response_with_body(
 
592
            reference_format.get_format_string(), 'ok')
 
593
        # PackRepository wants to do a stat
 
594
        client.add_success_response('stat', '0', '65535')
 
595
        remote_transport = RemoteTransport('bzr://example.com/quack/', medium=False,
 
596
            _client=client)
 
597
        bzrdir = RemoteBzrDir(remote_transport, remote.RemoteBzrDirFormat(),
 
598
            _client=client)
 
599
        repo = bzrdir.open_repository()
 
600
        self.assertEqual(
 
601
            [('call', 'BzrDir.find_repositoryV3', ('quack/',)),
 
602
             ('call', 'BzrDir.find_repositoryV2', ('quack/',)),
 
603
             ('call_expecting_body', 'get', ('/quack/.bzr/branch-format',)),
 
604
             ('call_expecting_body', 'get', ('/quack/.bzr/repository/format',)),
 
605
             ('call', 'stat', ('/quack/.bzr/repository',)),
 
606
             ],
 
607
            client._calls)
 
608
        self.assertEqual(network_name, repo._format.network_name())
 
609
 
 
610
    def test_current_server(self):
 
611
        reference_format = self.get_repo_format()
 
612
        network_name = reference_format.network_name()
 
613
        transport = MemoryTransport()
 
614
        transport.mkdir('quack')
 
615
        transport = transport.clone('quack')
 
616
        client = FakeClient(transport.base)
 
617
        client.add_success_response('ok', '', 'no', 'no', 'no', network_name)
458
618
        bzrdir = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
459
619
            _client=client)
460
620
        repo = bzrdir.open_repository()
461
621
        self.assertEqual(
462
 
            [('call', 'BzrDir.find_repositoryV2', ('quack/',)),
463
 
             ('call', 'BzrDir.find_repository', ('quack/',))],
 
622
            [('call', 'BzrDir.find_repositoryV3', ('quack/',))],
464
623
            client._calls)
 
624
        self.assertEqual(network_name, repo._format.network_name())
465
625
 
466
626
 
467
627
class OldSmartClient(object):
496
656
 
497
657
    def make_remote_branch(self, transport, client):
498
658
        """Make a RemoteBranch using 'client' as its _SmartClient.
499
 
        
 
659
 
500
660
        A RemoteBzrDir and RemoteRepository will also be created to fill out
501
661
        the RemoteBranch, albeit with stub values for some of their attributes.
502
662
        """
546
706
        self.assertEqual((2, revid), result)
547
707
 
548
708
 
549
 
class TestBranch_get_stacked_on_url(tests.TestCaseWithMemoryTransport):
 
709
class TestBranch_get_stacked_on_url(TestRemote):
550
710
    """Test Branch._get_stacked_on_url rpc"""
551
711
 
552
712
    def test_get_stacked_on_invalid_url(self):
586
746
            'BzrDir.open_branch', ('stacked/',),
587
747
            'success', ('ok', ''))
588
748
        client.add_expected_call(
589
 
            'BzrDir.find_repositoryV2', ('stacked/',),
590
 
            'success', ('ok', '', 'no', 'no', 'no'))
 
749
            'BzrDir.find_repositoryV3', ('stacked/',),
 
750
            'success', ('ok', '', 'no', 'no', 'no',
 
751
                stacked_branch.repository._format.network_name()))
591
752
        # called twice, once from constructor and then again by us
592
753
        client.add_expected_call(
593
754
            'Branch.get_stacked_on_url', ('stacked/',),
613
774
        base_branch = self.make_branch('base', format='1.6')
614
775
        stacked_branch = self.make_branch('stacked', format='1.6')
615
776
        stacked_branch.set_stacked_on_url('../base')
 
777
        reference_format = self.get_repo_format()
 
778
        network_name = reference_format.network_name()
616
779
        client = FakeClient(self.get_url())
617
780
        client.add_expected_call(
618
781
            'BzrDir.open_branch', ('stacked/',),
619
782
            'success', ('ok', ''))
620
783
        client.add_expected_call(
621
 
            'BzrDir.find_repositoryV2', ('stacked/',),
622
 
            'success', ('ok', '', 'no', 'no', 'no'))
 
784
            'BzrDir.find_repositoryV3', ('stacked/',),
 
785
            'success', ('ok', '', 'no', 'no', 'no', network_name))
623
786
        # called twice, once from constructor and then again by us
624
787
        client.add_expected_call(
625
788
            'Branch.get_stacked_on_url', ('stacked/',),
781
944
        branch = self.make_remote_branch(transport, client)
782
945
        branch._ensure_real = lambda: None
783
946
        branch.lock_write()
784
 
        self.addCleanup(branch.unlock)
785
947
        # The 'TipChangeRejected' error response triggered by calling
786
948
        # set_revision_history causes a TipChangeRejected exception.
787
949
        err = self.assertRaises(
1036
1198
 
1037
1199
    def test_error_from_old_server(self):
1038
1200
        """bzr 0.15 and earlier servers don't recognise the is_readonly verb.
1039
 
        
 
1201
 
1040
1202
        Clients should treat it as a "no" response, because is_readonly is only
1041
1203
        advisory anyway (a transport could be read-write, but then the
1042
1204
        underlying filesystem could be readonly anyway).
1080
1242
        self.assertEqual('bar', t._get_credentials()[0])
1081
1243
 
1082
1244
 
1083
 
class TestRemoteRepository(tests.TestCase):
 
1245
class TestRemoteRepository(TestRemote):
1084
1246
    """Base for testing RemoteRepository protocol usage.
1085
 
    
1086
 
    These tests contain frozen requests and responses.  We want any changes to 
 
1247
 
 
1248
    These tests contain frozen requests and responses.  We want any changes to
1087
1249
    what is sent or expected to be require a thoughtful update to these tests
1088
1250
    because they might break compatibility with different-versioned servers.
1089
1251
    """
1090
1252
 
1091
1253
    def setup_fake_client_and_repository(self, transport_path):
1092
1254
        """Create the fake client and repository for testing with.
1093
 
        
 
1255
 
1094
1256
        There's no real server here; we just have canned responses sent
1095
1257
        back one by one.
1096
 
        
 
1258
 
1097
1259
        :param transport_path: Path below the root of the MemoryTransport
1098
1260
            where the repository will be created.
1099
1261
        """
1296
1458
 
1297
1459
 
1298
1460
class TestRepositoryGetRevisionGraph(TestRemoteRepository):
1299
 
    
 
1461
 
1300
1462
    def test_null_revision(self):
1301
1463
        # a null revision has the predictable result {}, we should have no wire
1302
1464
        # traffic when calling it with this argument
1366
1528
            self.applyDeprecated, one_four, repo.get_revision_graph, revid)
1367
1529
        self.assertEqual(('AnUnexpectedError',), e.error_tuple)
1368
1530
 
1369
 
        
 
1531
 
1370
1532
class TestRepositoryIsShared(TestRemoteRepository):
1371
1533
 
1372
1534
    def test_is_shared(self):
1423
1585
            client._calls)
1424
1586
 
1425
1587
 
 
1588
class TestRepositorySetMakeWorkingTrees(TestRemoteRepository):
 
1589
 
 
1590
    def test_backwards_compat(self):
 
1591
        self.setup_smart_server_with_call_log()
 
1592
        repo = self.make_repository('.')
 
1593
        self.reset_smart_call_log()
 
1594
        verb = 'Repository.set_make_working_trees'
 
1595
        self.disable_verb(verb)
 
1596
        repo.set_make_working_trees(True)
 
1597
        call_count = len([call for call in self.hpss_calls if
 
1598
            call[0].method == verb])
 
1599
        self.assertEqual(1, call_count)
 
1600
 
 
1601
    def test_current(self):
 
1602
        transport_path = 'quack'
 
1603
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
1604
        client.add_expected_call(
 
1605
            'Repository.set_make_working_trees', ('quack/', 'True'),
 
1606
            'success', ('ok',))
 
1607
        client.add_expected_call(
 
1608
            'Repository.set_make_working_trees', ('quack/', 'False'),
 
1609
            'success', ('ok',))
 
1610
        repo.set_make_working_trees(True)
 
1611
        repo.set_make_working_trees(False)
 
1612
 
 
1613
 
1426
1614
class TestRepositoryUnlock(TestRemoteRepository):
1427
1615
 
1428
1616
    def test_unlock(self):
1532
1720
    def reload_pack_names(self):
1533
1721
        self.calls.append(('pack collection reload_pack_names',))
1534
1722
 
1535
 
    
 
1723
 
1536
1724
class TestRemotePackRepositoryAutoPack(TestRemoteRepository):
1537
1725
    """Tests for RemoteRepository.autopack implementation."""
1538
1726
 
1562
1750
            [('call', 'PackRepository.autopack', ('quack/',)),
1563
1751
             ('pack collection reload_pack_names',)],
1564
1752
            client._calls)
1565
 
        
 
1753
 
1566
1754
    def test_backwards_compatibility(self):
1567
1755
        """If the server does not recognise the PackRepository.autopack verb,
1568
1756
        fallback to the real_repository's implementation.
1618
1806
 
1619
1807
class TestErrorTranslationSuccess(TestErrorTranslationBase):
1620
1808
    """Unit tests for bzrlib.remote._translate_error.
1621
 
    
 
1809
 
1622
1810
    Given an ErrorFromSmartServer (which has an error tuple from a smart
1623
1811
    server) and some context, _translate_error raises more specific errors from
1624
1812
    bzrlib.errors.
1729
1917
 
1730
1918
class TestErrorTranslationRobustness(TestErrorTranslationBase):
1731
1919
    """Unit tests for bzrlib.remote._translate_error's robustness.
1732
 
    
 
1920
 
1733
1921
    TestErrorTranslationSuccess is for cases where _translate_error can
1734
1922
    translate successfully.  This class about how _translate_err behaves when
1735
1923
    it fails to translate: it re-raises the original error.
1763
1951
        self.assertContainsRe(
1764
1952
            self._get_log(keep_log_file=True),
1765
1953
            "Missing key 'branch' in context")
1766
 
        
 
1954
 
1767
1955
    def test_path_missing(self):
1768
1956
        """Some translations (PermissionDenied, ReadError) can determine the
1769
1957
        'path' variable from either the wire or the local context.  If neither
1781
1969
 
1782
1970
class TestStacking(tests.TestCaseWithTransport):
1783
1971
    """Tests for operations on stacked remote repositories.
1784
 
    
 
1972
 
1785
1973
    The underlying format type must support stacking.
1786
1974
    """
1787
1975