~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_remote.py

  • Committer: Andrew Bennetts
  • Date: 2011-03-24 00:13:10 UTC
  • mto: This revision was merged to the branch mainline in revision 5739.
  • Revision ID: andrew.bennetts@canonical.com-20110324001310-5w56qjom53j091r3
Minor English tweaks.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006-2010 Canonical Ltd
 
1
# Copyright (C) 2006-2011 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,
33
34
    errors,
34
35
    graph,
35
36
    inventory,
36
37
    inventory_delta,
37
 
    pack,
38
38
    remote,
39
39
    repository,
40
40
    tests,
41
41
    transport,
42
42
    treebuilder,
43
 
    urlutils,
44
43
    versionedfile,
45
44
    )
46
45
from bzrlib.branch import Branch
47
 
from bzrlib.bzrdir import BzrDir, BzrDirFormat
 
46
from bzrlib.bzrdir import (
 
47
    BzrDir,
 
48
    BzrDirFormat,
 
49
    RemoteBzrProber,
 
50
    )
48
51
from bzrlib.remote import (
49
52
    RemoteBranch,
50
53
    RemoteBranchFormat,
55
58
    )
56
59
from bzrlib.repofmt import groupcompress_repo, pack_repo
57
60
from bzrlib.revision import NULL_REVISION
58
 
from bzrlib.smart import medium
 
61
from bzrlib.smart import medium, request
59
62
from bzrlib.smart.client import _SmartClient
60
 
from bzrlib.smart.repository import SmartServerRepositoryGetParentMap
 
63
from bzrlib.smart.repository import (
 
64
    SmartServerRepositoryGetParentMap,
 
65
    SmartServerRepositoryGetStream_1_19,
 
66
    )
61
67
from bzrlib.tests import (
62
 
    condition_isinstance,
63
 
    split_suite_by_condition,
64
 
    multiply_tests,
65
68
    test_server,
66
69
    )
 
70
from bzrlib.tests.scenarios import load_tests_apply_scenarios
67
71
from bzrlib.transport.memory import MemoryTransport
68
72
from bzrlib.transport.remote import (
69
73
    RemoteTransport,
70
74
    RemoteSSHTransport,
71
75
    RemoteTCPTransport,
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 = [
 
76
    )
 
77
 
 
78
 
 
79
load_tests = load_tests_apply_scenarios
 
80
 
 
81
 
 
82
class BasicRemoteObjectTests(tests.TestCaseWithTransport):
 
83
 
 
84
    scenarios = [
78
85
        ('HPSS-v2',
79
 
         {'transport_server': test_server.SmartTCPServer_for_testing_v2_only}),
 
86
            {'transport_server': test_server.SmartTCPServer_for_testing_v2_only}),
80
87
        ('HPSS-v3',
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):
 
88
            {'transport_server': test_server.SmartTCPServer_for_testing})]
 
89
 
86
90
 
87
91
    def setUp(self):
88
92
        super(BasicRemoteObjectTests, self).setUp()
92
96
        self.addCleanup(self.transport.disconnect)
93
97
 
94
98
    def test_create_remote_bzrdir(self):
95
 
        b = remote.RemoteBzrDir(self.transport, remote.RemoteBzrDirFormat())
 
99
        b = remote.RemoteBzrDir(self.transport, RemoteBzrDirFormat())
96
100
        self.assertIsInstance(b, BzrDir)
97
101
 
98
102
    def test_open_remote_branch(self):
99
103
        # open a standalone branch in the working directory
100
 
        b = remote.RemoteBzrDir(self.transport, remote.RemoteBzrDirFormat())
 
104
        b = remote.RemoteBzrDir(self.transport, RemoteBzrDirFormat())
101
105
        branch = b.open_branch()
102
106
        self.assertIsInstance(branch, Branch)
103
107
 
119
123
    def test_find_correct_format(self):
120
124
        """Should open a RemoteBzrDir over a RemoteTransport"""
121
125
        fmt = BzrDirFormat.find_format(self.transport)
122
 
        self.assertTrue(RemoteBzrDirFormat
123
 
                        in BzrDirFormat._control_server_formats)
124
 
        self.assertIsInstance(fmt, remote.RemoteBzrDirFormat)
 
126
        self.assertTrue(bzrdir.RemoteBzrProber
 
127
                        in controldir.ControlDirFormat._server_probers)
 
128
        self.assertIsInstance(fmt, RemoteBzrDirFormat)
125
129
 
126
130
    def test_open_detected_smart_format(self):
127
131
        fmt = BzrDirFormat.find_format(self.transport)
447
451
        client.add_expected_call(
448
452
            'BzrDir.open_branchV3', ('quack/',),
449
453
            'success', ('ref', self.get_url('referenced'))),
450
 
        a_bzrdir = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
 
454
        a_bzrdir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
451
455
            _client=client)
452
456
        result = a_bzrdir.cloning_metadir()
453
457
        # We should have got a control dir matching the referenced branch.
466
470
        client.add_expected_call(
467
471
            'BzrDir.cloning_metadir', ('quack/', 'False'),
468
472
            'success', (control_name, '', ('branch', ''))),
469
 
        a_bzrdir = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
 
473
        a_bzrdir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
470
474
            _client=client)
471
475
        result = a_bzrdir.cloning_metadir()
472
476
        # We should have got a reference control dir with default branch and
492
496
        client.add_expected_call(
493
497
            'BzrDir.open_2.1', ('quack/',), 'success', ('no',))
494
498
        self.assertRaises(errors.NotBranchError, RemoteBzrDir, transport,
495
 
                remote.RemoteBzrDirFormat(), _client=client, _force_probe=True)
 
499
                RemoteBzrDirFormat(), _client=client, _force_probe=True)
496
500
        self.assertFinished(client)
497
501
 
498
502
    def test_present_without_workingtree(self):
499
503
        client, transport = self.make_fake_client_and_transport()
500
504
        client.add_expected_call(
501
505
            'BzrDir.open_2.1', ('quack/',), 'success', ('yes', 'no'))
502
 
        bd = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
 
506
        bd = RemoteBzrDir(transport, RemoteBzrDirFormat(),
503
507
            _client=client, _force_probe=True)
504
508
        self.assertIsInstance(bd, RemoteBzrDir)
505
509
        self.assertFalse(bd.has_workingtree())
510
514
        client, transport = self.make_fake_client_and_transport()
511
515
        client.add_expected_call(
512
516
            'BzrDir.open_2.1', ('quack/',), 'success', ('yes', 'yes'))
513
 
        bd = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
 
517
        bd = RemoteBzrDir(transport, RemoteBzrDirFormat(),
514
518
            _client=client, _force_probe=True)
515
519
        self.assertIsInstance(bd, RemoteBzrDir)
516
520
        self.assertTrue(bd.has_workingtree())
523
527
            'BzrDir.open_2.1', ('quack/',), 'unknown', ('BzrDir.open_2.1',))
524
528
        client.add_expected_call(
525
529
            'BzrDir.open', ('quack/',), 'success', ('yes',))
526
 
        bd = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
 
530
        bd = RemoteBzrDir(transport, RemoteBzrDirFormat(),
527
531
            _client=client, _force_probe=True)
528
532
        self.assertIsInstance(bd, RemoteBzrDir)
529
533
        self.assertFinished(client)
545
549
            'BzrDir.open_2.1', ('quack/',), 'unknown', ('BzrDir.open_2.1',))
546
550
        client.add_expected_call(
547
551
            'BzrDir.open', ('quack/',), 'success', ('yes',))
548
 
        bd = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
 
552
        bd = RemoteBzrDir(transport, RemoteBzrDirFormat(),
549
553
            _client=client, _force_probe=True)
550
554
        self.assertIsInstance(bd, RemoteBzrDir)
551
555
        self.assertFinished(client)
582
586
        client.add_expected_call(
583
587
            'Branch.get_stacked_on_url', ('quack/',),
584
588
            'error', ('NotStacked',))
585
 
        bzrdir = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
 
589
        bzrdir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
586
590
            _client=client)
587
591
        result = bzrdir.open_branch()
588
592
        self.assertIsInstance(result, RemoteBranch)
595
599
        transport = transport.clone('quack')
596
600
        client = FakeClient(transport.base)
597
601
        client.add_error_response('nobranch')
598
 
        bzrdir = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
 
602
        bzrdir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
599
603
            _client=client)
600
604
        self.assertRaises(errors.NotBranchError, bzrdir.open_branch)
601
605
        self.assertEqual(
612
616
        transport = MemoryTransport()
613
617
        # no requests on the network - catches other api calls being made.
614
618
        client = FakeClient(transport.base)
615
 
        bzrdir = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
 
619
        bzrdir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
616
620
            _client=client)
617
621
        # patch the open_branch call to record that it was called.
618
622
        bzrdir.open_branch = open_branch
637
641
        client.add_expected_call(
638
642
            'Branch.get_stacked_on_url', ('~hello/',),
639
643
            'error', ('NotStacked',))
640
 
        bzrdir = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
 
644
        bzrdir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
641
645
            _client=client)
642
646
        result = bzrdir.open_branch()
643
647
        self.assertFinished(client)
660
664
        client.add_success_response(
661
665
            'ok', '', rich_response, subtree_response, external_lookup,
662
666
            network_name)
663
 
        bzrdir = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
 
667
        bzrdir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
664
668
            _client=client)
665
669
        result = bzrdir.open_repository()
666
670
        self.assertEqual(
683
687
        old.
684
688
        """
685
689
        self.assertRaises(errors.NotBranchError,
686
 
            RemoteBzrDirFormat.probe_transport, OldServerTransport())
 
690
            RemoteBzrProber.probe_transport, OldServerTransport())
687
691
 
688
692
 
689
693
class TestBzrDirCreateBranch(TestRemote):
712
716
            'BzrDir.create_branch', ('quack/', network_name),
713
717
            'success', ('ok', network_name, '', 'no', 'no', 'yes',
714
718
            reference_repo_name))
715
 
        a_bzrdir = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
 
719
        a_bzrdir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
716
720
            _client=client)
717
721
        branch = a_bzrdir.create_branch()
718
722
        # We should have got a remote branch
721
725
        format = branch._format
722
726
        self.assertEqual(network_name, format.network_name())
723
727
 
 
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
 
724
756
 
725
757
class TestBzrDirCreateRepository(TestRemote):
726
758
 
747
779
                'Bazaar repository format 2a (needs bzr 1.16 or later)\n',
748
780
                'False'),
749
781
            'success', ('ok', 'yes', 'yes', 'yes', network_name))
750
 
        a_bzrdir = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
 
782
        a_bzrdir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
751
783
            _client=client)
752
784
        repo = a_bzrdir.create_repository()
753
785
        # We should have got a remote repository
782
814
        client.add_success_response('stat', '0', '65535')
783
815
        remote_transport = RemoteTransport(server_url + 'quack/', medium=False,
784
816
            _client=client)
785
 
        bzrdir = RemoteBzrDir(remote_transport, remote.RemoteBzrDirFormat(),
 
817
        bzrdir = RemoteBzrDir(remote_transport, RemoteBzrDirFormat(),
786
818
            _client=client)
787
819
        repo = bzrdir.open_repository()
788
820
        self.assertEqual(
815
847
        client.add_success_response('stat', '0', '65535')
816
848
        remote_transport = RemoteTransport(server_url + 'quack/', medium=False,
817
849
            _client=client)
818
 
        bzrdir = RemoteBzrDir(remote_transport, remote.RemoteBzrDirFormat(),
 
850
        bzrdir = RemoteBzrDir(remote_transport, RemoteBzrDirFormat(),
819
851
            _client=client)
820
852
        repo = bzrdir.open_repository()
821
853
        self.assertEqual(
836
868
        transport = transport.clone('quack')
837
869
        client = FakeClient(transport.base)
838
870
        client.add_success_response('ok', '', 'no', 'no', 'no', network_name)
839
 
        bzrdir = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
 
871
        bzrdir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
840
872
            _client=client)
841
873
        repo = bzrdir.open_repository()
842
874
        self.assertEqual(
849
881
 
850
882
    def test_success(self):
851
883
        """Simple test for typical successful call."""
852
 
        fmt = bzrdir.RemoteBzrDirFormat()
 
884
        fmt = RemoteBzrDirFormat()
853
885
        default_format_name = BzrDirFormat.get_default_format().network_name()
854
886
        transport = self.get_transport()
855
887
        client = FakeClient(transport.base)
871
903
        """Error responses are translated, e.g. 'PermissionDenied' raises the
872
904
        corresponding error from the client.
873
905
        """
874
 
        fmt = bzrdir.RemoteBzrDirFormat()
 
906
        fmt = RemoteBzrDirFormat()
875
907
        default_format_name = BzrDirFormat.get_default_format().network_name()
876
908
        transport = self.get_transport()
877
909
        client = FakeClient(transport.base)
895
927
        """Integration test for error translation."""
896
928
        transport = self.make_smart_server('foo')
897
929
        transport = transport.clone('no-such-path')
898
 
        fmt = bzrdir.RemoteBzrDirFormat()
 
930
        fmt = RemoteBzrDirFormat()
899
931
        err = self.assertRaises(errors.NoSuchFile,
900
932
            fmt.initialize_on_transport_ex, transport, create_prefix=False)
901
933
 
932
964
 
933
965
    def make_remote_bzrdir(self, transport, client):
934
966
        """Make a RemotebzrDir using 'client' as the _client."""
935
 
        return RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
 
967
        return RemoteBzrDir(transport, RemoteBzrDirFormat(),
936
968
            _client=client)
937
969
 
938
970
 
1140
1172
            [('set_tags_bytes', 'tags bytes')] * 2, real_branch.calls)
1141
1173
 
1142
1174
 
 
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
 
1143
1240
class TestBranchLastRevisionInfo(RemoteBranchTestCase):
1144
1241
 
1145
1242
    def test_empty_branch(self):
1200
1297
        client.add_expected_call(
1201
1298
            'Branch.get_stacked_on_url', ('stacked/',),
1202
1299
            'success', ('ok', vfs_url))
1203
 
        bzrdir = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
 
1300
        bzrdir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
1204
1301
            _client=client)
1205
1302
        repo_fmt = remote.RemoteRepositoryFormat()
1206
1303
        repo_fmt._custom_format = stacked_branch.repository._format
1233
1330
        # this will also do vfs access, but that goes direct to the transport
1234
1331
        # and isn't seen by the FakeClient.
1235
1332
        bzrdir = RemoteBzrDir(self.get_transport('stacked'),
1236
 
            remote.RemoteBzrDirFormat(), _client=client)
 
1333
            RemoteBzrDirFormat(), _client=client)
1237
1334
        branch = bzrdir.open_branch()
1238
1335
        result = branch.get_stacked_on_url()
1239
1336
        self.assertEqual('../base', result)
1266
1363
            'Branch.get_stacked_on_url', ('stacked/',),
1267
1364
            'success', ('ok', '../base'))
1268
1365
        bzrdir = RemoteBzrDir(self.get_transport('stacked'),
1269
 
            remote.RemoteBzrDirFormat(), _client=client)
 
1366
            RemoteBzrDirFormat(), _client=client)
1270
1367
        branch = bzrdir.open_branch()
1271
1368
        result = branch.get_stacked_on_url()
1272
1369
        self.assertEqual('../base', result)
1842
1939
        client = FakeClient(transport.base)
1843
1940
        transport = transport.clone(transport_path)
1844
1941
        # we do not want bzrdir to make any remote calls
1845
 
        bzrdir = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
 
1942
        bzrdir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
1846
1943
            _client=False)
1847
1944
        repo = RemoteRepository(bzrdir, None, _client=client)
1848
1945
        return repo, client
1856
1953
 
1857
1954
    def test_get_format_description(self):
1858
1955
        remote_format = RemoteBranchFormat()
1859
 
        real_format = branch.BranchFormat.get_default_format()
 
1956
        real_format = branch.format_registry.get_default()
1860
1957
        remote_format._network_name = real_format.network_name()
1861
1958
        self.assertEqual(remoted_description(real_format),
1862
1959
            remote_format.get_format_description())
1865
1962
class TestRepositoryFormat(TestRemoteRepository):
1866
1963
 
1867
1964
    def test_fast_delta(self):
1868
 
        true_name = groupcompress_repo.RepositoryFormatCHK1().network_name()
 
1965
        true_name = groupcompress_repo.RepositoryFormat2a().network_name()
1869
1966
        true_format = RemoteRepositoryFormat()
1870
1967
        true_format._network_name = true_name
1871
1968
        self.assertEqual(True, true_format.fast_deltas)
1876
1973
 
1877
1974
    def test_get_format_description(self):
1878
1975
        remote_repo_format = RemoteRepositoryFormat()
1879
 
        real_format = repository.RepositoryFormat.get_default_format()
 
1976
        real_format = repository.format_registry.get_default()
1880
1977
        remote_repo_format._network_name = real_format.network_name()
1881
1978
        self.assertEqual(remoted_description(real_format),
1882
1979
            remote_repo_format.get_format_description())
2440
2537
        the client is finished.
2441
2538
        """
2442
2539
        sink = repo._get_sink()
2443
 
        fmt = repository.RepositoryFormat.get_default_format()
 
2540
        fmt = repository.format_registry.get_default()
2444
2541
        resume_tokens, missing_keys = sink.insert_stream([], fmt, [])
2445
2542
        self.assertEqual([], resume_tokens)
2446
2543
        self.assertEqual(set(), missing_keys)
2546
2643
                return True
2547
2644
        repo._real_repository = FakeRealRepository()
2548
2645
        sink = repo._get_sink()
2549
 
        fmt = repository.RepositoryFormat.get_default_format()
 
2646
        fmt = repository.format_registry.get_default()
2550
2647
        stream = self.make_stream_with_inv_deltas(fmt)
2551
2648
        resume_tokens, missing_keys = sink.insert_stream(stream, fmt, [])
2552
2649
        # Every record from the first inventory delta should have been sent to
2772
2869
             ('pack collection autopack',)],
2773
2870
            client._calls)
2774
2871
 
 
2872
    def test_oom_error_reporting(self):
 
2873
        """An out-of-memory condition on the server is reported clearly"""
 
2874
        transport_path = 'quack'
 
2875
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
2876
        client.add_expected_call(
 
2877
            'PackRepository.autopack', ('quack/',),
 
2878
            'error', ('MemoryError',))
 
2879
        err = self.assertRaises(errors.BzrError, repo.autopack)
 
2880
        self.assertContainsRe(str(err), "^remote server out of mem")
 
2881
 
2775
2882
 
2776
2883
class TestErrorTranslationBase(tests.TestCaseWithMemoryTransport):
2777
2884
    """Base class for unit tests for bzrlib.remote._translate_error."""
2850
2957
            detail='extra detail')
2851
2958
        self.assertEqual(expected_error, translated_error)
2852
2959
 
 
2960
    def test_norepository(self):
 
2961
        bzrdir = self.make_bzrdir('')
 
2962
        translated_error = self.translateTuple(('norepository',),
 
2963
            bzrdir=bzrdir)
 
2964
        expected_error = errors.NoRepositoryPresent(bzrdir)
 
2965
        self.assertEqual(expected_error, translated_error)
 
2966
 
2853
2967
    def test_LockContention(self):
2854
2968
        translated_error = self.translateTuple(('LockContention',))
2855
2969
        expected_error = errors.LockContention('(remote lock)')
2883
2997
        expected_error = errors.DivergedBranches(branch, other_branch)
2884
2998
        self.assertEqual(expected_error, translated_error)
2885
2999
 
 
3000
    def test_NotStacked(self):
 
3001
        branch = self.make_branch('')
 
3002
        translated_error = self.translateTuple(('NotStacked',), branch=branch)
 
3003
        expected_error = errors.NotStacked(branch)
 
3004
        self.assertEqual(expected_error, translated_error)
 
3005
 
2886
3006
    def test_ReadError_no_args(self):
2887
3007
        path = 'a path'
2888
3008
        translated_error = self.translateTuple(('ReadError',), path=path)
2904
3024
 
2905
3025
    def test_PermissionDenied_no_args(self):
2906
3026
        path = 'a path'
2907
 
        translated_error = self.translateTuple(('PermissionDenied',), path=path)
 
3027
        translated_error = self.translateTuple(('PermissionDenied',),
 
3028
            path=path)
2908
3029
        expected_error = errors.PermissionDenied(path)
2909
3030
        self.assertEqual(expected_error, translated_error)
2910
3031
 
2933
3054
        expected_error = errors.PermissionDenied(path, extra)
2934
3055
        self.assertEqual(expected_error, translated_error)
2935
3056
 
 
3057
    # GZ 2011-03-02: TODO test for PermissionDenied with non-ascii 'extra'
 
3058
 
 
3059
    def test_NoSuchFile_context_path(self):
 
3060
        local_path = "local path"
 
3061
        translated_error = self.translateTuple(('ReadError', "remote path"),
 
3062
            path=local_path)
 
3063
        expected_error = errors.ReadError(local_path)
 
3064
        self.assertEqual(expected_error, translated_error)
 
3065
 
 
3066
    def test_NoSuchFile_without_context(self):
 
3067
        remote_path = "remote path"
 
3068
        translated_error = self.translateTuple(('ReadError', remote_path))
 
3069
        expected_error = errors.ReadError(remote_path)
 
3070
        self.assertEqual(expected_error, translated_error)
 
3071
 
 
3072
    def test_ReadOnlyError(self):
 
3073
        translated_error = self.translateTuple(('ReadOnlyError',))
 
3074
        expected_error = errors.TransportNotPossible("readonly transport")
 
3075
        self.assertEqual(expected_error, translated_error)
 
3076
 
 
3077
    def test_MemoryError(self):
 
3078
        translated_error = self.translateTuple(('MemoryError',))
 
3079
        self.assertStartsWith(str(translated_error),
 
3080
            "remote server out of memory")
 
3081
 
 
3082
    def test_generic_IndexError_no_classname(self):
 
3083
        err = errors.ErrorFromSmartServer(('error', "list index out of range"))
 
3084
        translated_error = self.translateErrorFromSmartServer(err)
 
3085
        expected_error = errors.UnknownErrorFromSmartServer(err)
 
3086
        self.assertEqual(expected_error, translated_error)
 
3087
 
 
3088
    # GZ 2011-03-02: TODO test generic non-ascii error string
 
3089
 
 
3090
    def test_generic_KeyError(self):
 
3091
        err = errors.ErrorFromSmartServer(('error', 'KeyError', "1"))
 
3092
        translated_error = self.translateErrorFromSmartServer(err)
 
3093
        expected_error = errors.UnknownErrorFromSmartServer(err)
 
3094
        self.assertEqual(expected_error, translated_error)
 
3095
 
2936
3096
 
2937
3097
class TestErrorTranslationRobustness(TestErrorTranslationBase):
2938
3098
    """Unit tests for bzrlib.remote._translate_error's robustness.
3180
3340
 
3181
3341
    def test_copy_content_into_avoids_revision_history(self):
3182
3342
        local = self.make_branch('local')
3183
 
        remote_backing_tree = self.make_branch_and_tree('remote')
3184
 
        remote_backing_tree.commit("Commit.")
 
3343
        builder = self.make_branch_builder('remote')
 
3344
        builder.build_commit(message="Commit.")
3185
3345
        remote_branch_url = self.smart_server.get_url() + 'remote'
3186
3346
        remote_branch = bzrdir.BzrDir.open(remote_branch_url).open_branch()
3187
3347
        local.repository.fetch(remote_branch.repository)
3188
3348
        self.hpss_calls = []
3189
3349
        remote_branch.copy_content_into(local)
3190
3350
        self.assertFalse('Branch.revision_history' in self.hpss_calls)
 
3351
 
 
3352
    def test_fetch_everything_needs_just_one_call(self):
 
3353
        local = self.make_branch('local')
 
3354
        builder = self.make_branch_builder('remote')
 
3355
        builder.build_commit(message="Commit.")
 
3356
        remote_branch_url = self.smart_server.get_url() + 'remote'
 
3357
        remote_branch = bzrdir.BzrDir.open(remote_branch_url).open_branch()
 
3358
        self.hpss_calls = []
 
3359
        local.repository.fetch(remote_branch.repository,
 
3360
                fetch_spec=graph.EverythingResult(remote_branch.repository))
 
3361
        self.assertEqual(['Repository.get_stream_1.19'], self.hpss_calls)
 
3362
 
 
3363
    def override_verb(self, verb_name, verb):
 
3364
        request_handlers = request.request_handlers
 
3365
        orig_verb = request_handlers.get(verb_name)
 
3366
        request_handlers.register(verb_name, verb, override_existing=True)
 
3367
        self.addCleanup(request_handlers.register, verb_name, orig_verb,
 
3368
                override_existing=True)
 
3369
 
 
3370
    def test_fetch_everything_backwards_compat(self):
 
3371
        """Can fetch with EverythingResult even with pre 2.4 servers.
 
3372
        
 
3373
        Pre-2.4 do not support 'everything' searches with the
 
3374
        Repository.get_stream_1.19 verb.
 
3375
        """
 
3376
        verb_log = []
 
3377
        class OldGetStreamVerb(SmartServerRepositoryGetStream_1_19):
 
3378
            """A version of the Repository.get_stream_1.19 verb patched to
 
3379
            reject 'everything' searches the way 2.3 and earlier do.
 
3380
            """
 
3381
            def recreate_search(self, repository, search_bytes, discard_excess=False):
 
3382
                verb_log.append(search_bytes.split('\n', 1)[0])
 
3383
                if search_bytes == 'everything':
 
3384
                    return (None, request.FailedSmartServerResponse(('BadSearch',)))
 
3385
                return super(OldGetStreamVerb,
 
3386
                        self).recreate_search(repository, search_bytes,
 
3387
                            discard_excess=discard_excess)
 
3388
        self.override_verb('Repository.get_stream_1.19', OldGetStreamVerb)
 
3389
        local = self.make_branch('local')
 
3390
        builder = self.make_branch_builder('remote')
 
3391
        builder.build_commit(message="Commit.")
 
3392
        remote_branch_url = self.smart_server.get_url() + 'remote'
 
3393
        remote_branch = bzrdir.BzrDir.open(remote_branch_url).open_branch()
 
3394
        self.hpss_calls = []
 
3395
        local.repository.fetch(remote_branch.repository,
 
3396
                fetch_spec=graph.EverythingResult(remote_branch.repository))
 
3397
        # make sure the overridden verb was used
 
3398
        self.assertLength(1, verb_log)
 
3399
        # more than one HPSS call is needed, but because it's a VFS callback
 
3400
        # its hard to predict exactly how many.
 
3401
        self.assertTrue(len(self.hpss_calls) > 1)
 
3402