280
283
self.expecting_body = True
281
284
return result[1], FakeProtocol(result[2], self)
286
def call_with_body_bytes(self, method, args, body):
287
self._check_call(method, args)
288
self._calls.append(('call_with_body_bytes', method, args, body))
289
result = self._get_next_response()
290
return result[1], FakeProtocol(result[2], self)
283
292
def call_with_body_bytes_expecting_body(self, method, args, body):
284
293
self._check_call(method, args)
285
294
self._calls.append(('call_with_body_bytes_expecting_body', method,
435
444
'BzrDir.cloning_metadir', ('quack/', 'False'),
436
445
'error', ('BranchReference',)),
437
446
client.add_expected_call(
438
'BzrDir.open_branchV2', ('quack/',),
447
'BzrDir.open_branchV3', ('quack/',),
439
448
'success', ('ref', self.get_url('referenced'))),
440
449
a_bzrdir = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
468
477
self.assertFinished(client)
480
class TestBzrDirOpen(TestRemote):
482
def make_fake_client_and_transport(self, path='quack'):
483
transport = MemoryTransport()
484
transport.mkdir(path)
485
transport = transport.clone(path)
486
client = FakeClient(transport.base)
487
return client, transport
489
def test_absent(self):
490
client, transport = self.make_fake_client_and_transport()
491
client.add_expected_call(
492
'BzrDir.open_2.1', ('quack/',), 'success', ('no',))
493
self.assertRaises(errors.NotBranchError, RemoteBzrDir, transport,
494
remote.RemoteBzrDirFormat(), _client=client, _force_probe=True)
495
self.assertFinished(client)
497
def test_present_without_workingtree(self):
498
client, transport = self.make_fake_client_and_transport()
499
client.add_expected_call(
500
'BzrDir.open_2.1', ('quack/',), 'success', ('yes', 'no'))
501
bd = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
502
_client=client, _force_probe=True)
503
self.assertIsInstance(bd, RemoteBzrDir)
504
self.assertFalse(bd.has_workingtree())
505
self.assertRaises(errors.NoWorkingTree, bd.open_workingtree)
506
self.assertFinished(client)
508
def test_present_with_workingtree(self):
509
client, transport = self.make_fake_client_and_transport()
510
client.add_expected_call(
511
'BzrDir.open_2.1', ('quack/',), 'success', ('yes', 'yes'))
512
bd = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
513
_client=client, _force_probe=True)
514
self.assertIsInstance(bd, RemoteBzrDir)
515
self.assertTrue(bd.has_workingtree())
516
self.assertRaises(errors.NotLocalUrl, bd.open_workingtree)
517
self.assertFinished(client)
519
def test_backwards_compat(self):
520
client, transport = self.make_fake_client_and_transport()
521
client.add_expected_call(
522
'BzrDir.open_2.1', ('quack/',), 'unknown', ('BzrDir.open_2.1',))
523
client.add_expected_call(
524
'BzrDir.open', ('quack/',), 'success', ('yes',))
525
bd = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
526
_client=client, _force_probe=True)
527
self.assertIsInstance(bd, RemoteBzrDir)
528
self.assertFinished(client)
471
531
class TestBzrDirOpenBranch(TestRemote):
473
533
def test_backwards_compat(self):
491
551
transport = transport.clone('quack')
492
552
client = FakeClient(transport.base)
493
553
client.add_expected_call(
494
'BzrDir.open_branchV2', ('quack/',),
554
'BzrDir.open_branchV3', ('quack/',),
495
555
'success', ('branch', branch_network_name))
496
556
client.add_expected_call(
497
557
'BzrDir.find_repositoryV3', ('quack/',),
546
606
network_name = reference_format.network_name()
547
607
branch_network_name = self.get_branch_format().network_name()
548
608
client.add_expected_call(
549
'BzrDir.open_branchV2', ('~hello/',),
609
'BzrDir.open_branchV3', ('~hello/',),
550
610
'success', ('branch', branch_network_name))
551
611
client.add_expected_call(
552
612
'BzrDir.find_repositoryV3', ('~hello/',),
661
721
network_name = reference_format.network_name()
662
722
client.add_expected_call(
663
723
'BzrDir.create_repository', ('quack/',
664
'Bazaar pack repository format 1 (needs bzr 0.92)\n', 'False'),
665
'success', ('ok', 'no', 'no', 'no', network_name))
724
'Bazaar repository format 2a (needs bzr 1.16 or later)\n',
726
'success', ('ok', 'yes', 'yes', 'yes', network_name))
666
727
a_bzrdir = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
668
729
repo = a_bzrdir.create_repository()
670
731
self.assertIsInstance(repo, remote.RemoteRepository)
671
732
# its format should have the settings from the response
672
733
format = repo._format
673
self.assertFalse(format.rich_root_data)
674
self.assertFalse(format.supports_tree_reference)
675
self.assertFalse(format.supports_external_lookups)
734
self.assertTrue(format.rich_root_data)
735
self.assertTrue(format.supports_tree_reference)
736
self.assertTrue(format.supports_external_lookups)
676
737
self.assertEqual(network_name, format.network_name())
682
743
# fallback all the way to the first version.
683
744
reference_format = self.get_repo_format()
684
745
network_name = reference_format.network_name()
685
client = FakeClient('bzr://example.com/')
746
server_url = 'bzr://example.com/'
747
self.permit_url(server_url)
748
client = FakeClient(server_url)
686
749
client.add_unknown_method_response('BzrDir.find_repositoryV3')
687
750
client.add_unknown_method_response('BzrDir.find_repositoryV2')
688
751
client.add_success_response('ok', '', 'no', 'no')
694
757
reference_format.get_format_string(), 'ok')
695
758
# PackRepository wants to do a stat
696
759
client.add_success_response('stat', '0', '65535')
697
remote_transport = RemoteTransport('bzr://example.com/quack/', medium=False,
760
remote_transport = RemoteTransport(server_url + 'quack/', medium=False,
699
762
bzrdir = RemoteBzrDir(remote_transport, remote.RemoteBzrDirFormat(),
714
777
# fallback to find_repositoryV2
715
778
reference_format = self.get_repo_format()
716
779
network_name = reference_format.network_name()
717
client = FakeClient('bzr://example.com/')
780
server_url = 'bzr://example.com/'
781
self.permit_url(server_url)
782
client = FakeClient(server_url)
718
783
client.add_unknown_method_response('BzrDir.find_repositoryV3')
719
784
client.add_success_response('ok', '', 'no', 'no', 'no')
720
785
# A real repository instance will be created to determine the network
725
790
reference_format.get_format_string(), 'ok')
726
791
# PackRepository wants to do a stat
727
792
client.add_success_response('stat', '0', '65535')
728
remote_transport = RemoteTransport('bzr://example.com/quack/', medium=False,
793
remote_transport = RemoteTransport(server_url + 'quack/', medium=False,
730
795
bzrdir = RemoteBzrDir(remote_transport, remote.RemoteBzrDirFormat(),
851
916
class RemoteBranchTestCase(RemoteBzrDirTestCase):
918
def lock_remote_branch(self, branch):
919
"""Trick a RemoteBranch into thinking it is locked."""
920
branch._lock_mode = 'w'
921
branch._lock_count = 2
922
branch._lock_token = 'branch token'
923
branch._repo_lock_token = 'repo token'
924
branch.repository._lock_mode = 'w'
925
branch.repository._lock_count = 2
926
branch.repository._lock_token = 'repo token'
853
928
def make_remote_branch(self, transport, client):
854
929
"""Make a RemoteBranch using 'client' as its _SmartClient.
994
1069
self.assertEqual({}, result)
1072
class TestBranchSetTagsBytes(RemoteBranchTestCase):
1074
def test_trivial(self):
1075
transport = MemoryTransport()
1076
client = FakeClient(transport.base)
1077
client.add_expected_call(
1078
'Branch.get_stacked_on_url', ('quack/',),
1079
'error', ('NotStacked',))
1080
client.add_expected_call(
1081
'Branch.set_tags_bytes', ('quack/', 'branch token', 'repo token'),
1083
transport.mkdir('quack')
1084
transport = transport.clone('quack')
1085
branch = self.make_remote_branch(transport, client)
1086
self.lock_remote_branch(branch)
1087
branch._set_tags_bytes('tags bytes')
1088
self.assertFinished(client)
1089
self.assertEqual('tags bytes', client._calls[-1][-1])
1091
def test_backwards_compatible(self):
1092
transport = MemoryTransport()
1093
client = FakeClient(transport.base)
1094
client.add_expected_call(
1095
'Branch.get_stacked_on_url', ('quack/',),
1096
'error', ('NotStacked',))
1097
client.add_expected_call(
1098
'Branch.set_tags_bytes', ('quack/', 'branch token', 'repo token'),
1099
'unknown', ('Branch.set_tags_bytes',))
1100
transport.mkdir('quack')
1101
transport = transport.clone('quack')
1102
branch = self.make_remote_branch(transport, client)
1103
self.lock_remote_branch(branch)
1104
class StubRealBranch(object):
1107
def _set_tags_bytes(self, bytes):
1108
self.calls.append(('set_tags_bytes', bytes))
1109
real_branch = StubRealBranch()
1110
branch._real_branch = real_branch
1111
branch._set_tags_bytes('tags bytes')
1112
# Call a second time, to exercise the 'remote version already inferred'
1114
branch._set_tags_bytes('tags bytes')
1115
self.assertFinished(client)
1117
[('set_tags_bytes', 'tags bytes')] * 2, real_branch.calls)
997
1120
class TestBranchLastRevisionInfo(RemoteBranchTestCase):
999
1122
def test_empty_branch(self):
1071
1194
client = FakeClient(self.get_url())
1072
1195
branch_network_name = self.get_branch_format().network_name()
1073
1196
client.add_expected_call(
1074
'BzrDir.open_branchV2', ('stacked/',),
1197
'BzrDir.open_branchV3', ('stacked/',),
1075
1198
'success', ('branch', branch_network_name))
1076
1199
client.add_expected_call(
1077
1200
'BzrDir.find_repositoryV3', ('stacked/',),
1107
1230
client = FakeClient(self.get_url())
1108
1231
branch_network_name = self.get_branch_format().network_name()
1109
1232
client.add_expected_call(
1110
'BzrDir.open_branchV2', ('stacked/',),
1233
'BzrDir.open_branchV3', ('stacked/',),
1111
1234
'success', ('branch', branch_network_name))
1112
1235
client.add_expected_call(
1113
1236
'BzrDir.find_repositoryV3', ('stacked/',),
1341
1464
errors.NoSuchRevision, branch.set_last_revision_info, 123, 'revid')
1342
1465
branch.unlock()
1344
def lock_remote_branch(self, branch):
1345
"""Trick a RemoteBranch into thinking it is locked."""
1346
branch._lock_mode = 'w'
1347
branch._lock_count = 2
1348
branch._lock_token = 'branch token'
1349
branch._repo_lock_token = 'repo token'
1350
branch.repository._lock_mode = 'w'
1351
branch.repository._lock_count = 2
1352
branch.repository._lock_token = 'repo token'
1354
1467
def test_backwards_compatibility(self):
1355
1468
"""If the server does not support the Branch.set_last_revision_info
1356
1469
verb (which is new in 1.4), then the client falls back to VFS methods.
1672
1785
return repo, client
1788
def remoted_description(format):
1789
return 'Remote: ' + format.get_format_description()
1792
class TestBranchFormat(tests.TestCase):
1794
def test_get_format_description(self):
1795
remote_format = RemoteBranchFormat()
1796
real_format = branch.BranchFormat.get_default_format()
1797
remote_format._network_name = real_format.network_name()
1798
self.assertEqual(remoted_description(real_format),
1799
remote_format.get_format_description())
1675
1802
class TestRepositoryFormat(TestRemoteRepository):
1677
1804
def test_fast_delta(self):
1684
1811
false_format._network_name = false_name
1685
1812
self.assertEqual(False, false_format.fast_deltas)
1814
def test_get_format_description(self):
1815
remote_repo_format = RemoteRepositoryFormat()
1816
real_format = repository.RepositoryFormat.get_default_format()
1817
remote_repo_format._network_name = real_format.network_name()
1818
self.assertEqual(remoted_description(real_format),
1819
remote_repo_format.get_format_description())
1688
1822
class TestRepositoryGatherStats(TestRemoteRepository):
1874
2008
self.assertLength(1, self.hpss_calls)
1876
2010
def disableExtraResults(self):
1877
old_flag = SmartServerRepositoryGetParentMap.no_extra_results
1878
SmartServerRepositoryGetParentMap.no_extra_results = True
1880
SmartServerRepositoryGetParentMap.no_extra_results = old_flag
1881
self.addCleanup(reset_values)
2011
self.overrideAttr(SmartServerRepositoryGetParentMap,
2012
'no_extra_results', True)
1883
2014
def test_null_cached_missing_and_stop_key(self):
1884
2015
self.setup_smart_server_with_call_log()
2092
2222
repo.get_rev_id_for_revno, 5, (42, 'rev-foo'))
2093
2223
self.assertFinished(client)
2225
def test_branch_fallback_locking(self):
2226
"""RemoteBranch.get_rev_id takes a read lock, and tries to call the
2227
get_rev_id_for_revno verb. If the verb is unknown the VFS fallback
2228
will be invoked, which will fail if the repo is unlocked.
2230
self.setup_smart_server_with_call_log()
2231
tree = self.make_branch_and_memory_tree('.')
2233
rev1 = tree.commit('First')
2234
rev2 = tree.commit('Second')
2236
branch = tree.branch
2237
self.assertFalse(branch.is_locked())
2238
self.reset_smart_call_log()
2239
verb = 'Repository.get_rev_id_for_revno'
2240
self.disable_verb(verb)
2241
self.assertEqual(rev1, branch.get_rev_id(1))
2242
self.assertLength(1, [call for call in self.hpss_calls if
2243
call.call.method == verb])
2096
2246
class TestRepositoryIsShared(TestRemoteRepository):
2621
2776
expected_error = errors.NotBranchError(path=bzrdir.root_transport.base)
2622
2777
self.assertEqual(expected_error, translated_error)
2779
def test_nobranch_one_arg(self):
2780
bzrdir = self.make_bzrdir('')
2781
translated_error = self.translateTuple(
2782
('nobranch', 'extra detail'), bzrdir=bzrdir)
2783
expected_error = errors.NotBranchError(
2784
path=bzrdir.root_transport.base,
2785
detail='extra detail')
2786
self.assertEqual(expected_error, translated_error)
2624
2788
def test_LockContention(self):
2625
2789
translated_error = self.translateTuple(('LockContention',))
2626
2790
expected_error = errors.LockContention('(remote lock)')
2666
2830
expected_error = errors.ReadError(path)
2667
2831
self.assertEqual(expected_error, translated_error)
2833
def test_IncompatibleRepositories(self):
2834
translated_error = self.translateTuple(('IncompatibleRepositories',
2835
"repo1", "repo2", "details here"))
2836
expected_error = errors.IncompatibleRepositories("repo1", "repo2",
2838
self.assertEqual(expected_error, translated_error)
2669
2840
def test_PermissionDenied_no_args(self):
2670
2841
path = 'a path'
2671
2842
translated_error = self.translateTuple(('PermissionDenied',), path=path)