~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_remote.py

  • Committer: Vincent Ladeuil
  • Date: 2010-06-17 07:11:55 UTC
  • mto: (5299.1.1 integration)
  • mto: This revision was merged to the branch mainline in revision 5302.
  • Revision ID: v.ladeuil+lp@free.fr-20100617071155-by34vqnqqlvzuwt1
Fix typo.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006-2011 Canonical Ltd
 
1
# Copyright (C) 2006-2010 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
30
30
    branch,
31
31
    bzrdir,
32
32
    config,
33
 
    controldir,
34
33
    errors,
35
34
    graph,
36
35
    inventory,
37
36
    inventory_delta,
 
37
    pack,
38
38
    remote,
39
39
    repository,
40
40
    tests,
41
 
    transport,
42
41
    treebuilder,
 
42
    urlutils,
43
43
    versionedfile,
44
44
    )
45
45
from bzrlib.branch import Branch
46
 
from bzrlib.bzrdir import (
47
 
    BzrDir,
48
 
    BzrDirFormat,
49
 
    RemoteBzrProber,
50
 
    )
 
46
from bzrlib.bzrdir import BzrDir, BzrDirFormat
51
47
from bzrlib.remote import (
52
48
    RemoteBranch,
53
49
    RemoteBranchFormat,
56
52
    RemoteRepository,
57
53
    RemoteRepositoryFormat,
58
54
    )
59
 
from bzrlib.repofmt import groupcompress_repo, knitpack_repo
 
55
from bzrlib.repofmt import groupcompress_repo, pack_repo
60
56
from bzrlib.revision import NULL_REVISION
61
 
from bzrlib.smart import medium, request
 
57
from bzrlib.smart import medium
62
58
from bzrlib.smart.client import _SmartClient
63
 
from bzrlib.smart.repository import (
64
 
    SmartServerRepositoryGetParentMap,
65
 
    SmartServerRepositoryGetStream_1_19,
66
 
    )
 
59
from bzrlib.smart.repository import SmartServerRepositoryGetParentMap
67
60
from bzrlib.tests import (
 
61
    condition_isinstance,
 
62
    split_suite_by_condition,
 
63
    multiply_tests,
68
64
    test_server,
69
65
    )
70
 
from bzrlib.tests.scenarios import load_tests_apply_scenarios
 
66
from bzrlib.transport import get_transport
71
67
from bzrlib.transport.memory import MemoryTransport
72
68
from bzrlib.transport.remote import (
73
69
    RemoteTransport,
74
70
    RemoteSSHTransport,
75
71
    RemoteTCPTransport,
76
 
    )
77
 
 
78
 
 
79
 
load_tests = load_tests_apply_scenarios
80
 
 
81
 
 
82
 
class BasicRemoteObjectTests(tests.TestCaseWithTransport):
83
 
 
84
 
    scenarios = [
 
72
)
 
73
 
 
74
def load_tests(standard_tests, module, loader):
 
75
    to_adapt, result = split_suite_by_condition(
 
76
        standard_tests, condition_isinstance(BasicRemoteObjectTests))
 
77
    smart_server_version_scenarios = [
85
78
        ('HPSS-v2',
86
 
            {'transport_server': test_server.SmartTCPServer_for_testing_v2_only}),
 
79
         {'transport_server': test_server.SmartTCPServer_for_testing_v2_only}),
87
80
        ('HPSS-v3',
88
 
            {'transport_server': test_server.SmartTCPServer_for_testing})]
89
 
 
 
81
         {'transport_server': test_server.SmartTCPServer_for_testing})]
 
82
    return multiply_tests(to_adapt, smart_server_version_scenarios, result)
 
83
 
 
84
 
 
85
class BasicRemoteObjectTests(tests.TestCaseWithTransport):
90
86
 
91
87
    def setUp(self):
92
88
        super(BasicRemoteObjectTests, self).setUp()
93
89
        self.transport = self.get_transport()
94
90
        # make a branch that can be opened over the smart transport
95
91
        self.local_wt = BzrDir.create_standalone_workingtree('.')
96
 
        self.addCleanup(self.transport.disconnect)
 
92
 
 
93
    def tearDown(self):
 
94
        self.transport.disconnect()
 
95
        tests.TestCaseWithTransport.tearDown(self)
97
96
 
98
97
    def test_create_remote_bzrdir(self):
99
 
        b = remote.RemoteBzrDir(self.transport, RemoteBzrDirFormat())
 
98
        b = remote.RemoteBzrDir(self.transport, remote.RemoteBzrDirFormat())
100
99
        self.assertIsInstance(b, BzrDir)
101
100
 
102
101
    def test_open_remote_branch(self):
103
102
        # open a standalone branch in the working directory
104
 
        b = remote.RemoteBzrDir(self.transport, RemoteBzrDirFormat())
 
103
        b = remote.RemoteBzrDir(self.transport, remote.RemoteBzrDirFormat())
105
104
        branch = b.open_branch()
106
105
        self.assertIsInstance(branch, Branch)
107
106
 
123
122
    def test_find_correct_format(self):
124
123
        """Should open a RemoteBzrDir over a RemoteTransport"""
125
124
        fmt = BzrDirFormat.find_format(self.transport)
126
 
        self.assertTrue(bzrdir.RemoteBzrProber
127
 
                        in controldir.ControlDirFormat._server_probers)
128
 
        self.assertIsInstance(fmt, RemoteBzrDirFormat)
 
125
        self.assertTrue(RemoteBzrDirFormat
 
126
                        in BzrDirFormat._control_server_formats)
 
127
        self.assertIsInstance(fmt, remote.RemoteBzrDirFormat)
129
128
 
130
129
    def test_open_detected_smart_format(self):
131
130
        fmt = BzrDirFormat.find_format(self.transport)
360
359
        a given client_base and transport_base.
361
360
        """
362
361
        client_medium = medium.SmartClientMedium(client_base)
363
 
        t = transport.get_transport(transport_base)
364
 
        result = client_medium.remote_path_from_transport(t)
 
362
        transport = get_transport(transport_base)
 
363
        result = client_medium.remote_path_from_transport(transport)
365
364
        self.assertEqual(expected, result)
366
365
 
367
366
    def test_remote_path_from_transport(self):
378
377
        a given transport_base and relpath of that transport.  (Note that
379
378
        HttpTransportBase is a subclass of SmartClientMedium)
380
379
        """
381
 
        base_transport = transport.get_transport(transport_base)
 
380
        base_transport = get_transport(transport_base)
382
381
        client_medium = base_transport.get_smart_medium()
383
382
        cloned_transport = base_transport.clone(relpath)
384
383
        result = client_medium.remote_path_from_transport(cloned_transport)
451
450
        client.add_expected_call(
452
451
            'BzrDir.open_branchV3', ('quack/',),
453
452
            'success', ('ref', self.get_url('referenced'))),
454
 
        a_bzrdir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
 
453
        a_bzrdir = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
455
454
            _client=client)
456
455
        result = a_bzrdir.cloning_metadir()
457
456
        # We should have got a control dir matching the referenced branch.
470
469
        client.add_expected_call(
471
470
            'BzrDir.cloning_metadir', ('quack/', 'False'),
472
471
            'success', (control_name, '', ('branch', ''))),
473
 
        a_bzrdir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
 
472
        a_bzrdir = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
474
473
            _client=client)
475
474
        result = a_bzrdir.cloning_metadir()
476
475
        # We should have got a reference control dir with default branch and
496
495
        client.add_expected_call(
497
496
            'BzrDir.open_2.1', ('quack/',), 'success', ('no',))
498
497
        self.assertRaises(errors.NotBranchError, RemoteBzrDir, transport,
499
 
                RemoteBzrDirFormat(), _client=client, _force_probe=True)
 
498
                remote.RemoteBzrDirFormat(), _client=client, _force_probe=True)
500
499
        self.assertFinished(client)
501
500
 
502
501
    def test_present_without_workingtree(self):
503
502
        client, transport = self.make_fake_client_and_transport()
504
503
        client.add_expected_call(
505
504
            'BzrDir.open_2.1', ('quack/',), 'success', ('yes', 'no'))
506
 
        bd = RemoteBzrDir(transport, RemoteBzrDirFormat(),
 
505
        bd = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
507
506
            _client=client, _force_probe=True)
508
507
        self.assertIsInstance(bd, RemoteBzrDir)
509
508
        self.assertFalse(bd.has_workingtree())
514
513
        client, transport = self.make_fake_client_and_transport()
515
514
        client.add_expected_call(
516
515
            'BzrDir.open_2.1', ('quack/',), 'success', ('yes', 'yes'))
517
 
        bd = RemoteBzrDir(transport, RemoteBzrDirFormat(),
 
516
        bd = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
518
517
            _client=client, _force_probe=True)
519
518
        self.assertIsInstance(bd, RemoteBzrDir)
520
519
        self.assertTrue(bd.has_workingtree())
527
526
            'BzrDir.open_2.1', ('quack/',), 'unknown', ('BzrDir.open_2.1',))
528
527
        client.add_expected_call(
529
528
            'BzrDir.open', ('quack/',), 'success', ('yes',))
530
 
        bd = RemoteBzrDir(transport, RemoteBzrDirFormat(),
 
529
        bd = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
531
530
            _client=client, _force_probe=True)
532
531
        self.assertIsInstance(bd, RemoteBzrDir)
533
532
        self.assertFinished(client)
549
548
            'BzrDir.open_2.1', ('quack/',), 'unknown', ('BzrDir.open_2.1',))
550
549
        client.add_expected_call(
551
550
            'BzrDir.open', ('quack/',), 'success', ('yes',))
552
 
        bd = RemoteBzrDir(transport, RemoteBzrDirFormat(),
 
551
        bd = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
553
552
            _client=client, _force_probe=True)
554
553
        self.assertIsInstance(bd, RemoteBzrDir)
555
554
        self.assertFinished(client)
586
585
        client.add_expected_call(
587
586
            'Branch.get_stacked_on_url', ('quack/',),
588
587
            'error', ('NotStacked',))
589
 
        bzrdir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
 
588
        bzrdir = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
590
589
            _client=client)
591
590
        result = bzrdir.open_branch()
592
591
        self.assertIsInstance(result, RemoteBranch)
599
598
        transport = transport.clone('quack')
600
599
        client = FakeClient(transport.base)
601
600
        client.add_error_response('nobranch')
602
 
        bzrdir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
 
601
        bzrdir = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
603
602
            _client=client)
604
603
        self.assertRaises(errors.NotBranchError, bzrdir.open_branch)
605
604
        self.assertEqual(
616
615
        transport = MemoryTransport()
617
616
        # no requests on the network - catches other api calls being made.
618
617
        client = FakeClient(transport.base)
619
 
        bzrdir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
 
618
        bzrdir = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
620
619
            _client=client)
621
620
        # patch the open_branch call to record that it was called.
622
621
        bzrdir.open_branch = open_branch
641
640
        client.add_expected_call(
642
641
            'Branch.get_stacked_on_url', ('~hello/',),
643
642
            'error', ('NotStacked',))
644
 
        bzrdir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
 
643
        bzrdir = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
645
644
            _client=client)
646
645
        result = bzrdir.open_branch()
647
646
        self.assertFinished(client)
664
663
        client.add_success_response(
665
664
            'ok', '', rich_response, subtree_response, external_lookup,
666
665
            network_name)
667
 
        bzrdir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
 
666
        bzrdir = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
668
667
            _client=client)
669
668
        result = bzrdir.open_repository()
670
669
        self.assertEqual(
687
686
        old.
688
687
        """
689
688
        self.assertRaises(errors.NotBranchError,
690
 
            RemoteBzrProber.probe_transport, OldServerTransport())
 
689
            RemoteBzrDirFormat.probe_transport, OldServerTransport())
691
690
 
692
691
 
693
692
class TestBzrDirCreateBranch(TestRemote):
716
715
            'BzrDir.create_branch', ('quack/', network_name),
717
716
            'success', ('ok', network_name, '', 'no', 'no', 'yes',
718
717
            reference_repo_name))
719
 
        a_bzrdir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
 
718
        a_bzrdir = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
720
719
            _client=client)
721
720
        branch = a_bzrdir.create_branch()
722
721
        # We should have got a remote branch
725
724
        format = branch._format
726
725
        self.assertEqual(network_name, format.network_name())
727
726
 
728
 
    def test_already_open_repo_and_reused_medium(self):
729
 
        """Bug 726584: create_branch(..., repository=repo) should work
730
 
        regardless of what the smart medium's base URL is.
731
 
        """
732
 
        self.transport_server = test_server.SmartTCPServer_for_testing
733
 
        transport = self.get_transport('.')
734
 
        repo = self.make_repository('quack')
735
 
        # Client's medium rooted a transport root (not at the bzrdir)
736
 
        client = FakeClient(transport.base)
737
 
        transport = transport.clone('quack')
738
 
        reference_bzrdir_format = bzrdir.format_registry.get('default')()
739
 
        reference_format = reference_bzrdir_format.get_branch_format()
740
 
        network_name = reference_format.network_name()
741
 
        reference_repo_fmt = reference_bzrdir_format.repository_format
742
 
        reference_repo_name = reference_repo_fmt.network_name()
743
 
        client.add_expected_call(
744
 
            'BzrDir.create_branch', ('extra/quack/', network_name),
745
 
            'success', ('ok', network_name, '', 'no', 'no', 'yes',
746
 
            reference_repo_name))
747
 
        a_bzrdir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
748
 
            _client=client)
749
 
        branch = a_bzrdir.create_branch(repository=repo)
750
 
        # We should have got a remote branch
751
 
        self.assertIsInstance(branch, remote.RemoteBranch)
752
 
        # its format should have the settings from the response
753
 
        format = branch._format
754
 
        self.assertEqual(network_name, format.network_name())
755
 
 
756
727
 
757
728
class TestBzrDirCreateRepository(TestRemote):
758
729
 
779
750
                'Bazaar repository format 2a (needs bzr 1.16 or later)\n',
780
751
                'False'),
781
752
            'success', ('ok', 'yes', 'yes', 'yes', network_name))
782
 
        a_bzrdir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
 
753
        a_bzrdir = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
783
754
            _client=client)
784
755
        repo = a_bzrdir.create_repository()
785
756
        # We should have got a remote repository
814
785
        client.add_success_response('stat', '0', '65535')
815
786
        remote_transport = RemoteTransport(server_url + 'quack/', medium=False,
816
787
            _client=client)
817
 
        bzrdir = RemoteBzrDir(remote_transport, RemoteBzrDirFormat(),
 
788
        bzrdir = RemoteBzrDir(remote_transport, remote.RemoteBzrDirFormat(),
818
789
            _client=client)
819
790
        repo = bzrdir.open_repository()
820
791
        self.assertEqual(
847
818
        client.add_success_response('stat', '0', '65535')
848
819
        remote_transport = RemoteTransport(server_url + 'quack/', medium=False,
849
820
            _client=client)
850
 
        bzrdir = RemoteBzrDir(remote_transport, RemoteBzrDirFormat(),
 
821
        bzrdir = RemoteBzrDir(remote_transport, remote.RemoteBzrDirFormat(),
851
822
            _client=client)
852
823
        repo = bzrdir.open_repository()
853
824
        self.assertEqual(
868
839
        transport = transport.clone('quack')
869
840
        client = FakeClient(transport.base)
870
841
        client.add_success_response('ok', '', 'no', 'no', 'no', network_name)
871
 
        bzrdir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
 
842
        bzrdir = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
872
843
            _client=client)
873
844
        repo = bzrdir.open_repository()
874
845
        self.assertEqual(
881
852
 
882
853
    def test_success(self):
883
854
        """Simple test for typical successful call."""
884
 
        fmt = RemoteBzrDirFormat()
 
855
        fmt = bzrdir.RemoteBzrDirFormat()
885
856
        default_format_name = BzrDirFormat.get_default_format().network_name()
886
857
        transport = self.get_transport()
887
858
        client = FakeClient(transport.base)
903
874
        """Error responses are translated, e.g. 'PermissionDenied' raises the
904
875
        corresponding error from the client.
905
876
        """
906
 
        fmt = RemoteBzrDirFormat()
 
877
        fmt = bzrdir.RemoteBzrDirFormat()
907
878
        default_format_name = BzrDirFormat.get_default_format().network_name()
908
879
        transport = self.get_transport()
909
880
        client = FakeClient(transport.base)
927
898
        """Integration test for error translation."""
928
899
        transport = self.make_smart_server('foo')
929
900
        transport = transport.clone('no-such-path')
930
 
        fmt = RemoteBzrDirFormat()
 
901
        fmt = bzrdir.RemoteBzrDirFormat()
931
902
        err = self.assertRaises(errors.NoSuchFile,
932
903
            fmt.initialize_on_transport_ex, transport, create_prefix=False)
933
904
 
964
935
 
965
936
    def make_remote_bzrdir(self, transport, client):
966
937
        """Make a RemotebzrDir using 'client' as the _client."""
967
 
        return RemoteBzrDir(transport, RemoteBzrDirFormat(),
 
938
        return RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
968
939
            _client=client)
969
940
 
970
941
 
1172
1143
            [('set_tags_bytes', 'tags bytes')] * 2, real_branch.calls)
1173
1144
 
1174
1145
 
1175
 
class TestBranchHeadsToFetch(RemoteBranchTestCase):
1176
 
 
1177
 
    def test_uses_last_revision_info_and_tags_by_default(self):
1178
 
        transport = MemoryTransport()
1179
 
        client = FakeClient(transport.base)
1180
 
        client.add_expected_call(
1181
 
            'Branch.get_stacked_on_url', ('quack/',),
1182
 
            'error', ('NotStacked',))
1183
 
        client.add_expected_call(
1184
 
            'Branch.last_revision_info', ('quack/',),
1185
 
            'success', ('ok', '1', 'rev-tip'))
1186
 
        # XXX: this will break if the default format's serialization of tags
1187
 
        # changes, or if the RPC for fetching tags changes from get_tags_bytes.
1188
 
        client.add_expected_call(
1189
 
            'Branch.get_tags_bytes', ('quack/',),
1190
 
            'success', ('d5:tag-17:rev-foo5:tag-27:rev-bare',))
1191
 
        transport.mkdir('quack')
1192
 
        transport = transport.clone('quack')
1193
 
        branch = self.make_remote_branch(transport, client)
1194
 
        result = branch.heads_to_fetch()
1195
 
        self.assertFinished(client)
1196
 
        self.assertEqual(
1197
 
            (set(['rev-tip']), set(['rev-foo', 'rev-bar'])), result)
1198
 
 
1199
 
    def test_uses_rpc_for_formats_with_non_default_heads_to_fetch(self):
1200
 
        transport = MemoryTransport()
1201
 
        client = FakeClient(transport.base)
1202
 
        client.add_expected_call(
1203
 
            'Branch.get_stacked_on_url', ('quack/',),
1204
 
            'error', ('NotStacked',))
1205
 
        client.add_expected_call(
1206
 
            'Branch.heads_to_fetch', ('quack/',),
1207
 
            'success', (['tip'], ['tagged-1', 'tagged-2']))
1208
 
        transport.mkdir('quack')
1209
 
        transport = transport.clone('quack')
1210
 
        branch = self.make_remote_branch(transport, client)
1211
 
        branch._format._use_default_local_heads_to_fetch = lambda: False
1212
 
        result = branch.heads_to_fetch()
1213
 
        self.assertFinished(client)
1214
 
        self.assertEqual((set(['tip']), set(['tagged-1', 'tagged-2'])), result)
1215
 
 
1216
 
    def test_backwards_compatible(self):
1217
 
        self.setup_smart_server_with_call_log()
1218
 
        # Make a branch with a single revision.
1219
 
        builder = self.make_branch_builder('foo')
1220
 
        builder.start_series()
1221
 
        builder.build_snapshot('tip', None, [
1222
 
            ('add', ('', 'root-id', 'directory', ''))])
1223
 
        builder.finish_series()
1224
 
        branch = builder.get_branch()
1225
 
        # Add two tags to that branch
1226
 
        branch.tags.set_tag('tag-1', 'rev-1')
1227
 
        branch.tags.set_tag('tag-2', 'rev-2')
1228
 
        self.addCleanup(branch.lock_read().unlock)
1229
 
        # Disable the heads_to_fetch verb
1230
 
        verb = 'Branch.heads_to_fetch'
1231
 
        self.disable_verb(verb)
1232
 
        self.reset_smart_call_log()
1233
 
        result = branch.heads_to_fetch()
1234
 
        self.assertEqual((set(['tip']), set(['rev-1', 'rev-2'])), result)
1235
 
        self.assertEqual(
1236
 
            ['Branch.last_revision_info', 'Branch.get_tags_bytes'],
1237
 
            [call.call.method for call in self.hpss_calls])
1238
 
 
1239
 
 
1240
1146
class TestBranchLastRevisionInfo(RemoteBranchTestCase):
1241
1147
 
1242
1148
    def test_empty_branch(self):
1297
1203
        client.add_expected_call(
1298
1204
            'Branch.get_stacked_on_url', ('stacked/',),
1299
1205
            'success', ('ok', vfs_url))
1300
 
        bzrdir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
 
1206
        bzrdir = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
1301
1207
            _client=client)
1302
1208
        repo_fmt = remote.RemoteRepositoryFormat()
1303
1209
        repo_fmt._custom_format = stacked_branch.repository._format
1330
1236
        # this will also do vfs access, but that goes direct to the transport
1331
1237
        # and isn't seen by the FakeClient.
1332
1238
        bzrdir = RemoteBzrDir(self.get_transport('stacked'),
1333
 
            RemoteBzrDirFormat(), _client=client)
 
1239
            remote.RemoteBzrDirFormat(), _client=client)
1334
1240
        branch = bzrdir.open_branch()
1335
1241
        result = branch.get_stacked_on_url()
1336
1242
        self.assertEqual('../base', result)
1363
1269
            'Branch.get_stacked_on_url', ('stacked/',),
1364
1270
            'success', ('ok', '../base'))
1365
1271
        bzrdir = RemoteBzrDir(self.get_transport('stacked'),
1366
 
            RemoteBzrDirFormat(), _client=client)
 
1272
            remote.RemoteBzrDirFormat(), _client=client)
1367
1273
        branch = bzrdir.open_branch()
1368
1274
        result = branch.get_stacked_on_url()
1369
1275
        self.assertEqual('../base', result)
1377
1283
class TestBranchSetLastRevision(RemoteBranchTestCase):
1378
1284
 
1379
1285
    def test_set_empty(self):
1380
 
        # _set_last_revision_info('null:') is translated to calling
 
1286
        # set_revision_history([]) is translated to calling
1381
1287
        # Branch.set_last_revision(path, '') on the wire.
1382
1288
        transport = MemoryTransport()
1383
1289
        transport.mkdir('branch')
1405
1311
        # unnecessarily invokes _ensure_real upon a call to lock_write.
1406
1312
        branch._ensure_real = lambda: None
1407
1313
        branch.lock_write()
1408
 
        result = branch._set_last_revision(NULL_REVISION)
 
1314
        result = branch.set_revision_history([])
1409
1315
        branch.unlock()
1410
1316
        self.assertEqual(None, result)
1411
1317
        self.assertFinished(client)
1412
1318
 
1413
1319
    def test_set_nonempty(self):
1414
 
        # set_last_revision_info(N, rev-idN) is translated to calling
 
1320
        # set_revision_history([rev-id1, ..., rev-idN]) is translated to calling
1415
1321
        # Branch.set_last_revision(path, rev-idN) on the wire.
1416
1322
        transport = MemoryTransport()
1417
1323
        transport.mkdir('branch')
1443
1349
        branch._ensure_real = lambda: None
1444
1350
        # Lock the branch, reset the record of remote calls.
1445
1351
        branch.lock_write()
1446
 
        result = branch._set_last_revision('rev-id2')
 
1352
        result = branch.set_revision_history(['rev-id1', 'rev-id2'])
1447
1353
        branch.unlock()
1448
1354
        self.assertEqual(None, result)
1449
1355
        self.assertFinished(client)
1479
1385
        branch = self.make_remote_branch(transport, client)
1480
1386
        branch.lock_write()
1481
1387
        self.assertRaises(
1482
 
            errors.NoSuchRevision, branch._set_last_revision, 'rev-id')
 
1388
            errors.NoSuchRevision, branch.set_revision_history, ['rev-id'])
1483
1389
        branch.unlock()
1484
1390
        self.assertFinished(client)
1485
1391
 
1516
1422
        branch._ensure_real = lambda: None
1517
1423
        branch.lock_write()
1518
1424
        # The 'TipChangeRejected' error response triggered by calling
1519
 
        # set_last_revision_info causes a TipChangeRejected exception.
 
1425
        # set_revision_history causes a TipChangeRejected exception.
1520
1426
        err = self.assertRaises(
1521
 
            errors.TipChangeRejected,
1522
 
            branch._set_last_revision, 'rev-id')
 
1427
            errors.TipChangeRejected, branch.set_revision_history, ['rev-id'])
1523
1428
        # The UTF-8 message from the response has been decoded into a unicode
1524
1429
        # object.
1525
1430
        self.assertIsInstance(err.msg, unicode)
1940
1845
        client = FakeClient(transport.base)
1941
1846
        transport = transport.clone(transport_path)
1942
1847
        # we do not want bzrdir to make any remote calls
1943
 
        bzrdir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
 
1848
        bzrdir = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
1944
1849
            _client=False)
1945
1850
        repo = RemoteRepository(bzrdir, None, _client=client)
1946
1851
        return repo, client
1954
1859
 
1955
1860
    def test_get_format_description(self):
1956
1861
        remote_format = RemoteBranchFormat()
1957
 
        real_format = branch.format_registry.get_default()
 
1862
        real_format = branch.BranchFormat.get_default_format()
1958
1863
        remote_format._network_name = real_format.network_name()
1959
1864
        self.assertEqual(remoted_description(real_format),
1960
1865
            remote_format.get_format_description())
1963
1868
class TestRepositoryFormat(TestRemoteRepository):
1964
1869
 
1965
1870
    def test_fast_delta(self):
1966
 
        true_name = groupcompress_repo.RepositoryFormat2a().network_name()
 
1871
        true_name = groupcompress_repo.RepositoryFormatCHK1().network_name()
1967
1872
        true_format = RemoteRepositoryFormat()
1968
1873
        true_format._network_name = true_name
1969
1874
        self.assertEqual(True, true_format.fast_deltas)
1970
 
        false_name = knitpack_repo.RepositoryFormatKnitPack1().network_name()
 
1875
        false_name = pack_repo.RepositoryFormatKnitPack1().network_name()
1971
1876
        false_format = RemoteRepositoryFormat()
1972
1877
        false_format._network_name = false_name
1973
1878
        self.assertEqual(False, false_format.fast_deltas)
1974
1879
 
1975
1880
    def test_get_format_description(self):
1976
1881
        remote_repo_format = RemoteRepositoryFormat()
1977
 
        real_format = repository.format_registry.get_default()
 
1882
        real_format = repository.RepositoryFormat.get_default_format()
1978
1883
        remote_repo_format._network_name = real_format.network_name()
1979
1884
        self.assertEqual(remoted_description(real_format),
1980
1885
            remote_repo_format.get_format_description())
2538
2443
        the client is finished.
2539
2444
        """
2540
2445
        sink = repo._get_sink()
2541
 
        fmt = repository.format_registry.get_default()
 
2446
        fmt = repository.RepositoryFormat.get_default_format()
2542
2447
        resume_tokens, missing_keys = sink.insert_stream([], fmt, [])
2543
2448
        self.assertEqual([], resume_tokens)
2544
2449
        self.assertEqual(set(), missing_keys)
2644
2549
                return True
2645
2550
        repo._real_repository = FakeRealRepository()
2646
2551
        sink = repo._get_sink()
2647
 
        fmt = repository.format_registry.get_default()
 
2552
        fmt = repository.RepositoryFormat.get_default_format()
2648
2553
        stream = self.make_stream_with_inv_deltas(fmt)
2649
2554
        resume_tokens, missing_keys = sink.insert_stream(stream, fmt, [])
2650
2555
        # Every record from the first inventory delta should have been sent to
2870
2775
             ('pack collection autopack',)],
2871
2776
            client._calls)
2872
2777
 
2873
 
    def test_oom_error_reporting(self):
2874
 
        """An out-of-memory condition on the server is reported clearly"""
2875
 
        transport_path = 'quack'
2876
 
        repo, client = self.setup_fake_client_and_repository(transport_path)
2877
 
        client.add_expected_call(
2878
 
            'PackRepository.autopack', ('quack/',),
2879
 
            'error', ('MemoryError',))
2880
 
        err = self.assertRaises(errors.BzrError, repo.autopack)
2881
 
        self.assertContainsRe(str(err), "^remote server out of mem")
2882
 
 
2883
2778
 
2884
2779
class TestErrorTranslationBase(tests.TestCaseWithMemoryTransport):
2885
2780
    """Base class for unit tests for bzrlib.remote._translate_error."""
2958
2853
            detail='extra detail')
2959
2854
        self.assertEqual(expected_error, translated_error)
2960
2855
 
2961
 
    def test_norepository(self):
2962
 
        bzrdir = self.make_bzrdir('')
2963
 
        translated_error = self.translateTuple(('norepository',),
2964
 
            bzrdir=bzrdir)
2965
 
        expected_error = errors.NoRepositoryPresent(bzrdir)
2966
 
        self.assertEqual(expected_error, translated_error)
2967
 
 
2968
2856
    def test_LockContention(self):
2969
2857
        translated_error = self.translateTuple(('LockContention',))
2970
2858
        expected_error = errors.LockContention('(remote lock)')
2998
2886
        expected_error = errors.DivergedBranches(branch, other_branch)
2999
2887
        self.assertEqual(expected_error, translated_error)
3000
2888
 
3001
 
    def test_NotStacked(self):
3002
 
        branch = self.make_branch('')
3003
 
        translated_error = self.translateTuple(('NotStacked',), branch=branch)
3004
 
        expected_error = errors.NotStacked(branch)
3005
 
        self.assertEqual(expected_error, translated_error)
3006
 
 
3007
2889
    def test_ReadError_no_args(self):
3008
2890
        path = 'a path'
3009
2891
        translated_error = self.translateTuple(('ReadError',), path=path)
3025
2907
 
3026
2908
    def test_PermissionDenied_no_args(self):
3027
2909
        path = 'a path'
3028
 
        translated_error = self.translateTuple(('PermissionDenied',),
3029
 
            path=path)
 
2910
        translated_error = self.translateTuple(('PermissionDenied',), path=path)
3030
2911
        expected_error = errors.PermissionDenied(path)
3031
2912
        self.assertEqual(expected_error, translated_error)
3032
2913
 
3055
2936
        expected_error = errors.PermissionDenied(path, extra)
3056
2937
        self.assertEqual(expected_error, translated_error)
3057
2938
 
3058
 
    # GZ 2011-03-02: TODO test for PermissionDenied with non-ascii 'extra'
3059
 
 
3060
 
    def test_NoSuchFile_context_path(self):
3061
 
        local_path = "local path"
3062
 
        translated_error = self.translateTuple(('ReadError', "remote path"),
3063
 
            path=local_path)
3064
 
        expected_error = errors.ReadError(local_path)
3065
 
        self.assertEqual(expected_error, translated_error)
3066
 
 
3067
 
    def test_NoSuchFile_without_context(self):
3068
 
        remote_path = "remote path"
3069
 
        translated_error = self.translateTuple(('ReadError', remote_path))
3070
 
        expected_error = errors.ReadError(remote_path)
3071
 
        self.assertEqual(expected_error, translated_error)
3072
 
 
3073
 
    def test_ReadOnlyError(self):
3074
 
        translated_error = self.translateTuple(('ReadOnlyError',))
3075
 
        expected_error = errors.TransportNotPossible("readonly transport")
3076
 
        self.assertEqual(expected_error, translated_error)
3077
 
 
3078
 
    def test_MemoryError(self):
3079
 
        translated_error = self.translateTuple(('MemoryError',))
3080
 
        self.assertStartsWith(str(translated_error),
3081
 
            "remote server out of memory")
3082
 
 
3083
 
    def test_generic_IndexError_no_classname(self):
3084
 
        err = errors.ErrorFromSmartServer(('error', "list index out of range"))
3085
 
        translated_error = self.translateErrorFromSmartServer(err)
3086
 
        expected_error = errors.UnknownErrorFromSmartServer(err)
3087
 
        self.assertEqual(expected_error, translated_error)
3088
 
 
3089
 
    # GZ 2011-03-02: TODO test generic non-ascii error string
3090
 
 
3091
 
    def test_generic_KeyError(self):
3092
 
        err = errors.ErrorFromSmartServer(('error', 'KeyError', "1"))
3093
 
        translated_error = self.translateErrorFromSmartServer(err)
3094
 
        expected_error = errors.UnknownErrorFromSmartServer(err)
3095
 
        self.assertEqual(expected_error, translated_error)
3096
 
 
3097
2939
 
3098
2940
class TestErrorTranslationRobustness(TestErrorTranslationBase):
3099
2941
    """Unit tests for bzrlib.remote._translate_error's robustness.
3341
3183
 
3342
3184
    def test_copy_content_into_avoids_revision_history(self):
3343
3185
        local = self.make_branch('local')
3344
 
        builder = self.make_branch_builder('remote')
3345
 
        builder.build_commit(message="Commit.")
 
3186
        remote_backing_tree = self.make_branch_and_tree('remote')
 
3187
        remote_backing_tree.commit("Commit.")
3346
3188
        remote_branch_url = self.smart_server.get_url() + 'remote'
3347
3189
        remote_branch = bzrdir.BzrDir.open(remote_branch_url).open_branch()
3348
3190
        local.repository.fetch(remote_branch.repository)
3349
3191
        self.hpss_calls = []
3350
3192
        remote_branch.copy_content_into(local)
3351
3193
        self.assertFalse('Branch.revision_history' in self.hpss_calls)
3352
 
 
3353
 
    def test_fetch_everything_needs_just_one_call(self):
3354
 
        local = self.make_branch('local')
3355
 
        builder = self.make_branch_builder('remote')
3356
 
        builder.build_commit(message="Commit.")
3357
 
        remote_branch_url = self.smart_server.get_url() + 'remote'
3358
 
        remote_branch = bzrdir.BzrDir.open(remote_branch_url).open_branch()
3359
 
        self.hpss_calls = []
3360
 
        local.repository.fetch(remote_branch.repository,
3361
 
                fetch_spec=graph.EverythingResult(remote_branch.repository))
3362
 
        self.assertEqual(['Repository.get_stream_1.19'], self.hpss_calls)
3363
 
 
3364
 
    def override_verb(self, verb_name, verb):
3365
 
        request_handlers = request.request_handlers
3366
 
        orig_verb = request_handlers.get(verb_name)
3367
 
        request_handlers.register(verb_name, verb, override_existing=True)
3368
 
        self.addCleanup(request_handlers.register, verb_name, orig_verb,
3369
 
                override_existing=True)
3370
 
 
3371
 
    def test_fetch_everything_backwards_compat(self):
3372
 
        """Can fetch with EverythingResult even with pre 2.4 servers.
3373
 
        
3374
 
        Pre-2.4 do not support 'everything' searches with the
3375
 
        Repository.get_stream_1.19 verb.
3376
 
        """
3377
 
        verb_log = []
3378
 
        class OldGetStreamVerb(SmartServerRepositoryGetStream_1_19):
3379
 
            """A version of the Repository.get_stream_1.19 verb patched to
3380
 
            reject 'everything' searches the way 2.3 and earlier do.
3381
 
            """
3382
 
            def recreate_search(self, repository, search_bytes, discard_excess=False):
3383
 
                verb_log.append(search_bytes.split('\n', 1)[0])
3384
 
                if search_bytes == 'everything':
3385
 
                    return (None, request.FailedSmartServerResponse(('BadSearch',)))
3386
 
                return super(OldGetStreamVerb,
3387
 
                        self).recreate_search(repository, search_bytes,
3388
 
                            discard_excess=discard_excess)
3389
 
        self.override_verb('Repository.get_stream_1.19', OldGetStreamVerb)
3390
 
        local = self.make_branch('local')
3391
 
        builder = self.make_branch_builder('remote')
3392
 
        builder.build_commit(message="Commit.")
3393
 
        remote_branch_url = self.smart_server.get_url() + 'remote'
3394
 
        remote_branch = bzrdir.BzrDir.open(remote_branch_url).open_branch()
3395
 
        self.hpss_calls = []
3396
 
        local.repository.fetch(remote_branch.repository,
3397
 
                fetch_spec=graph.EverythingResult(remote_branch.repository))
3398
 
        # make sure the overridden verb was used
3399
 
        self.assertLength(1, verb_log)
3400
 
        # more than one HPSS call is needed, but because it's a VFS callback
3401
 
        # its hard to predict exactly how many.
3402
 
        self.assertTrue(len(self.hpss_calls) > 1)
3403