257
258
def _get_next_response(self):
259
260
response_tuple = self.responses.pop(0)
260
except IndexError as e:
261
raise AssertionError("%r didn't expect any more calls"
262
raise AssertionError("%r didn't expect any more calls" % (self,))
263
263
if response_tuple[0] == b'unknown':
264
264
raise errors.UnknownSmartMethod(response_tuple[1])
265
265
elif response_tuple[0] == b'error':
279
279
if next_call is None:
281
281
if method != next_call[0] or args != next_call[1]:
282
raise AssertionError("%r expected %r%r "
284
% (self, next_call[0], next_call[1], method, args,))
282
raise AssertionError(
283
"%r expected %r%r but got %r%r" %
284
(self, next_call[0], next_call[1], method, args,))
286
286
def call(self, method, *args):
287
287
self._check_call(method, args)
449
449
self.reset_smart_call_log()
450
450
verb = b'BzrDir.cloning_metadir'
451
451
self.disable_verb(verb)
452
format = a_dir.cloning_metadir()
452
a_dir.cloning_metadir()
453
453
call_count = len([call for call in self.hpss_calls if
454
454
call.call.method == verb])
455
455
self.assertEqual(1, call_count)
499
499
def test_unknown(self):
500
500
transport = self.get_transport('quack')
501
501
referenced = self.make_branch('referenced')
502
expected = referenced.controldir.cloning_metadir()
502
referenced.controldir.cloning_metadir()
503
503
client = FakeClient(transport.base)
504
504
client.add_expected_call(
505
505
b'BzrDir.cloning_metadir', (b'quack/', b'False'),
586
586
def test_destroy_default(self):
587
587
transport = self.get_transport('quack')
588
referenced = self.make_branch('referenced')
588
self.make_branch('referenced')
589
589
client = FakeClient(transport.base)
590
590
client.add_expected_call(
591
591
b'BzrDir.destroy_branch', (b'quack/', ),
649
649
client.add_expected_call(
650
650
b'BzrDir.open_2.1', (b'quack/',), b'success', (b'no',))
651
651
self.assertRaises(errors.NotBranchError, RemoteBzrDir, transport,
652
RemoteBzrDirFormat(), _client=client, _force_probe=True)
652
RemoteBzrDirFormat(), _client=client,
653
654
self.assertFinished(client)
655
656
def test_present_without_workingtree(self):
677
678
def test_backwards_compat(self):
678
679
client, transport = self.make_fake_client_and_transport()
679
680
client.add_expected_call(
680
b'BzrDir.open_2.1', (b'quack/',), b'unknown', (b'BzrDir.open_2.1',))
681
b'BzrDir.open_2.1', (b'quack/',), b'unknown',
682
(b'BzrDir.open_2.1',))
681
683
client.add_expected_call(
682
684
b'BzrDir.open', (b'quack/',), b'success', (b'yes',))
683
685
bd = RemoteBzrDir(transport, RemoteBzrDirFormat(),
700
702
client._check_call(method, args)
701
703
client._check_call = check_call
702
704
client.add_expected_call(
703
b'BzrDir.open_2.1', (b'quack/',), b'unknown', (b'BzrDir.open_2.1',))
705
b'BzrDir.open_2.1', (b'quack/',), b'unknown',
706
(b'BzrDir.open_2.1',))
704
707
client.add_expected_call(
705
708
b'BzrDir.open', (b'quack/',), b'success', (b'yes',))
706
709
bd = RemoteBzrDir(transport, RemoteBzrDirFormat(),
718
721
self.reset_smart_call_log()
719
722
verb = b'BzrDir.open_branchV3'
720
723
self.disable_verb(verb)
721
format = a_dir.open_branch()
722
725
call_count = len([call for call in self.hpss_calls if
723
726
call.call.method == verb])
724
727
self.assertEqual(1, call_count)
798
801
b'error', (b'NotStacked',))
799
802
bzrdir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
801
result = bzrdir.open_branch()
802
805
self.assertFinished(client)
804
def check_open_repository(self, rich_root, subtrees, external_lookup=b'no'):
807
def check_open_repository(self, rich_root, subtrees,
808
external_lookup=b'no'):
805
809
reference_format = self.get_repo_format()
806
810
network_name = reference_format.network_name()
807
811
transport = MemoryTransport()
841
845
"""RemoteBzrDirFormat should fail to probe if the server version is too
844
self.assertRaises(errors.NotBranchError,
845
RemoteBzrProber.probe_transport, OldServerTransport())
849
errors.NotBranchError,
850
RemoteBzrProber.probe_transport, OldServerTransport())
848
853
class TestBzrDirCreateBranch(TestRemote):
852
857
repo = self.make_repository('.')
853
858
self.reset_smart_call_log()
854
859
self.disable_verb(b'BzrDir.create_branch')
855
branch = repo.controldir.create_branch()
856
create_branch_call_count = len([call for call in self.hpss_calls if
857
call.call.method == b'BzrDir.create_branch'])
860
repo.controldir.create_branch()
861
create_branch_call_count = len(
862
[call for call in self.hpss_calls
863
if call.call.method == b'BzrDir.create_branch'])
858
864
self.assertEqual(1, create_branch_call_count)
860
866
def test_current_server(self):
916
922
bzrdir = self.make_controldir('.')
917
923
self.reset_smart_call_log()
918
924
self.disable_verb(b'BzrDir.create_repository')
919
repo = bzrdir.create_repository()
925
bzrdir.create_repository()
920
926
create_repo_call_count = len([call for call in self.hpss_calls if
921
927
call.call.method == b'BzrDir.create_repository'])
922
928
self.assertEqual(1, create_repo_call_count)
1013
1019
('call', b'BzrDir.find_repositoryV2', (b'quack/',)),
1014
1020
('call_expecting_body', b'get', (b'/quack/.bzr/branch-format',)),
1015
1021
('call', b'stat', (b'/quack/.bzr',)),
1016
('call_expecting_body', b'get', (b'/quack/.bzr/repository/format',)),
1022
('call_expecting_body', b'get',
1023
(b'/quack/.bzr/repository/format',)),
1017
1024
('call', b'stat', (b'/quack/.bzr/repository',)),
1055
1062
# XXX: It would be better to call fmt.initialize_on_transport_ex, but
1056
1063
# it's currently hard to test that without supplying a real remote
1057
1064
# transport connected to a real server.
1058
result = fmt._initialize_on_transport_ex_rpc(client, b'path',
1059
transport, False, False, False, None, None, None, None, False)
1065
fmt._initialize_on_transport_ex_rpc(
1066
client, b'path', transport, False, False, False, None, None, None,
1060
1068
self.assertFinished(client)
1062
1070
def test_error(self):
1076
1084
# XXX: It would be better to call fmt.initialize_on_transport_ex, but
1077
1085
# it's currently hard to test that without supplying a real remote
1078
1086
# transport connected to a real server.
1079
err = self.assertRaises(errors.PermissionDenied,
1080
fmt._initialize_on_transport_ex_rpc, client, b'path', transport,
1081
False, False, False, None, None, None, None, False)
1087
err = self.assertRaises(
1088
errors.PermissionDenied,
1089
fmt._initialize_on_transport_ex_rpc, client, b'path', transport,
1090
False, False, False, None, None, None, None, False)
1082
1091
self.assertEqual('path', err.path)
1083
1092
self.assertEqual(': extra info', err.extra)
1084
1093
self.assertFinished(client)
1088
1097
transport = self.make_smart_server('foo')
1089
1098
transport = transport.clone('no-such-path')
1090
1099
fmt = RemoteBzrDirFormat()
1091
err = self.assertRaises(errors.NoSuchFile,
1092
fmt.initialize_on_transport_ex, transport, create_prefix=False)
1101
errors.NoSuchFile, fmt.initialize_on_transport_ex, transport,
1102
create_prefix=False)
1095
1105
class OldSmartClient(object):
1159
1169
class TestBranchBreakLock(RemoteBranchTestCase):
1161
1171
def test_break_lock(self):
1162
transport_path = 'quack'
1163
1172
transport = MemoryTransport()
1164
1173
client = FakeClient(transport.base)
1165
1174
client.add_expected_call(
1544
1553
# doesn't just open in - this test probably needs to be rewritten using
1545
1554
# a spawn()ed server.
1546
1555
stacked_branch = self.make_branch('stacked', format='1.9')
1547
memory_branch = self.make_branch('base', format='1.9')
1556
self.make_branch('base', format='1.9')
1548
1557
vfs_url = self.get_vfs_only_url('base')
1549
1558
stacked_branch.set_stacked_on_url(vfs_url)
1550
1559
transport = stacked_branch.controldir.root_transport
1569
1578
def test_backwards_compatible(self):
1570
1579
# like with bzr1.6 with no Branch.get_stacked_on_url rpc
1571
base_branch = self.make_branch('base', format='1.6')
1580
self.make_branch('base', format='1.6')
1572
1581
stacked_branch = self.make_branch('stacked', format='1.6')
1573
1582
stacked_branch.set_stacked_on_url('../base')
1574
1583
client = FakeClient(self.get_url())
1602
1611
len(branch.repository._real_repository._fallback_repositories))
1604
1613
def test_get_stacked_on_real_branch(self):
1605
base_branch = self.make_branch('base')
1614
self.make_branch('base')
1606
1615
stacked_branch = self.make_branch('stacked')
1607
1616
stacked_branch.set_stacked_on_url('../base')
1608
1617
reference_format = self.get_repo_format()
1887
1896
self.lock_remote_branch(branch)
1889
1898
# Call set_last_revision_info, and verify it behaved as expected.
1890
result = branch.set_last_revision_info(1234, b'a-revision-id')
1899
branch.set_last_revision_info(1234, b'a-revision-id')
1891
1900
self.assertEqual(
1892
1901
[('set_last_revision_info', 1234, b'a-revision-id')],
1893
1902
real_branch.calls)
2110
2119
self.assertEqual(
2111
2120
[('call', b'Branch.get_stacked_on_url', (b'memory:///',)),
2112
2121
('call', b'Branch.lock_write', (b'memory:///', b'', b'')),
2113
('call_expecting_body', b'Branch.get_config_file', (b'memory:///',)),
2114
('call_expecting_body', b'Branch.get_config_file', (b'memory:///',)),
2122
('call_expecting_body', b'Branch.get_config_file',
2124
('call_expecting_body', b'Branch.get_config_file',
2115
2126
('call_with_body_bytes_expecting_body', b'Branch.put_config_file',
2116
2127
(b'memory:///', b'branch token', b'repo token'),
2117
2128
b'# line 1\nemail = The Dude <lebowski@example.com>\n'),
2118
('call', b'Branch.unlock', (b'memory:///', b'branch token', b'repo token'))],
2129
('call', b'Branch.unlock',
2130
(b'memory:///', b'branch token', b'repo token'))],
2199
2211
config = bzrdir.get_config()
2200
2212
self.assertEqual('/', config.get_default_stack_on())
2201
2213
self.assertEqual(
2202
[('call_expecting_body', b'BzrDir.get_config_file', (b'memory:///',))],
2214
[('call_expecting_body', b'BzrDir.get_config_file',
2205
2218
def test_set_option_uses_vfs(self):
2535
2548
b'success', (b'ok', ), None)
2536
2549
repo.lock_write()
2537
2550
repo.start_write_group()
2539
repo.add_signature_text(b"rev1", b"every bloody emperor"))
2552
None, repo.add_signature_text(b"rev1", b"every bloody emperor"))
2540
2553
self.assertEqual(
2541
2554
('call_with_body_bytes_expecting_body',
2542
2555
b'Repository.add_signature_text',
2651
2664
self.addCleanup(repo.unlock)
2652
2665
self.reset_smart_call_log()
2653
2666
graph = repo.get_graph()
2654
self.assertEqual({},
2655
graph.get_parent_map([b'some-missing', b'other-missing']))
2668
{}, graph.get_parent_map([b'some-missing', b'other-missing']))
2656
2669
self.assertLength(1, self.hpss_calls)
2657
2670
# No call if we repeat this
2658
2671
self.reset_smart_call_log()
2659
2672
graph = repo.get_graph()
2660
self.assertEqual({},
2661
graph.get_parent_map([b'some-missing', b'other-missing']))
2674
{}, graph.get_parent_map([b'some-missing', b'other-missing']))
2662
2675
self.assertLength(0, self.hpss_calls)
2663
2676
# Asking for more unknown keys makes a request.
2664
2677
self.reset_smart_call_log()
2665
2678
graph = repo.get_graph()
2666
self.assertEqual({},
2667
graph.get_parent_map([b'some-missing', b'other-missing',
2680
{}, graph.get_parent_map([b'some-missing', b'other-missing',
2669
2682
self.assertLength(1, self.hpss_calls)
2671
2684
def disableExtraResults(self):
2692
2705
graph = repo.get_graph()
2693
2706
# Query for b'first' and b'null:'. Because b'null:' is a parent of
2694
2707
# 'first' it will be a candidate for the stop_keys of subsequent
2695
# requests, and because b'null:' was queried but not returned it will be
2696
# cached as missing.
2708
# requests, and because b'null:' was queried but not returned it will
2709
# be cached as missing.
2697
2710
self.assertEqual({b'first': (b'null:',)},
2698
2711
graph.get_parent_map([b'first', b'null:']))
2699
2712
# Now query for another key. This request will pass along a recipe of
2787
2800
self.assertRaises(errors.NoSuchRevision, repo.get_revisions,
2788
2801
[b'somerev1', b'anotherrev2'])
2789
2802
self.assertEqual(
2790
[('call_with_body_bytes_expecting_body', b'Repository.iter_revisions',
2791
(b'quack/', ), b"somerev1\nanotherrev2")],
2803
[('call_with_body_bytes_expecting_body',
2804
b'Repository.iter_revisions', (b'quack/', ),
2805
b"somerev1\nanotherrev2")],
2794
2808
def test_hpss_get_single_revision(self):
2809
2823
revs = repo.get_revisions([b'somerev1'])
2810
2824
self.assertEqual(revs, [somerev1])
2811
2825
self.assertEqual(
2812
[('call_with_body_bytes_expecting_body', b'Repository.iter_revisions',
2826
[('call_with_body_bytes_expecting_body',
2827
b'Repository.iter_revisions',
2813
2828
(b'quack/', ), b"somerev1")],
3907
3922
# To translate a NoSuchRevision error _translate_error needs a 'branch'
3908
3923
# in the context dict. So let's give it an empty context dict instead
3909
3924
# to exercise its error recovery.
3911
3925
error_tuple = (b'NoSuchRevision', b'revid')
3912
3926
server_error = errors.ErrorFromSmartServer(error_tuple)
3913
3927
translated_error = self.translateErrorFromSmartServer(server_error)
3943
3957
# make a branch stacked on another repository containing an empty
3944
3958
# revision, then open it over hpss - we should be able to see that
3946
base_transport = self.get_transport()
3947
3960
base_builder = self.make_branch_builder('base', format='1.9')
3948
3961
base_builder.start_series()
3949
3962
base_revid = base_builder.build_snapshot(None,
4067
4080
branch.lock_read()
4068
4081
self.addCleanup(branch.unlock)
4069
4082
return None, branch
4070
rev_ord, expected_revs = self.get_ordered_revs('1.9', 'unordered',
4071
branch_factory=make_stacked_stacked)
4083
rev_ord, expected_revs = self.get_ordered_revs(
4084
'1.9', 'unordered', branch_factory=make_stacked_stacked)
4072
4085
self.assertEqual(set(expected_revs), set(rev_ord))
4073
4086
# Getting unordered results should have made a streaming data request
4074
4087
# from the server, and one from each backing repo
4103
4116
# branch pulling content from stacked and trunk.
4104
4117
self.setup_smart_server_with_call_log()
4105
4118
trunk = self.make_branch_and_tree('trunk', format="1.9-rich-root")
4106
r1 = trunk.commit('start')
4119
trunk.commit('start')
4107
4120
stacked_branch = trunk.branch.create_clone_on_transport(
4108
4121
self.get_transport('stacked'), stacked_on=trunk.branch.base)
4109
4122
local = self.make_branch('local', format='1.9-rich-root')
4417
4430
repo, client = self.setup_fake_client_and_repository(transport_path)
4418
4431
fmt = controldir.format_registry.get('2a')().repository_format
4419
4432
repo._format = fmt
4420
stream = [('inventory-deltas', [
4421
versionedfile.FulltextContentFactory(b'somerevid', None, None,
4422
self._serialize_inv_delta(b'null:', b'somerevid', []))])]
4434
('inventory-deltas', [
4435
versionedfile.FulltextContentFactory(
4436
b'somerevid', None, None,
4437
self._serialize_inv_delta(b'null:', b'somerevid', []))])]
4423
4438
client.add_expected_call(
4424
4439
b'VersionedFileRepository.get_inventories', (
4425
4440
b'quack/', b'unordered'),