72
72
tests.TestCaseWithTransport.tearDown(self)
74
74
def test_create_remote_bzrdir(self):
75
b = remote.RemoteBzrDir(self.transport)
75
b = remote.RemoteBzrDir(self.transport, remote.RemoteBzrDirFormat())
76
76
self.assertIsInstance(b, BzrDir)
78
78
def test_open_remote_branch(self):
79
79
# open a standalone branch in the working directory
80
b = remote.RemoteBzrDir(self.transport)
80
b = remote.RemoteBzrDir(self.transport, remote.RemoteBzrDirFormat())
81
81
branch = b.open_branch()
82
82
self.assertIsInstance(branch, Branch)
113
113
self.assertStartsWith(str(b), 'RemoteBranch(')
116
class FakeRemoteTransport(object):
117
"""This class provides the minimum support for use in place of a RemoteTransport.
119
It doesn't actually transmit requests, but rather expects them to be
120
handled by a FakeClient which holds canned responses. It does not allow
121
any vfs access, therefore is not suitable for testing any operation that
122
will fallback to vfs access. Backing the test by an instance of this
123
class guarantees that it's - done using non-vfs operations.
126
_default_url = 'fakeremotetransport://host/path/'
128
def __init__(self, url=None):
130
url = self._default_url
134
return "%r(%r)" % (self.__class__.__name__,
137
def clone(self, relpath):
138
return FakeRemoteTransport(urlutils.join(self.base, relpath))
140
def get(self, relpath):
141
# only get is specifically stubbed out, because it's usually the first
142
# thing we do. anything else will fail with an AttributeError.
143
raise AssertionError("%r doesn't support file access to %r"
148
116
class FakeProtocol(object):
149
117
"""Lookalike SmartClientRequestProtocolOne allowing body reading tests."""
178
146
self.expecting_body = False
179
147
# if non-None, this is the list of expected calls, with only the
180
148
# method name and arguments included. the body might be hard to
181
# compute so is not included
149
# compute so is not included. If a call is None, that call can
182
151
self._expected_calls = None
183
152
_SmartClient.__init__(self, FakeMedium(self._calls, fake_medium_base))
195
164
def add_success_response_with_body(self, body, *args):
196
165
self.responses.append(('success', args, body))
166
if self._expected_calls is not None:
167
self._expected_calls.append(None)
198
169
def add_error_response(self, *args):
199
170
self.responses.append(('error', args))
375
348
client.add_expected_call(
376
349
'Branch.get_stacked_on_url', ('quack/',),
377
350
'error', ('NotStacked',))
378
bzrdir = RemoteBzrDir(transport, _client=client)
351
bzrdir = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
379
353
result = bzrdir.open_branch()
380
354
self.assertIsInstance(result, RemoteBranch)
381
355
self.assertEqual(bzrdir, result.bzrdir)
387
361
transport = transport.clone('quack')
388
362
client = FakeClient(transport.base)
389
363
client.add_error_response('nobranch')
390
bzrdir = RemoteBzrDir(transport, _client=client)
364
bzrdir = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
391
366
self.assertRaises(errors.NotBranchError, bzrdir.open_branch)
392
367
self.assertEqual(
393
368
[('call', 'BzrDir.open_branch', ('quack/',))],
403
378
transport = MemoryTransport()
404
379
# no requests on the network - catches other api calls being made.
405
380
client = FakeClient(transport.base)
406
bzrdir = RemoteBzrDir(transport, _client=client)
381
bzrdir = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
407
383
# patch the open_branch call to record that it was called.
408
384
bzrdir.open_branch = open_branch
409
385
self.assertEqual((None, "a-branch"), bzrdir._get_tree_branch())
424
400
client.add_expected_call(
425
401
'Branch.get_stacked_on_url', ('~hello/',),
426
402
'error', ('NotStacked',))
427
bzrdir = RemoteBzrDir(transport, _client=client)
403
bzrdir = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
428
405
result = bzrdir.open_branch()
429
406
client.finished_test()
443
420
client = FakeClient(transport.base)
444
421
client.add_success_response(
445
422
'ok', '', rich_response, subtree_response, external_lookup)
446
bzrdir = RemoteBzrDir(transport, _client=client)
423
bzrdir = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
447
425
result = bzrdir.open_repository()
448
426
self.assertEqual(
449
427
[('call', 'BzrDir.find_repositoryV2', ('quack/',))],
477
455
client = FakeClient(transport.base)
478
456
client.add_unknown_method_response('RemoteRepository.find_repositoryV2')
479
457
client.add_success_response('ok', '', 'no', 'no')
480
bzrdir = RemoteBzrDir(transport, _client=client)
458
bzrdir = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
481
460
repo = bzrdir.open_repository()
482
461
self.assertEqual(
483
462
[('call', 'BzrDir.find_repositoryV2', ('quack/',)),
524
503
# we do not want bzrdir to make any remote calls, so use False as its
525
504
# _client. If it tries to make a remote call, this will fail
527
bzrdir = RemoteBzrDir(transport, _client=False)
506
bzrdir = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
528
508
repo = RemoteRepository(bzrdir, None, _client=client)
529
509
return RemoteBranch(bzrdir, repo, _client=client)
570
550
"""Test Branch._get_stacked_on_url rpc"""
572
552
def test_get_stacked_on_invalid_url(self):
573
raise tests.KnownFailure('opening a branch requires the server to open the fallback repository')
574
transport = FakeRemoteTransport('fakeremotetransport:///')
553
# test that asking for a stacked on url the server can't access works.
554
# This isn't perfect, but then as we're in the same process there
555
# really isn't anything we can do to be 100% sure that the server
556
# doesn't just open in - this test probably needs to be rewritten using
557
# a spawn()ed server.
558
stacked_branch = self.make_branch('stacked', format='1.9')
559
memory_branch = self.make_branch('base', format='1.9')
560
vfs_url = self.get_vfs_only_url('base')
561
stacked_branch.set_stacked_on_url(vfs_url)
562
transport = stacked_branch.bzrdir.root_transport
575
563
client = FakeClient(transport.base)
576
564
client.add_expected_call(
577
'Branch.get_stacked_on_url', ('.',),
578
'success', ('ok', 'file:///stacked/on'))
579
bzrdir = RemoteBzrDir(transport, _client=client)
580
branch = RemoteBranch(bzrdir, None, _client=client)
565
'Branch.get_stacked_on_url', ('stacked/',),
566
'success', ('ok', vfs_url))
567
# XXX: Multiple calls are bad, this second call documents what is
569
client.add_expected_call(
570
'Branch.get_stacked_on_url', ('stacked/',),
571
'success', ('ok', vfs_url))
572
bzrdir = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
574
branch = RemoteBranch(bzrdir, RemoteRepository(bzrdir, None),
581
576
result = branch.get_stacked_on_url()
583
'file:///stacked/on', result)
577
self.assertEqual(vfs_url, result)
585
579
def test_backwards_compatible(self):
586
580
# like with bzr1.6 with no Branch.get_stacked_on_url rpc
603
597
'unknown', ('Branch.get_stacked_on_url',))
604
598
# this will also do vfs access, but that goes direct to the transport
605
599
# and isn't seen by the FakeClient.
606
bzrdir = RemoteBzrDir(self.get_transport('stacked'), _client=client)
600
bzrdir = RemoteBzrDir(self.get_transport('stacked'),
601
remote.RemoteBzrDirFormat(), _client=client)
607
602
branch = bzrdir.open_branch()
608
603
result = branch.get_stacked_on_url()
609
604
self.assertEqual('../base', result)
632
627
client.add_expected_call(
633
628
'Branch.get_stacked_on_url', ('stacked/',),
634
629
'success', ('ok', '../base'))
635
bzrdir = RemoteBzrDir(self.get_transport('stacked'), _client=client)
630
bzrdir = RemoteBzrDir(self.get_transport('stacked'),
631
remote.RemoteBzrDirFormat(), _client=client)
636
632
branch = bzrdir.open_branch()
637
633
result = branch.get_stacked_on_url()
638
634
self.assertEqual('../base', result)
661
657
'Branch.lock_write', ('branch/', '', ''),
662
658
'success', ('ok', 'branch token', 'repo token'))
663
659
client.add_expected_call(
660
'Branch.last_revision_info',
662
'success', ('ok', '0', 'null:'))
663
client.add_expected_call(
664
664
'Branch.set_last_revision', ('branch/', 'branch token', 'repo token', 'null:',),
665
665
'success', ('ok',))
666
666
client.add_expected_call(
691
691
'Branch.lock_write', ('branch/', '', ''),
692
692
'success', ('ok', 'branch token', 'repo token'))
693
693
client.add_expected_call(
694
'Branch.last_revision_info',
696
'success', ('ok', '0', 'null:'))
698
encoded_body = bz2.compress('\n'.join(lines))
699
client.add_success_response_with_body(encoded_body, 'ok')
700
client.add_expected_call(
694
701
'Branch.set_last_revision', ('branch/', 'branch token', 'repo token', 'rev-id2',),
695
702
'success', ('ok',))
696
703
client.add_expected_call(
720
727
'Branch.lock_write', ('branch/', '', ''),
721
728
'success', ('ok', 'branch token', 'repo token'))
722
729
client.add_expected_call(
730
'Branch.last_revision_info',
732
'success', ('ok', '0', 'null:'))
733
# get_graph calls to construct the revision history, for the set_rh
736
encoded_body = bz2.compress('\n'.join(lines))
737
client.add_success_response_with_body(encoded_body, 'ok')
738
client.add_expected_call(
723
739
'Branch.set_last_revision', ('branch/', 'branch token', 'repo token', 'rev-id',),
724
740
'error', ('NoSuchRevision', 'rev-id'))
725
741
client.add_expected_call(
750
766
'Branch.lock_write', ('branch/', '', ''),
751
767
'success', ('ok', 'branch token', 'repo token'))
752
768
client.add_expected_call(
769
'Branch.last_revision_info',
771
'success', ('ok', '0', 'null:'))
773
encoded_body = bz2.compress('\n'.join(lines))
774
client.add_success_response_with_body(encoded_body, 'ok')
775
client.add_expected_call(
753
776
'Branch.set_last_revision', ('branch/', 'branch token', 'repo token', 'rev-id',),
754
777
'error', ('TipChangeRejected', rejection_msg_utf8))
755
778
client.add_expected_call(
784
807
client.add_error_response('NotStacked')
786
809
client.add_success_response('ok', 'branch token', 'repo token')
810
# query the current revision
811
client.add_success_response('ok', '0', 'null:')
787
812
# set_last_revision
788
813
client.add_success_response('ok')
795
820
client._calls = []
796
821
result = branch.set_last_revision_info(1234, 'a-revision-id')
797
822
self.assertEqual(
798
[('call', 'Branch.set_last_revision_info',
823
[('call', 'Branch.last_revision_info', ('branch/',)),
824
('call', 'Branch.set_last_revision_info',
799
825
('branch/', 'branch token', 'repo token',
800
826
'1234', 'a-revision-id'))],
855
881
'Branch.get_stacked_on_url', ('branch/',),
856
882
'error', ('NotStacked',))
857
883
client.add_expected_call(
884
'Branch.last_revision_info',
886
'success', ('ok', '0', 'null:'))
887
client.add_expected_call(
858
888
'Branch.set_last_revision_info',
859
889
('branch/', 'branch token', 'repo token', '1234', 'a-revision-id',),
860
890
'unknown', 'Branch.set_last_revision_info')
1072
1102
client = FakeClient(transport.base)
1073
1103
transport = transport.clone(transport_path)
1074
1104
# we do not want bzrdir to make any remote calls
1075
bzrdir = RemoteBzrDir(transport, _client=False)
1105
bzrdir = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
1076
1107
repo = RemoteRepository(bzrdir, None, _client=client)
1077
1108
return repo, client