/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
2018.18.1 by Martin Pool
Add stub Repository.tarball smart method
1
# Copyright (C) 2006, 2007 Canonical Ltd
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
2
#
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
2748.4.1 by Andrew Bennetts
Implement a ChunkedBodyDecoder.
17
"""Tests for the smart wire/domain protocol.
18
19
This module contains tests for the domain-level smart requests and responses,
3015.2.12 by Robert Collins
Make test_smart use specific formats as needed to exercise locked and unlocked repositories.
20
such as the 'Branch.lock_write' request. Many of these use specific disk
21
formats to exercise calls that only make sense for formats with specific
22
properties.
2748.4.1 by Andrew Bennetts
Implement a ChunkedBodyDecoder.
23
24
Tests for low-level protocol encoding are found in test_smart_transport.
25
"""
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
26
3211.5.2 by Robert Collins
Change RemoteRepository.get_parent_map to use bz2 not gzip for compression.
27
import bz2
2692.1.18 by Andrew Bennetts
Merge from bzr.dev.
28
from cStringIO import StringIO
2018.18.2 by Martin Pool
smart method Repository.tarball actually returns the tarball
29
import tarfile
30
2692.1.2 by Andrew Bennetts
Merge from bzr.dev.
31
from bzrlib import (
32
    bzrdir,
33
    errors,
34
    pack,
35
    smart,
36
    tests,
37
    urlutils,
38
    )
3577.1.1 by Andrew Bennetts
Cherry-pick TipChangeRejected changes from pre-branch-tip-changed-hook loom.
39
from bzrlib.branch import Branch, BranchReferenceFormat
2692.1.22 by Andrew Bennetts
Reinstate imports needed to run test_smart alone.
40
import bzrlib.smart.branch
4070.2.3 by Robert Collins
Get BzrDir.cloning_metadir working.
41
import bzrlib.smart.bzrdir, bzrlib.smart.bzrdir as smart_dir
42
import bzrlib.smart.packrepository
2692.1.22 by Andrew Bennetts
Reinstate imports needed to run test_smart alone.
43
import bzrlib.smart.repository
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
44
from bzrlib.smart.request import (
45
    FailedSmartServerResponse,
46
    SmartServerRequest,
47
    SmartServerResponse,
48
    SuccessfulSmartServerResponse,
49
    )
3221.3.2 by Robert Collins
* New remote method ``RemoteBzrDir.find_repositoryV2`` adding support for
50
from bzrlib.tests import (
51
    split_suite_by_re,
52
    )
2692.1.3 by Andrew Bennetts
Fix imports so that tests in test_smart.py can be run alone.
53
from bzrlib.transport import chroot, get_transport
2535.3.15 by Andrew Bennetts
Add KnitVersionedFile.get_stream_as_bytes, start smart implementation of RemoteRepository.get_data_stream.
54
from bzrlib.util import bencode
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
55
56
3221.3.2 by Robert Collins
* New remote method ``RemoteBzrDir.find_repositoryV2`` adding support for
57
def load_tests(standard_tests, module, loader):
58
    """Multiply tests version and protocol consistency."""
59
    # FindRepository tests.
60
    bzrdir_mod = bzrlib.smart.bzrdir
4084.5.1 by Robert Collins
Bulk update all test adaptation into a single approach, using multiply_tests rather than test adapters.
61
    scenarios = [
3221.3.2 by Robert Collins
* New remote method ``RemoteBzrDir.find_repositoryV2`` adding support for
62
        ("find_repository", {
63
            "_request_class":bzrdir_mod.SmartServerRequestFindRepositoryV1}),
64
        ("find_repositoryV2", {
65
            "_request_class":bzrdir_mod.SmartServerRequestFindRepositoryV2}),
4053.1.4 by Robert Collins
Move the fetch control attributes from Repository to RepositoryFormat.
66
        ("find_repositoryV3", {
67
            "_request_class":bzrdir_mod.SmartServerRequestFindRepositoryV3}),
3221.3.2 by Robert Collins
* New remote method ``RemoteBzrDir.find_repositoryV2`` adding support for
68
        ]
69
    to_adapt, result = split_suite_by_re(standard_tests,
70
        "TestSmartServerRequestFindRepository")
71
    v2_only, v1_and_2 = split_suite_by_re(to_adapt,
72
        "_v2")
4084.5.1 by Robert Collins
Bulk update all test adaptation into a single approach, using multiply_tests rather than test adapters.
73
    tests.multiply_tests(v1_and_2, scenarios, result)
74
    # The first scenario is only applicable to v1 protocols, it is deleted
75
    # since.
76
    tests.multiply_tests(v2_only, scenarios[1:], result)
3221.3.2 by Robert Collins
* New remote method ``RemoteBzrDir.find_repositoryV2`` adding support for
77
    return result
78
79
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
80
class TestCaseWithChrootedTransport(tests.TestCaseWithTransport):
81
82
    def setUp(self):
83
        tests.TestCaseWithTransport.setUp(self)
84
        self._chroot_server = None
85
86
    def get_transport(self, relpath=None):
87
        if self._chroot_server is None:
88
            backing_transport = tests.TestCaseWithTransport.get_transport(self)
89
            self._chroot_server = chroot.ChrootServer(backing_transport)
90
            self._chroot_server.setUp()
91
            self.addCleanup(self._chroot_server.tearDown)
92
        t = get_transport(self._chroot_server.get_url())
93
        if relpath is not None:
94
            t = t.clone(relpath)
95
        return t
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
96
97
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
98
class TestCaseWithSmartMedium(tests.TestCaseWithTransport):
99
100
    def setUp(self):
101
        super(TestCaseWithSmartMedium, self).setUp()
102
        # We're allowed to set  the transport class here, so that we don't use
103
        # the default or a parameterized class, but rather use the
104
        # TestCaseWithTransport infrastructure to set up a smart server and
105
        # transport.
3245.4.28 by Andrew Bennetts
Remove another XXX, and include test ID in smart server thread names.
106
        self.transport_server = self.make_transport_server
107
108
    def make_transport_server(self):
109
        return smart.server.SmartTCPServer_for_testing('-' + self.id())
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
110
111
    def get_smart_medium(self):
112
        """Get a smart medium to use in tests."""
113
        return self.get_transport().get_smart_medium()
114
115
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
116
class TestSmartServerResponse(tests.TestCase):
117
118
    def test__eq__(self):
119
        self.assertEqual(SmartServerResponse(('ok', )),
120
            SmartServerResponse(('ok', )))
121
        self.assertEqual(SmartServerResponse(('ok', ), 'body'),
122
            SmartServerResponse(('ok', ), 'body'))
123
        self.assertNotEqual(SmartServerResponse(('ok', )),
124
            SmartServerResponse(('notok', )))
125
        self.assertNotEqual(SmartServerResponse(('ok', ), 'body'),
126
            SmartServerResponse(('ok', )))
2018.5.41 by Robert Collins
Fix SmartServerResponse.__eq__ to handle None.
127
        self.assertNotEqual(None,
128
            SmartServerResponse(('ok', )))
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
129
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
130
    def test__str__(self):
131
        """SmartServerResponses can be stringified."""
132
        self.assertEqual(
3691.2.6 by Martin Pool
Disable RemoteBranch stacking, but get get_stacked_on_url working, and passing back exceptions
133
            "<SuccessfulSmartServerResponse args=('args',) body='body'>",
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
134
            str(SuccessfulSmartServerResponse(('args',), 'body')))
135
        self.assertEqual(
3691.2.6 by Martin Pool
Disable RemoteBranch stacking, but get get_stacked_on_url working, and passing back exceptions
136
            "<FailedSmartServerResponse args=('args',) body='body'>",
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
137
            str(FailedSmartServerResponse(('args',), 'body')))
138
139
140
class TestSmartServerRequest(tests.TestCaseWithMemoryTransport):
141
142
    def test_translate_client_path(self):
143
        transport = self.get_transport()
144
        request = SmartServerRequest(transport, 'foo/')
145
        self.assertEqual('./', request.translate_client_path('foo/'))
146
        self.assertRaises(
147
            errors.InvalidURLJoin, request.translate_client_path, 'foo/..')
148
        self.assertRaises(
149
            errors.PathNotChild, request.translate_client_path, '/')
150
        self.assertRaises(
151
            errors.PathNotChild, request.translate_client_path, 'bar/')
152
        self.assertEqual('./baz', request.translate_client_path('foo/baz'))
153
154
    def test_transport_from_client_path(self):
155
        transport = self.get_transport()
156
        request = SmartServerRequest(transport, 'foo/')
157
        self.assertEqual(
158
            transport.base,
159
            request.transport_from_client_path('foo/').base)
160
161
4070.2.3 by Robert Collins
Get BzrDir.cloning_metadir working.
162
class TestSmartServerBzrDirRequestCloningMetaDir(
163
    tests.TestCaseWithMemoryTransport):
164
    """Tests for BzrDir.cloning_metadir."""
165
166
    def test_cloning_metadir(self):
167
        """When there is a bzrdir present, the call succeeds."""
168
        backing = self.get_transport()
169
        dir = self.make_bzrdir('.')
170
        local_result = dir.cloning_metadir()
171
        request_class = smart_dir.SmartServerBzrDirRequestCloningMetaDir
172
        request = request_class(backing)
173
        expected = SuccessfulSmartServerResponse(
174
            (local_result.network_name(),
175
            local_result.repository_format.network_name(),
4084.2.2 by Robert Collins
Review feedback.
176
            ('branch', local_result.get_branch_format().network_name())))
4070.7.4 by Andrew Bennetts
Deal with branch references better in BzrDir.cloning_metadir RPC (changes protocol).
177
        self.assertEqual(expected, request.execute('', 'False'))
178
179
    def test_cloning_metadir_reference(self):
180
        """The request works when bzrdir contains a branch reference."""
181
        backing = self.get_transport()
182
        referenced_branch = self.make_branch('referenced')
183
        dir = self.make_bzrdir('.')
184
        local_result = dir.cloning_metadir()
185
        reference = BranchReferenceFormat().initialize(dir, referenced_branch)
186
        reference_url = BranchReferenceFormat().get_reference(dir)
187
        # The server shouldn't try to follow the branch reference, so it's fine
188
        # if the referenced branch isn't reachable.
189
        backing.rename('referenced', 'moved')
190
        request_class = smart_dir.SmartServerBzrDirRequestCloningMetaDir
191
        request = request_class(backing)
192
        expected = SuccessfulSmartServerResponse(
193
            (local_result.network_name(),
194
            local_result.repository_format.network_name(),
4084.2.2 by Robert Collins
Review feedback.
195
            ('ref', reference_url)))
4070.2.3 by Robert Collins
Get BzrDir.cloning_metadir working.
196
        self.assertEqual(expected, request.execute('', 'False'))
197
198
4017.3.2 by Robert Collins
Reduce the number of round trips required to create a repository over the network.
199
class TestSmartServerRequestCreateRepository(tests.TestCaseWithMemoryTransport):
200
    """Tests for BzrDir.create_repository."""
201
202
    def test_makes_repository(self):
203
        """When there is a bzrdir present, the call succeeds."""
204
        backing = self.get_transport()
205
        self.make_bzrdir('.')
206
        request_class = bzrlib.smart.bzrdir.SmartServerRequestCreateRepository
207
        request = request_class(backing)
208
        reference_bzrdir_format = bzrdir.format_registry.get('default')()
209
        reference_format = reference_bzrdir_format.repository_format
210
        network_name = reference_format.network_name()
211
        expected = SuccessfulSmartServerResponse(
212
            ('ok', 'no', 'no', 'no', network_name))
213
        self.assertEqual(expected, request.execute('', network_name, 'True'))
214
215
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
216
class TestSmartServerRequestFindRepository(tests.TestCaseWithMemoryTransport):
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
217
    """Tests for BzrDir.find_repository."""
2018.5.34 by Robert Collins
Get test_remote.BasicRemoteObjectTests.test_open_remote_branch passing by implementing a remote method BzrDir.find_repository.
218
219
    def test_no_repository(self):
220
        """When there is no repository to be found, ('norepository', ) is returned."""
221
        backing = self.get_transport()
3221.3.2 by Robert Collins
* New remote method ``RemoteBzrDir.find_repositoryV2`` adding support for
222
        request = self._request_class(backing)
2018.5.34 by Robert Collins
Get test_remote.BasicRemoteObjectTests.test_open_remote_branch passing by implementing a remote method BzrDir.find_repository.
223
        self.make_bzrdir('.')
224
        self.assertEqual(SmartServerResponse(('norepository', )),
2692.1.19 by Andrew Bennetts
Tweak for consistency suggested by John's review.
225
            request.execute(''))
2018.5.34 by Robert Collins
Get test_remote.BasicRemoteObjectTests.test_open_remote_branch passing by implementing a remote method BzrDir.find_repository.
226
227
    def test_nonshared_repository(self):
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
228
        # nonshared repositorys only allow 'find' to return a handle when the
229
        # path the repository is being searched on is the same as that that
2018.5.34 by Robert Collins
Get test_remote.BasicRemoteObjectTests.test_open_remote_branch passing by implementing a remote method BzrDir.find_repository.
230
        # the repository is at.
231
        backing = self.get_transport()
3221.3.2 by Robert Collins
* New remote method ``RemoteBzrDir.find_repositoryV2`` adding support for
232
        request = self._request_class(backing)
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
233
        result = self._make_repository_and_result()
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
234
        self.assertEqual(result, request.execute(''))
2018.5.34 by Robert Collins
Get test_remote.BasicRemoteObjectTests.test_open_remote_branch passing by implementing a remote method BzrDir.find_repository.
235
        self.make_bzrdir('subdir')
236
        self.assertEqual(SmartServerResponse(('norepository', )),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
237
            request.execute('subdir'))
2018.5.34 by Robert Collins
Get test_remote.BasicRemoteObjectTests.test_open_remote_branch passing by implementing a remote method BzrDir.find_repository.
238
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
239
    def _make_repository_and_result(self, shared=False, format=None):
240
        """Convenience function to setup a repository.
241
242
        :result: The SmartServerResponse to expect when opening it.
243
        """
244
        repo = self.make_repository('.', shared=shared, format=format)
245
        if repo.supports_rich_root():
2018.5.166 by Andrew Bennetts
Small changes in response to Aaron's review.
246
            rich_root = 'yes'
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
247
        else:
2018.5.166 by Andrew Bennetts
Small changes in response to Aaron's review.
248
            rich_root = 'no'
2018.5.138 by Robert Collins
Merge bzr.dev.
249
        if repo._format.supports_tree_reference:
2018.5.166 by Andrew Bennetts
Small changes in response to Aaron's review.
250
            subtrees = 'yes'
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
251
        else:
2018.5.166 by Andrew Bennetts
Small changes in response to Aaron's review.
252
            subtrees = 'no'
4053.1.4 by Robert Collins
Move the fetch control attributes from Repository to RepositoryFormat.
253
        if (smart.bzrdir.SmartServerRequestFindRepositoryV3 ==
254
            self._request_class):
255
            return SuccessfulSmartServerResponse(
256
                ('ok', '', rich_root, subtrees, 'no',
257
                 repo._format.network_name()))
258
        elif (smart.bzrdir.SmartServerRequestFindRepositoryV2 ==
3221.3.2 by Robert Collins
* New remote method ``RemoteBzrDir.find_repositoryV2`` adding support for
259
            self._request_class):
260
            # All tests so far are on formats, and for non-external
261
            # repositories.
262
            return SuccessfulSmartServerResponse(
263
                ('ok', '', rich_root, subtrees, 'no'))
264
        else:
265
            return SuccessfulSmartServerResponse(('ok', '', rich_root, subtrees))
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
266
2018.5.34 by Robert Collins
Get test_remote.BasicRemoteObjectTests.test_open_remote_branch passing by implementing a remote method BzrDir.find_repository.
267
    def test_shared_repository(self):
268
        """When there is a shared repository, we get 'ok', 'relpath-to-repo'."""
269
        backing = self.get_transport()
3221.3.2 by Robert Collins
* New remote method ``RemoteBzrDir.find_repositoryV2`` adding support for
270
        request = self._request_class(backing)
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
271
        result = self._make_repository_and_result(shared=True)
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
272
        self.assertEqual(result, request.execute(''))
2018.5.34 by Robert Collins
Get test_remote.BasicRemoteObjectTests.test_open_remote_branch passing by implementing a remote method BzrDir.find_repository.
273
        self.make_bzrdir('subdir')
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
274
        result2 = SmartServerResponse(result.args[0:1] + ('..', ) + result.args[2:])
275
        self.assertEqual(result2,
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
276
            request.execute('subdir'))
2018.5.34 by Robert Collins
Get test_remote.BasicRemoteObjectTests.test_open_remote_branch passing by implementing a remote method BzrDir.find_repository.
277
        self.make_bzrdir('subdir/deeper')
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
278
        result3 = SmartServerResponse(result.args[0:1] + ('../..', ) + result.args[2:])
279
        self.assertEqual(result3,
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
280
            request.execute('subdir/deeper'))
2018.5.34 by Robert Collins
Get test_remote.BasicRemoteObjectTests.test_open_remote_branch passing by implementing a remote method BzrDir.find_repository.
281
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
282
    def test_rich_root_and_subtree_encoding(self):
283
        """Test for the format attributes for rich root and subtree support."""
284
        backing = self.get_transport()
3221.3.2 by Robert Collins
* New remote method ``RemoteBzrDir.find_repositoryV2`` adding support for
285
        request = self._request_class(backing)
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
286
        result = self._make_repository_and_result(format='dirstate-with-subtree')
287
        # check the test will be valid
2018.5.166 by Andrew Bennetts
Small changes in response to Aaron's review.
288
        self.assertEqual('yes', result.args[2])
289
        self.assertEqual('yes', result.args[3])
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
290
        self.assertEqual(result, request.execute(''))
291
3221.3.2 by Robert Collins
* New remote method ``RemoteBzrDir.find_repositoryV2`` adding support for
292
    def test_supports_external_lookups_no_v2(self):
293
        """Test for the supports_external_lookups attribute."""
294
        backing = self.get_transport()
295
        request = self._request_class(backing)
296
        result = self._make_repository_and_result(format='dirstate-with-subtree')
297
        # check the test will be valid
298
        self.assertEqual('no', result.args[4])
2692.1.24 by Andrew Bennetts
Merge from bzr.dev.
299
        self.assertEqual(result, request.execute(''))
300
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
301
302
class TestSmartServerRequestInitializeBzrDir(tests.TestCaseWithMemoryTransport):
2018.5.42 by Robert Collins
Various hopefully improvements, but wsgi is broken, handing over to spiv :).
303
304
    def test_empty_dir(self):
305
        """Initializing an empty dir should succeed and do it."""
306
        backing = self.get_transport()
307
        request = smart.bzrdir.SmartServerRequestInitializeBzrDir(backing)
308
        self.assertEqual(SmartServerResponse(('ok', )),
2692.1.20 by Andrew Bennetts
Tweak for consistency suggested by John's review.
309
            request.execute(''))
2018.5.42 by Robert Collins
Various hopefully improvements, but wsgi is broken, handing over to spiv :).
310
        made_dir = bzrdir.BzrDir.open_from_transport(backing)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
311
        # no branch, tree or repository is expected with the current
2018.5.42 by Robert Collins
Various hopefully improvements, but wsgi is broken, handing over to spiv :).
312
        # default formart.
313
        self.assertRaises(errors.NoWorkingTree, made_dir.open_workingtree)
314
        self.assertRaises(errors.NotBranchError, made_dir.open_branch)
315
        self.assertRaises(errors.NoRepositoryPresent, made_dir.open_repository)
316
317
    def test_missing_dir(self):
318
        """Initializing a missing directory should fail like the bzrdir api."""
319
        backing = self.get_transport()
320
        request = smart.bzrdir.SmartServerRequestInitializeBzrDir(backing)
321
        self.assertRaises(errors.NoSuchFile,
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
322
            request.execute, 'subdir')
2018.5.42 by Robert Collins
Various hopefully improvements, but wsgi is broken, handing over to spiv :).
323
324
    def test_initialized_dir(self):
325
        """Initializing an extant bzrdir should fail like the bzrdir api."""
326
        backing = self.get_transport()
327
        request = smart.bzrdir.SmartServerRequestInitializeBzrDir(backing)
328
        self.make_bzrdir('subdir')
329
        self.assertRaises(errors.FileExists,
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
330
            request.execute, 'subdir')
331
332
333
class TestSmartServerRequestOpenBranch(TestCaseWithChrootedTransport):
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
334
335
    def test_no_branch(self):
336
        """When there is no branch, ('nobranch', ) is returned."""
337
        backing = self.get_transport()
338
        request = smart.bzrdir.SmartServerRequestOpenBranch(backing)
339
        self.make_bzrdir('.')
340
        self.assertEqual(SmartServerResponse(('nobranch', )),
2692.1.20 by Andrew Bennetts
Tweak for consistency suggested by John's review.
341
            request.execute(''))
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
342
343
    def test_branch(self):
344
        """When there is a branch, 'ok' is returned."""
345
        backing = self.get_transport()
346
        request = smart.bzrdir.SmartServerRequestOpenBranch(backing)
347
        self.make_branch('.')
348
        self.assertEqual(SmartServerResponse(('ok', '')),
2692.1.20 by Andrew Bennetts
Tweak for consistency suggested by John's review.
349
            request.execute(''))
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
350
351
    def test_branch_reference(self):
352
        """When there is a branch reference, the reference URL is returned."""
353
        backing = self.get_transport()
354
        request = smart.bzrdir.SmartServerRequestOpenBranch(backing)
355
        branch = self.make_branch('branch')
356
        checkout = branch.create_checkout('reference',lightweight=True)
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
357
        reference_url = BranchReferenceFormat().get_reference(checkout.bzrdir)
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
358
        self.assertFileEqual(reference_url, 'reference/.bzr/branch/location')
359
        self.assertEqual(SmartServerResponse(('ok', reference_url)),
2692.1.20 by Andrew Bennetts
Tweak for consistency suggested by John's review.
360
            request.execute('reference'))
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
361
362
4084.2.1 by Robert Collins
Make accessing a branch.tags.get_tag_dict use a smart[er] method rather than VFS calls and real objects.
363
class TestSmartServerRequestOpenBranchV2(TestCaseWithChrootedTransport):
364
365
    def test_no_branch(self):
366
        """When there is no branch, ('nobranch', ) is returned."""
367
        backing = self.get_transport()
368
        self.make_bzrdir('.')
369
        request = smart.bzrdir.SmartServerRequestOpenBranchV2(backing)
370
        self.assertEqual(SmartServerResponse(('nobranch', )),
371
            request.execute(''))
372
373
    def test_branch(self):
374
        """When there is a branch, 'ok' is returned."""
375
        backing = self.get_transport()
376
        expected = self.make_branch('.')._format.network_name()
377
        request = smart.bzrdir.SmartServerRequestOpenBranchV2(backing)
378
        self.assertEqual(SuccessfulSmartServerResponse(('branch', expected)),
379
            request.execute(''))
380
381
    def test_branch_reference(self):
382
        """When there is a branch reference, the reference URL is returned."""
383
        backing = self.get_transport()
384
        request = smart.bzrdir.SmartServerRequestOpenBranchV2(backing)
385
        branch = self.make_branch('branch')
386
        checkout = branch.create_checkout('reference',lightweight=True)
387
        reference_url = BranchReferenceFormat().get_reference(checkout.bzrdir)
388
        self.assertFileEqual(reference_url, 'reference/.bzr/branch/location')
389
        self.assertEqual(SuccessfulSmartServerResponse(('ref', reference_url)),
390
            request.execute('reference'))
391
392
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
393
class TestSmartServerRequestRevisionHistory(tests.TestCaseWithMemoryTransport):
2018.5.38 by Robert Collins
Implement RemoteBranch.revision_history().
394
395
    def test_empty(self):
396
        """For an empty branch, the body is empty."""
397
        backing = self.get_transport()
398
        request = smart.branch.SmartServerRequestRevisionHistory(backing)
399
        self.make_branch('.')
400
        self.assertEqual(SmartServerResponse(('ok', ), ''),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
401
            request.execute(''))
2018.5.38 by Robert Collins
Implement RemoteBranch.revision_history().
402
403
    def test_not_empty(self):
404
        """For a non-empty branch, the body is empty."""
405
        backing = self.get_transport()
406
        request = smart.branch.SmartServerRequestRevisionHistory(backing)
407
        tree = self.make_branch_and_memory_tree('.')
408
        tree.lock_write()
409
        tree.add('')
410
        r1 = tree.commit('1st commit')
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
411
        r2 = tree.commit('2nd commit', rev_id=u'\xc8'.encode('utf-8'))
2018.5.38 by Robert Collins
Implement RemoteBranch.revision_history().
412
        tree.unlock()
2018.5.83 by Andrew Bennetts
Fix some test failures caused by the switch from unicode to UTF-8-encoded strs for revision IDs.
413
        self.assertEqual(
414
            SmartServerResponse(('ok', ), ('\x00'.join([r1, r2]))),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
415
            request.execute(''))
416
417
418
class TestSmartServerBranchRequest(tests.TestCaseWithMemoryTransport):
2018.5.49 by Wouter van Heyst
Refactor SmartServerBranchRequest out from SmartServerRequestRevisionHistory to
419
420
    def test_no_branch(self):
421
        """When there is a bzrdir and no branch, NotBranchError is raised."""
422
        backing = self.get_transport()
423
        request = smart.branch.SmartServerBranchRequest(backing)
424
        self.make_bzrdir('.')
425
        self.assertRaises(errors.NotBranchError,
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
426
            request.execute, '')
2018.5.49 by Wouter van Heyst
Refactor SmartServerBranchRequest out from SmartServerRequestRevisionHistory to
427
2018.5.38 by Robert Collins
Implement RemoteBranch.revision_history().
428
    def test_branch_reference(self):
429
        """When there is a branch reference, NotBranchError is raised."""
430
        backing = self.get_transport()
2018.5.49 by Wouter van Heyst
Refactor SmartServerBranchRequest out from SmartServerRequestRevisionHistory to
431
        request = smart.branch.SmartServerBranchRequest(backing)
2018.5.38 by Robert Collins
Implement RemoteBranch.revision_history().
432
        branch = self.make_branch('branch')
433
        checkout = branch.create_checkout('reference',lightweight=True)
434
        self.assertRaises(errors.NotBranchError,
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
435
            request.execute, 'checkout')
436
437
438
class TestSmartServerBranchRequestLastRevisionInfo(tests.TestCaseWithMemoryTransport):
2018.5.50 by Wouter van Heyst
Add SmartServerBranchRequestLastRevisionInfo method.
439
440
    def test_empty(self):
2018.5.170 by Andrew Bennetts
Use 'null:' instead of '' to mean NULL_REVISION on the wire.
441
        """For an empty branch, the result is ('ok', '0', 'null:')."""
2018.5.50 by Wouter van Heyst
Add SmartServerBranchRequestLastRevisionInfo method.
442
        backing = self.get_transport()
443
        request = smart.branch.SmartServerBranchRequestLastRevisionInfo(backing)
444
        self.make_branch('.')
2018.5.170 by Andrew Bennetts
Use 'null:' instead of '' to mean NULL_REVISION on the wire.
445
        self.assertEqual(SmartServerResponse(('ok', '0', 'null:')),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
446
            request.execute(''))
2018.5.50 by Wouter van Heyst
Add SmartServerBranchRequestLastRevisionInfo method.
447
448
    def test_not_empty(self):
449
        """For a non-empty branch, the result is ('ok', 'revno', 'revid')."""
450
        backing = self.get_transport()
451
        request = smart.branch.SmartServerBranchRequestLastRevisionInfo(backing)
452
        tree = self.make_branch_and_memory_tree('.')
453
        tree.lock_write()
454
        tree.add('')
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
455
        rev_id_utf8 = u'\xc8'.encode('utf-8')
2018.5.50 by Wouter van Heyst
Add SmartServerBranchRequestLastRevisionInfo method.
456
        r1 = tree.commit('1st commit')
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
457
        r2 = tree.commit('2nd commit', rev_id=rev_id_utf8)
2018.5.50 by Wouter van Heyst
Add SmartServerBranchRequestLastRevisionInfo method.
458
        tree.unlock()
459
        self.assertEqual(
2018.5.83 by Andrew Bennetts
Fix some test failures caused by the switch from unicode to UTF-8-encoded strs for revision IDs.
460
            SmartServerResponse(('ok', '2', rev_id_utf8)),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
461
            request.execute(''))
462
463
464
class TestSmartServerBranchRequestGetConfigFile(tests.TestCaseWithMemoryTransport):
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
465
466
    def test_default(self):
467
        """With no file, we get empty content."""
468
        backing = self.get_transport()
469
        request = smart.branch.SmartServerBranchGetConfigFile(backing)
470
        branch = self.make_branch('.')
471
        # there should be no file by default
472
        content = ''
473
        self.assertEqual(SmartServerResponse(('ok', ), content),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
474
            request.execute(''))
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
475
476
    def test_with_content(self):
477
        # SmartServerBranchGetConfigFile should return the content from
478
        # branch.control_files.get('branch.conf') for now - in the future it may
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
479
        # perform more complex processing.
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
480
        backing = self.get_transport()
481
        request = smart.branch.SmartServerBranchGetConfigFile(backing)
482
        branch = self.make_branch('.')
3407.2.5 by Martin Pool
Deprecate LockableFiles.put_utf8
483
        branch._transport.put_bytes('branch.conf', 'foo bar baz')
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
484
        self.assertEqual(SmartServerResponse(('ok', ), 'foo bar baz'),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
485
            request.execute(''))
486
487
3441.5.30 by Andrew Bennetts
Improve tests for all Branch.set_last_revision* verbs.
488
class SetLastRevisionTestBase(tests.TestCaseWithMemoryTransport):
489
    """Base test case for verbs that implement set_last_revision."""
490
491
    def setUp(self):
492
        tests.TestCaseWithMemoryTransport.setUp(self)
493
        backing_transport = self.get_transport()
494
        self.request = self.request_class(backing_transport)
495
        self.tree = self.make_branch_and_memory_tree('.')
496
497
    def lock_branch(self):
498
        b = self.tree.branch
499
        branch_token = b.lock_write()
500
        repo_token = b.repository.lock_write()
501
        b.repository.unlock()
502
        return branch_token, repo_token
503
504
    def unlock_branch(self):
505
        self.tree.branch.unlock()
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
506
3441.5.30 by Andrew Bennetts
Improve tests for all Branch.set_last_revision* verbs.
507
    def set_last_revision(self, revision_id, revno):
508
        branch_token, repo_token = self.lock_branch()
509
        response = self._set_last_revision(
510
            revision_id, revno, branch_token, repo_token)
511
        self.unlock_branch()
512
        return response
513
514
    def assertRequestSucceeds(self, revision_id, revno):
515
        response = self.set_last_revision(revision_id, revno)
516
        self.assertEqual(SuccessfulSmartServerResponse(('ok',)), response)
517
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
518
3441.5.30 by Andrew Bennetts
Improve tests for all Branch.set_last_revision* verbs.
519
class TestSetLastRevisionVerbMixin(object):
520
    """Mixin test case for verbs that implement set_last_revision."""
521
522
    def test_set_null_to_null(self):
523
        """An empty branch can have its last revision set to 'null:'."""
524
        self.assertRequestSucceeds('null:', 0)
525
526
    def test_NoSuchRevision(self):
527
        """If the revision_id is not present, the verb returns NoSuchRevision.
528
        """
529
        revision_id = 'non-existent revision'
530
        self.assertEqual(
531
            FailedSmartServerResponse(('NoSuchRevision', revision_id)),
532
            self.set_last_revision(revision_id, 1))
533
534
    def make_tree_with_two_commits(self):
535
        self.tree.lock_write()
536
        self.tree.add('')
537
        rev_id_utf8 = u'\xc8'.encode('utf-8')
538
        r1 = self.tree.commit('1st commit', rev_id=rev_id_utf8)
539
        r2 = self.tree.commit('2nd commit', rev_id='rev-2')
540
        self.tree.unlock()
541
542
    def test_branch_last_revision_info_is_updated(self):
543
        """A branch's tip can be set to a revision that is present in its
544
        repository.
545
        """
546
        # Make a branch with an empty revision history, but two revisions in
547
        # its repository.
548
        self.make_tree_with_two_commits()
549
        rev_id_utf8 = u'\xc8'.encode('utf-8')
550
        self.tree.branch.set_revision_history([])
551
        self.assertEqual(
552
            (0, 'null:'), self.tree.branch.last_revision_info())
553
        # We can update the branch to a revision that is present in the
554
        # repository.
555
        self.assertRequestSucceeds(rev_id_utf8, 1)
556
        self.assertEqual(
557
            (1, rev_id_utf8), self.tree.branch.last_revision_info())
558
559
    def test_branch_last_revision_info_rewind(self):
560
        """A branch's tip can be set to a revision that is an ancestor of the
561
        current tip.
562
        """
563
        self.make_tree_with_two_commits()
564
        rev_id_utf8 = u'\xc8'.encode('utf-8')
565
        self.assertEqual(
566
            (2, 'rev-2'), self.tree.branch.last_revision_info())
567
        self.assertRequestSucceeds(rev_id_utf8, 1)
568
        self.assertEqual(
569
            (1, rev_id_utf8), self.tree.branch.last_revision_info())
570
3577.1.1 by Andrew Bennetts
Cherry-pick TipChangeRejected changes from pre-branch-tip-changed-hook loom.
571
    def test_TipChangeRejected(self):
572
        """If a pre_change_branch_tip hook raises TipChangeRejected, the verb
573
        returns TipChangeRejected.
574
        """
575
        rejection_message = u'rejection message\N{INTERROBANG}'
576
        def hook_that_rejects(params):
577
            raise errors.TipChangeRejected(rejection_message)
578
        Branch.hooks.install_named_hook(
579
            'pre_change_branch_tip', hook_that_rejects, None)
580
        self.assertEqual(
581
            FailedSmartServerResponse(
582
                ('TipChangeRejected', rejection_message.encode('utf-8'))),
583
            self.set_last_revision('null:', 0))
584
3441.5.30 by Andrew Bennetts
Improve tests for all Branch.set_last_revision* verbs.
585
3441.5.6 by Andrew Bennetts
Greatly simplify RemoteBranch.update_revisions. Still needs more tests.
586
class TestSmartServerBranchRequestSetLastRevision(
3441.5.30 by Andrew Bennetts
Improve tests for all Branch.set_last_revision* verbs.
587
        SetLastRevisionTestBase, TestSetLastRevisionVerbMixin):
588
    """Tests for Branch.set_last_revision verb."""
3441.5.6 by Andrew Bennetts
Greatly simplify RemoteBranch.update_revisions. Still needs more tests.
589
590
    request_class = smart.branch.SmartServerBranchRequestSetLastRevision
591
3441.5.30 by Andrew Bennetts
Improve tests for all Branch.set_last_revision* verbs.
592
    def _set_last_revision(self, revision_id, revno, branch_token, repo_token):
593
        return self.request.execute(
594
            '', branch_token, repo_token, revision_id)
595
596
597
class TestSmartServerBranchRequestSetLastRevisionInfo(
598
        SetLastRevisionTestBase, TestSetLastRevisionVerbMixin):
599
    """Tests for Branch.set_last_revision_info verb."""
600
601
    request_class = smart.branch.SmartServerBranchRequestSetLastRevisionInfo
602
603
    def _set_last_revision(self, revision_id, revno, branch_token, repo_token):
604
        return self.request.execute(
605
            '', branch_token, repo_token, revno, revision_id)
606
607
    def test_NoSuchRevision(self):
608
        """Branch.set_last_revision_info does not have to return
609
        NoSuchRevision if the revision_id is absent.
610
        """
611
        raise tests.TestNotApplicable()
3441.5.6 by Andrew Bennetts
Greatly simplify RemoteBranch.update_revisions. Still needs more tests.
612
613
3441.5.25 by Andrew Bennetts
Rename Branch.set_last_revision_descendant verb to Branch.set_last_revision_ex. It's a cop out, but at least it's not misleading.
614
class TestSmartServerBranchRequestSetLastRevisionEx(
3441.5.30 by Andrew Bennetts
Improve tests for all Branch.set_last_revision* verbs.
615
        SetLastRevisionTestBase, TestSetLastRevisionVerbMixin):
616
    """Tests for Branch.set_last_revision_ex verb."""
3441.5.6 by Andrew Bennetts
Greatly simplify RemoteBranch.update_revisions. Still needs more tests.
617
3441.5.25 by Andrew Bennetts
Rename Branch.set_last_revision_descendant verb to Branch.set_last_revision_ex. It's a cop out, but at least it's not misleading.
618
    request_class = smart.branch.SmartServerBranchRequestSetLastRevisionEx
3441.5.6 by Andrew Bennetts
Greatly simplify RemoteBranch.update_revisions. Still needs more tests.
619
3441.5.30 by Andrew Bennetts
Improve tests for all Branch.set_last_revision* verbs.
620
    def _set_last_revision(self, revision_id, revno, branch_token, repo_token):
621
        return self.request.execute(
622
            '', branch_token, repo_token, revision_id, 0, 0)
623
624
    def assertRequestSucceeds(self, revision_id, revno):
625
        response = self.set_last_revision(revision_id, revno)
626
        self.assertEqual(
627
            SuccessfulSmartServerResponse(('ok', revno, revision_id)),
628
            response)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
629
3441.5.30 by Andrew Bennetts
Improve tests for all Branch.set_last_revision* verbs.
630
    def test_branch_last_revision_info_rewind(self):
631
        """A branch's tip can be set to a revision that is an ancestor of the
632
        current tip, but only if allow_overwrite_descendant is passed.
633
        """
634
        self.make_tree_with_two_commits()
3441.5.6 by Andrew Bennetts
Greatly simplify RemoteBranch.update_revisions. Still needs more tests.
635
        rev_id_utf8 = u'\xc8'.encode('utf-8')
3441.5.30 by Andrew Bennetts
Improve tests for all Branch.set_last_revision* verbs.
636
        self.assertEqual(
637
            (2, 'rev-2'), self.tree.branch.last_revision_info())
638
        # If allow_overwrite_descendant flag is 0, then trying to set the tip
639
        # to an older revision ID has no effect.
640
        branch_token, repo_token = self.lock_branch()
641
        response = self.request.execute(
642
            '', branch_token, repo_token, rev_id_utf8, 0, 0)
643
        self.assertEqual(
644
            SuccessfulSmartServerResponse(('ok', 2, 'rev-2')),
645
            response)
646
        self.assertEqual(
647
            (2, 'rev-2'), self.tree.branch.last_revision_info())
648
649
        # If allow_overwrite_descendant flag is 1, then setting the tip to an
650
        # ancestor works.
651
        response = self.request.execute(
652
            '', branch_token, repo_token, rev_id_utf8, 0, 1)
653
        self.assertEqual(
654
            SuccessfulSmartServerResponse(('ok', 1, rev_id_utf8)),
655
            response)
656
        self.unlock_branch()
657
        self.assertEqual(
658
            (1, rev_id_utf8), self.tree.branch.last_revision_info())
659
3441.5.31 by Andrew Bennetts
Add test for allow_diverged flag.
660
    def make_branch_with_divergent_history(self):
661
        """Make a branch with divergent history in its repo.
662
663
        The branch's tip will be 'child-2', and the repo will also contain
664
        'child-1', which diverges from a common base revision.
3441.5.30 by Andrew Bennetts
Improve tests for all Branch.set_last_revision* verbs.
665
        """
666
        self.tree.lock_write()
667
        self.tree.add('')
668
        r1 = self.tree.commit('1st commit')
669
        revno_1, revid_1 = self.tree.branch.last_revision_info()
670
        r2 = self.tree.commit('2nd commit', rev_id='child-1')
3441.5.6 by Andrew Bennetts
Greatly simplify RemoteBranch.update_revisions. Still needs more tests.
671
        # Undo the second commit
3441.5.30 by Andrew Bennetts
Improve tests for all Branch.set_last_revision* verbs.
672
        self.tree.branch.set_last_revision_info(revno_1, revid_1)
673
        self.tree.set_parent_ids([revid_1])
3441.5.6 by Andrew Bennetts
Greatly simplify RemoteBranch.update_revisions. Still needs more tests.
674
        # Make a new second commit, child-2.  child-2 has diverged from
675
        # child-1.
3441.5.30 by Andrew Bennetts
Improve tests for all Branch.set_last_revision* verbs.
676
        new_r2 = self.tree.commit('2nd commit', rev_id='child-2')
677
        self.tree.unlock()
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
678
3441.5.31 by Andrew Bennetts
Add test for allow_diverged flag.
679
    def test_not_allow_diverged(self):
680
        """If allow_diverged is not passed, then setting a divergent history
681
        returns a Diverged error.
682
        """
683
        self.make_branch_with_divergent_history()
3297.4.3 by Andrew Bennetts
Add more tests, handle NoSuchRevision in case the remote branch's format can raise it.
684
        self.assertEqual(
3441.5.30 by Andrew Bennetts
Improve tests for all Branch.set_last_revision* verbs.
685
            FailedSmartServerResponse(('Diverged',)),
686
            self.set_last_revision('child-1', 2))
687
        # The branch tip was not changed.
688
        self.assertEqual('child-2', self.tree.branch.last_revision())
2892.2.1 by Andrew Bennetts
Add Branch.set_last_revision_info smart method, and make the RemoteBranch client use it.
689
3441.5.31 by Andrew Bennetts
Add test for allow_diverged flag.
690
    def test_allow_diverged(self):
691
        """If allow_diverged is passed, then setting a divergent history
692
        succeeds.
693
        """
694
        self.make_branch_with_divergent_history()
695
        branch_token, repo_token = self.lock_branch()
696
        response = self.request.execute(
697
            '', branch_token, repo_token, 'child-1', 1, 0)
698
        self.assertEqual(
699
            SuccessfulSmartServerResponse(('ok', 2, 'child-1')),
700
            response)
701
        self.unlock_branch()
702
        # The branch tip was changed.
703
        self.assertEqual('child-1', self.tree.branch.last_revision())
704
2892.2.1 by Andrew Bennetts
Add Branch.set_last_revision_info smart method, and make the RemoteBranch client use it.
705
4078.2.1 by Robert Collins
Add a Branch.get_parent remote call for RemoteBranch.
706
class TestSmartServerBranchRequestGetParent(tests.TestCaseWithMemoryTransport):
707
708
    def test_get_parent_none(self):
709
        base_branch = self.make_branch('base')
710
        request = smart.branch.SmartServerBranchGetParent(self.get_transport())
711
        response = request.execute('base')
712
        self.assertEquals(
4083.1.7 by Andrew Bennetts
Fix same trivial bug [(x) != (x,)] in test_remote and test_smart.
713
            SuccessfulSmartServerResponse(('',)), response)
4078.2.1 by Robert Collins
Add a Branch.get_parent remote call for RemoteBranch.
714
715
    def test_get_parent_something(self):
716
        base_branch = self.make_branch('base')
717
        base_branch.set_parent(self.get_url('foo'))
718
        request = smart.branch.SmartServerBranchGetParent(self.get_transport())
719
        response = request.execute('base')
720
        self.assertEquals(
4083.1.7 by Andrew Bennetts
Fix same trivial bug [(x) != (x,)] in test_remote and test_smart.
721
            SuccessfulSmartServerResponse(("../foo",)),
4078.2.1 by Robert Collins
Add a Branch.get_parent remote call for RemoteBranch.
722
            response)
723
724
4084.2.1 by Robert Collins
Make accessing a branch.tags.get_tag_dict use a smart[er] method rather than VFS calls and real objects.
725
class TestSmartServerBranchRequestGetTagsBytes(tests.TestCaseWithMemoryTransport):
726
# Only called when the branch format and tags match [yay factory
727
# methods] so only need to test straight forward cases.
728
729
    def test_get_bytes(self):
730
        base_branch = self.make_branch('base')
731
        request = smart.branch.SmartServerBranchGetTagsBytes(
732
            self.get_transport())
733
        response = request.execute('base')
734
        self.assertEquals(
735
            SuccessfulSmartServerResponse(('',)), response)
736
737
3691.2.5 by Martin Pool
Add Branch.get_stacked_on_url rpc and tests for same
738
class TestSmartServerBranchRequestGetStackedOnURL(tests.TestCaseWithMemoryTransport):
739
740
    def test_get_stacked_on_url(self):
741
        base_branch = self.make_branch('base', format='1.6')
742
        stacked_branch = self.make_branch('stacked', format='1.6')
743
        # typically should be relative
744
        stacked_branch.set_stacked_on_url('../base')
745
        request = smart.branch.SmartServerBranchRequestGetStackedOnURL(
746
            self.get_transport())
747
        response = request.execute('stacked')
748
        self.assertEquals(
749
            SmartServerResponse(('ok', '../base')),
750
            response)
751
752
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
753
class TestSmartServerBranchRequestLockWrite(tests.TestCaseWithMemoryTransport):
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
754
755
    def setUp(self):
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
756
        tests.TestCaseWithMemoryTransport.setUp(self)
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
757
758
    def test_lock_write_on_unlocked_branch(self):
759
        backing = self.get_transport()
760
        request = smart.branch.SmartServerBranchRequestLockWrite(backing)
3015.2.12 by Robert Collins
Make test_smart use specific formats as needed to exercise locked and unlocked repositories.
761
        branch = self.make_branch('.', format='knit')
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
762
        repository = branch.repository
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
763
        response = request.execute('')
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
764
        branch_nonce = branch.control_files._lock.peek().get('nonce')
765
        repository_nonce = repository.control_files._lock.peek().get('nonce')
766
        self.assertEqual(
767
            SmartServerResponse(('ok', branch_nonce, repository_nonce)),
768
            response)
769
        # The branch (and associated repository) is now locked.  Verify that
770
        # with a new branch object.
771
        new_branch = repository.bzrdir.open_branch()
772
        self.assertRaises(errors.LockContention, new_branch.lock_write)
773
774
    def test_lock_write_on_locked_branch(self):
775
        backing = self.get_transport()
776
        request = smart.branch.SmartServerBranchRequestLockWrite(backing)
777
        branch = self.make_branch('.')
778
        branch.lock_write()
779
        branch.leave_lock_in_place()
780
        branch.unlock()
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
781
        response = request.execute('')
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
782
        self.assertEqual(
783
            SmartServerResponse(('LockContention',)), response)
784
785
    def test_lock_write_with_tokens_on_locked_branch(self):
786
        backing = self.get_transport()
787
        request = smart.branch.SmartServerBranchRequestLockWrite(backing)
3015.2.12 by Robert Collins
Make test_smart use specific formats as needed to exercise locked and unlocked repositories.
788
        branch = self.make_branch('.', format='knit')
2018.5.142 by Andrew Bennetts
Change Branch.lock_token to only accept and receive the branch lock token (rather than the branch and repo lock tokens).
789
        branch_token = branch.lock_write()
790
        repo_token = branch.repository.lock_write()
791
        branch.repository.unlock()
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
792
        branch.leave_lock_in_place()
793
        branch.repository.leave_lock_in_place()
794
        branch.unlock()
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
795
        response = request.execute('',
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
796
                                   branch_token, repo_token)
797
        self.assertEqual(
798
            SmartServerResponse(('ok', branch_token, repo_token)), response)
799
800
    def test_lock_write_with_mismatched_tokens_on_locked_branch(self):
801
        backing = self.get_transport()
802
        request = smart.branch.SmartServerBranchRequestLockWrite(backing)
3015.2.12 by Robert Collins
Make test_smart use specific formats as needed to exercise locked and unlocked repositories.
803
        branch = self.make_branch('.', format='knit')
2018.5.142 by Andrew Bennetts
Change Branch.lock_token to only accept and receive the branch lock token (rather than the branch and repo lock tokens).
804
        branch_token = branch.lock_write()
805
        repo_token = branch.repository.lock_write()
806
        branch.repository.unlock()
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
807
        branch.leave_lock_in_place()
808
        branch.repository.leave_lock_in_place()
809
        branch.unlock()
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
810
        response = request.execute('',
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
811
                                   branch_token+'xxx', repo_token)
812
        self.assertEqual(
813
            SmartServerResponse(('TokenMismatch',)), response)
814
815
    def test_lock_write_on_locked_repo(self):
816
        backing = self.get_transport()
817
        request = smart.branch.SmartServerBranchRequestLockWrite(backing)
3015.2.12 by Robert Collins
Make test_smart use specific formats as needed to exercise locked and unlocked repositories.
818
        branch = self.make_branch('.', format='knit')
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
819
        branch.repository.lock_write()
820
        branch.repository.leave_lock_in_place()
821
        branch.repository.unlock()
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
822
        response = request.execute('')
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
823
        self.assertEqual(
824
            SmartServerResponse(('LockContention',)), response)
825
2018.5.95 by Andrew Bennetts
Add a Transport.is_readonly remote call, let {Branch,Repository}.lock_write remote call return UnlockableTransport, and miscellaneous test fixes.
826
    def test_lock_write_on_readonly_transport(self):
827
        backing = self.get_readonly_transport()
828
        request = smart.branch.SmartServerBranchRequestLockWrite(backing)
829
        branch = self.make_branch('.')
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
830
        root = self.get_transport().clone('/')
831
        path = urlutils.relative_url(root.base, self.get_transport().base)
832
        response = request.execute(path)
2872.5.3 by Martin Pool
Pass back LockFailed from smart server lock methods
833
        error_name, lock_str, why_str = response.args
834
        self.assertFalse(response.is_successful())
835
        self.assertEqual('LockFailed', error_name)
2018.5.95 by Andrew Bennetts
Add a Transport.is_readonly remote call, let {Branch,Repository}.lock_write remote call return UnlockableTransport, and miscellaneous test fixes.
836
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
837
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
838
class TestSmartServerBranchRequestUnlock(tests.TestCaseWithMemoryTransport):
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
839
840
    def setUp(self):
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
841
        tests.TestCaseWithMemoryTransport.setUp(self)
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
842
843
    def test_unlock_on_locked_branch_and_repo(self):
844
        backing = self.get_transport()
845
        request = smart.branch.SmartServerBranchRequestUnlock(backing)
3015.2.12 by Robert Collins
Make test_smart use specific formats as needed to exercise locked and unlocked repositories.
846
        branch = self.make_branch('.', format='knit')
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
847
        # Lock the branch
2018.5.142 by Andrew Bennetts
Change Branch.lock_token to only accept and receive the branch lock token (rather than the branch and repo lock tokens).
848
        branch_token = branch.lock_write()
849
        repo_token = branch.repository.lock_write()
850
        branch.repository.unlock()
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
851
        # Unlock the branch (and repo) object, leaving the physical locks
852
        # in place.
853
        branch.leave_lock_in_place()
854
        branch.repository.leave_lock_in_place()
855
        branch.unlock()
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
856
        response = request.execute('',
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
857
                                   branch_token, repo_token)
858
        self.assertEqual(
859
            SmartServerResponse(('ok',)), response)
860
        # The branch is now unlocked.  Verify that with a new branch
861
        # object.
862
        new_branch = branch.bzrdir.open_branch()
863
        new_branch.lock_write()
864
        new_branch.unlock()
865
866
    def test_unlock_on_unlocked_branch_unlocked_repo(self):
867
        backing = self.get_transport()
868
        request = smart.branch.SmartServerBranchRequestUnlock(backing)
3015.2.12 by Robert Collins
Make test_smart use specific formats as needed to exercise locked and unlocked repositories.
869
        branch = self.make_branch('.', format='knit')
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
870
        response = request.execute(
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
871
            '', 'branch token', 'repo token')
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
872
        self.assertEqual(
873
            SmartServerResponse(('TokenMismatch',)), response)
874
875
    def test_unlock_on_unlocked_branch_locked_repo(self):
876
        backing = self.get_transport()
877
        request = smart.branch.SmartServerBranchRequestUnlock(backing)
3015.2.12 by Robert Collins
Make test_smart use specific formats as needed to exercise locked and unlocked repositories.
878
        branch = self.make_branch('.', format='knit')
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
879
        # Lock the repository.
880
        repo_token = branch.repository.lock_write()
881
        branch.repository.leave_lock_in_place()
882
        branch.repository.unlock()
883
        # Issue branch lock_write request on the unlocked branch (with locked
884
        # repo).
885
        response = request.execute(
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
886
            '', 'branch token', repo_token)
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
887
        self.assertEqual(
888
            SmartServerResponse(('TokenMismatch',)), response)
889
890
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
891
class TestSmartServerRepositoryRequest(tests.TestCaseWithMemoryTransport):
2018.5.56 by Robert Collins
Factor out code we expect to be common in SmartServerRequestHasRevision to SmartServerRepositoryRequest (Robert Collins, Vincent Ladeuil).
892
893
    def test_no_repository(self):
894
        """Raise NoRepositoryPresent when there is a bzrdir and no repo."""
895
        # we test this using a shared repository above the named path,
896
        # thus checking the right search logic is used - that is, that
897
        # its the exact path being looked at and the server is not
898
        # searching.
899
        backing = self.get_transport()
2018.5.58 by Wouter van Heyst
Small test fixes to reflect naming and documentation
900
        request = smart.repository.SmartServerRepositoryRequest(backing)
2018.5.56 by Robert Collins
Factor out code we expect to be common in SmartServerRequestHasRevision to SmartServerRepositoryRequest (Robert Collins, Vincent Ladeuil).
901
        self.make_repository('.', shared=True)
902
        self.make_bzrdir('subdir')
903
        self.assertRaises(errors.NoRepositoryPresent,
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
904
            request.execute, 'subdir')
905
906
3441.5.4 by Andrew Bennetts
Fix test failures, and add some tests for the remote graph heads RPC.
907
class TestSmartServerRepositoryGetParentMap(tests.TestCaseWithMemoryTransport):
3211.5.1 by Robert Collins
Change the smart server get_parents method to take a graph search to exclude already recieved parents from. This prevents history shortcuts causing huge numbers of duplicates.
908
3211.5.3 by Robert Collins
Adjust size of batch and change gzip comments to bzip2.
909
    def test_trivial_bzipped(self):
910
        # This tests that the wire encoding is actually bzipped
3211.5.1 by Robert Collins
Change the smart server get_parents method to take a graph search to exclude already recieved parents from. This prevents history shortcuts causing huge numbers of duplicates.
911
        backing = self.get_transport()
912
        request = smart.repository.SmartServerRepositoryGetParentMap(backing)
913
        tree = self.make_branch_and_memory_tree('.')
914
915
        self.assertEqual(None,
2692.1.24 by Andrew Bennetts
Merge from bzr.dev.
916
            request.execute('', 'missing-id'))
3211.5.3 by Robert Collins
Adjust size of batch and change gzip comments to bzip2.
917
        # Note that it returns a body (of '' bzipped).
3211.5.1 by Robert Collins
Change the smart server get_parents method to take a graph search to exclude already recieved parents from. This prevents history shortcuts causing huge numbers of duplicates.
918
        self.assertEqual(
3211.5.2 by Robert Collins
Change RemoteRepository.get_parent_map to use bz2 not gzip for compression.
919
            SuccessfulSmartServerResponse(('ok', ), bz2.compress('')),
3211.5.1 by Robert Collins
Change the smart server get_parents method to take a graph search to exclude already recieved parents from. This prevents history shortcuts causing huge numbers of duplicates.
920
            request.do_body('\n\n0\n'))
921
922
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
923
class TestSmartServerRepositoryGetRevisionGraph(tests.TestCaseWithMemoryTransport):
2018.5.67 by Wouter van Heyst
Implement RemoteRepository.get_revision_graph (Wouter van Heyst, Robert Collins)
924
925
    def test_none_argument(self):
926
        backing = self.get_transport()
927
        request = smart.repository.SmartServerRepositoryGetRevisionGraph(backing)
928
        tree = self.make_branch_and_memory_tree('.')
929
        tree.lock_write()
930
        tree.add('')
931
        r1 = tree.commit('1st commit')
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
932
        r2 = tree.commit('2nd commit', rev_id=u'\xc8'.encode('utf-8'))
2018.5.67 by Wouter van Heyst
Implement RemoteRepository.get_revision_graph (Wouter van Heyst, Robert Collins)
933
        tree.unlock()
934
935
        # the lines of revision_id->revision_parent_list has no guaranteed
936
        # order coming out of a dict, so sort both our test and response
937
        lines = sorted([' '.join([r2, r1]), r1])
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
938
        response = request.execute('', '')
2018.5.67 by Wouter van Heyst
Implement RemoteRepository.get_revision_graph (Wouter van Heyst, Robert Collins)
939
        response.body = '\n'.join(sorted(response.body.split('\n')))
940
2018.5.83 by Andrew Bennetts
Fix some test failures caused by the switch from unicode to UTF-8-encoded strs for revision IDs.
941
        self.assertEqual(
942
            SmartServerResponse(('ok', ), '\n'.join(lines)), response)
2018.5.67 by Wouter van Heyst
Implement RemoteRepository.get_revision_graph (Wouter van Heyst, Robert Collins)
943
944
    def test_specific_revision_argument(self):
945
        backing = self.get_transport()
946
        request = smart.repository.SmartServerRepositoryGetRevisionGraph(backing)
947
        tree = self.make_branch_and_memory_tree('.')
948
        tree.lock_write()
949
        tree.add('')
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
950
        rev_id_utf8 = u'\xc9'.encode('utf-8')
951
        r1 = tree.commit('1st commit', rev_id=rev_id_utf8)
952
        r2 = tree.commit('2nd commit', rev_id=u'\xc8'.encode('utf-8'))
2018.5.67 by Wouter van Heyst
Implement RemoteRepository.get_revision_graph (Wouter van Heyst, Robert Collins)
953
        tree.unlock()
954
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
955
        self.assertEqual(SmartServerResponse(('ok', ), rev_id_utf8),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
956
            request.execute('', rev_id_utf8))
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
957
2018.5.67 by Wouter van Heyst
Implement RemoteRepository.get_revision_graph (Wouter van Heyst, Robert Collins)
958
    def test_no_such_revision(self):
959
        backing = self.get_transport()
960
        request = smart.repository.SmartServerRepositoryGetRevisionGraph(backing)
961
        tree = self.make_branch_and_memory_tree('.')
962
        tree.lock_write()
963
        tree.add('')
964
        r1 = tree.commit('1st commit')
965
        tree.unlock()
966
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
967
        # Note that it still returns body (of zero bytes).
968
        self.assertEqual(
969
            SmartServerResponse(('nosuchrevision', 'missingrevision', ), ''),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
970
            request.execute('', 'missingrevision'))
971
972
4070.9.14 by Andrew Bennetts
Tweaks requested by Robert's review.
973
class TestSmartServerRepositoryGetStream(tests.TestCaseWithMemoryTransport):
974
975
    def make_two_commit_repo(self):
976
        tree = self.make_branch_and_memory_tree('.')
977
        tree.lock_write()
978
        tree.add('')
979
        r1 = tree.commit('1st commit')
980
        r2 = tree.commit('2nd commit', rev_id=u'\xc8'.encode('utf-8'))
981
        tree.unlock()
982
        repo = tree.branch.repository
983
        return repo, r1, r2
984
985
    def test_ancestry_of(self):
986
        """The search argument may be a 'ancestry-of' some heads'."""
987
        backing = self.get_transport()
988
        request = smart.repository.SmartServerRepositoryGetStream(backing)
989
        repo, r1, r2 = self.make_two_commit_repo()
990
        fetch_spec = ['ancestry-of', r2]
991
        lines = '\n'.join(fetch_spec)
992
        request.execute('', repo._format.network_name())
993
        response = request.do_body(lines)
994
        self.assertEqual(('ok',), response.args)
995
        stream_bytes = ''.join(response.body_stream)
996
        self.assertStartsWith(stream_bytes, 'Bazaar pack format 1')
997
998
    def test_search(self):
999
        """The search argument may be a 'search' of some explicit keys."""
1000
        backing = self.get_transport()
1001
        request = smart.repository.SmartServerRepositoryGetStream(backing)
1002
        repo, r1, r2 = self.make_two_commit_repo()
1003
        fetch_spec = ['search', '%s %s' % (r1, r2), 'null:', '2']
1004
        lines = '\n'.join(fetch_spec)
1005
        request.execute('', repo._format.network_name())
1006
        response = request.do_body(lines)
1007
        self.assertEqual(('ok',), response.args)
1008
        stream_bytes = ''.join(response.body_stream)
1009
        self.assertStartsWith(stream_bytes, 'Bazaar pack format 1')
1010
1011
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1012
class TestSmartServerRequestHasRevision(tests.TestCaseWithMemoryTransport):
2018.5.56 by Robert Collins
Factor out code we expect to be common in SmartServerRequestHasRevision to SmartServerRepositoryRequest (Robert Collins, Vincent Ladeuil).
1013
1014
    def test_missing_revision(self):
1015
        """For a missing revision, ('no', ) is returned."""
1016
        backing = self.get_transport()
1017
        request = smart.repository.SmartServerRequestHasRevision(backing)
1018
        self.make_repository('.')
1019
        self.assertEqual(SmartServerResponse(('no', )),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1020
            request.execute('', 'revid'))
2018.5.56 by Robert Collins
Factor out code we expect to be common in SmartServerRequestHasRevision to SmartServerRepositoryRequest (Robert Collins, Vincent Ladeuil).
1021
1022
    def test_present_revision(self):
2018.5.158 by Andrew Bennetts
Return 'yes'/'no' rather than 'ok'/'no' from the Repository.has_revision smart command.
1023
        """For a present revision, ('yes', ) is returned."""
2018.5.56 by Robert Collins
Factor out code we expect to be common in SmartServerRequestHasRevision to SmartServerRepositoryRequest (Robert Collins, Vincent Ladeuil).
1024
        backing = self.get_transport()
1025
        request = smart.repository.SmartServerRequestHasRevision(backing)
1026
        tree = self.make_branch_and_memory_tree('.')
1027
        tree.lock_write()
1028
        tree.add('')
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
1029
        rev_id_utf8 = u'\xc8abc'.encode('utf-8')
1030
        r1 = tree.commit('a commit', rev_id=rev_id_utf8)
2018.5.56 by Robert Collins
Factor out code we expect to be common in SmartServerRequestHasRevision to SmartServerRepositoryRequest (Robert Collins, Vincent Ladeuil).
1031
        tree.unlock()
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
1032
        self.assertTrue(tree.branch.repository.has_revision(rev_id_utf8))
2018.5.158 by Andrew Bennetts
Return 'yes'/'no' rather than 'ok'/'no' from the Repository.has_revision smart command.
1033
        self.assertEqual(SmartServerResponse(('yes', )),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1034
            request.execute('', rev_id_utf8))
1035
1036
1037
class TestSmartServerRepositoryGatherStats(tests.TestCaseWithMemoryTransport):
2018.10.2 by v.ladeuil+lp at free
gather_stats server side and request registration
1038
1039
    def test_empty_revid(self):
1040
        """With an empty revid, we get only size an number and revisions"""
1041
        backing = self.get_transport()
1042
        request = smart.repository.SmartServerRepositoryGatherStats(backing)
1043
        repository = self.make_repository('.')
1044
        stats = repository.gather_stats()
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1045
        expected_body = 'revisions: 0\n'
2018.10.2 by v.ladeuil+lp at free
gather_stats server side and request registration
1046
        self.assertEqual(SmartServerResponse(('ok', ), expected_body),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1047
                         request.execute('', '', 'no'))
2018.10.2 by v.ladeuil+lp at free
gather_stats server side and request registration
1048
1049
    def test_revid_with_committers(self):
1050
        """For a revid we get more infos."""
1051
        backing = self.get_transport()
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
1052
        rev_id_utf8 = u'\xc8abc'.encode('utf-8')
2018.10.2 by v.ladeuil+lp at free
gather_stats server side and request registration
1053
        request = smart.repository.SmartServerRepositoryGatherStats(backing)
1054
        tree = self.make_branch_and_memory_tree('.')
1055
        tree.lock_write()
1056
        tree.add('')
1057
        # Let's build a predictable result
1058
        tree.commit('a commit', timestamp=123456.2, timezone=3600)
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
1059
        tree.commit('a commit', timestamp=654321.4, timezone=0,
1060
                    rev_id=rev_id_utf8)
2018.10.2 by v.ladeuil+lp at free
gather_stats server side and request registration
1061
        tree.unlock()
1062
1063
        stats = tree.branch.repository.gather_stats()
1064
        expected_body = ('firstrev: 123456.200 3600\n'
1065
                         'latestrev: 654321.400 0\n'
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1066
                         'revisions: 2\n')
2018.10.2 by v.ladeuil+lp at free
gather_stats server side and request registration
1067
        self.assertEqual(SmartServerResponse(('ok', ), expected_body),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1068
                         request.execute('',
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
1069
                                         rev_id_utf8, 'no'))
2018.10.2 by v.ladeuil+lp at free
gather_stats server side and request registration
1070
1071
    def test_not_empty_repository_with_committers(self):
1072
        """For a revid and requesting committers we get the whole thing."""
1073
        backing = self.get_transport()
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
1074
        rev_id_utf8 = u'\xc8abc'.encode('utf-8')
2018.10.2 by v.ladeuil+lp at free
gather_stats server side and request registration
1075
        request = smart.repository.SmartServerRepositoryGatherStats(backing)
1076
        tree = self.make_branch_and_memory_tree('.')
1077
        tree.lock_write()
1078
        tree.add('')
1079
        # Let's build a predictable result
1080
        tree.commit('a commit', timestamp=123456.2, timezone=3600,
1081
                    committer='foo')
1082
        tree.commit('a commit', timestamp=654321.4, timezone=0,
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
1083
                    committer='bar', rev_id=rev_id_utf8)
2018.10.2 by v.ladeuil+lp at free
gather_stats server side and request registration
1084
        tree.unlock()
1085
        stats = tree.branch.repository.gather_stats()
1086
1087
        expected_body = ('committers: 2\n'
1088
                         'firstrev: 123456.200 3600\n'
1089
                         'latestrev: 654321.400 0\n'
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1090
                         'revisions: 2\n')
2018.10.2 by v.ladeuil+lp at free
gather_stats server side and request registration
1091
        self.assertEqual(SmartServerResponse(('ok', ), expected_body),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1092
                         request.execute('',
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
1093
                                         rev_id_utf8, 'yes'))
2018.10.2 by v.ladeuil+lp at free
gather_stats server side and request registration
1094
1095
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1096
class TestSmartServerRepositoryIsShared(tests.TestCaseWithMemoryTransport):
2018.5.57 by Robert Collins
Implement RemoteRepository.is_shared (Robert Collins, Vincent Ladeuil).
1097
1098
    def test_is_shared(self):
1099
        """For a shared repository, ('yes', ) is returned."""
1100
        backing = self.get_transport()
1101
        request = smart.repository.SmartServerRepositoryIsShared(backing)
1102
        self.make_repository('.', shared=True)
1103
        self.assertEqual(SmartServerResponse(('yes', )),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1104
            request.execute('', ))
2018.5.57 by Robert Collins
Implement RemoteRepository.is_shared (Robert Collins, Vincent Ladeuil).
1105
1106
    def test_is_not_shared(self):
2018.5.58 by Wouter van Heyst
Small test fixes to reflect naming and documentation
1107
        """For a shared repository, ('no', ) is returned."""
2018.5.57 by Robert Collins
Implement RemoteRepository.is_shared (Robert Collins, Vincent Ladeuil).
1108
        backing = self.get_transport()
1109
        request = smart.repository.SmartServerRepositoryIsShared(backing)
1110
        self.make_repository('.', shared=False)
1111
        self.assertEqual(SmartServerResponse(('no', )),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1112
            request.execute('', ))
1113
1114
1115
class TestSmartServerRepositoryLockWrite(tests.TestCaseWithMemoryTransport):
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
1116
1117
    def test_lock_write_on_unlocked_repo(self):
1118
        backing = self.get_transport()
1119
        request = smart.repository.SmartServerRepositoryLockWrite(backing)
3015.2.12 by Robert Collins
Make test_smart use specific formats as needed to exercise locked and unlocked repositories.
1120
        repository = self.make_repository('.', format='knit')
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1121
        response = request.execute('')
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
1122
        nonce = repository.control_files._lock.peek().get('nonce')
1123
        self.assertEqual(SmartServerResponse(('ok', nonce)), response)
1124
        # The repository is now locked.  Verify that with a new repository
1125
        # object.
1126
        new_repo = repository.bzrdir.open_repository()
1127
        self.assertRaises(errors.LockContention, new_repo.lock_write)
1128
1129
    def test_lock_write_on_locked_repo(self):
1130
        backing = self.get_transport()
1131
        request = smart.repository.SmartServerRepositoryLockWrite(backing)
3015.2.12 by Robert Collins
Make test_smart use specific formats as needed to exercise locked and unlocked repositories.
1132
        repository = self.make_repository('.', format='knit')
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
1133
        repository.lock_write()
1134
        repository.leave_lock_in_place()
1135
        repository.unlock()
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1136
        response = request.execute('')
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
1137
        self.assertEqual(
1138
            SmartServerResponse(('LockContention',)), response)
1139
2018.5.95 by Andrew Bennetts
Add a Transport.is_readonly remote call, let {Branch,Repository}.lock_write remote call return UnlockableTransport, and miscellaneous test fixes.
1140
    def test_lock_write_on_readonly_transport(self):
1141
        backing = self.get_readonly_transport()
1142
        request = smart.repository.SmartServerRepositoryLockWrite(backing)
3015.2.12 by Robert Collins
Make test_smart use specific formats as needed to exercise locked and unlocked repositories.
1143
        repository = self.make_repository('.', format='knit')
2018.5.95 by Andrew Bennetts
Add a Transport.is_readonly remote call, let {Branch,Repository}.lock_write remote call return UnlockableTransport, and miscellaneous test fixes.
1144
        response = request.execute('')
2872.5.3 by Martin Pool
Pass back LockFailed from smart server lock methods
1145
        self.assertFalse(response.is_successful())
1146
        self.assertEqual('LockFailed', response.args[0])
2018.5.95 by Andrew Bennetts
Add a Transport.is_readonly remote call, let {Branch,Repository}.lock_write remote call return UnlockableTransport, and miscellaneous test fixes.
1147
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
1148
4144.3.1 by Andrew Bennetts
Add Repository.insert_stream_locked server-side implementation, plus tests for server-side _translate_error.
1149
class TestInsertStreamBase(tests.TestCaseWithMemoryTransport):
1150
1151
    def make_empty_byte_stream(self, repo):
1152
        byte_stream = smart.repository._stream_to_byte_stream([], repo._format)
1153
        return ''.join(byte_stream)
1154
1155
1156
class TestSmartServerRepositoryInsertStream(TestInsertStreamBase):
1157
1158
    def test_insert_stream_empty(self):
1159
        backing = self.get_transport()
1160
        request = smart.repository.SmartServerRepositoryInsertStream(backing)
1161
        repository = self.make_repository('.')
1162
        response = request.execute('', '')
1163
        self.assertEqual(None, response)
1164
        response = request.do_chunk(self.make_empty_byte_stream(repository))
1165
        self.assertEqual(None, response)
1166
        response = request.do_end()
1167
        self.assertEqual(SmartServerResponse(('ok', )), response)
1168
        
1169
1170
class TestSmartServerRepositoryInsertStreamLocked(TestInsertStreamBase):
1171
1172
    def test_insert_stream_empty(self):
1173
        backing = self.get_transport()
1174
        request = smart.repository.SmartServerRepositoryInsertStreamLocked(
1175
            backing)
1176
        repository = self.make_repository('.', format='knit')
1177
        lock_token = repository.lock_write()
1178
        response = request.execute('', '', lock_token)
1179
        self.assertEqual(None, response)
1180
        response = request.do_chunk(self.make_empty_byte_stream(repository))
1181
        self.assertEqual(None, response)
1182
        response = request.do_end()
1183
        self.assertEqual(SmartServerResponse(('ok', )), response)
1184
        repository.unlock()
1185
1186
    def test_insert_stream_with_wrong_lock_token(self):
1187
        backing = self.get_transport()
1188
        request = smart.repository.SmartServerRepositoryInsertStreamLocked(
1189
            backing)
1190
        repository = self.make_repository('.', format='knit')
1191
        lock_token = repository.lock_write()
1192
        self.assertRaises(
1193
            errors.TokenMismatch, request.execute, '', '', 'wrong-token')
1194
        repository.unlock()
1195
1196
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1197
class TestSmartServerRepositoryUnlock(tests.TestCaseWithMemoryTransport):
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
1198
1199
    def setUp(self):
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1200
        tests.TestCaseWithMemoryTransport.setUp(self)
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
1201
1202
    def test_unlock_on_locked_repo(self):
1203
        backing = self.get_transport()
1204
        request = smart.repository.SmartServerRepositoryUnlock(backing)
3015.2.12 by Robert Collins
Make test_smart use specific formats as needed to exercise locked and unlocked repositories.
1205
        repository = self.make_repository('.', format='knit')
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
1206
        token = repository.lock_write()
1207
        repository.leave_lock_in_place()
1208
        repository.unlock()
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1209
        response = request.execute('', token)
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
1210
        self.assertEqual(
1211
            SmartServerResponse(('ok',)), response)
1212
        # The repository is now unlocked.  Verify that with a new repository
1213
        # object.
1214
        new_repo = repository.bzrdir.open_repository()
1215
        new_repo.lock_write()
1216
        new_repo.unlock()
1217
1218
    def test_unlock_on_unlocked_repo(self):
1219
        backing = self.get_transport()
1220
        request = smart.repository.SmartServerRepositoryUnlock(backing)
3015.2.12 by Robert Collins
Make test_smart use specific formats as needed to exercise locked and unlocked repositories.
1221
        repository = self.make_repository('.', format='knit')
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1222
        response = request.execute('', 'some token')
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
1223
        self.assertEqual(
1224
            SmartServerResponse(('TokenMismatch',)), response)
1225
1226
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1227
class TestSmartServerIsReadonly(tests.TestCaseWithMemoryTransport):
2018.5.95 by Andrew Bennetts
Add a Transport.is_readonly remote call, let {Branch,Repository}.lock_write remote call return UnlockableTransport, and miscellaneous test fixes.
1228
1229
    def test_is_readonly_no(self):
1230
        backing = self.get_transport()
1231
        request = smart.request.SmartServerIsReadonly(backing)
1232
        response = request.execute()
1233
        self.assertEqual(
1234
            SmartServerResponse(('no',)), response)
1235
1236
    def test_is_readonly_yes(self):
1237
        backing = self.get_readonly_transport()
1238
        request = smart.request.SmartServerIsReadonly(backing)
1239
        response = request.execute()
1240
        self.assertEqual(
1241
            SmartServerResponse(('yes',)), response)
1242
1243
4017.3.4 by Robert Collins
Create a verb for Repository.set_make_working_trees.
1244
class TestSmartServerRepositorySetMakeWorkingTrees(tests.TestCaseWithMemoryTransport):
1245
1246
    def test_set_false(self):
1247
        backing = self.get_transport()
1248
        repo = self.make_repository('.', shared=True)
1249
        repo.set_make_working_trees(True)
1250
        request_class = smart.repository.SmartServerRepositorySetMakeWorkingTrees
1251
        request = request_class(backing)
1252
        self.assertEqual(SuccessfulSmartServerResponse(('ok',)),
1253
            request.execute('', 'False'))
1254
        repo = repo.bzrdir.open_repository()
1255
        self.assertFalse(repo.make_working_trees())
1256
1257
    def test_set_true(self):
1258
        backing = self.get_transport()
1259
        repo = self.make_repository('.', shared=True)
1260
        repo.set_make_working_trees(False)
1261
        request_class = smart.repository.SmartServerRepositorySetMakeWorkingTrees
1262
        request = request_class(backing)
1263
        self.assertEqual(SuccessfulSmartServerResponse(('ok',)),
1264
            request.execute('', 'True'))
1265
        repo = repo.bzrdir.open_repository()
1266
        self.assertTrue(repo.make_working_trees())
1267
1268
3801.1.4 by Andrew Bennetts
Add tests for autopack RPC.
1269
class TestSmartServerPackRepositoryAutopack(tests.TestCaseWithTransport):
1270
1271
    def make_repo_needing_autopacking(self, path='.'):
1272
        # Make a repo in need of autopacking.
1273
        tree = self.make_branch_and_tree('.', format='pack-0.92')
1274
        repo = tree.branch.repository
1275
        # monkey-patch the pack collection to disable autopacking
1276
        repo._pack_collection._max_pack_count = lambda count: count
1277
        for x in range(10):
1278
            tree.commit('commit %s' % x)
1279
        self.assertEqual(10, len(repo._pack_collection.names()))
1280
        del repo._pack_collection._max_pack_count
1281
        return repo
1282
1283
    def test_autopack_needed(self):
1284
        repo = self.make_repo_needing_autopacking()
4145.1.6 by Robert Collins
More test fallout, but all caught now.
1285
        repo.lock_write()
1286
        self.addCleanup(repo.unlock)
3801.1.4 by Andrew Bennetts
Add tests for autopack RPC.
1287
        backing = self.get_transport()
1288
        request = smart.packrepository.SmartServerPackRepositoryAutopack(
1289
            backing)
1290
        response = request.execute('')
1291
        self.assertEqual(SmartServerResponse(('ok',)), response)
1292
        repo._pack_collection.reload_pack_names()
1293
        self.assertEqual(1, len(repo._pack_collection.names()))
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
1294
3801.1.4 by Andrew Bennetts
Add tests for autopack RPC.
1295
    def test_autopack_not_needed(self):
1296
        tree = self.make_branch_and_tree('.', format='pack-0.92')
1297
        repo = tree.branch.repository
4145.1.6 by Robert Collins
More test fallout, but all caught now.
1298
        repo.lock_write()
1299
        self.addCleanup(repo.unlock)
3801.1.4 by Andrew Bennetts
Add tests for autopack RPC.
1300
        for x in range(9):
1301
            tree.commit('commit %s' % x)
1302
        backing = self.get_transport()
1303
        request = smart.packrepository.SmartServerPackRepositoryAutopack(
1304
            backing)
1305
        response = request.execute('')
1306
        self.assertEqual(SmartServerResponse(('ok',)), response)
1307
        repo._pack_collection.reload_pack_names()
1308
        self.assertEqual(9, len(repo._pack_collection.names()))
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
1309
3801.1.4 by Andrew Bennetts
Add tests for autopack RPC.
1310
    def test_autopack_on_nonpack_format(self):
3801.1.20 by Andrew Bennetts
Return ('ok',) rather than an error the autopack RPC is used on a non-pack repo.
1311
        """A request to autopack a non-pack repo is a no-op."""
3801.1.4 by Andrew Bennetts
Add tests for autopack RPC.
1312
        repo = self.make_repository('.', format='knit')
1313
        backing = self.get_transport()
1314
        request = smart.packrepository.SmartServerPackRepositoryAutopack(
1315
            backing)
1316
        response = request.execute('')
3801.1.20 by Andrew Bennetts
Return ('ok',) rather than an error the autopack RPC is used on a non-pack repo.
1317
        self.assertEqual(SmartServerResponse(('ok',)), response)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
1318
3801.1.4 by Andrew Bennetts
Add tests for autopack RPC.
1319
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
1320
class TestHandlers(tests.TestCase):
1321
    """Tests for the request.request_handlers object."""
1322
3526.3.1 by Andrew Bennetts
Remove registrations of defunct HPSS verbs.
1323
    def test_all_registrations_exist(self):
1324
        """All registered request_handlers can be found."""
1325
        # If there's a typo in a register_lazy call, this loop will fail with
1326
        # an AttributeError.
1327
        for key, item in smart.request.request_handlers.iteritems():
1328
            pass
1329
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
1330
    def test_registered_methods(self):
1331
        """Test that known methods are registered to the correct object."""
1332
        self.assertEqual(
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
1333
            smart.request.request_handlers.get('Branch.get_config_file'),
1334
            smart.branch.SmartServerBranchGetConfigFile)
1335
        self.assertEqual(
4078.2.1 by Robert Collins
Add a Branch.get_parent remote call for RemoteBranch.
1336
            smart.request.request_handlers.get('Branch.get_parent'),
1337
            smart.branch.SmartServerBranchGetParent)
1338
        self.assertEqual(
4084.2.1 by Robert Collins
Make accessing a branch.tags.get_tag_dict use a smart[er] method rather than VFS calls and real objects.
1339
            smart.request.request_handlers.get('Branch.get_tags_bytes'),
1340
            smart.branch.SmartServerBranchGetTagsBytes)
1341
        self.assertEqual(
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1342
            smart.request.request_handlers.get('Branch.lock_write'),
1343
            smart.branch.SmartServerBranchRequestLockWrite)
1344
        self.assertEqual(
2018.5.51 by Wouter van Heyst
Test and implement RemoteBranch.last_revision_info()
1345
            smart.request.request_handlers.get('Branch.last_revision_info'),
1346
            smart.branch.SmartServerBranchRequestLastRevisionInfo)
1347
        self.assertEqual(
2018.5.38 by Robert Collins
Implement RemoteBranch.revision_history().
1348
            smart.request.request_handlers.get('Branch.revision_history'),
1349
            smart.branch.SmartServerRequestRevisionHistory)
1350
        self.assertEqual(
2018.5.77 by Wouter van Heyst
Fix typo in request_handlers registration of Branch.set_last_revision, and test that registration
1351
            smart.request.request_handlers.get('Branch.set_last_revision'),
1352
            smart.branch.SmartServerBranchRequestSetLastRevision)
1353
        self.assertEqual(
2892.2.1 by Andrew Bennetts
Add Branch.set_last_revision_info smart method, and make the RemoteBranch client use it.
1354
            smart.request.request_handlers.get('Branch.set_last_revision_info'),
1355
            smart.branch.SmartServerBranchRequestSetLastRevisionInfo)
1356
        self.assertEqual(
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1357
            smart.request.request_handlers.get('Branch.unlock'),
1358
            smart.branch.SmartServerBranchRequestUnlock)
1359
        self.assertEqual(
2018.5.34 by Robert Collins
Get test_remote.BasicRemoteObjectTests.test_open_remote_branch passing by implementing a remote method BzrDir.find_repository.
1360
            smart.request.request_handlers.get('BzrDir.find_repository'),
3221.3.2 by Robert Collins
* New remote method ``RemoteBzrDir.find_repositoryV2`` adding support for
1361
            smart.bzrdir.SmartServerRequestFindRepositoryV1)
1362
        self.assertEqual(
1363
            smart.request.request_handlers.get('BzrDir.find_repositoryV2'),
1364
            smart.bzrdir.SmartServerRequestFindRepositoryV2)
2018.5.34 by Robert Collins
Get test_remote.BasicRemoteObjectTests.test_open_remote_branch passing by implementing a remote method BzrDir.find_repository.
1365
        self.assertEqual(
2018.5.42 by Robert Collins
Various hopefully improvements, but wsgi is broken, handing over to spiv :).
1366
            smart.request.request_handlers.get('BzrDirFormat.initialize'),
1367
            smart.bzrdir.SmartServerRequestInitializeBzrDir)
1368
        self.assertEqual(
4070.2.3 by Robert Collins
Get BzrDir.cloning_metadir working.
1369
            smart.request.request_handlers.get('BzrDir.cloning_metadir'),
1370
            smart.bzrdir.SmartServerBzrDirRequestCloningMetaDir)
1371
        self.assertEqual(
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
1372
            smart.request.request_handlers.get('BzrDir.open_branch'),
1373
            smart.bzrdir.SmartServerRequestOpenBranch)
2018.5.40 by Robert Collins
Implement a remote Repository.has_revision method.
1374
        self.assertEqual(
4084.2.1 by Robert Collins
Make accessing a branch.tags.get_tag_dict use a smart[er] method rather than VFS calls and real objects.
1375
            smart.request.request_handlers.get('BzrDir.open_branchV2'),
1376
            smart.bzrdir.SmartServerRequestOpenBranchV2)
1377
        self.assertEqual(
3801.1.4 by Andrew Bennetts
Add tests for autopack RPC.
1378
            smart.request.request_handlers.get('PackRepository.autopack'),
1379
            smart.packrepository.SmartServerPackRepositoryAutopack)
1380
        self.assertEqual(
2018.10.2 by v.ladeuil+lp at free
gather_stats server side and request registration
1381
            smart.request.request_handlers.get('Repository.gather_stats'),
1382
            smart.repository.SmartServerRepositoryGatherStats)
1383
        self.assertEqual(
3172.5.6 by Robert Collins
Create new smart server verb Repository.get_parent_map.
1384
            smart.request.request_handlers.get('Repository.get_parent_map'),
1385
            smart.repository.SmartServerRepositoryGetParentMap)
1386
        self.assertEqual(
2535.3.69 by Andrew Bennetts
Add check for Repository.stream_knit_data_for_revisions to TestHandlers.test_registered_methods.
1387
            smart.request.request_handlers.get(
1388
                'Repository.get_revision_graph'),
2018.5.67 by Wouter van Heyst
Implement RemoteRepository.get_revision_graph (Wouter van Heyst, Robert Collins)
1389
            smart.repository.SmartServerRepositoryGetRevisionGraph)
1390
        self.assertEqual(
4144.3.1 by Andrew Bennetts
Add Repository.insert_stream_locked server-side implementation, plus tests for server-side _translate_error.
1391
            smart.request.request_handlers.get('Repository.get_stream'),
1392
            smart.repository.SmartServerRepositoryGetStream)
1393
        self.assertEqual(
2018.5.40 by Robert Collins
Implement a remote Repository.has_revision method.
1394
            smart.request.request_handlers.get('Repository.has_revision'),
1395
            smart.repository.SmartServerRequestHasRevision)
2018.5.57 by Robert Collins
Implement RemoteRepository.is_shared (Robert Collins, Vincent Ladeuil).
1396
        self.assertEqual(
4144.3.1 by Andrew Bennetts
Add Repository.insert_stream_locked server-side implementation, plus tests for server-side _translate_error.
1397
            smart.request.request_handlers.get('Repository.insert_stream'),
1398
            smart.repository.SmartServerRepositoryInsertStream)
1399
        self.assertEqual(
1400
            smart.request.request_handlers.get('Repository.insert_stream_locked'),
1401
            smart.repository.SmartServerRepositoryInsertStreamLocked)
1402
        self.assertEqual(
2018.5.57 by Robert Collins
Implement RemoteRepository.is_shared (Robert Collins, Vincent Ladeuil).
1403
            smart.request.request_handlers.get('Repository.is_shared'),
1404
            smart.repository.SmartServerRepositoryIsShared)
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
1405
        self.assertEqual(
1406
            smart.request.request_handlers.get('Repository.lock_write'),
1407
            smart.repository.SmartServerRepositoryLockWrite)
1408
        self.assertEqual(
2535.3.69 by Andrew Bennetts
Add check for Repository.stream_knit_data_for_revisions to TestHandlers.test_registered_methods.
1409
            smart.request.request_handlers.get('Repository.tarball'),
1410
            smart.repository.SmartServerRepositoryTarball)
1411
        self.assertEqual(
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
1412
            smart.request.request_handlers.get('Repository.unlock'),
1413
            smart.repository.SmartServerRepositoryUnlock)
2018.5.95 by Andrew Bennetts
Add a Transport.is_readonly remote call, let {Branch,Repository}.lock_write remote call return UnlockableTransport, and miscellaneous test fixes.
1414
        self.assertEqual(
1415
            smart.request.request_handlers.get('Transport.is_readonly'),
1416
            smart.request.SmartServerIsReadonly)