/brz/remove-bazaar

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

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_remote.py

  • Committer: Jelmer Vernooij
  • Date: 2011-03-11 15:34:14 UTC
  • mto: This revision was merged to the branch mainline in revision 5718.
  • Revision ID: jelmer@samba.org-20110311153414-i7vjkje5p8s2ozo9
Move more weave code.

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
    transport,
41
42
    treebuilder,
42
 
    urlutils,
43
43
    versionedfile,
44
44
    )
45
45
from bzrlib.branch import Branch
46
 
from bzrlib.bzrdir import BzrDir, BzrDirFormat
 
46
from bzrlib.bzrdir import (
 
47
    BzrDir,
 
48
    BzrDirFormat,
 
49
    RemoteBzrProber,
 
50
    )
47
51
from bzrlib.remote import (
48
52
    RemoteBranch,
49
53
    RemoteBranchFormat,
50
54
    RemoteBzrDir,
51
 
    RemoteBzrDirFormat,
52
55
    RemoteRepository,
53
56
    RemoteRepositoryFormat,
54
57
    )
55
58
from bzrlib.repofmt import groupcompress_repo, pack_repo
56
59
from bzrlib.revision import NULL_REVISION
57
 
from bzrlib.smart import medium
 
60
from bzrlib.smart import medium, request
58
61
from bzrlib.smart.client import _SmartClient
59
 
from bzrlib.smart.repository import SmartServerRepositoryGetParentMap
 
62
from bzrlib.smart.repository import (
 
63
    SmartServerRepositoryGetParentMap,
 
64
    SmartServerRepositoryGetStream_1_19,
 
65
    )
60
66
from bzrlib.tests import (
61
 
    condition_isinstance,
62
 
    split_suite_by_condition,
63
 
    multiply_tests,
64
67
    test_server,
65
68
    )
66
 
from bzrlib.transport import get_transport
 
69
from bzrlib.tests.scenarios import load_tests_apply_scenarios
67
70
from bzrlib.transport.memory import MemoryTransport
68
71
from bzrlib.transport.remote import (
69
72
    RemoteTransport,
70
73
    RemoteSSHTransport,
71
74
    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 = [
 
75
    )
 
76
 
 
77
 
 
78
load_tests = load_tests_apply_scenarios
 
79
 
 
80
 
 
81
class BasicRemoteObjectTests(tests.TestCaseWithTransport):
 
82
 
 
83
    scenarios = [
78
84
        ('HPSS-v2',
79
 
         {'transport_server': test_server.SmartTCPServer_for_testing_v2_only}),
 
85
            {'transport_server': test_server.SmartTCPServer_for_testing_v2_only}),
80
86
        ('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):
 
87
            {'transport_server': test_server.SmartTCPServer_for_testing})]
 
88
 
86
89
 
87
90
    def setUp(self):
88
91
        super(BasicRemoteObjectTests, self).setUp()
89
92
        self.transport = self.get_transport()
90
93
        # make a branch that can be opened over the smart transport
91
94
        self.local_wt = BzrDir.create_standalone_workingtree('.')
92
 
 
93
 
    def tearDown(self):
94
 
        self.transport.disconnect()
95
 
        tests.TestCaseWithTransport.tearDown(self)
 
95
        self.addCleanup(self.transport.disconnect)
96
96
 
97
97
    def test_create_remote_bzrdir(self):
98
98
        b = remote.RemoteBzrDir(self.transport, remote.RemoteBzrDirFormat())
122
122
    def test_find_correct_format(self):
123
123
        """Should open a RemoteBzrDir over a RemoteTransport"""
124
124
        fmt = BzrDirFormat.find_format(self.transport)
125
 
        self.assertTrue(RemoteBzrDirFormat
126
 
                        in BzrDirFormat._control_server_formats)
 
125
        self.assertTrue(bzrdir.RemoteBzrProber
 
126
                        in controldir.ControlDirFormat._server_probers)
127
127
        self.assertIsInstance(fmt, remote.RemoteBzrDirFormat)
128
128
 
129
129
    def test_open_detected_smart_format(self):
359
359
        a given client_base and transport_base.
360
360
        """
361
361
        client_medium = medium.SmartClientMedium(client_base)
362
 
        transport = get_transport(transport_base)
363
 
        result = client_medium.remote_path_from_transport(transport)
 
362
        t = transport.get_transport(transport_base)
 
363
        result = client_medium.remote_path_from_transport(t)
364
364
        self.assertEqual(expected, result)
365
365
 
366
366
    def test_remote_path_from_transport(self):
377
377
        a given transport_base and relpath of that transport.  (Note that
378
378
        HttpTransportBase is a subclass of SmartClientMedium)
379
379
        """
380
 
        base_transport = get_transport(transport_base)
 
380
        base_transport = transport.get_transport(transport_base)
381
381
        client_medium = base_transport.get_smart_medium()
382
382
        cloned_transport = base_transport.clone(relpath)
383
383
        result = client_medium.remote_path_from_transport(cloned_transport)
609
609
        # _get_tree_branch is a form of open_branch, but it should only ask for
610
610
        # branch opening, not any other network requests.
611
611
        calls = []
612
 
        def open_branch():
 
612
        def open_branch(name=None):
613
613
            calls.append("Called")
614
614
            return "a-branch"
615
615
        transport = MemoryTransport()
686
686
        old.
687
687
        """
688
688
        self.assertRaises(errors.NotBranchError,
689
 
            RemoteBzrDirFormat.probe_transport, OldServerTransport())
 
689
            RemoteBzrProber.probe_transport, OldServerTransport())
690
690
 
691
691
 
692
692
class TestBzrDirCreateBranch(TestRemote):
724
724
        format = branch._format
725
725
        self.assertEqual(network_name, format.network_name())
726
726
 
 
727
    def test_already_open_repo_and_reused_medium(self):
 
728
        """Bug 726584: create_branch(..., repository=repo) should work
 
729
        regardless of what the smart medium's base URL is.
 
730
        """
 
731
        self.transport_server = test_server.SmartTCPServer_for_testing
 
732
        transport = self.get_transport('.')
 
733
        repo = self.make_repository('quack')
 
734
        # Client's medium rooted a transport root (not at the bzrdir)
 
735
        client = FakeClient(transport.base)
 
736
        transport = transport.clone('quack')
 
737
        reference_bzrdir_format = bzrdir.format_registry.get('default')()
 
738
        reference_format = reference_bzrdir_format.get_branch_format()
 
739
        network_name = reference_format.network_name()
 
740
        reference_repo_fmt = reference_bzrdir_format.repository_format
 
741
        reference_repo_name = reference_repo_fmt.network_name()
 
742
        client.add_expected_call(
 
743
            'BzrDir.create_branch', ('extra/quack/', network_name),
 
744
            'success', ('ok', network_name, '', 'no', 'no', 'yes',
 
745
            reference_repo_name))
 
746
        a_bzrdir = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
 
747
            _client=client)
 
748
        branch = a_bzrdir.create_branch(repository=repo)
 
749
        # We should have got a remote branch
 
750
        self.assertIsInstance(branch, remote.RemoteBranch)
 
751
        # its format should have the settings from the response
 
752
        format = branch._format
 
753
        self.assertEqual(network_name, format.network_name())
 
754
 
727
755
 
728
756
class TestBzrDirCreateRepository(TestRemote):
729
757
 
1143
1171
            [('set_tags_bytes', 'tags bytes')] * 2, real_branch.calls)
1144
1172
 
1145
1173
 
 
1174
class TestBranchHeadsToFetch(RemoteBranchTestCase):
 
1175
 
 
1176
    def test_uses_last_revision_info_and_tags_by_default(self):
 
1177
        transport = MemoryTransport()
 
1178
        client = FakeClient(transport.base)
 
1179
        client.add_expected_call(
 
1180
            'Branch.get_stacked_on_url', ('quack/',),
 
1181
            'error', ('NotStacked',))
 
1182
        client.add_expected_call(
 
1183
            'Branch.last_revision_info', ('quack/',),
 
1184
            'success', ('ok', '1', 'rev-tip'))
 
1185
        # XXX: this will break if the default format's serialization of tags
 
1186
        # changes, or if the RPC for fetching tags changes from get_tags_bytes.
 
1187
        client.add_expected_call(
 
1188
            'Branch.get_tags_bytes', ('quack/',),
 
1189
            'success', ('d5:tag-17:rev-foo5:tag-27:rev-bare',))
 
1190
        transport.mkdir('quack')
 
1191
        transport = transport.clone('quack')
 
1192
        branch = self.make_remote_branch(transport, client)
 
1193
        result = branch.heads_to_fetch()
 
1194
        self.assertFinished(client)
 
1195
        self.assertEqual(
 
1196
            (set(['rev-tip']), set(['rev-foo', 'rev-bar'])), result)
 
1197
 
 
1198
    def test_uses_rpc_for_formats_with_non_default_heads_to_fetch(self):
 
1199
        transport = MemoryTransport()
 
1200
        client = FakeClient(transport.base)
 
1201
        client.add_expected_call(
 
1202
            'Branch.get_stacked_on_url', ('quack/',),
 
1203
            'error', ('NotStacked',))
 
1204
        client.add_expected_call(
 
1205
            'Branch.heads_to_fetch', ('quack/',),
 
1206
            'success', (['tip'], ['tagged-1', 'tagged-2']))
 
1207
        transport.mkdir('quack')
 
1208
        transport = transport.clone('quack')
 
1209
        branch = self.make_remote_branch(transport, client)
 
1210
        branch._format._use_default_local_heads_to_fetch = lambda: False
 
1211
        result = branch.heads_to_fetch()
 
1212
        self.assertFinished(client)
 
1213
        self.assertEqual((set(['tip']), set(['tagged-1', 'tagged-2'])), result)
 
1214
 
 
1215
    def test_backwards_compatible(self):
 
1216
        self.setup_smart_server_with_call_log()
 
1217
        # Make a branch with a single revision.
 
1218
        builder = self.make_branch_builder('foo')
 
1219
        builder.start_series()
 
1220
        builder.build_snapshot('tip', None, [
 
1221
            ('add', ('', 'root-id', 'directory', ''))])
 
1222
        builder.finish_series()
 
1223
        branch = builder.get_branch()
 
1224
        # Add two tags to that branch
 
1225
        branch.tags.set_tag('tag-1', 'rev-1')
 
1226
        branch.tags.set_tag('tag-2', 'rev-2')
 
1227
        self.addCleanup(branch.lock_read().unlock)
 
1228
        # Disable the heads_to_fetch verb
 
1229
        verb = 'Branch.heads_to_fetch'
 
1230
        self.disable_verb(verb)
 
1231
        self.reset_smart_call_log()
 
1232
        result = branch.heads_to_fetch()
 
1233
        self.assertEqual((set(['tip']), set(['rev-1', 'rev-2'])), result)
 
1234
        self.assertEqual(
 
1235
            ['Branch.last_revision_info', 'Branch.get_tags_bytes'],
 
1236
            [call.call.method for call in self.hpss_calls])
 
1237
 
 
1238
 
1146
1239
class TestBranchLastRevisionInfo(RemoteBranchTestCase):
1147
1240
 
1148
1241
    def test_empty_branch(self):
1618
1711
    def test_get_multi_line_branch_conf(self):
1619
1712
        # Make sure that multiple-line branch.conf files are supported
1620
1713
        #
1621
 
        # https://bugs.edge.launchpad.net/bzr/+bug/354075
 
1714
        # https://bugs.launchpad.net/bzr/+bug/354075
1622
1715
        client = FakeClient()
1623
1716
        client.add_expected_call(
1624
1717
            'Branch.get_stacked_on_url', ('memory:///',),
1652
1745
        branch.unlock()
1653
1746
        self.assertFinished(client)
1654
1747
 
 
1748
    def test_set_option_with_dict(self):
 
1749
        client = FakeClient()
 
1750
        client.add_expected_call(
 
1751
            'Branch.get_stacked_on_url', ('memory:///',),
 
1752
            'error', ('NotStacked',),)
 
1753
        client.add_expected_call(
 
1754
            'Branch.lock_write', ('memory:///', '', ''),
 
1755
            'success', ('ok', 'branch token', 'repo token'))
 
1756
        encoded_dict_value = 'd5:ascii1:a11:unicode \xe2\x8c\x9a3:\xe2\x80\xbde'
 
1757
        client.add_expected_call(
 
1758
            'Branch.set_config_option_dict', ('memory:///', 'branch token',
 
1759
            'repo token', encoded_dict_value, 'foo', ''),
 
1760
            'success', ())
 
1761
        client.add_expected_call(
 
1762
            'Branch.unlock', ('memory:///', 'branch token', 'repo token'),
 
1763
            'success', ('ok',))
 
1764
        transport = MemoryTransport()
 
1765
        branch = self.make_remote_branch(transport, client)
 
1766
        branch.lock_write()
 
1767
        config = branch._get_config()
 
1768
        config.set_option(
 
1769
            {'ascii': 'a', u'unicode \N{WATCH}': u'\N{INTERROBANG}'},
 
1770
            'foo')
 
1771
        branch.unlock()
 
1772
        self.assertFinished(client)
 
1773
 
1655
1774
    def test_backwards_compat_set_option(self):
1656
1775
        self.setup_smart_server_with_call_log()
1657
1776
        branch = self.make_branch('.')
1664
1783
        self.assertLength(10, self.hpss_calls)
1665
1784
        self.assertEqual('value', branch._get_config().get_option('name'))
1666
1785
 
 
1786
    def test_backwards_compat_set_option_with_dict(self):
 
1787
        self.setup_smart_server_with_call_log()
 
1788
        branch = self.make_branch('.')
 
1789
        verb = 'Branch.set_config_option_dict'
 
1790
        self.disable_verb(verb)
 
1791
        branch.lock_write()
 
1792
        self.addCleanup(branch.unlock)
 
1793
        self.reset_smart_call_log()
 
1794
        config = branch._get_config()
 
1795
        value_dict = {'ascii': 'a', u'unicode \N{WATCH}': u'\N{INTERROBANG}'}
 
1796
        config.set_option(value_dict, 'name')
 
1797
        self.assertLength(10, self.hpss_calls)
 
1798
        self.assertEqual(value_dict, branch._get_config().get_option('name'))
 
1799
 
1667
1800
 
1668
1801
class TestBranchLockWrite(RemoteBranchTestCase):
1669
1802
 
1819
1952
 
1820
1953
    def test_get_format_description(self):
1821
1954
        remote_format = RemoteBranchFormat()
1822
 
        real_format = branch.BranchFormat.get_default_format()
 
1955
        real_format = branch.format_registry.get_default()
1823
1956
        remote_format._network_name = real_format.network_name()
1824
1957
        self.assertEqual(remoted_description(real_format),
1825
1958
            remote_format.get_format_description())
1828
1961
class TestRepositoryFormat(TestRemoteRepository):
1829
1962
 
1830
1963
    def test_fast_delta(self):
1831
 
        true_name = groupcompress_repo.RepositoryFormatCHK1().network_name()
 
1964
        true_name = groupcompress_repo.RepositoryFormat2a().network_name()
1832
1965
        true_format = RemoteRepositoryFormat()
1833
1966
        true_format._network_name = true_name
1834
1967
        self.assertEqual(True, true_format.fast_deltas)
1839
1972
 
1840
1973
    def test_get_format_description(self):
1841
1974
        remote_repo_format = RemoteRepositoryFormat()
1842
 
        real_format = repository.RepositoryFormat.get_default_format()
 
1975
        real_format = repository.format_registry.get_default()
1843
1976
        remote_repo_format._network_name = real_format.network_name()
1844
1977
        self.assertEqual(remoted_description(real_format),
1845
1978
            remote_repo_format.get_format_description())
2257
2390
        self.setup_smart_server_with_call_log()
2258
2391
        tree = self.make_branch_and_memory_tree('.')
2259
2392
        tree.lock_write()
 
2393
        tree.add('')
2260
2394
        rev1 = tree.commit('First')
2261
2395
        rev2 = tree.commit('Second')
2262
2396
        tree.unlock()
2301
2435
        transport_path = 'quack'
2302
2436
        repo, client = self.setup_fake_client_and_repository(transport_path)
2303
2437
        client.add_success_response('ok', 'a token')
2304
 
        result = repo.lock_write()
 
2438
        token = repo.lock_write().repository_token
2305
2439
        self.assertEqual(
2306
2440
            [('call', 'Repository.lock_write', ('quack/', ''))],
2307
2441
            client._calls)
2308
 
        self.assertEqual('a token', result)
 
2442
        self.assertEqual('a token', token)
2309
2443
 
2310
2444
    def test_lock_write_already_locked(self):
2311
2445
        transport_path = 'quack'
2402
2536
        the client is finished.
2403
2537
        """
2404
2538
        sink = repo._get_sink()
2405
 
        fmt = repository.RepositoryFormat.get_default_format()
 
2539
        fmt = repository.format_registry.get_default()
2406
2540
        resume_tokens, missing_keys = sink.insert_stream([], fmt, [])
2407
2541
        self.assertEqual([], resume_tokens)
2408
2542
        self.assertEqual(set(), missing_keys)
2508
2642
                return True
2509
2643
        repo._real_repository = FakeRealRepository()
2510
2644
        sink = repo._get_sink()
2511
 
        fmt = repository.RepositoryFormat.get_default_format()
 
2645
        fmt = repository.format_registry.get_default()
2512
2646
        stream = self.make_stream_with_inv_deltas(fmt)
2513
2647
        resume_tokens, missing_keys = sink.insert_stream(stream, fmt, [])
2514
2648
        # Every record from the first inventory delta should have been sent to
2734
2868
             ('pack collection autopack',)],
2735
2869
            client._calls)
2736
2870
 
 
2871
    def test_oom_error_reporting(self):
 
2872
        """An out-of-memory condition on the server is reported clearly"""
 
2873
        transport_path = 'quack'
 
2874
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
2875
        client.add_expected_call(
 
2876
            'PackRepository.autopack', ('quack/',),
 
2877
            'error', ('MemoryError',))
 
2878
        err = self.assertRaises(errors.BzrError, repo.autopack)
 
2879
        self.assertContainsRe(str(err), "^remote server out of mem")
 
2880
 
2737
2881
 
2738
2882
class TestErrorTranslationBase(tests.TestCaseWithMemoryTransport):
2739
2883
    """Base class for unit tests for bzrlib.remote._translate_error."""
2812
2956
            detail='extra detail')
2813
2957
        self.assertEqual(expected_error, translated_error)
2814
2958
 
 
2959
    def test_norepository(self):
 
2960
        bzrdir = self.make_bzrdir('')
 
2961
        translated_error = self.translateTuple(('norepository',),
 
2962
            bzrdir=bzrdir)
 
2963
        expected_error = errors.NoRepositoryPresent(bzrdir)
 
2964
        self.assertEqual(expected_error, translated_error)
 
2965
 
2815
2966
    def test_LockContention(self):
2816
2967
        translated_error = self.translateTuple(('LockContention',))
2817
2968
        expected_error = errors.LockContention('(remote lock)')
2845
2996
        expected_error = errors.DivergedBranches(branch, other_branch)
2846
2997
        self.assertEqual(expected_error, translated_error)
2847
2998
 
 
2999
    def test_NotStacked(self):
 
3000
        branch = self.make_branch('')
 
3001
        translated_error = self.translateTuple(('NotStacked',), branch=branch)
 
3002
        expected_error = errors.NotStacked(branch)
 
3003
        self.assertEqual(expected_error, translated_error)
 
3004
 
2848
3005
    def test_ReadError_no_args(self):
2849
3006
        path = 'a path'
2850
3007
        translated_error = self.translateTuple(('ReadError',), path=path)
2866
3023
 
2867
3024
    def test_PermissionDenied_no_args(self):
2868
3025
        path = 'a path'
2869
 
        translated_error = self.translateTuple(('PermissionDenied',), path=path)
 
3026
        translated_error = self.translateTuple(('PermissionDenied',),
 
3027
            path=path)
2870
3028
        expected_error = errors.PermissionDenied(path)
2871
3029
        self.assertEqual(expected_error, translated_error)
2872
3030
 
2895
3053
        expected_error = errors.PermissionDenied(path, extra)
2896
3054
        self.assertEqual(expected_error, translated_error)
2897
3055
 
 
3056
    # GZ 2011-03-02: TODO test for PermissionDenied with non-ascii 'extra'
 
3057
 
 
3058
    def test_NoSuchFile_context_path(self):
 
3059
        local_path = "local path"
 
3060
        translated_error = self.translateTuple(('ReadError', "remote path"),
 
3061
            path=local_path)
 
3062
        expected_error = errors.ReadError(local_path)
 
3063
        self.assertEqual(expected_error, translated_error)
 
3064
 
 
3065
    def test_NoSuchFile_without_context(self):
 
3066
        remote_path = "remote path"
 
3067
        translated_error = self.translateTuple(('ReadError', remote_path))
 
3068
        expected_error = errors.ReadError(remote_path)
 
3069
        self.assertEqual(expected_error, translated_error)
 
3070
 
 
3071
    def test_ReadOnlyError(self):
 
3072
        translated_error = self.translateTuple(('ReadOnlyError',))
 
3073
        expected_error = errors.TransportNotPossible("readonly transport")
 
3074
        self.assertEqual(expected_error, translated_error)
 
3075
 
 
3076
    def test_MemoryError(self):
 
3077
        translated_error = self.translateTuple(('MemoryError',))
 
3078
        self.assertStartsWith(str(translated_error),
 
3079
            "remote server out of memory")
 
3080
 
 
3081
    def test_generic_IndexError_no_classname(self):
 
3082
        err = errors.ErrorFromSmartServer(('error', "list index out of range"))
 
3083
        translated_error = self.translateErrorFromSmartServer(err)
 
3084
        expected_error = errors.UnknownErrorFromSmartServer(err)
 
3085
        self.assertEqual(expected_error, translated_error)
 
3086
 
 
3087
    # GZ 2011-03-02: TODO test generic non-ascii error string
 
3088
 
 
3089
    def test_generic_KeyError(self):
 
3090
        err = errors.ErrorFromSmartServer(('error', 'KeyError', "1"))
 
3091
        translated_error = self.translateErrorFromSmartServer(err)
 
3092
        expected_error = errors.UnknownErrorFromSmartServer(err)
 
3093
        self.assertEqual(expected_error, translated_error)
 
3094
 
2898
3095
 
2899
3096
class TestErrorTranslationRobustness(TestErrorTranslationBase):
2900
3097
    """Unit tests for bzrlib.remote._translate_error's robustness.
3142
3339
 
3143
3340
    def test_copy_content_into_avoids_revision_history(self):
3144
3341
        local = self.make_branch('local')
3145
 
        remote_backing_tree = self.make_branch_and_tree('remote')
3146
 
        remote_backing_tree.commit("Commit.")
 
3342
        builder = self.make_branch_builder('remote')
 
3343
        builder.build_commit(message="Commit.")
3147
3344
        remote_branch_url = self.smart_server.get_url() + 'remote'
3148
3345
        remote_branch = bzrdir.BzrDir.open(remote_branch_url).open_branch()
3149
3346
        local.repository.fetch(remote_branch.repository)
3150
3347
        self.hpss_calls = []
3151
3348
        remote_branch.copy_content_into(local)
3152
3349
        self.assertFalse('Branch.revision_history' in self.hpss_calls)
 
3350
 
 
3351
    def test_fetch_everything_needs_just_one_call(self):
 
3352
        local = self.make_branch('local')
 
3353
        builder = self.make_branch_builder('remote')
 
3354
        builder.build_commit(message="Commit.")
 
3355
        remote_branch_url = self.smart_server.get_url() + 'remote'
 
3356
        remote_branch = bzrdir.BzrDir.open(remote_branch_url).open_branch()
 
3357
        self.hpss_calls = []
 
3358
        local.repository.fetch(remote_branch.repository,
 
3359
                fetch_spec=graph.EverythingResult(remote_branch.repository))
 
3360
        self.assertEqual(['Repository.get_stream_1.19'], self.hpss_calls)
 
3361
 
 
3362
    def override_verb(self, verb_name, verb):
 
3363
        request_handlers = request.request_handlers
 
3364
        orig_verb = request_handlers.get(verb_name)
 
3365
        request_handlers.register(verb_name, verb, override_existing=True)
 
3366
        self.addCleanup(request_handlers.register, verb_name, orig_verb,
 
3367
                override_existing=True)
 
3368
 
 
3369
    def test_fetch_everything_backwards_compat(self):
 
3370
        """Can fetch with EverythingResult even with pre 2.4 servers.
 
3371
        
 
3372
        Pre-2.4 do not support 'everything' searches with the
 
3373
        Repository.get_stream_1.19 verb.
 
3374
        """
 
3375
        verb_log = []
 
3376
        class OldGetStreamVerb(SmartServerRepositoryGetStream_1_19):
 
3377
            """A version of the Repository.get_stream_1.19 verb patched to
 
3378
            reject 'everything' searches the way 2.3 and earlier do.
 
3379
            """
 
3380
            def recreate_search(self, repository, search_bytes, discard_excess=False):
 
3381
                verb_log.append(search_bytes.split('\n', 1)[0])
 
3382
                if search_bytes == 'everything':
 
3383
                    return (None, request.FailedSmartServerResponse(('BadSearch',)))
 
3384
                return super(OldGetStreamVerb,
 
3385
                        self).recreate_search(repository, search_bytes,
 
3386
                            discard_excess=discard_excess)
 
3387
        self.override_verb('Repository.get_stream_1.19', OldGetStreamVerb)
 
3388
        local = self.make_branch('local')
 
3389
        builder = self.make_branch_builder('remote')
 
3390
        builder.build_commit(message="Commit.")
 
3391
        remote_branch_url = self.smart_server.get_url() + 'remote'
 
3392
        remote_branch = bzrdir.BzrDir.open(remote_branch_url).open_branch()
 
3393
        self.hpss_calls = []
 
3394
        local.repository.fetch(remote_branch.repository,
 
3395
                fetch_spec=graph.EverythingResult(remote_branch.repository))
 
3396
        # make sure the overridden verb was used
 
3397
        self.assertLength(1, verb_log)
 
3398
        # more than one HPSS call is needed, but because it's a VFS callback
 
3399
        # its hard to predict exactly how many.
 
3400
        self.assertTrue(len(self.hpss_calls) > 1)
 
3401