~bzr-pqm/bzr/bzr.dev

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