/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
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
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 (
2694.5.4 by Jelmer Vernooij
Move bzrlib.util.bencode to bzrlib._bencode_py.
32
    bencode,
2692.1.2 by Andrew Bennetts
Merge from bzr.dev.
33
    bzrdir,
34
    errors,
35
    pack,
36
    smart,
37
    tests,
38
    urlutils,
4634.19.1 by Robert Collins
Combine adjacent substreams of the same type in bzrlib.smart.repository._byte_stream_to_stream.
39
    versionedfile,
2692.1.2 by Andrew Bennetts
Merge from bzr.dev.
40
    )
3577.1.1 by Andrew Bennetts
Cherry-pick TipChangeRejected changes from pre-branch-tip-changed-hook loom.
41
from bzrlib.branch import Branch, BranchReferenceFormat
2692.1.22 by Andrew Bennetts
Reinstate imports needed to run test_smart alone.
42
import bzrlib.smart.branch
4070.2.3 by Robert Collins
Get BzrDir.cloning_metadir working.
43
import bzrlib.smart.bzrdir, bzrlib.smart.bzrdir as smart_dir
44
import bzrlib.smart.packrepository
2692.1.22 by Andrew Bennetts
Reinstate imports needed to run test_smart alone.
45
import bzrlib.smart.repository
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
46
from bzrlib.smart.request import (
47
    FailedSmartServerResponse,
48
    SmartServerRequest,
49
    SmartServerResponse,
50
    SuccessfulSmartServerResponse,
51
    )
3221.3.2 by Robert Collins
* New remote method ``RemoteBzrDir.find_repositoryV2`` adding support for
52
from bzrlib.tests import (
53
    split_suite_by_re,
54
    )
2692.1.3 by Andrew Bennetts
Fix imports so that tests in test_smart.py can be run alone.
55
from bzrlib.transport import chroot, get_transport
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
56
57
3221.3.2 by Robert Collins
* New remote method ``RemoteBzrDir.find_repositoryV2`` adding support for
58
def load_tests(standard_tests, module, loader):
59
    """Multiply tests version and protocol consistency."""
60
    # FindRepository tests.
61
    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.
62
    scenarios = [
3221.3.2 by Robert Collins
* New remote method ``RemoteBzrDir.find_repositoryV2`` adding support for
63
        ("find_repository", {
64
            "_request_class":bzrdir_mod.SmartServerRequestFindRepositoryV1}),
65
        ("find_repositoryV2", {
66
            "_request_class":bzrdir_mod.SmartServerRequestFindRepositoryV2}),
4053.1.4 by Robert Collins
Move the fetch control attributes from Repository to RepositoryFormat.
67
        ("find_repositoryV3", {
68
            "_request_class":bzrdir_mod.SmartServerRequestFindRepositoryV3}),
3221.3.2 by Robert Collins
* New remote method ``RemoteBzrDir.find_repositoryV2`` adding support for
69
        ]
70
    to_adapt, result = split_suite_by_re(standard_tests,
71
        "TestSmartServerRequestFindRepository")
72
    v2_only, v1_and_2 = split_suite_by_re(to_adapt,
73
        "_v2")
4084.5.1 by Robert Collins
Bulk update all test adaptation into a single approach, using multiply_tests rather than test adapters.
74
    tests.multiply_tests(v1_and_2, scenarios, result)
75
    # The first scenario is only applicable to v1 protocols, it is deleted
76
    # since.
77
    tests.multiply_tests(v2_only, scenarios[1:], result)
3221.3.2 by Robert Collins
* New remote method ``RemoteBzrDir.find_repositoryV2`` adding support for
78
    return result
79
80
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
81
class TestCaseWithChrootedTransport(tests.TestCaseWithTransport):
82
83
    def setUp(self):
84
        tests.TestCaseWithTransport.setUp(self)
85
        self._chroot_server = None
86
87
    def get_transport(self, relpath=None):
88
        if self._chroot_server is None:
89
            backing_transport = tests.TestCaseWithTransport.get_transport(self)
90
            self._chroot_server = chroot.ChrootServer(backing_transport)
4659.1.2 by Robert Collins
Refactor creation and shutdown of test servers to use a common helper,
91
            self.start_server(self._chroot_server)
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
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
4634.19.1 by Robert Collins
Combine adjacent substreams of the same type in bzrlib.smart.repository._byte_stream_to_stream.
116
class TestByteStreamToStream(tests.TestCase):
117
118
    def test_repeated_substreams_same_kind_are_one_stream(self):
119
        # Make a stream - an iterable of bytestrings.
120
        stream = [('text', [versionedfile.FulltextContentFactory(('k1',), None,
121
            None, 'foo')]),('text', [
122
            versionedfile.FulltextContentFactory(('k2',), None, None, 'bar')])]
123
        fmt = bzrdir.format_registry.get('pack-0.92')().repository_format
124
        bytes = smart.repository._stream_to_byte_stream(stream, fmt)
125
        streams = []
126
        # Iterate the resulting iterable; checking that we get only one stream
127
        # out.
128
        fmt, stream = smart.repository._byte_stream_to_stream(bytes)
129
        for kind, substream in stream:
130
            streams.append((kind, list(substream)))
131
        self.assertLength(1, streams)
132
        self.assertLength(2, streams[0][1])
133
134
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
135
class TestSmartServerResponse(tests.TestCase):
136
137
    def test__eq__(self):
138
        self.assertEqual(SmartServerResponse(('ok', )),
139
            SmartServerResponse(('ok', )))
140
        self.assertEqual(SmartServerResponse(('ok', ), 'body'),
141
            SmartServerResponse(('ok', ), 'body'))
142
        self.assertNotEqual(SmartServerResponse(('ok', )),
143
            SmartServerResponse(('notok', )))
144
        self.assertNotEqual(SmartServerResponse(('ok', ), 'body'),
145
            SmartServerResponse(('ok', )))
2018.5.41 by Robert Collins
Fix SmartServerResponse.__eq__ to handle None.
146
        self.assertNotEqual(None,
147
            SmartServerResponse(('ok', )))
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
148
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
149
    def test__str__(self):
150
        """SmartServerResponses can be stringified."""
151
        self.assertEqual(
3691.2.6 by Martin Pool
Disable RemoteBranch stacking, but get get_stacked_on_url working, and passing back exceptions
152
            "<SuccessfulSmartServerResponse args=('args',) body='body'>",
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
153
            str(SuccessfulSmartServerResponse(('args',), 'body')))
154
        self.assertEqual(
3691.2.6 by Martin Pool
Disable RemoteBranch stacking, but get get_stacked_on_url working, and passing back exceptions
155
            "<FailedSmartServerResponse args=('args',) body='body'>",
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
156
            str(FailedSmartServerResponse(('args',), 'body')))
157
158
159
class TestSmartServerRequest(tests.TestCaseWithMemoryTransport):
160
161
    def test_translate_client_path(self):
162
        transport = self.get_transport()
163
        request = SmartServerRequest(transport, 'foo/')
164
        self.assertEqual('./', request.translate_client_path('foo/'))
165
        self.assertRaises(
166
            errors.InvalidURLJoin, request.translate_client_path, 'foo/..')
167
        self.assertRaises(
168
            errors.PathNotChild, request.translate_client_path, '/')
169
        self.assertRaises(
170
            errors.PathNotChild, request.translate_client_path, 'bar/')
171
        self.assertEqual('./baz', request.translate_client_path('foo/baz'))
172
173
    def test_transport_from_client_path(self):
174
        transport = self.get_transport()
175
        request = SmartServerRequest(transport, 'foo/')
176
        self.assertEqual(
177
            transport.base,
178
            request.transport_from_client_path('foo/').base)
179
180
4070.2.3 by Robert Collins
Get BzrDir.cloning_metadir working.
181
class TestSmartServerBzrDirRequestCloningMetaDir(
182
    tests.TestCaseWithMemoryTransport):
183
    """Tests for BzrDir.cloning_metadir."""
184
185
    def test_cloning_metadir(self):
186
        """When there is a bzrdir present, the call succeeds."""
187
        backing = self.get_transport()
188
        dir = self.make_bzrdir('.')
189
        local_result = dir.cloning_metadir()
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
            ('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).
196
        self.assertEqual(expected, request.execute('', 'False'))
197
198
    def test_cloning_metadir_reference(self):
4160.2.9 by Andrew Bennetts
Fix BzrDir.cloning_metadir RPC to fail on branch references, and make
199
        """The request fails when bzrdir contains a branch reference."""
4070.7.4 by Andrew Bennetts
Deal with branch references better in BzrDir.cloning_metadir RPC (changes protocol).
200
        backing = self.get_transport()
201
        referenced_branch = self.make_branch('referenced')
202
        dir = self.make_bzrdir('.')
203
        local_result = dir.cloning_metadir()
204
        reference = BranchReferenceFormat().initialize(dir, referenced_branch)
205
        reference_url = BranchReferenceFormat().get_reference(dir)
206
        # The server shouldn't try to follow the branch reference, so it's fine
207
        # if the referenced branch isn't reachable.
208
        backing.rename('referenced', 'moved')
209
        request_class = smart_dir.SmartServerBzrDirRequestCloningMetaDir
210
        request = request_class(backing)
4160.2.9 by Andrew Bennetts
Fix BzrDir.cloning_metadir RPC to fail on branch references, and make
211
        expected = FailedSmartServerResponse(('BranchReference',))
4070.2.3 by Robert Collins
Get BzrDir.cloning_metadir working.
212
        self.assertEqual(expected, request.execute('', 'False'))
213
214
4017.3.2 by Robert Collins
Reduce the number of round trips required to create a repository over the network.
215
class TestSmartServerRequestCreateRepository(tests.TestCaseWithMemoryTransport):
216
    """Tests for BzrDir.create_repository."""
217
218
    def test_makes_repository(self):
219
        """When there is a bzrdir present, the call succeeds."""
220
        backing = self.get_transport()
221
        self.make_bzrdir('.')
222
        request_class = bzrlib.smart.bzrdir.SmartServerRequestCreateRepository
223
        request = request_class(backing)
4606.3.1 by Robert Collins
Make test_smart tests more stable when the default format changes.
224
        reference_bzrdir_format = bzrdir.format_registry.get('pack-0.92')()
4017.3.2 by Robert Collins
Reduce the number of round trips required to create a repository over the network.
225
        reference_format = reference_bzrdir_format.repository_format
226
        network_name = reference_format.network_name()
227
        expected = SuccessfulSmartServerResponse(
228
            ('ok', 'no', 'no', 'no', network_name))
229
        self.assertEqual(expected, request.execute('', network_name, 'True'))
230
231
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
232
class TestSmartServerRequestFindRepository(tests.TestCaseWithMemoryTransport):
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
233
    """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.
234
235
    def test_no_repository(self):
236
        """When there is no repository to be found, ('norepository', ) is returned."""
237
        backing = self.get_transport()
3221.3.2 by Robert Collins
* New remote method ``RemoteBzrDir.find_repositoryV2`` adding support for
238
        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.
239
        self.make_bzrdir('.')
240
        self.assertEqual(SmartServerResponse(('norepository', )),
2692.1.19 by Andrew Bennetts
Tweak for consistency suggested by John's review.
241
            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.
242
243
    def test_nonshared_repository(self):
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
244
        # nonshared repositorys only allow 'find' to return a handle when the
245
        # 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.
246
        # the repository is at.
247
        backing = self.get_transport()
3221.3.2 by Robert Collins
* New remote method ``RemoteBzrDir.find_repositoryV2`` adding support for
248
        request = self._request_class(backing)
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
249
        result = self._make_repository_and_result()
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
250
        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.
251
        self.make_bzrdir('subdir')
252
        self.assertEqual(SmartServerResponse(('norepository', )),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
253
            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.
254
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
255
    def _make_repository_and_result(self, shared=False, format=None):
256
        """Convenience function to setup a repository.
257
258
        :result: The SmartServerResponse to expect when opening it.
259
        """
260
        repo = self.make_repository('.', shared=shared, format=format)
261
        if repo.supports_rich_root():
2018.5.166 by Andrew Bennetts
Small changes in response to Aaron's review.
262
            rich_root = 'yes'
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
263
        else:
2018.5.166 by Andrew Bennetts
Small changes in response to Aaron's review.
264
            rich_root = 'no'
2018.5.138 by Robert Collins
Merge bzr.dev.
265
        if repo._format.supports_tree_reference:
2018.5.166 by Andrew Bennetts
Small changes in response to Aaron's review.
266
            subtrees = 'yes'
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
267
        else:
2018.5.166 by Andrew Bennetts
Small changes in response to Aaron's review.
268
            subtrees = 'no'
4606.3.1 by Robert Collins
Make test_smart tests more stable when the default format changes.
269
        if repo._format.supports_external_lookups:
270
            external = 'yes'
271
        else:
272
            external = 'no'
4053.1.4 by Robert Collins
Move the fetch control attributes from Repository to RepositoryFormat.
273
        if (smart.bzrdir.SmartServerRequestFindRepositoryV3 ==
274
            self._request_class):
275
            return SuccessfulSmartServerResponse(
4606.3.1 by Robert Collins
Make test_smart tests more stable when the default format changes.
276
                ('ok', '', rich_root, subtrees, external,
4053.1.4 by Robert Collins
Move the fetch control attributes from Repository to RepositoryFormat.
277
                 repo._format.network_name()))
278
        elif (smart.bzrdir.SmartServerRequestFindRepositoryV2 ==
3221.3.2 by Robert Collins
* New remote method ``RemoteBzrDir.find_repositoryV2`` adding support for
279
            self._request_class):
280
            # All tests so far are on formats, and for non-external
281
            # repositories.
282
            return SuccessfulSmartServerResponse(
4606.3.1 by Robert Collins
Make test_smart tests more stable when the default format changes.
283
                ('ok', '', rich_root, subtrees, external))
3221.3.2 by Robert Collins
* New remote method ``RemoteBzrDir.find_repositoryV2`` adding support for
284
        else:
285
            return SuccessfulSmartServerResponse(('ok', '', rich_root, subtrees))
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
286
2018.5.34 by Robert Collins
Get test_remote.BasicRemoteObjectTests.test_open_remote_branch passing by implementing a remote method BzrDir.find_repository.
287
    def test_shared_repository(self):
288
        """When there is a shared repository, we get 'ok', 'relpath-to-repo'."""
289
        backing = self.get_transport()
3221.3.2 by Robert Collins
* New remote method ``RemoteBzrDir.find_repositoryV2`` adding support for
290
        request = self._request_class(backing)
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
291
        result = self._make_repository_and_result(shared=True)
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
292
        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.
293
        self.make_bzrdir('subdir')
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
294
        result2 = SmartServerResponse(result.args[0:1] + ('..', ) + result.args[2:])
295
        self.assertEqual(result2,
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
296
            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.
297
        self.make_bzrdir('subdir/deeper')
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
298
        result3 = SmartServerResponse(result.args[0:1] + ('../..', ) + result.args[2:])
299
        self.assertEqual(result3,
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
300
            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.
301
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
302
    def test_rich_root_and_subtree_encoding(self):
303
        """Test for the format attributes for rich root and subtree support."""
304
        backing = self.get_transport()
3221.3.2 by Robert Collins
* New remote method ``RemoteBzrDir.find_repositoryV2`` adding support for
305
        request = self._request_class(backing)
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
306
        result = self._make_repository_and_result(format='dirstate-with-subtree')
307
        # check the test will be valid
2018.5.166 by Andrew Bennetts
Small changes in response to Aaron's review.
308
        self.assertEqual('yes', result.args[2])
309
        self.assertEqual('yes', result.args[3])
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
310
        self.assertEqual(result, request.execute(''))
311
3221.3.2 by Robert Collins
* New remote method ``RemoteBzrDir.find_repositoryV2`` adding support for
312
    def test_supports_external_lookups_no_v2(self):
313
        """Test for the supports_external_lookups attribute."""
314
        backing = self.get_transport()
315
        request = self._request_class(backing)
316
        result = self._make_repository_and_result(format='dirstate-with-subtree')
317
        # check the test will be valid
318
        self.assertEqual('no', result.args[4])
2692.1.24 by Andrew Bennetts
Merge from bzr.dev.
319
        self.assertEqual(result, request.execute(''))
320
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
321
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
322
class TestSmartServerBzrDirRequestGetConfigFile(
323
    tests.TestCaseWithMemoryTransport):
324
    """Tests for BzrDir.get_config_file."""
325
326
    def test_present(self):
327
        backing = self.get_transport()
328
        dir = self.make_bzrdir('.')
329
        dir.get_config().set_default_stack_on("/")
330
        local_result = dir._get_config()._get_config_file().read()
331
        request_class = smart_dir.SmartServerBzrDirRequestConfigFile
332
        request = request_class(backing)
333
        expected = SuccessfulSmartServerResponse((), local_result)
334
        self.assertEqual(expected, request.execute(''))
335
336
    def test_missing(self):
337
        backing = self.get_transport()
338
        dir = self.make_bzrdir('.')
339
        request_class = smart_dir.SmartServerBzrDirRequestConfigFile
340
        request = request_class(backing)
341
        expected = SuccessfulSmartServerResponse((), '')
342
        self.assertEqual(expected, request.execute(''))
343
344
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
345
class TestSmartServerRequestInitializeBzrDir(tests.TestCaseWithMemoryTransport):
2018.5.42 by Robert Collins
Various hopefully improvements, but wsgi is broken, handing over to spiv :).
346
347
    def test_empty_dir(self):
348
        """Initializing an empty dir should succeed and do it."""
349
        backing = self.get_transport()
350
        request = smart.bzrdir.SmartServerRequestInitializeBzrDir(backing)
351
        self.assertEqual(SmartServerResponse(('ok', )),
2692.1.20 by Andrew Bennetts
Tweak for consistency suggested by John's review.
352
            request.execute(''))
2018.5.42 by Robert Collins
Various hopefully improvements, but wsgi is broken, handing over to spiv :).
353
        made_dir = bzrdir.BzrDir.open_from_transport(backing)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
354
        # 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 :).
355
        # default formart.
356
        self.assertRaises(errors.NoWorkingTree, made_dir.open_workingtree)
357
        self.assertRaises(errors.NotBranchError, made_dir.open_branch)
358
        self.assertRaises(errors.NoRepositoryPresent, made_dir.open_repository)
359
360
    def test_missing_dir(self):
361
        """Initializing a missing directory should fail like the bzrdir api."""
362
        backing = self.get_transport()
363
        request = smart.bzrdir.SmartServerRequestInitializeBzrDir(backing)
364
        self.assertRaises(errors.NoSuchFile,
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
365
            request.execute, 'subdir')
2018.5.42 by Robert Collins
Various hopefully improvements, but wsgi is broken, handing over to spiv :).
366
367
    def test_initialized_dir(self):
368
        """Initializing an extant bzrdir should fail like the bzrdir api."""
369
        backing = self.get_transport()
370
        request = smart.bzrdir.SmartServerRequestInitializeBzrDir(backing)
371
        self.make_bzrdir('subdir')
372
        self.assertRaises(errors.FileExists,
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
373
            request.execute, 'subdir')
374
375
4294.2.7 by Robert Collins
Start building up a BzrDir.initialize_ex verb for the smart server.
376
class TestSmartServerRequestBzrDirInitializeEx(tests.TestCaseWithMemoryTransport):
4436.1.1 by Andrew Bennetts
Rename BzrDirFormat.initialize_ex verb to BzrDirFormat.initialize_ex_1.16.
377
    """Basic tests for BzrDir.initialize_ex_1.16 in the smart server.
4294.2.7 by Robert Collins
Start building up a BzrDir.initialize_ex verb for the smart server.
378
4294.2.10 by Robert Collins
Review feedback.
379
    The main unit tests in test_bzrdir exercise the API comprehensively.
4294.2.7 by Robert Collins
Start building up a BzrDir.initialize_ex verb for the smart server.
380
    """
381
382
    def test_empty_dir(self):
383
        """Initializing an empty dir should succeed and do it."""
384
        backing = self.get_transport()
4294.2.8 by Robert Collins
Reduce round trips pushing new branches substantially.
385
        name = self.make_bzrdir('reference')._format.network_name()
4294.2.7 by Robert Collins
Start building up a BzrDir.initialize_ex verb for the smart server.
386
        request = smart.bzrdir.SmartServerRequestBzrDirInitializeEx(backing)
4294.2.8 by Robert Collins
Reduce round trips pushing new branches substantially.
387
        self.assertEqual(SmartServerResponse(('', '', '', '', '', '', name,
4307.2.2 by Robert Collins
Lock repositories created by BzrDirFormat.initialize_on_transport_ex.
388
            'False', '', '', '')),
4294.2.8 by Robert Collins
Reduce round trips pushing new branches substantially.
389
            request.execute(name, '', 'True', 'False', 'False', '', '', '', '',
390
            'False'))
4294.2.7 by Robert Collins
Start building up a BzrDir.initialize_ex verb for the smart server.
391
        made_dir = bzrdir.BzrDir.open_from_transport(backing)
392
        # no branch, tree or repository is expected with the current
4294.2.10 by Robert Collins
Review feedback.
393
        # default format.
4294.2.7 by Robert Collins
Start building up a BzrDir.initialize_ex verb for the smart server.
394
        self.assertRaises(errors.NoWorkingTree, made_dir.open_workingtree)
395
        self.assertRaises(errors.NotBranchError, made_dir.open_branch)
396
        self.assertRaises(errors.NoRepositoryPresent, made_dir.open_repository)
397
398
    def test_missing_dir(self):
399
        """Initializing a missing directory should fail like the bzrdir api."""
400
        backing = self.get_transport()
4294.2.8 by Robert Collins
Reduce round trips pushing new branches substantially.
401
        name = self.make_bzrdir('reference')._format.network_name()
4294.2.7 by Robert Collins
Start building up a BzrDir.initialize_ex verb for the smart server.
402
        request = smart.bzrdir.SmartServerRequestBzrDirInitializeEx(backing)
4294.2.8 by Robert Collins
Reduce round trips pushing new branches substantially.
403
        self.assertRaises(errors.NoSuchFile, request.execute, name,
404
            'subdir/dir', 'False', 'False', 'False', '', '', '', '', 'False')
4294.2.7 by Robert Collins
Start building up a BzrDir.initialize_ex verb for the smart server.
405
406
    def test_initialized_dir(self):
4416.3.4 by Jonathan Lange
Fix a typo.
407
        """Initializing an extant directory should fail like the bzrdir api."""
4294.2.7 by Robert Collins
Start building up a BzrDir.initialize_ex verb for the smart server.
408
        backing = self.get_transport()
4294.2.8 by Robert Collins
Reduce round trips pushing new branches substantially.
409
        name = self.make_bzrdir('reference')._format.network_name()
4294.2.7 by Robert Collins
Start building up a BzrDir.initialize_ex verb for the smart server.
410
        request = smart.bzrdir.SmartServerRequestBzrDirInitializeEx(backing)
411
        self.make_bzrdir('subdir')
4294.2.8 by Robert Collins
Reduce round trips pushing new branches substantially.
412
        self.assertRaises(errors.FileExists, request.execute, name, 'subdir',
413
            'False', 'False', 'False', '', '', '', '', 'False')
4294.2.7 by Robert Collins
Start building up a BzrDir.initialize_ex verb for the smart server.
414
415
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
416
class TestSmartServerRequestOpenBranch(TestCaseWithChrootedTransport):
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
417
418
    def test_no_branch(self):
419
        """When there is no branch, ('nobranch', ) is returned."""
420
        backing = self.get_transport()
421
        request = smart.bzrdir.SmartServerRequestOpenBranch(backing)
422
        self.make_bzrdir('.')
423
        self.assertEqual(SmartServerResponse(('nobranch', )),
2692.1.20 by Andrew Bennetts
Tweak for consistency suggested by John's review.
424
            request.execute(''))
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
425
426
    def test_branch(self):
427
        """When there is a branch, 'ok' is returned."""
428
        backing = self.get_transport()
429
        request = smart.bzrdir.SmartServerRequestOpenBranch(backing)
430
        self.make_branch('.')
431
        self.assertEqual(SmartServerResponse(('ok', '')),
2692.1.20 by Andrew Bennetts
Tweak for consistency suggested by John's review.
432
            request.execute(''))
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
433
434
    def test_branch_reference(self):
435
        """When there is a branch reference, the reference URL is returned."""
436
        backing = self.get_transport()
437
        request = smart.bzrdir.SmartServerRequestOpenBranch(backing)
438
        branch = self.make_branch('branch')
439
        checkout = branch.create_checkout('reference',lightweight=True)
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
440
        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.
441
        self.assertFileEqual(reference_url, 'reference/.bzr/branch/location')
442
        self.assertEqual(SmartServerResponse(('ok', reference_url)),
2692.1.20 by Andrew Bennetts
Tweak for consistency suggested by John's review.
443
            request.execute('reference'))
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
444
445
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.
446
class TestSmartServerRequestOpenBranchV2(TestCaseWithChrootedTransport):
447
448
    def test_no_branch(self):
449
        """When there is no branch, ('nobranch', ) is returned."""
450
        backing = self.get_transport()
451
        self.make_bzrdir('.')
452
        request = smart.bzrdir.SmartServerRequestOpenBranchV2(backing)
453
        self.assertEqual(SmartServerResponse(('nobranch', )),
454
            request.execute(''))
455
456
    def test_branch(self):
457
        """When there is a branch, 'ok' is returned."""
458
        backing = self.get_transport()
459
        expected = self.make_branch('.')._format.network_name()
460
        request = smart.bzrdir.SmartServerRequestOpenBranchV2(backing)
461
        self.assertEqual(SuccessfulSmartServerResponse(('branch', expected)),
462
            request.execute(''))
463
464
    def test_branch_reference(self):
465
        """When there is a branch reference, the reference URL is returned."""
466
        backing = self.get_transport()
467
        request = smart.bzrdir.SmartServerRequestOpenBranchV2(backing)
468
        branch = self.make_branch('branch')
469
        checkout = branch.create_checkout('reference',lightweight=True)
470
        reference_url = BranchReferenceFormat().get_reference(checkout.bzrdir)
471
        self.assertFileEqual(reference_url, 'reference/.bzr/branch/location')
472
        self.assertEqual(SuccessfulSmartServerResponse(('ref', reference_url)),
473
            request.execute('reference'))
474
4160.2.1 by Andrew Bennetts
Failing test for BzrDir.open_branchV2 RPC not opening stacked-on branch.
475
    def test_stacked_branch(self):
476
        """Opening a stacked branch does not open the stacked-on branch."""
477
        trunk = self.make_branch('trunk')
4599.4.30 by Robert Collins
Remove hard coded format in test_smart's test_stacked_branch now the default format stacks.
478
        feature = self.make_branch('feature')
4160.2.1 by Andrew Bennetts
Failing test for BzrDir.open_branchV2 RPC not opening stacked-on branch.
479
        feature.set_stacked_on_url(trunk.base)
480
        opened_branches = []
481
        Branch.hooks.install_named_hook('open', opened_branches.append, None)
482
        backing = self.get_transport()
483
        request = smart.bzrdir.SmartServerRequestOpenBranchV2(backing)
4160.2.4 by Andrew Bennetts
Use BzrDir pre_open hook to jail request code from accessing transports other than the backing transport.
484
        request.setup_jail()
485
        try:
486
            response = request.execute('feature')
487
        finally:
488
            request.teardown_jail()
4160.2.1 by Andrew Bennetts
Failing test for BzrDir.open_branchV2 RPC not opening stacked-on branch.
489
        expected_format = feature._format.network_name()
490
        self.assertEqual(
491
            SuccessfulSmartServerResponse(('branch', expected_format)),
492
            response)
493
        self.assertLength(1, opened_branches)
494
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.
495
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
496
class TestSmartServerRequestRevisionHistory(tests.TestCaseWithMemoryTransport):
2018.5.38 by Robert Collins
Implement RemoteBranch.revision_history().
497
498
    def test_empty(self):
499
        """For an empty branch, the body is empty."""
500
        backing = self.get_transport()
501
        request = smart.branch.SmartServerRequestRevisionHistory(backing)
502
        self.make_branch('.')
503
        self.assertEqual(SmartServerResponse(('ok', ), ''),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
504
            request.execute(''))
2018.5.38 by Robert Collins
Implement RemoteBranch.revision_history().
505
506
    def test_not_empty(self):
507
        """For a non-empty branch, the body is empty."""
508
        backing = self.get_transport()
509
        request = smart.branch.SmartServerRequestRevisionHistory(backing)
510
        tree = self.make_branch_and_memory_tree('.')
511
        tree.lock_write()
512
        tree.add('')
513
        r1 = tree.commit('1st commit')
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
514
        r2 = tree.commit('2nd commit', rev_id=u'\xc8'.encode('utf-8'))
2018.5.38 by Robert Collins
Implement RemoteBranch.revision_history().
515
        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.
516
        self.assertEqual(
517
            SmartServerResponse(('ok', ), ('\x00'.join([r1, r2]))),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
518
            request.execute(''))
519
520
521
class TestSmartServerBranchRequest(tests.TestCaseWithMemoryTransport):
2018.5.49 by Wouter van Heyst
Refactor SmartServerBranchRequest out from SmartServerRequestRevisionHistory to
522
523
    def test_no_branch(self):
524
        """When there is a bzrdir and no branch, NotBranchError is raised."""
525
        backing = self.get_transport()
526
        request = smart.branch.SmartServerBranchRequest(backing)
527
        self.make_bzrdir('.')
528
        self.assertRaises(errors.NotBranchError,
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
529
            request.execute, '')
2018.5.49 by Wouter van Heyst
Refactor SmartServerBranchRequest out from SmartServerRequestRevisionHistory to
530
2018.5.38 by Robert Collins
Implement RemoteBranch.revision_history().
531
    def test_branch_reference(self):
532
        """When there is a branch reference, NotBranchError is raised."""
533
        backing = self.get_transport()
2018.5.49 by Wouter van Heyst
Refactor SmartServerBranchRequest out from SmartServerRequestRevisionHistory to
534
        request = smart.branch.SmartServerBranchRequest(backing)
2018.5.38 by Robert Collins
Implement RemoteBranch.revision_history().
535
        branch = self.make_branch('branch')
536
        checkout = branch.create_checkout('reference',lightweight=True)
537
        self.assertRaises(errors.NotBranchError,
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
538
            request.execute, 'checkout')
539
540
541
class TestSmartServerBranchRequestLastRevisionInfo(tests.TestCaseWithMemoryTransport):
2018.5.50 by Wouter van Heyst
Add SmartServerBranchRequestLastRevisionInfo method.
542
543
    def test_empty(self):
2018.5.170 by Andrew Bennetts
Use 'null:' instead of '' to mean NULL_REVISION on the wire.
544
        """For an empty branch, the result is ('ok', '0', 'null:')."""
2018.5.50 by Wouter van Heyst
Add SmartServerBranchRequestLastRevisionInfo method.
545
        backing = self.get_transport()
546
        request = smart.branch.SmartServerBranchRequestLastRevisionInfo(backing)
547
        self.make_branch('.')
2018.5.170 by Andrew Bennetts
Use 'null:' instead of '' to mean NULL_REVISION on the wire.
548
        self.assertEqual(SmartServerResponse(('ok', '0', 'null:')),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
549
            request.execute(''))
2018.5.50 by Wouter van Heyst
Add SmartServerBranchRequestLastRevisionInfo method.
550
551
    def test_not_empty(self):
552
        """For a non-empty branch, the result is ('ok', 'revno', 'revid')."""
553
        backing = self.get_transport()
554
        request = smart.branch.SmartServerBranchRequestLastRevisionInfo(backing)
555
        tree = self.make_branch_and_memory_tree('.')
556
        tree.lock_write()
557
        tree.add('')
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
558
        rev_id_utf8 = u'\xc8'.encode('utf-8')
2018.5.50 by Wouter van Heyst
Add SmartServerBranchRequestLastRevisionInfo method.
559
        r1 = tree.commit('1st commit')
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
560
        r2 = tree.commit('2nd commit', rev_id=rev_id_utf8)
2018.5.50 by Wouter van Heyst
Add SmartServerBranchRequestLastRevisionInfo method.
561
        tree.unlock()
562
        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.
563
            SmartServerResponse(('ok', '2', rev_id_utf8)),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
564
            request.execute(''))
565
566
567
class TestSmartServerBranchRequestGetConfigFile(tests.TestCaseWithMemoryTransport):
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
568
569
    def test_default(self):
570
        """With no file, we get empty content."""
571
        backing = self.get_transport()
572
        request = smart.branch.SmartServerBranchGetConfigFile(backing)
573
        branch = self.make_branch('.')
574
        # there should be no file by default
575
        content = ''
576
        self.assertEqual(SmartServerResponse(('ok', ), content),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
577
            request.execute(''))
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
578
579
    def test_with_content(self):
580
        # SmartServerBranchGetConfigFile should return the content from
581
        # 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
582
        # perform more complex processing.
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
583
        backing = self.get_transport()
584
        request = smart.branch.SmartServerBranchGetConfigFile(backing)
585
        branch = self.make_branch('.')
3407.2.5 by Martin Pool
Deprecate LockableFiles.put_utf8
586
        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).
587
        self.assertEqual(SmartServerResponse(('ok', ), 'foo bar baz'),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
588
            request.execute(''))
589
590
4226.2.1 by Robert Collins
Set branch config options via a smart method.
591
class TestLockedBranch(tests.TestCaseWithMemoryTransport):
592
593
    def get_lock_tokens(self, branch):
594
        branch_token = branch.lock_write()
595
        repo_token = branch.repository.lock_write()
596
        branch.repository.unlock()
597
        return branch_token, repo_token
598
599
600
class TestSmartServerBranchRequestSetConfigOption(TestLockedBranch):
601
602
    def test_value_name(self):
603
        branch = self.make_branch('.')
604
        request = smart.branch.SmartServerBranchRequestSetConfigOption(
605
            branch.bzrdir.root_transport)
606
        branch_token, repo_token = self.get_lock_tokens(branch)
607
        config = branch._get_config()
608
        result = request.execute('', branch_token, repo_token, 'bar', 'foo',
609
            '')
610
        self.assertEqual(SuccessfulSmartServerResponse(()), result)
611
        self.assertEqual('bar', config.get_option('foo'))
4327.1.10 by Vincent Ladeuil
Fix 10 more lock-related test failures.
612
        # Cleanup
613
        branch.unlock()
4226.2.1 by Robert Collins
Set branch config options via a smart method.
614
615
    def test_value_name_section(self):
616
        branch = self.make_branch('.')
617
        request = smart.branch.SmartServerBranchRequestSetConfigOption(
618
            branch.bzrdir.root_transport)
619
        branch_token, repo_token = self.get_lock_tokens(branch)
620
        config = branch._get_config()
621
        result = request.execute('', branch_token, repo_token, 'bar', 'foo',
622
            'gam')
623
        self.assertEqual(SuccessfulSmartServerResponse(()), result)
624
        self.assertEqual('bar', config.get_option('foo', 'gam'))
4327.1.10 by Vincent Ladeuil
Fix 10 more lock-related test failures.
625
        # Cleanup
626
        branch.unlock()
4226.2.1 by Robert Collins
Set branch config options via a smart method.
627
628
4556.2.2 by Andrew Bennetts
Handle failures more gracefully.
629
class TestSmartServerBranchRequestSetTagsBytes(TestLockedBranch):
630
    # Only called when the branch format and tags match [yay factory
631
    # methods] so only need to test straight forward cases.
632
633
    def test_set_bytes(self):
634
        base_branch = self.make_branch('base')
635
        tag_bytes = base_branch._get_tags_bytes()
636
        # get_lock_tokens takes out a lock.
637
        branch_token, repo_token = self.get_lock_tokens(base_branch)
638
        request = smart.branch.SmartServerBranchSetTagsBytes(
639
            self.get_transport())
640
        response = request.execute('base', branch_token, repo_token)
641
        self.assertEqual(None, response)
642
        response = request.do_chunk(tag_bytes)
643
        self.assertEqual(None, response)
644
        response = request.do_end()
645
        self.assertEquals(
646
            SuccessfulSmartServerResponse(()), response)
647
        base_branch.unlock()
648
649
    def test_lock_failed(self):
650
        base_branch = self.make_branch('base')
651
        base_branch.lock_write()
652
        tag_bytes = base_branch._get_tags_bytes()
653
        request = smart.branch.SmartServerBranchSetTagsBytes(
654
            self.get_transport())
655
        self.assertRaises(errors.TokenMismatch, request.execute,
656
            'base', 'wrong token', 'wrong token')
657
        # The request handler will keep processing the message parts, so even
658
        # if the request fails immediately do_chunk and do_end are still
659
        # called.
660
        request.do_chunk(tag_bytes)
661
        request.do_end()
662
        base_branch.unlock()
663
664
665
4226.2.1 by Robert Collins
Set branch config options via a smart method.
666
class SetLastRevisionTestBase(TestLockedBranch):
3441.5.30 by Andrew Bennetts
Improve tests for all Branch.set_last_revision* verbs.
667
    """Base test case for verbs that implement set_last_revision."""
668
669
    def setUp(self):
670
        tests.TestCaseWithMemoryTransport.setUp(self)
671
        backing_transport = self.get_transport()
672
        self.request = self.request_class(backing_transport)
673
        self.tree = self.make_branch_and_memory_tree('.')
674
675
    def lock_branch(self):
4226.2.1 by Robert Collins
Set branch config options via a smart method.
676
        return self.get_lock_tokens(self.tree.branch)
3441.5.30 by Andrew Bennetts
Improve tests for all Branch.set_last_revision* verbs.
677
678
    def unlock_branch(self):
679
        self.tree.branch.unlock()
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
680
3441.5.30 by Andrew Bennetts
Improve tests for all Branch.set_last_revision* verbs.
681
    def set_last_revision(self, revision_id, revno):
682
        branch_token, repo_token = self.lock_branch()
683
        response = self._set_last_revision(
684
            revision_id, revno, branch_token, repo_token)
685
        self.unlock_branch()
686
        return response
687
688
    def assertRequestSucceeds(self, revision_id, revno):
689
        response = self.set_last_revision(revision_id, revno)
690
        self.assertEqual(SuccessfulSmartServerResponse(('ok',)), response)
691
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
692
3441.5.30 by Andrew Bennetts
Improve tests for all Branch.set_last_revision* verbs.
693
class TestSetLastRevisionVerbMixin(object):
694
    """Mixin test case for verbs that implement set_last_revision."""
695
696
    def test_set_null_to_null(self):
697
        """An empty branch can have its last revision set to 'null:'."""
698
        self.assertRequestSucceeds('null:', 0)
699
700
    def test_NoSuchRevision(self):
701
        """If the revision_id is not present, the verb returns NoSuchRevision.
702
        """
703
        revision_id = 'non-existent revision'
704
        self.assertEqual(
705
            FailedSmartServerResponse(('NoSuchRevision', revision_id)),
706
            self.set_last_revision(revision_id, 1))
707
708
    def make_tree_with_two_commits(self):
709
        self.tree.lock_write()
710
        self.tree.add('')
711
        rev_id_utf8 = u'\xc8'.encode('utf-8')
712
        r1 = self.tree.commit('1st commit', rev_id=rev_id_utf8)
713
        r2 = self.tree.commit('2nd commit', rev_id='rev-2')
714
        self.tree.unlock()
715
716
    def test_branch_last_revision_info_is_updated(self):
717
        """A branch's tip can be set to a revision that is present in its
718
        repository.
719
        """
720
        # Make a branch with an empty revision history, but two revisions in
721
        # its repository.
722
        self.make_tree_with_two_commits()
723
        rev_id_utf8 = u'\xc8'.encode('utf-8')
724
        self.tree.branch.set_revision_history([])
725
        self.assertEqual(
726
            (0, 'null:'), self.tree.branch.last_revision_info())
727
        # We can update the branch to a revision that is present in the
728
        # repository.
729
        self.assertRequestSucceeds(rev_id_utf8, 1)
730
        self.assertEqual(
731
            (1, rev_id_utf8), self.tree.branch.last_revision_info())
732
733
    def test_branch_last_revision_info_rewind(self):
734
        """A branch's tip can be set to a revision that is an ancestor of the
735
        current tip.
736
        """
737
        self.make_tree_with_two_commits()
738
        rev_id_utf8 = u'\xc8'.encode('utf-8')
739
        self.assertEqual(
740
            (2, 'rev-2'), self.tree.branch.last_revision_info())
741
        self.assertRequestSucceeds(rev_id_utf8, 1)
742
        self.assertEqual(
743
            (1, rev_id_utf8), self.tree.branch.last_revision_info())
744
3577.1.1 by Andrew Bennetts
Cherry-pick TipChangeRejected changes from pre-branch-tip-changed-hook loom.
745
    def test_TipChangeRejected(self):
746
        """If a pre_change_branch_tip hook raises TipChangeRejected, the verb
747
        returns TipChangeRejected.
748
        """
749
        rejection_message = u'rejection message\N{INTERROBANG}'
750
        def hook_that_rejects(params):
751
            raise errors.TipChangeRejected(rejection_message)
752
        Branch.hooks.install_named_hook(
753
            'pre_change_branch_tip', hook_that_rejects, None)
754
        self.assertEqual(
755
            FailedSmartServerResponse(
756
                ('TipChangeRejected', rejection_message.encode('utf-8'))),
757
            self.set_last_revision('null:', 0))
758
3441.5.30 by Andrew Bennetts
Improve tests for all Branch.set_last_revision* verbs.
759
3441.5.6 by Andrew Bennetts
Greatly simplify RemoteBranch.update_revisions. Still needs more tests.
760
class TestSmartServerBranchRequestSetLastRevision(
3441.5.30 by Andrew Bennetts
Improve tests for all Branch.set_last_revision* verbs.
761
        SetLastRevisionTestBase, TestSetLastRevisionVerbMixin):
762
    """Tests for Branch.set_last_revision verb."""
3441.5.6 by Andrew Bennetts
Greatly simplify RemoteBranch.update_revisions. Still needs more tests.
763
764
    request_class = smart.branch.SmartServerBranchRequestSetLastRevision
765
3441.5.30 by Andrew Bennetts
Improve tests for all Branch.set_last_revision* verbs.
766
    def _set_last_revision(self, revision_id, revno, branch_token, repo_token):
767
        return self.request.execute(
768
            '', branch_token, repo_token, revision_id)
769
770
771
class TestSmartServerBranchRequestSetLastRevisionInfo(
772
        SetLastRevisionTestBase, TestSetLastRevisionVerbMixin):
773
    """Tests for Branch.set_last_revision_info verb."""
774
775
    request_class = smart.branch.SmartServerBranchRequestSetLastRevisionInfo
776
777
    def _set_last_revision(self, revision_id, revno, branch_token, repo_token):
778
        return self.request.execute(
779
            '', branch_token, repo_token, revno, revision_id)
780
781
    def test_NoSuchRevision(self):
782
        """Branch.set_last_revision_info does not have to return
783
        NoSuchRevision if the revision_id is absent.
784
        """
785
        raise tests.TestNotApplicable()
3441.5.6 by Andrew Bennetts
Greatly simplify RemoteBranch.update_revisions. Still needs more tests.
786
787
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.
788
class TestSmartServerBranchRequestSetLastRevisionEx(
3441.5.30 by Andrew Bennetts
Improve tests for all Branch.set_last_revision* verbs.
789
        SetLastRevisionTestBase, TestSetLastRevisionVerbMixin):
790
    """Tests for Branch.set_last_revision_ex verb."""
3441.5.6 by Andrew Bennetts
Greatly simplify RemoteBranch.update_revisions. Still needs more tests.
791
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.
792
    request_class = smart.branch.SmartServerBranchRequestSetLastRevisionEx
3441.5.6 by Andrew Bennetts
Greatly simplify RemoteBranch.update_revisions. Still needs more tests.
793
3441.5.30 by Andrew Bennetts
Improve tests for all Branch.set_last_revision* verbs.
794
    def _set_last_revision(self, revision_id, revno, branch_token, repo_token):
795
        return self.request.execute(
796
            '', branch_token, repo_token, revision_id, 0, 0)
797
798
    def assertRequestSucceeds(self, revision_id, revno):
799
        response = self.set_last_revision(revision_id, revno)
800
        self.assertEqual(
801
            SuccessfulSmartServerResponse(('ok', revno, revision_id)),
802
            response)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
803
3441.5.30 by Andrew Bennetts
Improve tests for all Branch.set_last_revision* verbs.
804
    def test_branch_last_revision_info_rewind(self):
805
        """A branch's tip can be set to a revision that is an ancestor of the
806
        current tip, but only if allow_overwrite_descendant is passed.
807
        """
808
        self.make_tree_with_two_commits()
3441.5.6 by Andrew Bennetts
Greatly simplify RemoteBranch.update_revisions. Still needs more tests.
809
        rev_id_utf8 = u'\xc8'.encode('utf-8')
3441.5.30 by Andrew Bennetts
Improve tests for all Branch.set_last_revision* verbs.
810
        self.assertEqual(
811
            (2, 'rev-2'), self.tree.branch.last_revision_info())
812
        # If allow_overwrite_descendant flag is 0, then trying to set the tip
813
        # to an older revision ID has no effect.
814
        branch_token, repo_token = self.lock_branch()
815
        response = self.request.execute(
816
            '', branch_token, repo_token, rev_id_utf8, 0, 0)
817
        self.assertEqual(
818
            SuccessfulSmartServerResponse(('ok', 2, 'rev-2')),
819
            response)
820
        self.assertEqual(
821
            (2, 'rev-2'), self.tree.branch.last_revision_info())
822
823
        # If allow_overwrite_descendant flag is 1, then setting the tip to an
824
        # ancestor works.
825
        response = self.request.execute(
826
            '', branch_token, repo_token, rev_id_utf8, 0, 1)
827
        self.assertEqual(
828
            SuccessfulSmartServerResponse(('ok', 1, rev_id_utf8)),
829
            response)
830
        self.unlock_branch()
831
        self.assertEqual(
832
            (1, rev_id_utf8), self.tree.branch.last_revision_info())
833
3441.5.31 by Andrew Bennetts
Add test for allow_diverged flag.
834
    def make_branch_with_divergent_history(self):
835
        """Make a branch with divergent history in its repo.
836
837
        The branch's tip will be 'child-2', and the repo will also contain
838
        'child-1', which diverges from a common base revision.
3441.5.30 by Andrew Bennetts
Improve tests for all Branch.set_last_revision* verbs.
839
        """
840
        self.tree.lock_write()
841
        self.tree.add('')
842
        r1 = self.tree.commit('1st commit')
843
        revno_1, revid_1 = self.tree.branch.last_revision_info()
844
        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.
845
        # Undo the second commit
3441.5.30 by Andrew Bennetts
Improve tests for all Branch.set_last_revision* verbs.
846
        self.tree.branch.set_last_revision_info(revno_1, revid_1)
847
        self.tree.set_parent_ids([revid_1])
3441.5.6 by Andrew Bennetts
Greatly simplify RemoteBranch.update_revisions. Still needs more tests.
848
        # Make a new second commit, child-2.  child-2 has diverged from
849
        # child-1.
3441.5.30 by Andrew Bennetts
Improve tests for all Branch.set_last_revision* verbs.
850
        new_r2 = self.tree.commit('2nd commit', rev_id='child-2')
851
        self.tree.unlock()
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
852
3441.5.31 by Andrew Bennetts
Add test for allow_diverged flag.
853
    def test_not_allow_diverged(self):
854
        """If allow_diverged is not passed, then setting a divergent history
855
        returns a Diverged error.
856
        """
857
        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.
858
        self.assertEqual(
3441.5.30 by Andrew Bennetts
Improve tests for all Branch.set_last_revision* verbs.
859
            FailedSmartServerResponse(('Diverged',)),
860
            self.set_last_revision('child-1', 2))
861
        # The branch tip was not changed.
862
        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.
863
3441.5.31 by Andrew Bennetts
Add test for allow_diverged flag.
864
    def test_allow_diverged(self):
865
        """If allow_diverged is passed, then setting a divergent history
866
        succeeds.
867
        """
868
        self.make_branch_with_divergent_history()
869
        branch_token, repo_token = self.lock_branch()
870
        response = self.request.execute(
871
            '', branch_token, repo_token, 'child-1', 1, 0)
872
        self.assertEqual(
873
            SuccessfulSmartServerResponse(('ok', 2, 'child-1')),
874
            response)
875
        self.unlock_branch()
876
        # The branch tip was changed.
877
        self.assertEqual('child-1', self.tree.branch.last_revision())
878
2892.2.1 by Andrew Bennetts
Add Branch.set_last_revision_info smart method, and make the RemoteBranch client use it.
879
4078.2.1 by Robert Collins
Add a Branch.get_parent remote call for RemoteBranch.
880
class TestSmartServerBranchRequestGetParent(tests.TestCaseWithMemoryTransport):
881
882
    def test_get_parent_none(self):
883
        base_branch = self.make_branch('base')
884
        request = smart.branch.SmartServerBranchGetParent(self.get_transport())
885
        response = request.execute('base')
886
        self.assertEquals(
4083.1.7 by Andrew Bennetts
Fix same trivial bug [(x) != (x,)] in test_remote and test_smart.
887
            SuccessfulSmartServerResponse(('',)), response)
4078.2.1 by Robert Collins
Add a Branch.get_parent remote call for RemoteBranch.
888
889
    def test_get_parent_something(self):
890
        base_branch = self.make_branch('base')
891
        base_branch.set_parent(self.get_url('foo'))
892
        request = smart.branch.SmartServerBranchGetParent(self.get_transport())
893
        response = request.execute('base')
894
        self.assertEquals(
4083.1.7 by Andrew Bennetts
Fix same trivial bug [(x) != (x,)] in test_remote and test_smart.
895
            SuccessfulSmartServerResponse(("../foo",)),
4078.2.1 by Robert Collins
Add a Branch.get_parent remote call for RemoteBranch.
896
            response)
897
898
4288.1.7 by Robert Collins
Add new remote server verb Branch.set_parent_location, dropping roundtrips further on push operations.
899
class TestSmartServerBranchRequestSetParent(tests.TestCaseWithMemoryTransport):
900
901
    def test_set_parent_none(self):
902
        branch = self.make_branch('base', format="1.9")
4288.1.9 by Robert Collins
Fix up test usable of _set_parent_location on unlocked branches.
903
        branch.lock_write()
4288.1.7 by Robert Collins
Add new remote server verb Branch.set_parent_location, dropping roundtrips further on push operations.
904
        branch._set_parent_location('foo')
4288.1.9 by Robert Collins
Fix up test usable of _set_parent_location on unlocked branches.
905
        branch.unlock()
4288.1.7 by Robert Collins
Add new remote server verb Branch.set_parent_location, dropping roundtrips further on push operations.
906
        request = smart.branch.SmartServerBranchRequestSetParentLocation(
907
            self.get_transport())
908
        branch_token = branch.lock_write()
909
        repo_token = branch.repository.lock_write()
910
        try:
911
            response = request.execute('base', branch_token, repo_token, '')
912
        finally:
913
            branch.repository.unlock()
914
            branch.unlock()
915
        self.assertEqual(SuccessfulSmartServerResponse(()), response)
916
        self.assertEqual(None, branch.get_parent())
917
918
    def test_set_parent_something(self):
919
        branch = self.make_branch('base', format="1.9")
920
        request = smart.branch.SmartServerBranchRequestSetParentLocation(
921
            self.get_transport())
922
        branch_token = branch.lock_write()
923
        repo_token = branch.repository.lock_write()
924
        try:
925
            response = request.execute('base', branch_token, repo_token,
926
            'http://bar/')
927
        finally:
928
            branch.repository.unlock()
929
            branch.unlock()
930
        self.assertEqual(SuccessfulSmartServerResponse(()), response)
931
        self.assertEqual('http://bar/', branch.get_parent())
932
933
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.
934
class TestSmartServerBranchRequestGetTagsBytes(tests.TestCaseWithMemoryTransport):
4556.2.2 by Andrew Bennetts
Handle failures more gracefully.
935
    # Only called when the branch format and tags match [yay factory
936
    # methods] so only need to test straight forward cases.
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.
937
938
    def test_get_bytes(self):
939
        base_branch = self.make_branch('base')
940
        request = smart.branch.SmartServerBranchGetTagsBytes(
941
            self.get_transport())
942
        response = request.execute('base')
943
        self.assertEquals(
944
            SuccessfulSmartServerResponse(('',)), response)
945
946
3691.2.5 by Martin Pool
Add Branch.get_stacked_on_url rpc and tests for same
947
class TestSmartServerBranchRequestGetStackedOnURL(tests.TestCaseWithMemoryTransport):
948
949
    def test_get_stacked_on_url(self):
950
        base_branch = self.make_branch('base', format='1.6')
951
        stacked_branch = self.make_branch('stacked', format='1.6')
952
        # typically should be relative
953
        stacked_branch.set_stacked_on_url('../base')
954
        request = smart.branch.SmartServerBranchRequestGetStackedOnURL(
955
            self.get_transport())
956
        response = request.execute('stacked')
957
        self.assertEquals(
958
            SmartServerResponse(('ok', '../base')),
959
            response)
960
961
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
962
class TestSmartServerBranchRequestLockWrite(tests.TestCaseWithMemoryTransport):
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
963
964
    def setUp(self):
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
965
        tests.TestCaseWithMemoryTransport.setUp(self)
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
966
967
    def test_lock_write_on_unlocked_branch(self):
968
        backing = self.get_transport()
969
        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.
970
        branch = self.make_branch('.', format='knit')
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
971
        repository = branch.repository
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
972
        response = request.execute('')
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
973
        branch_nonce = branch.control_files._lock.peek().get('nonce')
974
        repository_nonce = repository.control_files._lock.peek().get('nonce')
975
        self.assertEqual(
976
            SmartServerResponse(('ok', branch_nonce, repository_nonce)),
977
            response)
978
        # The branch (and associated repository) is now locked.  Verify that
979
        # with a new branch object.
980
        new_branch = repository.bzrdir.open_branch()
981
        self.assertRaises(errors.LockContention, new_branch.lock_write)
4327.1.10 by Vincent Ladeuil
Fix 10 more lock-related test failures.
982
        # Cleanup
983
        request = smart.branch.SmartServerBranchRequestUnlock(backing)
984
        response = request.execute('', branch_nonce, repository_nonce)
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
985
986
    def test_lock_write_on_locked_branch(self):
987
        backing = self.get_transport()
988
        request = smart.branch.SmartServerBranchRequestLockWrite(backing)
989
        branch = self.make_branch('.')
4327.1.10 by Vincent Ladeuil
Fix 10 more lock-related test failures.
990
        branch_token = branch.lock_write()
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
991
        branch.leave_lock_in_place()
992
        branch.unlock()
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
993
        response = request.execute('')
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
994
        self.assertEqual(
995
            SmartServerResponse(('LockContention',)), response)
4327.1.10 by Vincent Ladeuil
Fix 10 more lock-related test failures.
996
        # Cleanup
997
        branch.lock_write(branch_token)
998
        branch.dont_leave_lock_in_place()
999
        branch.unlock()
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1000
1001
    def test_lock_write_with_tokens_on_locked_branch(self):
1002
        backing = self.get_transport()
1003
        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.
1004
        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).
1005
        branch_token = branch.lock_write()
1006
        repo_token = branch.repository.lock_write()
1007
        branch.repository.unlock()
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1008
        branch.leave_lock_in_place()
1009
        branch.repository.leave_lock_in_place()
1010
        branch.unlock()
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1011
        response = request.execute('',
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1012
                                   branch_token, repo_token)
1013
        self.assertEqual(
1014
            SmartServerResponse(('ok', branch_token, repo_token)), response)
4327.1.10 by Vincent Ladeuil
Fix 10 more lock-related test failures.
1015
        # Cleanup
1016
        branch.repository.lock_write(repo_token)
1017
        branch.repository.dont_leave_lock_in_place()
1018
        branch.repository.unlock()
1019
        branch.lock_write(branch_token)
1020
        branch.dont_leave_lock_in_place()
1021
        branch.unlock()
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1022
1023
    def test_lock_write_with_mismatched_tokens_on_locked_branch(self):
1024
        backing = self.get_transport()
1025
        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.
1026
        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).
1027
        branch_token = branch.lock_write()
1028
        repo_token = branch.repository.lock_write()
1029
        branch.repository.unlock()
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1030
        branch.leave_lock_in_place()
1031
        branch.repository.leave_lock_in_place()
1032
        branch.unlock()
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1033
        response = request.execute('',
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1034
                                   branch_token+'xxx', repo_token)
1035
        self.assertEqual(
1036
            SmartServerResponse(('TokenMismatch',)), response)
4327.1.10 by Vincent Ladeuil
Fix 10 more lock-related test failures.
1037
        # Cleanup
1038
        branch.repository.lock_write(repo_token)
1039
        branch.repository.dont_leave_lock_in_place()
1040
        branch.repository.unlock()
1041
        branch.lock_write(branch_token)
1042
        branch.dont_leave_lock_in_place()
1043
        branch.unlock()
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1044
1045
    def test_lock_write_on_locked_repo(self):
1046
        backing = self.get_transport()
1047
        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.
1048
        branch = self.make_branch('.', format='knit')
4327.1.10 by Vincent Ladeuil
Fix 10 more lock-related test failures.
1049
        repo = branch.repository
1050
        repo_token = repo.lock_write()
1051
        repo.leave_lock_in_place()
1052
        repo.unlock()
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1053
        response = request.execute('')
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1054
        self.assertEqual(
1055
            SmartServerResponse(('LockContention',)), response)
4327.1.10 by Vincent Ladeuil
Fix 10 more lock-related test failures.
1056
        # Cleanup
1057
        repo.lock_write(repo_token)
1058
        repo.dont_leave_lock_in_place()
1059
        repo.unlock()
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1060
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.
1061
    def test_lock_write_on_readonly_transport(self):
1062
        backing = self.get_readonly_transport()
1063
        request = smart.branch.SmartServerBranchRequestLockWrite(backing)
1064
        branch = self.make_branch('.')
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1065
        root = self.get_transport().clone('/')
1066
        path = urlutils.relative_url(root.base, self.get_transport().base)
1067
        response = request.execute(path)
2872.5.3 by Martin Pool
Pass back LockFailed from smart server lock methods
1068
        error_name, lock_str, why_str = response.args
1069
        self.assertFalse(response.is_successful())
1070
        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.
1071
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1072
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1073
class TestSmartServerBranchRequestUnlock(tests.TestCaseWithMemoryTransport):
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1074
1075
    def setUp(self):
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1076
        tests.TestCaseWithMemoryTransport.setUp(self)
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1077
1078
    def test_unlock_on_locked_branch_and_repo(self):
1079
        backing = self.get_transport()
1080
        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.
1081
        branch = self.make_branch('.', format='knit')
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1082
        # 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).
1083
        branch_token = branch.lock_write()
1084
        repo_token = branch.repository.lock_write()
1085
        branch.repository.unlock()
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1086
        # Unlock the branch (and repo) object, leaving the physical locks
1087
        # in place.
1088
        branch.leave_lock_in_place()
1089
        branch.repository.leave_lock_in_place()
1090
        branch.unlock()
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1091
        response = request.execute('',
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1092
                                   branch_token, repo_token)
1093
        self.assertEqual(
1094
            SmartServerResponse(('ok',)), response)
1095
        # The branch is now unlocked.  Verify that with a new branch
1096
        # object.
1097
        new_branch = branch.bzrdir.open_branch()
1098
        new_branch.lock_write()
1099
        new_branch.unlock()
1100
1101
    def test_unlock_on_unlocked_branch_unlocked_repo(self):
1102
        backing = self.get_transport()
1103
        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.
1104
        branch = self.make_branch('.', format='knit')
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1105
        response = request.execute(
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1106
            '', 'branch token', 'repo token')
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1107
        self.assertEqual(
1108
            SmartServerResponse(('TokenMismatch',)), response)
1109
1110
    def test_unlock_on_unlocked_branch_locked_repo(self):
1111
        backing = self.get_transport()
1112
        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.
1113
        branch = self.make_branch('.', format='knit')
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1114
        # Lock the repository.
1115
        repo_token = branch.repository.lock_write()
1116
        branch.repository.leave_lock_in_place()
1117
        branch.repository.unlock()
1118
        # Issue branch lock_write request on the unlocked branch (with locked
1119
        # repo).
1120
        response = request.execute(
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1121
            '', 'branch token', repo_token)
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1122
        self.assertEqual(
1123
            SmartServerResponse(('TokenMismatch',)), response)
4327.1.10 by Vincent Ladeuil
Fix 10 more lock-related test failures.
1124
        # Cleanup
1125
        branch.repository.lock_write(repo_token)
1126
        branch.repository.dont_leave_lock_in_place()
1127
        branch.repository.unlock()
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1128
1129
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1130
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).
1131
1132
    def test_no_repository(self):
1133
        """Raise NoRepositoryPresent when there is a bzrdir and no repo."""
1134
        # we test this using a shared repository above the named path,
1135
        # thus checking the right search logic is used - that is, that
1136
        # its the exact path being looked at and the server is not
1137
        # searching.
1138
        backing = self.get_transport()
2018.5.58 by Wouter van Heyst
Small test fixes to reflect naming and documentation
1139
        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).
1140
        self.make_repository('.', shared=True)
1141
        self.make_bzrdir('subdir')
1142
        self.assertRaises(errors.NoRepositoryPresent,
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1143
            request.execute, 'subdir')
1144
1145
3441.5.4 by Andrew Bennetts
Fix test failures, and add some tests for the remote graph heads RPC.
1146
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.
1147
3211.5.3 by Robert Collins
Adjust size of batch and change gzip comments to bzip2.
1148
    def test_trivial_bzipped(self):
1149
        # 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.
1150
        backing = self.get_transport()
1151
        request = smart.repository.SmartServerRepositoryGetParentMap(backing)
1152
        tree = self.make_branch_and_memory_tree('.')
1153
1154
        self.assertEqual(None,
2692.1.24 by Andrew Bennetts
Merge from bzr.dev.
1155
            request.execute('', 'missing-id'))
4190.1.3 by Robert Collins
Allow optional inclusion of ghost data in server get_parent_map calls.
1156
        # Note that it returns a body that is 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.
1157
        self.assertEqual(
3211.5.2 by Robert Collins
Change RemoteRepository.get_parent_map to use bz2 not gzip for compression.
1158
            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.
1159
            request.do_body('\n\n0\n'))
1160
4190.1.3 by Robert Collins
Allow optional inclusion of ghost data in server get_parent_map calls.
1161
    def test_trivial_include_missing(self):
1162
        backing = self.get_transport()
1163
        request = smart.repository.SmartServerRepositoryGetParentMap(backing)
1164
        tree = self.make_branch_and_memory_tree('.')
1165
1166
        self.assertEqual(None,
1167
            request.execute('', 'missing-id', 'include-missing:'))
1168
        self.assertEqual(
1169
            SuccessfulSmartServerResponse(('ok', ),
1170
                bz2.compress('missing:missing-id')),
1171
            request.do_body('\n\n0\n'))
1172
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.
1173
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1174
class TestSmartServerRepositoryGetRevisionGraph(tests.TestCaseWithMemoryTransport):
2018.5.67 by Wouter van Heyst
Implement RemoteRepository.get_revision_graph (Wouter van Heyst, Robert Collins)
1175
1176
    def test_none_argument(self):
1177
        backing = self.get_transport()
1178
        request = smart.repository.SmartServerRepositoryGetRevisionGraph(backing)
1179
        tree = self.make_branch_and_memory_tree('.')
1180
        tree.lock_write()
1181
        tree.add('')
1182
        r1 = tree.commit('1st commit')
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
1183
        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)
1184
        tree.unlock()
1185
1186
        # the lines of revision_id->revision_parent_list has no guaranteed
1187
        # order coming out of a dict, so sort both our test and response
1188
        lines = sorted([' '.join([r2, r1]), r1])
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1189
        response = request.execute('', '')
2018.5.67 by Wouter van Heyst
Implement RemoteRepository.get_revision_graph (Wouter van Heyst, Robert Collins)
1190
        response.body = '\n'.join(sorted(response.body.split('\n')))
1191
2018.5.83 by Andrew Bennetts
Fix some test failures caused by the switch from unicode to UTF-8-encoded strs for revision IDs.
1192
        self.assertEqual(
1193
            SmartServerResponse(('ok', ), '\n'.join(lines)), response)
2018.5.67 by Wouter van Heyst
Implement RemoteRepository.get_revision_graph (Wouter van Heyst, Robert Collins)
1194
1195
    def test_specific_revision_argument(self):
1196
        backing = self.get_transport()
1197
        request = smart.repository.SmartServerRepositoryGetRevisionGraph(backing)
1198
        tree = self.make_branch_and_memory_tree('.')
1199
        tree.lock_write()
1200
        tree.add('')
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
1201
        rev_id_utf8 = u'\xc9'.encode('utf-8')
1202
        r1 = tree.commit('1st commit', rev_id=rev_id_utf8)
1203
        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)
1204
        tree.unlock()
1205
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
1206
        self.assertEqual(SmartServerResponse(('ok', ), rev_id_utf8),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1207
            request.execute('', rev_id_utf8))
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
1208
2018.5.67 by Wouter van Heyst
Implement RemoteRepository.get_revision_graph (Wouter van Heyst, Robert Collins)
1209
    def test_no_such_revision(self):
1210
        backing = self.get_transport()
1211
        request = smart.repository.SmartServerRepositoryGetRevisionGraph(backing)
1212
        tree = self.make_branch_and_memory_tree('.')
1213
        tree.lock_write()
1214
        tree.add('')
1215
        r1 = tree.commit('1st commit')
1216
        tree.unlock()
1217
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
1218
        # Note that it still returns body (of zero bytes).
1219
        self.assertEqual(
1220
            SmartServerResponse(('nosuchrevision', 'missingrevision', ), ''),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1221
            request.execute('', 'missingrevision'))
1222
1223
4419.2.6 by Andrew Bennetts
Add tests for server-side logic, and fix the bugs exposed by those tests.
1224
class TestSmartServerRepositoryGetRevIdForRevno(tests.TestCaseWithMemoryTransport):
1225
1226
    def test_revno_found(self):
1227
        backing = self.get_transport()
1228
        request = smart.repository.SmartServerRepositoryGetRevIdForRevno(backing)
1229
        tree = self.make_branch_and_memory_tree('.')
1230
        tree.lock_write()
1231
        tree.add('')
1232
        rev1_id_utf8 = u'\xc8'.encode('utf-8')
1233
        rev2_id_utf8 = u'\xc9'.encode('utf-8')
1234
        tree.commit('1st commit', rev_id=rev1_id_utf8)
1235
        tree.commit('2nd commit', rev_id=rev2_id_utf8)
1236
        tree.unlock()
1237
1238
        self.assertEqual(SmartServerResponse(('ok', rev1_id_utf8)),
1239
            request.execute('', 1, (2, rev2_id_utf8)))
1240
1241
    def test_known_revid_missing(self):
1242
        backing = self.get_transport()
1243
        request = smart.repository.SmartServerRepositoryGetRevIdForRevno(backing)
1244
        repo = self.make_repository('.')
1245
        self.assertEqual(
1246
            FailedSmartServerResponse(('nosuchrevision', 'ghost')),
1247
            request.execute('', 1, (2, 'ghost')))
1248
1249
    def test_history_incomplete(self):
1250
        backing = self.get_transport()
1251
        request = smart.repository.SmartServerRepositoryGetRevIdForRevno(backing)
1252
        parent = self.make_branch_and_memory_tree('parent', format='1.9')
4526.9.21 by Robert Collins
Fix test_smart's test_history_incomplete to generate a good tree before committing.
1253
        parent.lock_write()
1254
        parent.add([''], ['TREE_ROOT'])
4419.2.6 by Andrew Bennetts
Add tests for server-side logic, and fix the bugs exposed by those tests.
1255
        r1 = parent.commit(message='first commit')
1256
        r2 = parent.commit(message='second commit')
4526.9.21 by Robert Collins
Fix test_smart's test_history_incomplete to generate a good tree before committing.
1257
        parent.unlock()
4419.2.6 by Andrew Bennetts
Add tests for server-side logic, and fix the bugs exposed by those tests.
1258
        local = self.make_branch_and_memory_tree('local', format='1.9')
1259
        local.branch.pull(parent.branch)
1260
        local.set_parent_ids([r2])
1261
        r3 = local.commit(message='local commit')
1262
        local.branch.create_clone_on_transport(
1263
            self.get_transport('stacked'), stacked_on=self.get_url('parent'))
1264
        self.assertEqual(
1265
            SmartServerResponse(('history-incomplete', 2, r2)),
1266
            request.execute('stacked', 1, (3, r3)))
1267
4476.3.68 by Andrew Bennetts
Review comments from John.
1268
4070.9.14 by Andrew Bennetts
Tweaks requested by Robert's review.
1269
class TestSmartServerRepositoryGetStream(tests.TestCaseWithMemoryTransport):
1270
1271
    def make_two_commit_repo(self):
1272
        tree = self.make_branch_and_memory_tree('.')
1273
        tree.lock_write()
1274
        tree.add('')
1275
        r1 = tree.commit('1st commit')
1276
        r2 = tree.commit('2nd commit', rev_id=u'\xc8'.encode('utf-8'))
1277
        tree.unlock()
1278
        repo = tree.branch.repository
1279
        return repo, r1, r2
1280
1281
    def test_ancestry_of(self):
1282
        """The search argument may be a 'ancestry-of' some heads'."""
1283
        backing = self.get_transport()
1284
        request = smart.repository.SmartServerRepositoryGetStream(backing)
1285
        repo, r1, r2 = self.make_two_commit_repo()
1286
        fetch_spec = ['ancestry-of', r2]
1287
        lines = '\n'.join(fetch_spec)
1288
        request.execute('', repo._format.network_name())
1289
        response = request.do_body(lines)
1290
        self.assertEqual(('ok',), response.args)
1291
        stream_bytes = ''.join(response.body_stream)
1292
        self.assertStartsWith(stream_bytes, 'Bazaar pack format 1')
1293
1294
    def test_search(self):
1295
        """The search argument may be a 'search' of some explicit keys."""
1296
        backing = self.get_transport()
1297
        request = smart.repository.SmartServerRepositoryGetStream(backing)
1298
        repo, r1, r2 = self.make_two_commit_repo()
1299
        fetch_spec = ['search', '%s %s' % (r1, r2), 'null:', '2']
1300
        lines = '\n'.join(fetch_spec)
1301
        request.execute('', repo._format.network_name())
1302
        response = request.do_body(lines)
1303
        self.assertEqual(('ok',), response.args)
1304
        stream_bytes = ''.join(response.body_stream)
1305
        self.assertStartsWith(stream_bytes, 'Bazaar pack format 1')
1306
1307
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1308
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).
1309
1310
    def test_missing_revision(self):
1311
        """For a missing revision, ('no', ) is returned."""
1312
        backing = self.get_transport()
1313
        request = smart.repository.SmartServerRequestHasRevision(backing)
1314
        self.make_repository('.')
1315
        self.assertEqual(SmartServerResponse(('no', )),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1316
            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).
1317
1318
    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.
1319
        """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).
1320
        backing = self.get_transport()
1321
        request = smart.repository.SmartServerRequestHasRevision(backing)
1322
        tree = self.make_branch_and_memory_tree('.')
1323
        tree.lock_write()
1324
        tree.add('')
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
1325
        rev_id_utf8 = u'\xc8abc'.encode('utf-8')
1326
        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).
1327
        tree.unlock()
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
1328
        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.
1329
        self.assertEqual(SmartServerResponse(('yes', )),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1330
            request.execute('', rev_id_utf8))
1331
1332
1333
class TestSmartServerRepositoryGatherStats(tests.TestCaseWithMemoryTransport):
2018.10.2 by v.ladeuil+lp at free
gather_stats server side and request registration
1334
1335
    def test_empty_revid(self):
1336
        """With an empty revid, we get only size an number and revisions"""
1337
        backing = self.get_transport()
1338
        request = smart.repository.SmartServerRepositoryGatherStats(backing)
1339
        repository = self.make_repository('.')
1340
        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.
1341
        expected_body = 'revisions: 0\n'
2018.10.2 by v.ladeuil+lp at free
gather_stats server side and request registration
1342
        self.assertEqual(SmartServerResponse(('ok', ), expected_body),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1343
                         request.execute('', '', 'no'))
2018.10.2 by v.ladeuil+lp at free
gather_stats server side and request registration
1344
1345
    def test_revid_with_committers(self):
1346
        """For a revid we get more infos."""
1347
        backing = self.get_transport()
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
1348
        rev_id_utf8 = u'\xc8abc'.encode('utf-8')
2018.10.2 by v.ladeuil+lp at free
gather_stats server side and request registration
1349
        request = smart.repository.SmartServerRepositoryGatherStats(backing)
1350
        tree = self.make_branch_and_memory_tree('.')
1351
        tree.lock_write()
1352
        tree.add('')
1353
        # Let's build a predictable result
1354
        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.
1355
        tree.commit('a commit', timestamp=654321.4, timezone=0,
1356
                    rev_id=rev_id_utf8)
2018.10.2 by v.ladeuil+lp at free
gather_stats server side and request registration
1357
        tree.unlock()
1358
1359
        stats = tree.branch.repository.gather_stats()
1360
        expected_body = ('firstrev: 123456.200 3600\n'
1361
                         '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.
1362
                         'revisions: 2\n')
2018.10.2 by v.ladeuil+lp at free
gather_stats server side and request registration
1363
        self.assertEqual(SmartServerResponse(('ok', ), expected_body),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1364
                         request.execute('',
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
1365
                                         rev_id_utf8, 'no'))
2018.10.2 by v.ladeuil+lp at free
gather_stats server side and request registration
1366
1367
    def test_not_empty_repository_with_committers(self):
1368
        """For a revid and requesting committers we get the whole thing."""
1369
        backing = self.get_transport()
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
1370
        rev_id_utf8 = u'\xc8abc'.encode('utf-8')
2018.10.2 by v.ladeuil+lp at free
gather_stats server side and request registration
1371
        request = smart.repository.SmartServerRepositoryGatherStats(backing)
1372
        tree = self.make_branch_and_memory_tree('.')
1373
        tree.lock_write()
1374
        tree.add('')
1375
        # Let's build a predictable result
1376
        tree.commit('a commit', timestamp=123456.2, timezone=3600,
1377
                    committer='foo')
1378
        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.
1379
                    committer='bar', rev_id=rev_id_utf8)
2018.10.2 by v.ladeuil+lp at free
gather_stats server side and request registration
1380
        tree.unlock()
1381
        stats = tree.branch.repository.gather_stats()
1382
1383
        expected_body = ('committers: 2\n'
1384
                         'firstrev: 123456.200 3600\n'
1385
                         '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.
1386
                         'revisions: 2\n')
2018.10.2 by v.ladeuil+lp at free
gather_stats server side and request registration
1387
        self.assertEqual(SmartServerResponse(('ok', ), expected_body),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1388
                         request.execute('',
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
1389
                                         rev_id_utf8, 'yes'))
2018.10.2 by v.ladeuil+lp at free
gather_stats server side and request registration
1390
1391
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1392
class TestSmartServerRepositoryIsShared(tests.TestCaseWithMemoryTransport):
2018.5.57 by Robert Collins
Implement RemoteRepository.is_shared (Robert Collins, Vincent Ladeuil).
1393
1394
    def test_is_shared(self):
1395
        """For a shared repository, ('yes', ) is returned."""
1396
        backing = self.get_transport()
1397
        request = smart.repository.SmartServerRepositoryIsShared(backing)
1398
        self.make_repository('.', shared=True)
1399
        self.assertEqual(SmartServerResponse(('yes', )),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1400
            request.execute('', ))
2018.5.57 by Robert Collins
Implement RemoteRepository.is_shared (Robert Collins, Vincent Ladeuil).
1401
1402
    def test_is_not_shared(self):
2018.5.58 by Wouter van Heyst
Small test fixes to reflect naming and documentation
1403
        """For a shared repository, ('no', ) is returned."""
2018.5.57 by Robert Collins
Implement RemoteRepository.is_shared (Robert Collins, Vincent Ladeuil).
1404
        backing = self.get_transport()
1405
        request = smart.repository.SmartServerRepositoryIsShared(backing)
1406
        self.make_repository('.', shared=False)
1407
        self.assertEqual(SmartServerResponse(('no', )),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1408
            request.execute('', ))
1409
1410
1411
class TestSmartServerRepositoryLockWrite(tests.TestCaseWithMemoryTransport):
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
1412
1413
    def test_lock_write_on_unlocked_repo(self):
1414
        backing = self.get_transport()
1415
        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.
1416
        repository = self.make_repository('.', format='knit')
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1417
        response = request.execute('')
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
1418
        nonce = repository.control_files._lock.peek().get('nonce')
1419
        self.assertEqual(SmartServerResponse(('ok', nonce)), response)
1420
        # The repository is now locked.  Verify that with a new repository
1421
        # object.
1422
        new_repo = repository.bzrdir.open_repository()
1423
        self.assertRaises(errors.LockContention, new_repo.lock_write)
4327.1.10 by Vincent Ladeuil
Fix 10 more lock-related test failures.
1424
        # Cleanup
1425
        request = smart.repository.SmartServerRepositoryUnlock(backing)
1426
        response = request.execute('', nonce)
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
1427
1428
    def test_lock_write_on_locked_repo(self):
1429
        backing = self.get_transport()
1430
        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.
1431
        repository = self.make_repository('.', format='knit')
4327.1.10 by Vincent Ladeuil
Fix 10 more lock-related test failures.
1432
        repo_token = repository.lock_write()
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
1433
        repository.leave_lock_in_place()
1434
        repository.unlock()
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1435
        response = request.execute('')
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
1436
        self.assertEqual(
1437
            SmartServerResponse(('LockContention',)), response)
4327.1.10 by Vincent Ladeuil
Fix 10 more lock-related test failures.
1438
        # Cleanup
1439
        repository.lock_write(repo_token)
1440
        repository.dont_leave_lock_in_place()
1441
        repository.unlock()
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
1442
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.
1443
    def test_lock_write_on_readonly_transport(self):
1444
        backing = self.get_readonly_transport()
1445
        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.
1446
        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.
1447
        response = request.execute('')
2872.5.3 by Martin Pool
Pass back LockFailed from smart server lock methods
1448
        self.assertFalse(response.is_successful())
1449
        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.
1450
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
1451
4144.3.1 by Andrew Bennetts
Add Repository.insert_stream_locked server-side implementation, plus tests for server-side _translate_error.
1452
class TestInsertStreamBase(tests.TestCaseWithMemoryTransport):
1453
1454
    def make_empty_byte_stream(self, repo):
1455
        byte_stream = smart.repository._stream_to_byte_stream([], repo._format)
1456
        return ''.join(byte_stream)
1457
1458
1459
class TestSmartServerRepositoryInsertStream(TestInsertStreamBase):
1460
1461
    def test_insert_stream_empty(self):
1462
        backing = self.get_transport()
1463
        request = smart.repository.SmartServerRepositoryInsertStream(backing)
1464
        repository = self.make_repository('.')
1465
        response = request.execute('', '')
1466
        self.assertEqual(None, response)
1467
        response = request.do_chunk(self.make_empty_byte_stream(repository))
1468
        self.assertEqual(None, response)
1469
        response = request.do_end()
1470
        self.assertEqual(SmartServerResponse(('ok', )), response)
1471
        
1472
1473
class TestSmartServerRepositoryInsertStreamLocked(TestInsertStreamBase):
1474
1475
    def test_insert_stream_empty(self):
1476
        backing = self.get_transport()
1477
        request = smart.repository.SmartServerRepositoryInsertStreamLocked(
1478
            backing)
1479
        repository = self.make_repository('.', format='knit')
1480
        lock_token = repository.lock_write()
1481
        response = request.execute('', '', lock_token)
1482
        self.assertEqual(None, response)
1483
        response = request.do_chunk(self.make_empty_byte_stream(repository))
1484
        self.assertEqual(None, response)
1485
        response = request.do_end()
1486
        self.assertEqual(SmartServerResponse(('ok', )), response)
1487
        repository.unlock()
1488
1489
    def test_insert_stream_with_wrong_lock_token(self):
1490
        backing = self.get_transport()
1491
        request = smart.repository.SmartServerRepositoryInsertStreamLocked(
1492
            backing)
1493
        repository = self.make_repository('.', format='knit')
1494
        lock_token = repository.lock_write()
1495
        self.assertRaises(
1496
            errors.TokenMismatch, request.execute, '', '', 'wrong-token')
1497
        repository.unlock()
1498
1499
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1500
class TestSmartServerRepositoryUnlock(tests.TestCaseWithMemoryTransport):
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
1501
1502
    def setUp(self):
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1503
        tests.TestCaseWithMemoryTransport.setUp(self)
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
1504
1505
    def test_unlock_on_locked_repo(self):
1506
        backing = self.get_transport()
1507
        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.
1508
        repository = self.make_repository('.', format='knit')
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
1509
        token = repository.lock_write()
1510
        repository.leave_lock_in_place()
1511
        repository.unlock()
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1512
        response = request.execute('', token)
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
1513
        self.assertEqual(
1514
            SmartServerResponse(('ok',)), response)
1515
        # The repository is now unlocked.  Verify that with a new repository
1516
        # object.
1517
        new_repo = repository.bzrdir.open_repository()
1518
        new_repo.lock_write()
1519
        new_repo.unlock()
1520
1521
    def test_unlock_on_unlocked_repo(self):
1522
        backing = self.get_transport()
1523
        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.
1524
        repository = self.make_repository('.', format='knit')
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1525
        response = request.execute('', 'some token')
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
1526
        self.assertEqual(
1527
            SmartServerResponse(('TokenMismatch',)), response)
1528
1529
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1530
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.
1531
1532
    def test_is_readonly_no(self):
1533
        backing = self.get_transport()
1534
        request = smart.request.SmartServerIsReadonly(backing)
1535
        response = request.execute()
1536
        self.assertEqual(
1537
            SmartServerResponse(('no',)), response)
1538
1539
    def test_is_readonly_yes(self):
1540
        backing = self.get_readonly_transport()
1541
        request = smart.request.SmartServerIsReadonly(backing)
1542
        response = request.execute()
1543
        self.assertEqual(
1544
            SmartServerResponse(('yes',)), response)
1545
1546
4017.3.4 by Robert Collins
Create a verb for Repository.set_make_working_trees.
1547
class TestSmartServerRepositorySetMakeWorkingTrees(tests.TestCaseWithMemoryTransport):
1548
1549
    def test_set_false(self):
1550
        backing = self.get_transport()
1551
        repo = self.make_repository('.', shared=True)
1552
        repo.set_make_working_trees(True)
1553
        request_class = smart.repository.SmartServerRepositorySetMakeWorkingTrees
1554
        request = request_class(backing)
1555
        self.assertEqual(SuccessfulSmartServerResponse(('ok',)),
1556
            request.execute('', 'False'))
1557
        repo = repo.bzrdir.open_repository()
1558
        self.assertFalse(repo.make_working_trees())
1559
1560
    def test_set_true(self):
1561
        backing = self.get_transport()
1562
        repo = self.make_repository('.', shared=True)
1563
        repo.set_make_working_trees(False)
1564
        request_class = smart.repository.SmartServerRepositorySetMakeWorkingTrees
1565
        request = request_class(backing)
1566
        self.assertEqual(SuccessfulSmartServerResponse(('ok',)),
1567
            request.execute('', 'True'))
1568
        repo = repo.bzrdir.open_repository()
1569
        self.assertTrue(repo.make_working_trees())
1570
1571
3801.1.4 by Andrew Bennetts
Add tests for autopack RPC.
1572
class TestSmartServerPackRepositoryAutopack(tests.TestCaseWithTransport):
1573
1574
    def make_repo_needing_autopacking(self, path='.'):
1575
        # Make a repo in need of autopacking.
1576
        tree = self.make_branch_and_tree('.', format='pack-0.92')
1577
        repo = tree.branch.repository
1578
        # monkey-patch the pack collection to disable autopacking
1579
        repo._pack_collection._max_pack_count = lambda count: count
1580
        for x in range(10):
1581
            tree.commit('commit %s' % x)
1582
        self.assertEqual(10, len(repo._pack_collection.names()))
1583
        del repo._pack_collection._max_pack_count
1584
        return repo
1585
1586
    def test_autopack_needed(self):
1587
        repo = self.make_repo_needing_autopacking()
4145.1.6 by Robert Collins
More test fallout, but all caught now.
1588
        repo.lock_write()
1589
        self.addCleanup(repo.unlock)
3801.1.4 by Andrew Bennetts
Add tests for autopack RPC.
1590
        backing = self.get_transport()
1591
        request = smart.packrepository.SmartServerPackRepositoryAutopack(
1592
            backing)
1593
        response = request.execute('')
1594
        self.assertEqual(SmartServerResponse(('ok',)), response)
1595
        repo._pack_collection.reload_pack_names()
1596
        self.assertEqual(1, len(repo._pack_collection.names()))
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
1597
3801.1.4 by Andrew Bennetts
Add tests for autopack RPC.
1598
    def test_autopack_not_needed(self):
1599
        tree = self.make_branch_and_tree('.', format='pack-0.92')
1600
        repo = tree.branch.repository
4145.1.6 by Robert Collins
More test fallout, but all caught now.
1601
        repo.lock_write()
1602
        self.addCleanup(repo.unlock)
3801.1.4 by Andrew Bennetts
Add tests for autopack RPC.
1603
        for x in range(9):
1604
            tree.commit('commit %s' % x)
1605
        backing = self.get_transport()
1606
        request = smart.packrepository.SmartServerPackRepositoryAutopack(
1607
            backing)
1608
        response = request.execute('')
1609
        self.assertEqual(SmartServerResponse(('ok',)), response)
1610
        repo._pack_collection.reload_pack_names()
1611
        self.assertEqual(9, len(repo._pack_collection.names()))
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
1612
3801.1.4 by Andrew Bennetts
Add tests for autopack RPC.
1613
    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.
1614
        """A request to autopack a non-pack repo is a no-op."""
3801.1.4 by Andrew Bennetts
Add tests for autopack RPC.
1615
        repo = self.make_repository('.', format='knit')
1616
        backing = self.get_transport()
1617
        request = smart.packrepository.SmartServerPackRepositoryAutopack(
1618
            backing)
1619
        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.
1620
        self.assertEqual(SmartServerResponse(('ok',)), response)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
1621
3801.1.4 by Andrew Bennetts
Add tests for autopack RPC.
1622
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
1623
class TestHandlers(tests.TestCase):
1624
    """Tests for the request.request_handlers object."""
1625
3526.3.1 by Andrew Bennetts
Remove registrations of defunct HPSS verbs.
1626
    def test_all_registrations_exist(self):
1627
        """All registered request_handlers can be found."""
1628
        # If there's a typo in a register_lazy call, this loop will fail with
1629
        # an AttributeError.
1630
        for key, item in smart.request.request_handlers.iteritems():
1631
            pass
1632
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
1633
    def assertHandlerEqual(self, verb, handler):
1634
        self.assertEqual(smart.request.request_handlers.get(verb), handler)
1635
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
1636
    def test_registered_methods(self):
1637
        """Test that known methods are registered to the correct object."""
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
1638
        self.assertHandlerEqual('Branch.get_config_file',
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
1639
            smart.branch.SmartServerBranchGetConfigFile)
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
1640
        self.assertHandlerEqual('Branch.get_parent',
4078.2.1 by Robert Collins
Add a Branch.get_parent remote call for RemoteBranch.
1641
            smart.branch.SmartServerBranchGetParent)
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
1642
        self.assertHandlerEqual('Branch.get_tags_bytes',
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.
1643
            smart.branch.SmartServerBranchGetTagsBytes)
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
1644
        self.assertHandlerEqual('Branch.lock_write',
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1645
            smart.branch.SmartServerBranchRequestLockWrite)
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
1646
        self.assertHandlerEqual('Branch.last_revision_info',
2018.5.51 by Wouter van Heyst
Test and implement RemoteBranch.last_revision_info()
1647
            smart.branch.SmartServerBranchRequestLastRevisionInfo)
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
1648
        self.assertHandlerEqual('Branch.revision_history',
2018.5.38 by Robert Collins
Implement RemoteBranch.revision_history().
1649
            smart.branch.SmartServerRequestRevisionHistory)
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
1650
        self.assertHandlerEqual('Branch.set_config_option',
4226.2.1 by Robert Collins
Set branch config options via a smart method.
1651
            smart.branch.SmartServerBranchRequestSetConfigOption)
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
1652
        self.assertHandlerEqual('Branch.set_last_revision',
2018.5.77 by Wouter van Heyst
Fix typo in request_handlers registration of Branch.set_last_revision, and test that registration
1653
            smart.branch.SmartServerBranchRequestSetLastRevision)
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
1654
        self.assertHandlerEqual('Branch.set_last_revision_info',
2892.2.1 by Andrew Bennetts
Add Branch.set_last_revision_info smart method, and make the RemoteBranch client use it.
1655
            smart.branch.SmartServerBranchRequestSetLastRevisionInfo)
4288.1.7 by Robert Collins
Add new remote server verb Branch.set_parent_location, dropping roundtrips further on push operations.
1656
        self.assertHandlerEqual('Branch.set_last_revision_ex',
1657
            smart.branch.SmartServerBranchRequestSetLastRevisionEx)
1658
        self.assertHandlerEqual('Branch.set_parent_location',
1659
            smart.branch.SmartServerBranchRequestSetParentLocation)
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
1660
        self.assertHandlerEqual('Branch.unlock',
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1661
            smart.branch.SmartServerBranchRequestUnlock)
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
1662
        self.assertHandlerEqual('BzrDir.find_repository',
3221.3.2 by Robert Collins
* New remote method ``RemoteBzrDir.find_repositoryV2`` adding support for
1663
            smart.bzrdir.SmartServerRequestFindRepositoryV1)
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
1664
        self.assertHandlerEqual('BzrDir.find_repositoryV2',
3221.3.2 by Robert Collins
* New remote method ``RemoteBzrDir.find_repositoryV2`` adding support for
1665
            smart.bzrdir.SmartServerRequestFindRepositoryV2)
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
1666
        self.assertHandlerEqual('BzrDirFormat.initialize',
2018.5.42 by Robert Collins
Various hopefully improvements, but wsgi is broken, handing over to spiv :).
1667
            smart.bzrdir.SmartServerRequestInitializeBzrDir)
4436.1.1 by Andrew Bennetts
Rename BzrDirFormat.initialize_ex verb to BzrDirFormat.initialize_ex_1.16.
1668
        self.assertHandlerEqual('BzrDirFormat.initialize_ex_1.16',
4294.2.7 by Robert Collins
Start building up a BzrDir.initialize_ex verb for the smart server.
1669
            smart.bzrdir.SmartServerRequestBzrDirInitializeEx)
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
1670
        self.assertHandlerEqual('BzrDir.cloning_metadir',
4070.2.3 by Robert Collins
Get BzrDir.cloning_metadir working.
1671
            smart.bzrdir.SmartServerBzrDirRequestCloningMetaDir)
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
1672
        self.assertHandlerEqual('BzrDir.get_config_file',
1673
            smart.bzrdir.SmartServerBzrDirRequestConfigFile)
1674
        self.assertHandlerEqual('BzrDir.open_branch',
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
1675
            smart.bzrdir.SmartServerRequestOpenBranch)
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
1676
        self.assertHandlerEqual('BzrDir.open_branchV2',
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.
1677
            smart.bzrdir.SmartServerRequestOpenBranchV2)
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
1678
        self.assertHandlerEqual('PackRepository.autopack',
3801.1.4 by Andrew Bennetts
Add tests for autopack RPC.
1679
            smart.packrepository.SmartServerPackRepositoryAutopack)
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
1680
        self.assertHandlerEqual('Repository.gather_stats',
2018.10.2 by v.ladeuil+lp at free
gather_stats server side and request registration
1681
            smart.repository.SmartServerRepositoryGatherStats)
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
1682
        self.assertHandlerEqual('Repository.get_parent_map',
3172.5.6 by Robert Collins
Create new smart server verb Repository.get_parent_map.
1683
            smart.repository.SmartServerRepositoryGetParentMap)
4419.2.6 by Andrew Bennetts
Add tests for server-side logic, and fix the bugs exposed by those tests.
1684
        self.assertHandlerEqual('Repository.get_rev_id_for_revno',
1685
            smart.repository.SmartServerRepositoryGetRevIdForRevno)
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
1686
        self.assertHandlerEqual('Repository.get_revision_graph',
2018.5.67 by Wouter van Heyst
Implement RemoteRepository.get_revision_graph (Wouter van Heyst, Robert Collins)
1687
            smart.repository.SmartServerRepositoryGetRevisionGraph)
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
1688
        self.assertHandlerEqual('Repository.get_stream',
4144.3.1 by Andrew Bennetts
Add Repository.insert_stream_locked server-side implementation, plus tests for server-side _translate_error.
1689
            smart.repository.SmartServerRepositoryGetStream)
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
1690
        self.assertHandlerEqual('Repository.has_revision',
2018.5.40 by Robert Collins
Implement a remote Repository.has_revision method.
1691
            smart.repository.SmartServerRequestHasRevision)
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
1692
        self.assertHandlerEqual('Repository.insert_stream',
4144.3.1 by Andrew Bennetts
Add Repository.insert_stream_locked server-side implementation, plus tests for server-side _translate_error.
1693
            smart.repository.SmartServerRepositoryInsertStream)
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
1694
        self.assertHandlerEqual('Repository.insert_stream_locked',
4144.3.1 by Andrew Bennetts
Add Repository.insert_stream_locked server-side implementation, plus tests for server-side _translate_error.
1695
            smart.repository.SmartServerRepositoryInsertStreamLocked)
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
1696
        self.assertHandlerEqual('Repository.is_shared',
2018.5.57 by Robert Collins
Implement RemoteRepository.is_shared (Robert Collins, Vincent Ladeuil).
1697
            smart.repository.SmartServerRepositoryIsShared)
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
1698
        self.assertHandlerEqual('Repository.lock_write',
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
1699
            smart.repository.SmartServerRepositoryLockWrite)
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
1700
        self.assertHandlerEqual('Repository.tarball',
2535.3.69 by Andrew Bennetts
Add check for Repository.stream_knit_data_for_revisions to TestHandlers.test_registered_methods.
1701
            smart.repository.SmartServerRepositoryTarball)
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
1702
        self.assertHandlerEqual('Repository.unlock',
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
1703
            smart.repository.SmartServerRepositoryUnlock)
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
1704
        self.assertHandlerEqual('Transport.is_readonly',
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.
1705
            smart.request.SmartServerIsReadonly)