57
50
RemoteRepositoryFormat,
59
from bzrlib.repofmt import groupcompress_repo, knitpack_repo
52
from bzrlib.repofmt import groupcompress_repo, pack_repo
60
53
from bzrlib.revision import NULL_REVISION
61
from bzrlib.smart import medium, request
54
from bzrlib.smart import server, medium
62
55
from bzrlib.smart.client import _SmartClient
63
from bzrlib.smart.repository import (
64
SmartServerRepositoryGetParentMap,
65
SmartServerRepositoryGetStream_1_19,
56
from bzrlib.smart.repository import SmartServerRepositoryGetParentMap
67
57
from bzrlib.tests import (
59
split_suite_by_condition,
70
from bzrlib.tests.scenarios import load_tests_apply_scenarios
63
from bzrlib.transport import get_transport, http
71
64
from bzrlib.transport.memory import MemoryTransport
72
65
from bzrlib.transport.remote import (
74
67
RemoteSSHTransport,
75
68
RemoteTCPTransport,
79
load_tests = load_tests_apply_scenarios
82
class BasicRemoteObjectTests(tests.TestCaseWithTransport):
71
def load_tests(standard_tests, module, loader):
72
to_adapt, result = split_suite_by_condition(
73
standard_tests, condition_isinstance(BasicRemoteObjectTests))
74
smart_server_version_scenarios = [
86
{'transport_server': test_server.SmartTCPServer_for_testing_v2_only}),
76
{'transport_server': server.SmartTCPServer_for_testing_v2_only}),
88
{'transport_server': test_server.SmartTCPServer_for_testing})]
78
{'transport_server': server.SmartTCPServer_for_testing})]
79
return multiply_tests(to_adapt, smart_server_version_scenarios, result)
82
class BasicRemoteObjectTests(tests.TestCaseWithTransport):
92
85
super(BasicRemoteObjectTests, self).setUp()
93
86
self.transport = self.get_transport()
94
87
# make a branch that can be opened over the smart transport
95
88
self.local_wt = BzrDir.create_standalone_workingtree('.')
96
self.addCleanup(self.transport.disconnect)
91
self.transport.disconnect()
92
tests.TestCaseWithTransport.tearDown(self)
98
94
def test_create_remote_bzrdir(self):
99
b = remote.RemoteBzrDir(self.transport, RemoteBzrDirFormat())
95
b = remote.RemoteBzrDir(self.transport, remote.RemoteBzrDirFormat())
100
96
self.assertIsInstance(b, BzrDir)
102
98
def test_open_remote_branch(self):
103
99
# open a standalone branch in the working directory
104
b = remote.RemoteBzrDir(self.transport, RemoteBzrDirFormat())
100
b = remote.RemoteBzrDir(self.transport, remote.RemoteBzrDirFormat())
105
101
branch = b.open_branch()
106
102
self.assertIsInstance(branch, Branch)
482
474
self.assertFinished(client)
485
class TestBzrDirOpen(TestRemote):
487
def make_fake_client_and_transport(self, path='quack'):
488
transport = MemoryTransport()
489
transport.mkdir(path)
490
transport = transport.clone(path)
491
client = FakeClient(transport.base)
492
return client, transport
494
def test_absent(self):
495
client, transport = self.make_fake_client_and_transport()
496
client.add_expected_call(
497
'BzrDir.open_2.1', ('quack/',), 'success', ('no',))
498
self.assertRaises(errors.NotBranchError, RemoteBzrDir, transport,
499
RemoteBzrDirFormat(), _client=client, _force_probe=True)
500
self.assertFinished(client)
502
def test_present_without_workingtree(self):
503
client, transport = self.make_fake_client_and_transport()
504
client.add_expected_call(
505
'BzrDir.open_2.1', ('quack/',), 'success', ('yes', 'no'))
506
bd = RemoteBzrDir(transport, RemoteBzrDirFormat(),
507
_client=client, _force_probe=True)
508
self.assertIsInstance(bd, RemoteBzrDir)
509
self.assertFalse(bd.has_workingtree())
510
self.assertRaises(errors.NoWorkingTree, bd.open_workingtree)
511
self.assertFinished(client)
513
def test_present_with_workingtree(self):
514
client, transport = self.make_fake_client_and_transport()
515
client.add_expected_call(
516
'BzrDir.open_2.1', ('quack/',), 'success', ('yes', 'yes'))
517
bd = RemoteBzrDir(transport, RemoteBzrDirFormat(),
518
_client=client, _force_probe=True)
519
self.assertIsInstance(bd, RemoteBzrDir)
520
self.assertTrue(bd.has_workingtree())
521
self.assertRaises(errors.NotLocalUrl, bd.open_workingtree)
522
self.assertFinished(client)
524
def test_backwards_compat(self):
525
client, transport = self.make_fake_client_and_transport()
526
client.add_expected_call(
527
'BzrDir.open_2.1', ('quack/',), 'unknown', ('BzrDir.open_2.1',))
528
client.add_expected_call(
529
'BzrDir.open', ('quack/',), 'success', ('yes',))
530
bd = RemoteBzrDir(transport, RemoteBzrDirFormat(),
531
_client=client, _force_probe=True)
532
self.assertIsInstance(bd, RemoteBzrDir)
533
self.assertFinished(client)
535
def test_backwards_compat_hpss_v2(self):
536
client, transport = self.make_fake_client_and_transport()
537
# Monkey-patch fake client to simulate real-world behaviour with v2
538
# server: upon first RPC call detect the protocol version, and because
539
# the version is 2 also do _remember_remote_is_before((1, 6)) before
540
# continuing with the RPC.
541
orig_check_call = client._check_call
542
def check_call(method, args):
543
client._medium._protocol_version = 2
544
client._medium._remember_remote_is_before((1, 6))
545
client._check_call = orig_check_call
546
client._check_call(method, args)
547
client._check_call = check_call
548
client.add_expected_call(
549
'BzrDir.open_2.1', ('quack/',), 'unknown', ('BzrDir.open_2.1',))
550
client.add_expected_call(
551
'BzrDir.open', ('quack/',), 'success', ('yes',))
552
bd = RemoteBzrDir(transport, RemoteBzrDirFormat(),
553
_client=client, _force_probe=True)
554
self.assertIsInstance(bd, RemoteBzrDir)
555
self.assertFinished(client)
558
477
class TestBzrDirOpenBranch(TestRemote):
560
479
def test_backwards_compat(self):
1124
1000
self.assertEqual({}, result)
1127
class TestBranchSetTagsBytes(RemoteBranchTestCase):
1129
def test_trivial(self):
1130
transport = MemoryTransport()
1131
client = FakeClient(transport.base)
1132
client.add_expected_call(
1133
'Branch.get_stacked_on_url', ('quack/',),
1134
'error', ('NotStacked',))
1135
client.add_expected_call(
1136
'Branch.set_tags_bytes', ('quack/', 'branch token', 'repo token'),
1138
transport.mkdir('quack')
1139
transport = transport.clone('quack')
1140
branch = self.make_remote_branch(transport, client)
1141
self.lock_remote_branch(branch)
1142
branch._set_tags_bytes('tags bytes')
1143
self.assertFinished(client)
1144
self.assertEqual('tags bytes', client._calls[-1][-1])
1146
def test_backwards_compatible(self):
1147
transport = MemoryTransport()
1148
client = FakeClient(transport.base)
1149
client.add_expected_call(
1150
'Branch.get_stacked_on_url', ('quack/',),
1151
'error', ('NotStacked',))
1152
client.add_expected_call(
1153
'Branch.set_tags_bytes', ('quack/', 'branch token', 'repo token'),
1154
'unknown', ('Branch.set_tags_bytes',))
1155
transport.mkdir('quack')
1156
transport = transport.clone('quack')
1157
branch = self.make_remote_branch(transport, client)
1158
self.lock_remote_branch(branch)
1159
class StubRealBranch(object):
1162
def _set_tags_bytes(self, bytes):
1163
self.calls.append(('set_tags_bytes', bytes))
1164
real_branch = StubRealBranch()
1165
branch._real_branch = real_branch
1166
branch._set_tags_bytes('tags bytes')
1167
# Call a second time, to exercise the 'remote version already inferred'
1169
branch._set_tags_bytes('tags bytes')
1170
self.assertFinished(client)
1172
[('set_tags_bytes', 'tags bytes')] * 2, real_branch.calls)
1175
class TestBranchHeadsToFetch(RemoteBranchTestCase):
1177
def test_uses_last_revision_info_and_tags_by_default(self):
1178
transport = MemoryTransport()
1179
client = FakeClient(transport.base)
1180
client.add_expected_call(
1181
'Branch.get_stacked_on_url', ('quack/',),
1182
'error', ('NotStacked',))
1183
client.add_expected_call(
1184
'Branch.last_revision_info', ('quack/',),
1185
'success', ('ok', '1', 'rev-tip'))
1186
# XXX: this will break if the default format's serialization of tags
1187
# changes, or if the RPC for fetching tags changes from get_tags_bytes.
1188
client.add_expected_call(
1189
'Branch.get_tags_bytes', ('quack/',),
1190
'success', ('d5:tag-17:rev-foo5:tag-27:rev-bare',))
1191
transport.mkdir('quack')
1192
transport = transport.clone('quack')
1193
branch = self.make_remote_branch(transport, client)
1194
result = branch.heads_to_fetch()
1195
self.assertFinished(client)
1197
(set(['rev-tip']), set(['rev-foo', 'rev-bar'])), result)
1199
def test_uses_rpc_for_formats_with_non_default_heads_to_fetch(self):
1200
transport = MemoryTransport()
1201
client = FakeClient(transport.base)
1202
client.add_expected_call(
1203
'Branch.get_stacked_on_url', ('quack/',),
1204
'error', ('NotStacked',))
1205
client.add_expected_call(
1206
'Branch.heads_to_fetch', ('quack/',),
1207
'success', (['tip'], ['tagged-1', 'tagged-2']))
1208
transport.mkdir('quack')
1209
transport = transport.clone('quack')
1210
branch = self.make_remote_branch(transport, client)
1211
branch._format._use_default_local_heads_to_fetch = lambda: False
1212
result = branch.heads_to_fetch()
1213
self.assertFinished(client)
1214
self.assertEqual((set(['tip']), set(['tagged-1', 'tagged-2'])), result)
1216
def test_backwards_compatible(self):
1217
self.setup_smart_server_with_call_log()
1218
# Make a branch with a single revision.
1219
builder = self.make_branch_builder('foo')
1220
builder.start_series()
1221
builder.build_snapshot('tip', None, [
1222
('add', ('', 'root-id', 'directory', ''))])
1223
builder.finish_series()
1224
branch = builder.get_branch()
1225
# Add two tags to that branch
1226
branch.tags.set_tag('tag-1', 'rev-1')
1227
branch.tags.set_tag('tag-2', 'rev-2')
1228
self.addCleanup(branch.lock_read().unlock)
1229
# Disable the heads_to_fetch verb
1230
verb = 'Branch.heads_to_fetch'
1231
self.disable_verb(verb)
1232
self.reset_smart_call_log()
1233
result = branch.heads_to_fetch()
1234
self.assertEqual((set(['tip']), set(['rev-1', 'rev-2'])), result)
1236
['Branch.last_revision_info', 'Branch.get_tags_bytes'],
1237
[call.call.method for call in self.hpss_calls])
1240
1003
class TestBranchLastRevisionInfo(RemoteBranchTestCase):
1242
1005
def test_empty_branch(self):
2526
2219
self.assertEqual([], client._calls)
2529
class TestRepositoryInsertStreamBase(TestRemoteRepository):
2530
"""Base class for Repository.insert_stream and .insert_stream_1.19
2534
def checkInsertEmptyStream(self, repo, client):
2535
"""Insert an empty stream, checking the result.
2537
This checks that there are no resume_tokens or missing_keys, and that
2538
the client is finished.
2540
sink = repo._get_sink()
2541
fmt = repository.format_registry.get_default()
2542
resume_tokens, missing_keys = sink.insert_stream([], fmt, [])
2543
self.assertEqual([], resume_tokens)
2544
self.assertEqual(set(), missing_keys)
2545
self.assertFinished(client)
2548
class TestRepositoryInsertStream(TestRepositoryInsertStreamBase):
2549
"""Tests for using Repository.insert_stream verb when the _1.19 variant is
2552
This test case is very similar to TestRepositoryInsertStream_1_19.
2556
TestRemoteRepository.setUp(self)
2557
self.disable_verb('Repository.insert_stream_1.19')
2559
def test_unlocked_repo(self):
2560
transport_path = 'quack'
2561
repo, client = self.setup_fake_client_and_repository(transport_path)
2562
client.add_expected_call(
2563
'Repository.insert_stream_1.19', ('quack/', ''),
2564
'unknown', ('Repository.insert_stream_1.19',))
2565
client.add_expected_call(
2566
'Repository.insert_stream', ('quack/', ''),
2568
client.add_expected_call(
2569
'Repository.insert_stream', ('quack/', ''),
2571
self.checkInsertEmptyStream(repo, client)
2573
def test_locked_repo_with_no_lock_token(self):
2574
transport_path = 'quack'
2575
repo, client = self.setup_fake_client_and_repository(transport_path)
2576
client.add_expected_call(
2577
'Repository.lock_write', ('quack/', ''),
2578
'success', ('ok', ''))
2579
client.add_expected_call(
2580
'Repository.insert_stream_1.19', ('quack/', ''),
2581
'unknown', ('Repository.insert_stream_1.19',))
2582
client.add_expected_call(
2583
'Repository.insert_stream', ('quack/', ''),
2585
client.add_expected_call(
2586
'Repository.insert_stream', ('quack/', ''),
2589
self.checkInsertEmptyStream(repo, client)
2591
def test_locked_repo_with_lock_token(self):
2592
transport_path = 'quack'
2593
repo, client = self.setup_fake_client_and_repository(transport_path)
2594
client.add_expected_call(
2595
'Repository.lock_write', ('quack/', ''),
2596
'success', ('ok', 'a token'))
2597
client.add_expected_call(
2598
'Repository.insert_stream_1.19', ('quack/', '', 'a token'),
2599
'unknown', ('Repository.insert_stream_1.19',))
2600
client.add_expected_call(
2601
'Repository.insert_stream_locked', ('quack/', '', 'a token'),
2603
client.add_expected_call(
2604
'Repository.insert_stream_locked', ('quack/', '', 'a token'),
2607
self.checkInsertEmptyStream(repo, client)
2609
def test_stream_with_inventory_deltas(self):
2610
"""'inventory-deltas' substreams cannot be sent to the
2611
Repository.insert_stream verb, because not all servers that implement
2612
that verb will accept them. So when one is encountered the RemoteSink
2613
immediately stops using that verb and falls back to VFS insert_stream.
2615
transport_path = 'quack'
2616
repo, client = self.setup_fake_client_and_repository(transport_path)
2617
client.add_expected_call(
2618
'Repository.insert_stream_1.19', ('quack/', ''),
2619
'unknown', ('Repository.insert_stream_1.19',))
2620
client.add_expected_call(
2621
'Repository.insert_stream', ('quack/', ''),
2623
client.add_expected_call(
2624
'Repository.insert_stream', ('quack/', ''),
2626
# Create a fake real repository for insert_stream to fall back on, so
2627
# that we can directly see the records the RemoteSink passes to the
2632
def insert_stream(self, stream, src_format, resume_tokens):
2633
for substream_kind, substream in stream:
2634
self.records.append(
2635
(substream_kind, [record.key for record in substream]))
2636
return ['fake tokens'], ['fake missing keys']
2637
fake_real_sink = FakeRealSink()
2638
class FakeRealRepository:
2639
def _get_sink(self):
2640
return fake_real_sink
2641
def is_in_write_group(self):
2643
def refresh_data(self):
2645
repo._real_repository = FakeRealRepository()
2646
sink = repo._get_sink()
2647
fmt = repository.format_registry.get_default()
2648
stream = self.make_stream_with_inv_deltas(fmt)
2649
resume_tokens, missing_keys = sink.insert_stream(stream, fmt, [])
2650
# Every record from the first inventory delta should have been sent to
2652
expected_records = [
2653
('inventory-deltas', [('rev2',), ('rev3',)]),
2654
('texts', [('some-rev', 'some-file')])]
2655
self.assertEqual(expected_records, fake_real_sink.records)
2656
# The return values from the real sink's insert_stream are propagated
2657
# back to the original caller.
2658
self.assertEqual(['fake tokens'], resume_tokens)
2659
self.assertEqual(['fake missing keys'], missing_keys)
2660
self.assertFinished(client)
2662
def make_stream_with_inv_deltas(self, fmt):
2663
"""Make a simple stream with an inventory delta followed by more
2664
records and more substreams to test that all records and substreams
2665
from that point on are used.
2667
This sends, in order:
2668
* inventories substream: rev1, rev2, rev3. rev2 and rev3 are
2670
* texts substream: (some-rev, some-file)
2672
# Define a stream using generators so that it isn't rewindable.
2673
inv = inventory.Inventory(revision_id='rev1')
2674
inv.root.revision = 'rev1'
2675
def stream_with_inv_delta():
2676
yield ('inventories', inventories_substream())
2677
yield ('inventory-deltas', inventory_delta_substream())
2679
versionedfile.FulltextContentFactory(
2680
('some-rev', 'some-file'), (), None, 'content')])
2681
def inventories_substream():
2682
# An empty inventory fulltext. This will be streamed normally.
2683
text = fmt._serializer.write_inventory_to_string(inv)
2684
yield versionedfile.FulltextContentFactory(
2685
('rev1',), (), None, text)
2686
def inventory_delta_substream():
2687
# An inventory delta. This can't be streamed via this verb, so it
2688
# will trigger a fallback to VFS insert_stream.
2689
entry = inv.make_entry(
2690
'directory', 'newdir', inv.root.file_id, 'newdir-id')
2691
entry.revision = 'ghost'
2692
delta = [(None, 'newdir', 'newdir-id', entry)]
2693
serializer = inventory_delta.InventoryDeltaSerializer(
2694
versioned_root=True, tree_references=False)
2695
lines = serializer.delta_to_lines('rev1', 'rev2', delta)
2696
yield versionedfile.ChunkedContentFactory(
2697
('rev2',), (('rev1',)), None, lines)
2699
lines = serializer.delta_to_lines('rev1', 'rev3', delta)
2700
yield versionedfile.ChunkedContentFactory(
2701
('rev3',), (('rev1',)), None, lines)
2702
return stream_with_inv_delta()
2705
class TestRepositoryInsertStream_1_19(TestRepositoryInsertStreamBase):
2707
def test_unlocked_repo(self):
2708
transport_path = 'quack'
2709
repo, client = self.setup_fake_client_and_repository(transport_path)
2710
client.add_expected_call(
2711
'Repository.insert_stream_1.19', ('quack/', ''),
2713
client.add_expected_call(
2714
'Repository.insert_stream_1.19', ('quack/', ''),
2716
self.checkInsertEmptyStream(repo, client)
2718
def test_locked_repo_with_no_lock_token(self):
2719
transport_path = 'quack'
2720
repo, client = self.setup_fake_client_and_repository(transport_path)
2721
client.add_expected_call(
2722
'Repository.lock_write', ('quack/', ''),
2723
'success', ('ok', ''))
2724
client.add_expected_call(
2725
'Repository.insert_stream_1.19', ('quack/', ''),
2727
client.add_expected_call(
2728
'Repository.insert_stream_1.19', ('quack/', ''),
2731
self.checkInsertEmptyStream(repo, client)
2733
def test_locked_repo_with_lock_token(self):
2734
transport_path = 'quack'
2735
repo, client = self.setup_fake_client_and_repository(transport_path)
2736
client.add_expected_call(
2737
'Repository.lock_write', ('quack/', ''),
2738
'success', ('ok', 'a token'))
2739
client.add_expected_call(
2740
'Repository.insert_stream_1.19', ('quack/', '', 'a token'),
2742
client.add_expected_call(
2743
'Repository.insert_stream_1.19', ('quack/', '', 'a token'),
2746
self.checkInsertEmptyStream(repo, client)
2222
class TestRepositoryInsertStream(TestRemoteRepository):
2224
def test_unlocked_repo(self):
2225
transport_path = 'quack'
2226
repo, client = self.setup_fake_client_and_repository(transport_path)
2227
client.add_expected_call(
2228
'Repository.insert_stream', ('quack/', ''),
2230
client.add_expected_call(
2231
'Repository.insert_stream', ('quack/', ''),
2233
sink = repo._get_sink()
2234
fmt = repository.RepositoryFormat.get_default_format()
2235
resume_tokens, missing_keys = sink.insert_stream([], fmt, [])
2236
self.assertEqual([], resume_tokens)
2237
self.assertEqual(set(), missing_keys)
2238
self.assertFinished(client)
2240
def test_locked_repo_with_no_lock_token(self):
2241
transport_path = 'quack'
2242
repo, client = self.setup_fake_client_and_repository(transport_path)
2243
client.add_expected_call(
2244
'Repository.lock_write', ('quack/', ''),
2245
'success', ('ok', ''))
2246
client.add_expected_call(
2247
'Repository.insert_stream', ('quack/', ''),
2249
client.add_expected_call(
2250
'Repository.insert_stream', ('quack/', ''),
2253
sink = repo._get_sink()
2254
fmt = repository.RepositoryFormat.get_default_format()
2255
resume_tokens, missing_keys = sink.insert_stream([], fmt, [])
2256
self.assertEqual([], resume_tokens)
2257
self.assertEqual(set(), missing_keys)
2258
self.assertFinished(client)
2260
def test_locked_repo_with_lock_token(self):
2261
transport_path = 'quack'
2262
repo, client = self.setup_fake_client_and_repository(transport_path)
2263
client.add_expected_call(
2264
'Repository.lock_write', ('quack/', ''),
2265
'success', ('ok', 'a token'))
2266
client.add_expected_call(
2267
'Repository.insert_stream_locked', ('quack/', '', 'a token'),
2269
client.add_expected_call(
2270
'Repository.insert_stream_locked', ('quack/', '', 'a token'),
2273
sink = repo._get_sink()
2274
fmt = repository.RepositoryFormat.get_default_format()
2275
resume_tokens, missing_keys = sink.insert_stream([], fmt, [])
2276
self.assertEqual([], resume_tokens)
2277
self.assertEqual(set(), missing_keys)
2278
self.assertFinished(client)
2749
2281
class TestRepositoryTarball(TestRemoteRepository):
3344
2794
def test_copy_content_into_avoids_revision_history(self):
3345
2795
local = self.make_branch('local')
3346
builder = self.make_branch_builder('remote')
3347
builder.build_commit(message="Commit.")
2796
remote_backing_tree = self.make_branch_and_tree('remote')
2797
remote_backing_tree.commit("Commit.")
3348
2798
remote_branch_url = self.smart_server.get_url() + 'remote'
3349
2799
remote_branch = bzrdir.BzrDir.open(remote_branch_url).open_branch()
3350
2800
local.repository.fetch(remote_branch.repository)
3351
2801
self.hpss_calls = []
3352
2802
remote_branch.copy_content_into(local)
3353
2803
self.assertFalse('Branch.revision_history' in self.hpss_calls)
3355
def test_fetch_everything_needs_just_one_call(self):
3356
local = self.make_branch('local')
3357
builder = self.make_branch_builder('remote')
3358
builder.build_commit(message="Commit.")
3359
remote_branch_url = self.smart_server.get_url() + 'remote'
3360
remote_branch = bzrdir.BzrDir.open(remote_branch_url).open_branch()
3361
self.hpss_calls = []
3362
local.repository.fetch(remote_branch.repository,
3363
fetch_spec=_mod_graph.EverythingResult(remote_branch.repository))
3364
self.assertEqual(['Repository.get_stream_1.19'], self.hpss_calls)
3366
def override_verb(self, verb_name, verb):
3367
request_handlers = request.request_handlers
3368
orig_verb = request_handlers.get(verb_name)
3369
request_handlers.register(verb_name, verb, override_existing=True)
3370
self.addCleanup(request_handlers.register, verb_name, orig_verb,
3371
override_existing=True)
3373
def test_fetch_everything_backwards_compat(self):
3374
"""Can fetch with EverythingResult even with pre 2.4 servers.
3376
Pre-2.4 do not support 'everything' searches with the
3377
Repository.get_stream_1.19 verb.
3380
class OldGetStreamVerb(SmartServerRepositoryGetStream_1_19):
3381
"""A version of the Repository.get_stream_1.19 verb patched to
3382
reject 'everything' searches the way 2.3 and earlier do.
3384
def recreate_search(self, repository, search_bytes, discard_excess=False):
3385
verb_log.append(search_bytes.split('\n', 1)[0])
3386
if search_bytes == 'everything':
3387
return (None, request.FailedSmartServerResponse(('BadSearch',)))
3388
return super(OldGetStreamVerb,
3389
self).recreate_search(repository, search_bytes,
3390
discard_excess=discard_excess)
3391
self.override_verb('Repository.get_stream_1.19', OldGetStreamVerb)
3392
local = self.make_branch('local')
3393
builder = self.make_branch_builder('remote')
3394
builder.build_commit(message="Commit.")
3395
remote_branch_url = self.smart_server.get_url() + 'remote'
3396
remote_branch = bzrdir.BzrDir.open(remote_branch_url).open_branch()
3397
self.hpss_calls = []
3398
local.repository.fetch(remote_branch.repository,
3399
fetch_spec=_mod_graph.EverythingResult(remote_branch.repository))
3400
# make sure the overridden verb was used
3401
self.assertLength(1, verb_log)
3402
# more than one HPSS call is needed, but because it's a VFS callback
3403
# its hard to predict exactly how many.
3404
self.assertTrue(len(self.hpss_calls) > 1)