~bzr-pqm/bzr/bzr.dev

6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
1
# Copyright (C) 2006-2012, 2016 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
6280.9.4 by Jelmer Vernooij
use zlib instead.
28
import zlib
2018.18.2 by Martin Pool
smart method Repository.tarball actually returns the tarball
29
2692.1.2 by Andrew Bennetts
Merge from bzr.dev.
30
from bzrlib import (
6436.3.2 by Jelmer Vernooij
Add HPSS call for BzrDir.get_branches.
31
    bencode,
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
32
    branch as _mod_branch,
6472.2.1 by Jelmer Vernooij
Use bzrdir.controldir for generic access to control directories.
33
    controldir,
2692.1.2 by Andrew Bennetts
Merge from bzr.dev.
34
    errors,
6263.3.2 by Jelmer Vernooij
Add new HPSS call 'Repository.get_revision_signature_text'.
35
    gpg,
6282.6.7 by Jelmer Vernooij
Add basic server side test.
36
    inventory_delta,
2692.1.2 by Andrew Bennetts
Merge from bzr.dev.
37
    tests,
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
38
    transport,
2692.1.2 by Andrew Bennetts
Merge from bzr.dev.
39
    urlutils,
4634.19.1 by Robert Collins
Combine adjacent substreams of the same type in bzrlib.smart.repository._byte_stream_to_stream.
40
    versionedfile,
2692.1.2 by Andrew Bennetts
Merge from bzr.dev.
41
    )
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
42
from bzrlib.smart import (
43
    branch as smart_branch,
44
    bzrdir as smart_dir,
45
    repository as smart_repo,
46
    packrepository as smart_packrepo,
47
    request as smart_req,
5611.1.2 by Jelmer Vernooij
Add some tests for the hooks.
48
    server,
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
49
    vfs,
50
    )
6263.3.2 by Jelmer Vernooij
Add new HPSS call 'Repository.get_revision_signature_text'.
51
from bzrlib.testament import Testament
5017.3.25 by Vincent Ladeuil
selftest -s bt.test_smart_transport passing
52
from bzrlib.tests import test_server
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
53
from bzrlib.transport import (
54
    chroot,
5017.3.45 by Vincent Ladeuil
Move MemoryServer back into bzrlib.transport.memory as it's needed as soon as a MemoryTransport is used. Add a NEWS entry.
55
    memory,
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
56
    )
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
57
58
3221.3.2 by Robert Collins
* New remote method ``RemoteBzrDir.find_repositoryV2`` adding support for
59
def load_tests(standard_tests, module, loader):
60
    """Multiply tests version and protocol consistency."""
61
    # FindRepository tests.
4084.5.1 by Robert Collins
Bulk update all test adaptation into a single approach, using multiply_tests rather than test adapters.
62
    scenarios = [
3221.3.2 by Robert Collins
* New remote method ``RemoteBzrDir.find_repositoryV2`` adding support for
63
        ("find_repository", {
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
64
            "_request_class": smart_dir.SmartServerRequestFindRepositoryV1}),
3221.3.2 by Robert Collins
* New remote method ``RemoteBzrDir.find_repositoryV2`` adding support for
65
        ("find_repositoryV2", {
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
66
            "_request_class": smart_dir.SmartServerRequestFindRepositoryV2}),
4053.1.4 by Robert Collins
Move the fetch control attributes from Repository to RepositoryFormat.
67
        ("find_repositoryV3", {
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
68
            "_request_class": smart_dir.SmartServerRequestFindRepositoryV3}),
3221.3.2 by Robert Collins
* New remote method ``RemoteBzrDir.find_repositoryV2`` adding support for
69
        ]
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
70
    to_adapt, result = tests.split_suite_by_re(standard_tests,
3221.3.2 by Robert Collins
* New remote method ``RemoteBzrDir.find_repositoryV2`` adding support for
71
        "TestSmartServerRequestFindRepository")
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
72
    v2_only, v1_and_2 = tests.split_suite_by_re(to_adapt,
3221.3.2 by Robert Collins
* New remote method ``RemoteBzrDir.find_repositoryV2`` adding support for
73
        "_v2")
4084.5.1 by Robert Collins
Bulk update all test adaptation into a single approach, using multiply_tests rather than test adapters.
74
    tests.multiply_tests(v1_and_2, scenarios, result)
75
    # The first scenario is only applicable to v1 protocols, it is deleted
76
    # since.
77
    tests.multiply_tests(v2_only, scenarios[1:], result)
3221.3.2 by Robert Collins
* New remote method ``RemoteBzrDir.find_repositoryV2`` adding support for
78
    return result
79
80
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
81
class TestCaseWithChrootedTransport(tests.TestCaseWithTransport):
82
83
    def setUp(self):
5017.3.45 by Vincent Ladeuil
Move MemoryServer back into bzrlib.transport.memory as it's needed as soon as a MemoryTransport is used. Add a NEWS entry.
84
        self.vfs_transport_factory = memory.MemoryServer
6552.1.4 by Vincent Ladeuil
Remaining tests matching setup(self) that can be rewritten with super().
85
        super(TestCaseWithChrootedTransport, self).setUp()
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
86
        self._chroot_server = None
87
88
    def get_transport(self, relpath=None):
89
        if self._chroot_server is None:
90
            backing_transport = tests.TestCaseWithTransport.get_transport(self)
91
            self._chroot_server = chroot.ChrootServer(backing_transport)
4659.1.2 by Robert Collins
Refactor creation and shutdown of test servers to use a common helper,
92
            self.start_server(self._chroot_server)
6083.1.1 by Jelmer Vernooij
Use get_transport_from_{url,path} in more places.
93
        t = transport.get_transport_from_url(self._chroot_server.get_url())
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
94
        if relpath is not None:
95
            t = t.clone(relpath)
96
        return t
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
97
98
4634.47.4 by Andrew Bennetts
Make more of bzrlib/tests/test_smart.py use MemoryTransport.
99
class TestCaseWithSmartMedium(tests.TestCaseWithMemoryTransport):
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
100
101
    def setUp(self):
102
        super(TestCaseWithSmartMedium, self).setUp()
103
        # We're allowed to set  the transport class here, so that we don't use
104
        # the default or a parameterized class, but rather use the
105
        # TestCaseWithTransport infrastructure to set up a smart server and
106
        # transport.
5340.15.1 by John Arbash Meinel
supersede exc-info branch
107
        self.overrideAttr(self, "transport_server", self.make_transport_server)
3245.4.28 by Andrew Bennetts
Remove another XXX, and include test ID in smart server thread names.
108
109
    def make_transport_server(self):
5017.3.25 by Vincent Ladeuil
selftest -s bt.test_smart_transport passing
110
        return test_server.SmartTCPServer_for_testing('-' + self.id())
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
111
112
    def get_smart_medium(self):
113
        """Get a smart medium to use in tests."""
114
        return self.get_transport().get_smart_medium()
115
116
4634.19.1 by Robert Collins
Combine adjacent substreams of the same type in bzrlib.smart.repository._byte_stream_to_stream.
117
class TestByteStreamToStream(tests.TestCase):
118
119
    def test_repeated_substreams_same_kind_are_one_stream(self):
120
        # Make a stream - an iterable of bytestrings.
121
        stream = [('text', [versionedfile.FulltextContentFactory(('k1',), None,
122
            None, 'foo')]),('text', [
123
            versionedfile.FulltextContentFactory(('k2',), None, None, 'bar')])]
6472.2.1 by Jelmer Vernooij
Use bzrdir.controldir for generic access to control directories.
124
        fmt = controldir.format_registry.get('pack-0.92')().repository_format
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
125
        bytes = smart_repo._stream_to_byte_stream(stream, fmt)
4634.19.1 by Robert Collins
Combine adjacent substreams of the same type in bzrlib.smart.repository._byte_stream_to_stream.
126
        streams = []
127
        # Iterate the resulting iterable; checking that we get only one stream
128
        # out.
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
129
        fmt, stream = smart_repo._byte_stream_to_stream(bytes)
4634.19.1 by Robert Collins
Combine adjacent substreams of the same type in bzrlib.smart.repository._byte_stream_to_stream.
130
        for kind, substream in stream:
131
            streams.append((kind, list(substream)))
132
        self.assertLength(1, streams)
133
        self.assertLength(2, streams[0][1])
134
135
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
136
class TestSmartServerResponse(tests.TestCase):
137
138
    def test__eq__(self):
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
139
        self.assertEqual(smart_req.SmartServerResponse(('ok', )),
140
            smart_req.SmartServerResponse(('ok', )))
141
        self.assertEqual(smart_req.SmartServerResponse(('ok', ), 'body'),
142
            smart_req.SmartServerResponse(('ok', ), 'body'))
143
        self.assertNotEqual(smart_req.SmartServerResponse(('ok', )),
144
            smart_req.SmartServerResponse(('notok', )))
145
        self.assertNotEqual(smart_req.SmartServerResponse(('ok', ), 'body'),
146
            smart_req.SmartServerResponse(('ok', )))
2018.5.41 by Robert Collins
Fix SmartServerResponse.__eq__ to handle None.
147
        self.assertNotEqual(None,
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
148
            smart_req.SmartServerResponse(('ok', )))
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
149
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
150
    def test__str__(self):
151
        """SmartServerResponses can be stringified."""
152
        self.assertEqual(
3691.2.6 by Martin Pool
Disable RemoteBranch stacking, but get get_stacked_on_url working, and passing back exceptions
153
            "<SuccessfulSmartServerResponse args=('args',) body='body'>",
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
154
            str(smart_req.SuccessfulSmartServerResponse(('args',), 'body')))
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
155
        self.assertEqual(
3691.2.6 by Martin Pool
Disable RemoteBranch stacking, but get get_stacked_on_url working, and passing back exceptions
156
            "<FailedSmartServerResponse args=('args',) body='body'>",
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
157
            str(smart_req.FailedSmartServerResponse(('args',), 'body')))
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
158
159
160
class TestSmartServerRequest(tests.TestCaseWithMemoryTransport):
161
162
    def test_translate_client_path(self):
163
        transport = self.get_transport()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
164
        request = smart_req.SmartServerRequest(transport, 'foo/')
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
165
        self.assertEqual('./', request.translate_client_path('foo/'))
166
        self.assertRaises(
167
            errors.InvalidURLJoin, request.translate_client_path, 'foo/..')
168
        self.assertRaises(
169
            errors.PathNotChild, request.translate_client_path, '/')
170
        self.assertRaises(
171
            errors.PathNotChild, request.translate_client_path, 'bar/')
172
        self.assertEqual('./baz', request.translate_client_path('foo/baz'))
4760.2.2 by Michael Hudson
test
173
        e_acute = u'\N{LATIN SMALL LETTER E WITH ACUTE}'.encode('utf-8')
174
        self.assertEqual('./' + urlutils.escape(e_acute),
175
                         request.translate_client_path('foo/' + e_acute))
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
176
4760.2.5 by Andrew Bennetts
Add some more tests.
177
    def test_translate_client_path_vfs(self):
178
        """VfsRequests receive escaped paths rather than raw UTF-8."""
179
        transport = self.get_transport()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
180
        request = vfs.VfsRequest(transport, 'foo/')
4760.2.5 by Andrew Bennetts
Add some more tests.
181
        e_acute = u'\N{LATIN SMALL LETTER E WITH ACUTE}'.encode('utf-8')
182
        escaped = urlutils.escape('foo/' + e_acute)
183
        self.assertEqual('./' + urlutils.escape(e_acute),
184
                         request.translate_client_path(escaped))
185
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
186
    def test_transport_from_client_path(self):
187
        transport = self.get_transport()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
188
        request = smart_req.SmartServerRequest(transport, 'foo/')
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
189
        self.assertEqual(
190
            transport.base,
191
            request.transport_from_client_path('foo/').base)
192
193
4070.2.3 by Robert Collins
Get BzrDir.cloning_metadir working.
194
class TestSmartServerBzrDirRequestCloningMetaDir(
195
    tests.TestCaseWithMemoryTransport):
196
    """Tests for BzrDir.cloning_metadir."""
197
198
    def test_cloning_metadir(self):
199
        """When there is a bzrdir present, the call succeeds."""
200
        backing = self.get_transport()
201
        dir = self.make_bzrdir('.')
202
        local_result = dir.cloning_metadir()
203
        request_class = smart_dir.SmartServerBzrDirRequestCloningMetaDir
204
        request = request_class(backing)
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
205
        expected = smart_req.SuccessfulSmartServerResponse(
4070.2.3 by Robert Collins
Get BzrDir.cloning_metadir working.
206
            (local_result.network_name(),
207
            local_result.repository_format.network_name(),
4084.2.2 by Robert Collins
Review feedback.
208
            ('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).
209
        self.assertEqual(expected, request.execute('', 'False'))
210
211
    def test_cloning_metadir_reference(self):
4160.2.9 by Andrew Bennetts
Fix BzrDir.cloning_metadir RPC to fail on branch references, and make
212
        """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).
213
        backing = self.get_transport()
214
        referenced_branch = self.make_branch('referenced')
215
        dir = self.make_bzrdir('.')
216
        local_result = dir.cloning_metadir()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
217
        reference = _mod_branch.BranchReferenceFormat().initialize(
5051.3.10 by Jelmer Vernooij
Pass colocated branch name around in more places.
218
            dir, target_branch=referenced_branch)
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
219
        reference_url = _mod_branch.BranchReferenceFormat().get_reference(dir)
4070.7.4 by Andrew Bennetts
Deal with branch references better in BzrDir.cloning_metadir RPC (changes protocol).
220
        # The server shouldn't try to follow the branch reference, so it's fine
221
        # if the referenced branch isn't reachable.
222
        backing.rename('referenced', 'moved')
223
        request_class = smart_dir.SmartServerBzrDirRequestCloningMetaDir
224
        request = request_class(backing)
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
225
        expected = smart_req.FailedSmartServerResponse(('BranchReference',))
4070.2.3 by Robert Collins
Get BzrDir.cloning_metadir working.
226
        self.assertEqual(expected, request.execute('', 'False'))
227
228
6305.5.11 by Jelmer Vernooij
Fix smart server tests.
229
class TestSmartServerBzrDirRequestCloningMetaDir(
230
    tests.TestCaseWithMemoryTransport):
231
    """Tests for BzrDir.checkout_metadir."""
232
233
    def test_checkout_metadir(self):
234
        backing = self.get_transport()
235
        request = smart_dir.SmartServerBzrDirRequestCheckoutMetaDir(
236
            backing)
237
        branch = self.make_branch('.', format='2a')
238
        response = request.execute('')
239
        self.assertEqual(
240
            smart_req.SmartServerResponse(
241
                ('Bazaar-NG meta directory, format 1\n',
242
                 'Bazaar repository format 2a (needs bzr 1.16 or later)\n',
243
                 'Bazaar Branch Format 7 (needs bzr 1.6)\n')),
244
            response)
245
246
6266.4.1 by Jelmer Vernooij
HPSS call 'BzrDir.destroy_branch'.
247
class TestSmartServerBzrDirRequestDestroyBranch(
248
    tests.TestCaseWithMemoryTransport):
249
    """Tests for BzrDir.destroy_branch."""
250
251
    def test_destroy_branch_default(self):
252
        """The default branch can be removed."""
253
        backing = self.get_transport()
254
        dir = self.make_branch('.').bzrdir
255
        request_class = smart_dir.SmartServerBzrDirRequestDestroyBranch
256
        request = request_class(backing)
257
        expected = smart_req.SuccessfulSmartServerResponse(('ok',))
258
        self.assertEqual(expected, request.execute('', None))
259
260
    def test_destroy_branch_named(self):
261
        """A named branch can be removed."""
262
        backing = self.get_transport()
263
        dir = self.make_repository('.', format="development-colo").bzrdir
264
        dir.create_branch(name="branchname")
265
        request_class = smart_dir.SmartServerBzrDirRequestDestroyBranch
266
        request = request_class(backing)
267
        expected = smart_req.SuccessfulSmartServerResponse(('ok',))
268
        self.assertEqual(expected, request.execute('', "branchname"))
269
270
    def test_destroy_branch_missing(self):
271
        """An error is raised if the branch didn't exist."""
272
        backing = self.get_transport()
273
        dir = self.make_bzrdir('.', format="development-colo")
274
        request_class = smart_dir.SmartServerBzrDirRequestDestroyBranch
275
        request = request_class(backing)
276
        expected = smart_req.FailedSmartServerResponse(('nobranch',), None)
277
        self.assertEqual(expected, request.execute('', "branchname"))
278
279
6266.3.1 by Jelmer Vernooij
Add HPSS call for BzrDir.has_workingtree.
280
class TestSmartServerBzrDirRequestHasWorkingTree(
281
    tests.TestCaseWithTransport):
282
    """Tests for BzrDir.has_workingtree."""
283
284
    def test_has_workingtree_yes(self):
285
        """A working tree is present."""
286
        backing = self.get_transport()
287
        dir = self.make_branch_and_tree('.').bzrdir
288
        request_class = smart_dir.SmartServerBzrDirRequestHasWorkingTree
289
        request = request_class(backing)
290
        expected = smart_req.SuccessfulSmartServerResponse(('yes',))
291
        self.assertEqual(expected, request.execute(''))
292
293
    def test_has_workingtree_no(self):
294
        """A working tree is missing."""
295
        backing = self.get_transport()
296
        dir = self.make_bzrdir('.')
297
        request_class = smart_dir.SmartServerBzrDirRequestHasWorkingTree
298
        request = request_class(backing)
299
        expected = smart_req.SuccessfulSmartServerResponse(('no',))
300
        self.assertEqual(expected, request.execute(''))
301
302
6266.2.1 by Jelmer Vernooij
New HPSS call BzrDir.destroy_repository.
303
class TestSmartServerBzrDirRequestDestroyRepository(
304
    tests.TestCaseWithMemoryTransport):
305
    """Tests for BzrDir.destroy_repository."""
306
307
    def test_destroy_repository_default(self):
308
        """The repository can be removed."""
309
        backing = self.get_transport()
310
        dir = self.make_repository('.').bzrdir
6266.2.2 by Jelmer Vernooij
Fix tests.
311
        request_class = smart_dir.SmartServerBzrDirRequestDestroyRepository
6266.2.1 by Jelmer Vernooij
New HPSS call BzrDir.destroy_repository.
312
        request = request_class(backing)
313
        expected = smart_req.SuccessfulSmartServerResponse(('ok',))
314
        self.assertEqual(expected, request.execute(''))
315
316
    def test_destroy_repository_missing(self):
317
        """An error is raised if the repository didn't exist."""
318
        backing = self.get_transport()
319
        dir = self.make_bzrdir('.')
6266.2.2 by Jelmer Vernooij
Fix tests.
320
        request_class = smart_dir.SmartServerBzrDirRequestDestroyRepository
6266.2.1 by Jelmer Vernooij
New HPSS call BzrDir.destroy_repository.
321
        request = request_class(backing)
6266.2.2 by Jelmer Vernooij
Fix tests.
322
        expected = smart_req.FailedSmartServerResponse(
323
            ('norepository',), None)
6266.2.1 by Jelmer Vernooij
New HPSS call BzrDir.destroy_repository.
324
        self.assertEqual(expected, request.execute(''))
325
326
4017.3.2 by Robert Collins
Reduce the number of round trips required to create a repository over the network.
327
class TestSmartServerRequestCreateRepository(tests.TestCaseWithMemoryTransport):
328
    """Tests for BzrDir.create_repository."""
329
330
    def test_makes_repository(self):
331
        """When there is a bzrdir present, the call succeeds."""
332
        backing = self.get_transport()
333
        self.make_bzrdir('.')
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
334
        request_class = smart_dir.SmartServerRequestCreateRepository
4017.3.2 by Robert Collins
Reduce the number of round trips required to create a repository over the network.
335
        request = request_class(backing)
6472.2.1 by Jelmer Vernooij
Use bzrdir.controldir for generic access to control directories.
336
        reference_bzrdir_format = controldir.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.
337
        reference_format = reference_bzrdir_format.repository_format
338
        network_name = reference_format.network_name()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
339
        expected = smart_req.SuccessfulSmartServerResponse(
4017.3.2 by Robert Collins
Reduce the number of round trips required to create a repository over the network.
340
            ('ok', 'no', 'no', 'no', network_name))
341
        self.assertEqual(expected, request.execute('', network_name, 'True'))
342
343
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
344
class TestSmartServerRequestFindRepository(tests.TestCaseWithMemoryTransport):
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
345
    """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.
346
347
    def test_no_repository(self):
348
        """When there is no repository to be found, ('norepository', ) is returned."""
349
        backing = self.get_transport()
3221.3.2 by Robert Collins
* New remote method ``RemoteBzrDir.find_repositoryV2`` adding support for
350
        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.
351
        self.make_bzrdir('.')
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
352
        self.assertEqual(smart_req.SmartServerResponse(('norepository', )),
2692.1.19 by Andrew Bennetts
Tweak for consistency suggested by John's review.
353
            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.
354
355
    def test_nonshared_repository(self):
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
356
        # nonshared repositorys only allow 'find' to return a handle when the
357
        # 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.
358
        # the repository is at.
359
        backing = self.get_transport()
3221.3.2 by Robert Collins
* New remote method ``RemoteBzrDir.find_repositoryV2`` adding support for
360
        request = self._request_class(backing)
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
361
        result = self._make_repository_and_result()
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
362
        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.
363
        self.make_bzrdir('subdir')
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
364
        self.assertEqual(smart_req.SmartServerResponse(('norepository', )),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
365
            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.
366
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
367
    def _make_repository_and_result(self, shared=False, format=None):
368
        """Convenience function to setup a repository.
369
370
        :result: The SmartServerResponse to expect when opening it.
371
        """
372
        repo = self.make_repository('.', shared=shared, format=format)
373
        if repo.supports_rich_root():
2018.5.166 by Andrew Bennetts
Small changes in response to Aaron's review.
374
            rich_root = 'yes'
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
375
        else:
2018.5.166 by Andrew Bennetts
Small changes in response to Aaron's review.
376
            rich_root = 'no'
2018.5.138 by Robert Collins
Merge bzr.dev.
377
        if repo._format.supports_tree_reference:
2018.5.166 by Andrew Bennetts
Small changes in response to Aaron's review.
378
            subtrees = 'yes'
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
379
        else:
2018.5.166 by Andrew Bennetts
Small changes in response to Aaron's review.
380
            subtrees = 'no'
4606.3.1 by Robert Collins
Make test_smart tests more stable when the default format changes.
381
        if repo._format.supports_external_lookups:
382
            external = 'yes'
383
        else:
384
            external = 'no'
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
385
        if (smart_dir.SmartServerRequestFindRepositoryV3 ==
4053.1.4 by Robert Collins
Move the fetch control attributes from Repository to RepositoryFormat.
386
            self._request_class):
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
387
            return smart_req.SuccessfulSmartServerResponse(
4606.3.1 by Robert Collins
Make test_smart tests more stable when the default format changes.
388
                ('ok', '', rich_root, subtrees, external,
4053.1.4 by Robert Collins
Move the fetch control attributes from Repository to RepositoryFormat.
389
                 repo._format.network_name()))
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
390
        elif (smart_dir.SmartServerRequestFindRepositoryV2 ==
3221.3.2 by Robert Collins
* New remote method ``RemoteBzrDir.find_repositoryV2`` adding support for
391
            self._request_class):
392
            # All tests so far are on formats, and for non-external
393
            # repositories.
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
394
            return smart_req.SuccessfulSmartServerResponse(
4606.3.1 by Robert Collins
Make test_smart tests more stable when the default format changes.
395
                ('ok', '', rich_root, subtrees, external))
3221.3.2 by Robert Collins
* New remote method ``RemoteBzrDir.find_repositoryV2`` adding support for
396
        else:
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
397
            return smart_req.SuccessfulSmartServerResponse(
398
                ('ok', '', rich_root, subtrees))
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
399
2018.5.34 by Robert Collins
Get test_remote.BasicRemoteObjectTests.test_open_remote_branch passing by implementing a remote method BzrDir.find_repository.
400
    def test_shared_repository(self):
401
        """When there is a shared repository, we get 'ok', 'relpath-to-repo'."""
402
        backing = self.get_transport()
3221.3.2 by Robert Collins
* New remote method ``RemoteBzrDir.find_repositoryV2`` adding support for
403
        request = self._request_class(backing)
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
404
        result = self._make_repository_and_result(shared=True)
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
405
        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.
406
        self.make_bzrdir('subdir')
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
407
        result2 = smart_req.SmartServerResponse(
408
            result.args[0:1] + ('..', ) + result.args[2:])
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
409
        self.assertEqual(result2,
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
410
            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.
411
        self.make_bzrdir('subdir/deeper')
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
412
        result3 = smart_req.SmartServerResponse(
413
            result.args[0:1] + ('../..', ) + result.args[2:])
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
414
        self.assertEqual(result3,
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
415
            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.
416
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
417
    def test_rich_root_and_subtree_encoding(self):
418
        """Test for the format attributes for rich root and subtree support."""
419
        backing = self.get_transport()
3221.3.2 by Robert Collins
* New remote method ``RemoteBzrDir.find_repositoryV2`` adding support for
420
        request = self._request_class(backing)
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
421
        result = self._make_repository_and_result(
6437.14.2 by Jelmer Vernooij
Run subtree tests with development-subtree rather than deprecated dirstate-with-subtree.
422
            format='development-subtree')
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
423
        # check the test will be valid
2018.5.166 by Andrew Bennetts
Small changes in response to Aaron's review.
424
        self.assertEqual('yes', result.args[2])
425
        self.assertEqual('yes', result.args[3])
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
426
        self.assertEqual(result, request.execute(''))
427
3221.3.2 by Robert Collins
* New remote method ``RemoteBzrDir.find_repositoryV2`` adding support for
428
    def test_supports_external_lookups_no_v2(self):
429
        """Test for the supports_external_lookups attribute."""
430
        backing = self.get_transport()
431
        request = self._request_class(backing)
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
432
        result = self._make_repository_and_result(
6437.14.2 by Jelmer Vernooij
Run subtree tests with development-subtree rather than deprecated dirstate-with-subtree.
433
            format='development-subtree')
3221.3.2 by Robert Collins
* New remote method ``RemoteBzrDir.find_repositoryV2`` adding support for
434
        # check the test will be valid
6437.14.2 by Jelmer Vernooij
Run subtree tests with development-subtree rather than deprecated dirstate-with-subtree.
435
        self.assertEqual('yes', result.args[4])
2692.1.24 by Andrew Bennetts
Merge from bzr.dev.
436
        self.assertEqual(result, request.execute(''))
437
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
438
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
439
class TestSmartServerBzrDirRequestGetConfigFile(
440
    tests.TestCaseWithMemoryTransport):
441
    """Tests for BzrDir.get_config_file."""
442
443
    def test_present(self):
444
        backing = self.get_transport()
445
        dir = self.make_bzrdir('.')
446
        dir.get_config().set_default_stack_on("/")
447
        local_result = dir._get_config()._get_config_file().read()
448
        request_class = smart_dir.SmartServerBzrDirRequestConfigFile
449
        request = request_class(backing)
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
450
        expected = smart_req.SuccessfulSmartServerResponse((), local_result)
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
451
        self.assertEqual(expected, request.execute(''))
452
453
    def test_missing(self):
454
        backing = self.get_transport()
455
        dir = self.make_bzrdir('.')
456
        request_class = smart_dir.SmartServerBzrDirRequestConfigFile
457
        request = request_class(backing)
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
458
        expected = smart_req.SuccessfulSmartServerResponse((), '')
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
459
        self.assertEqual(expected, request.execute(''))
460
461
6436.3.2 by Jelmer Vernooij
Add HPSS call for BzrDir.get_branches.
462
class TestSmartServerBzrDirRequestGetBranches(
463
    tests.TestCaseWithMemoryTransport):
464
    """Tests for BzrDir.get_branches."""
465
466
    def test_simple(self):
467
        backing = self.get_transport()
468
        branch = self.make_branch('.')
469
        request_class = smart_dir.SmartServerBzrDirRequestGetBranches
470
        request = request_class(backing)
471
        local_result = bencode.bencode(
472
            {"": ("branch", branch._format.network_name())})
473
        expected = smart_req.SuccessfulSmartServerResponse(
474
            ("success", ), local_result)
475
        self.assertEqual(expected, request.execute(''))
476
477
    def test_empty(self):
478
        backing = self.get_transport()
479
        dir = self.make_bzrdir('.')
480
        request_class = smart_dir.SmartServerBzrDirRequestGetBranches
481
        request = request_class(backing)
482
        local_result = bencode.bencode({})
483
        expected = smart_req.SuccessfulSmartServerResponse(
484
            ('success',), local_result)
485
        self.assertEqual(expected, request.execute(''))
486
487
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
488
class TestSmartServerRequestInitializeBzrDir(tests.TestCaseWithMemoryTransport):
2018.5.42 by Robert Collins
Various hopefully improvements, but wsgi is broken, handing over to spiv :).
489
490
    def test_empty_dir(self):
491
        """Initializing an empty dir should succeed and do it."""
492
        backing = self.get_transport()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
493
        request = smart_dir.SmartServerRequestInitializeBzrDir(backing)
494
        self.assertEqual(smart_req.SmartServerResponse(('ok', )),
2692.1.20 by Andrew Bennetts
Tweak for consistency suggested by John's review.
495
            request.execute(''))
6472.2.1 by Jelmer Vernooij
Use bzrdir.controldir for generic access to control directories.
496
        made_dir = controldir.ControlDir.open_from_transport(backing)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
497
        # 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 :).
498
        # default formart.
499
        self.assertRaises(errors.NoWorkingTree, made_dir.open_workingtree)
500
        self.assertRaises(errors.NotBranchError, made_dir.open_branch)
501
        self.assertRaises(errors.NoRepositoryPresent, made_dir.open_repository)
502
503
    def test_missing_dir(self):
504
        """Initializing a missing directory should fail like the bzrdir api."""
505
        backing = self.get_transport()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
506
        request = smart_dir.SmartServerRequestInitializeBzrDir(backing)
2018.5.42 by Robert Collins
Various hopefully improvements, but wsgi is broken, handing over to spiv :).
507
        self.assertRaises(errors.NoSuchFile,
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
508
            request.execute, 'subdir')
2018.5.42 by Robert Collins
Various hopefully improvements, but wsgi is broken, handing over to spiv :).
509
510
    def test_initialized_dir(self):
511
        """Initializing an extant bzrdir should fail like the bzrdir api."""
512
        backing = self.get_transport()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
513
        request = smart_dir.SmartServerRequestInitializeBzrDir(backing)
2018.5.42 by Robert Collins
Various hopefully improvements, but wsgi is broken, handing over to spiv :).
514
        self.make_bzrdir('subdir')
6437.10.6 by Jelmer Vernooij
Fix test.
515
        self.assertRaises(errors.AlreadyControlDirError,
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
516
            request.execute, 'subdir')
517
518
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
519
class TestSmartServerRequestBzrDirInitializeEx(
520
    tests.TestCaseWithMemoryTransport):
4436.1.1 by Andrew Bennetts
Rename BzrDirFormat.initialize_ex verb to BzrDirFormat.initialize_ex_1.16.
521
    """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.
522
4294.2.10 by Robert Collins
Review feedback.
523
    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.
524
    """
525
526
    def test_empty_dir(self):
527
        """Initializing an empty dir should succeed and do it."""
528
        backing = self.get_transport()
4294.2.8 by Robert Collins
Reduce round trips pushing new branches substantially.
529
        name = self.make_bzrdir('reference')._format.network_name()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
530
        request = smart_dir.SmartServerRequestBzrDirInitializeEx(backing)
531
        self.assertEqual(
532
            smart_req.SmartServerResponse(('', '', '', '', '', '', name,
533
                                           'False', '', '', '')),
4294.2.8 by Robert Collins
Reduce round trips pushing new branches substantially.
534
            request.execute(name, '', 'True', 'False', 'False', '', '', '', '',
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
535
                            'False'))
6472.2.1 by Jelmer Vernooij
Use bzrdir.controldir for generic access to control directories.
536
        made_dir = controldir.ControlDir.open_from_transport(backing)
4294.2.7 by Robert Collins
Start building up a BzrDir.initialize_ex verb for the smart server.
537
        # no branch, tree or repository is expected with the current
4294.2.10 by Robert Collins
Review feedback.
538
        # default format.
4294.2.7 by Robert Collins
Start building up a BzrDir.initialize_ex verb for the smart server.
539
        self.assertRaises(errors.NoWorkingTree, made_dir.open_workingtree)
540
        self.assertRaises(errors.NotBranchError, made_dir.open_branch)
541
        self.assertRaises(errors.NoRepositoryPresent, made_dir.open_repository)
542
543
    def test_missing_dir(self):
544
        """Initializing a missing directory should fail like the bzrdir api."""
545
        backing = self.get_transport()
4294.2.8 by Robert Collins
Reduce round trips pushing new branches substantially.
546
        name = self.make_bzrdir('reference')._format.network_name()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
547
        request = smart_dir.SmartServerRequestBzrDirInitializeEx(backing)
4294.2.8 by Robert Collins
Reduce round trips pushing new branches substantially.
548
        self.assertRaises(errors.NoSuchFile, request.execute, name,
549
            'subdir/dir', 'False', 'False', 'False', '', '', '', '', 'False')
4294.2.7 by Robert Collins
Start building up a BzrDir.initialize_ex verb for the smart server.
550
551
    def test_initialized_dir(self):
4416.3.4 by Jonathan Lange
Fix a typo.
552
        """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.
553
        backing = self.get_transport()
4294.2.8 by Robert Collins
Reduce round trips pushing new branches substantially.
554
        name = self.make_bzrdir('reference')._format.network_name()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
555
        request = smart_dir.SmartServerRequestBzrDirInitializeEx(backing)
4294.2.7 by Robert Collins
Start building up a BzrDir.initialize_ex verb for the smart server.
556
        self.make_bzrdir('subdir')
4294.2.8 by Robert Collins
Reduce round trips pushing new branches substantially.
557
        self.assertRaises(errors.FileExists, request.execute, name, 'subdir',
558
            'False', 'False', 'False', '', '', '', '', 'False')
4294.2.7 by Robert Collins
Start building up a BzrDir.initialize_ex verb for the smart server.
559
4634.47.5 by Andrew Bennetts
Add tests, and fix BzrDirMeta1.has_workingtree which was failing if the local transport is decorated with a ChrootTransport or similar.
560
561
class TestSmartServerRequestOpenBzrDir(tests.TestCaseWithMemoryTransport):
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
562
4634.47.5 by Andrew Bennetts
Add tests, and fix BzrDirMeta1.has_workingtree which was failing if the local transport is decorated with a ChrootTransport or similar.
563
    def test_no_directory(self):
564
        backing = self.get_transport()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
565
        request = smart_dir.SmartServerRequestOpenBzrDir(backing)
566
        self.assertEqual(smart_req.SmartServerResponse(('no', )),
4634.47.5 by Andrew Bennetts
Add tests, and fix BzrDirMeta1.has_workingtree which was failing if the local transport is decorated with a ChrootTransport or similar.
567
            request.execute('does-not-exist'))
568
569
    def test_empty_directory(self):
570
        backing = self.get_transport()
571
        backing.mkdir('empty')
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
572
        request = smart_dir.SmartServerRequestOpenBzrDir(backing)
573
        self.assertEqual(smart_req.SmartServerResponse(('no', )),
4634.47.5 by Andrew Bennetts
Add tests, and fix BzrDirMeta1.has_workingtree which was failing if the local transport is decorated with a ChrootTransport or similar.
574
            request.execute('empty'))
575
576
    def test_outside_root_client_path(self):
577
        backing = self.get_transport()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
578
        request = smart_dir.SmartServerRequestOpenBzrDir(backing,
4634.47.5 by Andrew Bennetts
Add tests, and fix BzrDirMeta1.has_workingtree which was failing if the local transport is decorated with a ChrootTransport or similar.
579
            root_client_path='root')
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
580
        self.assertEqual(smart_req.SmartServerResponse(('no', )),
4634.47.5 by Andrew Bennetts
Add tests, and fix BzrDirMeta1.has_workingtree which was failing if the local transport is decorated with a ChrootTransport or similar.
581
            request.execute('not-root'))
582
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
583
4634.47.5 by Andrew Bennetts
Add tests, and fix BzrDirMeta1.has_workingtree which was failing if the local transport is decorated with a ChrootTransport or similar.
584
class TestSmartServerRequestOpenBzrDir_2_1(tests.TestCaseWithMemoryTransport):
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
585
4634.47.5 by Andrew Bennetts
Add tests, and fix BzrDirMeta1.has_workingtree which was failing if the local transport is decorated with a ChrootTransport or similar.
586
    def test_no_directory(self):
587
        backing = self.get_transport()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
588
        request = smart_dir.SmartServerRequestOpenBzrDir_2_1(backing)
589
        self.assertEqual(smart_req.SmartServerResponse(('no', )),
4634.47.5 by Andrew Bennetts
Add tests, and fix BzrDirMeta1.has_workingtree which was failing if the local transport is decorated with a ChrootTransport or similar.
590
            request.execute('does-not-exist'))
591
592
    def test_empty_directory(self):
593
        backing = self.get_transport()
594
        backing.mkdir('empty')
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
595
        request = smart_dir.SmartServerRequestOpenBzrDir_2_1(backing)
596
        self.assertEqual(smart_req.SmartServerResponse(('no', )),
4634.47.5 by Andrew Bennetts
Add tests, and fix BzrDirMeta1.has_workingtree which was failing if the local transport is decorated with a ChrootTransport or similar.
597
            request.execute('empty'))
598
599
    def test_present_without_workingtree(self):
600
        backing = self.get_transport()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
601
        request = smart_dir.SmartServerRequestOpenBzrDir_2_1(backing)
4634.47.5 by Andrew Bennetts
Add tests, and fix BzrDirMeta1.has_workingtree which was failing if the local transport is decorated with a ChrootTransport or similar.
602
        self.make_bzrdir('.')
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
603
        self.assertEqual(smart_req.SmartServerResponse(('yes', 'no')),
4634.47.5 by Andrew Bennetts
Add tests, and fix BzrDirMeta1.has_workingtree which was failing if the local transport is decorated with a ChrootTransport or similar.
604
            request.execute(''))
605
4634.47.6 by Andrew Bennetts
Give 'no' response for paths outside the root_client_path.
606
    def test_outside_root_client_path(self):
4634.47.5 by Andrew Bennetts
Add tests, and fix BzrDirMeta1.has_workingtree which was failing if the local transport is decorated with a ChrootTransport or similar.
607
        backing = self.get_transport()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
608
        request = smart_dir.SmartServerRequestOpenBzrDir_2_1(backing,
4634.47.5 by Andrew Bennetts
Add tests, and fix BzrDirMeta1.has_workingtree which was failing if the local transport is decorated with a ChrootTransport or similar.
609
            root_client_path='root')
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
610
        self.assertEqual(smart_req.SmartServerResponse(('no',)),
4634.47.6 by Andrew Bennetts
Give 'no' response for paths outside the root_client_path.
611
            request.execute('not-root'))
4634.47.5 by Andrew Bennetts
Add tests, and fix BzrDirMeta1.has_workingtree which was failing if the local transport is decorated with a ChrootTransport or similar.
612
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
613
4634.47.5 by Andrew Bennetts
Add tests, and fix BzrDirMeta1.has_workingtree which was failing if the local transport is decorated with a ChrootTransport or similar.
614
class TestSmartServerRequestOpenBzrDir_2_1_disk(TestCaseWithChrootedTransport):
615
616
    def test_present_with_workingtree(self):
5017.3.26 by Vincent Ladeuil
./bzr selftest -s bt.test_smart passing
617
        self.vfs_transport_factory = test_server.LocalURLServer
4634.47.5 by Andrew Bennetts
Add tests, and fix BzrDirMeta1.has_workingtree which was failing if the local transport is decorated with a ChrootTransport or similar.
618
        backing = self.get_transport()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
619
        request = smart_dir.SmartServerRequestOpenBzrDir_2_1(backing)
4634.47.5 by Andrew Bennetts
Add tests, and fix BzrDirMeta1.has_workingtree which was failing if the local transport is decorated with a ChrootTransport or similar.
620
        bd = self.make_bzrdir('.')
621
        bd.create_repository()
622
        bd.create_branch()
623
        bd.create_workingtree()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
624
        self.assertEqual(smart_req.SmartServerResponse(('yes', 'yes')),
4634.47.5 by Andrew Bennetts
Add tests, and fix BzrDirMeta1.has_workingtree which was failing if the local transport is decorated with a ChrootTransport or similar.
625
            request.execute(''))
626
627
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
628
class TestSmartServerRequestOpenBranch(TestCaseWithChrootedTransport):
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
629
630
    def test_no_branch(self):
631
        """When there is no branch, ('nobranch', ) is returned."""
632
        backing = self.get_transport()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
633
        request = smart_dir.SmartServerRequestOpenBranch(backing)
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
634
        self.make_bzrdir('.')
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
635
        self.assertEqual(smart_req.SmartServerResponse(('nobranch', )),
2692.1.20 by Andrew Bennetts
Tweak for consistency suggested by John's review.
636
            request.execute(''))
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
637
638
    def test_branch(self):
639
        """When there is a branch, 'ok' is returned."""
640
        backing = self.get_transport()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
641
        request = smart_dir.SmartServerRequestOpenBranch(backing)
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
642
        self.make_branch('.')
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
643
        self.assertEqual(smart_req.SmartServerResponse(('ok', '')),
2692.1.20 by Andrew Bennetts
Tweak for consistency suggested by John's review.
644
            request.execute(''))
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
645
646
    def test_branch_reference(self):
647
        """When there is a branch reference, the reference URL is returned."""
5017.3.26 by Vincent Ladeuil
./bzr selftest -s bt.test_smart passing
648
        self.vfs_transport_factory = test_server.LocalURLServer
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
649
        backing = self.get_transport()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
650
        request = smart_dir.SmartServerRequestOpenBranch(backing)
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
651
        branch = self.make_branch('branch')
652
        checkout = branch.create_checkout('reference',lightweight=True)
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
653
        reference_url = _mod_branch.BranchReferenceFormat().get_reference(
654
            checkout.bzrdir)
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
655
        self.assertFileEqual(reference_url, 'reference/.bzr/branch/location')
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
656
        self.assertEqual(smart_req.SmartServerResponse(('ok', reference_url)),
2692.1.20 by Andrew Bennetts
Tweak for consistency suggested by John's review.
657
            request.execute('reference'))
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
658
4734.4.5 by Brian de Alwis
Address comments from Aaron Bentley
659
    def test_notification_on_branch_from_repository(self):
4734.4.4 by Brian de Alwis
Added tests to ensure branching-from-repository error returns detail
660
        """When there is a repository, the error should return details."""
661
        backing = self.get_transport()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
662
        request = smart_dir.SmartServerRequestOpenBranch(backing)
4734.4.4 by Brian de Alwis
Added tests to ensure branching-from-repository error returns detail
663
        repo = self.make_repository('.')
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
664
        self.assertEqual(smart_req.SmartServerResponse(('nobranch',)),
4734.4.4 by Brian de Alwis
Added tests to ensure branching-from-repository error returns detail
665
            request.execute(''))
666
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
667
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.
668
class TestSmartServerRequestOpenBranchV2(TestCaseWithChrootedTransport):
669
670
    def test_no_branch(self):
671
        """When there is no branch, ('nobranch', ) is returned."""
672
        backing = self.get_transport()
673
        self.make_bzrdir('.')
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
674
        request = smart_dir.SmartServerRequestOpenBranchV2(backing)
675
        self.assertEqual(smart_req.SmartServerResponse(('nobranch', )),
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.
676
            request.execute(''))
677
678
    def test_branch(self):
679
        """When there is a branch, 'ok' is returned."""
680
        backing = self.get_transport()
681
        expected = self.make_branch('.')._format.network_name()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
682
        request = smart_dir.SmartServerRequestOpenBranchV2(backing)
683
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(
684
                ('branch', expected)),
685
                         request.execute(''))
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.
686
687
    def test_branch_reference(self):
688
        """When there is a branch reference, the reference URL is returned."""
5017.3.26 by Vincent Ladeuil
./bzr selftest -s bt.test_smart passing
689
        self.vfs_transport_factory = test_server.LocalURLServer
4084.2.1 by Robert Collins
Make accessing a branch.tags.get_tag_dict use a smart[er] method rather than VFS calls and real objects.
690
        backing = self.get_transport()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
691
        request = smart_dir.SmartServerRequestOpenBranchV2(backing)
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.
692
        branch = self.make_branch('branch')
693
        checkout = branch.create_checkout('reference',lightweight=True)
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
694
        reference_url = _mod_branch.BranchReferenceFormat().get_reference(
695
            checkout.bzrdir)
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.
696
        self.assertFileEqual(reference_url, 'reference/.bzr/branch/location')
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
697
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(
698
                ('ref', reference_url)),
699
                         request.execute('reference'))
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.
700
4160.2.1 by Andrew Bennetts
Failing test for BzrDir.open_branchV2 RPC not opening stacked-on branch.
701
    def test_stacked_branch(self):
702
        """Opening a stacked branch does not open the stacked-on branch."""
703
        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.
704
        feature = self.make_branch('feature')
4160.2.1 by Andrew Bennetts
Failing test for BzrDir.open_branchV2 RPC not opening stacked-on branch.
705
        feature.set_stacked_on_url(trunk.base)
706
        opened_branches = []
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
707
        _mod_branch.Branch.hooks.install_named_hook(
708
            'open', opened_branches.append, None)
4160.2.1 by Andrew Bennetts
Failing test for BzrDir.open_branchV2 RPC not opening stacked-on branch.
709
        backing = self.get_transport()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
710
        request = smart_dir.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.
711
        request.setup_jail()
712
        try:
713
            response = request.execute('feature')
714
        finally:
715
            request.teardown_jail()
4160.2.1 by Andrew Bennetts
Failing test for BzrDir.open_branchV2 RPC not opening stacked-on branch.
716
        expected_format = feature._format.network_name()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
717
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(
718
                ('branch', expected_format)),
719
                         response)
4160.2.1 by Andrew Bennetts
Failing test for BzrDir.open_branchV2 RPC not opening stacked-on branch.
720
        self.assertLength(1, opened_branches)
721
4734.4.5 by Brian de Alwis
Address comments from Aaron Bentley
722
    def test_notification_on_branch_from_repository(self):
4734.4.4 by Brian de Alwis
Added tests to ensure branching-from-repository error returns detail
723
        """When there is a repository, the error should return details."""
724
        backing = self.get_transport()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
725
        request = smart_dir.SmartServerRequestOpenBranchV2(backing)
4734.4.4 by Brian de Alwis
Added tests to ensure branching-from-repository error returns detail
726
        repo = self.make_repository('.')
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
727
        self.assertEqual(smart_req.SmartServerResponse(('nobranch',)),
4734.4.8 by Andrew Bennetts
Fix HPSS tests; pass 'location is a repository' message via smart server when possible (adds BzrDir.open_branchV3 verb).
728
            request.execute(''))
729
730
731
class TestSmartServerRequestOpenBranchV3(TestCaseWithChrootedTransport):
732
733
    def test_no_branch(self):
734
        """When there is no branch, ('nobranch', ) is returned."""
735
        backing = self.get_transport()
736
        self.make_bzrdir('.')
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
737
        request = smart_dir.SmartServerRequestOpenBranchV3(backing)
738
        self.assertEqual(smart_req.SmartServerResponse(('nobranch',)),
4734.4.8 by Andrew Bennetts
Fix HPSS tests; pass 'location is a repository' message via smart server when possible (adds BzrDir.open_branchV3 verb).
739
            request.execute(''))
740
741
    def test_branch(self):
742
        """When there is a branch, 'ok' is returned."""
743
        backing = self.get_transport()
744
        expected = self.make_branch('.')._format.network_name()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
745
        request = smart_dir.SmartServerRequestOpenBranchV3(backing)
746
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(
747
                ('branch', expected)),
748
                         request.execute(''))
4734.4.8 by Andrew Bennetts
Fix HPSS tests; pass 'location is a repository' message via smart server when possible (adds BzrDir.open_branchV3 verb).
749
750
    def test_branch_reference(self):
751
        """When there is a branch reference, the reference URL is returned."""
5017.3.26 by Vincent Ladeuil
./bzr selftest -s bt.test_smart passing
752
        self.vfs_transport_factory = test_server.LocalURLServer
4734.4.8 by Andrew Bennetts
Fix HPSS tests; pass 'location is a repository' message via smart server when possible (adds BzrDir.open_branchV3 verb).
753
        backing = self.get_transport()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
754
        request = smart_dir.SmartServerRequestOpenBranchV3(backing)
4734.4.8 by Andrew Bennetts
Fix HPSS tests; pass 'location is a repository' message via smart server when possible (adds BzrDir.open_branchV3 verb).
755
        branch = self.make_branch('branch')
756
        checkout = branch.create_checkout('reference',lightweight=True)
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
757
        reference_url = _mod_branch.BranchReferenceFormat().get_reference(
758
            checkout.bzrdir)
4734.4.8 by Andrew Bennetts
Fix HPSS tests; pass 'location is a repository' message via smart server when possible (adds BzrDir.open_branchV3 verb).
759
        self.assertFileEqual(reference_url, 'reference/.bzr/branch/location')
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
760
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(
761
                ('ref', reference_url)),
762
                         request.execute('reference'))
4734.4.8 by Andrew Bennetts
Fix HPSS tests; pass 'location is a repository' message via smart server when possible (adds BzrDir.open_branchV3 verb).
763
764
    def test_stacked_branch(self):
765
        """Opening a stacked branch does not open the stacked-on branch."""
766
        trunk = self.make_branch('trunk')
767
        feature = self.make_branch('feature')
768
        feature.set_stacked_on_url(trunk.base)
769
        opened_branches = []
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
770
        _mod_branch.Branch.hooks.install_named_hook(
771
            'open', opened_branches.append, None)
4734.4.8 by Andrew Bennetts
Fix HPSS tests; pass 'location is a repository' message via smart server when possible (adds BzrDir.open_branchV3 verb).
772
        backing = self.get_transport()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
773
        request = smart_dir.SmartServerRequestOpenBranchV3(backing)
4734.4.8 by Andrew Bennetts
Fix HPSS tests; pass 'location is a repository' message via smart server when possible (adds BzrDir.open_branchV3 verb).
774
        request.setup_jail()
775
        try:
776
            response = request.execute('feature')
777
        finally:
778
            request.teardown_jail()
779
        expected_format = feature._format.network_name()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
780
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(
781
                ('branch', expected_format)),
782
                         response)
4734.4.8 by Andrew Bennetts
Fix HPSS tests; pass 'location is a repository' message via smart server when possible (adds BzrDir.open_branchV3 verb).
783
        self.assertLength(1, opened_branches)
784
785
    def test_notification_on_branch_from_repository(self):
786
        """When there is a repository, the error should return details."""
787
        backing = self.get_transport()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
788
        request = smart_dir.SmartServerRequestOpenBranchV3(backing)
4734.4.8 by Andrew Bennetts
Fix HPSS tests; pass 'location is a repository' message via smart server when possible (adds BzrDir.open_branchV3 verb).
789
        repo = self.make_repository('.')
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
790
        self.assertEqual(smart_req.SmartServerResponse(
791
                ('nobranch', 'location is a repository')),
792
                         request.execute(''))
4734.4.4 by Brian de Alwis
Added tests to ensure branching-from-repository error returns detail
793
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.
794
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
795
class TestSmartServerRequestRevisionHistory(tests.TestCaseWithMemoryTransport):
2018.5.38 by Robert Collins
Implement RemoteBranch.revision_history().
796
797
    def test_empty(self):
798
        """For an empty branch, the body is empty."""
799
        backing = self.get_transport()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
800
        request = smart_branch.SmartServerRequestRevisionHistory(backing)
2018.5.38 by Robert Collins
Implement RemoteBranch.revision_history().
801
        self.make_branch('.')
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
802
        self.assertEqual(smart_req.SmartServerResponse(('ok', ), ''),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
803
            request.execute(''))
2018.5.38 by Robert Collins
Implement RemoteBranch.revision_history().
804
805
    def test_not_empty(self):
806
        """For a non-empty branch, the body is empty."""
807
        backing = self.get_transport()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
808
        request = smart_branch.SmartServerRequestRevisionHistory(backing)
2018.5.38 by Robert Collins
Implement RemoteBranch.revision_history().
809
        tree = self.make_branch_and_memory_tree('.')
810
        tree.lock_write()
811
        tree.add('')
812
        r1 = tree.commit('1st commit')
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
813
        r2 = tree.commit('2nd commit', rev_id=u'\xc8'.encode('utf-8'))
2018.5.38 by Robert Collins
Implement RemoteBranch.revision_history().
814
        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.
815
        self.assertEqual(
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
816
            smart_req.SmartServerResponse(('ok', ), ('\x00'.join([r1, r2]))),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
817
            request.execute(''))
818
819
820
class TestSmartServerBranchRequest(tests.TestCaseWithMemoryTransport):
2018.5.49 by Wouter van Heyst
Refactor SmartServerBranchRequest out from SmartServerRequestRevisionHistory to
821
822
    def test_no_branch(self):
823
        """When there is a bzrdir and no branch, NotBranchError is raised."""
824
        backing = self.get_transport()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
825
        request = smart_branch.SmartServerBranchRequest(backing)
2018.5.49 by Wouter van Heyst
Refactor SmartServerBranchRequest out from SmartServerRequestRevisionHistory to
826
        self.make_bzrdir('.')
827
        self.assertRaises(errors.NotBranchError,
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
828
            request.execute, '')
2018.5.49 by Wouter van Heyst
Refactor SmartServerBranchRequest out from SmartServerRequestRevisionHistory to
829
2018.5.38 by Robert Collins
Implement RemoteBranch.revision_history().
830
    def test_branch_reference(self):
831
        """When there is a branch reference, NotBranchError is raised."""
832
        backing = self.get_transport()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
833
        request = smart_branch.SmartServerBranchRequest(backing)
2018.5.38 by Robert Collins
Implement RemoteBranch.revision_history().
834
        branch = self.make_branch('branch')
835
        checkout = branch.create_checkout('reference',lightweight=True)
836
        self.assertRaises(errors.NotBranchError,
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
837
            request.execute, 'checkout')
838
839
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
840
class TestSmartServerBranchRequestLastRevisionInfo(
841
    tests.TestCaseWithMemoryTransport):
2018.5.50 by Wouter van Heyst
Add SmartServerBranchRequestLastRevisionInfo method.
842
843
    def test_empty(self):
2018.5.170 by Andrew Bennetts
Use 'null:' instead of '' to mean NULL_REVISION on the wire.
844
        """For an empty branch, the result is ('ok', '0', 'null:')."""
2018.5.50 by Wouter van Heyst
Add SmartServerBranchRequestLastRevisionInfo method.
845
        backing = self.get_transport()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
846
        request = smart_branch.SmartServerBranchRequestLastRevisionInfo(backing)
2018.5.50 by Wouter van Heyst
Add SmartServerBranchRequestLastRevisionInfo method.
847
        self.make_branch('.')
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
848
        self.assertEqual(smart_req.SmartServerResponse(('ok', '0', 'null:')),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
849
            request.execute(''))
2018.5.50 by Wouter van Heyst
Add SmartServerBranchRequestLastRevisionInfo method.
850
851
    def test_not_empty(self):
852
        """For a non-empty branch, the result is ('ok', 'revno', 'revid')."""
853
        backing = self.get_transport()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
854
        request = smart_branch.SmartServerBranchRequestLastRevisionInfo(backing)
2018.5.50 by Wouter van Heyst
Add SmartServerBranchRequestLastRevisionInfo method.
855
        tree = self.make_branch_and_memory_tree('.')
856
        tree.lock_write()
857
        tree.add('')
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
858
        rev_id_utf8 = u'\xc8'.encode('utf-8')
2018.5.50 by Wouter van Heyst
Add SmartServerBranchRequestLastRevisionInfo method.
859
        r1 = tree.commit('1st commit')
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
860
        r2 = tree.commit('2nd commit', rev_id=rev_id_utf8)
2018.5.50 by Wouter van Heyst
Add SmartServerBranchRequestLastRevisionInfo method.
861
        tree.unlock()
862
        self.assertEqual(
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
863
            smart_req.SmartServerResponse(('ok', '2', rev_id_utf8)),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
864
            request.execute(''))
865
866
6263.1.2 by Jelmer Vernooij
Add ``Branch.revision_id_to_revno`` smart verb.
867
class TestSmartServerBranchRequestRevisionIdToRevno(
868
    tests.TestCaseWithMemoryTransport):
869
870
    def test_null(self):
871
        backing = self.get_transport()
872
        request = smart_branch.SmartServerBranchRequestRevisionIdToRevno(
873
            backing)
874
        self.make_branch('.')
875
        self.assertEqual(smart_req.SmartServerResponse(('ok', '0')),
876
            request.execute('', 'null:'))
877
878
    def test_simple(self):
879
        backing = self.get_transport()
880
        request = smart_branch.SmartServerBranchRequestRevisionIdToRevno(
881
            backing)
882
        tree = self.make_branch_and_memory_tree('.')
883
        tree.lock_write()
884
        tree.add('')
885
        r1 = tree.commit('1st commit')
886
        tree.unlock()
887
        self.assertEqual(
888
            smart_req.SmartServerResponse(('ok', '1')),
889
            request.execute('', r1))
890
891
    def test_not_found(self):
892
        backing = self.get_transport()
893
        request = smart_branch.SmartServerBranchRequestRevisionIdToRevno(
894
            backing)
895
        branch = self.make_branch('.')
896
        self.assertEqual(
897
            smart_req.FailedSmartServerResponse(
898
                ('NoSuchRevision', 'idontexist')),
899
            request.execute('', 'idontexist'))
900
901
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
902
class TestSmartServerBranchRequestGetConfigFile(
903
    tests.TestCaseWithMemoryTransport):
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
904
905
    def test_default(self):
906
        """With no file, we get empty content."""
907
        backing = self.get_transport()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
908
        request = smart_branch.SmartServerBranchGetConfigFile(backing)
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
909
        branch = self.make_branch('.')
910
        # there should be no file by default
911
        content = ''
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
912
        self.assertEqual(smart_req.SmartServerResponse(('ok', ), content),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
913
            request.execute(''))
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
914
915
    def test_with_content(self):
916
        # SmartServerBranchGetConfigFile should return the content from
917
        # 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
918
        # perform more complex processing.
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
919
        backing = self.get_transport()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
920
        request = smart_branch.SmartServerBranchGetConfigFile(backing)
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
921
        branch = self.make_branch('.')
3407.2.5 by Martin Pool
Deprecate LockableFiles.put_utf8
922
        branch._transport.put_bytes('branch.conf', 'foo bar baz')
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
923
        self.assertEqual(smart_req.SmartServerResponse(('ok', ), 'foo bar baz'),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
924
            request.execute(''))
925
926
4226.2.1 by Robert Collins
Set branch config options via a smart method.
927
class TestLockedBranch(tests.TestCaseWithMemoryTransport):
928
929
    def get_lock_tokens(self, branch):
5200.3.3 by Robert Collins
Lock methods on ``Tree``, ``Branch`` and ``Repository`` are now
930
        branch_token = branch.lock_write().branch_token
931
        repo_token = branch.repository.lock_write().repository_token
4226.2.1 by Robert Collins
Set branch config options via a smart method.
932
        branch.repository.unlock()
933
        return branch_token, repo_token
934
935
6270.1.17 by Jelmer Vernooij
s/set_config_file/put_config_file.
936
class TestSmartServerBranchRequestPutConfigFile(TestLockedBranch):
6270.1.9 by Jelmer Vernooij
add Branch.set_config_file.
937
938
    def test_with_content(self):
939
        backing = self.get_transport()
6270.1.17 by Jelmer Vernooij
s/set_config_file/put_config_file.
940
        request = smart_branch.SmartServerBranchPutConfigFile(backing)
6270.1.9 by Jelmer Vernooij
add Branch.set_config_file.
941
        branch = self.make_branch('.')
942
        branch_token, repo_token = self.get_lock_tokens(branch)
6270.1.10 by Jelmer Vernooij
Fix testing Branch.set_config_file.
943
        self.assertIs(None, request.execute('', branch_token, repo_token))
6270.1.9 by Jelmer Vernooij
add Branch.set_config_file.
944
        self.assertEqual(
945
            smart_req.SmartServerResponse(('ok', )),
946
            request.do_body('foo bar baz'))
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
947
        self.assertEqual(
6270.1.9 by Jelmer Vernooij
add Branch.set_config_file.
948
            branch.control_transport.get_bytes('branch.conf'),
949
            'foo bar baz')
950
        branch.unlock()
951
952
4226.2.1 by Robert Collins
Set branch config options via a smart method.
953
class TestSmartServerBranchRequestSetConfigOption(TestLockedBranch):
954
955
    def test_value_name(self):
956
        branch = self.make_branch('.')
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
957
        request = smart_branch.SmartServerBranchRequestSetConfigOption(
4226.2.1 by Robert Collins
Set branch config options via a smart method.
958
            branch.bzrdir.root_transport)
959
        branch_token, repo_token = self.get_lock_tokens(branch)
960
        config = branch._get_config()
961
        result = request.execute('', branch_token, repo_token, 'bar', 'foo',
962
            '')
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
963
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), result)
4226.2.1 by Robert Collins
Set branch config options via a smart method.
964
        self.assertEqual('bar', config.get_option('foo'))
4327.1.10 by Vincent Ladeuil
Fix 10 more lock-related test failures.
965
        # Cleanup
966
        branch.unlock()
4226.2.1 by Robert Collins
Set branch config options via a smart method.
967
968
    def test_value_name_section(self):
969
        branch = self.make_branch('.')
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
970
        request = smart_branch.SmartServerBranchRequestSetConfigOption(
4226.2.1 by Robert Collins
Set branch config options via a smart method.
971
            branch.bzrdir.root_transport)
972
        branch_token, repo_token = self.get_lock_tokens(branch)
973
        config = branch._get_config()
974
        result = request.execute('', branch_token, repo_token, 'bar', 'foo',
975
            'gam')
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
976
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), result)
4226.2.1 by Robert Collins
Set branch config options via a smart method.
977
        self.assertEqual('bar', config.get_option('foo', 'gam'))
4327.1.10 by Vincent Ladeuil
Fix 10 more lock-related test failures.
978
        # Cleanup
979
        branch.unlock()
4226.2.1 by Robert Collins
Set branch config options via a smart method.
980
981
5227.1.2 by Andrew Bennetts
Add Branch.set_config_option_dict RPC (and VFS fallback), fixes #430382.
982
class TestSmartServerBranchRequestSetConfigOptionDict(TestLockedBranch):
983
984
    def setUp(self):
985
        TestLockedBranch.setUp(self)
986
        # A dict with non-ascii keys and values to exercise unicode
987
        # roundtripping.
988
        self.encoded_value_dict = (
989
            'd5:ascii1:a11:unicode \xe2\x8c\x9a3:\xe2\x80\xbde')
990
        self.value_dict = {
991
            'ascii': 'a', u'unicode \N{WATCH}': u'\N{INTERROBANG}'}
992
993
    def test_value_name(self):
994
        branch = self.make_branch('.')
995
        request = smart_branch.SmartServerBranchRequestSetConfigOptionDict(
996
            branch.bzrdir.root_transport)
997
        branch_token, repo_token = self.get_lock_tokens(branch)
998
        config = branch._get_config()
999
        result = request.execute('', branch_token, repo_token,
1000
            self.encoded_value_dict, 'foo', '')
1001
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), result)
1002
        self.assertEqual(self.value_dict, config.get_option('foo'))
1003
        # Cleanup
1004
        branch.unlock()
1005
1006
    def test_value_name_section(self):
1007
        branch = self.make_branch('.')
1008
        request = smart_branch.SmartServerBranchRequestSetConfigOptionDict(
1009
            branch.bzrdir.root_transport)
1010
        branch_token, repo_token = self.get_lock_tokens(branch)
1011
        config = branch._get_config()
1012
        result = request.execute('', branch_token, repo_token,
1013
            self.encoded_value_dict, 'foo', 'gam')
1014
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), result)
1015
        self.assertEqual(self.value_dict, config.get_option('foo', 'gam'))
1016
        # Cleanup
1017
        branch.unlock()
1018
1019
4556.2.2 by Andrew Bennetts
Handle failures more gracefully.
1020
class TestSmartServerBranchRequestSetTagsBytes(TestLockedBranch):
1021
    # Only called when the branch format and tags match [yay factory
1022
    # methods] so only need to test straight forward cases.
1023
1024
    def test_set_bytes(self):
1025
        base_branch = self.make_branch('base')
1026
        tag_bytes = base_branch._get_tags_bytes()
1027
        # get_lock_tokens takes out a lock.
1028
        branch_token, repo_token = self.get_lock_tokens(base_branch)
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1029
        request = smart_branch.SmartServerBranchSetTagsBytes(
4556.2.2 by Andrew Bennetts
Handle failures more gracefully.
1030
            self.get_transport())
1031
        response = request.execute('base', branch_token, repo_token)
1032
        self.assertEqual(None, response)
1033
        response = request.do_chunk(tag_bytes)
1034
        self.assertEqual(None, response)
1035
        response = request.do_end()
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
1036
        self.assertEqual(
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1037
            smart_req.SuccessfulSmartServerResponse(()), response)
4556.2.2 by Andrew Bennetts
Handle failures more gracefully.
1038
        base_branch.unlock()
1039
1040
    def test_lock_failed(self):
1041
        base_branch = self.make_branch('base')
1042
        base_branch.lock_write()
1043
        tag_bytes = base_branch._get_tags_bytes()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1044
        request = smart_branch.SmartServerBranchSetTagsBytes(
4556.2.2 by Andrew Bennetts
Handle failures more gracefully.
1045
            self.get_transport())
1046
        self.assertRaises(errors.TokenMismatch, request.execute,
1047
            'base', 'wrong token', 'wrong token')
1048
        # The request handler will keep processing the message parts, so even
1049
        # if the request fails immediately do_chunk and do_end are still
1050
        # called.
1051
        request.do_chunk(tag_bytes)
1052
        request.do_end()
1053
        base_branch.unlock()
1054
1055
1056
4226.2.1 by Robert Collins
Set branch config options via a smart method.
1057
class SetLastRevisionTestBase(TestLockedBranch):
3441.5.30 by Andrew Bennetts
Improve tests for all Branch.set_last_revision* verbs.
1058
    """Base test case for verbs that implement set_last_revision."""
1059
1060
    def setUp(self):
6552.1.4 by Vincent Ladeuil
Remaining tests matching setup(self) that can be rewritten with super().
1061
        super(SetLastRevisionTestBase, self).setUp()
3441.5.30 by Andrew Bennetts
Improve tests for all Branch.set_last_revision* verbs.
1062
        backing_transport = self.get_transport()
1063
        self.request = self.request_class(backing_transport)
1064
        self.tree = self.make_branch_and_memory_tree('.')
1065
1066
    def lock_branch(self):
4226.2.1 by Robert Collins
Set branch config options via a smart method.
1067
        return self.get_lock_tokens(self.tree.branch)
3441.5.30 by Andrew Bennetts
Improve tests for all Branch.set_last_revision* verbs.
1068
1069
    def unlock_branch(self):
1070
        self.tree.branch.unlock()
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
1071
3441.5.30 by Andrew Bennetts
Improve tests for all Branch.set_last_revision* verbs.
1072
    def set_last_revision(self, revision_id, revno):
1073
        branch_token, repo_token = self.lock_branch()
1074
        response = self._set_last_revision(
1075
            revision_id, revno, branch_token, repo_token)
1076
        self.unlock_branch()
1077
        return response
1078
1079
    def assertRequestSucceeds(self, revision_id, revno):
1080
        response = self.set_last_revision(revision_id, revno)
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1081
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(('ok',)),
1082
                         response)
3441.5.30 by Andrew Bennetts
Improve tests for all Branch.set_last_revision* verbs.
1083
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
1084
3441.5.30 by Andrew Bennetts
Improve tests for all Branch.set_last_revision* verbs.
1085
class TestSetLastRevisionVerbMixin(object):
1086
    """Mixin test case for verbs that implement set_last_revision."""
1087
1088
    def test_set_null_to_null(self):
1089
        """An empty branch can have its last revision set to 'null:'."""
1090
        self.assertRequestSucceeds('null:', 0)
1091
1092
    def test_NoSuchRevision(self):
1093
        """If the revision_id is not present, the verb returns NoSuchRevision.
1094
        """
1095
        revision_id = 'non-existent revision'
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1096
        self.assertEqual(smart_req.FailedSmartServerResponse(('NoSuchRevision',
1097
                                                              revision_id)),
1098
                         self.set_last_revision(revision_id, 1))
3441.5.30 by Andrew Bennetts
Improve tests for all Branch.set_last_revision* verbs.
1099
1100
    def make_tree_with_two_commits(self):
1101
        self.tree.lock_write()
1102
        self.tree.add('')
1103
        rev_id_utf8 = u'\xc8'.encode('utf-8')
1104
        r1 = self.tree.commit('1st commit', rev_id=rev_id_utf8)
1105
        r2 = self.tree.commit('2nd commit', rev_id='rev-2')
1106
        self.tree.unlock()
1107
1108
    def test_branch_last_revision_info_is_updated(self):
1109
        """A branch's tip can be set to a revision that is present in its
1110
        repository.
1111
        """
1112
        # Make a branch with an empty revision history, but two revisions in
1113
        # its repository.
1114
        self.make_tree_with_two_commits()
1115
        rev_id_utf8 = u'\xc8'.encode('utf-8')
5718.7.4 by Jelmer Vernooij
Branch.set_revision_history.
1116
        self.tree.branch.set_last_revision_info(0, 'null:')
3441.5.30 by Andrew Bennetts
Improve tests for all Branch.set_last_revision* verbs.
1117
        self.assertEqual(
1118
            (0, 'null:'), self.tree.branch.last_revision_info())
1119
        # We can update the branch to a revision that is present in the
1120
        # repository.
1121
        self.assertRequestSucceeds(rev_id_utf8, 1)
1122
        self.assertEqual(
1123
            (1, rev_id_utf8), self.tree.branch.last_revision_info())
1124
1125
    def test_branch_last_revision_info_rewind(self):
1126
        """A branch's tip can be set to a revision that is an ancestor of the
1127
        current tip.
1128
        """
1129
        self.make_tree_with_two_commits()
1130
        rev_id_utf8 = u'\xc8'.encode('utf-8')
1131
        self.assertEqual(
1132
            (2, 'rev-2'), self.tree.branch.last_revision_info())
1133
        self.assertRequestSucceeds(rev_id_utf8, 1)
1134
        self.assertEqual(
1135
            (1, rev_id_utf8), self.tree.branch.last_revision_info())
1136
3577.1.1 by Andrew Bennetts
Cherry-pick TipChangeRejected changes from pre-branch-tip-changed-hook loom.
1137
    def test_TipChangeRejected(self):
1138
        """If a pre_change_branch_tip hook raises TipChangeRejected, the verb
1139
        returns TipChangeRejected.
1140
        """
1141
        rejection_message = u'rejection message\N{INTERROBANG}'
1142
        def hook_that_rejects(params):
1143
            raise errors.TipChangeRejected(rejection_message)
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1144
        _mod_branch.Branch.hooks.install_named_hook(
3577.1.1 by Andrew Bennetts
Cherry-pick TipChangeRejected changes from pre-branch-tip-changed-hook loom.
1145
            'pre_change_branch_tip', hook_that_rejects, None)
1146
        self.assertEqual(
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1147
            smart_req.FailedSmartServerResponse(
3577.1.1 by Andrew Bennetts
Cherry-pick TipChangeRejected changes from pre-branch-tip-changed-hook loom.
1148
                ('TipChangeRejected', rejection_message.encode('utf-8'))),
1149
            self.set_last_revision('null:', 0))
1150
3441.5.30 by Andrew Bennetts
Improve tests for all Branch.set_last_revision* verbs.
1151
3441.5.6 by Andrew Bennetts
Greatly simplify RemoteBranch.update_revisions. Still needs more tests.
1152
class TestSmartServerBranchRequestSetLastRevision(
3441.5.30 by Andrew Bennetts
Improve tests for all Branch.set_last_revision* verbs.
1153
        SetLastRevisionTestBase, TestSetLastRevisionVerbMixin):
1154
    """Tests for Branch.set_last_revision verb."""
3441.5.6 by Andrew Bennetts
Greatly simplify RemoteBranch.update_revisions. Still needs more tests.
1155
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1156
    request_class = smart_branch.SmartServerBranchRequestSetLastRevision
3441.5.6 by Andrew Bennetts
Greatly simplify RemoteBranch.update_revisions. Still needs more tests.
1157
3441.5.30 by Andrew Bennetts
Improve tests for all Branch.set_last_revision* verbs.
1158
    def _set_last_revision(self, revision_id, revno, branch_token, repo_token):
1159
        return self.request.execute(
1160
            '', branch_token, repo_token, revision_id)
1161
1162
1163
class TestSmartServerBranchRequestSetLastRevisionInfo(
1164
        SetLastRevisionTestBase, TestSetLastRevisionVerbMixin):
1165
    """Tests for Branch.set_last_revision_info verb."""
1166
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1167
    request_class = smart_branch.SmartServerBranchRequestSetLastRevisionInfo
3441.5.30 by Andrew Bennetts
Improve tests for all Branch.set_last_revision* verbs.
1168
1169
    def _set_last_revision(self, revision_id, revno, branch_token, repo_token):
1170
        return self.request.execute(
1171
            '', branch_token, repo_token, revno, revision_id)
1172
1173
    def test_NoSuchRevision(self):
1174
        """Branch.set_last_revision_info does not have to return
1175
        NoSuchRevision if the revision_id is absent.
1176
        """
1177
        raise tests.TestNotApplicable()
3441.5.6 by Andrew Bennetts
Greatly simplify RemoteBranch.update_revisions. Still needs more tests.
1178
1179
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.
1180
class TestSmartServerBranchRequestSetLastRevisionEx(
3441.5.30 by Andrew Bennetts
Improve tests for all Branch.set_last_revision* verbs.
1181
        SetLastRevisionTestBase, TestSetLastRevisionVerbMixin):
1182
    """Tests for Branch.set_last_revision_ex verb."""
3441.5.6 by Andrew Bennetts
Greatly simplify RemoteBranch.update_revisions. Still needs more tests.
1183
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1184
    request_class = smart_branch.SmartServerBranchRequestSetLastRevisionEx
3441.5.6 by Andrew Bennetts
Greatly simplify RemoteBranch.update_revisions. Still needs more tests.
1185
3441.5.30 by Andrew Bennetts
Improve tests for all Branch.set_last_revision* verbs.
1186
    def _set_last_revision(self, revision_id, revno, branch_token, repo_token):
1187
        return self.request.execute(
1188
            '', branch_token, repo_token, revision_id, 0, 0)
1189
1190
    def assertRequestSucceeds(self, revision_id, revno):
1191
        response = self.set_last_revision(revision_id, revno)
1192
        self.assertEqual(
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1193
            smart_req.SuccessfulSmartServerResponse(('ok', revno, revision_id)),
3441.5.30 by Andrew Bennetts
Improve tests for all Branch.set_last_revision* verbs.
1194
            response)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
1195
3441.5.30 by Andrew Bennetts
Improve tests for all Branch.set_last_revision* verbs.
1196
    def test_branch_last_revision_info_rewind(self):
1197
        """A branch's tip can be set to a revision that is an ancestor of the
1198
        current tip, but only if allow_overwrite_descendant is passed.
1199
        """
1200
        self.make_tree_with_two_commits()
3441.5.6 by Andrew Bennetts
Greatly simplify RemoteBranch.update_revisions. Still needs more tests.
1201
        rev_id_utf8 = u'\xc8'.encode('utf-8')
3441.5.30 by Andrew Bennetts
Improve tests for all Branch.set_last_revision* verbs.
1202
        self.assertEqual(
1203
            (2, 'rev-2'), self.tree.branch.last_revision_info())
1204
        # If allow_overwrite_descendant flag is 0, then trying to set the tip
1205
        # to an older revision ID has no effect.
1206
        branch_token, repo_token = self.lock_branch()
1207
        response = self.request.execute(
1208
            '', branch_token, repo_token, rev_id_utf8, 0, 0)
1209
        self.assertEqual(
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1210
            smart_req.SuccessfulSmartServerResponse(('ok', 2, 'rev-2')),
3441.5.30 by Andrew Bennetts
Improve tests for all Branch.set_last_revision* verbs.
1211
            response)
1212
        self.assertEqual(
1213
            (2, 'rev-2'), self.tree.branch.last_revision_info())
1214
1215
        # If allow_overwrite_descendant flag is 1, then setting the tip to an
1216
        # ancestor works.
1217
        response = self.request.execute(
1218
            '', branch_token, repo_token, rev_id_utf8, 0, 1)
1219
        self.assertEqual(
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1220
            smart_req.SuccessfulSmartServerResponse(('ok', 1, rev_id_utf8)),
3441.5.30 by Andrew Bennetts
Improve tests for all Branch.set_last_revision* verbs.
1221
            response)
1222
        self.unlock_branch()
1223
        self.assertEqual(
1224
            (1, rev_id_utf8), self.tree.branch.last_revision_info())
1225
3441.5.31 by Andrew Bennetts
Add test for allow_diverged flag.
1226
    def make_branch_with_divergent_history(self):
1227
        """Make a branch with divergent history in its repo.
1228
1229
        The branch's tip will be 'child-2', and the repo will also contain
1230
        'child-1', which diverges from a common base revision.
3441.5.30 by Andrew Bennetts
Improve tests for all Branch.set_last_revision* verbs.
1231
        """
1232
        self.tree.lock_write()
1233
        self.tree.add('')
1234
        r1 = self.tree.commit('1st commit')
1235
        revno_1, revid_1 = self.tree.branch.last_revision_info()
1236
        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.
1237
        # Undo the second commit
3441.5.30 by Andrew Bennetts
Improve tests for all Branch.set_last_revision* verbs.
1238
        self.tree.branch.set_last_revision_info(revno_1, revid_1)
1239
        self.tree.set_parent_ids([revid_1])
3441.5.6 by Andrew Bennetts
Greatly simplify RemoteBranch.update_revisions. Still needs more tests.
1240
        # Make a new second commit, child-2.  child-2 has diverged from
1241
        # child-1.
3441.5.30 by Andrew Bennetts
Improve tests for all Branch.set_last_revision* verbs.
1242
        new_r2 = self.tree.commit('2nd commit', rev_id='child-2')
1243
        self.tree.unlock()
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
1244
3441.5.31 by Andrew Bennetts
Add test for allow_diverged flag.
1245
    def test_not_allow_diverged(self):
1246
        """If allow_diverged is not passed, then setting a divergent history
1247
        returns a Diverged error.
1248
        """
1249
        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.
1250
        self.assertEqual(
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1251
            smart_req.FailedSmartServerResponse(('Diverged',)),
3441.5.30 by Andrew Bennetts
Improve tests for all Branch.set_last_revision* verbs.
1252
            self.set_last_revision('child-1', 2))
1253
        # The branch tip was not changed.
1254
        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.
1255
3441.5.31 by Andrew Bennetts
Add test for allow_diverged flag.
1256
    def test_allow_diverged(self):
1257
        """If allow_diverged is passed, then setting a divergent history
1258
        succeeds.
1259
        """
1260
        self.make_branch_with_divergent_history()
1261
        branch_token, repo_token = self.lock_branch()
1262
        response = self.request.execute(
1263
            '', branch_token, repo_token, 'child-1', 1, 0)
1264
        self.assertEqual(
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1265
            smart_req.SuccessfulSmartServerResponse(('ok', 2, 'child-1')),
3441.5.31 by Andrew Bennetts
Add test for allow_diverged flag.
1266
            response)
1267
        self.unlock_branch()
1268
        # The branch tip was changed.
1269
        self.assertEqual('child-1', self.tree.branch.last_revision())
1270
2892.2.1 by Andrew Bennetts
Add Branch.set_last_revision_info smart method, and make the RemoteBranch client use it.
1271
6280.4.4 by Jelmer Vernooij
Add Branch.break_lock.
1272
class TestSmartServerBranchBreakLock(tests.TestCaseWithMemoryTransport):
1273
1274
    def test_lock_to_break(self):
1275
        base_branch = self.make_branch('base')
1276
        request = smart_branch.SmartServerBranchBreakLock(
1277
            self.get_transport())
1278
        base_branch.lock_write()
1279
        self.assertEqual(
1280
            smart_req.SuccessfulSmartServerResponse(('ok', ), None),
1281
            request.execute('base'))
1282
1283
    def test_nothing_to_break(self):
1284
        base_branch = self.make_branch('base')
1285
        request = smart_branch.SmartServerBranchBreakLock(
1286
            self.get_transport())
1287
        self.assertEqual(
1288
            smart_req.SuccessfulSmartServerResponse(('ok', ), None),
1289
            request.execute('base'))
1290
1291
4078.2.1 by Robert Collins
Add a Branch.get_parent remote call for RemoteBranch.
1292
class TestSmartServerBranchRequestGetParent(tests.TestCaseWithMemoryTransport):
1293
1294
    def test_get_parent_none(self):
1295
        base_branch = self.make_branch('base')
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1296
        request = smart_branch.SmartServerBranchGetParent(self.get_transport())
4078.2.1 by Robert Collins
Add a Branch.get_parent remote call for RemoteBranch.
1297
        response = request.execute('base')
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
1298
        self.assertEqual(
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1299
            smart_req.SuccessfulSmartServerResponse(('',)), response)
4078.2.1 by Robert Collins
Add a Branch.get_parent remote call for RemoteBranch.
1300
1301
    def test_get_parent_something(self):
1302
        base_branch = self.make_branch('base')
1303
        base_branch.set_parent(self.get_url('foo'))
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1304
        request = smart_branch.SmartServerBranchGetParent(self.get_transport())
4078.2.1 by Robert Collins
Add a Branch.get_parent remote call for RemoteBranch.
1305
        response = request.execute('base')
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
1306
        self.assertEqual(
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1307
            smart_req.SuccessfulSmartServerResponse(("../foo",)),
4078.2.1 by Robert Collins
Add a Branch.get_parent remote call for RemoteBranch.
1308
            response)
1309
1310
5200.3.3 by Robert Collins
Lock methods on ``Tree``, ``Branch`` and ``Repository`` are now
1311
class TestSmartServerBranchRequestSetParent(TestLockedBranch):
4288.1.7 by Robert Collins
Add new remote server verb Branch.set_parent_location, dropping roundtrips further on push operations.
1312
1313
    def test_set_parent_none(self):
1314
        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.
1315
        branch.lock_write()
4288.1.7 by Robert Collins
Add new remote server verb Branch.set_parent_location, dropping roundtrips further on push operations.
1316
        branch._set_parent_location('foo')
4288.1.9 by Robert Collins
Fix up test usable of _set_parent_location on unlocked branches.
1317
        branch.unlock()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1318
        request = smart_branch.SmartServerBranchRequestSetParentLocation(
4288.1.7 by Robert Collins
Add new remote server verb Branch.set_parent_location, dropping roundtrips further on push operations.
1319
            self.get_transport())
5200.3.3 by Robert Collins
Lock methods on ``Tree``, ``Branch`` and ``Repository`` are now
1320
        branch_token, repo_token = self.get_lock_tokens(branch)
4288.1.7 by Robert Collins
Add new remote server verb Branch.set_parent_location, dropping roundtrips further on push operations.
1321
        try:
1322
            response = request.execute('base', branch_token, repo_token, '')
1323
        finally:
1324
            branch.unlock()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1325
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), response)
6404.6.6 by Vincent Ladeuil
Use idioms coherently and add comments to make their purpose clearer.
1326
        # Refresh branch as SetParentLocation modified it
1327
        branch = branch.bzrdir.open_branch()
1328
        self.assertEqual(None, branch.get_parent())
4288.1.7 by Robert Collins
Add new remote server verb Branch.set_parent_location, dropping roundtrips further on push operations.
1329
1330
    def test_set_parent_something(self):
1331
        branch = self.make_branch('base', format="1.9")
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1332
        request = smart_branch.SmartServerBranchRequestSetParentLocation(
4288.1.7 by Robert Collins
Add new remote server verb Branch.set_parent_location, dropping roundtrips further on push operations.
1333
            self.get_transport())
5200.3.3 by Robert Collins
Lock methods on ``Tree``, ``Branch`` and ``Repository`` are now
1334
        branch_token, repo_token = self.get_lock_tokens(branch)
4288.1.7 by Robert Collins
Add new remote server verb Branch.set_parent_location, dropping roundtrips further on push operations.
1335
        try:
1336
            response = request.execute('base', branch_token, repo_token,
6404.6.1 by Vincent Ladeuil
Tests passing for a first rough version of a cached branch config store. The changes here are too invasive and several parallel proposals have been made.
1337
                                       'http://bar/')
4288.1.7 by Robert Collins
Add new remote server verb Branch.set_parent_location, dropping roundtrips further on push operations.
1338
        finally:
1339
            branch.unlock()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1340
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), response)
6404.6.1 by Vincent Ladeuil
Tests passing for a first rough version of a cached branch config store. The changes here are too invasive and several parallel proposals have been made.
1341
        refreshed = _mod_branch.Branch.open(branch.base)
1342
        self.assertEqual('http://bar/', refreshed.get_parent())
4288.1.7 by Robert Collins
Add new remote server verb Branch.set_parent_location, dropping roundtrips further on push operations.
1343
1344
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1345
class TestSmartServerBranchRequestGetTagsBytes(
1346
    tests.TestCaseWithMemoryTransport):
4556.2.2 by Andrew Bennetts
Handle failures more gracefully.
1347
    # Only called when the branch format and tags match [yay factory
1348
    # 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.
1349
1350
    def test_get_bytes(self):
1351
        base_branch = self.make_branch('base')
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1352
        request = smart_branch.SmartServerBranchGetTagsBytes(
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.
1353
            self.get_transport())
1354
        response = request.execute('base')
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
1355
        self.assertEqual(
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1356
            smart_req.SuccessfulSmartServerResponse(('',)), response)
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.
1357
1358
3691.2.5 by Martin Pool
Add Branch.get_stacked_on_url rpc and tests for same
1359
class TestSmartServerBranchRequestGetStackedOnURL(tests.TestCaseWithMemoryTransport):
1360
1361
    def test_get_stacked_on_url(self):
1362
        base_branch = self.make_branch('base', format='1.6')
1363
        stacked_branch = self.make_branch('stacked', format='1.6')
1364
        # typically should be relative
1365
        stacked_branch.set_stacked_on_url('../base')
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1366
        request = smart_branch.SmartServerBranchRequestGetStackedOnURL(
3691.2.5 by Martin Pool
Add Branch.get_stacked_on_url rpc and tests for same
1367
            self.get_transport())
1368
        response = request.execute('stacked')
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
1369
        self.assertEqual(
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1370
            smart_req.SmartServerResponse(('ok', '../base')),
3691.2.5 by Martin Pool
Add Branch.get_stacked_on_url rpc and tests for same
1371
            response)
1372
1373
5200.3.3 by Robert Collins
Lock methods on ``Tree``, ``Branch`` and ``Repository`` are now
1374
class TestSmartServerBranchRequestLockWrite(TestLockedBranch):
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1375
1376
    def test_lock_write_on_unlocked_branch(self):
1377
        backing = self.get_transport()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1378
        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.
1379
        branch = self.make_branch('.', format='knit')
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1380
        repository = branch.repository
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1381
        response = request.execute('')
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1382
        branch_nonce = branch.control_files._lock.peek().get('nonce')
1383
        repository_nonce = repository.control_files._lock.peek().get('nonce')
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1384
        self.assertEqual(smart_req.SmartServerResponse(
1385
                ('ok', branch_nonce, repository_nonce)),
1386
                         response)
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1387
        # The branch (and associated repository) is now locked.  Verify that
1388
        # with a new branch object.
1389
        new_branch = repository.bzrdir.open_branch()
1390
        self.assertRaises(errors.LockContention, new_branch.lock_write)
4327.1.10 by Vincent Ladeuil
Fix 10 more lock-related test failures.
1391
        # Cleanup
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1392
        request = smart_branch.SmartServerBranchRequestUnlock(backing)
4327.1.10 by Vincent Ladeuil
Fix 10 more lock-related test failures.
1393
        response = request.execute('', branch_nonce, repository_nonce)
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1394
1395
    def test_lock_write_on_locked_branch(self):
1396
        backing = self.get_transport()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1397
        request = smart_branch.SmartServerBranchRequestLockWrite(backing)
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1398
        branch = self.make_branch('.')
5200.3.3 by Robert Collins
Lock methods on ``Tree``, ``Branch`` and ``Repository`` are now
1399
        branch_token = branch.lock_write().branch_token
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1400
        branch.leave_lock_in_place()
1401
        branch.unlock()
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1402
        response = request.execute('')
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1403
        self.assertEqual(
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1404
            smart_req.SmartServerResponse(('LockContention',)), response)
4327.1.10 by Vincent Ladeuil
Fix 10 more lock-related test failures.
1405
        # Cleanup
1406
        branch.lock_write(branch_token)
1407
        branch.dont_leave_lock_in_place()
1408
        branch.unlock()
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1409
1410
    def test_lock_write_with_tokens_on_locked_branch(self):
1411
        backing = self.get_transport()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1412
        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.
1413
        branch = self.make_branch('.', format='knit')
5200.3.3 by Robert Collins
Lock methods on ``Tree``, ``Branch`` and ``Repository`` are now
1414
        branch_token, repo_token = self.get_lock_tokens(branch)
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1415
        branch.leave_lock_in_place()
1416
        branch.repository.leave_lock_in_place()
1417
        branch.unlock()
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1418
        response = request.execute('',
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1419
                                   branch_token, repo_token)
1420
        self.assertEqual(
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1421
            smart_req.SmartServerResponse(('ok', branch_token, repo_token)),
1422
            response)
4327.1.10 by Vincent Ladeuil
Fix 10 more lock-related test failures.
1423
        # Cleanup
1424
        branch.repository.lock_write(repo_token)
1425
        branch.repository.dont_leave_lock_in_place()
1426
        branch.repository.unlock()
1427
        branch.lock_write(branch_token)
1428
        branch.dont_leave_lock_in_place()
1429
        branch.unlock()
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1430
1431
    def test_lock_write_with_mismatched_tokens_on_locked_branch(self):
1432
        backing = self.get_transport()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1433
        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.
1434
        branch = self.make_branch('.', format='knit')
5200.3.3 by Robert Collins
Lock methods on ``Tree``, ``Branch`` and ``Repository`` are now
1435
        branch_token, repo_token = self.get_lock_tokens(branch)
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1436
        branch.leave_lock_in_place()
1437
        branch.repository.leave_lock_in_place()
1438
        branch.unlock()
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1439
        response = request.execute('',
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1440
                                   branch_token+'xxx', repo_token)
1441
        self.assertEqual(
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1442
            smart_req.SmartServerResponse(('TokenMismatch',)), response)
4327.1.10 by Vincent Ladeuil
Fix 10 more lock-related test failures.
1443
        # Cleanup
1444
        branch.repository.lock_write(repo_token)
1445
        branch.repository.dont_leave_lock_in_place()
1446
        branch.repository.unlock()
1447
        branch.lock_write(branch_token)
1448
        branch.dont_leave_lock_in_place()
1449
        branch.unlock()
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1450
1451
    def test_lock_write_on_locked_repo(self):
1452
        backing = self.get_transport()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1453
        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.
1454
        branch = self.make_branch('.', format='knit')
4327.1.10 by Vincent Ladeuil
Fix 10 more lock-related test failures.
1455
        repo = branch.repository
5200.3.3 by Robert Collins
Lock methods on ``Tree``, ``Branch`` and ``Repository`` are now
1456
        repo_token = repo.lock_write().repository_token
4327.1.10 by Vincent Ladeuil
Fix 10 more lock-related test failures.
1457
        repo.leave_lock_in_place()
1458
        repo.unlock()
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1459
        response = request.execute('')
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1460
        self.assertEqual(
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1461
            smart_req.SmartServerResponse(('LockContention',)), response)
4327.1.10 by Vincent Ladeuil
Fix 10 more lock-related test failures.
1462
        # Cleanup
1463
        repo.lock_write(repo_token)
1464
        repo.dont_leave_lock_in_place()
1465
        repo.unlock()
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1466
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.
1467
    def test_lock_write_on_readonly_transport(self):
1468
        backing = self.get_readonly_transport()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1469
        request = smart_branch.SmartServerBranchRequestLockWrite(backing)
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.
1470
        branch = self.make_branch('.')
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1471
        root = self.get_transport().clone('/')
1472
        path = urlutils.relative_url(root.base, self.get_transport().base)
1473
        response = request.execute(path)
2872.5.3 by Martin Pool
Pass back LockFailed from smart server lock methods
1474
        error_name, lock_str, why_str = response.args
1475
        self.assertFalse(response.is_successful())
1476
        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.
1477
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1478
6280.6.2 by Jelmer Vernooij
Add HPSS calls Repository.get_physical_lock_status and Branch.get_physical_lock_status.
1479
class TestSmartServerBranchRequestGetPhysicalLockStatus(TestLockedBranch):
1480
1481
    def test_true(self):
1482
        backing = self.get_transport()
1483
        request = smart_branch.SmartServerBranchRequestGetPhysicalLockStatus(
1484
            backing)
1485
        branch = self.make_branch('.')
1486
        branch_token, repo_token = self.get_lock_tokens(branch)
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
1487
        self.assertEqual(True, branch.get_physical_lock_status())
6280.6.2 by Jelmer Vernooij
Add HPSS calls Repository.get_physical_lock_status and Branch.get_physical_lock_status.
1488
        response = request.execute('')
1489
        self.assertEqual(
1490
            smart_req.SmartServerResponse(('yes',)), response)
1491
        branch.unlock()
1492
1493
    def test_false(self):
1494
        backing = self.get_transport()
1495
        request = smart_branch.SmartServerBranchRequestGetPhysicalLockStatus(
1496
            backing)
1497
        branch = self.make_branch('.')
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
1498
        self.assertEqual(False, branch.get_physical_lock_status())
6280.6.2 by Jelmer Vernooij
Add HPSS calls Repository.get_physical_lock_status and Branch.get_physical_lock_status.
1499
        response = request.execute('')
1500
        self.assertEqual(
1501
            smart_req.SmartServerResponse(('no',)), response)
1502
1503
5200.3.3 by Robert Collins
Lock methods on ``Tree``, ``Branch`` and ``Repository`` are now
1504
class TestSmartServerBranchRequestUnlock(TestLockedBranch):
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1505
1506
    def test_unlock_on_locked_branch_and_repo(self):
1507
        backing = self.get_transport()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1508
        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.
1509
        branch = self.make_branch('.', format='knit')
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1510
        # Lock the branch
5200.3.3 by Robert Collins
Lock methods on ``Tree``, ``Branch`` and ``Repository`` are now
1511
        branch_token, repo_token = self.get_lock_tokens(branch)
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1512
        # Unlock the branch (and repo) object, leaving the physical locks
1513
        # in place.
1514
        branch.leave_lock_in_place()
1515
        branch.repository.leave_lock_in_place()
1516
        branch.unlock()
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1517
        response = request.execute('',
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1518
                                   branch_token, repo_token)
1519
        self.assertEqual(
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1520
            smart_req.SmartServerResponse(('ok',)), response)
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1521
        # The branch is now unlocked.  Verify that with a new branch
1522
        # object.
1523
        new_branch = branch.bzrdir.open_branch()
1524
        new_branch.lock_write()
1525
        new_branch.unlock()
1526
1527
    def test_unlock_on_unlocked_branch_unlocked_repo(self):
1528
        backing = self.get_transport()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1529
        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.
1530
        branch = self.make_branch('.', format='knit')
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1531
        response = request.execute(
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1532
            '', 'branch token', 'repo token')
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1533
        self.assertEqual(
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1534
            smart_req.SmartServerResponse(('TokenMismatch',)), response)
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1535
1536
    def test_unlock_on_unlocked_branch_locked_repo(self):
1537
        backing = self.get_transport()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1538
        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.
1539
        branch = self.make_branch('.', format='knit')
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1540
        # Lock the repository.
5200.3.3 by Robert Collins
Lock methods on ``Tree``, ``Branch`` and ``Repository`` are now
1541
        repo_token = branch.repository.lock_write().repository_token
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1542
        branch.repository.leave_lock_in_place()
1543
        branch.repository.unlock()
1544
        # Issue branch lock_write request on the unlocked branch (with locked
1545
        # repo).
5200.3.3 by Robert Collins
Lock methods on ``Tree``, ``Branch`` and ``Repository`` are now
1546
        response = request.execute('', 'branch token', repo_token)
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1547
        self.assertEqual(
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1548
            smart_req.SmartServerResponse(('TokenMismatch',)), response)
4327.1.10 by Vincent Ladeuil
Fix 10 more lock-related test failures.
1549
        # Cleanup
1550
        branch.repository.lock_write(repo_token)
1551
        branch.repository.dont_leave_lock_in_place()
1552
        branch.repository.unlock()
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1553
1554
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1555
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).
1556
1557
    def test_no_repository(self):
1558
        """Raise NoRepositoryPresent when there is a bzrdir and no repo."""
1559
        # we test this using a shared repository above the named path,
1560
        # thus checking the right search logic is used - that is, that
1561
        # its the exact path being looked at and the server is not
1562
        # searching.
1563
        backing = self.get_transport()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1564
        request = smart_repo.SmartServerRepositoryRequest(backing)
2018.5.56 by Robert Collins
Factor out code we expect to be common in SmartServerRequestHasRevision to SmartServerRepositoryRequest (Robert Collins, Vincent Ladeuil).
1565
        self.make_repository('.', shared=True)
1566
        self.make_bzrdir('subdir')
1567
        self.assertRaises(errors.NoRepositoryPresent,
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1568
            request.execute, 'subdir')
1569
1570
6268.1.2 by Jelmer Vernooij
Initial work on Repository.add_signature_text.
1571
class TestSmartServerRepositoryAddSignatureText(tests.TestCaseWithMemoryTransport):
1572
1573
    def test_add_text(self):
1574
        backing = self.get_transport()
1575
        request = smart_repo.SmartServerRepositoryAddSignatureText(backing)
1576
        tree = self.make_branch_and_memory_tree('.')
6268.1.6 by Jelmer Vernooij
Fix add_signature_text.
1577
        write_token = tree.lock_write()
1578
        self.addCleanup(tree.unlock)
1579
        tree.add('')
1580
        tree.commit("Message", rev_id='rev1')
6268.1.2 by Jelmer Vernooij
Initial work on Repository.add_signature_text.
1581
        tree.branch.repository.start_write_group()
6268.1.6 by Jelmer Vernooij
Fix add_signature_text.
1582
        write_group_tokens = tree.branch.repository.suspend_write_group()
1583
        self.assertEqual(None, request.execute('', write_token,
6280.10.32 by Jelmer Vernooij
Merge bzr.dev.
1584
            'rev1', *write_group_tokens))
6268.1.6 by Jelmer Vernooij
Fix add_signature_text.
1585
        response = request.do_body('somesignature')
1586
        self.assertTrue(response.is_successful())
1587
        self.assertEqual(response.args[0], 'ok')
1588
        write_group_tokens = response.args[1:]
1589
        tree.branch.repository.resume_write_group(write_group_tokens)
1590
        tree.branch.repository.commit_write_group()
1591
        tree.unlock()
6268.1.2 by Jelmer Vernooij
Initial work on Repository.add_signature_text.
1592
        self.assertEqual("somesignature",
1593
            tree.branch.repository.get_signature_text("rev1"))
1594
1595
6280.3.2 by Jelmer Vernooij
Add smart side of RemoteRepository.all_revision_ids().
1596
class TestSmartServerRepositoryAllRevisionIds(
1597
    tests.TestCaseWithMemoryTransport):
1598
1599
    def test_empty(self):
1600
        """An empty body should be returned for an empty repository."""
1601
        backing = self.get_transport()
1602
        request = smart_repo.SmartServerRepositoryAllRevisionIds(backing)
1603
        self.make_repository('.')
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
1604
        self.assertEqual(
6280.3.2 by Jelmer Vernooij
Add smart side of RemoteRepository.all_revision_ids().
1605
            smart_req.SuccessfulSmartServerResponse(("ok", ), ""),
1606
            request.execute(''))
1607
1608
    def test_some_revisions(self):
1609
        """An empty body should be returned for an empty repository."""
1610
        backing = self.get_transport()
1611
        request = smart_repo.SmartServerRepositoryAllRevisionIds(backing)
1612
        tree = self.make_branch_and_memory_tree('.')
1613
        tree.lock_write()
1614
        tree.add('')
1615
        tree.commit(rev_id='origineel', message="message")
1616
        tree.commit(rev_id='nog-een-revisie', message="message")
1617
        tree.unlock()
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
1618
        self.assertEqual(
6280.3.2 by Jelmer Vernooij
Add smart side of RemoteRepository.all_revision_ids().
1619
            smart_req.SuccessfulSmartServerResponse(("ok", ),
1620
                "origineel\nnog-een-revisie"),
1621
            request.execute(''))
1622
1623
6280.4.2 by Jelmer Vernooij
Provide server side of Repository.break_lock HPSS call.
1624
class TestSmartServerRepositoryBreakLock(tests.TestCaseWithMemoryTransport):
1625
1626
    def test_lock_to_break(self):
1627
        backing = self.get_transport()
1628
        request = smart_repo.SmartServerRepositoryBreakLock(backing)
1629
        tree = self.make_branch_and_memory_tree('.')
1630
        tree.branch.repository.lock_write()
1631
        self.assertEqual(
1632
            smart_req.SuccessfulSmartServerResponse(('ok', ), None),
1633
            request.execute(''))
1634
1635
    def test_nothing_to_break(self):
1636
        backing = self.get_transport()
1637
        request = smart_repo.SmartServerRepositoryBreakLock(backing)
1638
        tree = self.make_branch_and_memory_tree('.')
1639
        self.assertEqual(
1640
            smart_req.SuccessfulSmartServerResponse(('ok', ), None),
1641
            request.execute(''))
1642
1643
3441.5.4 by Andrew Bennetts
Fix test failures, and add some tests for the remote graph heads RPC.
1644
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.
1645
3211.5.3 by Robert Collins
Adjust size of batch and change gzip comments to bzip2.
1646
    def test_trivial_bzipped(self):
1647
        # 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.
1648
        backing = self.get_transport()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1649
        request = smart_repo.SmartServerRepositoryGetParentMap(backing)
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.
1650
        tree = self.make_branch_and_memory_tree('.')
1651
1652
        self.assertEqual(None,
2692.1.24 by Andrew Bennetts
Merge from bzr.dev.
1653
            request.execute('', 'missing-id'))
4190.1.3 by Robert Collins
Allow optional inclusion of ghost data in server get_parent_map calls.
1654
        # 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.
1655
        self.assertEqual(
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1656
            smart_req.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.
1657
            request.do_body('\n\n0\n'))
1658
4190.1.3 by Robert Collins
Allow optional inclusion of ghost data in server get_parent_map calls.
1659
    def test_trivial_include_missing(self):
1660
        backing = self.get_transport()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1661
        request = smart_repo.SmartServerRepositoryGetParentMap(backing)
4190.1.3 by Robert Collins
Allow optional inclusion of ghost data in server get_parent_map calls.
1662
        tree = self.make_branch_and_memory_tree('.')
1663
1664
        self.assertEqual(None,
1665
            request.execute('', 'missing-id', 'include-missing:'))
1666
        self.assertEqual(
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1667
            smart_req.SuccessfulSmartServerResponse(('ok', ),
4190.1.3 by Robert Collins
Allow optional inclusion of ghost data in server get_parent_map calls.
1668
                bz2.compress('missing:missing-id')),
1669
            request.do_body('\n\n0\n'))
1670
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.
1671
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1672
class TestSmartServerRepositoryGetRevisionGraph(
1673
    tests.TestCaseWithMemoryTransport):
2018.5.67 by Wouter van Heyst
Implement RemoteRepository.get_revision_graph (Wouter van Heyst, Robert Collins)
1674
1675
    def test_none_argument(self):
1676
        backing = self.get_transport()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1677
        request = smart_repo.SmartServerRepositoryGetRevisionGraph(backing)
2018.5.67 by Wouter van Heyst
Implement RemoteRepository.get_revision_graph (Wouter van Heyst, Robert Collins)
1678
        tree = self.make_branch_and_memory_tree('.')
1679
        tree.lock_write()
1680
        tree.add('')
1681
        r1 = tree.commit('1st commit')
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
1682
        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)
1683
        tree.unlock()
1684
1685
        # the lines of revision_id->revision_parent_list has no guaranteed
1686
        # order coming out of a dict, so sort both our test and response
1687
        lines = sorted([' '.join([r2, r1]), r1])
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1688
        response = request.execute('', '')
2018.5.67 by Wouter van Heyst
Implement RemoteRepository.get_revision_graph (Wouter van Heyst, Robert Collins)
1689
        response.body = '\n'.join(sorted(response.body.split('\n')))
1690
2018.5.83 by Andrew Bennetts
Fix some test failures caused by the switch from unicode to UTF-8-encoded strs for revision IDs.
1691
        self.assertEqual(
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1692
            smart_req.SmartServerResponse(('ok', ), '\n'.join(lines)), response)
2018.5.67 by Wouter van Heyst
Implement RemoteRepository.get_revision_graph (Wouter van Heyst, Robert Collins)
1693
1694
    def test_specific_revision_argument(self):
1695
        backing = self.get_transport()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1696
        request = smart_repo.SmartServerRepositoryGetRevisionGraph(backing)
2018.5.67 by Wouter van Heyst
Implement RemoteRepository.get_revision_graph (Wouter van Heyst, Robert Collins)
1697
        tree = self.make_branch_and_memory_tree('.')
1698
        tree.lock_write()
1699
        tree.add('')
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
1700
        rev_id_utf8 = u'\xc9'.encode('utf-8')
1701
        r1 = tree.commit('1st commit', rev_id=rev_id_utf8)
1702
        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)
1703
        tree.unlock()
1704
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1705
        self.assertEqual(smart_req.SmartServerResponse(('ok', ), rev_id_utf8),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1706
            request.execute('', rev_id_utf8))
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
1707
2018.5.67 by Wouter van Heyst
Implement RemoteRepository.get_revision_graph (Wouter van Heyst, Robert Collins)
1708
    def test_no_such_revision(self):
1709
        backing = self.get_transport()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1710
        request = smart_repo.SmartServerRepositoryGetRevisionGraph(backing)
2018.5.67 by Wouter van Heyst
Implement RemoteRepository.get_revision_graph (Wouter van Heyst, Robert Collins)
1711
        tree = self.make_branch_and_memory_tree('.')
1712
        tree.lock_write()
1713
        tree.add('')
1714
        r1 = tree.commit('1st commit')
1715
        tree.unlock()
1716
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
1717
        # Note that it still returns body (of zero bytes).
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1718
        self.assertEqual(smart_req.SmartServerResponse(
1719
                ('nosuchrevision', 'missingrevision', ), ''),
1720
                         request.execute('', 'missingrevision'))
1721
1722
1723
class TestSmartServerRepositoryGetRevIdForRevno(
1724
    tests.TestCaseWithMemoryTransport):
4419.2.6 by Andrew Bennetts
Add tests for server-side logic, and fix the bugs exposed by those tests.
1725
1726
    def test_revno_found(self):
1727
        backing = self.get_transport()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1728
        request = smart_repo.SmartServerRepositoryGetRevIdForRevno(backing)
4419.2.6 by Andrew Bennetts
Add tests for server-side logic, and fix the bugs exposed by those tests.
1729
        tree = self.make_branch_and_memory_tree('.')
1730
        tree.lock_write()
1731
        tree.add('')
1732
        rev1_id_utf8 = u'\xc8'.encode('utf-8')
1733
        rev2_id_utf8 = u'\xc9'.encode('utf-8')
1734
        tree.commit('1st commit', rev_id=rev1_id_utf8)
1735
        tree.commit('2nd commit', rev_id=rev2_id_utf8)
1736
        tree.unlock()
1737
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1738
        self.assertEqual(smart_req.SmartServerResponse(('ok', rev1_id_utf8)),
4419.2.6 by Andrew Bennetts
Add tests for server-side logic, and fix the bugs exposed by those tests.
1739
            request.execute('', 1, (2, rev2_id_utf8)))
1740
1741
    def test_known_revid_missing(self):
1742
        backing = self.get_transport()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1743
        request = smart_repo.SmartServerRepositoryGetRevIdForRevno(backing)
4419.2.6 by Andrew Bennetts
Add tests for server-side logic, and fix the bugs exposed by those tests.
1744
        repo = self.make_repository('.')
1745
        self.assertEqual(
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1746
            smart_req.FailedSmartServerResponse(('nosuchrevision', 'ghost')),
4419.2.6 by Andrew Bennetts
Add tests for server-side logic, and fix the bugs exposed by those tests.
1747
            request.execute('', 1, (2, 'ghost')))
1748
1749
    def test_history_incomplete(self):
1750
        backing = self.get_transport()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1751
        request = smart_repo.SmartServerRepositoryGetRevIdForRevno(backing)
4419.2.6 by Andrew Bennetts
Add tests for server-side logic, and fix the bugs exposed by those tests.
1752
        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.
1753
        parent.lock_write()
1754
        parent.add([''], ['TREE_ROOT'])
4419.2.6 by Andrew Bennetts
Add tests for server-side logic, and fix the bugs exposed by those tests.
1755
        r1 = parent.commit(message='first commit')
1756
        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.
1757
        parent.unlock()
4419.2.6 by Andrew Bennetts
Add tests for server-side logic, and fix the bugs exposed by those tests.
1758
        local = self.make_branch_and_memory_tree('local', format='1.9')
1759
        local.branch.pull(parent.branch)
1760
        local.set_parent_ids([r2])
1761
        r3 = local.commit(message='local commit')
1762
        local.branch.create_clone_on_transport(
1763
            self.get_transport('stacked'), stacked_on=self.get_url('parent'))
1764
        self.assertEqual(
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1765
            smart_req.SmartServerResponse(('history-incomplete', 2, r2)),
4419.2.6 by Andrew Bennetts
Add tests for server-side logic, and fix the bugs exposed by those tests.
1766
            request.execute('stacked', 1, (3, r3)))
1767
4476.3.68 by Andrew Bennetts
Review comments from John.
1768
6280.9.2 by Jelmer Vernooij
Add smart side.
1769
class TestSmartServerRepositoryIterRevisions(
1770
    tests.TestCaseWithMemoryTransport):
1771
1772
    def test_basic(self):
1773
        backing = self.get_transport()
1774
        request = smart_repo.SmartServerRepositoryIterRevisions(backing)
1775
        tree = self.make_branch_and_memory_tree('.', format='2a')
1776
        tree.lock_write()
1777
        tree.add('')
1778
        tree.commit('1st commit', rev_id="rev1")
1779
        tree.commit('2nd commit', rev_id="rev2")
1780
        tree.unlock()
1781
1782
        self.assertIs(None, request.execute(''))
1783
        response = request.do_body("rev1\nrev2")
1784
        self.assertTrue(response.is_successful())
1785
        # Format 2a uses serializer format 10
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
1786
        self.assertEqual(response.args, ("ok", "10"))
6280.9.2 by Jelmer Vernooij
Add smart side.
1787
6280.9.4 by Jelmer Vernooij
use zlib instead.
1788
        self.addCleanup(tree.branch.lock_read().unlock)
1789
        entries = [zlib.compress(record.get_bytes_as("fulltext")) for record in
6280.9.2 by Jelmer Vernooij
Add smart side.
1790
            tree.branch.repository.revisions.get_record_stream(
1791
            [("rev1", ), ("rev2", )], "unordered", True)]
1792
1793
        contents = "".join(response.body_stream)
6280.9.4 by Jelmer Vernooij
use zlib instead.
1794
        self.assertTrue(contents in (
1795
            "".join([entries[0], entries[1]]),
1796
            "".join([entries[1], entries[0]])))
6280.9.2 by Jelmer Vernooij
Add smart side.
1797
1798
    def test_missing(self):
1799
        backing = self.get_transport()
1800
        request = smart_repo.SmartServerRepositoryIterRevisions(backing)
1801
        tree = self.make_branch_and_memory_tree('.', format='2a')
1802
1803
        self.assertIs(None, request.execute(''))
1804
        response = request.do_body("rev1\nrev2")
1805
        self.assertTrue(response.is_successful())
1806
        # Format 2a uses serializer format 10
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
1807
        self.assertEqual(response.args, ("ok", "10"))
6280.9.2 by Jelmer Vernooij
Add smart side.
1808
1809
        contents = "".join(response.body_stream)
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
1810
        self.assertEqual(contents, "")
6280.9.2 by Jelmer Vernooij
Add smart side.
1811
1812
5539.2.4 by Andrew Bennetts
Add some basic tests for the new verb, fix some shallow bugs.
1813
class GetStreamTestBase(tests.TestCaseWithMemoryTransport):
4070.9.14 by Andrew Bennetts
Tweaks requested by Robert's review.
1814
1815
    def make_two_commit_repo(self):
1816
        tree = self.make_branch_and_memory_tree('.')
1817
        tree.lock_write()
1818
        tree.add('')
1819
        r1 = tree.commit('1st commit')
1820
        r2 = tree.commit('2nd commit', rev_id=u'\xc8'.encode('utf-8'))
1821
        tree.unlock()
1822
        repo = tree.branch.repository
1823
        return repo, r1, r2
1824
5539.2.4 by Andrew Bennetts
Add some basic tests for the new verb, fix some shallow bugs.
1825
1826
class TestSmartServerRepositoryGetStream(GetStreamTestBase):
1827
4070.9.14 by Andrew Bennetts
Tweaks requested by Robert's review.
1828
    def test_ancestry_of(self):
1829
        """The search argument may be a 'ancestry-of' some heads'."""
1830
        backing = self.get_transport()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1831
        request = smart_repo.SmartServerRepositoryGetStream(backing)
4070.9.14 by Andrew Bennetts
Tweaks requested by Robert's review.
1832
        repo, r1, r2 = self.make_two_commit_repo()
1833
        fetch_spec = ['ancestry-of', r2]
1834
        lines = '\n'.join(fetch_spec)
1835
        request.execute('', repo._format.network_name())
1836
        response = request.do_body(lines)
1837
        self.assertEqual(('ok',), response.args)
1838
        stream_bytes = ''.join(response.body_stream)
1839
        self.assertStartsWith(stream_bytes, 'Bazaar pack format 1')
1840
1841
    def test_search(self):
1842
        """The search argument may be a 'search' of some explicit keys."""
1843
        backing = self.get_transport()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1844
        request = smart_repo.SmartServerRepositoryGetStream(backing)
4070.9.14 by Andrew Bennetts
Tweaks requested by Robert's review.
1845
        repo, r1, r2 = self.make_two_commit_repo()
1846
        fetch_spec = ['search', '%s %s' % (r1, r2), 'null:', '2']
1847
        lines = '\n'.join(fetch_spec)
1848
        request.execute('', repo._format.network_name())
1849
        response = request.do_body(lines)
1850
        self.assertEqual(('ok',), response.args)
1851
        stream_bytes = ''.join(response.body_stream)
1852
        self.assertStartsWith(stream_bytes, 'Bazaar pack format 1')
1853
5539.2.4 by Andrew Bennetts
Add some basic tests for the new verb, fix some shallow bugs.
1854
    def test_search_everything(self):
1855
        """A search of 'everything' returns a stream."""
1856
        backing = self.get_transport()
5539.2.14 by Andrew Bennetts
Don't add a new verb; instead just teach the client to fallback if it gets a BadSearch error.
1857
        request = smart_repo.SmartServerRepositoryGetStream_1_19(backing)
5539.2.4 by Andrew Bennetts
Add some basic tests for the new verb, fix some shallow bugs.
1858
        repo, r1, r2 = self.make_two_commit_repo()
1859
        serialised_fetch_spec = 'everything'
1860
        request.execute('', repo._format.network_name())
1861
        response = request.do_body(serialised_fetch_spec)
1862
        self.assertEqual(('ok',), response.args)
1863
        stream_bytes = ''.join(response.body_stream)
1864
        self.assertStartsWith(stream_bytes, 'Bazaar pack format 1')
1865
4070.9.14 by Andrew Bennetts
Tweaks requested by Robert's review.
1866
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1867
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).
1868
1869
    def test_missing_revision(self):
1870
        """For a missing revision, ('no', ) is returned."""
1871
        backing = self.get_transport()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1872
        request = smart_repo.SmartServerRequestHasRevision(backing)
2018.5.56 by Robert Collins
Factor out code we expect to be common in SmartServerRequestHasRevision to SmartServerRepositoryRequest (Robert Collins, Vincent Ladeuil).
1873
        self.make_repository('.')
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1874
        self.assertEqual(smart_req.SmartServerResponse(('no', )),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1875
            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).
1876
1877
    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.
1878
        """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).
1879
        backing = self.get_transport()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1880
        request = smart_repo.SmartServerRequestHasRevision(backing)
2018.5.56 by Robert Collins
Factor out code we expect to be common in SmartServerRequestHasRevision to SmartServerRepositoryRequest (Robert Collins, Vincent Ladeuil).
1881
        tree = self.make_branch_and_memory_tree('.')
1882
        tree.lock_write()
1883
        tree.add('')
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
1884
        rev_id_utf8 = u'\xc8abc'.encode('utf-8')
1885
        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).
1886
        tree.unlock()
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
1887
        self.assertTrue(tree.branch.repository.has_revision(rev_id_utf8))
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1888
        self.assertEqual(smart_req.SmartServerResponse(('yes', )),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1889
            request.execute('', rev_id_utf8))
1890
1891
6280.10.20 by Jelmer Vernooij
Convert smart to zlib.
1892
class TestSmartServerRepositoryIterFilesBytes(tests.TestCaseWithTransport):
6280.10.6 by Jelmer Vernooij
Convert to iter_files_bytes_bz2.
1893
1894
    def test_single(self):
1895
        backing = self.get_transport()
6280.10.20 by Jelmer Vernooij
Convert smart to zlib.
1896
        request = smart_repo.SmartServerRepositoryIterFilesBytes(backing)
6280.10.6 by Jelmer Vernooij
Convert to iter_files_bytes_bz2.
1897
        t = self.make_branch_and_tree('.')
1898
        self.addCleanup(t.lock_write().unlock)
1899
        self.build_tree_contents([("file", "somecontents")])
1900
        t.add(["file"], ["thefileid"])
1901
        t.commit(rev_id='somerev', message="add file")
1902
        self.assertIs(None, request.execute(''))
1903
        response = request.do_body("thefileid\0somerev\n")
6280.10.5 by Jelmer Vernooij
Support bz2 compression.
1904
        self.assertTrue(response.is_successful())
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
1905
        self.assertEqual(response.args, ("ok", ))
1906
        self.assertEqual("".join(response.body_stream),
6280.10.20 by Jelmer Vernooij
Convert smart to zlib.
1907
            "ok\x000\n" + zlib.compress("somecontents"))
6280.10.5 by Jelmer Vernooij
Support bz2 compression.
1908
6280.10.3 by Jelmer Vernooij
Fix iter_file_bytes.
1909
    def test_missing(self):
1910
        backing = self.get_transport()
6280.10.20 by Jelmer Vernooij
Convert smart to zlib.
1911
        request = smart_repo.SmartServerRepositoryIterFilesBytes(backing)
6280.10.3 by Jelmer Vernooij
Fix iter_file_bytes.
1912
        t = self.make_branch_and_tree('.')
1913
        self.addCleanup(t.lock_write().unlock)
6280.10.6 by Jelmer Vernooij
Convert to iter_files_bytes_bz2.
1914
        self.assertIs(None, request.execute(''))
1915
        response = request.do_body("thefileid\0revision\n")
1916
        self.assertTrue(response.is_successful())
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
1917
        self.assertEqual(response.args, ("ok", ))
1918
        self.assertEqual("".join(response.body_stream),
6280.10.12 by Jelmer Vernooij
Handle stacking.
1919
            "absent\x00thefileid\x00revision\x000\n")
6280.10.3 by Jelmer Vernooij
Fix iter_file_bytes.
1920
6280.10.2 by Jelmer Vernooij
Add Repository.iter_file_bytes.
1921
6265.1.1 by Jelmer Vernooij
Add new HPSS call ``Repository.has_signature_for_revision_id``.
1922
class TestSmartServerRequestHasSignatureForRevisionId(
1923
        tests.TestCaseWithMemoryTransport):
1924
1925
    def test_missing_revision(self):
1926
        """For a missing revision, NoSuchRevision is returned."""
1927
        backing = self.get_transport()
1928
        request = smart_repo.SmartServerRequestHasSignatureForRevisionId(
1929
            backing)
1930
        self.make_repository('.')
1931
        self.assertEqual(
1932
            smart_req.FailedSmartServerResponse(
6265.1.5 by Jelmer Vernooij
Fix capitalization - NoSuchRevision is for branches.
1933
                ('nosuchrevision', 'revid'), None),
6265.1.1 by Jelmer Vernooij
Add new HPSS call ``Repository.has_signature_for_revision_id``.
1934
            request.execute('', 'revid'))
1935
1936
    def test_missing_signature(self):
1937
        """For a missing signature, ('no', ) is returned."""
1938
        backing = self.get_transport()
1939
        request = smart_repo.SmartServerRequestHasSignatureForRevisionId(
1940
            backing)
1941
        tree = self.make_branch_and_memory_tree('.')
1942
        tree.lock_write()
1943
        tree.add('')
1944
        r1 = tree.commit('a commit', rev_id='A')
1945
        tree.unlock()
1946
        self.assertTrue(tree.branch.repository.has_revision('A'))
1947
        self.assertEqual(smart_req.SmartServerResponse(('no', )),
1948
            request.execute('', 'A'))
1949
1950
    def test_present_signature(self):
1951
        """For a present signature, ('yes', ) is returned."""
1952
        backing = self.get_transport()
1953
        request = smart_repo.SmartServerRequestHasSignatureForRevisionId(
1954
            backing)
1955
        strategy = gpg.LoopbackGPGStrategy(None)
1956
        tree = self.make_branch_and_memory_tree('.')
1957
        tree.lock_write()
1958
        tree.add('')
1959
        r1 = tree.commit('a commit', rev_id='A')
1960
        tree.branch.repository.start_write_group()
1961
        tree.branch.repository.sign_revision('A', strategy)
1962
        tree.branch.repository.commit_write_group()
1963
        tree.unlock()
1964
        self.assertTrue(tree.branch.repository.has_revision('A'))
1965
        self.assertEqual(smart_req.SmartServerResponse(('yes', )),
1966
            request.execute('', 'A'))
1967
1968
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1969
class TestSmartServerRepositoryGatherStats(tests.TestCaseWithMemoryTransport):
2018.10.2 by v.ladeuil+lp at free
gather_stats server side and request registration
1970
1971
    def test_empty_revid(self):
1972
        """With an empty revid, we get only size an number and revisions"""
1973
        backing = self.get_transport()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1974
        request = smart_repo.SmartServerRepositoryGatherStats(backing)
2018.10.2 by v.ladeuil+lp at free
gather_stats server side and request registration
1975
        repository = self.make_repository('.')
1976
        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.
1977
        expected_body = 'revisions: 0\n'
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1978
        self.assertEqual(smart_req.SmartServerResponse(('ok', ), expected_body),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
1979
                         request.execute('', '', 'no'))
2018.10.2 by v.ladeuil+lp at free
gather_stats server side and request registration
1980
1981
    def test_revid_with_committers(self):
1982
        """For a revid we get more infos."""
1983
        backing = self.get_transport()
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
1984
        rev_id_utf8 = u'\xc8abc'.encode('utf-8')
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1985
        request = smart_repo.SmartServerRepositoryGatherStats(backing)
2018.10.2 by v.ladeuil+lp at free
gather_stats server side and request registration
1986
        tree = self.make_branch_and_memory_tree('.')
1987
        tree.lock_write()
1988
        tree.add('')
1989
        # Let's build a predictable result
1990
        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.
1991
        tree.commit('a commit', timestamp=654321.4, timezone=0,
1992
                    rev_id=rev_id_utf8)
2018.10.2 by v.ladeuil+lp at free
gather_stats server side and request registration
1993
        tree.unlock()
1994
1995
        stats = tree.branch.repository.gather_stats()
1996
        expected_body = ('firstrev: 123456.200 3600\n'
1997
                         '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.
1998
                         'revisions: 2\n')
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
1999
        self.assertEqual(smart_req.SmartServerResponse(('ok', ), expected_body),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
2000
                         request.execute('',
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
2001
                                         rev_id_utf8, 'no'))
2018.10.2 by v.ladeuil+lp at free
gather_stats server side and request registration
2002
2003
    def test_not_empty_repository_with_committers(self):
2004
        """For a revid and requesting committers we get the whole thing."""
2005
        backing = self.get_transport()
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
2006
        rev_id_utf8 = u'\xc8abc'.encode('utf-8')
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2007
        request = smart_repo.SmartServerRepositoryGatherStats(backing)
2018.10.2 by v.ladeuil+lp at free
gather_stats server side and request registration
2008
        tree = self.make_branch_and_memory_tree('.')
2009
        tree.lock_write()
2010
        tree.add('')
2011
        # Let's build a predictable result
2012
        tree.commit('a commit', timestamp=123456.2, timezone=3600,
2013
                    committer='foo')
2014
        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.
2015
                    committer='bar', rev_id=rev_id_utf8)
2018.10.2 by v.ladeuil+lp at free
gather_stats server side and request registration
2016
        tree.unlock()
2017
        stats = tree.branch.repository.gather_stats()
2018
2019
        expected_body = ('committers: 2\n'
2020
                         'firstrev: 123456.200 3600\n'
2021
                         '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.
2022
                         'revisions: 2\n')
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2023
        self.assertEqual(smart_req.SmartServerResponse(('ok', ), expected_body),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
2024
                         request.execute('',
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
2025
                                         rev_id_utf8, 'yes'))
2018.10.2 by v.ladeuil+lp at free
gather_stats server side and request registration
2026
6291.1.1 by Jelmer Vernooij
Cope with missing revision ids being specified to
2027
    def test_unknown_revid(self):
2028
        """An unknown revision id causes a 'nosuchrevision' error."""
2029
        backing = self.get_transport()
2030
        request = smart_repo.SmartServerRepositoryGatherStats(backing)
2031
        repository = self.make_repository('.')
2032
        expected_body = 'revisions: 0\n'
2033
        self.assertEqual(
2034
            smart_req.FailedSmartServerResponse(
2035
                ('nosuchrevision', 'mia'), None),
2036
            request.execute('', 'mia', 'yes'))
2037
2018.10.2 by v.ladeuil+lp at free
gather_stats server side and request registration
2038
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
2039
class TestSmartServerRepositoryIsShared(tests.TestCaseWithMemoryTransport):
2018.5.57 by Robert Collins
Implement RemoteRepository.is_shared (Robert Collins, Vincent Ladeuil).
2040
2041
    def test_is_shared(self):
2042
        """For a shared repository, ('yes', ) is returned."""
2043
        backing = self.get_transport()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2044
        request = smart_repo.SmartServerRepositoryIsShared(backing)
2018.5.57 by Robert Collins
Implement RemoteRepository.is_shared (Robert Collins, Vincent Ladeuil).
2045
        self.make_repository('.', shared=True)
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2046
        self.assertEqual(smart_req.SmartServerResponse(('yes', )),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
2047
            request.execute('', ))
2018.5.57 by Robert Collins
Implement RemoteRepository.is_shared (Robert Collins, Vincent Ladeuil).
2048
2049
    def test_is_not_shared(self):
2018.5.58 by Wouter van Heyst
Small test fixes to reflect naming and documentation
2050
        """For a shared repository, ('no', ) is returned."""
2018.5.57 by Robert Collins
Implement RemoteRepository.is_shared (Robert Collins, Vincent Ladeuil).
2051
        backing = self.get_transport()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2052
        request = smart_repo.SmartServerRepositoryIsShared(backing)
2018.5.57 by Robert Collins
Implement RemoteRepository.is_shared (Robert Collins, Vincent Ladeuil).
2053
        self.make_repository('.', shared=False)
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2054
        self.assertEqual(smart_req.SmartServerResponse(('no', )),
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
2055
            request.execute('', ))
2056
2057
6263.3.2 by Jelmer Vernooij
Add new HPSS call 'Repository.get_revision_signature_text'.
2058
class TestSmartServerRepositoryGetRevisionSignatureText(
2059
        tests.TestCaseWithMemoryTransport):
2060
2061
    def test_get_signature(self):
2062
        backing = self.get_transport()
2063
        request = smart_repo.SmartServerRepositoryGetRevisionSignatureText(
2064
            backing)
2065
        bb = self.make_branch_builder('.')
2066
        bb.build_commit(rev_id='A')
2067
        repo = bb.get_branch().repository
2068
        strategy = gpg.LoopbackGPGStrategy(None)
2069
        self.addCleanup(repo.lock_write().unlock)
2070
        repo.start_write_group()
2071
        repo.sign_revision('A', strategy)
2072
        repo.commit_write_group()
2073
        expected_body = (
2074
            '-----BEGIN PSEUDO-SIGNED CONTENT-----\n' +
2075
            Testament.from_revision(repo, 'A').as_short_text() +
2076
            '-----END PSEUDO-SIGNED CONTENT-----\n')
2077
        self.assertEqual(
2078
            smart_req.SmartServerResponse(('ok', ), expected_body),
2079
            request.execute('', 'A'))
2080
2081
6263.2.1 by Jelmer Vernooij
Add hpss call ``Repository.make_working_trees``
2082
class TestSmartServerRepositoryMakeWorkingTrees(
2083
        tests.TestCaseWithMemoryTransport):
2084
2085
    def test_make_working_trees(self):
2086
        """For a repository with working trees, ('yes', ) is returned."""
2087
        backing = self.get_transport()
2088
        request = smart_repo.SmartServerRepositoryMakeWorkingTrees(backing)
2089
        r = self.make_repository('.')
2090
        r.set_make_working_trees(True)
2091
        self.assertEqual(smart_req.SmartServerResponse(('yes', )),
2092
            request.execute('', ))
2093
2094
    def test_is_not_shared(self):
2095
        """For a repository with working trees, ('no', ) is returned."""
2096
        backing = self.get_transport()
2097
        request = smart_repo.SmartServerRepositoryMakeWorkingTrees(backing)
2098
        r = self.make_repository('.')
2099
        r.set_make_working_trees(False)
2100
        self.assertEqual(smart_req.SmartServerResponse(('no', )),
2101
            request.execute('', ))
2102
2103
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
2104
class TestSmartServerRepositoryLockWrite(tests.TestCaseWithMemoryTransport):
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
2105
2106
    def test_lock_write_on_unlocked_repo(self):
2107
        backing = self.get_transport()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2108
        request = smart_repo.SmartServerRepositoryLockWrite(backing)
3015.2.12 by Robert Collins
Make test_smart use specific formats as needed to exercise locked and unlocked repositories.
2109
        repository = self.make_repository('.', format='knit')
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
2110
        response = request.execute('')
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
2111
        nonce = repository.control_files._lock.peek().get('nonce')
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2112
        self.assertEqual(smart_req.SmartServerResponse(('ok', nonce)), response)
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
2113
        # The repository is now locked.  Verify that with a new repository
2114
        # object.
2115
        new_repo = repository.bzrdir.open_repository()
2116
        self.assertRaises(errors.LockContention, new_repo.lock_write)
4327.1.10 by Vincent Ladeuil
Fix 10 more lock-related test failures.
2117
        # Cleanup
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2118
        request = smart_repo.SmartServerRepositoryUnlock(backing)
4327.1.10 by Vincent Ladeuil
Fix 10 more lock-related test failures.
2119
        response = request.execute('', nonce)
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
2120
2121
    def test_lock_write_on_locked_repo(self):
2122
        backing = self.get_transport()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2123
        request = smart_repo.SmartServerRepositoryLockWrite(backing)
3015.2.12 by Robert Collins
Make test_smart use specific formats as needed to exercise locked and unlocked repositories.
2124
        repository = self.make_repository('.', format='knit')
5200.3.3 by Robert Collins
Lock methods on ``Tree``, ``Branch`` and ``Repository`` are now
2125
        repo_token = repository.lock_write().repository_token
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
2126
        repository.leave_lock_in_place()
2127
        repository.unlock()
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
2128
        response = request.execute('')
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
2129
        self.assertEqual(
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2130
            smart_req.SmartServerResponse(('LockContention',)), response)
4327.1.10 by Vincent Ladeuil
Fix 10 more lock-related test failures.
2131
        # Cleanup
2132
        repository.lock_write(repo_token)
2133
        repository.dont_leave_lock_in_place()
2134
        repository.unlock()
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
2135
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.
2136
    def test_lock_write_on_readonly_transport(self):
2137
        backing = self.get_readonly_transport()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2138
        request = smart_repo.SmartServerRepositoryLockWrite(backing)
3015.2.12 by Robert Collins
Make test_smart use specific formats as needed to exercise locked and unlocked repositories.
2139
        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.
2140
        response = request.execute('')
2872.5.3 by Martin Pool
Pass back LockFailed from smart server lock methods
2141
        self.assertFalse(response.is_successful())
2142
        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.
2143
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
2144
4144.3.1 by Andrew Bennetts
Add Repository.insert_stream_locked server-side implementation, plus tests for server-side _translate_error.
2145
class TestInsertStreamBase(tests.TestCaseWithMemoryTransport):
2146
2147
    def make_empty_byte_stream(self, repo):
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2148
        byte_stream = smart_repo._stream_to_byte_stream([], repo._format)
4144.3.1 by Andrew Bennetts
Add Repository.insert_stream_locked server-side implementation, plus tests for server-side _translate_error.
2149
        return ''.join(byte_stream)
2150
2151
2152
class TestSmartServerRepositoryInsertStream(TestInsertStreamBase):
2153
2154
    def test_insert_stream_empty(self):
2155
        backing = self.get_transport()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2156
        request = smart_repo.SmartServerRepositoryInsertStream(backing)
4144.3.1 by Andrew Bennetts
Add Repository.insert_stream_locked server-side implementation, plus tests for server-side _translate_error.
2157
        repository = self.make_repository('.')
2158
        response = request.execute('', '')
2159
        self.assertEqual(None, response)
2160
        response = request.do_chunk(self.make_empty_byte_stream(repository))
2161
        self.assertEqual(None, response)
2162
        response = request.do_end()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2163
        self.assertEqual(smart_req.SmartServerResponse(('ok', )), response)
2164
4144.3.1 by Andrew Bennetts
Add Repository.insert_stream_locked server-side implementation, plus tests for server-side _translate_error.
2165
2166
class TestSmartServerRepositoryInsertStreamLocked(TestInsertStreamBase):
2167
2168
    def test_insert_stream_empty(self):
2169
        backing = self.get_transport()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2170
        request = smart_repo.SmartServerRepositoryInsertStreamLocked(
4144.3.1 by Andrew Bennetts
Add Repository.insert_stream_locked server-side implementation, plus tests for server-side _translate_error.
2171
            backing)
2172
        repository = self.make_repository('.', format='knit')
5200.3.3 by Robert Collins
Lock methods on ``Tree``, ``Branch`` and ``Repository`` are now
2173
        lock_token = repository.lock_write().repository_token
4144.3.1 by Andrew Bennetts
Add Repository.insert_stream_locked server-side implementation, plus tests for server-side _translate_error.
2174
        response = request.execute('', '', lock_token)
2175
        self.assertEqual(None, response)
2176
        response = request.do_chunk(self.make_empty_byte_stream(repository))
2177
        self.assertEqual(None, response)
2178
        response = request.do_end()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2179
        self.assertEqual(smart_req.SmartServerResponse(('ok', )), response)
4144.3.1 by Andrew Bennetts
Add Repository.insert_stream_locked server-side implementation, plus tests for server-side _translate_error.
2180
        repository.unlock()
2181
2182
    def test_insert_stream_with_wrong_lock_token(self):
2183
        backing = self.get_transport()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2184
        request = smart_repo.SmartServerRepositoryInsertStreamLocked(
4144.3.1 by Andrew Bennetts
Add Repository.insert_stream_locked server-side implementation, plus tests for server-side _translate_error.
2185
            backing)
2186
        repository = self.make_repository('.', format='knit')
5200.3.3 by Robert Collins
Lock methods on ``Tree``, ``Branch`` and ``Repository`` are now
2187
        lock_token = repository.lock_write().repository_token
4144.3.1 by Andrew Bennetts
Add Repository.insert_stream_locked server-side implementation, plus tests for server-side _translate_error.
2188
        self.assertRaises(
2189
            errors.TokenMismatch, request.execute, '', '', 'wrong-token')
2190
        repository.unlock()
2191
2192
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
2193
class TestSmartServerRepositoryUnlock(tests.TestCaseWithMemoryTransport):
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
2194
2195
    def test_unlock_on_locked_repo(self):
2196
        backing = self.get_transport()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2197
        request = smart_repo.SmartServerRepositoryUnlock(backing)
3015.2.12 by Robert Collins
Make test_smart use specific formats as needed to exercise locked and unlocked repositories.
2198
        repository = self.make_repository('.', format='knit')
5200.3.3 by Robert Collins
Lock methods on ``Tree``, ``Branch`` and ``Repository`` are now
2199
        token = repository.lock_write().repository_token
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
2200
        repository.leave_lock_in_place()
2201
        repository.unlock()
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
2202
        response = request.execute('', token)
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
2203
        self.assertEqual(
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2204
            smart_req.SmartServerResponse(('ok',)), response)
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
2205
        # The repository is now unlocked.  Verify that with a new repository
2206
        # object.
2207
        new_repo = repository.bzrdir.open_repository()
2208
        new_repo.lock_write()
2209
        new_repo.unlock()
2210
2211
    def test_unlock_on_unlocked_repo(self):
2212
        backing = self.get_transport()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2213
        request = smart_repo.SmartServerRepositoryUnlock(backing)
3015.2.12 by Robert Collins
Make test_smart use specific formats as needed to exercise locked and unlocked repositories.
2214
        repository = self.make_repository('.', format='knit')
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
2215
        response = request.execute('', 'some token')
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
2216
        self.assertEqual(
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2217
            smart_req.SmartServerResponse(('TokenMismatch',)), response)
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
2218
2219
6280.6.2 by Jelmer Vernooij
Add HPSS calls Repository.get_physical_lock_status and Branch.get_physical_lock_status.
2220
class TestSmartServerRepositoryGetPhysicalLockStatus(
6280.6.3 by Jelmer Vernooij
Fix test.
2221
    tests.TestCaseWithTransport):
6280.6.2 by Jelmer Vernooij
Add HPSS calls Repository.get_physical_lock_status and Branch.get_physical_lock_status.
2222
6280.6.3 by Jelmer Vernooij
Fix test.
2223
    def test_with_write_lock(self):
6280.6.2 by Jelmer Vernooij
Add HPSS calls Repository.get_physical_lock_status and Branch.get_physical_lock_status.
2224
        backing = self.get_transport()
2225
        repo = self.make_repository('.')
6280.6.3 by Jelmer Vernooij
Fix test.
2226
        self.addCleanup(repo.lock_write().unlock)
2227
        # lock_write() doesn't necessarily actually take a physical
2228
        # lock out.
2229
        if repo.get_physical_lock_status():
2230
            expected = 'yes'
2231
        else:
2232
            expected = 'no'
6280.6.2 by Jelmer Vernooij
Add HPSS calls Repository.get_physical_lock_status and Branch.get_physical_lock_status.
2233
        request_class = smart_repo.SmartServerRepositoryGetPhysicalLockStatus
2234
        request = request_class(backing)
6280.6.3 by Jelmer Vernooij
Fix test.
2235
        self.assertEqual(smart_req.SuccessfulSmartServerResponse((expected,)),
6280.6.2 by Jelmer Vernooij
Add HPSS calls Repository.get_physical_lock_status and Branch.get_physical_lock_status.
2236
            request.execute('', ))
2237
6280.6.3 by Jelmer Vernooij
Fix test.
2238
    def test_without_write_lock(self):
6280.6.2 by Jelmer Vernooij
Add HPSS calls Repository.get_physical_lock_status and Branch.get_physical_lock_status.
2239
        backing = self.get_transport()
2240
        repo = self.make_repository('.')
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
2241
        self.assertEqual(False, repo.get_physical_lock_status())
6280.6.2 by Jelmer Vernooij
Add HPSS calls Repository.get_physical_lock_status and Branch.get_physical_lock_status.
2242
        request_class = smart_repo.SmartServerRepositoryGetPhysicalLockStatus
2243
        request = request_class(backing)
2244
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(('no',)),
2245
            request.execute('', ))
2246
2247
6300.1.2 by Jelmer Vernooij
Add remote side of Repository.reconcile.
2248
class TestSmartServerRepositoryReconcile(tests.TestCaseWithTransport):
2249
2250
    def test_reconcile(self):
2251
        backing = self.get_transport()
2252
        repo = self.make_repository('.')
6300.1.7 by Jelmer Vernooij
Fix test.
2253
        token = repo.lock_write().repository_token
2254
        self.addCleanup(repo.unlock)
6300.1.2 by Jelmer Vernooij
Add remote side of Repository.reconcile.
2255
        request_class = smart_repo.SmartServerRepositoryReconcile
2256
        request = request_class(backing)
6300.1.4 by Jelmer Vernooij
Add reconcile results.
2257
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(
2258
            ('ok', ),
2259
             'garbage_inventories: 0\n'
2260
             'inconsistent_parents: 0\n'),
6300.1.7 by Jelmer Vernooij
Fix test.
2261
            request.execute('', token))
6300.1.2 by Jelmer Vernooij
Add remote side of Repository.reconcile.
2262
2263
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
2264
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.
2265
2266
    def test_is_readonly_no(self):
2267
        backing = self.get_transport()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2268
        request = smart_req.SmartServerIsReadonly(backing)
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.
2269
        response = request.execute()
2270
        self.assertEqual(
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2271
            smart_req.SmartServerResponse(('no',)), response)
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.
2272
2273
    def test_is_readonly_yes(self):
2274
        backing = self.get_readonly_transport()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2275
        request = smart_req.SmartServerIsReadonly(backing)
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.
2276
        response = request.execute()
2277
        self.assertEqual(
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2278
            smart_req.SmartServerResponse(('yes',)), response)
2279
2280
2281
class TestSmartServerRepositorySetMakeWorkingTrees(
2282
    tests.TestCaseWithMemoryTransport):
4017.3.4 by Robert Collins
Create a verb for Repository.set_make_working_trees.
2283
2284
    def test_set_false(self):
2285
        backing = self.get_transport()
2286
        repo = self.make_repository('.', shared=True)
2287
        repo.set_make_working_trees(True)
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2288
        request_class = smart_repo.SmartServerRepositorySetMakeWorkingTrees
4017.3.4 by Robert Collins
Create a verb for Repository.set_make_working_trees.
2289
        request = request_class(backing)
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2290
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(('ok',)),
4017.3.4 by Robert Collins
Create a verb for Repository.set_make_working_trees.
2291
            request.execute('', 'False'))
2292
        repo = repo.bzrdir.open_repository()
2293
        self.assertFalse(repo.make_working_trees())
2294
2295
    def test_set_true(self):
2296
        backing = self.get_transport()
2297
        repo = self.make_repository('.', shared=True)
2298
        repo.set_make_working_trees(False)
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2299
        request_class = smart_repo.SmartServerRepositorySetMakeWorkingTrees
4017.3.4 by Robert Collins
Create a verb for Repository.set_make_working_trees.
2300
        request = request_class(backing)
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2301
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(('ok',)),
4017.3.4 by Robert Collins
Create a verb for Repository.set_make_working_trees.
2302
            request.execute('', 'True'))
2303
        repo = repo.bzrdir.open_repository()
2304
        self.assertTrue(repo.make_working_trees())
2305
2306
6280.5.2 by Jelmer Vernooij
New HPSS call VersionedFileRepository.get_serializer_format.
2307
class TestSmartServerRepositoryGetSerializerFormat(
2308
    tests.TestCaseWithMemoryTransport):
2309
6280.5.4 by Jelmer Vernooij
Fix test name.
2310
    def test_get_serializer_format(self):
6280.5.2 by Jelmer Vernooij
New HPSS call VersionedFileRepository.get_serializer_format.
2311
        backing = self.get_transport()
2312
        repo = self.make_repository('.', format='2a')
2313
        request_class = smart_repo.SmartServerRepositoryGetSerializerFormat
2314
        request = request_class(backing)
2315
        self.assertEqual(
2316
            smart_req.SuccessfulSmartServerResponse(('ok', '10')),
2317
            request.execute(''))
2318
2319
6280.7.2 by Jelmer Vernooij
Add HPSS calls ``Repository.start_write_group``, ``Repository.abort_write_group`` and ``Repository.commit_write_group``.
2320
class TestSmartServerRepositoryWriteGroup(
2321
    tests.TestCaseWithMemoryTransport):
2322
2323
    def test_start_write_group(self):
2324
        backing = self.get_transport()
2325
        repo = self.make_repository('.')
2326
        lock_token = repo.lock_write().repository_token
2327
        self.addCleanup(repo.unlock)
2328
        request_class = smart_repo.SmartServerRepositoryStartWriteGroup
2329
        request = request_class(backing)
6280.7.9 by Jelmer Vernooij
test repositories with unsuspendable write groups.
2330
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(('ok', [])),
2331
            request.execute('', lock_token))
2332
2333
    def test_start_write_group_unsuspendable(self):
2334
        backing = self.get_transport()
2335
        repo = self.make_repository('.', format='knit')
2336
        lock_token = repo.lock_write().repository_token
2337
        self.addCleanup(repo.unlock)
2338
        request_class = smart_repo.SmartServerRepositoryStartWriteGroup
2339
        request = request_class(backing)
2340
        self.assertEqual(
2341
            smart_req.FailedSmartServerResponse(('UnsuspendableWriteGroup',)),
6280.7.2 by Jelmer Vernooij
Add HPSS calls ``Repository.start_write_group``, ``Repository.abort_write_group`` and ``Repository.commit_write_group``.
2342
            request.execute('', lock_token))
2343
2344
    def test_commit_write_group(self):
2345
        backing = self.get_transport()
2346
        repo = self.make_repository('.')
2347
        lock_token = repo.lock_write().repository_token
2348
        self.addCleanup(repo.unlock)
2349
        repo.start_write_group()
2350
        tokens = repo.suspend_write_group()
2351
        request_class = smart_repo.SmartServerRepositoryCommitWriteGroup
2352
        request = request_class(backing)
2353
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(('ok',)),
6280.7.4 by Jelmer Vernooij
pass write group tokens as list/tuple.
2354
            request.execute('', lock_token, tokens))
6280.7.2 by Jelmer Vernooij
Add HPSS calls ``Repository.start_write_group``, ``Repository.abort_write_group`` and ``Repository.commit_write_group``.
2355
2356
    def test_abort_write_group(self):
2357
        backing = self.get_transport()
2358
        repo = self.make_repository('.')
2359
        lock_token = repo.lock_write().repository_token
2360
        repo.start_write_group()
2361
        tokens = repo.suspend_write_group()
2362
        self.addCleanup(repo.unlock)
2363
        request_class = smart_repo.SmartServerRepositoryAbortWriteGroup
2364
        request = request_class(backing)
2365
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(('ok',)),
6280.7.5 by Jelmer Vernooij
Bunch of test fixes.
2366
            request.execute('', lock_token, tokens))
6280.7.2 by Jelmer Vernooij
Add HPSS calls ``Repository.start_write_group``, ``Repository.abort_write_group`` and ``Repository.commit_write_group``.
2367
6280.7.6 by Jelmer Vernooij
Fix remaining tests.
2368
    def test_check_write_group(self):
2369
        backing = self.get_transport()
2370
        repo = self.make_repository('.')
2371
        lock_token = repo.lock_write().repository_token
2372
        repo.start_write_group()
2373
        tokens = repo.suspend_write_group()
2374
        self.addCleanup(repo.unlock)
2375
        request_class = smart_repo.SmartServerRepositoryCheckWriteGroup
2376
        request = request_class(backing)
2377
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(('ok',)),
2378
            request.execute('', lock_token, tokens))
2379
2380
    def test_check_write_group_invalid(self):
2381
        backing = self.get_transport()
2382
        repo = self.make_repository('.')
2383
        lock_token = repo.lock_write().repository_token
2384
        self.addCleanup(repo.unlock)
2385
        request_class = smart_repo.SmartServerRepositoryCheckWriteGroup
2386
        request = request_class(backing)
2387
        self.assertEqual(smart_req.FailedSmartServerResponse(
2388
            ('UnresumableWriteGroup', ['random'],
2389
                'Malformed write group token')),
2390
            request.execute('', lock_token, ["random"]))
2391
6280.7.2 by Jelmer Vernooij
Add HPSS calls ``Repository.start_write_group``, ``Repository.abort_write_group`` and ``Repository.commit_write_group``.
2392
3801.1.4 by Andrew Bennetts
Add tests for autopack RPC.
2393
class TestSmartServerPackRepositoryAutopack(tests.TestCaseWithTransport):
2394
2395
    def make_repo_needing_autopacking(self, path='.'):
2396
        # Make a repo in need of autopacking.
2397
        tree = self.make_branch_and_tree('.', format='pack-0.92')
2398
        repo = tree.branch.repository
2399
        # monkey-patch the pack collection to disable autopacking
2400
        repo._pack_collection._max_pack_count = lambda count: count
2401
        for x in range(10):
2402
            tree.commit('commit %s' % x)
2403
        self.assertEqual(10, len(repo._pack_collection.names()))
2404
        del repo._pack_collection._max_pack_count
2405
        return repo
2406
2407
    def test_autopack_needed(self):
2408
        repo = self.make_repo_needing_autopacking()
4145.1.6 by Robert Collins
More test fallout, but all caught now.
2409
        repo.lock_write()
2410
        self.addCleanup(repo.unlock)
3801.1.4 by Andrew Bennetts
Add tests for autopack RPC.
2411
        backing = self.get_transport()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2412
        request = smart_packrepo.SmartServerPackRepositoryAutopack(
3801.1.4 by Andrew Bennetts
Add tests for autopack RPC.
2413
            backing)
2414
        response = request.execute('')
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2415
        self.assertEqual(smart_req.SmartServerResponse(('ok',)), response)
3801.1.4 by Andrew Bennetts
Add tests for autopack RPC.
2416
        repo._pack_collection.reload_pack_names()
2417
        self.assertEqual(1, len(repo._pack_collection.names()))
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
2418
3801.1.4 by Andrew Bennetts
Add tests for autopack RPC.
2419
    def test_autopack_not_needed(self):
2420
        tree = self.make_branch_and_tree('.', format='pack-0.92')
2421
        repo = tree.branch.repository
4145.1.6 by Robert Collins
More test fallout, but all caught now.
2422
        repo.lock_write()
2423
        self.addCleanup(repo.unlock)
3801.1.4 by Andrew Bennetts
Add tests for autopack RPC.
2424
        for x in range(9):
2425
            tree.commit('commit %s' % x)
2426
        backing = self.get_transport()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2427
        request = smart_packrepo.SmartServerPackRepositoryAutopack(
3801.1.4 by Andrew Bennetts
Add tests for autopack RPC.
2428
            backing)
2429
        response = request.execute('')
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2430
        self.assertEqual(smart_req.SmartServerResponse(('ok',)), response)
3801.1.4 by Andrew Bennetts
Add tests for autopack RPC.
2431
        repo._pack_collection.reload_pack_names()
2432
        self.assertEqual(9, len(repo._pack_collection.names()))
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
2433
3801.1.4 by Andrew Bennetts
Add tests for autopack RPC.
2434
    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.
2435
        """A request to autopack a non-pack repo is a no-op."""
3801.1.4 by Andrew Bennetts
Add tests for autopack RPC.
2436
        repo = self.make_repository('.', format='knit')
2437
        backing = self.get_transport()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2438
        request = smart_packrepo.SmartServerPackRepositoryAutopack(
3801.1.4 by Andrew Bennetts
Add tests for autopack RPC.
2439
            backing)
2440
        response = request.execute('')
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2441
        self.assertEqual(smart_req.SmartServerResponse(('ok',)), response)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
2442
3801.1.4 by Andrew Bennetts
Add tests for autopack RPC.
2443
4760.2.5 by Andrew Bennetts
Add some more tests.
2444
class TestSmartServerVfsGet(tests.TestCaseWithMemoryTransport):
2445
2446
    def test_unicode_path(self):
2447
        """VFS requests expect unicode paths to be escaped."""
2448
        filename = u'foo\N{INTERROBANG}'
2449
        filename_escaped = urlutils.escape(filename)
2450
        backing = self.get_transport()
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2451
        request = vfs.GetRequest(backing)
4760.2.5 by Andrew Bennetts
Add some more tests.
2452
        backing.put_bytes_non_atomic(filename_escaped, 'contents')
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2453
        self.assertEqual(smart_req.SmartServerResponse(('ok', ), 'contents'),
4760.2.5 by Andrew Bennetts
Add some more tests.
2454
            request.execute(filename_escaped))
2455
2456
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
2457
class TestHandlers(tests.TestCase):
2458
    """Tests for the request.request_handlers object."""
2459
3526.3.1 by Andrew Bennetts
Remove registrations of defunct HPSS verbs.
2460
    def test_all_registrations_exist(self):
2461
        """All registered request_handlers can be found."""
2462
        # If there's a typo in a register_lazy call, this loop will fail with
2463
        # an AttributeError.
5050.78.5 by John Arbash Meinel
Merge the 2.1-client-read-reconnect-819604 (bug #819604) to bzr-2.2
2464
        for key in smart_req.request_handlers.keys():
2465
            try:
2466
                item = smart_req.request_handlers.get(key)
2467
            except AttributeError, e:
2468
                raise AttributeError('failed to get %s: %s' % (key, e))
3526.3.1 by Andrew Bennetts
Remove registrations of defunct HPSS verbs.
2469
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
2470
    def assertHandlerEqual(self, verb, handler):
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2471
        self.assertEqual(smart_req.request_handlers.get(verb), handler)
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
2472
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
2473
    def test_registered_methods(self):
2474
        """Test that known methods are registered to the correct object."""
6280.4.4 by Jelmer Vernooij
Add Branch.break_lock.
2475
        self.assertHandlerEqual('Branch.break_lock',
2476
            smart_branch.SmartServerBranchBreakLock)
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
2477
        self.assertHandlerEqual('Branch.get_config_file',
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2478
            smart_branch.SmartServerBranchGetConfigFile)
6270.1.17 by Jelmer Vernooij
s/set_config_file/put_config_file.
2479
        self.assertHandlerEqual('Branch.put_config_file',
2480
            smart_branch.SmartServerBranchPutConfigFile)
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
2481
        self.assertHandlerEqual('Branch.get_parent',
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2482
            smart_branch.SmartServerBranchGetParent)
6280.6.2 by Jelmer Vernooij
Add HPSS calls Repository.get_physical_lock_status and Branch.get_physical_lock_status.
2483
        self.assertHandlerEqual('Branch.get_physical_lock_status',
2484
            smart_branch.SmartServerBranchRequestGetPhysicalLockStatus)
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
2485
        self.assertHandlerEqual('Branch.get_tags_bytes',
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2486
            smart_branch.SmartServerBranchGetTagsBytes)
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
2487
        self.assertHandlerEqual('Branch.lock_write',
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2488
            smart_branch.SmartServerBranchRequestLockWrite)
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
2489
        self.assertHandlerEqual('Branch.last_revision_info',
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2490
            smart_branch.SmartServerBranchRequestLastRevisionInfo)
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
2491
        self.assertHandlerEqual('Branch.revision_history',
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2492
            smart_branch.SmartServerRequestRevisionHistory)
6263.1.5 by Jelmer Vernooij
Test for presence of Branch.revision_id_to_revno verb.
2493
        self.assertHandlerEqual('Branch.revision_id_to_revno',
2494
            smart_branch.SmartServerBranchRequestRevisionIdToRevno)
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
2495
        self.assertHandlerEqual('Branch.set_config_option',
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2496
            smart_branch.SmartServerBranchRequestSetConfigOption)
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
2497
        self.assertHandlerEqual('Branch.set_last_revision',
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2498
            smart_branch.SmartServerBranchRequestSetLastRevision)
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
2499
        self.assertHandlerEqual('Branch.set_last_revision_info',
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2500
            smart_branch.SmartServerBranchRequestSetLastRevisionInfo)
4288.1.7 by Robert Collins
Add new remote server verb Branch.set_parent_location, dropping roundtrips further on push operations.
2501
        self.assertHandlerEqual('Branch.set_last_revision_ex',
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2502
            smart_branch.SmartServerBranchRequestSetLastRevisionEx)
4288.1.7 by Robert Collins
Add new remote server verb Branch.set_parent_location, dropping roundtrips further on push operations.
2503
        self.assertHandlerEqual('Branch.set_parent_location',
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2504
            smart_branch.SmartServerBranchRequestSetParentLocation)
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
2505
        self.assertHandlerEqual('Branch.unlock',
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2506
            smart_branch.SmartServerBranchRequestUnlock)
6266.4.2 by Jelmer Vernooij
Test for the presence of the BzrDir.destroy_branch verb.
2507
        self.assertHandlerEqual('BzrDir.destroy_branch',
6266.4.3 by Jelmer Vernooij
fix tests.
2508
            smart_dir.SmartServerBzrDirRequestDestroyBranch)
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
2509
        self.assertHandlerEqual('BzrDir.find_repository',
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2510
            smart_dir.SmartServerRequestFindRepositoryV1)
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
2511
        self.assertHandlerEqual('BzrDir.find_repositoryV2',
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2512
            smart_dir.SmartServerRequestFindRepositoryV2)
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
2513
        self.assertHandlerEqual('BzrDirFormat.initialize',
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2514
            smart_dir.SmartServerRequestInitializeBzrDir)
4436.1.1 by Andrew Bennetts
Rename BzrDirFormat.initialize_ex verb to BzrDirFormat.initialize_ex_1.16.
2515
        self.assertHandlerEqual('BzrDirFormat.initialize_ex_1.16',
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2516
            smart_dir.SmartServerRequestBzrDirInitializeEx)
6305.5.10 by Jelmer Vernooij
Move to BzrDir.checkout_metadir.
2517
        self.assertHandlerEqual('BzrDir.checkout_metadir',
2518
            smart_dir.SmartServerBzrDirRequestCheckoutMetaDir)
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
2519
        self.assertHandlerEqual('BzrDir.cloning_metadir',
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2520
            smart_dir.SmartServerBzrDirRequestCloningMetaDir)
6436.3.2 by Jelmer Vernooij
Add HPSS call for BzrDir.get_branches.
2521
        self.assertHandlerEqual('BzrDir.get_branches',
2522
            smart_dir.SmartServerBzrDirRequestGetBranches)
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
2523
        self.assertHandlerEqual('BzrDir.get_config_file',
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2524
            smart_dir.SmartServerBzrDirRequestConfigFile)
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
2525
        self.assertHandlerEqual('BzrDir.open_branch',
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2526
            smart_dir.SmartServerRequestOpenBranch)
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
2527
        self.assertHandlerEqual('BzrDir.open_branchV2',
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2528
            smart_dir.SmartServerRequestOpenBranchV2)
4734.4.8 by Andrew Bennetts
Fix HPSS tests; pass 'location is a repository' message via smart server when possible (adds BzrDir.open_branchV3 verb).
2529
        self.assertHandlerEqual('BzrDir.open_branchV3',
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2530
            smart_dir.SmartServerRequestOpenBranchV3)
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
2531
        self.assertHandlerEqual('PackRepository.autopack',
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2532
            smart_packrepo.SmartServerPackRepositoryAutopack)
6268.1.2 by Jelmer Vernooij
Initial work on Repository.add_signature_text.
2533
        self.assertHandlerEqual('Repository.add_signature_text',
2534
            smart_repo.SmartServerRepositoryAddSignatureText)
6280.3.2 by Jelmer Vernooij
Add smart side of RemoteRepository.all_revision_ids().
2535
        self.assertHandlerEqual('Repository.all_revision_ids',
2536
            smart_repo.SmartServerRepositoryAllRevisionIds)
6280.4.2 by Jelmer Vernooij
Provide server side of Repository.break_lock HPSS call.
2537
        self.assertHandlerEqual('Repository.break_lock',
2538
            smart_repo.SmartServerRepositoryBreakLock)
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
2539
        self.assertHandlerEqual('Repository.gather_stats',
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2540
            smart_repo.SmartServerRepositoryGatherStats)
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
2541
        self.assertHandlerEqual('Repository.get_parent_map',
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2542
            smart_repo.SmartServerRepositoryGetParentMap)
6280.6.2 by Jelmer Vernooij
Add HPSS calls Repository.get_physical_lock_status and Branch.get_physical_lock_status.
2543
        self.assertHandlerEqual('Repository.get_physical_lock_status',
2544
            smart_repo.SmartServerRepositoryGetPhysicalLockStatus)
4419.2.6 by Andrew Bennetts
Add tests for server-side logic, and fix the bugs exposed by those tests.
2545
        self.assertHandlerEqual('Repository.get_rev_id_for_revno',
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2546
            smart_repo.SmartServerRepositoryGetRevIdForRevno)
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
2547
        self.assertHandlerEqual('Repository.get_revision_graph',
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2548
            smart_repo.SmartServerRepositoryGetRevisionGraph)
6263.3.3 by Jelmer Vernooij
Add test for presence.
2549
        self.assertHandlerEqual('Repository.get_revision_signature_text',
2550
            smart_repo.SmartServerRepositoryGetRevisionSignatureText)
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
2551
        self.assertHandlerEqual('Repository.get_stream',
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2552
            smart_repo.SmartServerRepositoryGetStream)
5539.2.4 by Andrew Bennetts
Add some basic tests for the new verb, fix some shallow bugs.
2553
        self.assertHandlerEqual('Repository.get_stream_1.19',
2554
            smart_repo.SmartServerRepositoryGetStream_1_19)
6280.9.2 by Jelmer Vernooij
Add smart side.
2555
        self.assertHandlerEqual('Repository.iter_revisions',
2556
            smart_repo.SmartServerRepositoryIterRevisions)
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
2557
        self.assertHandlerEqual('Repository.has_revision',
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2558
            smart_repo.SmartServerRequestHasRevision)
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
2559
        self.assertHandlerEqual('Repository.insert_stream',
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2560
            smart_repo.SmartServerRepositoryInsertStream)
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
2561
        self.assertHandlerEqual('Repository.insert_stream_locked',
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2562
            smart_repo.SmartServerRepositoryInsertStreamLocked)
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
2563
        self.assertHandlerEqual('Repository.is_shared',
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2564
            smart_repo.SmartServerRepositoryIsShared)
6280.10.20 by Jelmer Vernooij
Convert smart to zlib.
2565
        self.assertHandlerEqual('Repository.iter_files_bytes',
2566
            smart_repo.SmartServerRepositoryIterFilesBytes)
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
2567
        self.assertHandlerEqual('Repository.lock_write',
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2568
            smart_repo.SmartServerRepositoryLockWrite)
6263.2.1 by Jelmer Vernooij
Add hpss call ``Repository.make_working_trees``
2569
        self.assertHandlerEqual('Repository.make_working_trees',
2570
            smart_repo.SmartServerRepositoryMakeWorkingTrees)
6305.2.2 by Jelmer Vernooij
Add smart side of pack.
2571
        self.assertHandlerEqual('Repository.pack',
2572
            smart_repo.SmartServerRepositoryPack)
6300.1.2 by Jelmer Vernooij
Add remote side of Repository.reconcile.
2573
        self.assertHandlerEqual('Repository.reconcile',
2574
            smart_repo.SmartServerRepositoryReconcile)
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
2575
        self.assertHandlerEqual('Repository.tarball',
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2576
            smart_repo.SmartServerRepositoryTarball)
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
2577
        self.assertHandlerEqual('Repository.unlock',
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2578
            smart_repo.SmartServerRepositoryUnlock)
6280.7.2 by Jelmer Vernooij
Add HPSS calls ``Repository.start_write_group``, ``Repository.abort_write_group`` and ``Repository.commit_write_group``.
2579
        self.assertHandlerEqual('Repository.start_write_group',
2580
            smart_repo.SmartServerRepositoryStartWriteGroup)
6280.7.10 by Jelmer Vernooij
add test for existing of Repository.check_write_group.
2581
        self.assertHandlerEqual('Repository.check_write_group',
2582
            smart_repo.SmartServerRepositoryCheckWriteGroup)
6280.7.2 by Jelmer Vernooij
Add HPSS calls ``Repository.start_write_group``, ``Repository.abort_write_group`` and ``Repository.commit_write_group``.
2583
        self.assertHandlerEqual('Repository.commit_write_group',
2584
            smart_repo.SmartServerRepositoryCommitWriteGroup)
2585
        self.assertHandlerEqual('Repository.abort_write_group',
2586
            smart_repo.SmartServerRepositoryAbortWriteGroup)
6280.5.2 by Jelmer Vernooij
New HPSS call VersionedFileRepository.get_serializer_format.
2587
        self.assertHandlerEqual('VersionedFileRepository.get_serializer_format',
2588
            smart_repo.SmartServerRepositoryGetSerializerFormat)
6282.6.28 by Jelmer Vernooij
Rename VersionedFileRepository.iter_inventories to VersionedFileRepository.get_inventories.
2589
        self.assertHandlerEqual('VersionedFileRepository.get_inventories',
2590
            smart_repo.SmartServerRepositoryGetInventories)
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
2591
        self.assertHandlerEqual('Transport.is_readonly',
5010.2.8 by Vincent Ladeuil
Fix test_smart.py imports.
2592
            smart_req.SmartServerIsReadonly)
5611.1.2 by Jelmer Vernooij
Add some tests for the hooks.
2593
2594
2595
class SmartTCPServerHookTests(tests.TestCaseWithMemoryTransport):
2596
    """Tests for SmartTCPServer hooks."""
2597
2598
    def setUp(self):
2599
        super(SmartTCPServerHookTests, self).setUp()
2600
        self.server = server.SmartTCPServer(self.get_transport())
2601
2602
    def test_run_server_started_hooks(self):
2603
        """Test the server started hooks get fired properly."""
2604
        started_calls = []
2605
        server.SmartTCPServer.hooks.install_named_hook('server_started',
2606
            lambda backing_urls, url: started_calls.append((backing_urls, url)),
2607
            None)
2608
        started_ex_calls = []
2609
        server.SmartTCPServer.hooks.install_named_hook('server_started_ex',
2610
            lambda backing_urls, url: started_ex_calls.append((backing_urls, url)),
2611
            None)
5611.1.3 by Jelmer Vernooij
review comments from Vincent.
2612
        self.server._sockname = ('example.com', 42)
5611.1.2 by Jelmer Vernooij
Add some tests for the hooks.
2613
        self.server.run_server_started_hooks()
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
2614
        self.assertEqual(started_calls,
5611.1.3 by Jelmer Vernooij
review comments from Vincent.
2615
            [([self.get_transport().base], 'bzr://example.com:42/')])
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
2616
        self.assertEqual(started_ex_calls,
5611.1.2 by Jelmer Vernooij
Add some tests for the hooks.
2617
            [([self.get_transport().base], self.server)])
2618
2619
    def test_run_server_started_hooks_ipv6(self):
2620
        """Test that socknames can contain 4-tuples."""
2621
        self.server._sockname = ('::', 42, 0, 0)
2622
        started_calls = []
2623
        server.SmartTCPServer.hooks.install_named_hook('server_started',
2624
            lambda backing_urls, url: started_calls.append((backing_urls, url)),
2625
            None)
2626
        self.server.run_server_started_hooks()
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
2627
        self.assertEqual(started_calls,
5611.1.2 by Jelmer Vernooij
Add some tests for the hooks.
2628
                [([self.get_transport().base], 'bzr://:::42/')])
2629
2630
    def test_run_server_stopped_hooks(self):
2631
        """Test the server stopped hooks."""
5611.1.3 by Jelmer Vernooij
review comments from Vincent.
2632
        self.server._sockname = ('example.com', 42)
5611.1.2 by Jelmer Vernooij
Add some tests for the hooks.
2633
        stopped_calls = []
2634
        server.SmartTCPServer.hooks.install_named_hook('server_stopped',
2635
            lambda backing_urls, url: stopped_calls.append((backing_urls, url)),
2636
            None)
2637
        self.server.run_server_stopped_hooks()
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
2638
        self.assertEqual(stopped_calls,
5611.1.3 by Jelmer Vernooij
review comments from Vincent.
2639
            [([self.get_transport().base], 'bzr://example.com:42/')])
6305.2.2 by Jelmer Vernooij
Add smart side of pack.
2640
2641
2642
class TestSmartServerRepositoryPack(tests.TestCaseWithMemoryTransport):
2643
2644
    def test_pack(self):
2645
        backing = self.get_transport()
2646
        request = smart_repo.SmartServerRepositoryPack(backing)
2647
        tree = self.make_branch_and_memory_tree('.')
6305.2.4 by Jelmer Vernooij
Fix tests.
2648
        repo_token = tree.branch.repository.lock_write().repository_token
6305.2.2 by Jelmer Vernooij
Add smart side of pack.
2649
6305.2.4 by Jelmer Vernooij
Fix tests.
2650
        self.assertIs(None, request.execute('', repo_token, False))
6305.2.3 by Jelmer Vernooij
Store hint in body.
2651
6305.2.2 by Jelmer Vernooij
Add smart side of pack.
2652
        self.assertEqual(
2653
            smart_req.SuccessfulSmartServerResponse(('ok', ), ),
6305.2.3 by Jelmer Vernooij
Store hint in body.
2654
            request.do_body(''))
6305.2.2 by Jelmer Vernooij
Add smart side of pack.
2655
6282.6.7 by Jelmer Vernooij
Add basic server side test.
2656
6282.6.28 by Jelmer Vernooij
Rename VersionedFileRepository.iter_inventories to VersionedFileRepository.get_inventories.
2657
class TestSmartServerRepositoryGetInventories(tests.TestCaseWithTransport):
6282.6.7 by Jelmer Vernooij
Add basic server side test.
2658
2659
    def _get_serialized_inventory_delta(self, repository, base_revid, revid):
6405.2.10 by Jelmer Vernooij
Fix more tests.
2660
        base_inv = repository.revision_tree(base_revid).root_inventory
2661
        inv = repository.revision_tree(revid).root_inventory
6282.6.7 by Jelmer Vernooij
Add basic server side test.
2662
        inv_delta = inv._make_delta(base_inv)
2663
        serializer = inventory_delta.InventoryDeltaSerializer(True, False)
2664
        return "".join(serializer.delta_to_lines(base_revid, revid, inv_delta))
2665
2666
    def test_single(self):
2667
        backing = self.get_transport()
6282.6.28 by Jelmer Vernooij
Rename VersionedFileRepository.iter_inventories to VersionedFileRepository.get_inventories.
2668
        request = smart_repo.SmartServerRepositoryGetInventories(backing)
6282.6.36 by Jelmer Vernooij
Fix smart server tests.
2669
        t = self.make_branch_and_tree('.', format='2a')
6282.6.7 by Jelmer Vernooij
Add basic server side test.
2670
        self.addCleanup(t.lock_write().unlock)
2671
        self.build_tree_contents([("file", "somecontents")])
2672
        t.add(["file"], ["thefileid"])
2673
        t.commit(rev_id='somerev', message="add file")
2674
        self.assertIs(None, request.execute('', 'unordered'))
2675
        response = request.do_body("somerev\n")
2676
        self.assertTrue(response.is_successful())
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
2677
        self.assertEqual(response.args, ("ok", ))
6282.6.43 by Jelmer Vernooij
Fix stream name.
2678
        stream = [('inventory-deltas', [
6282.6.37 by Jelmer Vernooij
Cope with empty results.
2679
            versionedfile.FulltextContentFactory('somerev', None, None,
2680
                self._get_serialized_inventory_delta(
2681
                    t.branch.repository, 'null:', 'somerev'))])]
6472.2.1 by Jelmer Vernooij
Use bzrdir.controldir for generic access to control directories.
2682
        fmt = controldir.format_registry.get('2a')().repository_format
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
2683
        self.assertEqual(
6282.6.7 by Jelmer Vernooij
Add basic server side test.
2684
            "".join(response.body_stream),
6282.6.36 by Jelmer Vernooij
Fix smart server tests.
2685
            "".join(smart_repo._stream_to_byte_stream(stream, fmt)))
6282.6.10 by Jelmer Vernooij
Fix smart tests.
2686
2687
    def test_empty(self):
2688
        backing = self.get_transport()
6282.6.28 by Jelmer Vernooij
Rename VersionedFileRepository.iter_inventories to VersionedFileRepository.get_inventories.
2689
        request = smart_repo.SmartServerRepositoryGetInventories(backing)
6282.6.33 by Jelmer Vernooij
Fix some tests.
2690
        t = self.make_branch_and_tree('.', format='2a')
6282.6.10 by Jelmer Vernooij
Fix smart tests.
2691
        self.addCleanup(t.lock_write().unlock)
2692
        self.build_tree_contents([("file", "somecontents")])
2693
        t.add(["file"], ["thefileid"])
2694
        t.commit(rev_id='somerev', message="add file")
2695
        self.assertIs(None, request.execute('', 'unordered'))
2696
        response = request.do_body("")
2697
        self.assertTrue(response.is_successful())
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
2698
        self.assertEqual(response.args, ("ok", ))
2699
        self.assertEqual("".join(response.body_stream),
6282.6.33 by Jelmer Vernooij
Fix some tests.
2700
            "Bazaar pack format 1 (introduced in 0.18)\nB54\n\nBazaar repository format 2a (needs bzr 1.16 or later)\nE")