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