~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_remote.py

  • Committer: Jelmer Vernooij
  • Date: 2012-02-20 12:19:29 UTC
  • mfrom: (6437.23.11 2.5)
  • mto: (6581.1.1 trunk)
  • mto: This revision was merged to the branch mainline in revision 6582.
  • Revision ID: jelmer@samba.org-20120220121929-7ni2psvjoatm1yp4
Merge bzr/2.5.

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
 
26
26
import bz2
27
27
from cStringIO import StringIO
 
28
import zlib
28
29
 
29
30
from bzrlib import (
 
31
    bencode,
30
32
    branch,
31
33
    bzrdir,
32
34
    config,
33
35
    controldir,
34
36
    errors,
35
 
    graph as _mod_graph,
36
37
    inventory,
37
38
    inventory_delta,
38
39
    remote,
41
42
    transport,
42
43
    treebuilder,
43
44
    versionedfile,
 
45
    vf_search,
44
46
    )
45
47
from bzrlib.branch import Branch
46
48
from bzrlib.bzrdir import (
48
50
    BzrDirFormat,
49
51
    RemoteBzrProber,
50
52
    )
 
53
from bzrlib.chk_serializer import chk_bencode_serializer
51
54
from bzrlib.remote import (
52
55
    RemoteBranch,
53
56
    RemoteBranchFormat,
57
60
    RemoteRepositoryFormat,
58
61
    )
59
62
from bzrlib.repofmt import groupcompress_repo, knitpack_repo
60
 
from bzrlib.revision import NULL_REVISION
 
63
from bzrlib.revision import (
 
64
    NULL_REVISION,
 
65
    Revision,
 
66
    )
61
67
from bzrlib.smart import medium, request
62
68
from bzrlib.smart.client import _SmartClient
63
69
from bzrlib.smart.repository import (
64
70
    SmartServerRepositoryGetParentMap,
65
71
    SmartServerRepositoryGetStream_1_19,
 
72
    _stream_to_byte_stream,
66
73
    )
 
74
from bzrlib.symbol_versioning import deprecated_in
67
75
from bzrlib.tests import (
68
76
    test_server,
69
77
    )
115
123
 
116
124
    def test_remote_branch_revision_history(self):
117
125
        b = BzrDir.open_from_transport(self.transport).open_branch()
118
 
        self.assertEqual([], b.revision_history())
 
126
        self.assertEqual([],
 
127
            self.applyDeprecated(deprecated_in((2, 5, 0)), b.revision_history))
119
128
        r1 = self.local_wt.commit('1st commit')
120
129
        r2 = self.local_wt.commit('1st commit', rev_id=u'\xc8'.encode('utf8'))
121
 
        self.assertEqual([r1, r2], b.revision_history())
 
130
        self.assertEqual([r1, r2],
 
131
            self.applyDeprecated(deprecated_in((2, 5, 0)), b.revision_history))
122
132
 
123
133
    def test_find_correct_format(self):
124
134
        """Should open a RemoteBzrDir over a RemoteTransport"""
165
175
    def test_remote_branch_set_append_revisions_only(self):
166
176
        # Make a format 1.9 branch, which supports append_revisions_only
167
177
        branch = self.make_branch('branch', format='1.9')
168
 
        config = branch.get_config()
169
178
        branch.set_append_revisions_only(True)
 
179
        config = branch.get_config_stack()
170
180
        self.assertEqual(
171
 
            'True', config.get_user_option('append_revisions_only'))
 
181
            True, config.get('append_revisions_only'))
172
182
        branch.set_append_revisions_only(False)
 
183
        config = branch.get_config_stack()
173
184
        self.assertEqual(
174
 
            'False', config.get_user_option('append_revisions_only'))
 
185
            False, config.get('append_revisions_only'))
175
186
 
176
187
    def test_remote_branch_set_append_revisions_only_upgrade_reqd(self):
177
188
        branch = self.make_branch('branch', format='knit')
178
 
        config = branch.get_config()
179
189
        self.assertRaises(
180
190
            errors.UpgradeRequired, branch.set_append_revisions_only, True)
181
191
 
481
491
        self.assertEqual(None, result._branch_format)
482
492
        self.assertFinished(client)
483
493
 
 
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(),
 
503
            _client=client)
 
504
        self.assertRaises(errors.UnknownFormatError, a_bzrdir.cloning_metadir)
 
505
 
 
506
 
 
507
class TestBzrDirCheckoutMetaDir(TestRemote):
 
508
 
 
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(),
 
520
            _client=client)
 
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)
 
528
 
 
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(),
 
538
            _client=client)
 
539
        self.assertRaises(errors.UnknownFormatError,
 
540
            a_bzrdir.checkout_metadir)
 
541
        self.assertFinished(client)
 
542
 
 
543
 
 
544
class TestBzrDirGetBranches(TestRemote):
 
545
 
 
546
    def test_get_branches(self):
 
547
        transport = MemoryTransport()
 
548
        client = FakeClient(transport.base)
 
549
        reference_bzrdir_format = bzrdir.format_registry.get('default')()
 
550
        branch_name = reference_bzrdir_format.get_branch_format().network_name()
 
551
        client.add_success_response_with_body(
 
552
            bencode.bencode({
 
553
                "foo": ("branch", branch_name),
 
554
                "": ("branch", branch_name)}), "success")
 
555
        client.add_success_response(
 
556
            'ok', '', 'no', 'no', 'no',
 
557
                reference_bzrdir_format.repository_format.network_name())
 
558
        client.add_error_response('NotStacked')
 
559
        client.add_success_response(
 
560
            'ok', '', 'no', 'no', 'no',
 
561
                reference_bzrdir_format.repository_format.network_name())
 
562
        client.add_error_response('NotStacked')
 
563
        transport.mkdir('quack')
 
564
        transport = transport.clone('quack')
 
565
        a_bzrdir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
 
566
            _client=client)
 
567
        result = a_bzrdir.get_branches()
 
568
        self.assertEquals(set(["", "foo"]), set(result.keys()))
 
569
        self.assertEqual(
 
570
            [('call_expecting_body', 'BzrDir.get_branches', ('quack/',)),
 
571
             ('call', 'BzrDir.find_repositoryV3', ('quack/', )),
 
572
             ('call', 'Branch.get_stacked_on_url', ('quack/', )),
 
573
             ('call', 'BzrDir.find_repositoryV3', ('quack/', )),
 
574
             ('call', 'Branch.get_stacked_on_url', ('quack/', ))],
 
575
            client._calls)
 
576
 
 
577
 
 
578
class TestBzrDirDestroyBranch(TestRemote):
 
579
 
 
580
    def test_destroy_default(self):
 
581
        transport = self.get_transport('quack')
 
582
        referenced = self.make_branch('referenced')
 
583
        client = FakeClient(transport.base)
 
584
        client.add_expected_call(
 
585
            'BzrDir.destroy_branch', ('quack/', ),
 
586
            'success', ('ok',)),
 
587
        a_bzrdir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
 
588
            _client=client)
 
589
        a_bzrdir.destroy_branch()
 
590
        self.assertFinished(client)
 
591
 
 
592
 
 
593
class TestBzrDirHasWorkingTree(TestRemote):
 
594
 
 
595
    def test_has_workingtree(self):
 
596
        transport = self.get_transport('quack')
 
597
        client = FakeClient(transport.base)
 
598
        client.add_expected_call(
 
599
            'BzrDir.has_workingtree', ('quack/',),
 
600
            'success', ('yes',)),
 
601
        a_bzrdir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
 
602
            _client=client)
 
603
        self.assertTrue(a_bzrdir.has_workingtree())
 
604
        self.assertFinished(client)
 
605
 
 
606
    def test_no_workingtree(self):
 
607
        transport = self.get_transport('quack')
 
608
        client = FakeClient(transport.base)
 
609
        client.add_expected_call(
 
610
            'BzrDir.has_workingtree', ('quack/',),
 
611
            'success', ('no',)),
 
612
        a_bzrdir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
 
613
            _client=client)
 
614
        self.assertFalse(a_bzrdir.has_workingtree())
 
615
        self.assertFinished(client)
 
616
 
 
617
 
 
618
class TestBzrDirDestroyRepository(TestRemote):
 
619
 
 
620
    def test_destroy_repository(self):
 
621
        transport = self.get_transport('quack')
 
622
        client = FakeClient(transport.base)
 
623
        client.add_expected_call(
 
624
            'BzrDir.destroy_repository', ('quack/',),
 
625
            'success', ('ok',)),
 
626
        a_bzrdir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
 
627
            _client=client)
 
628
        a_bzrdir.destroy_repository()
 
629
        self.assertFinished(client)
 
630
 
484
631
 
485
632
class TestBzrDirOpen(TestRemote):
486
633
 
610
757
        # _get_tree_branch is a form of open_branch, but it should only ask for
611
758
        # branch opening, not any other network requests.
612
759
        calls = []
613
 
        def open_branch(name=None):
 
760
        def open_branch(name=None, possible_transports=None):
614
761
            calls.append("Called")
615
762
            return "a-branch"
616
763
        transport = MemoryTransport()
808
955
        # name.
809
956
        client.add_success_response_with_body(
810
957
            "Bazaar-NG meta directory, format 1\n", 'ok')
 
958
        client.add_success_response('stat', '0', '65535')
811
959
        client.add_success_response_with_body(
812
960
            reference_format.get_format_string(), 'ok')
813
961
        # PackRepository wants to do a stat
822
970
             ('call', 'BzrDir.find_repositoryV2', ('quack/',)),
823
971
             ('call', 'BzrDir.find_repository', ('quack/',)),
824
972
             ('call_expecting_body', 'get', ('/quack/.bzr/branch-format',)),
 
973
             ('call', 'stat', ('/quack/.bzr',)),
825
974
             ('call_expecting_body', 'get', ('/quack/.bzr/repository/format',)),
826
975
             ('call', 'stat', ('/quack/.bzr/repository',)),
827
976
             ],
841
990
        # name.
842
991
        client.add_success_response_with_body(
843
992
            "Bazaar-NG meta directory, format 1\n", 'ok')
 
993
        client.add_success_response('stat', '0', '65535')
844
994
        client.add_success_response_with_body(
845
995
            reference_format.get_format_string(), 'ok')
846
996
        # PackRepository wants to do a stat
854
1004
            [('call', 'BzrDir.find_repositoryV3', ('quack/',)),
855
1005
             ('call', 'BzrDir.find_repositoryV2', ('quack/',)),
856
1006
             ('call_expecting_body', 'get', ('/quack/.bzr/branch-format',)),
 
1007
             ('call', 'stat', ('/quack/.bzr',)),
857
1008
             ('call_expecting_body', 'get', ('/quack/.bzr/repository/format',)),
858
1009
             ('call', 'stat', ('/quack/.bzr/repository',)),
859
1010
             ],
996
1147
        return RemoteBranch(bzrdir, repo, _client=client, format=format)
997
1148
 
998
1149
 
 
1150
class TestBranchBreakLock(RemoteBranchTestCase):
 
1151
 
 
1152
    def test_break_lock(self):
 
1153
        transport_path = 'quack'
 
1154
        transport = MemoryTransport()
 
1155
        client = FakeClient(transport.base)
 
1156
        client.add_expected_call(
 
1157
            'Branch.get_stacked_on_url', ('quack/',),
 
1158
            'error', ('NotStacked',))
 
1159
        client.add_expected_call(
 
1160
            'Branch.break_lock', ('quack/',),
 
1161
            'success', ('ok',))
 
1162
        transport.mkdir('quack')
 
1163
        transport = transport.clone('quack')
 
1164
        branch = self.make_remote_branch(transport, client)
 
1165
        branch.break_lock()
 
1166
        self.assertFinished(client)
 
1167
 
 
1168
 
 
1169
class TestBranchGetPhysicalLockStatus(RemoteBranchTestCase):
 
1170
 
 
1171
    def test_get_physical_lock_status_yes(self):
 
1172
        transport = MemoryTransport()
 
1173
        client = FakeClient(transport.base)
 
1174
        client.add_expected_call(
 
1175
            'Branch.get_stacked_on_url', ('quack/',),
 
1176
            'error', ('NotStacked',))
 
1177
        client.add_expected_call(
 
1178
            'Branch.get_physical_lock_status', ('quack/',),
 
1179
            'success', ('yes',))
 
1180
        transport.mkdir('quack')
 
1181
        transport = transport.clone('quack')
 
1182
        branch = self.make_remote_branch(transport, client)
 
1183
        result = branch.get_physical_lock_status()
 
1184
        self.assertFinished(client)
 
1185
        self.assertEqual(True, result)
 
1186
 
 
1187
    def test_get_physical_lock_status_no(self):
 
1188
        transport = MemoryTransport()
 
1189
        client = FakeClient(transport.base)
 
1190
        client.add_expected_call(
 
1191
            'Branch.get_stacked_on_url', ('quack/',),
 
1192
            'error', ('NotStacked',))
 
1193
        client.add_expected_call(
 
1194
            'Branch.get_physical_lock_status', ('quack/',),
 
1195
            'success', ('no',))
 
1196
        transport.mkdir('quack')
 
1197
        transport = transport.clone('quack')
 
1198
        branch = self.make_remote_branch(transport, client)
 
1199
        result = branch.get_physical_lock_status()
 
1200
        self.assertFinished(client)
 
1201
        self.assertEqual(False, result)
 
1202
 
 
1203
 
999
1204
class TestBranchGetParent(RemoteBranchTestCase):
1000
1205
 
1001
1206
    def test_no_parent(self):
1091
1296
        verb = 'Branch.set_parent_location'
1092
1297
        self.disable_verb(verb)
1093
1298
        branch.set_parent('http://foo/')
1094
 
        self.assertLength(12, self.hpss_calls)
 
1299
        self.assertLength(13, self.hpss_calls)
1095
1300
 
1096
1301
 
1097
1302
class TestBranchGetTagsBytes(RemoteBranchTestCase):
1251
1456
 
1252
1457
    def test_backwards_compatible(self):
1253
1458
        branch = self.make_branch_with_tags()
1254
 
        c = branch.get_config()
1255
 
        c.set_user_option('branch.fetch_tags', 'True')
 
1459
        c = branch.get_config_stack()
 
1460
        c.set('branch.fetch_tags', True)
1256
1461
        self.addCleanup(branch.lock_read().unlock)
1257
1462
        # Disable the heads_to_fetch verb
1258
1463
        verb = 'Branch.heads_to_fetch'
1267
1472
 
1268
1473
    def test_backwards_compatible_no_tags(self):
1269
1474
        branch = self.make_branch_with_tags()
1270
 
        c = branch.get_config()
1271
 
        c.set_user_option('branch.fetch_tags', 'False')
 
1475
        c = branch.get_config_stack()
 
1476
        c.set('branch.fetch_tags', False)
1272
1477
        self.addCleanup(branch.lock_read().unlock)
1273
1478
        # Disable the heads_to_fetch verb
1274
1479
        verb = 'Branch.heads_to_fetch'
1445
1650
            'Branch.unlock', ('branch/', 'branch token', 'repo token'),
1446
1651
            'success', ('ok',))
1447
1652
        branch = self.make_remote_branch(transport, client)
1448
 
        # This is a hack to work around the problem that RemoteBranch currently
1449
 
        # unnecessarily invokes _ensure_real upon a call to lock_write.
1450
 
        branch._ensure_real = lambda: None
1451
1653
        branch.lock_write()
1452
1654
        result = branch._set_last_revision(NULL_REVISION)
1453
1655
        branch.unlock()
1482
1684
            'Branch.unlock', ('branch/', 'branch token', 'repo token'),
1483
1685
            'success', ('ok',))
1484
1686
        branch = self.make_remote_branch(transport, client)
1485
 
        # This is a hack to work around the problem that RemoteBranch currently
1486
 
        # unnecessarily invokes _ensure_real upon a call to lock_write.
1487
 
        branch._ensure_real = lambda: None
1488
1687
        # Lock the branch, reset the record of remote calls.
1489
1688
        branch.lock_write()
1490
1689
        result = branch._set_last_revision('rev-id2')
1557
1756
            'Branch.unlock', ('branch/', 'branch token', 'repo token'),
1558
1757
            'success', ('ok',))
1559
1758
        branch = self.make_remote_branch(transport, client)
1560
 
        branch._ensure_real = lambda: None
1561
1759
        branch.lock_write()
1562
1760
        # The 'TipChangeRejected' error response triggered by calling
1563
1761
        # set_last_revision_info causes a TipChangeRejected exception.
1826
2024
        self.addCleanup(branch.unlock)
1827
2025
        self.reset_smart_call_log()
1828
2026
        branch._get_config().set_option('value', 'name')
1829
 
        self.assertLength(10, self.hpss_calls)
 
2027
        self.assertLength(11, self.hpss_calls)
1830
2028
        self.assertEqual('value', branch._get_config().get_option('name'))
1831
2029
 
1832
2030
    def test_backwards_compat_set_option_with_dict(self):
1840
2038
        config = branch._get_config()
1841
2039
        value_dict = {'ascii': 'a', u'unicode \N{WATCH}': u'\N{INTERROBANG}'}
1842
2040
        config.set_option(value_dict, 'name')
1843
 
        self.assertLength(10, self.hpss_calls)
 
2041
        self.assertLength(11, self.hpss_calls)
1844
2042
        self.assertEqual(value_dict, branch._get_config().get_option('name'))
1845
2043
 
1846
2044
 
 
2045
class TestBranchGetPutConfigStore(RemoteBranchTestCase):
 
2046
 
 
2047
    def test_get_branch_conf(self):
 
2048
        # in an empty branch we decode the response properly
 
2049
        client = FakeClient()
 
2050
        client.add_expected_call(
 
2051
            'Branch.get_stacked_on_url', ('memory:///',),
 
2052
            'error', ('NotStacked',),)
 
2053
        client.add_success_response_with_body('# config file body', 'ok')
 
2054
        transport = MemoryTransport()
 
2055
        branch = self.make_remote_branch(transport, client)
 
2056
        config = branch.get_config_stack()
 
2057
        config.get("email")
 
2058
        config.get("log_format")
 
2059
        self.assertEqual(
 
2060
            [('call', 'Branch.get_stacked_on_url', ('memory:///',)),
 
2061
             ('call_expecting_body', 'Branch.get_config_file', ('memory:///',))],
 
2062
            client._calls)
 
2063
 
 
2064
    def test_set_branch_conf(self):
 
2065
        client = FakeClient()
 
2066
        client.add_expected_call(
 
2067
            'Branch.get_stacked_on_url', ('memory:///',),
 
2068
            'error', ('NotStacked',),)
 
2069
        client.add_expected_call(
 
2070
            'Branch.lock_write', ('memory:///', '', ''),
 
2071
            'success', ('ok', 'branch token', 'repo token'))
 
2072
        client.add_expected_call(
 
2073
            'Branch.get_config_file', ('memory:///', ),
 
2074
            'success', ('ok', ), "# line 1\n")
 
2075
        client.add_expected_call(
 
2076
            'Branch.put_config_file', ('memory:///', 'branch token',
 
2077
            'repo token'),
 
2078
            'success', ('ok',))
 
2079
        client.add_expected_call(
 
2080
            'Branch.unlock', ('memory:///', 'branch token', 'repo token'),
 
2081
            'success', ('ok',))
 
2082
        transport = MemoryTransport()
 
2083
        branch = self.make_remote_branch(transport, client)
 
2084
        branch.lock_write()
 
2085
        config = branch.get_config_stack()
 
2086
        config.set('email', 'The Dude <lebowski@example.com>')
 
2087
        branch.unlock()
 
2088
        self.assertFinished(client)
 
2089
        self.assertEqual(
 
2090
            [('call', 'Branch.get_stacked_on_url', ('memory:///',)),
 
2091
             ('call', 'Branch.lock_write', ('memory:///', '', '')),
 
2092
             ('call_expecting_body', 'Branch.get_config_file', ('memory:///',)),
 
2093
             ('call_with_body_bytes_expecting_body', 'Branch.put_config_file',
 
2094
                 ('memory:///', 'branch token', 'repo token'),
 
2095
                 '# line 1\nemail = The Dude <lebowski@example.com>\n'),
 
2096
             ('call', 'Branch.unlock', ('memory:///', 'branch token', 'repo token'))],
 
2097
            client._calls)
 
2098
 
 
2099
 
1847
2100
class TestBranchLockWrite(RemoteBranchTestCase):
1848
2101
 
1849
2102
    def test_lock_write_unlockable(self):
1862
2115
        self.assertFinished(client)
1863
2116
 
1864
2117
 
 
2118
class TestBranchRevisionIdToRevno(RemoteBranchTestCase):
 
2119
 
 
2120
    def test_simple(self):
 
2121
        transport = MemoryTransport()
 
2122
        client = FakeClient(transport.base)
 
2123
        client.add_expected_call(
 
2124
            'Branch.get_stacked_on_url', ('quack/',),
 
2125
            'error', ('NotStacked',),)
 
2126
        client.add_expected_call(
 
2127
            'Branch.revision_id_to_revno', ('quack/', 'null:'),
 
2128
            'success', ('ok', '0',),)
 
2129
        client.add_expected_call(
 
2130
            'Branch.revision_id_to_revno', ('quack/', 'unknown'),
 
2131
            'error', ('NoSuchRevision', 'unknown',),)
 
2132
        transport.mkdir('quack')
 
2133
        transport = transport.clone('quack')
 
2134
        branch = self.make_remote_branch(transport, client)
 
2135
        self.assertEquals(0, branch.revision_id_to_revno('null:'))
 
2136
        self.assertRaises(errors.NoSuchRevision,
 
2137
            branch.revision_id_to_revno, 'unknown')
 
2138
        self.assertFinished(client)
 
2139
 
 
2140
    def test_dotted(self):
 
2141
        transport = MemoryTransport()
 
2142
        client = FakeClient(transport.base)
 
2143
        client.add_expected_call(
 
2144
            'Branch.get_stacked_on_url', ('quack/',),
 
2145
            'error', ('NotStacked',),)
 
2146
        client.add_expected_call(
 
2147
            'Branch.revision_id_to_revno', ('quack/', 'null:'),
 
2148
            'success', ('ok', '0',),)
 
2149
        client.add_expected_call(
 
2150
            'Branch.revision_id_to_revno', ('quack/', 'unknown'),
 
2151
            'error', ('NoSuchRevision', 'unknown',),)
 
2152
        transport.mkdir('quack')
 
2153
        transport = transport.clone('quack')
 
2154
        branch = self.make_remote_branch(transport, client)
 
2155
        self.assertEquals((0, ), branch.revision_id_to_dotted_revno('null:'))
 
2156
        self.assertRaises(errors.NoSuchRevision,
 
2157
            branch.revision_id_to_dotted_revno, 'unknown')
 
2158
        self.assertFinished(client)
 
2159
 
 
2160
    def test_dotted_no_smart_verb(self):
 
2161
        self.setup_smart_server_with_call_log()
 
2162
        branch = self.make_branch('.')
 
2163
        self.disable_verb('Branch.revision_id_to_revno')
 
2164
        self.reset_smart_call_log()
 
2165
        self.assertEquals((0, ),
 
2166
            branch.revision_id_to_dotted_revno('null:'))
 
2167
        self.assertLength(8, self.hpss_calls)
 
2168
 
 
2169
 
1865
2170
class TestBzrDirGetSetConfig(RemoteBzrDirTestCase):
1866
2171
 
1867
2172
    def test__get_config(self):
1881
2186
        self.reset_smart_call_log()
1882
2187
        config = bzrdir.get_config()
1883
2188
        config.set_default_stack_on('/')
1884
 
        self.assertLength(3, self.hpss_calls)
 
2189
        self.assertLength(4, self.hpss_calls)
1885
2190
 
1886
2191
    def test_backwards_compat_get_option(self):
1887
2192
        self.setup_smart_server_with_call_log()
1891
2196
        self.reset_smart_call_log()
1892
2197
        self.assertEqual(None,
1893
2198
            bzrdir._get_config().get_option('default_stack_on'))
1894
 
        self.assertLength(3, self.hpss_calls)
 
2199
        self.assertLength(4, self.hpss_calls)
1895
2200
 
1896
2201
 
1897
2202
class TestTransportIsReadonly(tests.TestCase):
2024
2329
            remote_repo_format.get_format_description())
2025
2330
 
2026
2331
 
 
2332
class TestRepositoryAllRevisionIds(TestRemoteRepository):
 
2333
 
 
2334
    def test_empty(self):
 
2335
        transport_path = 'quack'
 
2336
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
2337
        client.add_success_response_with_body('', 'ok')
 
2338
        self.assertEquals([], repo.all_revision_ids())
 
2339
        self.assertEqual(
 
2340
            [('call_expecting_body', 'Repository.all_revision_ids',
 
2341
             ('quack/',))],
 
2342
            client._calls)
 
2343
 
 
2344
    def test_with_some_content(self):
 
2345
        transport_path = 'quack'
 
2346
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
2347
        client.add_success_response_with_body(
 
2348
            'rev1\nrev2\nanotherrev\n', 'ok')
 
2349
        self.assertEquals(["rev1", "rev2", "anotherrev"],
 
2350
            repo.all_revision_ids())
 
2351
        self.assertEqual(
 
2352
            [('call_expecting_body', 'Repository.all_revision_ids',
 
2353
             ('quack/',))],
 
2354
            client._calls)
 
2355
 
 
2356
 
2027
2357
class TestRepositoryGatherStats(TestRemoteRepository):
2028
2358
 
2029
2359
    def test_revid_none(self):
2082
2412
                         result)
2083
2413
 
2084
2414
 
 
2415
class TestRepositoryBreakLock(TestRemoteRepository):
 
2416
 
 
2417
    def test_break_lock(self):
 
2418
        transport_path = 'quack'
 
2419
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
2420
        client.add_success_response('ok')
 
2421
        repo.break_lock()
 
2422
        self.assertEqual(
 
2423
            [('call', 'Repository.break_lock', ('quack/',))],
 
2424
            client._calls)
 
2425
 
 
2426
 
 
2427
class TestRepositoryGetSerializerFormat(TestRemoteRepository):
 
2428
 
 
2429
    def test_get_serializer_format(self):
 
2430
        transport_path = 'hill'
 
2431
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
2432
        client.add_success_response('ok', '7')
 
2433
        self.assertEquals('7', repo.get_serializer_format())
 
2434
        self.assertEqual(
 
2435
            [('call', 'VersionedFileRepository.get_serializer_format',
 
2436
              ('hill/', ))],
 
2437
            client._calls)
 
2438
 
 
2439
 
 
2440
class TestRepositoryReconcile(TestRemoteRepository):
 
2441
 
 
2442
    def test_reconcile(self):
 
2443
        transport_path = 'hill'
 
2444
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
2445
        body = ("garbage_inventories: 2\n"
 
2446
                "inconsistent_parents: 3\n")
 
2447
        client.add_expected_call(
 
2448
            'Repository.lock_write', ('hill/', ''),
 
2449
            'success', ('ok', 'a token'))
 
2450
        client.add_success_response_with_body(body, 'ok')
 
2451
        reconciler = repo.reconcile()
 
2452
        self.assertEqual(
 
2453
            [('call', 'Repository.lock_write', ('hill/', '')),
 
2454
             ('call_expecting_body', 'Repository.reconcile',
 
2455
                ('hill/', 'a token'))],
 
2456
            client._calls)
 
2457
        self.assertEquals(2, reconciler.garbage_inventories)
 
2458
        self.assertEquals(3, reconciler.inconsistent_parents)
 
2459
 
 
2460
 
 
2461
class TestRepositoryGetRevisionSignatureText(TestRemoteRepository):
 
2462
 
 
2463
    def test_text(self):
 
2464
        # ('ok',), body with signature text
 
2465
        transport_path = 'quack'
 
2466
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
2467
        client.add_success_response_with_body(
 
2468
            'THETEXT', 'ok')
 
2469
        self.assertEquals("THETEXT", repo.get_signature_text("revid"))
 
2470
        self.assertEqual(
 
2471
            [('call_expecting_body', 'Repository.get_revision_signature_text',
 
2472
             ('quack/', 'revid'))],
 
2473
            client._calls)
 
2474
 
 
2475
    def test_no_signature(self):
 
2476
        transport_path = 'quick'
 
2477
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
2478
        client.add_error_response('nosuchrevision', 'unknown')
 
2479
        self.assertRaises(errors.NoSuchRevision, repo.get_signature_text,
 
2480
                "unknown")
 
2481
        self.assertEqual(
 
2482
            [('call_expecting_body', 'Repository.get_revision_signature_text',
 
2483
              ('quick/', 'unknown'))],
 
2484
            client._calls)
 
2485
 
 
2486
 
2085
2487
class TestRepositoryGetGraph(TestRemoteRepository):
2086
2488
 
2087
2489
    def test_get_graph(self):
2092
2494
        self.assertNotEqual(graph._parents_provider, repo)
2093
2495
 
2094
2496
 
 
2497
class TestRepositoryAddSignatureText(TestRemoteRepository):
 
2498
 
 
2499
    def test_add_signature_text(self):
 
2500
        transport_path = 'quack'
 
2501
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
2502
        client.add_expected_call(
 
2503
            'Repository.lock_write', ('quack/', ''),
 
2504
            'success', ('ok', 'a token'))
 
2505
        client.add_expected_call(
 
2506
            'Repository.start_write_group', ('quack/', 'a token'),
 
2507
            'success', ('ok', ('token1', )))
 
2508
        client.add_expected_call(
 
2509
            'Repository.add_signature_text', ('quack/', 'a token', 'rev1',
 
2510
                'token1'),
 
2511
            'success', ('ok', ), None)
 
2512
        repo.lock_write()
 
2513
        repo.start_write_group()
 
2514
        self.assertIs(None,
 
2515
            repo.add_signature_text("rev1", "every bloody emperor"))
 
2516
        self.assertEqual(
 
2517
            ('call_with_body_bytes_expecting_body',
 
2518
              'Repository.add_signature_text',
 
2519
                ('quack/', 'a token', 'rev1', 'token1'),
 
2520
              'every bloody emperor'),
 
2521
            client._calls[-1])
 
2522
 
 
2523
 
2095
2524
class TestRepositoryGetParentMap(TestRemoteRepository):
2096
2525
 
2097
2526
    def test_get_parent_map_caching(self):
2147
2576
        parents = repo.get_parent_map([rev_id])
2148
2577
        self.assertEqual(
2149
2578
            [('call_with_body_bytes_expecting_body',
2150
 
              'Repository.get_parent_map', ('quack/', 'include-missing:',
2151
 
              rev_id), '\n\n0'),
 
2579
              'Repository.get_parent_map',
 
2580
              ('quack/', 'include-missing:', rev_id), '\n\n0'),
2152
2581
             ('disconnect medium',),
2153
2582
             ('call_expecting_body', 'Repository.get_revision_graph',
2154
2583
              ('quack/', ''))],
2274
2703
        self.assertEqual({}, repo.get_parent_map(['non-existant']))
2275
2704
        self.assertLength(0, self.hpss_calls)
2276
2705
 
 
2706
    def test_exposes_get_cached_parent_map(self):
 
2707
        """RemoteRepository exposes get_cached_parent_map from
 
2708
        _unstacked_provider
 
2709
        """
 
2710
        r1 = u'\u0e33'.encode('utf8')
 
2711
        r2 = u'\u0dab'.encode('utf8')
 
2712
        lines = [' '.join([r2, r1]), r1]
 
2713
        encoded_body = bz2.compress('\n'.join(lines))
 
2714
 
 
2715
        transport_path = 'quack'
 
2716
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
2717
        client.add_success_response_with_body(encoded_body, 'ok')
 
2718
        repo.lock_read()
 
2719
        # get_cached_parent_map should *not* trigger an RPC
 
2720
        self.assertEqual({}, repo.get_cached_parent_map([r1]))
 
2721
        self.assertEqual([], client._calls)
 
2722
        self.assertEqual({r2: (r1,)}, repo.get_parent_map([r2]))
 
2723
        self.assertEqual({r1: (NULL_REVISION,)},
 
2724
            repo.get_cached_parent_map([r1]))
 
2725
        self.assertEqual(
 
2726
            [('call_with_body_bytes_expecting_body',
 
2727
              'Repository.get_parent_map', ('quack/', 'include-missing:', r2),
 
2728
              '\n\n0')],
 
2729
            client._calls)
 
2730
        repo.unlock()
 
2731
 
2277
2732
 
2278
2733
class TestGetParentMapAllowsNew(tests.TestCaseWithTransport):
2279
2734
 
2294
2749
        self.assertEqual({'rev1': ('null:',)}, graph.get_parent_map(['rev1']))
2295
2750
 
2296
2751
 
 
2752
class TestRepositoryGetRevisions(TestRemoteRepository):
 
2753
 
 
2754
    def test_hpss_missing_revision(self):
 
2755
        transport_path = 'quack'
 
2756
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
2757
        client.add_success_response_with_body(
 
2758
            '', 'ok', '10')
 
2759
        self.assertRaises(errors.NoSuchRevision, repo.get_revisions,
 
2760
            ['somerev1', 'anotherrev2'])
 
2761
        self.assertEqual(
 
2762
            [('call_with_body_bytes_expecting_body', 'Repository.iter_revisions',
 
2763
             ('quack/', ), "somerev1\nanotherrev2")],
 
2764
            client._calls)
 
2765
 
 
2766
    def test_hpss_get_single_revision(self):
 
2767
        transport_path = 'quack'
 
2768
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
2769
        somerev1 = Revision("somerev1")
 
2770
        somerev1.committer = "Joe Committer <joe@example.com>"
 
2771
        somerev1.timestamp = 1321828927
 
2772
        somerev1.timezone = -60
 
2773
        somerev1.inventory_sha1 = "691b39be74c67b1212a75fcb19c433aaed903c2b"
 
2774
        somerev1.message = "Message"
 
2775
        body = zlib.compress(chk_bencode_serializer.write_revision_to_string(
 
2776
            somerev1))
 
2777
        # Split up body into two bits to make sure the zlib compression object
 
2778
        # gets data fed twice.
 
2779
        client.add_success_response_with_body(
 
2780
                [body[:10], body[10:]], 'ok', '10')
 
2781
        revs = repo.get_revisions(['somerev1'])
 
2782
        self.assertEquals(revs, [somerev1])
 
2783
        self.assertEqual(
 
2784
            [('call_with_body_bytes_expecting_body', 'Repository.iter_revisions',
 
2785
             ('quack/', ), "somerev1")],
 
2786
            client._calls)
 
2787
 
 
2788
 
2297
2789
class TestRepositoryGetRevisionGraph(TestRemoteRepository):
2298
2790
 
2299
2791
    def test_null_revision(self):
2450
2942
                              call.call.method == verb])
2451
2943
 
2452
2944
 
 
2945
class TestRepositoryHasSignatureForRevisionId(TestRemoteRepository):
 
2946
 
 
2947
    def test_has_signature_for_revision_id(self):
 
2948
        # ('yes', ) for Repository.has_signature_for_revision_id -> 'True'.
 
2949
        transport_path = 'quack'
 
2950
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
2951
        client.add_success_response('yes')
 
2952
        result = repo.has_signature_for_revision_id('A')
 
2953
        self.assertEqual(
 
2954
            [('call', 'Repository.has_signature_for_revision_id',
 
2955
              ('quack/', 'A'))],
 
2956
            client._calls)
 
2957
        self.assertEqual(True, result)
 
2958
 
 
2959
    def test_is_not_shared(self):
 
2960
        # ('no', ) for Repository.has_signature_for_revision_id -> 'False'.
 
2961
        transport_path = 'qwack'
 
2962
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
2963
        client.add_success_response('no')
 
2964
        result = repo.has_signature_for_revision_id('A')
 
2965
        self.assertEqual(
 
2966
            [('call', 'Repository.has_signature_for_revision_id',
 
2967
              ('qwack/', 'A'))],
 
2968
            client._calls)
 
2969
        self.assertEqual(False, result)
 
2970
 
 
2971
 
 
2972
class TestRepositoryPhysicalLockStatus(TestRemoteRepository):
 
2973
 
 
2974
    def test_get_physical_lock_status_yes(self):
 
2975
        transport_path = 'qwack'
 
2976
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
2977
        client.add_success_response('yes')
 
2978
        result = repo.get_physical_lock_status()
 
2979
        self.assertEqual(
 
2980
            [('call', 'Repository.get_physical_lock_status',
 
2981
              ('qwack/', ))],
 
2982
            client._calls)
 
2983
        self.assertEqual(True, result)
 
2984
 
 
2985
    def test_get_physical_lock_status_no(self):
 
2986
        transport_path = 'qwack'
 
2987
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
2988
        client.add_success_response('no')
 
2989
        result = repo.get_physical_lock_status()
 
2990
        self.assertEqual(
 
2991
            [('call', 'Repository.get_physical_lock_status',
 
2992
              ('qwack/', ))],
 
2993
            client._calls)
 
2994
        self.assertEqual(False, result)
 
2995
 
 
2996
 
2453
2997
class TestRepositoryIsShared(TestRemoteRepository):
2454
2998
 
2455
2999
    def test_is_shared(self):
2475
3019
        self.assertEqual(False, result)
2476
3020
 
2477
3021
 
 
3022
class TestRepositoryMakeWorkingTrees(TestRemoteRepository):
 
3023
 
 
3024
    def test_make_working_trees(self):
 
3025
        # ('yes', ) for Repository.make_working_trees -> 'True'.
 
3026
        transport_path = 'quack'
 
3027
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
3028
        client.add_success_response('yes')
 
3029
        result = repo.make_working_trees()
 
3030
        self.assertEqual(
 
3031
            [('call', 'Repository.make_working_trees', ('quack/',))],
 
3032
            client._calls)
 
3033
        self.assertEqual(True, result)
 
3034
 
 
3035
    def test_no_working_trees(self):
 
3036
        # ('no', ) for Repository.make_working_trees -> 'False'.
 
3037
        transport_path = 'qwack'
 
3038
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
3039
        client.add_success_response('no')
 
3040
        result = repo.make_working_trees()
 
3041
        self.assertEqual(
 
3042
            [('call', 'Repository.make_working_trees', ('qwack/',))],
 
3043
            client._calls)
 
3044
        self.assertEqual(False, result)
 
3045
 
 
3046
 
2478
3047
class TestRepositoryLockWrite(TestRemoteRepository):
2479
3048
 
2480
3049
    def test_lock_write(self):
2506
3075
            client._calls)
2507
3076
 
2508
3077
 
 
3078
class TestRepositoryWriteGroups(TestRemoteRepository):
 
3079
 
 
3080
    def test_start_write_group(self):
 
3081
        transport_path = 'quack'
 
3082
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
3083
        client.add_expected_call(
 
3084
            'Repository.lock_write', ('quack/', ''),
 
3085
            'success', ('ok', 'a token'))
 
3086
        client.add_expected_call(
 
3087
            'Repository.start_write_group', ('quack/', 'a token'),
 
3088
            'success', ('ok', ('token1', )))
 
3089
        repo.lock_write()
 
3090
        repo.start_write_group()
 
3091
 
 
3092
    def test_start_write_group_unsuspendable(self):
 
3093
        # Some repositories do not support suspending write
 
3094
        # groups. For those, fall back to the "real" repository.
 
3095
        transport_path = 'quack'
 
3096
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
3097
        def stub_ensure_real():
 
3098
            client._calls.append(('_ensure_real',))
 
3099
            repo._real_repository = _StubRealPackRepository(client._calls)
 
3100
        repo._ensure_real = stub_ensure_real
 
3101
        client.add_expected_call(
 
3102
            'Repository.lock_write', ('quack/', ''),
 
3103
            'success', ('ok', 'a token'))
 
3104
        client.add_expected_call(
 
3105
            'Repository.start_write_group', ('quack/', 'a token'),
 
3106
            'error', ('UnsuspendableWriteGroup',))
 
3107
        repo.lock_write()
 
3108
        repo.start_write_group()
 
3109
        self.assertEquals(client._calls[-2:], [ 
 
3110
            ('_ensure_real',),
 
3111
            ('start_write_group',)])
 
3112
 
 
3113
    def test_commit_write_group(self):
 
3114
        transport_path = 'quack'
 
3115
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
3116
        client.add_expected_call(
 
3117
            'Repository.lock_write', ('quack/', ''),
 
3118
            'success', ('ok', 'a token'))
 
3119
        client.add_expected_call(
 
3120
            'Repository.start_write_group', ('quack/', 'a token'),
 
3121
            'success', ('ok', ['token1']))
 
3122
        client.add_expected_call(
 
3123
            'Repository.commit_write_group', ('quack/', 'a token', ['token1']),
 
3124
            'success', ('ok',))
 
3125
        repo.lock_write()
 
3126
        repo.start_write_group()
 
3127
        repo.commit_write_group()
 
3128
 
 
3129
    def test_abort_write_group(self):
 
3130
        transport_path = 'quack'
 
3131
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
3132
        client.add_expected_call(
 
3133
            'Repository.lock_write', ('quack/', ''),
 
3134
            'success', ('ok', 'a token'))
 
3135
        client.add_expected_call(
 
3136
            'Repository.start_write_group', ('quack/', 'a token'),
 
3137
            'success', ('ok', ['token1']))
 
3138
        client.add_expected_call(
 
3139
            'Repository.abort_write_group', ('quack/', 'a token', ['token1']),
 
3140
            'success', ('ok',))
 
3141
        repo.lock_write()
 
3142
        repo.start_write_group()
 
3143
        repo.abort_write_group(False)
 
3144
 
 
3145
    def test_suspend_write_group(self):
 
3146
        transport_path = 'quack'
 
3147
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
3148
        self.assertEquals([], repo.suspend_write_group())
 
3149
 
 
3150
    def test_resume_write_group(self):
 
3151
        transport_path = 'quack'
 
3152
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
3153
        client.add_expected_call(
 
3154
            'Repository.lock_write', ('quack/', ''),
 
3155
            'success', ('ok', 'a token'))
 
3156
        client.add_expected_call(
 
3157
            'Repository.check_write_group', ('quack/', 'a token', ['token1']),
 
3158
            'success', ('ok',))
 
3159
        repo.lock_write()
 
3160
        repo.resume_write_group(['token1'])
 
3161
 
 
3162
 
2509
3163
class TestRepositorySetMakeWorkingTrees(TestRemoteRepository):
2510
3164
 
2511
3165
    def test_backwards_compat(self):
2570
3224
        self.assertEqual([], client._calls)
2571
3225
 
2572
3226
 
 
3227
class TestRepositoryIterFilesBytes(TestRemoteRepository):
 
3228
    """Test Repository.iter_file_bytes."""
 
3229
 
 
3230
    def test_single(self):
 
3231
        transport_path = 'quack'
 
3232
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
3233
        client.add_expected_call(
 
3234
            'Repository.iter_files_bytes', ('quack/', ),
 
3235
            'success', ('ok',), iter(["ok\x000", "\n", zlib.compress("mydata" * 10)]))
 
3236
        for (identifier, byte_stream) in repo.iter_files_bytes([("somefile",
 
3237
                "somerev", "myid")]):
 
3238
            self.assertEquals("myid", identifier)
 
3239
            self.assertEquals("".join(byte_stream), "mydata" * 10)
 
3240
 
 
3241
    def test_missing(self):
 
3242
        transport_path = 'quack'
 
3243
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
3244
        client.add_expected_call(
 
3245
            'Repository.iter_files_bytes',
 
3246
                ('quack/', ),
 
3247
            'error', ('RevisionNotPresent', 'somefile', 'somerev'),
 
3248
            iter(["absent\0somefile\0somerev\n"]))
 
3249
        self.assertRaises(errors.RevisionNotPresent, list,
 
3250
                repo.iter_files_bytes(
 
3251
                [("somefile", "somerev", "myid")]))
 
3252
 
 
3253
 
2573
3254
class TestRepositoryInsertStreamBase(TestRemoteRepository):
2574
3255
    """Base class for Repository.insert_stream and .insert_stream_1.19
2575
3256
    tests.
2850
3531
        self.calls = calls
2851
3532
        self._pack_collection = _StubPackCollection(calls)
2852
3533
 
 
3534
    def start_write_group(self):
 
3535
        self.calls.append(('start_write_group',))
 
3536
 
2853
3537
    def is_in_write_group(self):
2854
3538
        return False
2855
3539
 
3293
3977
        revs = [r for (r,ps) in graph.iter_ancestry([tip])
3294
3978
                if r != NULL_REVISION]
3295
3979
        revs.reverse()
3296
 
        search = _mod_graph.PendingAncestryResult([tip], stacked.repository)
 
3980
        search = vf_search.PendingAncestryResult([tip], stacked.repository)
3297
3981
        self.reset_smart_call_log()
3298
3982
        stream = source.get_stream(search)
3299
3983
        # We trust that if a revision is in the stream the rest of the new
3405
4089
        self.hpss_calls = []
3406
4090
        local.repository.fetch(
3407
4091
            remote_branch.repository,
3408
 
            fetch_spec=_mod_graph.EverythingResult(remote_branch.repository))
 
4092
            fetch_spec=vf_search.EverythingResult(remote_branch.repository))
3409
4093
        self.assertEqual(['Repository.get_stream_1.19'], self.hpss_calls)
3410
4094
 
3411
4095
    def override_verb(self, verb_name, verb):
3412
4096
        request_handlers = request.request_handlers
3413
4097
        orig_verb = request_handlers.get(verb_name)
 
4098
        orig_info = request_handlers.get_info(verb_name)
3414
4099
        request_handlers.register(verb_name, verb, override_existing=True)
3415
4100
        self.addCleanup(request_handlers.register, verb_name, orig_verb,
3416
 
                override_existing=True)
 
4101
                override_existing=True, info=orig_info)
3417
4102
 
3418
4103
    def test_fetch_everything_backwards_compat(self):
3419
4104
        """Can fetch with EverythingResult even with pre 2.4 servers.
3444
4129
        self.hpss_calls = []
3445
4130
        local.repository.fetch(
3446
4131
            remote_branch.repository,
3447
 
            fetch_spec=_mod_graph.EverythingResult(remote_branch.repository))
 
4132
            fetch_spec=vf_search.EverythingResult(remote_branch.repository))
3448
4133
        # make sure the overridden verb was used
3449
4134
        self.assertLength(1, verb_log)
3450
4135
        # more than one HPSS call is needed, but because it's a VFS callback
3495
4180
        # interpretation
3496
4181
        self.make_master_and_checkout('mas~ter', 'checkout')
3497
4182
        self.assertUpdateSucceeds(self.bound_location.replace('%2E', '~', 1))
 
4183
 
 
4184
 
 
4185
class TestWithCustomErrorHandler(RemoteBranchTestCase):
 
4186
 
 
4187
    def test_no_context(self):
 
4188
        class OutOfCoffee(errors.BzrError):
 
4189
            """A dummy exception for testing."""
 
4190
 
 
4191
            def __init__(self, urgency):
 
4192
                self.urgency = urgency
 
4193
        remote.no_context_error_translators.register("OutOfCoffee",
 
4194
            lambda err: OutOfCoffee(err.error_args[0]))
 
4195
        transport = MemoryTransport()
 
4196
        client = FakeClient(transport.base)
 
4197
        client.add_expected_call(
 
4198
            'Branch.get_stacked_on_url', ('quack/',),
 
4199
            'error', ('NotStacked',))
 
4200
        client.add_expected_call(
 
4201
            'Branch.last_revision_info',
 
4202
            ('quack/',),
 
4203
            'error', ('OutOfCoffee', 'low'))
 
4204
        transport.mkdir('quack')
 
4205
        transport = transport.clone('quack')
 
4206
        branch = self.make_remote_branch(transport, client)
 
4207
        self.assertRaises(OutOfCoffee, branch.last_revision_info)
 
4208
        self.assertFinished(client)
 
4209
 
 
4210
    def test_with_context(self):
 
4211
        class OutOfTea(errors.BzrError):
 
4212
            def __init__(self, branch, urgency):
 
4213
                self.branch = branch
 
4214
                self.urgency = urgency
 
4215
        remote.error_translators.register("OutOfTea",
 
4216
            lambda err, find, path: OutOfTea(err.error_args[0],
 
4217
                find("branch")))
 
4218
        transport = MemoryTransport()
 
4219
        client = FakeClient(transport.base)
 
4220
        client.add_expected_call(
 
4221
            'Branch.get_stacked_on_url', ('quack/',),
 
4222
            'error', ('NotStacked',))
 
4223
        client.add_expected_call(
 
4224
            'Branch.last_revision_info',
 
4225
            ('quack/',),
 
4226
            'error', ('OutOfTea', 'low'))
 
4227
        transport.mkdir('quack')
 
4228
        transport = transport.clone('quack')
 
4229
        branch = self.make_remote_branch(transport, client)
 
4230
        self.assertRaises(OutOfTea, branch.last_revision_info)
 
4231
        self.assertFinished(client)
 
4232
 
 
4233
 
 
4234
class TestRepositoryPack(TestRemoteRepository):
 
4235
 
 
4236
    def test_pack(self):
 
4237
        transport_path = 'quack'
 
4238
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
4239
        client.add_expected_call(
 
4240
            'Repository.lock_write', ('quack/', ''),
 
4241
            'success', ('ok', 'token'))
 
4242
        client.add_expected_call(
 
4243
            'Repository.pack', ('quack/', 'token', 'False'),
 
4244
            'success', ('ok',), )
 
4245
        client.add_expected_call(
 
4246
            'Repository.unlock', ('quack/', 'token'),
 
4247
            'success', ('ok', ))
 
4248
        repo.pack()
 
4249
 
 
4250
    def test_pack_with_hint(self):
 
4251
        transport_path = 'quack'
 
4252
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
4253
        client.add_expected_call(
 
4254
            'Repository.lock_write', ('quack/', ''),
 
4255
            'success', ('ok', 'token'))
 
4256
        client.add_expected_call(
 
4257
            'Repository.pack', ('quack/', 'token', 'False'),
 
4258
            'success', ('ok',), )
 
4259
        client.add_expected_call(
 
4260
            'Repository.unlock', ('quack/', 'token', 'False'),
 
4261
            'success', ('ok', ))
 
4262
        repo.pack(['hinta', 'hintb'])
 
4263
 
 
4264
 
 
4265
class TestRepositoryIterInventories(TestRemoteRepository):
 
4266
    """Test Repository.iter_inventories."""
 
4267
 
 
4268
    def _serialize_inv_delta(self, old_name, new_name, delta):
 
4269
        serializer = inventory_delta.InventoryDeltaSerializer(True, False)
 
4270
        return "".join(serializer.delta_to_lines(old_name, new_name, delta))
 
4271
 
 
4272
    def test_single_empty(self):
 
4273
        transport_path = 'quack'
 
4274
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
4275
        fmt = bzrdir.format_registry.get('2a')().repository_format
 
4276
        repo._format = fmt
 
4277
        stream = [('inventory-deltas', [
 
4278
            versionedfile.FulltextContentFactory('somerevid', None, None,
 
4279
                self._serialize_inv_delta('null:', 'somerevid', []))])]
 
4280
        client.add_expected_call(
 
4281
            'VersionedFileRepository.get_inventories', ('quack/', 'unordered'),
 
4282
            'success', ('ok', ),
 
4283
            _stream_to_byte_stream(stream, fmt))
 
4284
        ret = list(repo.iter_inventories(["somerevid"]))
 
4285
        self.assertLength(1, ret)
 
4286
        inv = ret[0]
 
4287
        self.assertEquals("somerevid", inv.revision_id)
 
4288
 
 
4289
    def test_empty(self):
 
4290
        transport_path = 'quack'
 
4291
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
4292
        ret = list(repo.iter_inventories([]))
 
4293
        self.assertEquals(ret, [])
 
4294
 
 
4295
    def test_missing(self):
 
4296
        transport_path = 'quack'
 
4297
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
4298
        client.add_expected_call(
 
4299
            'VersionedFileRepository.get_inventories', ('quack/', 'unordered'),
 
4300
            'success', ('ok', ), iter([]))
 
4301
        self.assertRaises(errors.NoSuchRevision, list, repo.iter_inventories(
 
4302
            ["somerevid"]))