/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
2018.5.51 by Wouter van Heyst
Test and implement RemoteBranch.last_revision_info()
1
# Copyright (C) 2006, 2007 Canonical Ltd
1752.2.30 by Martin Pool
Start adding a RemoteBzrDir, etc
2
#
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
17
"""Tests for remote bzrdir/branch/repo/etc
18
19
These are proxy objects which act on remote objects by sending messages
20
through a smart client.  The proxies are to be created when attempting to open
21
the object given a transport that supports smartserver rpc operations. 
2018.18.7 by Martin Pool
(broken) Start addng client proxy test for Repository.tarball
22
23
These tests correspond to tests.test_smart, which exercises the server side.
1752.2.30 by Martin Pool
Start adding a RemoteBzrDir, etc
24
"""
25
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
26
from cStringIO import StringIO
27
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
28
from bzrlib import (
29
    bzrdir,
30
    errors,
31
    remote,
2018.18.9 by Martin Pool
remote Repository.tarball builds a temporary directory and tars that
32
    repository,
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
33
    tests,
34
    )
2018.5.51 by Wouter van Heyst
Test and implement RemoteBranch.last_revision_info()
35
from bzrlib.branch import Branch
36
from bzrlib.bzrdir import BzrDir, BzrDirFormat
37
from bzrlib.remote import (
38
    RemoteBranch,
39
    RemoteBzrDir,
40
    RemoteBzrDirFormat,
2018.5.57 by Robert Collins
Implement RemoteRepository.is_shared (Robert Collins, Vincent Ladeuil).
41
    RemoteRepository,
2018.5.51 by Wouter van Heyst
Test and implement RemoteBranch.last_revision_info()
42
    )
43
from bzrlib.revision import NULL_REVISION
2432.3.2 by Andrew Bennetts
Add test, and tidy implementation.
44
from bzrlib.smart import server, medium
2018.5.159 by Andrew Bennetts
Rename SmartClient to _SmartClient.
45
from bzrlib.smart.client import _SmartClient
2018.5.51 by Wouter van Heyst
Test and implement RemoteBranch.last_revision_info()
46
from bzrlib.transport.memory import MemoryTransport
2466.2.2 by Andrew Bennetts
Add tests for RemoteTransport.is_readonly in the style of the other remote object tests.
47
from bzrlib.transport.remote import RemoteTransport
1752.2.30 by Martin Pool
Start adding a RemoteBzrDir, etc
48
2018.5.24 by Andrew Bennetts
Setting NO_SMART_VFS in environment will disable VFS methods in the smart server. (Robert Collins, John Arbash Meinel, Andrew Bennetts)
49
2018.5.42 by Robert Collins
Various hopefully improvements, but wsgi is broken, handing over to spiv :).
50
class BasicRemoteObjectTests(tests.TestCaseWithTransport):
1752.2.30 by Martin Pool
Start adding a RemoteBzrDir, etc
51
52
    def setUp(self):
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.
53
        self.transport_server = server.SmartTCPServer_for_testing
2018.5.42 by Robert Collins
Various hopefully improvements, but wsgi is broken, handing over to spiv :).
54
        super(BasicRemoteObjectTests, self).setUp()
55
        self.transport = self.get_transport()
1752.2.30 by Martin Pool
Start adding a RemoteBzrDir, etc
56
        self.client = self.transport.get_smart_client()
57
        # make a branch that can be opened over the smart transport
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
58
        self.local_wt = BzrDir.create_standalone_workingtree('.')
1752.2.30 by Martin Pool
Start adding a RemoteBzrDir, etc
59
2018.5.171 by Andrew Bennetts
Disconnect RemoteTransports in some tests to avoid tripping up test_strace with leftover threads from previous tests.
60
    def tearDown(self):
61
        self.transport.disconnect()
62
        tests.TestCaseWithTransport.tearDown(self)
63
1752.2.30 by Martin Pool
Start adding a RemoteBzrDir, etc
64
    def test_create_remote_bzrdir(self):
65
        b = remote.RemoteBzrDir(self.transport)
66
        self.assertIsInstance(b, BzrDir)
67
68
    def test_open_remote_branch(self):
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
69
        # open a standalone branch in the working directory
1752.2.30 by Martin Pool
Start adding a RemoteBzrDir, etc
70
        b = remote.RemoteBzrDir(self.transport)
71
        branch = b.open_branch()
2018.5.163 by Andrew Bennetts
Deal with various review comments from Robert.
72
        self.assertIsInstance(branch, Branch)
1752.2.30 by Martin Pool
Start adding a RemoteBzrDir, etc
73
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
74
    def test_remote_repository(self):
75
        b = BzrDir.open_from_transport(self.transport)
76
        repo = b.open_repository()
2018.5.106 by Andrew Bennetts
Update tests in test_remote to use utf-8 byte strings for revision IDs, rather than unicode strings.
77
        revid = u'\xc823123123'.encode('utf8')
2018.5.40 by Robert Collins
Implement a remote Repository.has_revision method.
78
        self.assertFalse(repo.has_revision(revid))
79
        self.local_wt.commit(message='test commit', rev_id=revid)
80
        self.assertTrue(repo.has_revision(revid))
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
81
82
    def test_remote_branch_revision_history(self):
83
        b = BzrDir.open_from_transport(self.transport).open_branch()
2018.5.38 by Robert Collins
Implement RemoteBranch.revision_history().
84
        self.assertEqual([], b.revision_history())
85
        r1 = self.local_wt.commit('1st commit')
2018.5.106 by Andrew Bennetts
Update tests in test_remote to use utf-8 byte strings for revision IDs, rather than unicode strings.
86
        r2 = self.local_wt.commit('1st commit', rev_id=u'\xc8'.encode('utf8'))
2018.5.38 by Robert Collins
Implement RemoteBranch.revision_history().
87
        self.assertEqual([r1, r2], b.revision_history())
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
88
1752.2.30 by Martin Pool
Start adding a RemoteBzrDir, etc
89
    def test_find_correct_format(self):
2018.5.20 by Andrew Bennetts
Move bzrlib/transport/smart/_smart.py to bzrlib/transport/remote.py and rename SmartTransport to RemoteTransport (Robert Collins, Andrew Bennetts)
90
        """Should open a RemoteBzrDir over a RemoteTransport"""
1752.2.30 by Martin Pool
Start adding a RemoteBzrDir, etc
91
        fmt = BzrDirFormat.find_format(self.transport)
2018.5.169 by Andrew Bennetts
Add a _server_formats flag to BzrDir.open_from_transport and BzrDirFormat.find_format, make RemoteBranch.control_files into a property.
92
        self.assertTrue(RemoteBzrDirFormat
93
                        in BzrDirFormat._control_server_formats)
1752.2.30 by Martin Pool
Start adding a RemoteBzrDir, etc
94
        self.assertIsInstance(fmt, remote.RemoteBzrDirFormat)
95
96
    def test_open_detected_smart_format(self):
97
        fmt = BzrDirFormat.find_format(self.transport)
98
        d = fmt.open(self.transport)
99
        self.assertIsInstance(d, BzrDir)
2018.5.51 by Wouter van Heyst
Test and implement RemoteBranch.last_revision_info()
100
101
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
102
class FakeProtocol(object):
103
    """Lookalike SmartClientRequestProtocolOne allowing body reading tests."""
104
105
    def __init__(self, body):
106
        self._body_buffer = StringIO(body)
107
108
    def read_body_bytes(self, count=-1):
109
        return self._body_buffer.read(count)
110
111
2018.5.159 by Andrew Bennetts
Rename SmartClient to _SmartClient.
112
class FakeClient(_SmartClient):
113
    """Lookalike for _SmartClient allowing testing."""
2018.5.51 by Wouter van Heyst
Test and implement RemoteBranch.last_revision_info()
114
    
115
    def __init__(self, responses):
116
        # We don't call the super init because there is no medium.
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
117
        """create a FakeClient.
118
119
        :param respones: A list of response-tuple, body-data pairs to be sent
120
            back to callers.
121
        """
2018.5.51 by Wouter van Heyst
Test and implement RemoteBranch.last_revision_info()
122
        self.responses = responses
123
        self._calls = []
124
125
    def call(self, method, *args):
126
        self._calls.append(('call', method, args))
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
127
        return self.responses.pop(0)[0]
128
2018.5.153 by Andrew Bennetts
Rename call2 to call_expecting_body, and other small changes prompted by review.
129
    def call_expecting_body(self, method, *args):
130
        self._calls.append(('call_expecting_body', method, args))
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
131
        result = self.responses.pop(0)
132
        return result[0], FakeProtocol(result[1])
2018.5.51 by Wouter van Heyst
Test and implement RemoteBranch.last_revision_info()
133
134
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
135
class TestBzrDirOpenBranch(tests.TestCase):
136
137
    def test_branch_present(self):
2018.5.166 by Andrew Bennetts
Small changes in response to Aaron's review.
138
        client = FakeClient([(('ok', ''), ), (('ok', '', 'no', 'no'), )])
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
139
        transport = MemoryTransport()
140
        transport.mkdir('quack')
141
        transport = transport.clone('quack')
142
        bzrdir = RemoteBzrDir(transport, _client=client)
143
        result = bzrdir.open_branch()
144
        self.assertEqual(
145
            [('call', 'BzrDir.open_branch', ('///quack/',)),
146
             ('call', 'BzrDir.find_repository', ('///quack/',))],
147
            client._calls)
148
        self.assertIsInstance(result, RemoteBranch)
149
        self.assertEqual(bzrdir, result.bzrdir)
150
151
    def test_branch_missing(self):
152
        client = FakeClient([(('nobranch',), )])
153
        transport = MemoryTransport()
154
        transport.mkdir('quack')
155
        transport = transport.clone('quack')
156
        bzrdir = RemoteBzrDir(transport, _client=client)
157
        self.assertRaises(errors.NotBranchError, bzrdir.open_branch)
158
        self.assertEqual(
159
            [('call', 'BzrDir.open_branch', ('///quack/',))],
160
            client._calls)
161
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
162
    def check_open_repository(self, rich_root, subtrees):
163
        if rich_root:
2018.5.166 by Andrew Bennetts
Small changes in response to Aaron's review.
164
            rich_response = 'yes'
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
165
        else:
2018.5.166 by Andrew Bennetts
Small changes in response to Aaron's review.
166
            rich_response = 'no'
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
167
        if subtrees:
2018.5.166 by Andrew Bennetts
Small changes in response to Aaron's review.
168
            subtree_response = 'yes'
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
169
        else:
2018.5.166 by Andrew Bennetts
Small changes in response to Aaron's review.
170
            subtree_response = 'no'
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
171
        client = FakeClient([(('ok', '', rich_response, subtree_response), ),])
172
        transport = MemoryTransport()
173
        transport.mkdir('quack')
174
        transport = transport.clone('quack')
175
        bzrdir = RemoteBzrDir(transport, _client=client)
176
        result = bzrdir.open_repository()
177
        self.assertEqual(
178
            [('call', 'BzrDir.find_repository', ('///quack/',))],
179
            client._calls)
180
        self.assertIsInstance(result, RemoteRepository)
181
        self.assertEqual(bzrdir, result.bzrdir)
182
        self.assertEqual(rich_root, result._format.rich_root_data)
2018.5.138 by Robert Collins
Merge bzr.dev.
183
        self.assertEqual(subtrees, result._format.supports_tree_reference)
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
184
185
    def test_open_repository_sets_format_attributes(self):
186
        self.check_open_repository(True, True)
187
        self.check_open_repository(False, True)
188
        self.check_open_repository(True, False)
189
        self.check_open_repository(False, False)
190
2432.3.2 by Andrew Bennetts
Add test, and tidy implementation.
191
    def test_old_server(self):
192
        """RemoteBzrDirFormat should fail to probe if the server version is too
193
        old.
194
        """
195
        self.assertRaises(errors.NotBranchError,
196
            RemoteBzrDirFormat.probe_transport, OldServerTransport())
197
198
199
class OldSmartClient(object):
200
    """A fake smart client for test_old_version that just returns a version one
201
    response to the 'hello' (query version) command.
202
    """
203
204
    def get_request(self):
205
        input_file = StringIO('ok\x011\n')
206
        output_file = StringIO()
207
        client_medium = medium.SmartSimplePipesClientMedium(
208
            input_file, output_file)
209
        return medium.SmartClientStreamMediumRequest(client_medium)
210
211
212
class OldServerTransport(object):
213
    """A fake transport for test_old_server that reports it's smart server
214
    protocol version as version one.
215
    """
216
217
    def __init__(self):
218
        self.base = 'fake:'
219
220
    def get_smart_client(self):
221
        return OldSmartClient()
222
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
223
2018.5.51 by Wouter van Heyst
Test and implement RemoteBranch.last_revision_info()
224
class TestBranchLastRevisionInfo(tests.TestCase):
225
226
    def test_empty_branch(self):
227
        # in an empty branch we decode the response properly
2018.5.170 by Andrew Bennetts
Use 'null:' instead of '' to mean NULL_REVISION on the wire.
228
        client = FakeClient([(('ok', '0', 'null:'), )])
2018.5.51 by Wouter van Heyst
Test and implement RemoteBranch.last_revision_info()
229
        transport = MemoryTransport()
230
        transport.mkdir('quack')
231
        transport = transport.clone('quack')
232
        # we do not want bzrdir to make any remote calls
233
        bzrdir = RemoteBzrDir(transport, _client=False)
234
        branch = RemoteBranch(bzrdir, None, _client=client)
235
        result = branch.last_revision_info()
236
237
        self.assertEqual(
238
            [('call', 'Branch.last_revision_info', ('///quack/',))],
239
            client._calls)
240
        self.assertEqual((0, NULL_REVISION), result)
241
242
    def test_non_empty_branch(self):
243
        # in a non-empty branch we also decode the response properly
2018.5.106 by Andrew Bennetts
Update tests in test_remote to use utf-8 byte strings for revision IDs, rather than unicode strings.
244
        revid = u'\xc8'.encode('utf8')
245
        client = FakeClient([(('ok', '2', revid), )])
2018.5.51 by Wouter van Heyst
Test and implement RemoteBranch.last_revision_info()
246
        transport = MemoryTransport()
247
        transport.mkdir('kwaak')
248
        transport = transport.clone('kwaak')
249
        # we do not want bzrdir to make any remote calls
250
        bzrdir = RemoteBzrDir(transport, _client=False)
251
        branch = RemoteBranch(bzrdir, None, _client=client)
252
        result = branch.last_revision_info()
253
254
        self.assertEqual(
255
            [('call', 'Branch.last_revision_info', ('///kwaak/',))],
256
            client._calls)
2018.5.106 by Andrew Bennetts
Update tests in test_remote to use utf-8 byte strings for revision IDs, rather than unicode strings.
257
        self.assertEqual((2, revid), result)
2018.5.57 by Robert Collins
Implement RemoteRepository.is_shared (Robert Collins, Vincent Ladeuil).
258
259
2018.12.3 by Andrew Bennetts
Add a Branch.set_last_revision smart method, and make RemoteBranch.set_revision_history use it.
260
class TestBranchSetLastRevision(tests.TestCase):
261
262
    def test_set_empty(self):
263
        # set_revision_history([]) is translated to calling
264
        # Branch.set_last_revision(path, '') on the wire.
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
265
        client = FakeClient([
266
            # lock_write
267
            (('ok', 'branch token', 'repo token'), ),
268
            # set_last_revision
269
            (('ok',), ),
270
            # unlock
271
            (('ok',), )])
2018.12.3 by Andrew Bennetts
Add a Branch.set_last_revision smart method, and make RemoteBranch.set_revision_history use it.
272
        transport = MemoryTransport()
273
        transport.mkdir('branch')
274
        transport = transport.clone('branch')
275
276
        bzrdir = RemoteBzrDir(transport, _client=False)
277
        branch = RemoteBranch(bzrdir, None, _client=client)
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
278
        # This is a hack to work around the problem that RemoteBranch currently
279
        # unnecessarily invokes _ensure_real upon a call to lock_write.
280
        branch._ensure_real = lambda: None
281
        branch.lock_write()
282
        client._calls = []
2018.12.3 by Andrew Bennetts
Add a Branch.set_last_revision smart method, and make RemoteBranch.set_revision_history use it.
283
        result = branch.set_revision_history([])
284
        self.assertEqual(
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
285
            [('call', 'Branch.set_last_revision',
2018.5.170 by Andrew Bennetts
Use 'null:' instead of '' to mean NULL_REVISION on the wire.
286
                ('///branch/', 'branch token', 'repo token', 'null:'))],
2018.12.3 by Andrew Bennetts
Add a Branch.set_last_revision smart method, and make RemoteBranch.set_revision_history use it.
287
            client._calls)
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
288
        branch.unlock()
2018.12.3 by Andrew Bennetts
Add a Branch.set_last_revision smart method, and make RemoteBranch.set_revision_history use it.
289
        self.assertEqual(None, result)
290
291
    def test_set_nonempty(self):
292
        # set_revision_history([rev-id1, ..., rev-idN]) is translated to calling
293
        # Branch.set_last_revision(path, rev-idN) on the wire.
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
294
        client = FakeClient([
295
            # lock_write
296
            (('ok', 'branch token', 'repo token'), ),
297
            # set_last_revision
298
            (('ok',), ),
299
            # unlock
300
            (('ok',), )])
2018.12.3 by Andrew Bennetts
Add a Branch.set_last_revision smart method, and make RemoteBranch.set_revision_history use it.
301
        transport = MemoryTransport()
302
        transport.mkdir('branch')
303
        transport = transport.clone('branch')
304
305
        bzrdir = RemoteBzrDir(transport, _client=False)
306
        branch = RemoteBranch(bzrdir, None, _client=client)
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
307
        # This is a hack to work around the problem that RemoteBranch currently
308
        # unnecessarily invokes _ensure_real upon a call to lock_write.
309
        branch._ensure_real = lambda: None
310
        # Lock the branch, reset the record of remote calls.
311
        branch.lock_write()
312
        client._calls = []
2018.12.3 by Andrew Bennetts
Add a Branch.set_last_revision smart method, and make RemoteBranch.set_revision_history use it.
313
314
        result = branch.set_revision_history(['rev-id1', 'rev-id2'])
315
        self.assertEqual(
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
316
            [('call', 'Branch.set_last_revision',
317
                ('///branch/', 'branch token', 'repo token', 'rev-id2'))],
2018.12.3 by Andrew Bennetts
Add a Branch.set_last_revision smart method, and make RemoteBranch.set_revision_history use it.
318
            client._calls)
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
319
        branch.unlock()
2018.12.3 by Andrew Bennetts
Add a Branch.set_last_revision smart method, and make RemoteBranch.set_revision_history use it.
320
        self.assertEqual(None, result)
321
322
    def test_no_such_revision(self):
323
        # A response of 'NoSuchRevision' is translated into an exception.
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
324
        client = FakeClient([
325
            # lock_write
326
            (('ok', 'branch token', 'repo token'), ),
327
            # set_last_revision
328
            (('NoSuchRevision', 'rev-id'), ),
329
            # unlock
330
            (('ok',), )])
2018.12.3 by Andrew Bennetts
Add a Branch.set_last_revision smart method, and make RemoteBranch.set_revision_history use it.
331
        transport = MemoryTransport()
332
        transport.mkdir('branch')
333
        transport = transport.clone('branch')
334
335
        bzrdir = RemoteBzrDir(transport, _client=False)
336
        branch = RemoteBranch(bzrdir, None, _client=client)
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
337
        branch._ensure_real = lambda: None
338
        branch.lock_write()
339
        client._calls = []
2018.12.3 by Andrew Bennetts
Add a Branch.set_last_revision smart method, and make RemoteBranch.set_revision_history use it.
340
341
        self.assertRaises(
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
342
            errors.NoSuchRevision, branch.set_revision_history, ['rev-id'])
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
343
        branch.unlock()
2018.12.3 by Andrew Bennetts
Add a Branch.set_last_revision smart method, and make RemoteBranch.set_revision_history use it.
344
345
2018.5.169 by Andrew Bennetts
Add a _server_formats flag to BzrDir.open_from_transport and BzrDirFormat.find_format, make RemoteBranch.control_files into a property.
346
class TestBranchControlGetBranchConf(tests.TestCaseWithMemoryTransport):
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
347
    """Test branch.control_files api munging...
348
2018.5.169 by Andrew Bennetts
Add a _server_formats flag to BzrDir.open_from_transport and BzrDirFormat.find_format, make RemoteBranch.control_files into a property.
349
    We special case RemoteBranch.control_files.get('branch.conf') to
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
350
    call a specific API so that RemoteBranch's can intercept configuration
351
    file reading, allowing them to signal to the client about things like
352
    'email is configured for commits'.
353
    """
354
355
    def test_get_branch_conf(self):
356
        # in an empty branch we decode the response properly
357
        client = FakeClient([(('ok', ), 'config file body')])
2018.5.169 by Andrew Bennetts
Add a _server_formats flag to BzrDir.open_from_transport and BzrDirFormat.find_format, make RemoteBranch.control_files into a property.
358
        # we need to make a real branch because the remote_branch.control_files
359
        # will trigger _ensure_real.
360
        branch = self.make_branch('quack')
361
        transport = branch.bzrdir.root_transport
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
362
        # we do not want bzrdir to make any remote calls
363
        bzrdir = RemoteBzrDir(transport, _client=False)
364
        branch = RemoteBranch(bzrdir, None, _client=client)
365
        result = branch.control_files.get('branch.conf')
366
        self.assertEqual(
2018.5.153 by Andrew Bennetts
Rename call2 to call_expecting_body, and other small changes prompted by review.
367
            [('call_expecting_body', 'Branch.get_config_file', ('///quack/',))],
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
368
            client._calls)
369
        self.assertEqual('config file body', result.read())
370
371
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.
372
class TestBranchLockWrite(tests.TestCase):
373
374
    def test_lock_write_unlockable(self):
375
        client = FakeClient([(('UnlockableTransport', ), '')])
376
        transport = MemoryTransport()
377
        transport.mkdir('quack')
378
        transport = transport.clone('quack')
379
        # we do not want bzrdir to make any remote calls
380
        bzrdir = RemoteBzrDir(transport, _client=False)
381
        branch = RemoteBranch(bzrdir, None, _client=client)
382
        self.assertRaises(errors.UnlockableTransport, branch.lock_write)
383
        self.assertEqual(
384
            [('call', 'Branch.lock_write', ('///quack/', '', ''))],
385
            client._calls)
386
387
2466.2.2 by Andrew Bennetts
Add tests for RemoteTransport.is_readonly in the style of the other remote object tests.
388
class TestTransportIsReadonly(tests.TestCase):
389
390
    def test_true(self):
391
        client = FakeClient([(('yes',), '')])
392
        transport = RemoteTransport('bzr://example.com/', medium=False,
393
                                    _client=client)
394
        self.assertEqual(True, transport.is_readonly())
395
        self.assertEqual(
396
            [('call', 'Transport.is_readonly', ())],
397
            client._calls)
398
399
    def test_false(self):
400
        client = FakeClient([(('no',), '')])
401
        transport = RemoteTransport('bzr://example.com/', medium=False,
402
                                    _client=client)
403
        self.assertEqual(False, transport.is_readonly())
404
        self.assertEqual(
405
            [('call', 'Transport.is_readonly', ())],
406
            client._calls)
407
408
    def test_error_from_old_server(self):
409
        """bzr 0.15 and earlier servers don't recognise the is_readonly verb.
410
        
411
        Clients should treat it as a "no" response, because is_readonly is only
412
        advisory anyway (a transport could be read-write, but then the
413
        underlying filesystem could be readonly anyway).
414
        """
415
        client = FakeClient([(
416
            ('error', "Generic bzr smart protocol error: "
417
                      "bad request 'Transport.is_readonly'"), '')])
418
        transport = RemoteTransport('bzr://example.com/', medium=False,
419
                                    _client=client)
420
        self.assertEqual(False, transport.is_readonly())
421
        self.assertEqual(
422
            [('call', 'Transport.is_readonly', ())],
423
            client._calls)
424
2471.2.1 by Andrew Bennetts
Fix trivial incompatibility with bzr 0.11 servers, which give a slightly different error to bzr 0.15 servers.
425
    def test_error_from_old_0_11_server(self):
426
        """Same as test_error_from_old_server, but with the slightly different
427
        error message from bzr 0.11 servers.
428
        """
429
        client = FakeClient([(
430
            ('error', "Generic bzr smart protocol error: "
431
                      "bad request u'Transport.is_readonly'"), '')])
432
        transport = RemoteTransport('bzr://example.com/', medium=False,
433
                                    _client=client)
434
        self.assertEqual(False, transport.is_readonly())
435
        self.assertEqual(
436
            [('call', 'Transport.is_readonly', ())],
437
            client._calls)
438
2466.2.2 by Andrew Bennetts
Add tests for RemoteTransport.is_readonly in the style of the other remote object tests.
439
2018.5.67 by Wouter van Heyst
Implement RemoteRepository.get_revision_graph (Wouter van Heyst, Robert Collins)
440
class TestRemoteRepository(tests.TestCase):
2018.18.9 by Martin Pool
remote Repository.tarball builds a temporary directory and tars that
441
    """Base for testing RemoteRepository protocol usage.
442
    
443
    These tests contain frozen requests and responses.  We want any changes to 
444
    what is sent or expected to be require a thoughtful update to these tests
445
    because they might break compatibility with different-versioned servers.
446
    """
2018.5.57 by Robert Collins
Implement RemoteRepository.is_shared (Robert Collins, Vincent Ladeuil).
447
448
    def setup_fake_client_and_repository(self, responses, transport_path):
2018.18.7 by Martin Pool
(broken) Start addng client proxy test for Repository.tarball
449
        """Create the fake client and repository for testing with.
450
        
451
        There's no real server here; we just have canned responses sent
452
        back one by one.
453
        
454
        :param transport_path: Path below the root of the MemoryTransport
455
            where the repository will be created.
456
        """
2018.5.57 by Robert Collins
Implement RemoteRepository.is_shared (Robert Collins, Vincent Ladeuil).
457
        client = FakeClient(responses)
458
        transport = MemoryTransport()
459
        transport.mkdir(transport_path)
460
        transport = transport.clone(transport_path)
461
        # we do not want bzrdir to make any remote calls
462
        bzrdir = RemoteBzrDir(transport, _client=False)
463
        repo = RemoteRepository(bzrdir, None, _client=client)
464
        return repo, client
465
2018.5.67 by Wouter van Heyst
Implement RemoteRepository.get_revision_graph (Wouter van Heyst, Robert Collins)
466
2018.12.2 by Andrew Bennetts
Remove some duplicate code in test_remote
467
class TestRepositoryGatherStats(TestRemoteRepository):
2018.10.3 by v.ladeuil+lp at free
more tests for gather_stats
468
469
    def test_revid_none(self):
470
        # ('ok',), body with revisions and size
471
        responses = [(('ok', ), 'revisions: 2\nsize: 18\n')]
472
        transport_path = 'quack'
473
        repo, client = self.setup_fake_client_and_repository(
474
            responses, transport_path)
475
        result = repo.gather_stats(None)
476
        self.assertEqual(
2018.5.153 by Andrew Bennetts
Rename call2 to call_expecting_body, and other small changes prompted by review.
477
            [('call_expecting_body', 'Repository.gather_stats',
478
             ('///quack/','','no'))],
2018.10.3 by v.ladeuil+lp at free
more tests for gather_stats
479
            client._calls)
480
        self.assertEqual({'revisions': 2, 'size': 18}, result)
481
482
    def test_revid_no_committers(self):
483
        # ('ok',), body without committers
484
        responses = [(('ok', ),
485
                      'firstrev: 123456.300 3600\n'
486
                      'latestrev: 654231.400 0\n'
487
                      'revisions: 2\n'
488
                      'size: 18\n')]
489
        transport_path = 'quick'
2018.5.106 by Andrew Bennetts
Update tests in test_remote to use utf-8 byte strings for revision IDs, rather than unicode strings.
490
        revid = u'\xc8'.encode('utf8')
2018.10.3 by v.ladeuil+lp at free
more tests for gather_stats
491
        repo, client = self.setup_fake_client_and_repository(
492
            responses, transport_path)
493
        result = repo.gather_stats(revid)
494
        self.assertEqual(
2018.5.153 by Andrew Bennetts
Rename call2 to call_expecting_body, and other small changes prompted by review.
495
            [('call_expecting_body', 'Repository.gather_stats',
2018.5.106 by Andrew Bennetts
Update tests in test_remote to use utf-8 byte strings for revision IDs, rather than unicode strings.
496
              ('///quick/', revid, 'no'))],
2018.10.3 by v.ladeuil+lp at free
more tests for gather_stats
497
            client._calls)
498
        self.assertEqual({'revisions': 2, 'size': 18,
499
                          'firstrev': (123456.300, 3600),
500
                          'latestrev': (654231.400, 0),},
501
                         result)
502
503
    def test_revid_with_committers(self):
504
        # ('ok',), body with committers
505
        responses = [(('ok', ),
506
                      'committers: 128\n'
507
                      'firstrev: 123456.300 3600\n'
508
                      'latestrev: 654231.400 0\n'
509
                      'revisions: 2\n'
510
                      'size: 18\n')]
511
        transport_path = 'buick'
2018.5.106 by Andrew Bennetts
Update tests in test_remote to use utf-8 byte strings for revision IDs, rather than unicode strings.
512
        revid = u'\xc8'.encode('utf8')
2018.10.3 by v.ladeuil+lp at free
more tests for gather_stats
513
        repo, client = self.setup_fake_client_and_repository(
514
            responses, transport_path)
515
        result = repo.gather_stats(revid, True)
516
        self.assertEqual(
2018.5.153 by Andrew Bennetts
Rename call2 to call_expecting_body, and other small changes prompted by review.
517
            [('call_expecting_body', 'Repository.gather_stats',
2018.5.106 by Andrew Bennetts
Update tests in test_remote to use utf-8 byte strings for revision IDs, rather than unicode strings.
518
              ('///buick/', revid, 'yes'))],
2018.10.3 by v.ladeuil+lp at free
more tests for gather_stats
519
            client._calls)
520
        self.assertEqual({'revisions': 2, 'size': 18,
521
                          'committers': 128,
522
                          'firstrev': (123456.300, 3600),
523
                          'latestrev': (654231.400, 0),},
524
                         result)
525
526
2018.5.68 by Wouter van Heyst
Merge RemoteRepository.gather_stats.
527
class TestRepositoryGetRevisionGraph(TestRemoteRepository):
528
    
529
    def test_null_revision(self):
530
        # a null revision has the predictable result {}, we should have no wire
531
        # traffic when calling it with this argument
532
        responses = [(('notused', ), '')]
533
        transport_path = 'empty'
534
        repo, client = self.setup_fake_client_and_repository(
535
            responses, transport_path)
536
        result = repo.get_revision_graph(NULL_REVISION)
537
        self.assertEqual([], client._calls)
538
        self.assertEqual({}, result)
539
2018.5.67 by Wouter van Heyst
Implement RemoteRepository.get_revision_graph (Wouter van Heyst, Robert Collins)
540
    def test_none_revision(self):
541
        # with none we want the entire graph
2018.5.106 by Andrew Bennetts
Update tests in test_remote to use utf-8 byte strings for revision IDs, rather than unicode strings.
542
        r1 = u'\u0e33'.encode('utf8')
543
        r2 = u'\u0dab'.encode('utf8')
2018.5.67 by Wouter van Heyst
Implement RemoteRepository.get_revision_graph (Wouter van Heyst, Robert Collins)
544
        lines = [' '.join([r2, r1]), r1]
2018.5.106 by Andrew Bennetts
Update tests in test_remote to use utf-8 byte strings for revision IDs, rather than unicode strings.
545
        encoded_body = '\n'.join(lines)
2018.5.67 by Wouter van Heyst
Implement RemoteRepository.get_revision_graph (Wouter van Heyst, Robert Collins)
546
547
        responses = [(('ok', ), encoded_body)]
548
        transport_path = 'sinhala'
549
        repo, client = self.setup_fake_client_and_repository(
550
            responses, transport_path)
551
        result = repo.get_revision_graph()
552
        self.assertEqual(
2018.5.153 by Andrew Bennetts
Rename call2 to call_expecting_body, and other small changes prompted by review.
553
            [('call_expecting_body', 'Repository.get_revision_graph',
554
             ('///sinhala/', ''))],
2018.5.67 by Wouter van Heyst
Implement RemoteRepository.get_revision_graph (Wouter van Heyst, Robert Collins)
555
            client._calls)
556
        self.assertEqual({r1: [], r2: [r1]}, result)
557
558
    def test_specific_revision(self):
559
        # with a specific revision we want the graph for that
560
        # with none we want the entire graph
2018.5.106 by Andrew Bennetts
Update tests in test_remote to use utf-8 byte strings for revision IDs, rather than unicode strings.
561
        r11 = u'\u0e33'.encode('utf8')
562
        r12 = u'\xc9'.encode('utf8')
563
        r2 = u'\u0dab'.encode('utf8')
2018.5.67 by Wouter van Heyst
Implement RemoteRepository.get_revision_graph (Wouter van Heyst, Robert Collins)
564
        lines = [' '.join([r2, r11, r12]), r11, r12]
2018.5.106 by Andrew Bennetts
Update tests in test_remote to use utf-8 byte strings for revision IDs, rather than unicode strings.
565
        encoded_body = '\n'.join(lines)
2018.5.67 by Wouter van Heyst
Implement RemoteRepository.get_revision_graph (Wouter van Heyst, Robert Collins)
566
567
        responses = [(('ok', ), encoded_body)]
568
        transport_path = 'sinhala'
569
        repo, client = self.setup_fake_client_and_repository(
570
            responses, transport_path)
571
        result = repo.get_revision_graph(r2)
572
        self.assertEqual(
2018.5.153 by Andrew Bennetts
Rename call2 to call_expecting_body, and other small changes prompted by review.
573
            [('call_expecting_body', 'Repository.get_revision_graph',
574
             ('///sinhala/', r2))],
2018.5.67 by Wouter van Heyst
Implement RemoteRepository.get_revision_graph (Wouter van Heyst, Robert Collins)
575
            client._calls)
576
        self.assertEqual({r11: [], r12: [], r2: [r11, r12], }, result)
577
578
    def test_no_such_revision(self):
579
        revid = '123'
580
        responses = [(('nosuchrevision', revid), '')]
581
        transport_path = 'sinhala'
582
        repo, client = self.setup_fake_client_and_repository(
583
            responses, transport_path)
584
        # also check that the right revision is reported in the error
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
585
        self.assertRaises(errors.NoSuchRevision,
2018.5.67 by Wouter van Heyst
Implement RemoteRepository.get_revision_graph (Wouter van Heyst, Robert Collins)
586
            repo.get_revision_graph, revid)
587
        self.assertEqual(
2018.5.153 by Andrew Bennetts
Rename call2 to call_expecting_body, and other small changes prompted by review.
588
            [('call_expecting_body', 'Repository.get_revision_graph',
589
             ('///sinhala/', revid))],
2018.5.67 by Wouter van Heyst
Implement RemoteRepository.get_revision_graph (Wouter van Heyst, Robert Collins)
590
            client._calls)
591
592
        
593
class TestRepositoryIsShared(TestRemoteRepository):
594
2018.5.57 by Robert Collins
Implement RemoteRepository.is_shared (Robert Collins, Vincent Ladeuil).
595
    def test_is_shared(self):
596
        # ('yes', ) for Repository.is_shared -> 'True'.
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
597
        responses = [(('yes', ), )]
2018.5.57 by Robert Collins
Implement RemoteRepository.is_shared (Robert Collins, Vincent Ladeuil).
598
        transport_path = 'quack'
599
        repo, client = self.setup_fake_client_and_repository(
600
            responses, transport_path)
601
        result = repo.is_shared()
602
        self.assertEqual(
603
            [('call', 'Repository.is_shared', ('///quack/',))],
604
            client._calls)
605
        self.assertEqual(True, result)
606
607
    def test_is_not_shared(self):
608
        # ('no', ) for Repository.is_shared -> 'False'.
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
609
        responses = [(('no', ), )]
2018.5.57 by Robert Collins
Implement RemoteRepository.is_shared (Robert Collins, Vincent Ladeuil).
610
        transport_path = 'qwack'
611
        repo, client = self.setup_fake_client_and_repository(
612
            responses, transport_path)
613
        result = repo.is_shared()
614
        self.assertEqual(
615
            [('call', 'Repository.is_shared', ('///qwack/',))],
616
            client._calls)
617
        self.assertEqual(False, result)
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
618
619
620
class TestRepositoryLockWrite(TestRemoteRepository):
621
622
    def test_lock_write(self):
623
        responses = [(('ok', 'a token'), '')]
624
        transport_path = 'quack'
625
        repo, client = self.setup_fake_client_and_repository(
626
            responses, transport_path)
627
        result = repo.lock_write()
628
        self.assertEqual(
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.
629
            [('call', 'Repository.lock_write', ('///quack/', ''))],
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
630
            client._calls)
631
        self.assertEqual('a token', result)
632
633
    def test_lock_write_already_locked(self):
634
        responses = [(('LockContention', ), '')]
635
        transport_path = 'quack'
636
        repo, client = self.setup_fake_client_and_repository(
637
            responses, transport_path)
638
        self.assertRaises(errors.LockContention, repo.lock_write)
639
        self.assertEqual(
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.
640
            [('call', 'Repository.lock_write', ('///quack/', ''))],
641
            client._calls)
642
643
    def test_lock_write_unlockable(self):
644
        responses = [(('UnlockableTransport', ), '')]
645
        transport_path = 'quack'
646
        repo, client = self.setup_fake_client_and_repository(
647
            responses, transport_path)
648
        self.assertRaises(errors.UnlockableTransport, repo.lock_write)
649
        self.assertEqual(
650
            [('call', 'Repository.lock_write', ('///quack/', ''))],
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
651
            client._calls)
652
653
654
class TestRepositoryUnlock(TestRemoteRepository):
655
656
    def test_unlock(self):
657
        responses = [(('ok', 'a token'), ''),
658
                     (('ok',), '')]
659
        transport_path = 'quack'
660
        repo, client = self.setup_fake_client_and_repository(
661
            responses, transport_path)
662
        repo.lock_write()
663
        repo.unlock()
664
        self.assertEqual(
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.
665
            [('call', 'Repository.lock_write', ('///quack/', '')),
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
666
             ('call', 'Repository.unlock', ('///quack/', 'a token'))],
667
            client._calls)
668
669
    def test_unlock_wrong_token(self):
670
        # If somehow the token is wrong, unlock will raise TokenMismatch.
671
        responses = [(('ok', 'a token'), ''),
672
                     (('TokenMismatch',), '')]
673
        transport_path = 'quack'
674
        repo, client = self.setup_fake_client_and_repository(
675
            responses, transport_path)
676
        repo.lock_write()
677
        self.assertRaises(errors.TokenMismatch, repo.unlock)
678
679
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
680
class TestRepositoryHasRevision(TestRemoteRepository):
681
682
    def test_none(self):
683
        # repo.has_revision(None) should not cause any traffic.
684
        transport_path = 'quack'
685
        responses = None
686
        repo, client = self.setup_fake_client_and_repository(
687
            responses, transport_path)
688
689
        # The null revision is always there, so has_revision(None) == True.
690
        self.assertEqual(True, repo.has_revision(None))
691
692
        # The remote repo shouldn't be accessed.
693
        self.assertEqual([], client._calls)
2018.18.7 by Martin Pool
(broken) Start addng client proxy test for Repository.tarball
694
695
696
class TestRepositoryTarball(TestRemoteRepository):
697
2018.18.9 by Martin Pool
remote Repository.tarball builds a temporary directory and tars that
698
    # This is a canned tarball reponse we can validate against
2018.18.18 by Martin Pool
reformat
699
    tarball_content = (
2018.18.23 by Martin Pool
review cleanups
700
        'QlpoOTFBWSZTWdGkj3wAAWF/k8aQACBIB//A9+8cIX/v33AACEAYABAECEACNz'
701
        'JqsgJJFPTSnk1A3qh6mTQAAAANPUHkagkSTEkaA09QaNAAAGgAAAcwCYCZGAEY'
702
        'mJhMJghpiaYBUkKammSHqNMZQ0NABkNAeo0AGneAevnlwQoGzEzNVzaYxp/1Uk'
703
        'xXzA1CQX0BJMZZLcPBrluJir5SQyijWHYZ6ZUtVqqlYDdB2QoCwa9GyWwGYDMA'
704
        'OQYhkpLt/OKFnnlT8E0PmO8+ZNSo2WWqeCzGB5fBXZ3IvV7uNJVE7DYnWj6qwB'
705
        'k5DJDIrQ5OQHHIjkS9KqwG3mc3t+F1+iujb89ufyBNIKCgeZBWrl5cXxbMGoMs'
706
        'c9JuUkg5YsiVcaZJurc6KLi6yKOkgCUOlIlOpOoXyrTJjK8ZgbklReDdwGmFgt'
707
        'dkVsAIslSVCd4AtACSLbyhLHryfb14PKegrVDba+U8OL6KQtzdM5HLjAc8/p6n'
708
        '0lgaWU8skgO7xupPTkyuwheSckejFLK5T4ZOo0Gda9viaIhpD1Qn7JqqlKAJqC'
709
        'QplPKp2nqBWAfwBGaOwVrz3y1T+UZZNismXHsb2Jq18T+VaD9k4P8DqE3g70qV'
710
        'JLurpnDI6VS5oqDDPVbtVjMxMxMg4rzQVipn2Bv1fVNK0iq3Gl0hhnnHKm/egy'
711
        'nWQ7QH/F3JFOFCQ0aSPfA='
712
        ).decode('base64')
2018.18.9 by Martin Pool
remote Repository.tarball builds a temporary directory and tars that
713
2018.18.7 by Martin Pool
(broken) Start addng client proxy test for Repository.tarball
714
    def test_repository_tarball(self):
2018.18.9 by Martin Pool
remote Repository.tarball builds a temporary directory and tars that
715
        # Test that Repository.tarball generates the right operations
2018.18.7 by Martin Pool
(broken) Start addng client proxy test for Repository.tarball
716
        transport_path = 'repo'
2018.18.9 by Martin Pool
remote Repository.tarball builds a temporary directory and tars that
717
        expected_responses = [(('ok',), self.tarball_content),
2018.18.7 by Martin Pool
(broken) Start addng client proxy test for Repository.tarball
718
            ]
2018.18.14 by Martin Pool
merge hpss again; restore incorrectly removed RemoteRepository.break_lock
719
        expected_calls = [('call_expecting_body', 'Repository.tarball',
720
                           ('///repo/', 'bz2',),),
2018.18.7 by Martin Pool
(broken) Start addng client proxy test for Repository.tarball
721
            ]
722
        remote_repo, client = self.setup_fake_client_and_repository(
723
            expected_responses, transport_path)
724
        # Now actually ask for the tarball
2018.18.25 by Martin Pool
Repository.tarball fixes for python2.4
725
        tarball_file = remote_repo._get_tarball('bz2')
726
        try:
727
            self.assertEqual(expected_calls, client._calls)
728
            self.assertEqual(self.tarball_content, tarball_file.read())
729
        finally:
730
            tarball_file.close()
2018.18.9 by Martin Pool
remote Repository.tarball builds a temporary directory and tars that
731
2018.18.24 by Martin Pool
Merge Repository.sprout refactoring, and make that use Repository.tarball
732
    def test_sprout_uses_tarball(self):
733
        # RemoteRepository.sprout should try to use the
2018.18.17 by Martin Pool
Update and reenable rpc-level tests for Repository.tarball
734
        # tarball command rather than accessing all the files
735
        transport_path = 'srcrepo'
736
        expected_responses = [(('ok',), self.tarball_content),
737
            ]
738
        expected_calls = [('call2', 'Repository.tarball', ('///srcrepo/', 'bz2',),),
739
            ]
740
        remote_repo, client = self.setup_fake_client_and_repository(
741
            expected_responses, transport_path)
742
        # make a regular local repository to receive the results
743
        dest_transport = MemoryTransport()
744
        dest_transport.mkdir('destrepo')
745
        bzrdir_format = bzrdir.format_registry.make_bzrdir('default')
746
        dest_bzrdir = bzrdir_format.initialize_on_transport(dest_transport)
747
        # try to copy...
2018.18.24 by Martin Pool
Merge Repository.sprout refactoring, and make that use Repository.tarball
748
        remote_repo.sprout(dest_bzrdir)
2018.18.17 by Martin Pool
Update and reenable rpc-level tests for Repository.tarball
749
2018.18.9 by Martin Pool
remote Repository.tarball builds a temporary directory and tars that
750
751
class TestRemoteRepositoryCopyContent(tests.TestCaseWithTransport):
752
    """RemoteRepository.copy_content_into optimizations"""
753
2018.18.10 by Martin Pool
copy_content_into from Remote repositories by using temporary directories on both ends.
754
    def test_copy_content_remote_to_local(self):
755
        self.transport_server = server.SmartTCPServer_for_testing
756
        src_repo = self.make_repository('repo1')
757
        src_repo = repository.Repository.open(self.get_url('repo1'))
758
        # At the moment the tarball-based copy_content_into can't write back
759
        # into a smart server.  It would be good if it could upload the
760
        # tarball; once that works we'd have to create repositories of
761
        # different formats. -- mbp 20070410
762
        dest_url = self.get_vfs_only_url('repo2')
763
        dest_bzrdir = BzrDir.create(dest_url)
764
        dest_repo = dest_bzrdir.create_repository()
765
        self.assertFalse(isinstance(dest_repo, RemoteRepository))
766
        self.assertTrue(isinstance(src_repo, RemoteRepository))
767
        src_repo.copy_content_into(dest_repo)