113
114
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
117
class FakeProtocol(object):
149
118
"""Lookalike SmartClientRequestProtocolOne allowing body reading tests."""
375
361
client.add_expected_call(
376
362
'Branch.get_stacked_on_url', ('quack/',),
377
363
'error', ('NotStacked',))
378
bzrdir = RemoteBzrDir(transport, _client=client)
364
bzrdir = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
379
366
result = bzrdir.open_branch()
380
367
self.assertIsInstance(result, RemoteBranch)
381
368
self.assertEqual(bzrdir, result.bzrdir)
468
459
RemoteBzrDirFormat.probe_transport, OldServerTransport())
462
class TestBzrDirCreateBranch(TestRemote):
464
def test_backwards_compat(self):
465
self.setup_smart_server_with_call_log()
466
repo = self.make_repository('.')
467
self.reset_smart_call_log()
468
self.disable_verb('BzrDir.create_branch')
469
branch = repo.bzrdir.create_branch()
470
create_branch_call_count = len([call for call in self.hpss_calls if
471
call[0].method == 'BzrDir.create_branch'])
472
self.assertEqual(1, create_branch_call_count)
474
def test_current_server(self):
475
transport = self.get_transport('.')
476
transport = transport.clone('quack')
477
self.make_repository('quack')
478
client = FakeClient(transport.base)
479
reference_bzrdir_format = bzrdir.format_registry.get('default')()
480
reference_format = reference_bzrdir_format.get_branch_format()
481
network_name = reference_format.network_name()
482
reference_repo_fmt = reference_bzrdir_format.repository_format
483
reference_repo_name = reference_repo_fmt.network_name()
484
client.add_expected_call(
485
'BzrDir.create_branch', ('quack/', network_name),
486
'success', ('ok', network_name, '', 'no', 'no', 'yes',
487
reference_repo_name))
488
a_bzrdir = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
490
branch = a_bzrdir.create_branch()
491
# We should have got a remote branch
492
self.assertIsInstance(branch, remote.RemoteBranch)
493
# its format should have the settings from the response
494
format = branch._format
495
self.assertEqual(network_name, format.network_name())
498
class TestBzrDirCreateRepository(TestRemote):
500
def test_backwards_compat(self):
501
self.setup_smart_server_with_call_log()
502
bzrdir = self.make_bzrdir('.')
503
self.reset_smart_call_log()
504
self.disable_verb('BzrDir.create_repository')
505
repo = bzrdir.create_repository()
506
create_repo_call_count = len([call for call in self.hpss_calls if
507
call[0].method == 'BzrDir.create_repository'])
508
self.assertEqual(1, create_repo_call_count)
510
def test_current_server(self):
511
transport = self.get_transport('.')
512
transport = transport.clone('quack')
513
self.make_bzrdir('quack')
514
client = FakeClient(transport.base)
515
reference_bzrdir_format = bzrdir.format_registry.get('default')()
516
reference_format = reference_bzrdir_format.repository_format
517
network_name = reference_format.network_name()
518
client.add_expected_call(
519
'BzrDir.create_repository', ('quack/',
520
'Bazaar pack repository format 1 (needs bzr 0.92)\n', 'False'),
521
'success', ('ok', 'no', 'no', 'no', network_name))
522
a_bzrdir = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
524
repo = a_bzrdir.create_repository()
525
# We should have got a remote repository
526
self.assertIsInstance(repo, remote.RemoteRepository)
527
# its format should have the settings from the response
528
format = repo._format
529
self.assertFalse(format.rich_root_data)
530
self.assertFalse(format.supports_tree_reference)
531
self.assertFalse(format.supports_external_lookups)
532
self.assertEqual(network_name, format.network_name())
471
535
class TestBzrDirOpenRepository(tests.TestCase):
473
537
def test_backwards_compat_1_2(self):
475
539
transport.mkdir('quack')
476
540
transport = transport.clone('quack')
477
541
client = FakeClient(transport.base)
478
client.add_unknown_method_response('RemoteRepository.find_repositoryV2')
542
client.add_unknown_method_response('BzrDir.find_repositoryV2')
479
543
client.add_success_response('ok', '', 'no', 'no')
480
bzrdir = RemoteBzrDir(transport, _client=client)
544
bzrdir = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
481
546
repo = bzrdir.open_repository()
482
547
self.assertEqual(
483
548
[('call', 'BzrDir.find_repositoryV2', ('quack/',)),
518
583
def make_remote_branch(self, transport, client):
519
584
"""Make a RemoteBranch using 'client' as its _SmartClient.
521
586
A RemoteBzrDir and RemoteRepository will also be created to fill out
522
587
the RemoteBranch, albeit with stub values for some of their attributes.
524
589
# we do not want bzrdir to make any remote calls, so use False as its
525
590
# _client. If it tries to make a remote call, this will fail
527
bzrdir = RemoteBzrDir(transport, _client=False)
592
bzrdir = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
528
594
repo = RemoteRepository(bzrdir, None, _client=client)
529
595
return RemoteBranch(bzrdir, repo, _client=client)
570
636
"""Test Branch._get_stacked_on_url rpc"""
572
638
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:///')
639
# test that asking for a stacked on url the server can't access works.
640
# This isn't perfect, but then as we're in the same process there
641
# really isn't anything we can do to be 100% sure that the server
642
# doesn't just open in - this test probably needs to be rewritten using
643
# a spawn()ed server.
644
stacked_branch = self.make_branch('stacked', format='1.9')
645
memory_branch = self.make_branch('base', format='1.9')
646
vfs_url = self.get_vfs_only_url('base')
647
stacked_branch.set_stacked_on_url(vfs_url)
648
transport = stacked_branch.bzrdir.root_transport
575
649
client = FakeClient(transport.base)
576
650
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)
651
'Branch.get_stacked_on_url', ('stacked/',),
652
'success', ('ok', vfs_url))
653
# XXX: Multiple calls are bad, this second call documents what is
655
client.add_expected_call(
656
'Branch.get_stacked_on_url', ('stacked/',),
657
'success', ('ok', vfs_url))
658
bzrdir = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
660
branch = RemoteBranch(bzrdir, RemoteRepository(bzrdir, None),
581
662
result = branch.get_stacked_on_url()
583
'file:///stacked/on', result)
663
self.assertEqual(vfs_url, result)
585
665
def test_backwards_compatible(self):
586
666
# like with bzr1.6 with no Branch.get_stacked_on_url rpc
603
683
'unknown', ('Branch.get_stacked_on_url',))
604
684
# this will also do vfs access, but that goes direct to the transport
605
685
# and isn't seen by the FakeClient.
606
bzrdir = RemoteBzrDir(self.get_transport('stacked'), _client=client)
686
bzrdir = RemoteBzrDir(self.get_transport('stacked'),
687
remote.RemoteBzrDirFormat(), _client=client)
607
688
branch = bzrdir.open_branch()
608
689
result = branch.get_stacked_on_url()
609
690
self.assertEqual('../base', result)
632
713
client.add_expected_call(
633
714
'Branch.get_stacked_on_url', ('stacked/',),
634
715
'success', ('ok', '../base'))
635
bzrdir = RemoteBzrDir(self.get_transport('stacked'), _client=client)
716
bzrdir = RemoteBzrDir(self.get_transport('stacked'),
717
remote.RemoteBzrDirFormat(), _client=client)
636
718
branch = bzrdir.open_branch()
637
719
result = branch.get_stacked_on_url()
638
720
self.assertEqual('../base', result)
661
743
'Branch.lock_write', ('branch/', '', ''),
662
744
'success', ('ok', 'branch token', 'repo token'))
663
745
client.add_expected_call(
746
'Branch.last_revision_info',
748
'success', ('ok', '0', 'null:'))
749
client.add_expected_call(
664
750
'Branch.set_last_revision', ('branch/', 'branch token', 'repo token', 'null:',),
665
751
'success', ('ok',))
666
752
client.add_expected_call(
691
777
'Branch.lock_write', ('branch/', '', ''),
692
778
'success', ('ok', 'branch token', 'repo token'))
693
779
client.add_expected_call(
780
'Branch.last_revision_info',
782
'success', ('ok', '0', 'null:'))
784
encoded_body = bz2.compress('\n'.join(lines))
785
client.add_success_response_with_body(encoded_body, 'ok')
786
client.add_expected_call(
694
787
'Branch.set_last_revision', ('branch/', 'branch token', 'repo token', 'rev-id2',),
695
788
'success', ('ok',))
696
789
client.add_expected_call(
720
813
'Branch.lock_write', ('branch/', '', ''),
721
814
'success', ('ok', 'branch token', 'repo token'))
722
815
client.add_expected_call(
816
'Branch.last_revision_info',
818
'success', ('ok', '0', 'null:'))
819
# get_graph calls to construct the revision history, for the set_rh
822
encoded_body = bz2.compress('\n'.join(lines))
823
client.add_success_response_with_body(encoded_body, 'ok')
824
client.add_expected_call(
723
825
'Branch.set_last_revision', ('branch/', 'branch token', 'repo token', 'rev-id',),
724
826
'error', ('NoSuchRevision', 'rev-id'))
725
827
client.add_expected_call(
750
852
'Branch.lock_write', ('branch/', '', ''),
751
853
'success', ('ok', 'branch token', 'repo token'))
752
854
client.add_expected_call(
855
'Branch.last_revision_info',
857
'success', ('ok', '0', 'null:'))
859
encoded_body = bz2.compress('\n'.join(lines))
860
client.add_success_response_with_body(encoded_body, 'ok')
861
client.add_expected_call(
753
862
'Branch.set_last_revision', ('branch/', 'branch token', 'repo token', 'rev-id',),
754
863
'error', ('TipChangeRejected', rejection_msg_utf8))
755
864
client.add_expected_call(
855
966
'Branch.get_stacked_on_url', ('branch/',),
856
967
'error', ('NotStacked',))
857
968
client.add_expected_call(
969
'Branch.last_revision_info',
971
'success', ('ok', '0', 'null:'))
972
client.add_expected_call(
858
973
'Branch.set_last_revision_info',
859
974
('branch/', 'branch token', 'repo token', '1234', 'a-revision-id',),
860
975
'unknown', 'Branch.set_last_revision_info')
1050
1165
self.assertEqual('bar', t._get_credentials()[0])
1053
class TestRemoteRepository(tests.TestCase):
1168
class TestRemoteRepository(TestRemote):
1054
1169
"""Base for testing RemoteRepository protocol usage.
1056
These tests contain frozen requests and responses. We want any changes to
1171
These tests contain frozen requests and responses. We want any changes to
1057
1172
what is sent or expected to be require a thoughtful update to these tests
1058
1173
because they might break compatibility with different-versioned servers.
1061
1176
def setup_fake_client_and_repository(self, transport_path):
1062
1177
"""Create the fake client and repository for testing with.
1064
1179
There's no real server here; we just have canned responses sent
1065
1180
back one by one.
1067
1182
:param transport_path: Path below the root of the MemoryTransport
1068
1183
where the repository will be created.
1511
class TestRepositorySetMakeWorkingTrees(TestRemoteRepository):
1513
def test_backwards_compat(self):
1514
self.setup_smart_server_with_call_log()
1515
repo = self.make_repository('.')
1516
self.reset_smart_call_log()
1517
verb = 'Repository.set_make_working_trees'
1518
self.disable_verb(verb)
1519
repo.set_make_working_trees(True)
1520
call_count = len([call for call in self.hpss_calls if
1521
call[0].method == verb])
1522
self.assertEqual(1, call_count)
1524
def test_current(self):
1525
transport_path = 'quack'
1526
repo, client = self.setup_fake_client_and_repository(transport_path)
1527
client.add_expected_call(
1528
'Repository.set_make_working_trees', ('quack/', 'True'),
1530
client.add_expected_call(
1531
'Repository.set_make_working_trees', ('quack/', 'False'),
1533
repo.set_make_working_trees(True)
1534
repo.set_make_working_trees(False)
1395
1537
class TestRepositoryUnlock(TestRemoteRepository):
1397
1539
def test_unlock(self):