479
491
self.assertEqual(None, result._branch_format)
480
492
self.assertFinished(client)
494
def test_unknown(self):
495
transport = self.get_transport('quack')
496
referenced = self.make_branch('referenced')
497
expected = referenced.bzrdir.cloning_metadir()
498
client = FakeClient(transport.base)
499
client.add_expected_call(
500
'BzrDir.cloning_metadir', ('quack/', 'False'),
501
'success', ('unknown', 'unknown', ('branch', ''))),
502
a_bzrdir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
504
self.assertRaises(errors.UnknownFormatError, a_bzrdir.cloning_metadir)
507
class TestBzrDirCheckoutMetaDir(TestRemote):
509
def test__get_checkout_format(self):
510
transport = MemoryTransport()
511
client = FakeClient(transport.base)
512
reference_bzrdir_format = bzrdir.format_registry.get('default')()
513
control_name = reference_bzrdir_format.network_name()
514
client.add_expected_call(
515
'BzrDir.checkout_metadir', ('quack/', ),
516
'success', (control_name, '', ''))
517
transport.mkdir('quack')
518
transport = transport.clone('quack')
519
a_bzrdir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
521
result = a_bzrdir.checkout_metadir()
522
# We should have got a reference control dir with default branch and
523
# repository formats.
524
self.assertEqual(bzrdir.BzrDirMetaFormat1, type(result))
525
self.assertEqual(None, result._repository_format)
526
self.assertEqual(None, result._branch_format)
527
self.assertFinished(client)
529
def test_unknown_format(self):
530
transport = MemoryTransport()
531
client = FakeClient(transport.base)
532
client.add_expected_call(
533
'BzrDir.checkout_metadir', ('quack/',),
534
'success', ('dontknow', '', ''))
535
transport.mkdir('quack')
536
transport = transport.clone('quack')
537
a_bzrdir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
539
self.assertRaises(errors.UnknownFormatError,
540
a_bzrdir.checkout_metadir)
541
self.assertFinished(client)
544
class TestBzrDirDestroyBranch(TestRemote):
546
def test_destroy_default(self):
547
transport = self.get_transport('quack')
548
referenced = self.make_branch('referenced')
549
client = FakeClient(transport.base)
550
client.add_expected_call(
551
'BzrDir.destroy_branch', ('quack/', ),
553
a_bzrdir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
555
a_bzrdir.destroy_branch()
556
self.assertFinished(client)
558
def test_destroy_named(self):
559
transport = self.get_transport('quack')
560
referenced = self.make_branch('referenced')
561
client = FakeClient(transport.base)
562
client.add_expected_call(
563
'BzrDir.destroy_branch', ('quack/', "foo"),
565
a_bzrdir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
567
a_bzrdir.destroy_branch("foo")
568
self.assertFinished(client)
571
class TestBzrDirHasWorkingTree(TestRemote):
573
def test_has_workingtree(self):
574
transport = self.get_transport('quack')
575
client = FakeClient(transport.base)
576
client.add_expected_call(
577
'BzrDir.has_workingtree', ('quack/',),
578
'success', ('yes',)),
579
a_bzrdir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
581
self.assertTrue(a_bzrdir.has_workingtree())
582
self.assertFinished(client)
584
def test_no_workingtree(self):
585
transport = self.get_transport('quack')
586
client = FakeClient(transport.base)
587
client.add_expected_call(
588
'BzrDir.has_workingtree', ('quack/',),
590
a_bzrdir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
592
self.assertFalse(a_bzrdir.has_workingtree())
593
self.assertFinished(client)
596
class TestBzrDirDestroyRepository(TestRemote):
598
def test_destroy_repository(self):
599
transport = self.get_transport('quack')
600
client = FakeClient(transport.base)
601
client.add_expected_call(
602
'BzrDir.destroy_repository', ('quack/',),
604
a_bzrdir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
606
a_bzrdir.destroy_repository()
607
self.assertFinished(client)
483
610
class TestBzrDirOpen(TestRemote):
966
1121
return RemoteBranch(bzrdir, repo, _client=client, format=format)
1124
class TestBranchBreakLock(RemoteBranchTestCase):
1126
def test_break_lock(self):
1127
transport_path = 'quack'
1128
transport = MemoryTransport()
1129
client = FakeClient(transport.base)
1130
client.add_expected_call(
1131
'Branch.get_stacked_on_url', ('quack/',),
1132
'error', ('NotStacked',))
1133
client.add_expected_call(
1134
'Branch.break_lock', ('quack/',),
1136
transport.mkdir('quack')
1137
transport = transport.clone('quack')
1138
branch = self.make_remote_branch(transport, client)
1140
self.assertFinished(client)
1143
class TestBranchGetPhysicalLockStatus(RemoteBranchTestCase):
1145
def test_get_physical_lock_status_yes(self):
1146
transport = MemoryTransport()
1147
client = FakeClient(transport.base)
1148
client.add_expected_call(
1149
'Branch.get_stacked_on_url', ('quack/',),
1150
'error', ('NotStacked',))
1151
client.add_expected_call(
1152
'Branch.get_physical_lock_status', ('quack/',),
1153
'success', ('yes',))
1154
transport.mkdir('quack')
1155
transport = transport.clone('quack')
1156
branch = self.make_remote_branch(transport, client)
1157
result = branch.get_physical_lock_status()
1158
self.assertFinished(client)
1159
self.assertEqual(True, result)
1161
def test_get_physical_lock_status_no(self):
1162
transport = MemoryTransport()
1163
client = FakeClient(transport.base)
1164
client.add_expected_call(
1165
'Branch.get_stacked_on_url', ('quack/',),
1166
'error', ('NotStacked',))
1167
client.add_expected_call(
1168
'Branch.get_physical_lock_status', ('quack/',),
1170
transport.mkdir('quack')
1171
transport = transport.clone('quack')
1172
branch = self.make_remote_branch(transport, client)
1173
result = branch.get_physical_lock_status()
1174
self.assertFinished(client)
1175
self.assertEqual(False, result)
969
1178
class TestBranchGetParent(RemoteBranchTestCase):
971
1180
def test_no_parent(self):
1142
1351
[('set_tags_bytes', 'tags bytes')] * 2, real_branch.calls)
1354
class TestBranchHeadsToFetch(RemoteBranchTestCase):
1356
def test_uses_last_revision_info_and_tags_by_default(self):
1357
transport = MemoryTransport()
1358
client = FakeClient(transport.base)
1359
client.add_expected_call(
1360
'Branch.get_stacked_on_url', ('quack/',),
1361
'error', ('NotStacked',))
1362
client.add_expected_call(
1363
'Branch.last_revision_info', ('quack/',),
1364
'success', ('ok', '1', 'rev-tip'))
1365
client.add_expected_call(
1366
'Branch.get_config_file', ('quack/',),
1367
'success', ('ok',), '')
1368
transport.mkdir('quack')
1369
transport = transport.clone('quack')
1370
branch = self.make_remote_branch(transport, client)
1371
result = branch.heads_to_fetch()
1372
self.assertFinished(client)
1373
self.assertEqual((set(['rev-tip']), set()), result)
1375
def test_uses_last_revision_info_and_tags_when_set(self):
1376
transport = MemoryTransport()
1377
client = FakeClient(transport.base)
1378
client.add_expected_call(
1379
'Branch.get_stacked_on_url', ('quack/',),
1380
'error', ('NotStacked',))
1381
client.add_expected_call(
1382
'Branch.last_revision_info', ('quack/',),
1383
'success', ('ok', '1', 'rev-tip'))
1384
client.add_expected_call(
1385
'Branch.get_config_file', ('quack/',),
1386
'success', ('ok',), 'branch.fetch_tags = True')
1387
# XXX: this will break if the default format's serialization of tags
1388
# changes, or if the RPC for fetching tags changes from get_tags_bytes.
1389
client.add_expected_call(
1390
'Branch.get_tags_bytes', ('quack/',),
1391
'success', ('d5:tag-17:rev-foo5:tag-27:rev-bare',))
1392
transport.mkdir('quack')
1393
transport = transport.clone('quack')
1394
branch = self.make_remote_branch(transport, client)
1395
result = branch.heads_to_fetch()
1396
self.assertFinished(client)
1398
(set(['rev-tip']), set(['rev-foo', 'rev-bar'])), result)
1400
def test_uses_rpc_for_formats_with_non_default_heads_to_fetch(self):
1401
transport = MemoryTransport()
1402
client = FakeClient(transport.base)
1403
client.add_expected_call(
1404
'Branch.get_stacked_on_url', ('quack/',),
1405
'error', ('NotStacked',))
1406
client.add_expected_call(
1407
'Branch.heads_to_fetch', ('quack/',),
1408
'success', (['tip'], ['tagged-1', 'tagged-2']))
1409
transport.mkdir('quack')
1410
transport = transport.clone('quack')
1411
branch = self.make_remote_branch(transport, client)
1412
branch._format._use_default_local_heads_to_fetch = lambda: False
1413
result = branch.heads_to_fetch()
1414
self.assertFinished(client)
1415
self.assertEqual((set(['tip']), set(['tagged-1', 'tagged-2'])), result)
1417
def make_branch_with_tags(self):
1418
self.setup_smart_server_with_call_log()
1419
# Make a branch with a single revision.
1420
builder = self.make_branch_builder('foo')
1421
builder.start_series()
1422
builder.build_snapshot('tip', None, [
1423
('add', ('', 'root-id', 'directory', ''))])
1424
builder.finish_series()
1425
branch = builder.get_branch()
1426
# Add two tags to that branch
1427
branch.tags.set_tag('tag-1', 'rev-1')
1428
branch.tags.set_tag('tag-2', 'rev-2')
1431
def test_backwards_compatible(self):
1432
branch = self.make_branch_with_tags()
1433
c = branch.get_config()
1434
c.set_user_option('branch.fetch_tags', 'True')
1435
self.addCleanup(branch.lock_read().unlock)
1436
# Disable the heads_to_fetch verb
1437
verb = 'Branch.heads_to_fetch'
1438
self.disable_verb(verb)
1439
self.reset_smart_call_log()
1440
result = branch.heads_to_fetch()
1441
self.assertEqual((set(['tip']), set(['rev-1', 'rev-2'])), result)
1443
['Branch.last_revision_info', 'Branch.get_config_file',
1444
'Branch.get_tags_bytes'],
1445
[call.call.method for call in self.hpss_calls])
1447
def test_backwards_compatible_no_tags(self):
1448
branch = self.make_branch_with_tags()
1449
c = branch.get_config()
1450
c.set_user_option('branch.fetch_tags', 'False')
1451
self.addCleanup(branch.lock_read().unlock)
1452
# Disable the heads_to_fetch verb
1453
verb = 'Branch.heads_to_fetch'
1454
self.disable_verb(verb)
1455
self.reset_smart_call_log()
1456
result = branch.heads_to_fetch()
1457
self.assertEqual((set(['tip']), set()), result)
1459
['Branch.last_revision_info', 'Branch.get_config_file'],
1460
[call.call.method for call in self.hpss_calls])
1145
1463
class TestBranchLastRevisionInfo(RemoteBranchTestCase):
1147
1465
def test_empty_branch(self):
1704
2016
self.assertEqual(value_dict, branch._get_config().get_option('name'))
2019
class TestBranchGetPutConfigStore(RemoteBranchTestCase):
2021
def test_get_branch_conf(self):
2022
# in an empty branch we decode the response properly
2023
client = FakeClient()
2024
client.add_expected_call(
2025
'Branch.get_stacked_on_url', ('memory:///',),
2026
'error', ('NotStacked',),)
2027
client.add_success_response_with_body('# config file body', 'ok')
2028
transport = MemoryTransport()
2029
branch = self.make_remote_branch(transport, client)
2030
config = branch.get_config_stack()
2032
config.get("log_format")
2034
[('call', 'Branch.get_stacked_on_url', ('memory:///',)),
2035
('call_expecting_body', 'Branch.get_config_file', ('memory:///',))],
2038
def test_set_branch_conf(self):
2039
client = FakeClient()
2040
client.add_expected_call(
2041
'Branch.get_stacked_on_url', ('memory:///',),
2042
'error', ('NotStacked',),)
2043
client.add_expected_call(
2044
'Branch.lock_write', ('memory:///', '', ''),
2045
'success', ('ok', 'branch token', 'repo token'))
2046
client.add_expected_call(
2047
'Branch.get_config_file', ('memory:///', ),
2048
'success', ('ok', ), "# line 1\n")
2049
client.add_expected_call(
2050
'Branch.put_config_file', ('memory:///', 'branch token',
2053
client.add_expected_call(
2054
'Branch.unlock', ('memory:///', 'branch token', 'repo token'),
2056
transport = MemoryTransport()
2057
branch = self.make_remote_branch(transport, client)
2059
config = branch.get_config_stack()
2060
config.set('email', 'The Dude <lebowski@example.com>')
2062
self.assertFinished(client)
2064
[('call', 'Branch.get_stacked_on_url', ('memory:///',)),
2065
('call', 'Branch.lock_write', ('memory:///', '', '')),
2066
('call_expecting_body', 'Branch.get_config_file', ('memory:///',)),
2067
('call_with_body_bytes_expecting_body', 'Branch.put_config_file',
2068
('memory:///', 'branch token', 'repo token'),
2069
'# line 1\nemail = The Dude <lebowski@example.com>\n'),
2070
('call', 'Branch.unlock', ('memory:///', 'branch token', 'repo token'))],
1707
2074
class TestBranchLockWrite(RemoteBranchTestCase):
1709
2076
def test_lock_write_unlockable(self):
1722
2089
self.assertFinished(client)
2092
class TestBranchRevisionIdToRevno(RemoteBranchTestCase):
2094
def test_simple(self):
2095
transport = MemoryTransport()
2096
client = FakeClient(transport.base)
2097
client.add_expected_call(
2098
'Branch.get_stacked_on_url', ('quack/',),
2099
'error', ('NotStacked',),)
2100
client.add_expected_call(
2101
'Branch.revision_id_to_revno', ('quack/', 'null:'),
2102
'success', ('ok', '0',),)
2103
client.add_expected_call(
2104
'Branch.revision_id_to_revno', ('quack/', 'unknown'),
2105
'error', ('NoSuchRevision', 'unknown',),)
2106
transport.mkdir('quack')
2107
transport = transport.clone('quack')
2108
branch = self.make_remote_branch(transport, client)
2109
self.assertEquals(0, branch.revision_id_to_revno('null:'))
2110
self.assertRaises(errors.NoSuchRevision,
2111
branch.revision_id_to_revno, 'unknown')
2112
self.assertFinished(client)
2114
def test_dotted(self):
2115
transport = MemoryTransport()
2116
client = FakeClient(transport.base)
2117
client.add_expected_call(
2118
'Branch.get_stacked_on_url', ('quack/',),
2119
'error', ('NotStacked',),)
2120
client.add_expected_call(
2121
'Branch.revision_id_to_revno', ('quack/', 'null:'),
2122
'success', ('ok', '0',),)
2123
client.add_expected_call(
2124
'Branch.revision_id_to_revno', ('quack/', 'unknown'),
2125
'error', ('NoSuchRevision', 'unknown',),)
2126
transport.mkdir('quack')
2127
transport = transport.clone('quack')
2128
branch = self.make_remote_branch(transport, client)
2129
self.assertEquals((0, ), branch.revision_id_to_dotted_revno('null:'))
2130
self.assertRaises(errors.NoSuchRevision,
2131
branch.revision_id_to_dotted_revno, 'unknown')
2132
self.assertFinished(client)
2134
def test_dotted_no_smart_verb(self):
2135
self.setup_smart_server_with_call_log()
2136
branch = self.make_branch('.')
2137
self.disable_verb('Branch.revision_id_to_revno')
2138
self.reset_smart_call_log()
2139
self.assertEquals((0, ),
2140
branch.revision_id_to_dotted_revno('null:'))
2141
self.assertLength(7, self.hpss_calls)
1725
2144
class TestBzrDirGetSetConfig(RemoteBzrDirTestCase):
1727
2146
def test__get_config(self):
2389
class TestRepositoryBreakLock(TestRemoteRepository):
2391
def test_break_lock(self):
2392
transport_path = 'quack'
2393
repo, client = self.setup_fake_client_and_repository(transport_path)
2394
client.add_success_response('ok')
2397
[('call', 'Repository.break_lock', ('quack/',))],
2401
class TestRepositoryGetSerializerFormat(TestRemoteRepository):
2403
def test_get_serializer_format(self):
2404
transport_path = 'hill'
2405
repo, client = self.setup_fake_client_and_repository(transport_path)
2406
client.add_success_response('ok', '7')
2407
self.assertEquals('7', repo.get_serializer_format())
2409
[('call', 'VersionedFileRepository.get_serializer_format',
2414
class TestRepositoryReconcile(TestRemoteRepository):
2416
def test_reconcile(self):
2417
transport_path = 'hill'
2418
repo, client = self.setup_fake_client_and_repository(transport_path)
2419
body = ("garbage_inventories: 2\n"
2420
"inconsistent_parents: 3\n")
2421
client.add_expected_call(
2422
'Repository.lock_write', ('hill/', ''),
2423
'success', ('ok', 'a token'))
2424
client.add_success_response_with_body(body, 'ok')
2425
reconciler = repo.reconcile()
2427
[('call', 'Repository.lock_write', ('hill/', '')),
2428
('call_expecting_body', 'Repository.reconcile',
2429
('hill/', 'a token'))],
2431
self.assertEquals(2, reconciler.garbage_inventories)
2432
self.assertEquals(3, reconciler.inconsistent_parents)
2435
class TestRepositoryGetRevisionSignatureText(TestRemoteRepository):
2437
def test_text(self):
2438
# ('ok',), body with signature text
2439
transport_path = 'quack'
2440
repo, client = self.setup_fake_client_and_repository(transport_path)
2441
client.add_success_response_with_body(
2443
self.assertEquals("THETEXT", repo.get_signature_text("revid"))
2445
[('call_expecting_body', 'Repository.get_revision_signature_text',
2446
('quack/', 'revid'))],
2449
def test_no_signature(self):
2450
transport_path = 'quick'
2451
repo, client = self.setup_fake_client_and_repository(transport_path)
2452
client.add_error_response('nosuchrevision', 'unknown')
2453
self.assertRaises(errors.NoSuchRevision, repo.get_signature_text,
2456
[('call_expecting_body', 'Repository.get_revision_signature_text',
2457
('quick/', 'unknown'))],
1945
2461
class TestRepositoryGetGraph(TestRemoteRepository):
1947
2463
def test_get_graph(self):
3052
class TestRepositoryWriteGroups(TestRemoteRepository):
3054
def test_start_write_group(self):
3055
transport_path = 'quack'
3056
repo, client = self.setup_fake_client_and_repository(transport_path)
3057
client.add_expected_call(
3058
'Repository.lock_write', ('quack/', ''),
3059
'success', ('ok', 'a token'))
3060
client.add_expected_call(
3061
'Repository.start_write_group', ('quack/', 'a token'),
3062
'success', ('ok', ('token1', )))
3064
repo.start_write_group()
3066
def test_start_write_group_unsuspendable(self):
3067
# Some repositories do not support suspending write
3068
# groups. For those, fall back to the "real" repository.
3069
transport_path = 'quack'
3070
repo, client = self.setup_fake_client_and_repository(transport_path)
3071
def stub_ensure_real():
3072
client._calls.append(('_ensure_real',))
3073
repo._real_repository = _StubRealPackRepository(client._calls)
3074
repo._ensure_real = stub_ensure_real
3075
client.add_expected_call(
3076
'Repository.lock_write', ('quack/', ''),
3077
'success', ('ok', 'a token'))
3078
client.add_expected_call(
3079
'Repository.start_write_group', ('quack/', 'a token'),
3080
'error', ('UnsuspendableWriteGroup',))
3082
repo.start_write_group()
3083
self.assertEquals(client._calls[-2:], [
3085
('start_write_group',)])
3087
def test_commit_write_group(self):
3088
transport_path = 'quack'
3089
repo, client = self.setup_fake_client_and_repository(transport_path)
3090
client.add_expected_call(
3091
'Repository.lock_write', ('quack/', ''),
3092
'success', ('ok', 'a token'))
3093
client.add_expected_call(
3094
'Repository.start_write_group', ('quack/', 'a token'),
3095
'success', ('ok', ['token1']))
3096
client.add_expected_call(
3097
'Repository.commit_write_group', ('quack/', 'a token', ['token1']),
3100
repo.start_write_group()
3101
repo.commit_write_group()
3103
def test_abort_write_group(self):
3104
transport_path = 'quack'
3105
repo, client = self.setup_fake_client_and_repository(transport_path)
3106
client.add_expected_call(
3107
'Repository.lock_write', ('quack/', ''),
3108
'success', ('ok', 'a token'))
3109
client.add_expected_call(
3110
'Repository.start_write_group', ('quack/', 'a token'),
3111
'success', ('ok', ['token1']))
3112
client.add_expected_call(
3113
'Repository.abort_write_group', ('quack/', 'a token', ['token1']),
3116
repo.start_write_group()
3117
repo.abort_write_group(False)
3119
def test_suspend_write_group(self):
3120
transport_path = 'quack'
3121
repo, client = self.setup_fake_client_and_repository(transport_path)
3122
self.assertEquals([], repo.suspend_write_group())
3124
def test_resume_write_group(self):
3125
transport_path = 'quack'
3126
repo, client = self.setup_fake_client_and_repository(transport_path)
3127
client.add_expected_call(
3128
'Repository.lock_write', ('quack/', ''),
3129
'success', ('ok', 'a token'))
3130
client.add_expected_call(
3131
'Repository.check_write_group', ('quack/', 'a token', ['token1']),
3134
repo.resume_write_group(['token1'])
2369
3137
class TestRepositorySetMakeWorkingTrees(TestRemoteRepository):
2371
3139
def test_backwards_compat(self):
2935
3757
expected_error = errors.PermissionDenied(path, extra)
2936
3758
self.assertEqual(expected_error, translated_error)
3760
# GZ 2011-03-02: TODO test for PermissionDenied with non-ascii 'extra'
3762
def test_NoSuchFile_context_path(self):
3763
local_path = "local path"
3764
translated_error = self.translateTuple(('ReadError', "remote path"),
3766
expected_error = errors.ReadError(local_path)
3767
self.assertEqual(expected_error, translated_error)
3769
def test_NoSuchFile_without_context(self):
3770
remote_path = "remote path"
3771
translated_error = self.translateTuple(('ReadError', remote_path))
3772
expected_error = errors.ReadError(remote_path)
3773
self.assertEqual(expected_error, translated_error)
3775
def test_ReadOnlyError(self):
3776
translated_error = self.translateTuple(('ReadOnlyError',))
3777
expected_error = errors.TransportNotPossible("readonly transport")
3778
self.assertEqual(expected_error, translated_error)
3780
def test_MemoryError(self):
3781
translated_error = self.translateTuple(('MemoryError',))
3782
self.assertStartsWith(str(translated_error),
3783
"remote server out of memory")
3785
def test_generic_IndexError_no_classname(self):
3786
err = errors.ErrorFromSmartServer(('error', "list index out of range"))
3787
translated_error = self.translateErrorFromSmartServer(err)
3788
expected_error = errors.UnknownErrorFromSmartServer(err)
3789
self.assertEqual(expected_error, translated_error)
3791
# GZ 2011-03-02: TODO test generic non-ascii error string
3793
def test_generic_KeyError(self):
3794
err = errors.ErrorFromSmartServer(('error', 'KeyError', "1"))
3795
translated_error = self.translateErrorFromSmartServer(err)
3796
expected_error = errors.UnknownErrorFromSmartServer(err)
3797
self.assertEqual(expected_error, translated_error)
2939
3800
class TestErrorTranslationRobustness(TestErrorTranslationBase):
2940
3801
"""Unit tests for bzrlib.remote._translate_error's robustness.
3183
4046
def test_copy_content_into_avoids_revision_history(self):
3184
4047
local = self.make_branch('local')
3185
remote_backing_tree = self.make_branch_and_tree('remote')
3186
remote_backing_tree.commit("Commit.")
4048
builder = self.make_branch_builder('remote')
4049
builder.build_commit(message="Commit.")
3187
4050
remote_branch_url = self.smart_server.get_url() + 'remote'
3188
4051
remote_branch = bzrdir.BzrDir.open(remote_branch_url).open_branch()
3189
4052
local.repository.fetch(remote_branch.repository)
3190
4053
self.hpss_calls = []
3191
4054
remote_branch.copy_content_into(local)
3192
4055
self.assertFalse('Branch.revision_history' in self.hpss_calls)
4057
def test_fetch_everything_needs_just_one_call(self):
4058
local = self.make_branch('local')
4059
builder = self.make_branch_builder('remote')
4060
builder.build_commit(message="Commit.")
4061
remote_branch_url = self.smart_server.get_url() + 'remote'
4062
remote_branch = bzrdir.BzrDir.open(remote_branch_url).open_branch()
4063
self.hpss_calls = []
4064
local.repository.fetch(
4065
remote_branch.repository,
4066
fetch_spec=vf_search.EverythingResult(remote_branch.repository))
4067
self.assertEqual(['Repository.get_stream_1.19'], self.hpss_calls)
4069
def override_verb(self, verb_name, verb):
4070
request_handlers = request.request_handlers
4071
orig_verb = request_handlers.get(verb_name)
4072
orig_info = request_handlers.get_info(verb_name)
4073
request_handlers.register(verb_name, verb, override_existing=True)
4074
self.addCleanup(request_handlers.register, verb_name, orig_verb,
4075
override_existing=True, info=orig_info)
4077
def test_fetch_everything_backwards_compat(self):
4078
"""Can fetch with EverythingResult even with pre 2.4 servers.
4080
Pre-2.4 do not support 'everything' searches with the
4081
Repository.get_stream_1.19 verb.
4084
class OldGetStreamVerb(SmartServerRepositoryGetStream_1_19):
4085
"""A version of the Repository.get_stream_1.19 verb patched to
4086
reject 'everything' searches the way 2.3 and earlier do.
4088
def recreate_search(self, repository, search_bytes,
4089
discard_excess=False):
4090
verb_log.append(search_bytes.split('\n', 1)[0])
4091
if search_bytes == 'everything':
4093
request.FailedSmartServerResponse(('BadSearch',)))
4094
return super(OldGetStreamVerb,
4095
self).recreate_search(repository, search_bytes,
4096
discard_excess=discard_excess)
4097
self.override_verb('Repository.get_stream_1.19', OldGetStreamVerb)
4098
local = self.make_branch('local')
4099
builder = self.make_branch_builder('remote')
4100
builder.build_commit(message="Commit.")
4101
remote_branch_url = self.smart_server.get_url() + 'remote'
4102
remote_branch = bzrdir.BzrDir.open(remote_branch_url).open_branch()
4103
self.hpss_calls = []
4104
local.repository.fetch(
4105
remote_branch.repository,
4106
fetch_spec=vf_search.EverythingResult(remote_branch.repository))
4107
# make sure the overridden verb was used
4108
self.assertLength(1, verb_log)
4109
# more than one HPSS call is needed, but because it's a VFS callback
4110
# its hard to predict exactly how many.
4111
self.assertTrue(len(self.hpss_calls) > 1)
4114
class TestUpdateBoundBranchWithModifiedBoundLocation(
4115
tests.TestCaseWithTransport):
4116
"""Ensure correct handling of bound_location modifications.
4118
This is tested against a smart server as http://pad.lv/786980 was about a
4119
ReadOnlyError (write attempt during a read-only transaction) which can only
4120
happen in this context.
4124
super(TestUpdateBoundBranchWithModifiedBoundLocation, self).setUp()
4125
self.transport_server = test_server.SmartTCPServer_for_testing
4127
def make_master_and_checkout(self, master_name, checkout_name):
4128
# Create the master branch and its associated checkout
4129
self.master = self.make_branch_and_tree(master_name)
4130
self.checkout = self.master.branch.create_checkout(checkout_name)
4131
# Modify the master branch so there is something to update
4132
self.master.commit('add stuff')
4133
self.last_revid = self.master.commit('even more stuff')
4134
self.bound_location = self.checkout.branch.get_bound_location()
4136
def assertUpdateSucceeds(self, new_location):
4137
self.checkout.branch.set_bound_location(new_location)
4138
self.checkout.update()
4139
self.assertEquals(self.last_revid, self.checkout.last_revision())
4141
def test_without_final_slash(self):
4142
self.make_master_and_checkout('master', 'checkout')
4143
# For unclear reasons some users have a bound_location without a final
4144
# '/', simulate that by forcing such a value
4145
self.assertEndsWith(self.bound_location, '/')
4146
self.assertUpdateSucceeds(self.bound_location.rstrip('/'))
4148
def test_plus_sign(self):
4149
self.make_master_and_checkout('+master', 'checkout')
4150
self.assertUpdateSucceeds(self.bound_location.replace('%2B', '+', 1))
4152
def test_tilda(self):
4153
# Embed ~ in the middle of the path just to avoid any $HOME
4155
self.make_master_and_checkout('mas~ter', 'checkout')
4156
self.assertUpdateSucceeds(self.bound_location.replace('%2E', '~', 1))
4159
class TestWithCustomErrorHandler(RemoteBranchTestCase):
4161
def test_no_context(self):
4162
class OutOfCoffee(errors.BzrError):
4163
"""A dummy exception for testing."""
4165
def __init__(self, urgency):
4166
self.urgency = urgency
4167
remote.no_context_error_translators.register("OutOfCoffee",
4168
lambda err: OutOfCoffee(err.error_args[0]))
4169
transport = MemoryTransport()
4170
client = FakeClient(transport.base)
4171
client.add_expected_call(
4172
'Branch.get_stacked_on_url', ('quack/',),
4173
'error', ('NotStacked',))
4174
client.add_expected_call(
4175
'Branch.last_revision_info',
4177
'error', ('OutOfCoffee', 'low'))
4178
transport.mkdir('quack')
4179
transport = transport.clone('quack')
4180
branch = self.make_remote_branch(transport, client)
4181
self.assertRaises(OutOfCoffee, branch.last_revision_info)
4182
self.assertFinished(client)
4184
def test_with_context(self):
4185
class OutOfTea(errors.BzrError):
4186
def __init__(self, branch, urgency):
4187
self.branch = branch
4188
self.urgency = urgency
4189
remote.error_translators.register("OutOfTea",
4190
lambda err, find, path: OutOfTea(err.error_args[0],
4192
transport = MemoryTransport()
4193
client = FakeClient(transport.base)
4194
client.add_expected_call(
4195
'Branch.get_stacked_on_url', ('quack/',),
4196
'error', ('NotStacked',))
4197
client.add_expected_call(
4198
'Branch.last_revision_info',
4200
'error', ('OutOfTea', 'low'))
4201
transport.mkdir('quack')
4202
transport = transport.clone('quack')
4203
branch = self.make_remote_branch(transport, client)
4204
self.assertRaises(OutOfTea, branch.last_revision_info)
4205
self.assertFinished(client)
4208
class TestRepositoryPack(TestRemoteRepository):
4210
def test_pack(self):
4211
transport_path = 'quack'
4212
repo, client = self.setup_fake_client_and_repository(transport_path)
4213
client.add_expected_call(
4214
'Repository.lock_write', ('quack/', ''),
4215
'success', ('ok', 'token'))
4216
client.add_expected_call(
4217
'Repository.pack', ('quack/', 'token', 'False'),
4218
'success', ('ok',), )
4219
client.add_expected_call(
4220
'Repository.unlock', ('quack/', 'token'),
4221
'success', ('ok', ))
4224
def test_pack_with_hint(self):
4225
transport_path = 'quack'
4226
repo, client = self.setup_fake_client_and_repository(transport_path)
4227
client.add_expected_call(
4228
'Repository.lock_write', ('quack/', ''),
4229
'success', ('ok', 'token'))
4230
client.add_expected_call(
4231
'Repository.pack', ('quack/', 'token', 'False'),
4232
'success', ('ok',), )
4233
client.add_expected_call(
4234
'Repository.unlock', ('quack/', 'token', 'False'),
4235
'success', ('ok', ))
4236
repo.pack(['hinta', 'hintb'])
4239
class TestRepositoryIterInventories(TestRemoteRepository):
4240
"""Test Repository.iter_inventories."""
4242
def _serialize_inv_delta(self, old_name, new_name, delta):
4243
serializer = inventory_delta.InventoryDeltaSerializer(True, False)
4244
return "".join(serializer.delta_to_lines(old_name, new_name, delta))
4246
def test_single_empty(self):
4247
transport_path = 'quack'
4248
repo, client = self.setup_fake_client_and_repository(transport_path)
4249
fmt = bzrdir.format_registry.get('2a')().repository_format
4251
stream = [('inventory-deltas', [
4252
versionedfile.FulltextContentFactory('somerevid', None, None,
4253
self._serialize_inv_delta('null:', 'somerevid', []))])]
4254
client.add_expected_call(
4255
'VersionedFileRepository.get_inventories', ('quack/', 'unordered'),
4256
'success', ('ok', ),
4257
_stream_to_byte_stream(stream, fmt))
4258
ret = list(repo.iter_inventories(["somerevid"]))
4259
self.assertLength(1, ret)
4261
self.assertEquals("somerevid", inv.revision_id)
4263
def test_empty(self):
4264
transport_path = 'quack'
4265
repo, client = self.setup_fake_client_and_repository(transport_path)
4266
ret = list(repo.iter_inventories([]))
4267
self.assertEquals(ret, [])
4269
def test_missing(self):
4270
transport_path = 'quack'
4271
repo, client = self.setup_fake_client_and_repository(transport_path)
4272
client.add_expected_call(
4273
'VersionedFileRepository.get_inventories', ('quack/', 'unordered'),
4274
'success', ('ok', ), iter([]))
4275
self.assertRaises(errors.NoSuchRevision, list, repo.iter_inventories(