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