/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
4160.2.1 by Andrew Bennetts
Failing test for BzrDir.open_branchV2 RPC not opening stacked-on branch.
392
    def test_stacked_branch(self):
393
        """Opening a stacked branch does not open the stacked-on branch."""
394
        trunk = self.make_branch('trunk')
395
        feature = self.make_branch('feature', format='1.9')
396
        feature.set_stacked_on_url(trunk.base)
397
        opened_branches = []
398
        Branch.hooks.install_named_hook('open', opened_branches.append, None)
399
        backing = self.get_transport()
400
        request = smart.bzrdir.SmartServerRequestOpenBranchV2(backing)
401
        response = request.execute('feature')
402
        expected_format = feature._format.network_name()
403
        self.assertEqual(
404
            SuccessfulSmartServerResponse(('branch', expected_format)),
405
            response)
406
        self.assertLength(1, opened_branches)
407
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.
408
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
409
class TestSmartServerRequestRevisionHistory(tests.TestCaseWithMemoryTransport):
2018.5.38 by Robert Collins
Implement RemoteBranch.revision_history().
410
411
    def test_empty(self):
412
        """For an empty branch, the body is empty."""
413
        backing = self.get_transport()
414
        request = smart.branch.SmartServerRequestRevisionHistory(backing)
415
        self.make_branch('.')
416
        self.assertEqual(SmartServerResponse(('ok', ), ''),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
417
            request.execute(''))
2018.5.38 by Robert Collins
Implement RemoteBranch.revision_history().
418
419
    def test_not_empty(self):
420
        """For a non-empty branch, the body is empty."""
421
        backing = self.get_transport()
422
        request = smart.branch.SmartServerRequestRevisionHistory(backing)
423
        tree = self.make_branch_and_memory_tree('.')
424
        tree.lock_write()
425
        tree.add('')
426
        r1 = tree.commit('1st commit')
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
427
        r2 = tree.commit('2nd commit', rev_id=u'\xc8'.encode('utf-8'))
2018.5.38 by Robert Collins
Implement RemoteBranch.revision_history().
428
        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.
429
        self.assertEqual(
430
            SmartServerResponse(('ok', ), ('\x00'.join([r1, r2]))),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
431
            request.execute(''))
432
433
434
class TestSmartServerBranchRequest(tests.TestCaseWithMemoryTransport):
2018.5.49 by Wouter van Heyst
Refactor SmartServerBranchRequest out from SmartServerRequestRevisionHistory to
435
436
    def test_no_branch(self):
437
        """When there is a bzrdir and no branch, NotBranchError is raised."""
438
        backing = self.get_transport()
439
        request = smart.branch.SmartServerBranchRequest(backing)
440
        self.make_bzrdir('.')
441
        self.assertRaises(errors.NotBranchError,
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
442
            request.execute, '')
2018.5.49 by Wouter van Heyst
Refactor SmartServerBranchRequest out from SmartServerRequestRevisionHistory to
443
2018.5.38 by Robert Collins
Implement RemoteBranch.revision_history().
444
    def test_branch_reference(self):
445
        """When there is a branch reference, NotBranchError is raised."""
446
        backing = self.get_transport()
2018.5.49 by Wouter van Heyst
Refactor SmartServerBranchRequest out from SmartServerRequestRevisionHistory to
447
        request = smart.branch.SmartServerBranchRequest(backing)
2018.5.38 by Robert Collins
Implement RemoteBranch.revision_history().
448
        branch = self.make_branch('branch')
449
        checkout = branch.create_checkout('reference',lightweight=True)
450
        self.assertRaises(errors.NotBranchError,
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
451
            request.execute, 'checkout')
452
453
454
class TestSmartServerBranchRequestLastRevisionInfo(tests.TestCaseWithMemoryTransport):
2018.5.50 by Wouter van Heyst
Add SmartServerBranchRequestLastRevisionInfo method.
455
456
    def test_empty(self):
2018.5.170 by Andrew Bennetts
Use 'null:' instead of '' to mean NULL_REVISION on the wire.
457
        """For an empty branch, the result is ('ok', '0', 'null:')."""
2018.5.50 by Wouter van Heyst
Add SmartServerBranchRequestLastRevisionInfo method.
458
        backing = self.get_transport()
459
        request = smart.branch.SmartServerBranchRequestLastRevisionInfo(backing)
460
        self.make_branch('.')
2018.5.170 by Andrew Bennetts
Use 'null:' instead of '' to mean NULL_REVISION on the wire.
461
        self.assertEqual(SmartServerResponse(('ok', '0', 'null:')),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
462
            request.execute(''))
2018.5.50 by Wouter van Heyst
Add SmartServerBranchRequestLastRevisionInfo method.
463
464
    def test_not_empty(self):
465
        """For a non-empty branch, the result is ('ok', 'revno', 'revid')."""
466
        backing = self.get_transport()
467
        request = smart.branch.SmartServerBranchRequestLastRevisionInfo(backing)
468
        tree = self.make_branch_and_memory_tree('.')
469
        tree.lock_write()
470
        tree.add('')
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
471
        rev_id_utf8 = u'\xc8'.encode('utf-8')
2018.5.50 by Wouter van Heyst
Add SmartServerBranchRequestLastRevisionInfo method.
472
        r1 = tree.commit('1st commit')
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
473
        r2 = tree.commit('2nd commit', rev_id=rev_id_utf8)
2018.5.50 by Wouter van Heyst
Add SmartServerBranchRequestLastRevisionInfo method.
474
        tree.unlock()
475
        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.
476
            SmartServerResponse(('ok', '2', rev_id_utf8)),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
477
            request.execute(''))
478
479
480
class TestSmartServerBranchRequestGetConfigFile(tests.TestCaseWithMemoryTransport):
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
481
482
    def test_default(self):
483
        """With no file, we get empty content."""
484
        backing = self.get_transport()
485
        request = smart.branch.SmartServerBranchGetConfigFile(backing)
486
        branch = self.make_branch('.')
487
        # there should be no file by default
488
        content = ''
489
        self.assertEqual(SmartServerResponse(('ok', ), content),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
490
            request.execute(''))
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
491
492
    def test_with_content(self):
493
        # SmartServerBranchGetConfigFile should return the content from
494
        # 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
495
        # perform more complex processing.
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
496
        backing = self.get_transport()
497
        request = smart.branch.SmartServerBranchGetConfigFile(backing)
498
        branch = self.make_branch('.')
3407.2.5 by Martin Pool
Deprecate LockableFiles.put_utf8
499
        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).
500
        self.assertEqual(SmartServerResponse(('ok', ), 'foo bar baz'),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
501
            request.execute(''))
502
503
3441.5.30 by Andrew Bennetts
Improve tests for all Branch.set_last_revision* verbs.
504
class SetLastRevisionTestBase(tests.TestCaseWithMemoryTransport):
505
    """Base test case for verbs that implement set_last_revision."""
506
507
    def setUp(self):
508
        tests.TestCaseWithMemoryTransport.setUp(self)
509
        backing_transport = self.get_transport()
510
        self.request = self.request_class(backing_transport)
511
        self.tree = self.make_branch_and_memory_tree('.')
512
513
    def lock_branch(self):
514
        b = self.tree.branch
515
        branch_token = b.lock_write()
516
        repo_token = b.repository.lock_write()
517
        b.repository.unlock()
518
        return branch_token, repo_token
519
520
    def unlock_branch(self):
521
        self.tree.branch.unlock()
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
522
3441.5.30 by Andrew Bennetts
Improve tests for all Branch.set_last_revision* verbs.
523
    def set_last_revision(self, revision_id, revno):
524
        branch_token, repo_token = self.lock_branch()
525
        response = self._set_last_revision(
526
            revision_id, revno, branch_token, repo_token)
527
        self.unlock_branch()
528
        return response
529
530
    def assertRequestSucceeds(self, revision_id, revno):
531
        response = self.set_last_revision(revision_id, revno)
532
        self.assertEqual(SuccessfulSmartServerResponse(('ok',)), response)
533
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
534
3441.5.30 by Andrew Bennetts
Improve tests for all Branch.set_last_revision* verbs.
535
class TestSetLastRevisionVerbMixin(object):
536
    """Mixin test case for verbs that implement set_last_revision."""
537
538
    def test_set_null_to_null(self):
539
        """An empty branch can have its last revision set to 'null:'."""
540
        self.assertRequestSucceeds('null:', 0)
541
542
    def test_NoSuchRevision(self):
543
        """If the revision_id is not present, the verb returns NoSuchRevision.
544
        """
545
        revision_id = 'non-existent revision'
546
        self.assertEqual(
547
            FailedSmartServerResponse(('NoSuchRevision', revision_id)),
548
            self.set_last_revision(revision_id, 1))
549
550
    def make_tree_with_two_commits(self):
551
        self.tree.lock_write()
552
        self.tree.add('')
553
        rev_id_utf8 = u'\xc8'.encode('utf-8')
554
        r1 = self.tree.commit('1st commit', rev_id=rev_id_utf8)
555
        r2 = self.tree.commit('2nd commit', rev_id='rev-2')
556
        self.tree.unlock()
557
558
    def test_branch_last_revision_info_is_updated(self):
559
        """A branch's tip can be set to a revision that is present in its
560
        repository.
561
        """
562
        # Make a branch with an empty revision history, but two revisions in
563
        # its repository.
564
        self.make_tree_with_two_commits()
565
        rev_id_utf8 = u'\xc8'.encode('utf-8')
566
        self.tree.branch.set_revision_history([])
567
        self.assertEqual(
568
            (0, 'null:'), self.tree.branch.last_revision_info())
569
        # We can update the branch to a revision that is present in the
570
        # repository.
571
        self.assertRequestSucceeds(rev_id_utf8, 1)
572
        self.assertEqual(
573
            (1, rev_id_utf8), self.tree.branch.last_revision_info())
574
575
    def test_branch_last_revision_info_rewind(self):
576
        """A branch's tip can be set to a revision that is an ancestor of the
577
        current tip.
578
        """
579
        self.make_tree_with_two_commits()
580
        rev_id_utf8 = u'\xc8'.encode('utf-8')
581
        self.assertEqual(
582
            (2, 'rev-2'), self.tree.branch.last_revision_info())
583
        self.assertRequestSucceeds(rev_id_utf8, 1)
584
        self.assertEqual(
585
            (1, rev_id_utf8), self.tree.branch.last_revision_info())
586
3577.1.1 by Andrew Bennetts
Cherry-pick TipChangeRejected changes from pre-branch-tip-changed-hook loom.
587
    def test_TipChangeRejected(self):
588
        """If a pre_change_branch_tip hook raises TipChangeRejected, the verb
589
        returns TipChangeRejected.
590
        """
591
        rejection_message = u'rejection message\N{INTERROBANG}'
592
        def hook_that_rejects(params):
593
            raise errors.TipChangeRejected(rejection_message)
594
        Branch.hooks.install_named_hook(
595
            'pre_change_branch_tip', hook_that_rejects, None)
596
        self.assertEqual(
597
            FailedSmartServerResponse(
598
                ('TipChangeRejected', rejection_message.encode('utf-8'))),
599
            self.set_last_revision('null:', 0))
600
3441.5.30 by Andrew Bennetts
Improve tests for all Branch.set_last_revision* verbs.
601
3441.5.6 by Andrew Bennetts
Greatly simplify RemoteBranch.update_revisions. Still needs more tests.
602
class TestSmartServerBranchRequestSetLastRevision(
3441.5.30 by Andrew Bennetts
Improve tests for all Branch.set_last_revision* verbs.
603
        SetLastRevisionTestBase, TestSetLastRevisionVerbMixin):
604
    """Tests for Branch.set_last_revision verb."""
3441.5.6 by Andrew Bennetts
Greatly simplify RemoteBranch.update_revisions. Still needs more tests.
605
606
    request_class = smart.branch.SmartServerBranchRequestSetLastRevision
607
3441.5.30 by Andrew Bennetts
Improve tests for all Branch.set_last_revision* verbs.
608
    def _set_last_revision(self, revision_id, revno, branch_token, repo_token):
609
        return self.request.execute(
610
            '', branch_token, repo_token, revision_id)
611
612
613
class TestSmartServerBranchRequestSetLastRevisionInfo(
614
        SetLastRevisionTestBase, TestSetLastRevisionVerbMixin):
615
    """Tests for Branch.set_last_revision_info verb."""
616
617
    request_class = smart.branch.SmartServerBranchRequestSetLastRevisionInfo
618
619
    def _set_last_revision(self, revision_id, revno, branch_token, repo_token):
620
        return self.request.execute(
621
            '', branch_token, repo_token, revno, revision_id)
622
623
    def test_NoSuchRevision(self):
624
        """Branch.set_last_revision_info does not have to return
625
        NoSuchRevision if the revision_id is absent.
626
        """
627
        raise tests.TestNotApplicable()
3441.5.6 by Andrew Bennetts
Greatly simplify RemoteBranch.update_revisions. Still needs more tests.
628
629
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.
630
class TestSmartServerBranchRequestSetLastRevisionEx(
3441.5.30 by Andrew Bennetts
Improve tests for all Branch.set_last_revision* verbs.
631
        SetLastRevisionTestBase, TestSetLastRevisionVerbMixin):
632
    """Tests for Branch.set_last_revision_ex verb."""
3441.5.6 by Andrew Bennetts
Greatly simplify RemoteBranch.update_revisions. Still needs more tests.
633
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.
634
    request_class = smart.branch.SmartServerBranchRequestSetLastRevisionEx
3441.5.6 by Andrew Bennetts
Greatly simplify RemoteBranch.update_revisions. Still needs more tests.
635
3441.5.30 by Andrew Bennetts
Improve tests for all Branch.set_last_revision* verbs.
636
    def _set_last_revision(self, revision_id, revno, branch_token, repo_token):
637
        return self.request.execute(
638
            '', branch_token, repo_token, revision_id, 0, 0)
639
640
    def assertRequestSucceeds(self, revision_id, revno):
641
        response = self.set_last_revision(revision_id, revno)
642
        self.assertEqual(
643
            SuccessfulSmartServerResponse(('ok', revno, revision_id)),
644
            response)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
645
3441.5.30 by Andrew Bennetts
Improve tests for all Branch.set_last_revision* verbs.
646
    def test_branch_last_revision_info_rewind(self):
647
        """A branch's tip can be set to a revision that is an ancestor of the
648
        current tip, but only if allow_overwrite_descendant is passed.
649
        """
650
        self.make_tree_with_two_commits()
3441.5.6 by Andrew Bennetts
Greatly simplify RemoteBranch.update_revisions. Still needs more tests.
651
        rev_id_utf8 = u'\xc8'.encode('utf-8')
3441.5.30 by Andrew Bennetts
Improve tests for all Branch.set_last_revision* verbs.
652
        self.assertEqual(
653
            (2, 'rev-2'), self.tree.branch.last_revision_info())
654
        # If allow_overwrite_descendant flag is 0, then trying to set the tip
655
        # to an older revision ID has no effect.
656
        branch_token, repo_token = self.lock_branch()
657
        response = self.request.execute(
658
            '', branch_token, repo_token, rev_id_utf8, 0, 0)
659
        self.assertEqual(
660
            SuccessfulSmartServerResponse(('ok', 2, 'rev-2')),
661
            response)
662
        self.assertEqual(
663
            (2, 'rev-2'), self.tree.branch.last_revision_info())
664
665
        # If allow_overwrite_descendant flag is 1, then setting the tip to an
666
        # ancestor works.
667
        response = self.request.execute(
668
            '', branch_token, repo_token, rev_id_utf8, 0, 1)
669
        self.assertEqual(
670
            SuccessfulSmartServerResponse(('ok', 1, rev_id_utf8)),
671
            response)
672
        self.unlock_branch()
673
        self.assertEqual(
674
            (1, rev_id_utf8), self.tree.branch.last_revision_info())
675
3441.5.31 by Andrew Bennetts
Add test for allow_diverged flag.
676
    def make_branch_with_divergent_history(self):
677
        """Make a branch with divergent history in its repo.
678
679
        The branch's tip will be 'child-2', and the repo will also contain
680
        'child-1', which diverges from a common base revision.
3441.5.30 by Andrew Bennetts
Improve tests for all Branch.set_last_revision* verbs.
681
        """
682
        self.tree.lock_write()
683
        self.tree.add('')
684
        r1 = self.tree.commit('1st commit')
685
        revno_1, revid_1 = self.tree.branch.last_revision_info()
686
        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.
687
        # Undo the second commit
3441.5.30 by Andrew Bennetts
Improve tests for all Branch.set_last_revision* verbs.
688
        self.tree.branch.set_last_revision_info(revno_1, revid_1)
689
        self.tree.set_parent_ids([revid_1])
3441.5.6 by Andrew Bennetts
Greatly simplify RemoteBranch.update_revisions. Still needs more tests.
690
        # Make a new second commit, child-2.  child-2 has diverged from
691
        # child-1.
3441.5.30 by Andrew Bennetts
Improve tests for all Branch.set_last_revision* verbs.
692
        new_r2 = self.tree.commit('2nd commit', rev_id='child-2')
693
        self.tree.unlock()
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
694
3441.5.31 by Andrew Bennetts
Add test for allow_diverged flag.
695
    def test_not_allow_diverged(self):
696
        """If allow_diverged is not passed, then setting a divergent history
697
        returns a Diverged error.
698
        """
699
        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.
700
        self.assertEqual(
3441.5.30 by Andrew Bennetts
Improve tests for all Branch.set_last_revision* verbs.
701
            FailedSmartServerResponse(('Diverged',)),
702
            self.set_last_revision('child-1', 2))
703
        # The branch tip was not changed.
704
        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.
705
3441.5.31 by Andrew Bennetts
Add test for allow_diverged flag.
706
    def test_allow_diverged(self):
707
        """If allow_diverged is passed, then setting a divergent history
708
        succeeds.
709
        """
710
        self.make_branch_with_divergent_history()
711
        branch_token, repo_token = self.lock_branch()
712
        response = self.request.execute(
713
            '', branch_token, repo_token, 'child-1', 1, 0)
714
        self.assertEqual(
715
            SuccessfulSmartServerResponse(('ok', 2, 'child-1')),
716
            response)
717
        self.unlock_branch()
718
        # The branch tip was changed.
719
        self.assertEqual('child-1', self.tree.branch.last_revision())
720
2892.2.1 by Andrew Bennetts
Add Branch.set_last_revision_info smart method, and make the RemoteBranch client use it.
721
4078.2.1 by Robert Collins
Add a Branch.get_parent remote call for RemoteBranch.
722
class TestSmartServerBranchRequestGetParent(tests.TestCaseWithMemoryTransport):
723
724
    def test_get_parent_none(self):
725
        base_branch = self.make_branch('base')
726
        request = smart.branch.SmartServerBranchGetParent(self.get_transport())
727
        response = request.execute('base')
728
        self.assertEquals(
4083.1.7 by Andrew Bennetts
Fix same trivial bug [(x) != (x,)] in test_remote and test_smart.
729
            SuccessfulSmartServerResponse(('',)), response)
4078.2.1 by Robert Collins
Add a Branch.get_parent remote call for RemoteBranch.
730
731
    def test_get_parent_something(self):
732
        base_branch = self.make_branch('base')
733
        base_branch.set_parent(self.get_url('foo'))
734
        request = smart.branch.SmartServerBranchGetParent(self.get_transport())
735
        response = request.execute('base')
736
        self.assertEquals(
4083.1.7 by Andrew Bennetts
Fix same trivial bug [(x) != (x,)] in test_remote and test_smart.
737
            SuccessfulSmartServerResponse(("../foo",)),
4078.2.1 by Robert Collins
Add a Branch.get_parent remote call for RemoteBranch.
738
            response)
739
740
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.
741
class TestSmartServerBranchRequestGetTagsBytes(tests.TestCaseWithMemoryTransport):
742
# Only called when the branch format and tags match [yay factory
743
# methods] so only need to test straight forward cases.
744
745
    def test_get_bytes(self):
746
        base_branch = self.make_branch('base')
747
        request = smart.branch.SmartServerBranchGetTagsBytes(
748
            self.get_transport())
749
        response = request.execute('base')
750
        self.assertEquals(
751
            SuccessfulSmartServerResponse(('',)), response)
752
753
3691.2.5 by Martin Pool
Add Branch.get_stacked_on_url rpc and tests for same
754
class TestSmartServerBranchRequestGetStackedOnURL(tests.TestCaseWithMemoryTransport):
755
756
    def test_get_stacked_on_url(self):
757
        base_branch = self.make_branch('base', format='1.6')
758
        stacked_branch = self.make_branch('stacked', format='1.6')
759
        # typically should be relative
760
        stacked_branch.set_stacked_on_url('../base')
761
        request = smart.branch.SmartServerBranchRequestGetStackedOnURL(
762
            self.get_transport())
763
        response = request.execute('stacked')
764
        self.assertEquals(
765
            SmartServerResponse(('ok', '../base')),
766
            response)
767
768
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
769
class TestSmartServerBranchRequestLockWrite(tests.TestCaseWithMemoryTransport):
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
770
771
    def setUp(self):
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
772
        tests.TestCaseWithMemoryTransport.setUp(self)
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
773
774
    def test_lock_write_on_unlocked_branch(self):
775
        backing = self.get_transport()
776
        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.
777
        branch = self.make_branch('.', format='knit')
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
778
        repository = branch.repository
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
779
        response = request.execute('')
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
780
        branch_nonce = branch.control_files._lock.peek().get('nonce')
781
        repository_nonce = repository.control_files._lock.peek().get('nonce')
782
        self.assertEqual(
783
            SmartServerResponse(('ok', branch_nonce, repository_nonce)),
784
            response)
785
        # The branch (and associated repository) is now locked.  Verify that
786
        # with a new branch object.
787
        new_branch = repository.bzrdir.open_branch()
788
        self.assertRaises(errors.LockContention, new_branch.lock_write)
789
790
    def test_lock_write_on_locked_branch(self):
791
        backing = self.get_transport()
792
        request = smart.branch.SmartServerBranchRequestLockWrite(backing)
793
        branch = self.make_branch('.')
794
        branch.lock_write()
795
        branch.leave_lock_in_place()
796
        branch.unlock()
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
797
        response = request.execute('')
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
798
        self.assertEqual(
799
            SmartServerResponse(('LockContention',)), response)
800
801
    def test_lock_write_with_tokens_on_locked_branch(self):
802
        backing = self.get_transport()
803
        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.
804
        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).
805
        branch_token = branch.lock_write()
806
        repo_token = branch.repository.lock_write()
807
        branch.repository.unlock()
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
808
        branch.leave_lock_in_place()
809
        branch.repository.leave_lock_in_place()
810
        branch.unlock()
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
811
        response = request.execute('',
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
812
                                   branch_token, repo_token)
813
        self.assertEqual(
814
            SmartServerResponse(('ok', branch_token, repo_token)), response)
815
816
    def test_lock_write_with_mismatched_tokens_on_locked_branch(self):
817
        backing = self.get_transport()
818
        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.
819
        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).
820
        branch_token = branch.lock_write()
821
        repo_token = branch.repository.lock_write()
822
        branch.repository.unlock()
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
823
        branch.leave_lock_in_place()
824
        branch.repository.leave_lock_in_place()
825
        branch.unlock()
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
826
        response = request.execute('',
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
827
                                   branch_token+'xxx', repo_token)
828
        self.assertEqual(
829
            SmartServerResponse(('TokenMismatch',)), response)
830
831
    def test_lock_write_on_locked_repo(self):
832
        backing = self.get_transport()
833
        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.
834
        branch = self.make_branch('.', format='knit')
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
835
        branch.repository.lock_write()
836
        branch.repository.leave_lock_in_place()
837
        branch.repository.unlock()
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
838
        response = request.execute('')
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
839
        self.assertEqual(
840
            SmartServerResponse(('LockContention',)), response)
841
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.
842
    def test_lock_write_on_readonly_transport(self):
843
        backing = self.get_readonly_transport()
844
        request = smart.branch.SmartServerBranchRequestLockWrite(backing)
845
        branch = self.make_branch('.')
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
846
        root = self.get_transport().clone('/')
847
        path = urlutils.relative_url(root.base, self.get_transport().base)
848
        response = request.execute(path)
2872.5.3 by Martin Pool
Pass back LockFailed from smart server lock methods
849
        error_name, lock_str, why_str = response.args
850
        self.assertFalse(response.is_successful())
851
        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.
852
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
853
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
854
class TestSmartServerBranchRequestUnlock(tests.TestCaseWithMemoryTransport):
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
855
856
    def setUp(self):
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
857
        tests.TestCaseWithMemoryTransport.setUp(self)
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
858
859
    def test_unlock_on_locked_branch_and_repo(self):
860
        backing = self.get_transport()
861
        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.
862
        branch = self.make_branch('.', format='knit')
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
863
        # 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).
864
        branch_token = branch.lock_write()
865
        repo_token = branch.repository.lock_write()
866
        branch.repository.unlock()
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
867
        # Unlock the branch (and repo) object, leaving the physical locks
868
        # in place.
869
        branch.leave_lock_in_place()
870
        branch.repository.leave_lock_in_place()
871
        branch.unlock()
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
872
        response = request.execute('',
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
873
                                   branch_token, repo_token)
874
        self.assertEqual(
875
            SmartServerResponse(('ok',)), response)
876
        # The branch is now unlocked.  Verify that with a new branch
877
        # object.
878
        new_branch = branch.bzrdir.open_branch()
879
        new_branch.lock_write()
880
        new_branch.unlock()
881
882
    def test_unlock_on_unlocked_branch_unlocked_repo(self):
883
        backing = self.get_transport()
884
        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.
885
        branch = self.make_branch('.', format='knit')
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
886
        response = request.execute(
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
887
            '', 'branch token', 'repo token')
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
888
        self.assertEqual(
889
            SmartServerResponse(('TokenMismatch',)), response)
890
891
    def test_unlock_on_unlocked_branch_locked_repo(self):
892
        backing = self.get_transport()
893
        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.
894
        branch = self.make_branch('.', format='knit')
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
895
        # Lock the repository.
896
        repo_token = branch.repository.lock_write()
897
        branch.repository.leave_lock_in_place()
898
        branch.repository.unlock()
899
        # Issue branch lock_write request on the unlocked branch (with locked
900
        # repo).
901
        response = request.execute(
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
902
            '', 'branch token', repo_token)
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
903
        self.assertEqual(
904
            SmartServerResponse(('TokenMismatch',)), response)
905
906
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
907
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).
908
909
    def test_no_repository(self):
910
        """Raise NoRepositoryPresent when there is a bzrdir and no repo."""
911
        # we test this using a shared repository above the named path,
912
        # thus checking the right search logic is used - that is, that
913
        # its the exact path being looked at and the server is not
914
        # searching.
915
        backing = self.get_transport()
2018.5.58 by Wouter van Heyst
Small test fixes to reflect naming and documentation
916
        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).
917
        self.make_repository('.', shared=True)
918
        self.make_bzrdir('subdir')
919
        self.assertRaises(errors.NoRepositoryPresent,
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
920
            request.execute, 'subdir')
921
922
3441.5.4 by Andrew Bennetts
Fix test failures, and add some tests for the remote graph heads RPC.
923
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.
924
3211.5.3 by Robert Collins
Adjust size of batch and change gzip comments to bzip2.
925
    def test_trivial_bzipped(self):
926
        # 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.
927
        backing = self.get_transport()
928
        request = smart.repository.SmartServerRepositoryGetParentMap(backing)
929
        tree = self.make_branch_and_memory_tree('.')
930
931
        self.assertEqual(None,
2692.1.24 by Andrew Bennetts
Merge from bzr.dev.
932
            request.execute('', 'missing-id'))
3211.5.3 by Robert Collins
Adjust size of batch and change gzip comments to bzip2.
933
        # 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.
934
        self.assertEqual(
3211.5.2 by Robert Collins
Change RemoteRepository.get_parent_map to use bz2 not gzip for compression.
935
            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.
936
            request.do_body('\n\n0\n'))
937
938
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
939
class TestSmartServerRepositoryGetRevisionGraph(tests.TestCaseWithMemoryTransport):
2018.5.67 by Wouter van Heyst
Implement RemoteRepository.get_revision_graph (Wouter van Heyst, Robert Collins)
940
941
    def test_none_argument(self):
942
        backing = self.get_transport()
943
        request = smart.repository.SmartServerRepositoryGetRevisionGraph(backing)
944
        tree = self.make_branch_and_memory_tree('.')
945
        tree.lock_write()
946
        tree.add('')
947
        r1 = tree.commit('1st commit')
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
948
        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)
949
        tree.unlock()
950
951
        # the lines of revision_id->revision_parent_list has no guaranteed
952
        # order coming out of a dict, so sort both our test and response
953
        lines = sorted([' '.join([r2, r1]), r1])
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
954
        response = request.execute('', '')
2018.5.67 by Wouter van Heyst
Implement RemoteRepository.get_revision_graph (Wouter van Heyst, Robert Collins)
955
        response.body = '\n'.join(sorted(response.body.split('\n')))
956
2018.5.83 by Andrew Bennetts
Fix some test failures caused by the switch from unicode to UTF-8-encoded strs for revision IDs.
957
        self.assertEqual(
958
            SmartServerResponse(('ok', ), '\n'.join(lines)), response)
2018.5.67 by Wouter van Heyst
Implement RemoteRepository.get_revision_graph (Wouter van Heyst, Robert Collins)
959
960
    def test_specific_revision_argument(self):
961
        backing = self.get_transport()
962
        request = smart.repository.SmartServerRepositoryGetRevisionGraph(backing)
963
        tree = self.make_branch_and_memory_tree('.')
964
        tree.lock_write()
965
        tree.add('')
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
966
        rev_id_utf8 = u'\xc9'.encode('utf-8')
967
        r1 = tree.commit('1st commit', rev_id=rev_id_utf8)
968
        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)
969
        tree.unlock()
970
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
971
        self.assertEqual(SmartServerResponse(('ok', ), rev_id_utf8),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
972
            request.execute('', rev_id_utf8))
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
973
2018.5.67 by Wouter van Heyst
Implement RemoteRepository.get_revision_graph (Wouter van Heyst, Robert Collins)
974
    def test_no_such_revision(self):
975
        backing = self.get_transport()
976
        request = smart.repository.SmartServerRepositoryGetRevisionGraph(backing)
977
        tree = self.make_branch_and_memory_tree('.')
978
        tree.lock_write()
979
        tree.add('')
980
        r1 = tree.commit('1st commit')
981
        tree.unlock()
982
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
983
        # Note that it still returns body (of zero bytes).
984
        self.assertEqual(
985
            SmartServerResponse(('nosuchrevision', 'missingrevision', ), ''),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
986
            request.execute('', 'missingrevision'))
987
988
4070.9.14 by Andrew Bennetts
Tweaks requested by Robert's review.
989
class TestSmartServerRepositoryGetStream(tests.TestCaseWithMemoryTransport):
990
991
    def make_two_commit_repo(self):
992
        tree = self.make_branch_and_memory_tree('.')
993
        tree.lock_write()
994
        tree.add('')
995
        r1 = tree.commit('1st commit')
996
        r2 = tree.commit('2nd commit', rev_id=u'\xc8'.encode('utf-8'))
997
        tree.unlock()
998
        repo = tree.branch.repository
999
        return repo, r1, r2
1000
1001
    def test_ancestry_of(self):
1002
        """The search argument may be a 'ancestry-of' some heads'."""
1003
        backing = self.get_transport()
1004
        request = smart.repository.SmartServerRepositoryGetStream(backing)
1005
        repo, r1, r2 = self.make_two_commit_repo()
1006
        fetch_spec = ['ancestry-of', r2]
1007
        lines = '\n'.join(fetch_spec)
1008
        request.execute('', repo._format.network_name())
1009
        response = request.do_body(lines)
1010
        self.assertEqual(('ok',), response.args)
1011
        stream_bytes = ''.join(response.body_stream)
1012
        self.assertStartsWith(stream_bytes, 'Bazaar pack format 1')
1013
1014
    def test_search(self):
1015
        """The search argument may be a 'search' of some explicit keys."""
1016
        backing = self.get_transport()
1017
        request = smart.repository.SmartServerRepositoryGetStream(backing)
1018
        repo, r1, r2 = self.make_two_commit_repo()
1019
        fetch_spec = ['search', '%s %s' % (r1, r2), 'null:', '2']
1020
        lines = '\n'.join(fetch_spec)
1021
        request.execute('', repo._format.network_name())
1022
        response = request.do_body(lines)
1023
        self.assertEqual(('ok',), response.args)
1024
        stream_bytes = ''.join(response.body_stream)
1025
        self.assertStartsWith(stream_bytes, 'Bazaar pack format 1')
1026
1027
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1028
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).
1029
1030
    def test_missing_revision(self):
1031
        """For a missing revision, ('no', ) is returned."""
1032
        backing = self.get_transport()
1033
        request = smart.repository.SmartServerRequestHasRevision(backing)
1034
        self.make_repository('.')
1035
        self.assertEqual(SmartServerResponse(('no', )),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1036
            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).
1037
1038
    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.
1039
        """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).
1040
        backing = self.get_transport()
1041
        request = smart.repository.SmartServerRequestHasRevision(backing)
1042
        tree = self.make_branch_and_memory_tree('.')
1043
        tree.lock_write()
1044
        tree.add('')
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
1045
        rev_id_utf8 = u'\xc8abc'.encode('utf-8')
1046
        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).
1047
        tree.unlock()
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
1048
        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.
1049
        self.assertEqual(SmartServerResponse(('yes', )),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1050
            request.execute('', rev_id_utf8))
1051
1052
1053
class TestSmartServerRepositoryGatherStats(tests.TestCaseWithMemoryTransport):
2018.10.2 by v.ladeuil+lp at free
gather_stats server side and request registration
1054
1055
    def test_empty_revid(self):
1056
        """With an empty revid, we get only size an number and revisions"""
1057
        backing = self.get_transport()
1058
        request = smart.repository.SmartServerRepositoryGatherStats(backing)
1059
        repository = self.make_repository('.')
1060
        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.
1061
        expected_body = 'revisions: 0\n'
2018.10.2 by v.ladeuil+lp at free
gather_stats server side and request registration
1062
        self.assertEqual(SmartServerResponse(('ok', ), expected_body),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1063
                         request.execute('', '', 'no'))
2018.10.2 by v.ladeuil+lp at free
gather_stats server side and request registration
1064
1065
    def test_revid_with_committers(self):
1066
        """For a revid we get more infos."""
1067
        backing = self.get_transport()
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
1068
        rev_id_utf8 = u'\xc8abc'.encode('utf-8')
2018.10.2 by v.ladeuil+lp at free
gather_stats server side and request registration
1069
        request = smart.repository.SmartServerRepositoryGatherStats(backing)
1070
        tree = self.make_branch_and_memory_tree('.')
1071
        tree.lock_write()
1072
        tree.add('')
1073
        # Let's build a predictable result
1074
        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.
1075
        tree.commit('a commit', timestamp=654321.4, timezone=0,
1076
                    rev_id=rev_id_utf8)
2018.10.2 by v.ladeuil+lp at free
gather_stats server side and request registration
1077
        tree.unlock()
1078
1079
        stats = tree.branch.repository.gather_stats()
1080
        expected_body = ('firstrev: 123456.200 3600\n'
1081
                         '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.
1082
                         'revisions: 2\n')
2018.10.2 by v.ladeuil+lp at free
gather_stats server side and request registration
1083
        self.assertEqual(SmartServerResponse(('ok', ), expected_body),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1084
                         request.execute('',
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
1085
                                         rev_id_utf8, 'no'))
2018.10.2 by v.ladeuil+lp at free
gather_stats server side and request registration
1086
1087
    def test_not_empty_repository_with_committers(self):
1088
        """For a revid and requesting committers we get the whole thing."""
1089
        backing = self.get_transport()
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
1090
        rev_id_utf8 = u'\xc8abc'.encode('utf-8')
2018.10.2 by v.ladeuil+lp at free
gather_stats server side and request registration
1091
        request = smart.repository.SmartServerRepositoryGatherStats(backing)
1092
        tree = self.make_branch_and_memory_tree('.')
1093
        tree.lock_write()
1094
        tree.add('')
1095
        # Let's build a predictable result
1096
        tree.commit('a commit', timestamp=123456.2, timezone=3600,
1097
                    committer='foo')
1098
        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.
1099
                    committer='bar', rev_id=rev_id_utf8)
2018.10.2 by v.ladeuil+lp at free
gather_stats server side and request registration
1100
        tree.unlock()
1101
        stats = tree.branch.repository.gather_stats()
1102
1103
        expected_body = ('committers: 2\n'
1104
                         'firstrev: 123456.200 3600\n'
1105
                         '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.
1106
                         'revisions: 2\n')
2018.10.2 by v.ladeuil+lp at free
gather_stats server side and request registration
1107
        self.assertEqual(SmartServerResponse(('ok', ), expected_body),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1108
                         request.execute('',
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
1109
                                         rev_id_utf8, 'yes'))
2018.10.2 by v.ladeuil+lp at free
gather_stats server side and request registration
1110
1111
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1112
class TestSmartServerRepositoryIsShared(tests.TestCaseWithMemoryTransport):
2018.5.57 by Robert Collins
Implement RemoteRepository.is_shared (Robert Collins, Vincent Ladeuil).
1113
1114
    def test_is_shared(self):
1115
        """For a shared repository, ('yes', ) is returned."""
1116
        backing = self.get_transport()
1117
        request = smart.repository.SmartServerRepositoryIsShared(backing)
1118
        self.make_repository('.', shared=True)
1119
        self.assertEqual(SmartServerResponse(('yes', )),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1120
            request.execute('', ))
2018.5.57 by Robert Collins
Implement RemoteRepository.is_shared (Robert Collins, Vincent Ladeuil).
1121
1122
    def test_is_not_shared(self):
2018.5.58 by Wouter van Heyst
Small test fixes to reflect naming and documentation
1123
        """For a shared repository, ('no', ) is returned."""
2018.5.57 by Robert Collins
Implement RemoteRepository.is_shared (Robert Collins, Vincent Ladeuil).
1124
        backing = self.get_transport()
1125
        request = smart.repository.SmartServerRepositoryIsShared(backing)
1126
        self.make_repository('.', shared=False)
1127
        self.assertEqual(SmartServerResponse(('no', )),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1128
            request.execute('', ))
1129
1130
1131
class TestSmartServerRepositoryLockWrite(tests.TestCaseWithMemoryTransport):
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
1132
1133
    def test_lock_write_on_unlocked_repo(self):
1134
        backing = self.get_transport()
1135
        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.
1136
        repository = self.make_repository('.', format='knit')
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1137
        response = request.execute('')
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
1138
        nonce = repository.control_files._lock.peek().get('nonce')
1139
        self.assertEqual(SmartServerResponse(('ok', nonce)), response)
1140
        # The repository is now locked.  Verify that with a new repository
1141
        # object.
1142
        new_repo = repository.bzrdir.open_repository()
1143
        self.assertRaises(errors.LockContention, new_repo.lock_write)
1144
1145
    def test_lock_write_on_locked_repo(self):
1146
        backing = self.get_transport()
1147
        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.
1148
        repository = self.make_repository('.', format='knit')
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
1149
        repository.lock_write()
1150
        repository.leave_lock_in_place()
1151
        repository.unlock()
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1152
        response = request.execute('')
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
1153
        self.assertEqual(
1154
            SmartServerResponse(('LockContention',)), response)
1155
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.
1156
    def test_lock_write_on_readonly_transport(self):
1157
        backing = self.get_readonly_transport()
1158
        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.
1159
        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.
1160
        response = request.execute('')
2872.5.3 by Martin Pool
Pass back LockFailed from smart server lock methods
1161
        self.assertFalse(response.is_successful())
1162
        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.
1163
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
1164
4144.3.1 by Andrew Bennetts
Add Repository.insert_stream_locked server-side implementation, plus tests for server-side _translate_error.
1165
class TestInsertStreamBase(tests.TestCaseWithMemoryTransport):
1166
1167
    def make_empty_byte_stream(self, repo):
1168
        byte_stream = smart.repository._stream_to_byte_stream([], repo._format)
1169
        return ''.join(byte_stream)
1170
1171
1172
class TestSmartServerRepositoryInsertStream(TestInsertStreamBase):
1173
1174
    def test_insert_stream_empty(self):
1175
        backing = self.get_transport()
1176
        request = smart.repository.SmartServerRepositoryInsertStream(backing)
1177
        repository = self.make_repository('.')
1178
        response = request.execute('', '')
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
        
1185
1186
class TestSmartServerRepositoryInsertStreamLocked(TestInsertStreamBase):
1187
1188
    def test_insert_stream_empty(self):
1189
        backing = self.get_transport()
1190
        request = smart.repository.SmartServerRepositoryInsertStreamLocked(
1191
            backing)
1192
        repository = self.make_repository('.', format='knit')
1193
        lock_token = repository.lock_write()
1194
        response = request.execute('', '', lock_token)
1195
        self.assertEqual(None, response)
1196
        response = request.do_chunk(self.make_empty_byte_stream(repository))
1197
        self.assertEqual(None, response)
1198
        response = request.do_end()
1199
        self.assertEqual(SmartServerResponse(('ok', )), response)
1200
        repository.unlock()
1201
1202
    def test_insert_stream_with_wrong_lock_token(self):
1203
        backing = self.get_transport()
1204
        request = smart.repository.SmartServerRepositoryInsertStreamLocked(
1205
            backing)
1206
        repository = self.make_repository('.', format='knit')
1207
        lock_token = repository.lock_write()
1208
        self.assertRaises(
1209
            errors.TokenMismatch, request.execute, '', '', 'wrong-token')
1210
        repository.unlock()
1211
1212
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1213
class TestSmartServerRepositoryUnlock(tests.TestCaseWithMemoryTransport):
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
1214
1215
    def setUp(self):
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1216
        tests.TestCaseWithMemoryTransport.setUp(self)
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
1217
1218
    def test_unlock_on_locked_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')
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
1222
        token = repository.lock_write()
1223
        repository.leave_lock_in_place()
1224
        repository.unlock()
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1225
        response = request.execute('', token)
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
1226
        self.assertEqual(
1227
            SmartServerResponse(('ok',)), response)
1228
        # The repository is now unlocked.  Verify that with a new repository
1229
        # object.
1230
        new_repo = repository.bzrdir.open_repository()
1231
        new_repo.lock_write()
1232
        new_repo.unlock()
1233
1234
    def test_unlock_on_unlocked_repo(self):
1235
        backing = self.get_transport()
1236
        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.
1237
        repository = self.make_repository('.', format='knit')
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1238
        response = request.execute('', 'some token')
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
1239
        self.assertEqual(
1240
            SmartServerResponse(('TokenMismatch',)), response)
1241
1242
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1243
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.
1244
1245
    def test_is_readonly_no(self):
1246
        backing = self.get_transport()
1247
        request = smart.request.SmartServerIsReadonly(backing)
1248
        response = request.execute()
1249
        self.assertEqual(
1250
            SmartServerResponse(('no',)), response)
1251
1252
    def test_is_readonly_yes(self):
1253
        backing = self.get_readonly_transport()
1254
        request = smart.request.SmartServerIsReadonly(backing)
1255
        response = request.execute()
1256
        self.assertEqual(
1257
            SmartServerResponse(('yes',)), response)
1258
1259
4017.3.4 by Robert Collins
Create a verb for Repository.set_make_working_trees.
1260
class TestSmartServerRepositorySetMakeWorkingTrees(tests.TestCaseWithMemoryTransport):
1261
1262
    def test_set_false(self):
1263
        backing = self.get_transport()
1264
        repo = self.make_repository('.', shared=True)
1265
        repo.set_make_working_trees(True)
1266
        request_class = smart.repository.SmartServerRepositorySetMakeWorkingTrees
1267
        request = request_class(backing)
1268
        self.assertEqual(SuccessfulSmartServerResponse(('ok',)),
1269
            request.execute('', 'False'))
1270
        repo = repo.bzrdir.open_repository()
1271
        self.assertFalse(repo.make_working_trees())
1272
1273
    def test_set_true(self):
1274
        backing = self.get_transport()
1275
        repo = self.make_repository('.', shared=True)
1276
        repo.set_make_working_trees(False)
1277
        request_class = smart.repository.SmartServerRepositorySetMakeWorkingTrees
1278
        request = request_class(backing)
1279
        self.assertEqual(SuccessfulSmartServerResponse(('ok',)),
1280
            request.execute('', 'True'))
1281
        repo = repo.bzrdir.open_repository()
1282
        self.assertTrue(repo.make_working_trees())
1283
1284
3801.1.4 by Andrew Bennetts
Add tests for autopack RPC.
1285
class TestSmartServerPackRepositoryAutopack(tests.TestCaseWithTransport):
1286
1287
    def make_repo_needing_autopacking(self, path='.'):
1288
        # Make a repo in need of autopacking.
1289
        tree = self.make_branch_and_tree('.', format='pack-0.92')
1290
        repo = tree.branch.repository
1291
        # monkey-patch the pack collection to disable autopacking
1292
        repo._pack_collection._max_pack_count = lambda count: count
1293
        for x in range(10):
1294
            tree.commit('commit %s' % x)
1295
        self.assertEqual(10, len(repo._pack_collection.names()))
1296
        del repo._pack_collection._max_pack_count
1297
        return repo
1298
1299
    def test_autopack_needed(self):
1300
        repo = self.make_repo_needing_autopacking()
4145.1.6 by Robert Collins
More test fallout, but all caught now.
1301
        repo.lock_write()
1302
        self.addCleanup(repo.unlock)
3801.1.4 by Andrew Bennetts
Add tests for autopack RPC.
1303
        backing = self.get_transport()
1304
        request = smart.packrepository.SmartServerPackRepositoryAutopack(
1305
            backing)
1306
        response = request.execute('')
1307
        self.assertEqual(SmartServerResponse(('ok',)), response)
1308
        repo._pack_collection.reload_pack_names()
1309
        self.assertEqual(1, len(repo._pack_collection.names()))
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
1310
3801.1.4 by Andrew Bennetts
Add tests for autopack RPC.
1311
    def test_autopack_not_needed(self):
1312
        tree = self.make_branch_and_tree('.', format='pack-0.92')
1313
        repo = tree.branch.repository
4145.1.6 by Robert Collins
More test fallout, but all caught now.
1314
        repo.lock_write()
1315
        self.addCleanup(repo.unlock)
3801.1.4 by Andrew Bennetts
Add tests for autopack RPC.
1316
        for x in range(9):
1317
            tree.commit('commit %s' % x)
1318
        backing = self.get_transport()
1319
        request = smart.packrepository.SmartServerPackRepositoryAutopack(
1320
            backing)
1321
        response = request.execute('')
1322
        self.assertEqual(SmartServerResponse(('ok',)), response)
1323
        repo._pack_collection.reload_pack_names()
1324
        self.assertEqual(9, len(repo._pack_collection.names()))
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
1325
3801.1.4 by Andrew Bennetts
Add tests for autopack RPC.
1326
    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.
1327
        """A request to autopack a non-pack repo is a no-op."""
3801.1.4 by Andrew Bennetts
Add tests for autopack RPC.
1328
        repo = self.make_repository('.', format='knit')
1329
        backing = self.get_transport()
1330
        request = smart.packrepository.SmartServerPackRepositoryAutopack(
1331
            backing)
1332
        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.
1333
        self.assertEqual(SmartServerResponse(('ok',)), response)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
1334
3801.1.4 by Andrew Bennetts
Add tests for autopack RPC.
1335
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
1336
class TestHandlers(tests.TestCase):
1337
    """Tests for the request.request_handlers object."""
1338
3526.3.1 by Andrew Bennetts
Remove registrations of defunct HPSS verbs.
1339
    def test_all_registrations_exist(self):
1340
        """All registered request_handlers can be found."""
1341
        # If there's a typo in a register_lazy call, this loop will fail with
1342
        # an AttributeError.
1343
        for key, item in smart.request.request_handlers.iteritems():
1344
            pass
1345
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
1346
    def test_registered_methods(self):
1347
        """Test that known methods are registered to the correct object."""
1348
        self.assertEqual(
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
1349
            smart.request.request_handlers.get('Branch.get_config_file'),
1350
            smart.branch.SmartServerBranchGetConfigFile)
1351
        self.assertEqual(
4078.2.1 by Robert Collins
Add a Branch.get_parent remote call for RemoteBranch.
1352
            smart.request.request_handlers.get('Branch.get_parent'),
1353
            smart.branch.SmartServerBranchGetParent)
1354
        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.
1355
            smart.request.request_handlers.get('Branch.get_tags_bytes'),
1356
            smart.branch.SmartServerBranchGetTagsBytes)
1357
        self.assertEqual(
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1358
            smart.request.request_handlers.get('Branch.lock_write'),
1359
            smart.branch.SmartServerBranchRequestLockWrite)
1360
        self.assertEqual(
2018.5.51 by Wouter van Heyst
Test and implement RemoteBranch.last_revision_info()
1361
            smart.request.request_handlers.get('Branch.last_revision_info'),
1362
            smart.branch.SmartServerBranchRequestLastRevisionInfo)
1363
        self.assertEqual(
2018.5.38 by Robert Collins
Implement RemoteBranch.revision_history().
1364
            smart.request.request_handlers.get('Branch.revision_history'),
1365
            smart.branch.SmartServerRequestRevisionHistory)
1366
        self.assertEqual(
2018.5.77 by Wouter van Heyst
Fix typo in request_handlers registration of Branch.set_last_revision, and test that registration
1367
            smart.request.request_handlers.get('Branch.set_last_revision'),
1368
            smart.branch.SmartServerBranchRequestSetLastRevision)
1369
        self.assertEqual(
2892.2.1 by Andrew Bennetts
Add Branch.set_last_revision_info smart method, and make the RemoteBranch client use it.
1370
            smart.request.request_handlers.get('Branch.set_last_revision_info'),
1371
            smart.branch.SmartServerBranchRequestSetLastRevisionInfo)
1372
        self.assertEqual(
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1373
            smart.request.request_handlers.get('Branch.unlock'),
1374
            smart.branch.SmartServerBranchRequestUnlock)
1375
        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.
1376
            smart.request.request_handlers.get('BzrDir.find_repository'),
3221.3.2 by Robert Collins
* New remote method ``RemoteBzrDir.find_repositoryV2`` adding support for
1377
            smart.bzrdir.SmartServerRequestFindRepositoryV1)
1378
        self.assertEqual(
1379
            smart.request.request_handlers.get('BzrDir.find_repositoryV2'),
1380
            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.
1381
        self.assertEqual(
2018.5.42 by Robert Collins
Various hopefully improvements, but wsgi is broken, handing over to spiv :).
1382
            smart.request.request_handlers.get('BzrDirFormat.initialize'),
1383
            smart.bzrdir.SmartServerRequestInitializeBzrDir)
1384
        self.assertEqual(
4070.2.3 by Robert Collins
Get BzrDir.cloning_metadir working.
1385
            smart.request.request_handlers.get('BzrDir.cloning_metadir'),
1386
            smart.bzrdir.SmartServerBzrDirRequestCloningMetaDir)
1387
        self.assertEqual(
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
1388
            smart.request.request_handlers.get('BzrDir.open_branch'),
1389
            smart.bzrdir.SmartServerRequestOpenBranch)
2018.5.40 by Robert Collins
Implement a remote Repository.has_revision method.
1390
        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.
1391
            smart.request.request_handlers.get('BzrDir.open_branchV2'),
1392
            smart.bzrdir.SmartServerRequestOpenBranchV2)
1393
        self.assertEqual(
3801.1.4 by Andrew Bennetts
Add tests for autopack RPC.
1394
            smart.request.request_handlers.get('PackRepository.autopack'),
1395
            smart.packrepository.SmartServerPackRepositoryAutopack)
1396
        self.assertEqual(
2018.10.2 by v.ladeuil+lp at free
gather_stats server side and request registration
1397
            smart.request.request_handlers.get('Repository.gather_stats'),
1398
            smart.repository.SmartServerRepositoryGatherStats)
1399
        self.assertEqual(
3172.5.6 by Robert Collins
Create new smart server verb Repository.get_parent_map.
1400
            smart.request.request_handlers.get('Repository.get_parent_map'),
1401
            smart.repository.SmartServerRepositoryGetParentMap)
1402
        self.assertEqual(
2535.3.69 by Andrew Bennetts
Add check for Repository.stream_knit_data_for_revisions to TestHandlers.test_registered_methods.
1403
            smart.request.request_handlers.get(
1404
                'Repository.get_revision_graph'),
2018.5.67 by Wouter van Heyst
Implement RemoteRepository.get_revision_graph (Wouter van Heyst, Robert Collins)
1405
            smart.repository.SmartServerRepositoryGetRevisionGraph)
1406
        self.assertEqual(
4144.3.1 by Andrew Bennetts
Add Repository.insert_stream_locked server-side implementation, plus tests for server-side _translate_error.
1407
            smart.request.request_handlers.get('Repository.get_stream'),
1408
            smart.repository.SmartServerRepositoryGetStream)
1409
        self.assertEqual(
2018.5.40 by Robert Collins
Implement a remote Repository.has_revision method.
1410
            smart.request.request_handlers.get('Repository.has_revision'),
1411
            smart.repository.SmartServerRequestHasRevision)
2018.5.57 by Robert Collins
Implement RemoteRepository.is_shared (Robert Collins, Vincent Ladeuil).
1412
        self.assertEqual(
4144.3.1 by Andrew Bennetts
Add Repository.insert_stream_locked server-side implementation, plus tests for server-side _translate_error.
1413
            smart.request.request_handlers.get('Repository.insert_stream'),
1414
            smart.repository.SmartServerRepositoryInsertStream)
1415
        self.assertEqual(
1416
            smart.request.request_handlers.get('Repository.insert_stream_locked'),
1417
            smart.repository.SmartServerRepositoryInsertStreamLocked)
1418
        self.assertEqual(
2018.5.57 by Robert Collins
Implement RemoteRepository.is_shared (Robert Collins, Vincent Ladeuil).
1419
            smart.request.request_handlers.get('Repository.is_shared'),
1420
            smart.repository.SmartServerRepositoryIsShared)
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
1421
        self.assertEqual(
1422
            smart.request.request_handlers.get('Repository.lock_write'),
1423
            smart.repository.SmartServerRepositoryLockWrite)
1424
        self.assertEqual(
2535.3.69 by Andrew Bennetts
Add check for Repository.stream_knit_data_for_revisions to TestHandlers.test_registered_methods.
1425
            smart.request.request_handlers.get('Repository.tarball'),
1426
            smart.repository.SmartServerRepositoryTarball)
1427
        self.assertEqual(
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
1428
            smart.request.request_handlers.get('Repository.unlock'),
1429
            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.
1430
        self.assertEqual(
1431
            smart.request.request_handlers.get('Transport.is_readonly'),
1432
            smart.request.SmartServerIsReadonly)