/brz/remove-bazaar

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