284
280
self.expecting_body = True
285
281
return result[1], FakeProtocol(result[2], self)
287
def call_with_body_bytes(self, method, args, body):
288
self._check_call(method, args)
289
self._calls.append(('call_with_body_bytes', method, args, body))
290
result = self._get_next_response()
291
return result[1], FakeProtocol(result[2], self)
293
283
def call_with_body_bytes_expecting_body(self, method, args, body):
294
284
self._check_call(method, args)
295
285
self._calls.append(('call_with_body_bytes_expecting_body', method,
418
408
# Calling _remember_remote_is_before again with a lower value works.
419
409
client_medium._remember_remote_is_before((1, 5))
420
410
self.assertTrue(client_medium._is_remote_before((1, 5)))
421
# If you call _remember_remote_is_before with a higher value it logs a
422
# warning, and continues to remember the lower value.
423
self.assertNotContainsRe(self.get_log(), '_remember_remote_is_before')
424
client_medium._remember_remote_is_before((1, 9))
425
self.assertContainsRe(self.get_log(), '_remember_remote_is_before')
426
self.assertTrue(client_medium._is_remote_before((1, 5)))
411
# You cannot call _remember_remote_is_before with a larger value.
413
AssertionError, client_medium._remember_remote_is_before, (1, 9))
429
416
class TestBzrDirCloningMetaDir(TestRemote):
481
468
self.assertFinished(client)
484
class TestBzrDirOpen(TestRemote):
486
def make_fake_client_and_transport(self, path='quack'):
487
transport = MemoryTransport()
488
transport.mkdir(path)
489
transport = transport.clone(path)
490
client = FakeClient(transport.base)
491
return client, transport
493
def test_absent(self):
494
client, transport = self.make_fake_client_and_transport()
495
client.add_expected_call(
496
'BzrDir.open_2.1', ('quack/',), 'success', ('no',))
497
self.assertRaises(errors.NotBranchError, RemoteBzrDir, transport,
498
remote.RemoteBzrDirFormat(), _client=client, _force_probe=True)
499
self.assertFinished(client)
501
def test_present_without_workingtree(self):
502
client, transport = self.make_fake_client_and_transport()
503
client.add_expected_call(
504
'BzrDir.open_2.1', ('quack/',), 'success', ('yes', 'no'))
505
bd = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
506
_client=client, _force_probe=True)
507
self.assertIsInstance(bd, RemoteBzrDir)
508
self.assertFalse(bd.has_workingtree())
509
self.assertRaises(errors.NoWorkingTree, bd.open_workingtree)
510
self.assertFinished(client)
512
def test_present_with_workingtree(self):
513
client, transport = self.make_fake_client_and_transport()
514
client.add_expected_call(
515
'BzrDir.open_2.1', ('quack/',), 'success', ('yes', 'yes'))
516
bd = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
517
_client=client, _force_probe=True)
518
self.assertIsInstance(bd, RemoteBzrDir)
519
self.assertTrue(bd.has_workingtree())
520
self.assertRaises(errors.NotLocalUrl, bd.open_workingtree)
521
self.assertFinished(client)
523
def test_backwards_compat(self):
524
client, transport = self.make_fake_client_and_transport()
525
client.add_expected_call(
526
'BzrDir.open_2.1', ('quack/',), 'unknown', ('BzrDir.open_2.1',))
527
client.add_expected_call(
528
'BzrDir.open', ('quack/',), 'success', ('yes',))
529
bd = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
530
_client=client, _force_probe=True)
531
self.assertIsInstance(bd, RemoteBzrDir)
532
self.assertFinished(client)
534
def test_backwards_compat_hpss_v2(self):
535
client, transport = self.make_fake_client_and_transport()
536
# Monkey-patch fake client to simulate real-world behaviour with v2
537
# server: upon first RPC call detect the protocol version, and because
538
# the version is 2 also do _remember_remote_is_before((1, 6)) before
539
# continuing with the RPC.
540
orig_check_call = client._check_call
541
def check_call(method, args):
542
client._medium._protocol_version = 2
543
client._medium._remember_remote_is_before((1, 6))
544
client._check_call = orig_check_call
545
client._check_call(method, args)
546
client._check_call = check_call
547
client.add_expected_call(
548
'BzrDir.open_2.1', ('quack/',), 'unknown', ('BzrDir.open_2.1',))
549
client.add_expected_call(
550
'BzrDir.open', ('quack/',), 'success', ('yes',))
551
bd = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
552
_client=client, _force_probe=True)
553
self.assertIsInstance(bd, RemoteBzrDir)
554
self.assertFinished(client)
557
471
class TestBzrDirOpenBranch(TestRemote):
559
473
def test_backwards_compat(self):
747
661
network_name = reference_format.network_name()
748
662
client.add_expected_call(
749
663
'BzrDir.create_repository', ('quack/',
750
'Bazaar repository format 2a (needs bzr 1.16 or later)\n',
752
'success', ('ok', 'yes', 'yes', 'yes', network_name))
664
'Bazaar pack repository format 1 (needs bzr 0.92)\n', 'False'),
665
'success', ('ok', 'no', 'no', 'no', network_name))
753
666
a_bzrdir = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
755
668
repo = a_bzrdir.create_repository()
1095
994
self.assertEqual({}, result)
1098
class TestBranchSetTagsBytes(RemoteBranchTestCase):
1100
def test_trivial(self):
1101
transport = MemoryTransport()
1102
client = FakeClient(transport.base)
1103
client.add_expected_call(
1104
'Branch.get_stacked_on_url', ('quack/',),
1105
'error', ('NotStacked',))
1106
client.add_expected_call(
1107
'Branch.set_tags_bytes', ('quack/', 'branch token', 'repo token'),
1109
transport.mkdir('quack')
1110
transport = transport.clone('quack')
1111
branch = self.make_remote_branch(transport, client)
1112
self.lock_remote_branch(branch)
1113
branch._set_tags_bytes('tags bytes')
1114
self.assertFinished(client)
1115
self.assertEqual('tags bytes', client._calls[-1][-1])
1117
def test_backwards_compatible(self):
1118
transport = MemoryTransport()
1119
client = FakeClient(transport.base)
1120
client.add_expected_call(
1121
'Branch.get_stacked_on_url', ('quack/',),
1122
'error', ('NotStacked',))
1123
client.add_expected_call(
1124
'Branch.set_tags_bytes', ('quack/', 'branch token', 'repo token'),
1125
'unknown', ('Branch.set_tags_bytes',))
1126
transport.mkdir('quack')
1127
transport = transport.clone('quack')
1128
branch = self.make_remote_branch(transport, client)
1129
self.lock_remote_branch(branch)
1130
class StubRealBranch(object):
1133
def _set_tags_bytes(self, bytes):
1134
self.calls.append(('set_tags_bytes', bytes))
1135
real_branch = StubRealBranch()
1136
branch._real_branch = real_branch
1137
branch._set_tags_bytes('tags bytes')
1138
# Call a second time, to exercise the 'remote version already inferred'
1140
branch._set_tags_bytes('tags bytes')
1141
self.assertFinished(client)
1143
[('set_tags_bytes', 'tags bytes')] * 2, real_branch.calls)
1146
997
class TestBranchLastRevisionInfo(RemoteBranchTestCase):
1148
999
def test_empty_branch(self):
1248
1099
len(branch.repository._real_repository._fallback_repositories))
1250
1101
def test_get_stacked_on_real_branch(self):
1251
base_branch = self.make_branch('base')
1252
stacked_branch = self.make_branch('stacked')
1102
base_branch = self.make_branch('base', format='1.6')
1103
stacked_branch = self.make_branch('stacked', format='1.6')
1253
1104
stacked_branch.set_stacked_on_url('../base')
1254
1105
reference_format = self.get_repo_format()
1255
1106
network_name = reference_format.network_name()
1256
1107
client = FakeClient(self.get_url())
1257
1108
branch_network_name = self.get_branch_format().network_name()
1258
1109
client.add_expected_call(
1259
'BzrDir.open_branchV3', ('stacked/',),
1110
'BzrDir.open_branchV2', ('stacked/',),
1260
1111
'success', ('branch', branch_network_name))
1261
1112
client.add_expected_call(
1262
1113
'BzrDir.find_repositoryV3', ('stacked/',),
1263
'success', ('ok', '', 'yes', 'no', 'yes', network_name))
1114
'success', ('ok', '', 'no', 'no', 'yes', network_name))
1264
1115
# called twice, once from constructor and then again by us
1265
1116
client.add_expected_call(
1266
1117
'Branch.get_stacked_on_url', ('stacked/',),
2249
2092
repo.get_rev_id_for_revno, 5, (42, 'rev-foo'))
2250
2093
self.assertFinished(client)
2252
def test_branch_fallback_locking(self):
2253
"""RemoteBranch.get_rev_id takes a read lock, and tries to call the
2254
get_rev_id_for_revno verb. If the verb is unknown the VFS fallback
2255
will be invoked, which will fail if the repo is unlocked.
2257
self.setup_smart_server_with_call_log()
2258
tree = self.make_branch_and_memory_tree('.')
2260
rev1 = tree.commit('First')
2261
rev2 = tree.commit('Second')
2263
branch = tree.branch
2264
self.assertFalse(branch.is_locked())
2265
self.reset_smart_call_log()
2266
verb = 'Repository.get_rev_id_for_revno'
2267
self.disable_verb(verb)
2268
self.assertEqual(rev1, branch.get_rev_id(1))
2269
self.assertLength(1, [call for call in self.hpss_calls if
2270
call.call.method == verb])
2273
2096
class TestRepositoryIsShared(TestRemoteRepository):
2390
2213
self.assertEqual([], client._calls)
2393
class TestRepositoryInsertStreamBase(TestRemoteRepository):
2394
"""Base class for Repository.insert_stream and .insert_stream_1.19
2398
def checkInsertEmptyStream(self, repo, client):
2399
"""Insert an empty stream, checking the result.
2401
This checks that there are no resume_tokens or missing_keys, and that
2402
the client is finished.
2404
sink = repo._get_sink()
2405
fmt = repository.RepositoryFormat.get_default_format()
2406
resume_tokens, missing_keys = sink.insert_stream([], fmt, [])
2407
self.assertEqual([], resume_tokens)
2408
self.assertEqual(set(), missing_keys)
2409
self.assertFinished(client)
2412
class TestRepositoryInsertStream(TestRepositoryInsertStreamBase):
2413
"""Tests for using Repository.insert_stream verb when the _1.19 variant is
2216
class TestRepositoryInsertStream(TestRemoteRepository):
2217
"""Tests for using Repository.insert_stream verb when the _1.18 variant is
2416
This test case is very similar to TestRepositoryInsertStream_1_19.
2220
This test case is very similar to TestRepositoryInsertStream_1_18.
2419
2223
def setUp(self):
2420
2224
TestRemoteRepository.setUp(self)
2421
self.disable_verb('Repository.insert_stream_1.19')
2225
self.disable_verb('Repository.insert_stream_1.18')
2423
2227
def test_unlocked_repo(self):
2424
2228
transport_path = 'quack'
2425
2229
repo, client = self.setup_fake_client_and_repository(transport_path)
2426
2230
client.add_expected_call(
2427
'Repository.insert_stream_1.19', ('quack/', ''),
2428
'unknown', ('Repository.insert_stream_1.19',))
2429
client.add_expected_call(
2430
'Repository.insert_stream', ('quack/', ''),
2432
client.add_expected_call(
2433
'Repository.insert_stream', ('quack/', ''),
2435
self.checkInsertEmptyStream(repo, client)
2231
'Repository.insert_stream_1.18', ('quack/', ''),
2232
'unknown', ('Repository.insert_stream_1.18',))
2233
client.add_expected_call(
2234
'Repository.insert_stream', ('quack/', ''),
2236
client.add_expected_call(
2237
'Repository.insert_stream', ('quack/', ''),
2239
sink = repo._get_sink()
2240
fmt = repository.RepositoryFormat.get_default_format()
2241
resume_tokens, missing_keys = sink.insert_stream([], fmt, [])
2242
self.assertEqual([], resume_tokens)
2243
self.assertEqual(set(), missing_keys)
2244
self.assertFinished(client)
2437
2246
def test_locked_repo_with_no_lock_token(self):
2438
2247
transport_path = 'quack'
2459
2273
'Repository.lock_write', ('quack/', ''),
2460
2274
'success', ('ok', 'a token'))
2461
2275
client.add_expected_call(
2462
'Repository.insert_stream_1.19', ('quack/', '', 'a token'),
2463
'unknown', ('Repository.insert_stream_1.19',))
2276
'Repository.insert_stream_1.18', ('quack/', '', 'a token'),
2277
'unknown', ('Repository.insert_stream_1.18',))
2464
2278
client.add_expected_call(
2465
2279
'Repository.insert_stream_locked', ('quack/', '', 'a token'),
2466
2280
'success', ('ok',))
2566
2380
return stream_with_inv_delta()
2569
class TestRepositoryInsertStream_1_19(TestRepositoryInsertStreamBase):
2383
class TestRepositoryInsertStream_1_18(TestRemoteRepository):
2571
2385
def test_unlocked_repo(self):
2572
2386
transport_path = 'quack'
2573
2387
repo, client = self.setup_fake_client_and_repository(transport_path)
2574
2388
client.add_expected_call(
2575
'Repository.insert_stream_1.19', ('quack/', ''),
2389
'Repository.insert_stream_1.18', ('quack/', ''),
2576
2390
'success', ('ok',))
2577
2391
client.add_expected_call(
2578
'Repository.insert_stream_1.19', ('quack/', ''),
2392
'Repository.insert_stream_1.18', ('quack/', ''),
2579
2393
'success', ('ok',))
2580
self.checkInsertEmptyStream(repo, client)
2394
sink = repo._get_sink()
2395
fmt = repository.RepositoryFormat.get_default_format()
2396
resume_tokens, missing_keys = sink.insert_stream([], fmt, [])
2397
self.assertEqual([], resume_tokens)
2398
self.assertEqual(set(), missing_keys)
2399
self.assertFinished(client)
2582
2401
def test_locked_repo_with_no_lock_token(self):
2583
2402
transport_path = 'quack'
2586
2405
'Repository.lock_write', ('quack/', ''),
2587
2406
'success', ('ok', ''))
2588
2407
client.add_expected_call(
2589
'Repository.insert_stream_1.19', ('quack/', ''),
2408
'Repository.insert_stream_1.18', ('quack/', ''),
2590
2409
'success', ('ok',))
2591
2410
client.add_expected_call(
2592
'Repository.insert_stream_1.19', ('quack/', ''),
2411
'Repository.insert_stream_1.18', ('quack/', ''),
2593
2412
'success', ('ok',))
2594
2413
repo.lock_write()
2595
self.checkInsertEmptyStream(repo, client)
2414
sink = repo._get_sink()
2415
fmt = repository.RepositoryFormat.get_default_format()
2416
resume_tokens, missing_keys = sink.insert_stream([], fmt, [])
2417
self.assertEqual([], resume_tokens)
2418
self.assertEqual(set(), missing_keys)
2419
self.assertFinished(client)
2597
2421
def test_locked_repo_with_lock_token(self):
2598
2422
transport_path = 'quack'
2601
2425
'Repository.lock_write', ('quack/', ''),
2602
2426
'success', ('ok', 'a token'))
2603
2427
client.add_expected_call(
2604
'Repository.insert_stream_1.19', ('quack/', '', 'a token'),
2428
'Repository.insert_stream_1.18', ('quack/', '', 'a token'),
2605
2429
'success', ('ok',))
2606
2430
client.add_expected_call(
2607
'Repository.insert_stream_1.19', ('quack/', '', 'a token'),
2431
'Repository.insert_stream_1.18', ('quack/', '', 'a token'),
2608
2432
'success', ('ok',))
2609
2433
repo.lock_write()
2610
self.checkInsertEmptyStream(repo, client)
2434
sink = repo._get_sink()
2435
fmt = repository.RepositoryFormat.get_default_format()
2436
resume_tokens, missing_keys = sink.insert_stream([], fmt, [])
2437
self.assertEqual([], resume_tokens)
2438
self.assertEqual(set(), missing_keys)
2439
self.assertFinished(client)
2613
2442
class TestRepositoryTarball(TestRemoteRepository):