~bzr-pqm/bzr/bzr.dev

2018.18.1 by Martin Pool
Add stub Repository.tarball smart method
1
# Copyright (C) 2006, 2007 Canonical Ltd
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
2
#
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
2748.4.1 by Andrew Bennetts
Implement a ChunkedBodyDecoder.
17
"""Tests for the smart wire/domain protocol.
18
19
This module contains tests for the domain-level smart requests and responses,
3015.2.12 by Robert Collins
Make test_smart use specific formats as needed to exercise locked and unlocked repositories.
20
such as the 'Branch.lock_write' request. Many of these use specific disk
21
formats to exercise calls that only make sense for formats with specific
22
properties.
2748.4.1 by Andrew Bennetts
Implement a ChunkedBodyDecoder.
23
24
Tests for low-level protocol encoding are found in test_smart_transport.
25
"""
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
26
3211.5.2 by Robert Collins
Change RemoteRepository.get_parent_map to use bz2 not gzip for compression.
27
import bz2
2692.1.18 by Andrew Bennetts
Merge from bzr.dev.
28
from cStringIO import StringIO
2018.18.2 by Martin Pool
smart method Repository.tarball actually returns the tarball
29
import tarfile
30
2692.1.2 by Andrew Bennetts
Merge from bzr.dev.
31
from bzrlib import (
32
    bzrdir,
33
    errors,
34
    pack,
35
    smart,
36
    tests,
37
    urlutils,
38
    )
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
39
from bzrlib.branch import BranchReferenceFormat
2692.1.22 by Andrew Bennetts
Reinstate imports needed to run test_smart alone.
40
import bzrlib.smart.branch
41
import bzrlib.smart.bzrdir
42
import bzrlib.smart.repository
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
43
from bzrlib.smart.request import (
44
    FailedSmartServerResponse,
45
    SmartServerRequest,
46
    SmartServerResponse,
47
    SuccessfulSmartServerResponse,
48
    )
3221.3.2 by Robert Collins
* New remote method ``RemoteBzrDir.find_repositoryV2`` adding support for
49
from bzrlib.tests import (
50
    iter_suite_tests,
51
    split_suite_by_re,
52
    TestScenarioApplier,
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
2535.3.15 by Andrew Bennetts
Add KnitVersionedFile.get_stream_as_bytes, start smart implementation of RemoteRepository.get_data_stream.
55
from bzrlib.util import bencode
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
56
57
3221.3.2 by Robert Collins
* New remote method ``RemoteBzrDir.find_repositoryV2`` adding support for
58
def load_tests(standard_tests, module, loader):
59
    """Multiply tests version and protocol consistency."""
60
    # FindRepository tests.
61
    bzrdir_mod = bzrlib.smart.bzrdir
62
    applier = TestScenarioApplier()
63
    applier.scenarios = [
64
        ("find_repository", {
65
            "_request_class":bzrdir_mod.SmartServerRequestFindRepositoryV1}),
66
        ("find_repositoryV2", {
67
            "_request_class":bzrdir_mod.SmartServerRequestFindRepositoryV2}),
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")
73
    for test in iter_suite_tests(v1_and_2):
74
        result.addTests(applier.adapt(test))
75
    del applier.scenarios[0]
76
    for test in iter_suite_tests(v2_only):
77
        result.addTests(applier.adapt(test))
78
    return result
79
80
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
81
class TestCaseWithChrootedTransport(tests.TestCaseWithTransport):
82
83
    def setUp(self):
84
        tests.TestCaseWithTransport.setUp(self)
85
        self._chroot_server = None
86
87
    def get_transport(self, relpath=None):
88
        if self._chroot_server is None:
89
            backing_transport = tests.TestCaseWithTransport.get_transport(self)
90
            self._chroot_server = chroot.ChrootServer(backing_transport)
91
            self._chroot_server.setUp()
92
            self.addCleanup(self._chroot_server.tearDown)
93
        t = get_transport(self._chroot_server.get_url())
94
        if relpath is not None:
95
            t = t.clone(relpath)
96
        return t
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
97
98
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
99
class TestCaseWithSmartMedium(tests.TestCaseWithTransport):
100
101
    def setUp(self):
102
        super(TestCaseWithSmartMedium, self).setUp()
103
        # We're allowed to set  the transport class here, so that we don't use
104
        # the default or a parameterized class, but rather use the
105
        # TestCaseWithTransport infrastructure to set up a smart server and
106
        # transport.
107
        self.transport_server = smart.server.SmartTCPServer_for_testing
108
109
    def get_smart_medium(self):
110
        """Get a smart medium to use in tests."""
111
        return self.get_transport().get_smart_medium()
112
113
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
114
class TestSmartServerResponse(tests.TestCase):
115
116
    def test__eq__(self):
117
        self.assertEqual(SmartServerResponse(('ok', )),
118
            SmartServerResponse(('ok', )))
119
        self.assertEqual(SmartServerResponse(('ok', ), 'body'),
120
            SmartServerResponse(('ok', ), 'body'))
121
        self.assertNotEqual(SmartServerResponse(('ok', )),
122
            SmartServerResponse(('notok', )))
123
        self.assertNotEqual(SmartServerResponse(('ok', ), 'body'),
124
            SmartServerResponse(('ok', )))
2018.5.41 by Robert Collins
Fix SmartServerResponse.__eq__ to handle None.
125
        self.assertNotEqual(None,
126
            SmartServerResponse(('ok', )))
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
127
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
128
    def test__str__(self):
129
        """SmartServerResponses can be stringified."""
130
        self.assertEqual(
131
            "<SmartServerResponse status=OK args=('args',) body='body'>",
132
            str(SuccessfulSmartServerResponse(('args',), 'body')))
133
        self.assertEqual(
134
            "<SmartServerResponse status=ERR args=('args',) body='body'>",
135
            str(FailedSmartServerResponse(('args',), 'body')))
136
137
138
class TestSmartServerRequest(tests.TestCaseWithMemoryTransport):
139
140
    def test_translate_client_path(self):
141
        transport = self.get_transport()
142
        request = SmartServerRequest(transport, 'foo/')
143
        self.assertEqual('./', request.translate_client_path('foo/'))
144
        self.assertRaises(
145
            errors.InvalidURLJoin, request.translate_client_path, 'foo/..')
146
        self.assertRaises(
147
            errors.PathNotChild, request.translate_client_path, '/')
148
        self.assertRaises(
149
            errors.PathNotChild, request.translate_client_path, 'bar/')
150
        self.assertEqual('./baz', request.translate_client_path('foo/baz'))
151
152
    def test_transport_from_client_path(self):
153
        transport = self.get_transport()
154
        request = SmartServerRequest(transport, 'foo/')
155
        self.assertEqual(
156
            transport.base,
157
            request.transport_from_client_path('foo/').base)
158
159
160
class TestSmartServerRequestFindRepository(tests.TestCaseWithMemoryTransport):
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
161
    """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.
162
163
    def test_no_repository(self):
164
        """When there is no repository to be found, ('norepository', ) is returned."""
165
        backing = self.get_transport()
3221.3.2 by Robert Collins
* New remote method ``RemoteBzrDir.find_repositoryV2`` adding support for
166
        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.
167
        self.make_bzrdir('.')
168
        self.assertEqual(SmartServerResponse(('norepository', )),
2692.1.19 by Andrew Bennetts
Tweak for consistency suggested by John's review.
169
            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.
170
171
    def test_nonshared_repository(self):
172
        # nonshared repositorys only allow 'find' to return a handle when the 
173
        # path the repository is being searched on is the same as that that 
174
        # the repository is at.
175
        backing = self.get_transport()
3221.3.2 by Robert Collins
* New remote method ``RemoteBzrDir.find_repositoryV2`` adding support for
176
        request = self._request_class(backing)
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
177
        result = self._make_repository_and_result()
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
178
        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.
179
        self.make_bzrdir('subdir')
180
        self.assertEqual(SmartServerResponse(('norepository', )),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
181
            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.
182
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
183
    def _make_repository_and_result(self, shared=False, format=None):
184
        """Convenience function to setup a repository.
185
186
        :result: The SmartServerResponse to expect when opening it.
187
        """
188
        repo = self.make_repository('.', shared=shared, format=format)
189
        if repo.supports_rich_root():
2018.5.166 by Andrew Bennetts
Small changes in response to Aaron's review.
190
            rich_root = 'yes'
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
191
        else:
2018.5.166 by Andrew Bennetts
Small changes in response to Aaron's review.
192
            rich_root = 'no'
2018.5.138 by Robert Collins
Merge bzr.dev.
193
        if repo._format.supports_tree_reference:
2018.5.166 by Andrew Bennetts
Small changes in response to Aaron's review.
194
            subtrees = 'yes'
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
195
        else:
2018.5.166 by Andrew Bennetts
Small changes in response to Aaron's review.
196
            subtrees = 'no'
3221.3.2 by Robert Collins
* New remote method ``RemoteBzrDir.find_repositoryV2`` adding support for
197
        if (smart.bzrdir.SmartServerRequestFindRepositoryV2 ==
198
            self._request_class):
199
            # All tests so far are on formats, and for non-external
200
            # repositories.
201
            return SuccessfulSmartServerResponse(
202
                ('ok', '', rich_root, subtrees, 'no'))
203
        else:
204
            return SuccessfulSmartServerResponse(('ok', '', rich_root, subtrees))
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
205
2018.5.34 by Robert Collins
Get test_remote.BasicRemoteObjectTests.test_open_remote_branch passing by implementing a remote method BzrDir.find_repository.
206
    def test_shared_repository(self):
207
        """When there is a shared repository, we get 'ok', 'relpath-to-repo'."""
208
        backing = self.get_transport()
3221.3.2 by Robert Collins
* New remote method ``RemoteBzrDir.find_repositoryV2`` adding support for
209
        request = self._request_class(backing)
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
210
        result = self._make_repository_and_result(shared=True)
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
211
        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.
212
        self.make_bzrdir('subdir')
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
213
        result2 = SmartServerResponse(result.args[0:1] + ('..', ) + result.args[2:])
214
        self.assertEqual(result2,
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
215
            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.
216
        self.make_bzrdir('subdir/deeper')
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
217
        result3 = SmartServerResponse(result.args[0:1] + ('../..', ) + result.args[2:])
218
        self.assertEqual(result3,
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
219
            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.
220
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
221
    def test_rich_root_and_subtree_encoding(self):
222
        """Test for the format attributes for rich root and subtree support."""
223
        backing = self.get_transport()
3221.3.2 by Robert Collins
* New remote method ``RemoteBzrDir.find_repositoryV2`` adding support for
224
        request = self._request_class(backing)
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
225
        result = self._make_repository_and_result(format='dirstate-with-subtree')
226
        # check the test will be valid
2018.5.166 by Andrew Bennetts
Small changes in response to Aaron's review.
227
        self.assertEqual('yes', result.args[2])
228
        self.assertEqual('yes', result.args[3])
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
229
        self.assertEqual(result, request.execute(''))
230
3221.3.2 by Robert Collins
* New remote method ``RemoteBzrDir.find_repositoryV2`` adding support for
231
    def test_supports_external_lookups_no_v2(self):
232
        """Test for the supports_external_lookups attribute."""
233
        backing = self.get_transport()
234
        request = self._request_class(backing)
235
        result = self._make_repository_and_result(format='dirstate-with-subtree')
236
        # check the test will be valid
237
        self.assertEqual('no', result.args[4])
2692.1.24 by Andrew Bennetts
Merge from bzr.dev.
238
        self.assertEqual(result, request.execute(''))
239
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
240
241
class TestSmartServerRequestInitializeBzrDir(tests.TestCaseWithMemoryTransport):
2018.5.42 by Robert Collins
Various hopefully improvements, but wsgi is broken, handing over to spiv :).
242
243
    def test_empty_dir(self):
244
        """Initializing an empty dir should succeed and do it."""
245
        backing = self.get_transport()
246
        request = smart.bzrdir.SmartServerRequestInitializeBzrDir(backing)
247
        self.assertEqual(SmartServerResponse(('ok', )),
2692.1.20 by Andrew Bennetts
Tweak for consistency suggested by John's review.
248
            request.execute(''))
2018.5.42 by Robert Collins
Various hopefully improvements, but wsgi is broken, handing over to spiv :).
249
        made_dir = bzrdir.BzrDir.open_from_transport(backing)
250
        # no branch, tree or repository is expected with the current 
251
        # default formart.
252
        self.assertRaises(errors.NoWorkingTree, made_dir.open_workingtree)
253
        self.assertRaises(errors.NotBranchError, made_dir.open_branch)
254
        self.assertRaises(errors.NoRepositoryPresent, made_dir.open_repository)
255
256
    def test_missing_dir(self):
257
        """Initializing a missing directory should fail like the bzrdir api."""
258
        backing = self.get_transport()
259
        request = smart.bzrdir.SmartServerRequestInitializeBzrDir(backing)
260
        self.assertRaises(errors.NoSuchFile,
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
261
            request.execute, 'subdir')
2018.5.42 by Robert Collins
Various hopefully improvements, but wsgi is broken, handing over to spiv :).
262
263
    def test_initialized_dir(self):
264
        """Initializing an extant bzrdir should fail like the bzrdir api."""
265
        backing = self.get_transport()
266
        request = smart.bzrdir.SmartServerRequestInitializeBzrDir(backing)
267
        self.make_bzrdir('subdir')
268
        self.assertRaises(errors.FileExists,
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
269
            request.execute, 'subdir')
270
271
272
class TestSmartServerRequestOpenBranch(TestCaseWithChrootedTransport):
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
273
274
    def test_no_branch(self):
275
        """When there is no branch, ('nobranch', ) is returned."""
276
        backing = self.get_transport()
277
        request = smart.bzrdir.SmartServerRequestOpenBranch(backing)
278
        self.make_bzrdir('.')
279
        self.assertEqual(SmartServerResponse(('nobranch', )),
2692.1.20 by Andrew Bennetts
Tweak for consistency suggested by John's review.
280
            request.execute(''))
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
281
282
    def test_branch(self):
283
        """When there is a branch, 'ok' is returned."""
284
        backing = self.get_transport()
285
        request = smart.bzrdir.SmartServerRequestOpenBranch(backing)
286
        self.make_branch('.')
287
        self.assertEqual(SmartServerResponse(('ok', '')),
2692.1.20 by Andrew Bennetts
Tweak for consistency suggested by John's review.
288
            request.execute(''))
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
289
290
    def test_branch_reference(self):
291
        """When there is a branch reference, the reference URL is returned."""
292
        backing = self.get_transport()
293
        request = smart.bzrdir.SmartServerRequestOpenBranch(backing)
294
        branch = self.make_branch('branch')
295
        checkout = branch.create_checkout('reference',lightweight=True)
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
296
        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.
297
        self.assertFileEqual(reference_url, 'reference/.bzr/branch/location')
298
        self.assertEqual(SmartServerResponse(('ok', reference_url)),
2692.1.20 by Andrew Bennetts
Tweak for consistency suggested by John's review.
299
            request.execute('reference'))
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
300
301
302
class TestSmartServerRequestRevisionHistory(tests.TestCaseWithMemoryTransport):
2018.5.38 by Robert Collins
Implement RemoteBranch.revision_history().
303
304
    def test_empty(self):
305
        """For an empty branch, the body is empty."""
306
        backing = self.get_transport()
307
        request = smart.branch.SmartServerRequestRevisionHistory(backing)
308
        self.make_branch('.')
309
        self.assertEqual(SmartServerResponse(('ok', ), ''),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
310
            request.execute(''))
2018.5.38 by Robert Collins
Implement RemoteBranch.revision_history().
311
312
    def test_not_empty(self):
313
        """For a non-empty branch, the body is empty."""
314
        backing = self.get_transport()
315
        request = smart.branch.SmartServerRequestRevisionHistory(backing)
316
        tree = self.make_branch_and_memory_tree('.')
317
        tree.lock_write()
318
        tree.add('')
319
        r1 = tree.commit('1st commit')
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
320
        r2 = tree.commit('2nd commit', rev_id=u'\xc8'.encode('utf-8'))
2018.5.38 by Robert Collins
Implement RemoteBranch.revision_history().
321
        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.
322
        self.assertEqual(
323
            SmartServerResponse(('ok', ), ('\x00'.join([r1, r2]))),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
324
            request.execute(''))
325
326
327
class TestSmartServerBranchRequest(tests.TestCaseWithMemoryTransport):
2018.5.49 by Wouter van Heyst
Refactor SmartServerBranchRequest out from SmartServerRequestRevisionHistory to
328
329
    def test_no_branch(self):
330
        """When there is a bzrdir and no branch, NotBranchError is raised."""
331
        backing = self.get_transport()
332
        request = smart.branch.SmartServerBranchRequest(backing)
333
        self.make_bzrdir('.')
334
        self.assertRaises(errors.NotBranchError,
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
335
            request.execute, '')
2018.5.49 by Wouter van Heyst
Refactor SmartServerBranchRequest out from SmartServerRequestRevisionHistory to
336
2018.5.38 by Robert Collins
Implement RemoteBranch.revision_history().
337
    def test_branch_reference(self):
338
        """When there is a branch reference, NotBranchError is raised."""
339
        backing = self.get_transport()
2018.5.49 by Wouter van Heyst
Refactor SmartServerBranchRequest out from SmartServerRequestRevisionHistory to
340
        request = smart.branch.SmartServerBranchRequest(backing)
2018.5.38 by Robert Collins
Implement RemoteBranch.revision_history().
341
        branch = self.make_branch('branch')
342
        checkout = branch.create_checkout('reference',lightweight=True)
343
        self.assertRaises(errors.NotBranchError,
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
344
            request.execute, 'checkout')
345
346
347
class TestSmartServerBranchRequestLastRevisionInfo(tests.TestCaseWithMemoryTransport):
2018.5.50 by Wouter van Heyst
Add SmartServerBranchRequestLastRevisionInfo method.
348
349
    def test_empty(self):
2018.5.170 by Andrew Bennetts
Use 'null:' instead of '' to mean NULL_REVISION on the wire.
350
        """For an empty branch, the result is ('ok', '0', 'null:')."""
2018.5.50 by Wouter van Heyst
Add SmartServerBranchRequestLastRevisionInfo method.
351
        backing = self.get_transport()
352
        request = smart.branch.SmartServerBranchRequestLastRevisionInfo(backing)
353
        self.make_branch('.')
2018.5.170 by Andrew Bennetts
Use 'null:' instead of '' to mean NULL_REVISION on the wire.
354
        self.assertEqual(SmartServerResponse(('ok', '0', 'null:')),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
355
            request.execute(''))
2018.5.50 by Wouter van Heyst
Add SmartServerBranchRequestLastRevisionInfo method.
356
357
    def test_not_empty(self):
358
        """For a non-empty branch, the result is ('ok', 'revno', 'revid')."""
359
        backing = self.get_transport()
360
        request = smart.branch.SmartServerBranchRequestLastRevisionInfo(backing)
361
        tree = self.make_branch_and_memory_tree('.')
362
        tree.lock_write()
363
        tree.add('')
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
364
        rev_id_utf8 = u'\xc8'.encode('utf-8')
2018.5.50 by Wouter van Heyst
Add SmartServerBranchRequestLastRevisionInfo method.
365
        r1 = tree.commit('1st commit')
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
366
        r2 = tree.commit('2nd commit', rev_id=rev_id_utf8)
2018.5.50 by Wouter van Heyst
Add SmartServerBranchRequestLastRevisionInfo method.
367
        tree.unlock()
368
        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.
369
            SmartServerResponse(('ok', '2', rev_id_utf8)),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
370
            request.execute(''))
371
372
373
class TestSmartServerBranchRequestGetConfigFile(tests.TestCaseWithMemoryTransport):
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
374
375
    def test_default(self):
376
        """With no file, we get empty content."""
377
        backing = self.get_transport()
378
        request = smart.branch.SmartServerBranchGetConfigFile(backing)
379
        branch = self.make_branch('.')
380
        # there should be no file by default
381
        content = ''
382
        self.assertEqual(SmartServerResponse(('ok', ), content),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
383
            request.execute(''))
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
384
385
    def test_with_content(self):
386
        # SmartServerBranchGetConfigFile should return the content from
387
        # branch.control_files.get('branch.conf') for now - in the future it may
388
        # perform more complex processing. 
389
        backing = self.get_transport()
390
        request = smart.branch.SmartServerBranchGetConfigFile(backing)
391
        branch = self.make_branch('.')
392
        branch.control_files.put_utf8('branch.conf', 'foo bar baz')
393
        self.assertEqual(SmartServerResponse(('ok', ), 'foo bar baz'),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
394
            request.execute(''))
395
396
397
class TestSmartServerBranchRequestSetLastRevision(tests.TestCaseWithMemoryTransport):
2018.12.3 by Andrew Bennetts
Add a Branch.set_last_revision smart method, and make RemoteBranch.set_revision_history use it.
398
399
    def test_empty(self):
400
        backing = self.get_transport()
401
        request = smart.branch.SmartServerBranchRequestSetLastRevision(backing)
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
402
        b = self.make_branch('.')
2018.5.144 by Andrew Bennetts
Fix four tests I broke with the Branch.lock_write changes.
403
        branch_token = b.lock_write()
404
        repo_token = b.repository.lock_write()
405
        b.repository.unlock()
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
406
        try:
407
            self.assertEqual(SmartServerResponse(('ok',)),
408
                request.execute(
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
409
                    '', branch_token, repo_token,
2018.5.170 by Andrew Bennetts
Use 'null:' instead of '' to mean NULL_REVISION on the wire.
410
                    'null:'))
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
411
        finally:
412
            b.unlock()
2018.12.3 by Andrew Bennetts
Add a Branch.set_last_revision smart method, and make RemoteBranch.set_revision_history use it.
413
414
    def test_not_present_revision_id(self):
415
        backing = self.get_transport()
416
        request = smart.branch.SmartServerBranchRequestSetLastRevision(backing)
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
417
        b = self.make_branch('.')
2018.5.144 by Andrew Bennetts
Fix four tests I broke with the Branch.lock_write changes.
418
        branch_token = b.lock_write()
419
        repo_token = b.repository.lock_write()
420
        b.repository.unlock()
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
421
        try:
422
            revision_id = 'non-existent revision'
423
            self.assertEqual(
424
                SmartServerResponse(('NoSuchRevision', revision_id)),
425
                request.execute(
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
426
                    '', branch_token, repo_token,
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
427
                    revision_id))
428
        finally:
429
            b.unlock()
2018.12.3 by Andrew Bennetts
Add a Branch.set_last_revision smart method, and make RemoteBranch.set_revision_history use it.
430
431
    def test_revision_id_present(self):
432
        backing = self.get_transport()
433
        request = smart.branch.SmartServerBranchRequestSetLastRevision(backing)
434
        tree = self.make_branch_and_memory_tree('.')
435
        tree.lock_write()
436
        tree.add('')
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
437
        rev_id_utf8 = u'\xc8'.encode('utf-8')
438
        r1 = tree.commit('1st commit', rev_id=rev_id_utf8)
2018.12.3 by Andrew Bennetts
Add a Branch.set_last_revision smart method, and make RemoteBranch.set_revision_history use it.
439
        r2 = tree.commit('2nd commit')
440
        tree.unlock()
2018.5.144 by Andrew Bennetts
Fix four tests I broke with the Branch.lock_write changes.
441
        branch_token = tree.branch.lock_write()
442
        repo_token = tree.branch.repository.lock_write()
443
        tree.branch.repository.unlock()
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
444
        try:
445
            self.assertEqual(
446
                SmartServerResponse(('ok',)),
447
                request.execute(
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
448
                    '', branch_token, repo_token,
2018.5.83 by Andrew Bennetts
Fix some test failures caused by the switch from unicode to UTF-8-encoded strs for revision IDs.
449
                    rev_id_utf8))
450
            self.assertEqual([rev_id_utf8], tree.branch.revision_history())
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
451
        finally:
452
            tree.branch.unlock()
2018.12.3 by Andrew Bennetts
Add a Branch.set_last_revision smart method, and make RemoteBranch.set_revision_history use it.
453
454
    def test_revision_id_present2(self):
455
        backing = self.get_transport()
456
        request = smart.branch.SmartServerBranchRequestSetLastRevision(backing)
457
        tree = self.make_branch_and_memory_tree('.')
458
        tree.lock_write()
459
        tree.add('')
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
460
        rev_id_utf8 = u'\xc8'.encode('utf-8')
461
        r1 = tree.commit('1st commit', rev_id=rev_id_utf8)
2018.12.3 by Andrew Bennetts
Add a Branch.set_last_revision smart method, and make RemoteBranch.set_revision_history use it.
462
        r2 = tree.commit('2nd commit')
463
        tree.unlock()
464
        tree.branch.set_revision_history([])
2018.5.144 by Andrew Bennetts
Fix four tests I broke with the Branch.lock_write changes.
465
        branch_token = tree.branch.lock_write()
466
        repo_token = tree.branch.repository.lock_write()
467
        tree.branch.repository.unlock()
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
468
        try:
469
            self.assertEqual(
470
                SmartServerResponse(('ok',)),
471
                request.execute(
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
472
                    '', branch_token, repo_token,
2018.5.83 by Andrew Bennetts
Fix some test failures caused by the switch from unicode to UTF-8-encoded strs for revision IDs.
473
                    rev_id_utf8))
474
            self.assertEqual([rev_id_utf8], tree.branch.revision_history())
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
475
        finally:
476
            tree.branch.unlock()
2018.12.3 by Andrew Bennetts
Add a Branch.set_last_revision smart method, and make RemoteBranch.set_revision_history use it.
477
478
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
479
class TestSmartServerBranchRequestLockWrite(tests.TestCaseWithMemoryTransport):
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
480
481
    def setUp(self):
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
482
        tests.TestCaseWithMemoryTransport.setUp(self)
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
483
484
    def test_lock_write_on_unlocked_branch(self):
485
        backing = self.get_transport()
486
        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.
487
        branch = self.make_branch('.', format='knit')
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
488
        repository = branch.repository
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
489
        response = request.execute('')
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
490
        branch_nonce = branch.control_files._lock.peek().get('nonce')
491
        repository_nonce = repository.control_files._lock.peek().get('nonce')
492
        self.assertEqual(
493
            SmartServerResponse(('ok', branch_nonce, repository_nonce)),
494
            response)
495
        # The branch (and associated repository) is now locked.  Verify that
496
        # with a new branch object.
497
        new_branch = repository.bzrdir.open_branch()
498
        self.assertRaises(errors.LockContention, new_branch.lock_write)
499
500
    def test_lock_write_on_locked_branch(self):
501
        backing = self.get_transport()
502
        request = smart.branch.SmartServerBranchRequestLockWrite(backing)
503
        branch = self.make_branch('.')
504
        branch.lock_write()
505
        branch.leave_lock_in_place()
506
        branch.unlock()
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
507
        response = request.execute('')
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
508
        self.assertEqual(
509
            SmartServerResponse(('LockContention',)), response)
510
511
    def test_lock_write_with_tokens_on_locked_branch(self):
512
        backing = self.get_transport()
513
        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.
514
        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).
515
        branch_token = branch.lock_write()
516
        repo_token = branch.repository.lock_write()
517
        branch.repository.unlock()
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
518
        branch.leave_lock_in_place()
519
        branch.repository.leave_lock_in_place()
520
        branch.unlock()
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
521
        response = request.execute('',
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
522
                                   branch_token, repo_token)
523
        self.assertEqual(
524
            SmartServerResponse(('ok', branch_token, repo_token)), response)
525
526
    def test_lock_write_with_mismatched_tokens_on_locked_branch(self):
527
        backing = self.get_transport()
528
        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.
529
        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).
530
        branch_token = branch.lock_write()
531
        repo_token = branch.repository.lock_write()
532
        branch.repository.unlock()
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
533
        branch.leave_lock_in_place()
534
        branch.repository.leave_lock_in_place()
535
        branch.unlock()
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
536
        response = request.execute('',
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
537
                                   branch_token+'xxx', repo_token)
538
        self.assertEqual(
539
            SmartServerResponse(('TokenMismatch',)), response)
540
541
    def test_lock_write_on_locked_repo(self):
542
        backing = self.get_transport()
543
        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.
544
        branch = self.make_branch('.', format='knit')
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
545
        branch.repository.lock_write()
546
        branch.repository.leave_lock_in_place()
547
        branch.repository.unlock()
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
548
        response = request.execute('')
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
549
        self.assertEqual(
550
            SmartServerResponse(('LockContention',)), response)
551
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.
552
    def test_lock_write_on_readonly_transport(self):
553
        backing = self.get_readonly_transport()
554
        request = smart.branch.SmartServerBranchRequestLockWrite(backing)
555
        branch = self.make_branch('.')
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
556
        root = self.get_transport().clone('/')
557
        path = urlutils.relative_url(root.base, self.get_transport().base)
558
        response = request.execute(path)
2872.5.3 by Martin Pool
Pass back LockFailed from smart server lock methods
559
        error_name, lock_str, why_str = response.args
560
        self.assertFalse(response.is_successful())
561
        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.
562
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
563
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
564
class TestSmartServerBranchRequestUnlock(tests.TestCaseWithMemoryTransport):
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
565
566
    def setUp(self):
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
567
        tests.TestCaseWithMemoryTransport.setUp(self)
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
568
569
    def test_unlock_on_locked_branch_and_repo(self):
570
        backing = self.get_transport()
571
        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.
572
        branch = self.make_branch('.', format='knit')
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
573
        # 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).
574
        branch_token = branch.lock_write()
575
        repo_token = branch.repository.lock_write()
576
        branch.repository.unlock()
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
577
        # Unlock the branch (and repo) object, leaving the physical locks
578
        # in place.
579
        branch.leave_lock_in_place()
580
        branch.repository.leave_lock_in_place()
581
        branch.unlock()
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
582
        response = request.execute('',
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
583
                                   branch_token, repo_token)
584
        self.assertEqual(
585
            SmartServerResponse(('ok',)), response)
586
        # The branch is now unlocked.  Verify that with a new branch
587
        # object.
588
        new_branch = branch.bzrdir.open_branch()
589
        new_branch.lock_write()
590
        new_branch.unlock()
591
592
    def test_unlock_on_unlocked_branch_unlocked_repo(self):
593
        backing = self.get_transport()
594
        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.
595
        branch = self.make_branch('.', format='knit')
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
596
        response = request.execute(
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
597
            '', 'branch token', 'repo token')
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
598
        self.assertEqual(
599
            SmartServerResponse(('TokenMismatch',)), response)
600
601
    def test_unlock_on_unlocked_branch_locked_repo(self):
602
        backing = self.get_transport()
603
        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.
604
        branch = self.make_branch('.', format='knit')
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
605
        # Lock the repository.
606
        repo_token = branch.repository.lock_write()
607
        branch.repository.leave_lock_in_place()
608
        branch.repository.unlock()
609
        # Issue branch lock_write request on the unlocked branch (with locked
610
        # repo).
611
        response = request.execute(
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
612
            '', 'branch token', repo_token)
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
613
        self.assertEqual(
614
            SmartServerResponse(('TokenMismatch',)), response)
615
616
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
617
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).
618
619
    def test_no_repository(self):
620
        """Raise NoRepositoryPresent when there is a bzrdir and no repo."""
621
        # we test this using a shared repository above the named path,
622
        # thus checking the right search logic is used - that is, that
623
        # its the exact path being looked at and the server is not
624
        # searching.
625
        backing = self.get_transport()
2018.5.58 by Wouter van Heyst
Small test fixes to reflect naming and documentation
626
        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).
627
        self.make_repository('.', shared=True)
628
        self.make_bzrdir('subdir')
629
        self.assertRaises(errors.NoRepositoryPresent,
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
630
            request.execute, 'subdir')
631
632
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.
633
class TestSmartServerRepositoryGetParentMap(tests.TestCaseWithTransport):
634
3211.5.3 by Robert Collins
Adjust size of batch and change gzip comments to bzip2.
635
    def test_trivial_bzipped(self):
636
        # 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.
637
        backing = self.get_transport()
638
        request = smart.repository.SmartServerRepositoryGetParentMap(backing)
639
        tree = self.make_branch_and_memory_tree('.')
640
641
        self.assertEqual(None,
2692.1.24 by Andrew Bennetts
Merge from bzr.dev.
642
            request.execute('', 'missing-id'))
3211.5.3 by Robert Collins
Adjust size of batch and change gzip comments to bzip2.
643
        # Note that it returns a body (of '' bzipped).
3211.5.1 by Robert Collins
Change the smart server get_parents method to take a graph search to exclude already recieved parents from. This prevents history shortcuts causing huge numbers of duplicates.
644
        self.assertEqual(
3211.5.2 by Robert Collins
Change RemoteRepository.get_parent_map to use bz2 not gzip for compression.
645
            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.
646
            request.do_body('\n\n0\n'))
647
648
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
649
class TestSmartServerRepositoryGetRevisionGraph(tests.TestCaseWithMemoryTransport):
2018.5.67 by Wouter van Heyst
Implement RemoteRepository.get_revision_graph (Wouter van Heyst, Robert Collins)
650
651
    def test_none_argument(self):
652
        backing = self.get_transport()
653
        request = smart.repository.SmartServerRepositoryGetRevisionGraph(backing)
654
        tree = self.make_branch_and_memory_tree('.')
655
        tree.lock_write()
656
        tree.add('')
657
        r1 = tree.commit('1st commit')
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
658
        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)
659
        tree.unlock()
660
661
        # the lines of revision_id->revision_parent_list has no guaranteed
662
        # order coming out of a dict, so sort both our test and response
663
        lines = sorted([' '.join([r2, r1]), r1])
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
664
        response = request.execute('', '')
2018.5.67 by Wouter van Heyst
Implement RemoteRepository.get_revision_graph (Wouter van Heyst, Robert Collins)
665
        response.body = '\n'.join(sorted(response.body.split('\n')))
666
2018.5.83 by Andrew Bennetts
Fix some test failures caused by the switch from unicode to UTF-8-encoded strs for revision IDs.
667
        self.assertEqual(
668
            SmartServerResponse(('ok', ), '\n'.join(lines)), response)
2018.5.67 by Wouter van Heyst
Implement RemoteRepository.get_revision_graph (Wouter van Heyst, Robert Collins)
669
670
    def test_specific_revision_argument(self):
671
        backing = self.get_transport()
672
        request = smart.repository.SmartServerRepositoryGetRevisionGraph(backing)
673
        tree = self.make_branch_and_memory_tree('.')
674
        tree.lock_write()
675
        tree.add('')
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
676
        rev_id_utf8 = u'\xc9'.encode('utf-8')
677
        r1 = tree.commit('1st commit', rev_id=rev_id_utf8)
678
        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)
679
        tree.unlock()
680
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
681
        self.assertEqual(SmartServerResponse(('ok', ), rev_id_utf8),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
682
            request.execute('', rev_id_utf8))
2018.5.67 by Wouter van Heyst
Implement RemoteRepository.get_revision_graph (Wouter van Heyst, Robert Collins)
683
    
684
    def test_no_such_revision(self):
685
        backing = self.get_transport()
686
        request = smart.repository.SmartServerRepositoryGetRevisionGraph(backing)
687
        tree = self.make_branch_and_memory_tree('.')
688
        tree.lock_write()
689
        tree.add('')
690
        r1 = tree.commit('1st commit')
691
        tree.unlock()
692
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
693
        # Note that it still returns body (of zero bytes).
694
        self.assertEqual(
695
            SmartServerResponse(('nosuchrevision', 'missingrevision', ), ''),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
696
            request.execute('', 'missingrevision'))
697
698
699
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).
700
701
    def test_missing_revision(self):
702
        """For a missing revision, ('no', ) is returned."""
703
        backing = self.get_transport()
704
        request = smart.repository.SmartServerRequestHasRevision(backing)
705
        self.make_repository('.')
706
        self.assertEqual(SmartServerResponse(('no', )),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
707
            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).
708
709
    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.
710
        """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).
711
        backing = self.get_transport()
712
        request = smart.repository.SmartServerRequestHasRevision(backing)
713
        tree = self.make_branch_and_memory_tree('.')
714
        tree.lock_write()
715
        tree.add('')
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
716
        rev_id_utf8 = u'\xc8abc'.encode('utf-8')
717
        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).
718
        tree.unlock()
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
719
        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.
720
        self.assertEqual(SmartServerResponse(('yes', )),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
721
            request.execute('', rev_id_utf8))
722
723
724
class TestSmartServerRepositoryGatherStats(tests.TestCaseWithMemoryTransport):
2018.10.2 by v.ladeuil+lp at free
gather_stats server side and request registration
725
726
    def test_empty_revid(self):
727
        """With an empty revid, we get only size an number and revisions"""
728
        backing = self.get_transport()
729
        request = smart.repository.SmartServerRepositoryGatherStats(backing)
730
        repository = self.make_repository('.')
731
        stats = repository.gather_stats()
732
        size = stats['size']
733
        expected_body = 'revisions: 0\nsize: %d\n' % size
734
        self.assertEqual(SmartServerResponse(('ok', ), expected_body),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
735
                         request.execute('', '', 'no'))
2018.10.2 by v.ladeuil+lp at free
gather_stats server side and request registration
736
737
    def test_revid_with_committers(self):
738
        """For a revid we get more infos."""
739
        backing = self.get_transport()
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
740
        rev_id_utf8 = u'\xc8abc'.encode('utf-8')
2018.10.2 by v.ladeuil+lp at free
gather_stats server side and request registration
741
        request = smart.repository.SmartServerRepositoryGatherStats(backing)
742
        tree = self.make_branch_and_memory_tree('.')
743
        tree.lock_write()
744
        tree.add('')
745
        # Let's build a predictable result
746
        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.
747
        tree.commit('a commit', timestamp=654321.4, timezone=0,
748
                    rev_id=rev_id_utf8)
2018.10.2 by v.ladeuil+lp at free
gather_stats server side and request registration
749
        tree.unlock()
750
751
        stats = tree.branch.repository.gather_stats()
752
        size = stats['size']
753
        expected_body = ('firstrev: 123456.200 3600\n'
754
                         'latestrev: 654321.400 0\n'
755
                         'revisions: 2\n'
756
                         'size: %d\n' % size)
757
        self.assertEqual(SmartServerResponse(('ok', ), expected_body),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
758
                         request.execute('',
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
759
                                         rev_id_utf8, 'no'))
2018.10.2 by v.ladeuil+lp at free
gather_stats server side and request registration
760
761
    def test_not_empty_repository_with_committers(self):
762
        """For a revid and requesting committers we get the whole thing."""
763
        backing = self.get_transport()
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
764
        rev_id_utf8 = u'\xc8abc'.encode('utf-8')
2018.10.2 by v.ladeuil+lp at free
gather_stats server side and request registration
765
        request = smart.repository.SmartServerRepositoryGatherStats(backing)
766
        tree = self.make_branch_and_memory_tree('.')
767
        tree.lock_write()
768
        tree.add('')
769
        # Let's build a predictable result
770
        tree.commit('a commit', timestamp=123456.2, timezone=3600,
771
                    committer='foo')
772
        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.
773
                    committer='bar', rev_id=rev_id_utf8)
2018.10.2 by v.ladeuil+lp at free
gather_stats server side and request registration
774
        tree.unlock()
775
        stats = tree.branch.repository.gather_stats()
776
777
        size = stats['size']
778
        expected_body = ('committers: 2\n'
779
                         'firstrev: 123456.200 3600\n'
780
                         'latestrev: 654321.400 0\n'
781
                         'revisions: 2\n'
782
                         'size: %d\n' % size)
783
        self.assertEqual(SmartServerResponse(('ok', ), expected_body),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
784
                         request.execute('',
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
785
                                         rev_id_utf8, 'yes'))
2018.10.2 by v.ladeuil+lp at free
gather_stats server side and request registration
786
787
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
788
class TestSmartServerRepositoryIsShared(tests.TestCaseWithMemoryTransport):
2018.5.57 by Robert Collins
Implement RemoteRepository.is_shared (Robert Collins, Vincent Ladeuil).
789
790
    def test_is_shared(self):
791
        """For a shared repository, ('yes', ) is returned."""
792
        backing = self.get_transport()
793
        request = smart.repository.SmartServerRepositoryIsShared(backing)
794
        self.make_repository('.', shared=True)
795
        self.assertEqual(SmartServerResponse(('yes', )),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
796
            request.execute('', ))
2018.5.57 by Robert Collins
Implement RemoteRepository.is_shared (Robert Collins, Vincent Ladeuil).
797
798
    def test_is_not_shared(self):
2018.5.58 by Wouter van Heyst
Small test fixes to reflect naming and documentation
799
        """For a shared repository, ('no', ) is returned."""
2018.5.57 by Robert Collins
Implement RemoteRepository.is_shared (Robert Collins, Vincent Ladeuil).
800
        backing = self.get_transport()
801
        request = smart.repository.SmartServerRepositoryIsShared(backing)
802
        self.make_repository('.', shared=False)
803
        self.assertEqual(SmartServerResponse(('no', )),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
804
            request.execute('', ))
805
806
807
class TestSmartServerRepositoryLockWrite(tests.TestCaseWithMemoryTransport):
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
808
809
    def setUp(self):
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
810
        tests.TestCaseWithMemoryTransport.setUp(self)
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
811
812
    def test_lock_write_on_unlocked_repo(self):
813
        backing = self.get_transport()
814
        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.
815
        repository = self.make_repository('.', format='knit')
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
816
        response = request.execute('')
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
817
        nonce = repository.control_files._lock.peek().get('nonce')
818
        self.assertEqual(SmartServerResponse(('ok', nonce)), response)
819
        # The repository is now locked.  Verify that with a new repository
820
        # object.
821
        new_repo = repository.bzrdir.open_repository()
822
        self.assertRaises(errors.LockContention, new_repo.lock_write)
823
824
    def test_lock_write_on_locked_repo(self):
825
        backing = self.get_transport()
826
        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.
827
        repository = self.make_repository('.', format='knit')
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
828
        repository.lock_write()
829
        repository.leave_lock_in_place()
830
        repository.unlock()
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
831
        response = request.execute('')
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
832
        self.assertEqual(
833
            SmartServerResponse(('LockContention',)), response)
834
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.
835
    def test_lock_write_on_readonly_transport(self):
836
        backing = self.get_readonly_transport()
837
        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.
838
        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.
839
        response = request.execute('')
2872.5.3 by Martin Pool
Pass back LockFailed from smart server lock methods
840
        self.assertFalse(response.is_successful())
841
        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.
842
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
843
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
844
class TestSmartServerRepositoryUnlock(tests.TestCaseWithMemoryTransport):
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
845
846
    def setUp(self):
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
847
        tests.TestCaseWithMemoryTransport.setUp(self)
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
848
849
    def test_unlock_on_locked_repo(self):
850
        backing = self.get_transport()
851
        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.
852
        repository = self.make_repository('.', format='knit')
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
853
        token = repository.lock_write()
854
        repository.leave_lock_in_place()
855
        repository.unlock()
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
856
        response = request.execute('', token)
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
857
        self.assertEqual(
858
            SmartServerResponse(('ok',)), response)
859
        # The repository is now unlocked.  Verify that with a new repository
860
        # object.
861
        new_repo = repository.bzrdir.open_repository()
862
        new_repo.lock_write()
863
        new_repo.unlock()
864
865
    def test_unlock_on_unlocked_repo(self):
866
        backing = self.get_transport()
867
        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.
868
        repository = self.make_repository('.', format='knit')
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
869
        response = request.execute('', 'some token')
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
870
        self.assertEqual(
871
            SmartServerResponse(('TokenMismatch',)), response)
872
873
2018.18.1 by Martin Pool
Add stub Repository.tarball smart method
874
class TestSmartServerRepositoryTarball(tests.TestCaseWithTransport):
875
876
    def test_repository_tarball(self):
877
        backing = self.get_transport()
878
        request = smart.repository.SmartServerRepositoryTarball(backing)
879
        repository = self.make_repository('.')
2018.18.9 by Martin Pool
remote Repository.tarball builds a temporary directory and tars that
880
        # make some extraneous junk in the repository directory which should
881
        # not be copied
882
        self.build_tree(['.bzr/repository/extra-junk'])
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
883
        response = request.execute('', 'bz2')
2018.18.1 by Martin Pool
Add stub Repository.tarball smart method
884
        self.assertEqual(('ok',), response.args)
885
        # body should be a tbz2
2018.18.2 by Martin Pool
smart method Repository.tarball actually returns the tarball
886
        body_file = StringIO(response.body)
887
        body_tar = tarfile.open('body_tar.tbz2', fileobj=body_file,
2018.18.25 by Martin Pool
Repository.tarball fixes for python2.4
888
            mode='r|bz2')
2018.18.2 by Martin Pool
smart method Repository.tarball actually returns the tarball
889
        # let's make sure there are some key repository components inside it.
890
        # the tarfile returns directories with trailing slashes...
891
        names = set([n.rstrip('/') for n in body_tar.getnames()])
2018.18.11 by Martin Pool
merge hpss changes
892
        self.assertTrue('.bzr/repository/lock' in names)
893
        self.assertTrue('.bzr/repository/format' in names)
894
        self.assertTrue('.bzr/repository/extra-junk' not in names,
2018.18.9 by Martin Pool
remote Repository.tarball builds a temporary directory and tars that
895
            "extraneous file present in tar file")
2018.18.1 by Martin Pool
Add stub Repository.tarball smart method
896
897
2692.1.2 by Andrew Bennetts
Merge from bzr.dev.
898
class TestSmartServerRepositoryStreamKnitData(tests.TestCaseWithMemoryTransport):
2535.3.14 by Andrew Bennetts
Move serialising repo data stream to bytes into smart protocol.
899
900
    def test_fetch_revisions(self):
901
        backing = self.get_transport()
2535.3.49 by Andrew Bennetts
Rename 'Repository.fetch_revisions' smart request to 'Repository.stream_knit_data_for_revisions'.
902
        request = smart.repository.SmartServerRepositoryStreamKnitDataForRevisions(backing)
2535.3.14 by Andrew Bennetts
Move serialising repo data stream to bytes into smart protocol.
903
        tree = self.make_branch_and_memory_tree('.')
904
        tree.lock_write()
905
        tree.add('')
906
        rev_id1_utf8 = u'\xc8'.encode('utf-8')
907
        rev_id2_utf8 = u'\xc9'.encode('utf-8')
908
        r1 = tree.commit('1st commit', rev_id=rev_id1_utf8)
909
        r1 = tree.commit('2nd commit', rev_id=rev_id2_utf8)
910
        tree.unlock()
911
2692.1.2 by Andrew Bennetts
Merge from bzr.dev.
912
        response = request.execute('', rev_id2_utf8)
2535.3.14 by Andrew Bennetts
Move serialising repo data stream to bytes into smart protocol.
913
        self.assertEqual(('ok',), response.args)
2535.4.29 by Andrew Bennetts
Add a new smart method, Repository.stream_revisions_chunked, rather than changing the behaviour of an existing method.
914
        unpacker = pack.ContainerReader(StringIO(response.body))
915
        names = []
916
        for [name], read_bytes in unpacker.iter_records():
917
            names.append(name)
918
            bytes = read_bytes(None)
919
            # The bytes should be a valid bencoded string.
920
            bencode.bdecode(bytes)
921
            # XXX: assert that the bencoded knit records have the right
922
            # contents?
923
        
924
    def test_no_such_revision_error(self):
925
        backing = self.get_transport()
926
        request = smart.repository.SmartServerRepositoryStreamKnitDataForRevisions(backing)
927
        repo = self.make_repository('.')
928
        rev_id1_utf8 = u'\xc8'.encode('utf-8')
2692.1.2 by Andrew Bennetts
Merge from bzr.dev.
929
        response = request.execute('', rev_id1_utf8)
2535.4.29 by Andrew Bennetts
Add a new smart method, Repository.stream_revisions_chunked, rather than changing the behaviour of an existing method.
930
        self.assertEqual(
931
            SmartServerResponse(('NoSuchRevision', rev_id1_utf8)),
932
            response)
933
934
2692.1.18 by Andrew Bennetts
Merge from bzr.dev.
935
class TestSmartServerRepositoryStreamRevisionsChunked(tests.TestCaseWithMemoryTransport):
2535.4.29 by Andrew Bennetts
Add a new smart method, Repository.stream_revisions_chunked, rather than changing the behaviour of an existing method.
936
937
    def test_fetch_revisions(self):
938
        backing = self.get_transport()
939
        request = smart.repository.SmartServerRepositoryStreamRevisionsChunked(
940
            backing)
941
        tree = self.make_branch_and_memory_tree('.')
942
        tree.lock_write()
943
        tree.add('')
944
        rev_id1_utf8 = u'\xc8'.encode('utf-8')
945
        rev_id2_utf8 = u'\xc9'.encode('utf-8')
3184.1.10 by Robert Collins
Change the smart server verb for Repository.stream_revisions_chunked to use SearchResults as the request mechanism for downloads.
946
        tree.commit('1st commit', rev_id=rev_id1_utf8)
947
        tree.commit('2nd commit', rev_id=rev_id2_utf8)
2535.4.29 by Andrew Bennetts
Add a new smart method, Repository.stream_revisions_chunked, rather than changing the behaviour of an existing method.
948
        tree.unlock()
949
2692.1.24 by Andrew Bennetts
Merge from bzr.dev.
950
        response = request.execute('')
3184.1.10 by Robert Collins
Change the smart server verb for Repository.stream_revisions_chunked to use SearchResults as the request mechanism for downloads.
951
        self.assertEqual(None, response)
952
        response = request.do_body("%s\n%s\n1" % (rev_id2_utf8, rev_id1_utf8))
2535.4.29 by Andrew Bennetts
Add a new smart method, Repository.stream_revisions_chunked, rather than changing the behaviour of an existing method.
953
        self.assertEqual(('ok',), response.args)
2535.4.22 by Andrew Bennetts
Merge from streamable-containers.
954
        parser = pack.ContainerPushParser()
2535.3.14 by Andrew Bennetts
Move serialising repo data stream to bytes into smart protocol.
955
        names = []
2535.4.22 by Andrew Bennetts
Merge from streamable-containers.
956
        for stream_bytes in response.body_stream:
957
            parser.accept_bytes(stream_bytes)
958
            for [name], record_bytes in parser.read_pending_records():
959
                names.append(name)
960
                # The bytes should be a valid bencoded string.
961
                bencode.bdecode(record_bytes)
962
                # XXX: assert that the bencoded knit records have the right
963
                # contents?
2535.3.14 by Andrew Bennetts
Move serialising repo data stream to bytes into smart protocol.
964
        
2535.3.40 by Andrew Bennetts
Tidy up more XXXs.
965
    def test_no_such_revision_error(self):
966
        backing = self.get_transport()
2535.4.29 by Andrew Bennetts
Add a new smart method, Repository.stream_revisions_chunked, rather than changing the behaviour of an existing method.
967
        request = smart.repository.SmartServerRepositoryStreamRevisionsChunked(
968
            backing)
2535.3.40 by Andrew Bennetts
Tidy up more XXXs.
969
        repo = self.make_repository('.')
970
        rev_id1_utf8 = u'\xc8'.encode('utf-8')
2692.1.24 by Andrew Bennetts
Merge from bzr.dev.
971
        response = request.execute('')
3184.1.10 by Robert Collins
Change the smart server verb for Repository.stream_revisions_chunked to use SearchResults as the request mechanism for downloads.
972
        self.assertEqual(None, response)
973
        response = request.do_body("%s\n\n1" % (rev_id1_utf8,))
974
        self.assertEqual(
975
            FailedSmartServerResponse(('NoSuchRevision', )),
976
            response)
977
2535.3.12 by Andrew Bennetts
Add a first cut of a get_data_stream method to Repository.
978
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
979
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.
980
981
    def test_is_readonly_no(self):
982
        backing = self.get_transport()
983
        request = smart.request.SmartServerIsReadonly(backing)
984
        response = request.execute()
985
        self.assertEqual(
986
            SmartServerResponse(('no',)), response)
987
988
    def test_is_readonly_yes(self):
989
        backing = self.get_readonly_transport()
990
        request = smart.request.SmartServerIsReadonly(backing)
991
        response = request.execute()
992
        self.assertEqual(
993
            SmartServerResponse(('yes',)), response)
994
995
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
996
class TestHandlers(tests.TestCase):
997
    """Tests for the request.request_handlers object."""
998
999
    def test_registered_methods(self):
1000
        """Test that known methods are registered to the correct object."""
1001
        self.assertEqual(
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
1002
            smart.request.request_handlers.get('Branch.get_config_file'),
1003
            smart.branch.SmartServerBranchGetConfigFile)
1004
        self.assertEqual(
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1005
            smart.request.request_handlers.get('Branch.lock_write'),
1006
            smart.branch.SmartServerBranchRequestLockWrite)
1007
        self.assertEqual(
2018.5.51 by Wouter van Heyst
Test and implement RemoteBranch.last_revision_info()
1008
            smart.request.request_handlers.get('Branch.last_revision_info'),
1009
            smart.branch.SmartServerBranchRequestLastRevisionInfo)
1010
        self.assertEqual(
2018.5.38 by Robert Collins
Implement RemoteBranch.revision_history().
1011
            smart.request.request_handlers.get('Branch.revision_history'),
1012
            smart.branch.SmartServerRequestRevisionHistory)
1013
        self.assertEqual(
2018.5.77 by Wouter van Heyst
Fix typo in request_handlers registration of Branch.set_last_revision, and test that registration
1014
            smart.request.request_handlers.get('Branch.set_last_revision'),
1015
            smart.branch.SmartServerBranchRequestSetLastRevision)
1016
        self.assertEqual(
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1017
            smart.request.request_handlers.get('Branch.unlock'),
1018
            smart.branch.SmartServerBranchRequestUnlock)
1019
        self.assertEqual(
2018.5.34 by Robert Collins
Get test_remote.BasicRemoteObjectTests.test_open_remote_branch passing by implementing a remote method BzrDir.find_repository.
1020
            smart.request.request_handlers.get('BzrDir.find_repository'),
3221.3.2 by Robert Collins
* New remote method ``RemoteBzrDir.find_repositoryV2`` adding support for
1021
            smart.bzrdir.SmartServerRequestFindRepositoryV1)
1022
        self.assertEqual(
1023
            smart.request.request_handlers.get('BzrDir.find_repositoryV2'),
1024
            smart.bzrdir.SmartServerRequestFindRepositoryV2)
2018.5.34 by Robert Collins
Get test_remote.BasicRemoteObjectTests.test_open_remote_branch passing by implementing a remote method BzrDir.find_repository.
1025
        self.assertEqual(
2018.5.42 by Robert Collins
Various hopefully improvements, but wsgi is broken, handing over to spiv :).
1026
            smart.request.request_handlers.get('BzrDirFormat.initialize'),
1027
            smart.bzrdir.SmartServerRequestInitializeBzrDir)
1028
        self.assertEqual(
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
1029
            smart.request.request_handlers.get('BzrDir.open_branch'),
1030
            smart.bzrdir.SmartServerRequestOpenBranch)
2018.5.40 by Robert Collins
Implement a remote Repository.has_revision method.
1031
        self.assertEqual(
2018.10.2 by v.ladeuil+lp at free
gather_stats server side and request registration
1032
            smart.request.request_handlers.get('Repository.gather_stats'),
1033
            smart.repository.SmartServerRepositoryGatherStats)
1034
        self.assertEqual(
3172.5.6 by Robert Collins
Create new smart server verb Repository.get_parent_map.
1035
            smart.request.request_handlers.get('Repository.get_parent_map'),
1036
            smart.repository.SmartServerRepositoryGetParentMap)
1037
        self.assertEqual(
2535.3.69 by Andrew Bennetts
Add check for Repository.stream_knit_data_for_revisions to TestHandlers.test_registered_methods.
1038
            smart.request.request_handlers.get(
1039
                'Repository.get_revision_graph'),
2018.5.67 by Wouter van Heyst
Implement RemoteRepository.get_revision_graph (Wouter van Heyst, Robert Collins)
1040
            smart.repository.SmartServerRepositoryGetRevisionGraph)
1041
        self.assertEqual(
2018.5.40 by Robert Collins
Implement a remote Repository.has_revision method.
1042
            smart.request.request_handlers.get('Repository.has_revision'),
1043
            smart.repository.SmartServerRequestHasRevision)
2018.5.57 by Robert Collins
Implement RemoteRepository.is_shared (Robert Collins, Vincent Ladeuil).
1044
        self.assertEqual(
1045
            smart.request.request_handlers.get('Repository.is_shared'),
1046
            smart.repository.SmartServerRepositoryIsShared)
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
1047
        self.assertEqual(
1048
            smart.request.request_handlers.get('Repository.lock_write'),
1049
            smart.repository.SmartServerRepositoryLockWrite)
1050
        self.assertEqual(
2535.3.69 by Andrew Bennetts
Add check for Repository.stream_knit_data_for_revisions to TestHandlers.test_registered_methods.
1051
            smart.request.request_handlers.get('Repository.tarball'),
1052
            smart.repository.SmartServerRepositoryTarball)
1053
        self.assertEqual(
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
1054
            smart.request.request_handlers.get('Repository.unlock'),
1055
            smart.repository.SmartServerRepositoryUnlock)
2018.5.95 by Andrew Bennetts
Add a Transport.is_readonly remote call, let {Branch,Repository}.lock_write remote call return UnlockableTransport, and miscellaneous test fixes.
1056
        self.assertEqual(
1057
            smart.request.request_handlers.get('Transport.is_readonly'),
1058
            smart.request.SmartServerIsReadonly)