~bzr-pqm/bzr/bzr.dev

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