/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. 
22
"""
23
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
24
from cStringIO import StringIO
25
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
26
from bzrlib import (
27
    bzrdir,
28
    errors,
29
    remote,
30
    tests,
31
    )
2018.5.51 by Wouter van Heyst
Test and implement RemoteBranch.last_revision_info()
32
from bzrlib.branch import Branch
33
from bzrlib.bzrdir import BzrDir, BzrDirFormat
34
from bzrlib.remote import (
35
    RemoteBranch,
36
    RemoteBzrDir,
37
    RemoteBzrDirFormat,
2018.5.57 by Robert Collins
Implement RemoteRepository.is_shared (Robert Collins, Vincent Ladeuil).
38
    RemoteRepository,
2018.5.51 by Wouter van Heyst
Test and implement RemoteBranch.last_revision_info()
39
    )
40
from bzrlib.revision import NULL_REVISION
41
from bzrlib.smart import server
42
from bzrlib.smart.client import SmartClient
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)
43
from bzrlib.transport import remote as remote_transport
2018.5.51 by Wouter van Heyst
Test and implement RemoteBranch.last_revision_info()
44
from bzrlib.transport.memory import MemoryTransport
1752.2.30 by Martin Pool
Start adding a RemoteBzrDir, etc
45
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)
46
2018.5.42 by Robert Collins
Various hopefully improvements, but wsgi is broken, handing over to spiv :).
47
class BasicRemoteObjectTests(tests.TestCaseWithTransport):
1752.2.30 by Martin Pool
Start adding a RemoteBzrDir, etc
48
49
    def setUp(self):
2018.5.42 by Robert Collins
Various hopefully improvements, but wsgi is broken, handing over to spiv :).
50
        super(BasicRemoteObjectTests, self).setUp()
51
        self.transport_server = server.SmartTCPServer_for_testing
52
        self.transport = self.get_transport()
1752.2.30 by Martin Pool
Start adding a RemoteBzrDir, etc
53
        self.client = self.transport.get_smart_client()
54
        # 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
55
        self.local_wt = BzrDir.create_standalone_workingtree('.')
1752.2.30 by Martin Pool
Start adding a RemoteBzrDir, etc
56
57
    def test_create_remote_bzrdir(self):
58
        b = remote.RemoteBzrDir(self.transport)
59
        self.assertIsInstance(b, BzrDir)
60
61
    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.
62
        # open a standalone branch in the working directory
1752.2.30 by Martin Pool
Start adding a RemoteBzrDir, etc
63
        b = remote.RemoteBzrDir(self.transport)
64
        branch = b.open_branch()
65
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
66
    def test_remote_repository(self):
67
        b = BzrDir.open_from_transport(self.transport)
68
        repo = b.open_repository()
2018.5.40 by Robert Collins
Implement a remote Repository.has_revision method.
69
        revid = u'\xc823123123'
70
        self.assertFalse(repo.has_revision(revid))
71
        self.local_wt.commit(message='test commit', rev_id=revid)
72
        self.assertTrue(repo.has_revision(revid))
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
73
74
    def test_remote_branch_revision_history(self):
75
        b = BzrDir.open_from_transport(self.transport).open_branch()
2018.5.38 by Robert Collins
Implement RemoteBranch.revision_history().
76
        self.assertEqual([], b.revision_history())
77
        r1 = self.local_wt.commit('1st commit')
78
        r2 = self.local_wt.commit('1st commit', rev_id=u'\xc8')
79
        self.assertEqual([r1, r2], b.revision_history())
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
80
1752.2.30 by Martin Pool
Start adding a RemoteBzrDir, etc
81
    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)
82
        """Should open a RemoteBzrDir over a RemoteTransport"""
1752.2.30 by Martin Pool
Start adding a RemoteBzrDir, etc
83
        fmt = BzrDirFormat.find_format(self.transport)
2018.5.25 by Andrew Bennetts
Make sure RemoteBzrDirFormat is always registered (John Arbash Meinel, Robert Collins, Andrew Bennetts).
84
        self.assertTrue(RemoteBzrDirFormat in BzrDirFormat._control_formats)
1752.2.30 by Martin Pool
Start adding a RemoteBzrDir, etc
85
        self.assertIsInstance(fmt, remote.RemoteBzrDirFormat)
86
87
    def test_open_detected_smart_format(self):
88
        fmt = BzrDirFormat.find_format(self.transport)
89
        d = fmt.open(self.transport)
90
        self.assertIsInstance(d, BzrDir)
2018.5.51 by Wouter van Heyst
Test and implement RemoteBranch.last_revision_info()
91
92
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
93
class FakeProtocol(object):
94
    """Lookalike SmartClientRequestProtocolOne allowing body reading tests."""
95
96
    def __init__(self, body):
97
        self._body_buffer = StringIO(body)
98
99
    def read_body_bytes(self, count=-1):
100
        return self._body_buffer.read(count)
101
102
2018.5.51 by Wouter van Heyst
Test and implement RemoteBranch.last_revision_info()
103
class FakeClient(SmartClient):
104
    """Lookalike for SmartClient allowing testing."""
105
    
106
    def __init__(self, responses):
107
        # 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).
108
        """create a FakeClient.
109
110
        :param respones: A list of response-tuple, body-data pairs to be sent
111
            back to callers.
112
        """
2018.5.51 by Wouter van Heyst
Test and implement RemoteBranch.last_revision_info()
113
        self.responses = responses
114
        self._calls = []
115
116
    def call(self, method, *args):
117
        self._calls.append(('call', method, args))
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
118
        return self.responses.pop(0)[0]
119
120
    def call2(self, method, *args):
121
        self._calls.append(('call2', method, args))
122
        result = self.responses.pop(0)
123
        return result[0], FakeProtocol(result[1])
2018.5.51 by Wouter van Heyst
Test and implement RemoteBranch.last_revision_info()
124
125
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
126
class TestBzrDirOpenBranch(tests.TestCase):
127
128
    def test_branch_present(self):
129
        client = FakeClient([(('ok', ''), ), (('ok', ''), )])
130
        transport = MemoryTransport()
131
        transport.mkdir('quack')
132
        transport = transport.clone('quack')
133
        bzrdir = RemoteBzrDir(transport, _client=client)
134
        result = bzrdir.open_branch()
135
        self.assertEqual(
136
            [('call', 'BzrDir.open_branch', ('///quack/',)),
137
             ('call', 'BzrDir.find_repository', ('///quack/',))],
138
            client._calls)
139
        self.assertIsInstance(result, RemoteBranch)
140
        self.assertEqual(bzrdir, result.bzrdir)
141
142
    def test_branch_missing(self):
143
        client = FakeClient([(('nobranch',), )])
144
        transport = MemoryTransport()
145
        transport.mkdir('quack')
146
        transport = transport.clone('quack')
147
        bzrdir = RemoteBzrDir(transport, _client=client)
148
        self.assertRaises(errors.NotBranchError, bzrdir.open_branch)
149
        self.assertEqual(
150
            [('call', 'BzrDir.open_branch', ('///quack/',))],
151
            client._calls)
152
153
2018.5.51 by Wouter van Heyst
Test and implement RemoteBranch.last_revision_info()
154
class TestBranchLastRevisionInfo(tests.TestCase):
155
156
    def test_empty_branch(self):
157
        # in an empty branch we decode the response properly
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
158
        client = FakeClient([(('ok', '0', ''), )])
2018.5.51 by Wouter van Heyst
Test and implement RemoteBranch.last_revision_info()
159
        transport = MemoryTransport()
160
        transport.mkdir('quack')
161
        transport = transport.clone('quack')
162
        # we do not want bzrdir to make any remote calls
163
        bzrdir = RemoteBzrDir(transport, _client=False)
164
        branch = RemoteBranch(bzrdir, None, _client=client)
165
        result = branch.last_revision_info()
166
167
        self.assertEqual(
168
            [('call', 'Branch.last_revision_info', ('///quack/',))],
169
            client._calls)
170
        self.assertEqual((0, NULL_REVISION), result)
171
172
    def test_non_empty_branch(self):
173
        # in a non-empty branch we also decode the response properly
174
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
175
        client = FakeClient([(('ok', '2', u'\xc8'.encode('utf8')), )])
2018.5.51 by Wouter van Heyst
Test and implement RemoteBranch.last_revision_info()
176
        transport = MemoryTransport()
177
        transport.mkdir('kwaak')
178
        transport = transport.clone('kwaak')
179
        # we do not want bzrdir to make any remote calls
180
        bzrdir = RemoteBzrDir(transport, _client=False)
181
        branch = RemoteBranch(bzrdir, None, _client=client)
182
        result = branch.last_revision_info()
183
184
        self.assertEqual(
185
            [('call', 'Branch.last_revision_info', ('///kwaak/',))],
186
            client._calls)
187
        self.assertEqual((2, u'\xc8'), result)
2018.5.57 by Robert Collins
Implement RemoteRepository.is_shared (Robert Collins, Vincent Ladeuil).
188
189
2018.12.3 by Andrew Bennetts
Add a Branch.set_last_revision smart method, and make RemoteBranch.set_revision_history use it.
190
class TestBranchSetLastRevision(tests.TestCase):
191
192
    def test_set_empty(self):
193
        # set_revision_history([]) is translated to calling
194
        # Branch.set_last_revision(path, '') on the wire.
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
195
        client = FakeClient([
196
            # lock_write
197
            (('ok', 'branch token', 'repo token'), ),
198
            # set_last_revision
199
            (('ok',), ),
200
            # unlock
201
            (('ok',), )])
2018.12.3 by Andrew Bennetts
Add a Branch.set_last_revision smart method, and make RemoteBranch.set_revision_history use it.
202
        transport = MemoryTransport()
203
        transport.mkdir('branch')
204
        transport = transport.clone('branch')
205
206
        bzrdir = RemoteBzrDir(transport, _client=False)
207
        branch = RemoteBranch(bzrdir, None, _client=client)
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
208
        # This is a hack to work around the problem that RemoteBranch currently
209
        # unnecessarily invokes _ensure_real upon a call to lock_write.
210
        branch._ensure_real = lambda: None
211
        branch.lock_write()
212
        client._calls = []
2018.12.3 by Andrew Bennetts
Add a Branch.set_last_revision smart method, and make RemoteBranch.set_revision_history use it.
213
        result = branch.set_revision_history([])
214
        self.assertEqual(
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
215
            [('call', 'Branch.set_last_revision',
216
                ('///branch/', 'branch token', 'repo token', ''))],
2018.12.3 by Andrew Bennetts
Add a Branch.set_last_revision smart method, and make RemoteBranch.set_revision_history use it.
217
            client._calls)
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
218
        branch.unlock()
2018.12.3 by Andrew Bennetts
Add a Branch.set_last_revision smart method, and make RemoteBranch.set_revision_history use it.
219
        self.assertEqual(None, result)
220
221
    def test_set_nonempty(self):
222
        # set_revision_history([rev-id1, ..., rev-idN]) is translated to calling
223
        # 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.
224
        client = FakeClient([
225
            # lock_write
226
            (('ok', 'branch token', 'repo token'), ),
227
            # set_last_revision
228
            (('ok',), ),
229
            # unlock
230
            (('ok',), )])
2018.12.3 by Andrew Bennetts
Add a Branch.set_last_revision smart method, and make RemoteBranch.set_revision_history use it.
231
        transport = MemoryTransport()
232
        transport.mkdir('branch')
233
        transport = transport.clone('branch')
234
235
        bzrdir = RemoteBzrDir(transport, _client=False)
236
        branch = RemoteBranch(bzrdir, None, _client=client)
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
237
        # This is a hack to work around the problem that RemoteBranch currently
238
        # unnecessarily invokes _ensure_real upon a call to lock_write.
239
        branch._ensure_real = lambda: None
240
        # Lock the branch, reset the record of remote calls.
241
        branch.lock_write()
242
        client._calls = []
2018.12.3 by Andrew Bennetts
Add a Branch.set_last_revision smart method, and make RemoteBranch.set_revision_history use it.
243
244
        result = branch.set_revision_history(['rev-id1', 'rev-id2'])
245
        self.assertEqual(
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
246
            [('call', 'Branch.set_last_revision',
247
                ('///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.
248
            client._calls)
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
249
        branch.unlock()
2018.12.3 by Andrew Bennetts
Add a Branch.set_last_revision smart method, and make RemoteBranch.set_revision_history use it.
250
        self.assertEqual(None, result)
251
252
    def test_no_such_revision(self):
253
        # 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.
254
        client = FakeClient([
255
            # lock_write
256
            (('ok', 'branch token', 'repo token'), ),
257
            # set_last_revision
258
            (('NoSuchRevision', 'rev-id'), ),
259
            # unlock
260
            (('ok',), )])
2018.12.3 by Andrew Bennetts
Add a Branch.set_last_revision smart method, and make RemoteBranch.set_revision_history use it.
261
        transport = MemoryTransport()
262
        transport.mkdir('branch')
263
        transport = transport.clone('branch')
264
265
        bzrdir = RemoteBzrDir(transport, _client=False)
266
        branch = RemoteBranch(bzrdir, None, _client=client)
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
267
        branch._ensure_real = lambda: None
268
        branch.lock_write()
269
        client._calls = []
2018.12.3 by Andrew Bennetts
Add a Branch.set_last_revision smart method, and make RemoteBranch.set_revision_history use it.
270
271
        self.assertRaises(
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
272
            errors.NoSuchRevision, branch.set_revision_history, ['rev-id'])
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
273
        branch.unlock()
2018.12.3 by Andrew Bennetts
Add a Branch.set_last_revision smart method, and make RemoteBranch.set_revision_history use it.
274
275
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
276
class TestBranchControlGetBranchConf(tests.TestCase):
277
    """Test branch.control_files api munging...
278
2018.12.3 by Andrew Bennetts
Add a Branch.set_last_revision smart method, and make RemoteBranch.set_revision_history use it.
279
    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).
280
    call a specific API so that RemoteBranch's can intercept configuration
281
    file reading, allowing them to signal to the client about things like
282
    'email is configured for commits'.
283
    """
284
285
    def test_get_branch_conf(self):
286
        # in an empty branch we decode the response properly
287
        client = FakeClient([(('ok', ), 'config file body')])
288
        transport = MemoryTransport()
289
        transport.mkdir('quack')
290
        transport = transport.clone('quack')
291
        # we do not want bzrdir to make any remote calls
292
        bzrdir = RemoteBzrDir(transport, _client=False)
293
        branch = RemoteBranch(bzrdir, None, _client=client)
294
        result = branch.control_files.get('branch.conf')
295
        self.assertEqual(
296
            [('call2', 'Branch.get_config_file', ('///quack/',))],
297
            client._calls)
298
        self.assertEqual('config file body', result.read())
299
300
2018.5.67 by Wouter van Heyst
Implement RemoteRepository.get_revision_graph (Wouter van Heyst, Robert Collins)
301
class TestRemoteRepository(tests.TestCase):
2018.5.57 by Robert Collins
Implement RemoteRepository.is_shared (Robert Collins, Vincent Ladeuil).
302
303
    def setup_fake_client_and_repository(self, responses, transport_path):
304
        """Create the fake client and repository for testing with."""
305
        client = FakeClient(responses)
306
        transport = MemoryTransport()
307
        transport.mkdir(transport_path)
308
        transport = transport.clone(transport_path)
309
        # we do not want bzrdir to make any remote calls
310
        bzrdir = RemoteBzrDir(transport, _client=False)
311
        repo = RemoteRepository(bzrdir, None, _client=client)
312
        return repo, client
313
2018.5.67 by Wouter van Heyst
Implement RemoteRepository.get_revision_graph (Wouter van Heyst, Robert Collins)
314
2018.12.2 by Andrew Bennetts
Remove some duplicate code in test_remote
315
class TestRepositoryGatherStats(TestRemoteRepository):
2018.10.3 by v.ladeuil+lp at free
more tests for gather_stats
316
317
    def test_revid_none(self):
318
        # ('ok',), body with revisions and size
319
        responses = [(('ok', ), 'revisions: 2\nsize: 18\n')]
320
        transport_path = 'quack'
321
        repo, client = self.setup_fake_client_and_repository(
322
            responses, transport_path)
323
        result = repo.gather_stats(None)
324
        self.assertEqual(
325
            [('call2', 'Repository.gather_stats', ('///quack/','','no'))],
326
            client._calls)
327
        self.assertEqual({'revisions': 2, 'size': 18}, result)
328
329
    def test_revid_no_committers(self):
330
        # ('ok',), body without committers
331
        responses = [(('ok', ),
332
                      'firstrev: 123456.300 3600\n'
333
                      'latestrev: 654231.400 0\n'
334
                      'revisions: 2\n'
335
                      'size: 18\n')]
336
        transport_path = 'quick'
337
        revid = u'\xc8'
338
        repo, client = self.setup_fake_client_and_repository(
339
            responses, transport_path)
340
        result = repo.gather_stats(revid)
341
        self.assertEqual(
342
            [('call2', 'Repository.gather_stats',
343
              ('///quick/', revid.encode('utf8'), 'no'))],
344
            client._calls)
345
        self.assertEqual({'revisions': 2, 'size': 18,
346
                          'firstrev': (123456.300, 3600),
347
                          'latestrev': (654231.400, 0),},
348
                         result)
349
350
    def test_revid_with_committers(self):
351
        # ('ok',), body with committers
352
        responses = [(('ok', ),
353
                      'committers: 128\n'
354
                      'firstrev: 123456.300 3600\n'
355
                      'latestrev: 654231.400 0\n'
356
                      'revisions: 2\n'
357
                      'size: 18\n')]
358
        transport_path = 'buick'
359
        revid = u'\xc8'
360
        repo, client = self.setup_fake_client_and_repository(
361
            responses, transport_path)
362
        result = repo.gather_stats(revid, True)
363
        self.assertEqual(
364
            [('call2', 'Repository.gather_stats',
365
              ('///buick/', revid.encode('utf8'), 'yes'))],
366
            client._calls)
367
        self.assertEqual({'revisions': 2, 'size': 18,
368
                          'committers': 128,
369
                          'firstrev': (123456.300, 3600),
370
                          'latestrev': (654231.400, 0),},
371
                         result)
372
373
2018.5.68 by Wouter van Heyst
Merge RemoteRepository.gather_stats.
374
class TestRepositoryGetRevisionGraph(TestRemoteRepository):
375
    
376
    def test_null_revision(self):
377
        # a null revision has the predictable result {}, we should have no wire
378
        # traffic when calling it with this argument
379
        responses = [(('notused', ), '')]
380
        transport_path = 'empty'
381
        repo, client = self.setup_fake_client_and_repository(
382
            responses, transport_path)
383
        result = repo.get_revision_graph(NULL_REVISION)
384
        self.assertEqual([], client._calls)
385
        self.assertEqual({}, result)
386
2018.5.67 by Wouter van Heyst
Implement RemoteRepository.get_revision_graph (Wouter van Heyst, Robert Collins)
387
    def test_none_revision(self):
388
        # with none we want the entire graph
389
        r1 = u'\u0e33'
390
        r2 = u'\u0dab'
391
        lines = [' '.join([r2, r1]), r1]
392
        encoded_body = '\n'.join(lines).encode('utf8')
393
394
        responses = [(('ok', ), encoded_body)]
395
        transport_path = 'sinhala'
396
        repo, client = self.setup_fake_client_and_repository(
397
            responses, transport_path)
398
        result = repo.get_revision_graph()
399
        self.assertEqual(
400
            [('call2', 'Repository.get_revision_graph', ('///sinhala/', ''))],
401
            client._calls)
402
        self.assertEqual({r1: [], r2: [r1]}, result)
403
404
    def test_specific_revision(self):
405
        # with a specific revision we want the graph for that
406
        # with none we want the entire graph
407
        r11 = u'\u0e33'
408
        r12 = u'\xc9'
409
        r2 = u'\u0dab'
410
        lines = [' '.join([r2, r11, r12]), r11, r12]
411
        encoded_body = '\n'.join(lines).encode('utf8')
412
413
        responses = [(('ok', ), encoded_body)]
414
        transport_path = 'sinhala'
415
        repo, client = self.setup_fake_client_and_repository(
416
            responses, transport_path)
417
        result = repo.get_revision_graph(r2)
418
        self.assertEqual(
419
            [('call2', 'Repository.get_revision_graph', ('///sinhala/', r2.encode('utf8')))],
420
            client._calls)
421
        self.assertEqual({r11: [], r12: [], r2: [r11, r12], }, result)
422
423
    def test_no_such_revision(self):
424
        revid = '123'
425
        responses = [(('nosuchrevision', revid), '')]
426
        transport_path = 'sinhala'
427
        repo, client = self.setup_fake_client_and_repository(
428
            responses, transport_path)
429
        # 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
430
        self.assertRaises(errors.NoSuchRevision,
2018.5.67 by Wouter van Heyst
Implement RemoteRepository.get_revision_graph (Wouter van Heyst, Robert Collins)
431
            repo.get_revision_graph, revid)
432
        self.assertEqual(
433
            [('call2', 'Repository.get_revision_graph', ('///sinhala/', revid))],
434
            client._calls)
435
436
        
437
class TestRepositoryIsShared(TestRemoteRepository):
438
2018.5.57 by Robert Collins
Implement RemoteRepository.is_shared (Robert Collins, Vincent Ladeuil).
439
    def test_is_shared(self):
440
        # ('yes', ) for Repository.is_shared -> 'True'.
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
441
        responses = [(('yes', ), )]
2018.5.57 by Robert Collins
Implement RemoteRepository.is_shared (Robert Collins, Vincent Ladeuil).
442
        transport_path = 'quack'
443
        repo, client = self.setup_fake_client_and_repository(
444
            responses, transport_path)
445
        result = repo.is_shared()
446
        self.assertEqual(
447
            [('call', 'Repository.is_shared', ('///quack/',))],
448
            client._calls)
449
        self.assertEqual(True, result)
450
451
    def test_is_not_shared(self):
452
        # ('no', ) for Repository.is_shared -> 'False'.
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
453
        responses = [(('no', ), )]
2018.5.57 by Robert Collins
Implement RemoteRepository.is_shared (Robert Collins, Vincent Ladeuil).
454
        transport_path = 'qwack'
455
        repo, client = self.setup_fake_client_and_repository(
456
            responses, transport_path)
457
        result = repo.is_shared()
458
        self.assertEqual(
459
            [('call', 'Repository.is_shared', ('///qwack/',))],
460
            client._calls)
461
        self.assertEqual(False, result)
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
462
463
464
class TestRepositoryLockWrite(TestRemoteRepository):
465
466
    def test_lock_write(self):
467
        responses = [(('ok', 'a token'), '')]
468
        transport_path = 'quack'
469
        repo, client = self.setup_fake_client_and_repository(
470
            responses, transport_path)
471
        result = repo.lock_write()
472
        self.assertEqual(
473
            [('call', 'Repository.lock_write', ('///quack/',))],
474
            client._calls)
475
        self.assertEqual('a token', result)
476
477
    def test_lock_write_already_locked(self):
478
        responses = [(('LockContention', ), '')]
479
        transport_path = 'quack'
480
        repo, client = self.setup_fake_client_and_repository(
481
            responses, transport_path)
482
        self.assertRaises(errors.LockContention, repo.lock_write)
483
        self.assertEqual(
484
            [('call', 'Repository.lock_write', ('///quack/',))],
485
            client._calls)
486
487
488
class TestRepositoryUnlock(TestRemoteRepository):
489
490
    def test_unlock(self):
491
        responses = [(('ok', 'a token'), ''),
492
                     (('ok',), '')]
493
        transport_path = 'quack'
494
        repo, client = self.setup_fake_client_and_repository(
495
            responses, transport_path)
496
        repo.lock_write()
497
        repo.unlock()
498
        self.assertEqual(
499
            [('call', 'Repository.lock_write', ('///quack/',)),
500
             ('call', 'Repository.unlock', ('///quack/', 'a token'))],
501
            client._calls)
502
503
    def test_unlock_wrong_token(self):
504
        # If somehow the token is wrong, unlock will raise TokenMismatch.
505
        responses = [(('ok', 'a token'), ''),
506
                     (('TokenMismatch',), '')]
507
        transport_path = 'quack'
508
        repo, client = self.setup_fake_client_and_repository(
509
            responses, transport_path)
510
        repo.lock_write()
511
        self.assertRaises(errors.TokenMismatch, repo.unlock)
512
513
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
514
class TestRepositoryHasRevision(TestRemoteRepository):
515
516
    def test_none(self):
517
        # repo.has_revision(None) should not cause any traffic.
518
        transport_path = 'quack'
519
        responses = None
520
        repo, client = self.setup_fake_client_and_repository(
521
            responses, transport_path)
522
523
        # The null revision is always there, so has_revision(None) == True.
524
        self.assertEqual(True, repo.has_revision(None))
525
526
        # The remote repo shouldn't be accessed.
527
        self.assertEqual([], client._calls)
528
529