~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_remote.py

  • Committer: Ian Clatworthy
  • Date: 2009-09-09 00:49:50 UTC
  • mto: (4634.37.2 prepare-2.0)
  • mto: This revision was merged to the branch mainline in revision 4689.
  • Revision ID: ian.clatworthy@canonical.com-20090909004950-43z4zdicb5u91iet
tweak quick reference naming to make it consistent with other PDFs

Show diffs side-by-side

added added

removed removed

Lines of Context:
27
27
from cStringIO import StringIO
28
28
 
29
29
from bzrlib import (
30
 
    branch,
31
30
    bzrdir,
32
31
    config,
33
32
    errors,
37
36
    pack,
38
37
    remote,
39
38
    repository,
 
39
    smart,
40
40
    tests,
41
41
    treebuilder,
42
42
    urlutils,
54
54
    )
55
55
from bzrlib.repofmt import groupcompress_repo, pack_repo
56
56
from bzrlib.revision import NULL_REVISION
57
 
from bzrlib.smart import medium
 
57
from bzrlib.smart import server, medium
58
58
from bzrlib.smart.client import _SmartClient
59
59
from bzrlib.smart.repository import SmartServerRepositoryGetParentMap
60
60
from bzrlib.tests import (
61
61
    condition_isinstance,
62
62
    split_suite_by_condition,
63
63
    multiply_tests,
64
 
    test_server,
 
64
    KnownFailure,
65
65
    )
66
 
from bzrlib.transport import get_transport
 
66
from bzrlib.transport import get_transport, http
67
67
from bzrlib.transport.memory import MemoryTransport
68
68
from bzrlib.transport.remote import (
69
69
    RemoteTransport,
76
76
        standard_tests, condition_isinstance(BasicRemoteObjectTests))
77
77
    smart_server_version_scenarios = [
78
78
        ('HPSS-v2',
79
 
         {'transport_server': test_server.SmartTCPServer_for_testing_v2_only}),
 
79
            {'transport_server': server.SmartTCPServer_for_testing_v2_only}),
80
80
        ('HPSS-v3',
81
 
         {'transport_server': test_server.SmartTCPServer_for_testing})]
 
81
            {'transport_server': server.SmartTCPServer_for_testing})]
82
82
    return multiply_tests(to_adapt, smart_server_version_scenarios, result)
83
83
 
84
84
 
135
135
        b = BzrDir.open_from_transport(self.transport).open_branch()
136
136
        self.assertStartsWith(str(b), 'RemoteBranch(')
137
137
 
138
 
    def test_remote_bzrdir_repr(self):
139
 
        b = BzrDir.open_from_transport(self.transport)
140
 
        self.assertStartsWith(str(b), 'RemoteBzrDir(')
141
 
 
142
138
    def test_remote_branch_format_supports_stacking(self):
143
139
        t = self.transport
144
140
        self.make_branch('unstackable', format='pack-0.92')
284
280
        self.expecting_body = True
285
281
        return result[1], FakeProtocol(result[2], self)
286
282
 
287
 
    def call_with_body_bytes(self, method, args, body):
288
 
        self._check_call(method, args)
289
 
        self._calls.append(('call_with_body_bytes', method, args, body))
290
 
        result = self._get_next_response()
291
 
        return result[1], FakeProtocol(result[2], self)
292
 
 
293
283
    def call_with_body_bytes_expecting_body(self, method, args, body):
294
284
        self._check_call(method, args)
295
285
        self._calls.append(('call_with_body_bytes_expecting_body', method,
445
435
            'BzrDir.cloning_metadir', ('quack/', 'False'),
446
436
            'error', ('BranchReference',)),
447
437
        client.add_expected_call(
448
 
            'BzrDir.open_branchV3', ('quack/',),
 
438
            'BzrDir.open_branchV2', ('quack/',),
449
439
            'success', ('ref', self.get_url('referenced'))),
450
440
        a_bzrdir = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
451
441
            _client=client)
478
468
        self.assertFinished(client)
479
469
 
480
470
 
481
 
class TestBzrDirOpen(TestRemote):
482
 
 
483
 
    def make_fake_client_and_transport(self, path='quack'):
484
 
        transport = MemoryTransport()
485
 
        transport.mkdir(path)
486
 
        transport = transport.clone(path)
487
 
        client = FakeClient(transport.base)
488
 
        return client, transport
489
 
 
490
 
    def test_absent(self):
491
 
        client, transport = self.make_fake_client_and_transport()
492
 
        client.add_expected_call(
493
 
            'BzrDir.open_2.1', ('quack/',), 'success', ('no',))
494
 
        self.assertRaises(errors.NotBranchError, RemoteBzrDir, transport,
495
 
                remote.RemoteBzrDirFormat(), _client=client, _force_probe=True)
496
 
        self.assertFinished(client)
497
 
 
498
 
    def test_present_without_workingtree(self):
499
 
        client, transport = self.make_fake_client_and_transport()
500
 
        client.add_expected_call(
501
 
            'BzrDir.open_2.1', ('quack/',), 'success', ('yes', 'no'))
502
 
        bd = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
503
 
            _client=client, _force_probe=True)
504
 
        self.assertIsInstance(bd, RemoteBzrDir)
505
 
        self.assertFalse(bd.has_workingtree())
506
 
        self.assertRaises(errors.NoWorkingTree, bd.open_workingtree)
507
 
        self.assertFinished(client)
508
 
 
509
 
    def test_present_with_workingtree(self):
510
 
        client, transport = self.make_fake_client_and_transport()
511
 
        client.add_expected_call(
512
 
            'BzrDir.open_2.1', ('quack/',), 'success', ('yes', 'yes'))
513
 
        bd = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
514
 
            _client=client, _force_probe=True)
515
 
        self.assertIsInstance(bd, RemoteBzrDir)
516
 
        self.assertTrue(bd.has_workingtree())
517
 
        self.assertRaises(errors.NotLocalUrl, bd.open_workingtree)
518
 
        self.assertFinished(client)
519
 
 
520
 
    def test_backwards_compat(self):
521
 
        client, transport = self.make_fake_client_and_transport()
522
 
        client.add_expected_call(
523
 
            'BzrDir.open_2.1', ('quack/',), 'unknown', ('BzrDir.open_2.1',))
524
 
        client.add_expected_call(
525
 
            'BzrDir.open', ('quack/',), 'success', ('yes',))
526
 
        bd = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
527
 
            _client=client, _force_probe=True)
528
 
        self.assertIsInstance(bd, RemoteBzrDir)
529
 
        self.assertFinished(client)
530
 
 
531
 
 
532
471
class TestBzrDirOpenBranch(TestRemote):
533
472
 
534
473
    def test_backwards_compat(self):
536
475
        self.make_branch('.')
537
476
        a_dir = BzrDir.open(self.get_url('.'))
538
477
        self.reset_smart_call_log()
539
 
        verb = 'BzrDir.open_branchV3'
 
478
        verb = 'BzrDir.open_branchV2'
540
479
        self.disable_verb(verb)
541
480
        format = a_dir.open_branch()
542
481
        call_count = len([call for call in self.hpss_calls if
552
491
        transport = transport.clone('quack')
553
492
        client = FakeClient(transport.base)
554
493
        client.add_expected_call(
555
 
            'BzrDir.open_branchV3', ('quack/',),
 
494
            'BzrDir.open_branchV2', ('quack/',),
556
495
            'success', ('branch', branch_network_name))
557
496
        client.add_expected_call(
558
497
            'BzrDir.find_repositoryV3', ('quack/',),
577
516
            _client=client)
578
517
        self.assertRaises(errors.NotBranchError, bzrdir.open_branch)
579
518
        self.assertEqual(
580
 
            [('call', 'BzrDir.open_branchV3', ('quack/',))],
 
519
            [('call', 'BzrDir.open_branchV2', ('quack/',))],
581
520
            client._calls)
582
521
 
583
522
    def test__get_tree_branch(self):
607
546
        network_name = reference_format.network_name()
608
547
        branch_network_name = self.get_branch_format().network_name()
609
548
        client.add_expected_call(
610
 
            'BzrDir.open_branchV3', ('~hello/',),
 
549
            'BzrDir.open_branchV2', ('~hello/',),
611
550
            'success', ('branch', branch_network_name))
612
551
        client.add_expected_call(
613
552
            'BzrDir.find_repositoryV3', ('~hello/',),
744
683
        # fallback all the way to the first version.
745
684
        reference_format = self.get_repo_format()
746
685
        network_name = reference_format.network_name()
747
 
        server_url = 'bzr://example.com/'
748
 
        self.permit_url(server_url)
749
 
        client = FakeClient(server_url)
 
686
        client = FakeClient('bzr://example.com/')
750
687
        client.add_unknown_method_response('BzrDir.find_repositoryV3')
751
688
        client.add_unknown_method_response('BzrDir.find_repositoryV2')
752
689
        client.add_success_response('ok', '', 'no', 'no')
758
695
            reference_format.get_format_string(), 'ok')
759
696
        # PackRepository wants to do a stat
760
697
        client.add_success_response('stat', '0', '65535')
761
 
        remote_transport = RemoteTransport(server_url + 'quack/', medium=False,
 
698
        remote_transport = RemoteTransport('bzr://example.com/quack/', medium=False,
762
699
            _client=client)
763
700
        bzrdir = RemoteBzrDir(remote_transport, remote.RemoteBzrDirFormat(),
764
701
            _client=client)
778
715
        # fallback to find_repositoryV2
779
716
        reference_format = self.get_repo_format()
780
717
        network_name = reference_format.network_name()
781
 
        server_url = 'bzr://example.com/'
782
 
        self.permit_url(server_url)
783
 
        client = FakeClient(server_url)
 
718
        client = FakeClient('bzr://example.com/')
784
719
        client.add_unknown_method_response('BzrDir.find_repositoryV3')
785
720
        client.add_success_response('ok', '', 'no', 'no', 'no')
786
721
        # A real repository instance will be created to determine the network
791
726
            reference_format.get_format_string(), 'ok')
792
727
        # PackRepository wants to do a stat
793
728
        client.add_success_response('stat', '0', '65535')
794
 
        remote_transport = RemoteTransport(server_url + 'quack/', medium=False,
 
729
        remote_transport = RemoteTransport('bzr://example.com/quack/', medium=False,
795
730
            _client=client)
796
731
        bzrdir = RemoteBzrDir(remote_transport, remote.RemoteBzrDirFormat(),
797
732
            _client=client)
916
851
 
917
852
class RemoteBranchTestCase(RemoteBzrDirTestCase):
918
853
 
919
 
    def lock_remote_branch(self, branch):
920
 
        """Trick a RemoteBranch into thinking it is locked."""
921
 
        branch._lock_mode = 'w'
922
 
        branch._lock_count = 2
923
 
        branch._lock_token = 'branch token'
924
 
        branch._repo_lock_token = 'repo token'
925
 
        branch.repository._lock_mode = 'w'
926
 
        branch.repository._lock_count = 2
927
 
        branch.repository._lock_token = 'repo token'
928
 
 
929
854
    def make_remote_branch(self, transport, client):
930
855
        """Make a RemoteBranch using 'client' as its _SmartClient.
931
856
 
1070
995
        self.assertEqual({}, result)
1071
996
 
1072
997
 
1073
 
class TestBranchSetTagsBytes(RemoteBranchTestCase):
1074
 
 
1075
 
    def test_trivial(self):
1076
 
        transport = MemoryTransport()
1077
 
        client = FakeClient(transport.base)
1078
 
        client.add_expected_call(
1079
 
            'Branch.get_stacked_on_url', ('quack/',),
1080
 
            'error', ('NotStacked',))
1081
 
        client.add_expected_call(
1082
 
            'Branch.set_tags_bytes', ('quack/', 'branch token', 'repo token'),
1083
 
            'success', ('',))
1084
 
        transport.mkdir('quack')
1085
 
        transport = transport.clone('quack')
1086
 
        branch = self.make_remote_branch(transport, client)
1087
 
        self.lock_remote_branch(branch)
1088
 
        branch._set_tags_bytes('tags bytes')
1089
 
        self.assertFinished(client)
1090
 
        self.assertEqual('tags bytes', client._calls[-1][-1])
1091
 
 
1092
 
    def test_backwards_compatible(self):
1093
 
        transport = MemoryTransport()
1094
 
        client = FakeClient(transport.base)
1095
 
        client.add_expected_call(
1096
 
            'Branch.get_stacked_on_url', ('quack/',),
1097
 
            'error', ('NotStacked',))
1098
 
        client.add_expected_call(
1099
 
            'Branch.set_tags_bytes', ('quack/', 'branch token', 'repo token'),
1100
 
            'unknown', ('Branch.set_tags_bytes',))
1101
 
        transport.mkdir('quack')
1102
 
        transport = transport.clone('quack')
1103
 
        branch = self.make_remote_branch(transport, client)
1104
 
        self.lock_remote_branch(branch)
1105
 
        class StubRealBranch(object):
1106
 
            def __init__(self):
1107
 
                self.calls = []
1108
 
            def _set_tags_bytes(self, bytes):
1109
 
                self.calls.append(('set_tags_bytes', bytes))
1110
 
        real_branch = StubRealBranch()
1111
 
        branch._real_branch = real_branch
1112
 
        branch._set_tags_bytes('tags bytes')
1113
 
        # Call a second time, to exercise the 'remote version already inferred'
1114
 
        # code path.
1115
 
        branch._set_tags_bytes('tags bytes')
1116
 
        self.assertFinished(client)
1117
 
        self.assertEqual(
1118
 
            [('set_tags_bytes', 'tags bytes')] * 2, real_branch.calls)
1119
 
 
1120
 
 
1121
998
class TestBranchLastRevisionInfo(RemoteBranchTestCase):
1122
999
 
1123
1000
    def test_empty_branch(self):
1195
1072
        client = FakeClient(self.get_url())
1196
1073
        branch_network_name = self.get_branch_format().network_name()
1197
1074
        client.add_expected_call(
1198
 
            'BzrDir.open_branchV3', ('stacked/',),
 
1075
            'BzrDir.open_branchV2', ('stacked/',),
1199
1076
            'success', ('branch', branch_network_name))
1200
1077
        client.add_expected_call(
1201
1078
            'BzrDir.find_repositoryV3', ('stacked/',),
1231
1108
        client = FakeClient(self.get_url())
1232
1109
        branch_network_name = self.get_branch_format().network_name()
1233
1110
        client.add_expected_call(
1234
 
            'BzrDir.open_branchV3', ('stacked/',),
 
1111
            'BzrDir.open_branchV2', ('stacked/',),
1235
1112
            'success', ('branch', branch_network_name))
1236
1113
        client.add_expected_call(
1237
1114
            'BzrDir.find_repositoryV3', ('stacked/',),
1465
1342
            errors.NoSuchRevision, branch.set_last_revision_info, 123, 'revid')
1466
1343
        branch.unlock()
1467
1344
 
 
1345
    def lock_remote_branch(self, branch):
 
1346
        """Trick a RemoteBranch into thinking it is locked."""
 
1347
        branch._lock_mode = 'w'
 
1348
        branch._lock_count = 2
 
1349
        branch._lock_token = 'branch token'
 
1350
        branch._repo_lock_token = 'repo token'
 
1351
        branch.repository._lock_mode = 'w'
 
1352
        branch.repository._lock_count = 2
 
1353
        branch.repository._lock_token = 'repo token'
 
1354
 
1468
1355
    def test_backwards_compatibility(self):
1469
1356
        """If the server does not support the Branch.set_last_revision_info
1470
1357
        verb (which is new in 1.4), then the client falls back to VFS methods.
1786
1673
        return repo, client
1787
1674
 
1788
1675
 
1789
 
def remoted_description(format):
1790
 
    return 'Remote: ' + format.get_format_description()
1791
 
 
1792
 
 
1793
 
class TestBranchFormat(tests.TestCase):
1794
 
 
1795
 
    def test_get_format_description(self):
1796
 
        remote_format = RemoteBranchFormat()
1797
 
        real_format = branch.BranchFormat.get_default_format()
1798
 
        remote_format._network_name = real_format.network_name()
1799
 
        self.assertEqual(remoted_description(real_format),
1800
 
            remote_format.get_format_description())
1801
 
 
1802
 
 
1803
1676
class TestRepositoryFormat(TestRemoteRepository):
1804
1677
 
1805
1678
    def test_fast_delta(self):
1812
1685
        false_format._network_name = false_name
1813
1686
        self.assertEqual(False, false_format.fast_deltas)
1814
1687
 
1815
 
    def test_get_format_description(self):
1816
 
        remote_repo_format = RemoteRepositoryFormat()
1817
 
        real_format = repository.RepositoryFormat.get_default_format()
1818
 
        remote_repo_format._network_name = real_format.network_name()
1819
 
        self.assertEqual(remoted_description(real_format),
1820
 
            remote_repo_format.get_format_description())
1821
 
 
1822
1688
 
1823
1689
class TestRepositoryGatherStats(TestRemoteRepository):
1824
1690
 
2009
1875
        self.assertLength(1, self.hpss_calls)
2010
1876
 
2011
1877
    def disableExtraResults(self):
2012
 
        self.overrideAttr(SmartServerRepositoryGetParentMap,
2013
 
                          'no_extra_results', True)
 
1878
        old_flag = SmartServerRepositoryGetParentMap.no_extra_results
 
1879
        SmartServerRepositoryGetParentMap.no_extra_results = True
 
1880
        def reset_values():
 
1881
            SmartServerRepositoryGetParentMap.no_extra_results = old_flag
 
1882
        self.addCleanup(reset_values)
2014
1883
 
2015
1884
    def test_null_cached_missing_and_stop_key(self):
2016
1885
        self.setup_smart_server_with_call_log()
2075
1944
 
2076
1945
    def test_allows_new_revisions(self):
2077
1946
        """get_parent_map's results can be updated by commit."""
2078
 
        smart_server = test_server.SmartTCPServer_for_testing()
2079
 
        self.start_server(smart_server)
 
1947
        smart_server = server.SmartTCPServer_for_testing()
 
1948
        smart_server.setUp()
 
1949
        self.addCleanup(smart_server.tearDown)
2080
1950
        self.make_branch('branch')
2081
1951
        branch = Branch.open(smart_server.get_url() + '/branch')
2082
1952
        tree = branch.create_checkout('tree', lightweight=True)
2223
2093
            repo.get_rev_id_for_revno, 5, (42, 'rev-foo'))
2224
2094
        self.assertFinished(client)
2225
2095
 
2226
 
    def test_branch_fallback_locking(self):
2227
 
        """RemoteBranch.get_rev_id takes a read lock, and tries to call the
2228
 
        get_rev_id_for_revno verb.  If the verb is unknown the VFS fallback
2229
 
        will be invoked, which will fail if the repo is unlocked.
2230
 
        """
2231
 
        self.setup_smart_server_with_call_log()
2232
 
        tree = self.make_branch_and_memory_tree('.')
2233
 
        tree.lock_write()
2234
 
        rev1 = tree.commit('First')
2235
 
        rev2 = tree.commit('Second')
2236
 
        tree.unlock()
2237
 
        branch = tree.branch
2238
 
        self.assertFalse(branch.is_locked())
2239
 
        self.reset_smart_call_log()
2240
 
        verb = 'Repository.get_rev_id_for_revno'
2241
 
        self.disable_verb(verb)
2242
 
        self.assertEqual(rev1, branch.get_rev_id(1))
2243
 
        self.assertLength(1, [call for call in self.hpss_calls if
2244
 
                              call.call.method == verb])
2245
 
 
2246
2096
 
2247
2097
class TestRepositoryIsShared(TestRemoteRepository):
2248
2098
 
2476
2326
        class FakeRealRepository:
2477
2327
            def _get_sink(self):
2478
2328
                return fake_real_sink
2479
 
            def is_in_write_group(self):
2480
 
                return False
2481
 
            def refresh_data(self):
2482
 
                return True
2483
2329
        repo._real_repository = FakeRealRepository()
2484
2330
        sink = repo._get_sink()
2485
2331
        fmt = repository.RepositoryFormat.get_default_format()
2623
2469
    """RemoteRepository.copy_content_into optimizations"""
2624
2470
 
2625
2471
    def test_copy_content_remote_to_local(self):
2626
 
        self.transport_server = test_server.SmartTCPServer_for_testing
 
2472
        self.transport_server = server.SmartTCPServer_for_testing
2627
2473
        src_repo = self.make_repository('repo1')
2628
2474
        src_repo = repository.Repository.open(self.get_url('repo1'))
2629
2475
        # At the moment the tarball-based copy_content_into can't write back
2777
2623
        expected_error = errors.NotBranchError(path=bzrdir.root_transport.base)
2778
2624
        self.assertEqual(expected_error, translated_error)
2779
2625
 
2780
 
    def test_nobranch_one_arg(self):
2781
 
        bzrdir = self.make_bzrdir('')
2782
 
        translated_error = self.translateTuple(
2783
 
            ('nobranch', 'extra detail'), bzrdir=bzrdir)
2784
 
        expected_error = errors.NotBranchError(
2785
 
            path=bzrdir.root_transport.base,
2786
 
            detail='extra detail')
2787
 
        self.assertEqual(expected_error, translated_error)
2788
 
 
2789
2626
    def test_LockContention(self):
2790
2627
        translated_error = self.translateTuple(('LockContention',))
2791
2628
        expected_error = errors.LockContention('(remote lock)')
2904
2741
        # In addition to re-raising ErrorFromSmartServer, some debug info has
2905
2742
        # been muttered to the log file for developer to look at.
2906
2743
        self.assertContainsRe(
2907
 
            self.get_log(),
 
2744
            self._get_log(keep_log_file=True),
2908
2745
            "Missing key 'branch' in context")
2909
2746
 
2910
2747
    def test_path_missing(self):
2918
2755
        self.assertEqual(server_error, translated_error)
2919
2756
        # In addition to re-raising ErrorFromSmartServer, some debug info has
2920
2757
        # been muttered to the log file for developer to look at.
2921
 
        self.assertContainsRe(self.get_log(), "Missing key 'path' in context")
 
2758
        self.assertContainsRe(
 
2759
            self._get_log(keep_log_file=True), "Missing key 'path' in context")
2922
2760
 
2923
2761
 
2924
2762
class TestStacking(tests.TestCaseWithTransport):
2942
2780
        stacked_branch = self.make_branch('stacked', format='1.9')
2943
2781
        stacked_branch.set_stacked_on_url('../base')
2944
2782
        # start a server looking at this
2945
 
        smart_server = test_server.SmartTCPServer_for_testing()
2946
 
        self.start_server(smart_server)
 
2783
        smart_server = server.SmartTCPServer_for_testing()
 
2784
        smart_server.setUp()
 
2785
        self.addCleanup(smart_server.tearDown)
2947
2786
        remote_bzrdir = BzrDir.open(smart_server.get_url() + '/stacked')
2948
2787
        # can get its branch and repository
2949
2788
        remote_branch = remote_bzrdir.open_branch()
3052
2891
            local_tree.commit('more local changes are better')
3053
2892
            branch = Branch.open(self.get_url('tree3'))
3054
2893
            branch.lock_read()
3055
 
            self.addCleanup(branch.unlock)
3056
2894
            return None, branch
3057
2895
        rev_ord, expected_revs = self.get_ordered_revs('1.9', 'unordered',
3058
2896
            branch_factory=make_stacked_stacked)
3104
2942
        super(TestRemoteBranchEffort, self).setUp()
3105
2943
        # Create a smart server that publishes whatever the backing VFS server
3106
2944
        # does.
3107
 
        self.smart_server = test_server.SmartTCPServer_for_testing()
3108
 
        self.start_server(self.smart_server, self.get_server())
 
2945
        self.smart_server = server.SmartTCPServer_for_testing()
 
2946
        self.smart_server.setUp(self.get_server())
 
2947
        self.addCleanup(self.smart_server.tearDown)
3109
2948
        # Log all HPSS calls into self.hpss_calls.
3110
2949
        _SmartClient.hooks.install_named_hook(
3111
2950
            'call', self.capture_hpss_call, None)