~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_remote.py

  • Committer: Martin Packman
  • Date: 2012-01-05 09:50:04 UTC
  • mfrom: (6424 +trunk)
  • mto: This revision was merged to the branch mainline in revision 6426.
  • Revision ID: martin.packman@canonical.com-20120105095004-mia9xb7y0efmto0v
Merge bzr.dev to resolve conflicts in bzrlib.builtins

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 (
30
31
    branch,
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 TestBzrDirDestroyBranch(TestRemote):
 
545
 
 
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/', ),
 
552
            'success', ('ok',)),
 
553
        a_bzrdir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
 
554
            _client=client)
 
555
        a_bzrdir.destroy_branch()
 
556
        self.assertFinished(client)
 
557
 
 
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"),
 
564
            'success', ('ok',)),
 
565
        a_bzrdir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
 
566
            _client=client)
 
567
        a_bzrdir.destroy_branch("foo")
 
568
        self.assertFinished(client)
 
569
 
 
570
 
 
571
class TestBzrDirHasWorkingTree(TestRemote):
 
572
 
 
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(),
 
580
            _client=client)
 
581
        self.assertTrue(a_bzrdir.has_workingtree())
 
582
        self.assertFinished(client)
 
583
 
 
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/',),
 
589
            'success', ('no',)),
 
590
        a_bzrdir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
 
591
            _client=client)
 
592
        self.assertFalse(a_bzrdir.has_workingtree())
 
593
        self.assertFinished(client)
 
594
 
 
595
 
 
596
class TestBzrDirDestroyRepository(TestRemote):
 
597
 
 
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/',),
 
603
            'success', ('ok',)),
 
604
        a_bzrdir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
 
605
            _client=client)
 
606
        a_bzrdir.destroy_repository()
 
607
        self.assertFinished(client)
 
608
 
484
609
 
485
610
class TestBzrDirOpen(TestRemote):
486
611
 
610
735
        # _get_tree_branch is a form of open_branch, but it should only ask for
611
736
        # branch opening, not any other network requests.
612
737
        calls = []
613
 
        def open_branch(name=None):
 
738
        def open_branch(name=None, possible_transports=None):
614
739
            calls.append("Called")
615
740
            return "a-branch"
616
741
        transport = MemoryTransport()
808
933
        # name.
809
934
        client.add_success_response_with_body(
810
935
            "Bazaar-NG meta directory, format 1\n", 'ok')
 
936
        client.add_success_response('stat', '0', '65535')
811
937
        client.add_success_response_with_body(
812
938
            reference_format.get_format_string(), 'ok')
813
939
        # PackRepository wants to do a stat
822
948
             ('call', 'BzrDir.find_repositoryV2', ('quack/',)),
823
949
             ('call', 'BzrDir.find_repository', ('quack/',)),
824
950
             ('call_expecting_body', 'get', ('/quack/.bzr/branch-format',)),
 
951
             ('call', 'stat', ('/quack/.bzr',)),
825
952
             ('call_expecting_body', 'get', ('/quack/.bzr/repository/format',)),
826
953
             ('call', 'stat', ('/quack/.bzr/repository',)),
827
954
             ],
841
968
        # name.
842
969
        client.add_success_response_with_body(
843
970
            "Bazaar-NG meta directory, format 1\n", 'ok')
 
971
        client.add_success_response('stat', '0', '65535')
844
972
        client.add_success_response_with_body(
845
973
            reference_format.get_format_string(), 'ok')
846
974
        # PackRepository wants to do a stat
854
982
            [('call', 'BzrDir.find_repositoryV3', ('quack/',)),
855
983
             ('call', 'BzrDir.find_repositoryV2', ('quack/',)),
856
984
             ('call_expecting_body', 'get', ('/quack/.bzr/branch-format',)),
 
985
             ('call', 'stat', ('/quack/.bzr',)),
857
986
             ('call_expecting_body', 'get', ('/quack/.bzr/repository/format',)),
858
987
             ('call', 'stat', ('/quack/.bzr/repository',)),
859
988
             ],
996
1125
        return RemoteBranch(bzrdir, repo, _client=client, format=format)
997
1126
 
998
1127
 
 
1128
class TestBranchBreakLock(RemoteBranchTestCase):
 
1129
 
 
1130
    def test_break_lock(self):
 
1131
        transport_path = 'quack'
 
1132
        transport = MemoryTransport()
 
1133
        client = FakeClient(transport.base)
 
1134
        client.add_expected_call(
 
1135
            'Branch.get_stacked_on_url', ('quack/',),
 
1136
            'error', ('NotStacked',))
 
1137
        client.add_expected_call(
 
1138
            'Branch.break_lock', ('quack/',),
 
1139
            'success', ('ok',))
 
1140
        transport.mkdir('quack')
 
1141
        transport = transport.clone('quack')
 
1142
        branch = self.make_remote_branch(transport, client)
 
1143
        branch.break_lock()
 
1144
        self.assertFinished(client)
 
1145
 
 
1146
 
 
1147
class TestBranchGetPhysicalLockStatus(RemoteBranchTestCase):
 
1148
 
 
1149
    def test_get_physical_lock_status_yes(self):
 
1150
        transport = MemoryTransport()
 
1151
        client = FakeClient(transport.base)
 
1152
        client.add_expected_call(
 
1153
            'Branch.get_stacked_on_url', ('quack/',),
 
1154
            'error', ('NotStacked',))
 
1155
        client.add_expected_call(
 
1156
            'Branch.get_physical_lock_status', ('quack/',),
 
1157
            'success', ('yes',))
 
1158
        transport.mkdir('quack')
 
1159
        transport = transport.clone('quack')
 
1160
        branch = self.make_remote_branch(transport, client)
 
1161
        result = branch.get_physical_lock_status()
 
1162
        self.assertFinished(client)
 
1163
        self.assertEqual(True, result)
 
1164
 
 
1165
    def test_get_physical_lock_status_no(self):
 
1166
        transport = MemoryTransport()
 
1167
        client = FakeClient(transport.base)
 
1168
        client.add_expected_call(
 
1169
            'Branch.get_stacked_on_url', ('quack/',),
 
1170
            'error', ('NotStacked',))
 
1171
        client.add_expected_call(
 
1172
            'Branch.get_physical_lock_status', ('quack/',),
 
1173
            'success', ('no',))
 
1174
        transport.mkdir('quack')
 
1175
        transport = transport.clone('quack')
 
1176
        branch = self.make_remote_branch(transport, client)
 
1177
        result = branch.get_physical_lock_status()
 
1178
        self.assertFinished(client)
 
1179
        self.assertEqual(False, result)
 
1180
 
 
1181
 
999
1182
class TestBranchGetParent(RemoteBranchTestCase):
1000
1183
 
1001
1184
    def test_no_parent(self):
1091
1274
        verb = 'Branch.set_parent_location'
1092
1275
        self.disable_verb(verb)
1093
1276
        branch.set_parent('http://foo/')
1094
 
        self.assertLength(12, self.hpss_calls)
 
1277
        self.assertLength(13, self.hpss_calls)
1095
1278
 
1096
1279
 
1097
1280
class TestBranchGetTagsBytes(RemoteBranchTestCase):
1251
1434
 
1252
1435
    def test_backwards_compatible(self):
1253
1436
        branch = self.make_branch_with_tags()
1254
 
        c = branch.get_config()
1255
 
        c.set_user_option('branch.fetch_tags', 'True')
 
1437
        c = branch.get_config_stack()
 
1438
        c.set('branch.fetch_tags', True)
1256
1439
        self.addCleanup(branch.lock_read().unlock)
1257
1440
        # Disable the heads_to_fetch verb
1258
1441
        verb = 'Branch.heads_to_fetch'
1267
1450
 
1268
1451
    def test_backwards_compatible_no_tags(self):
1269
1452
        branch = self.make_branch_with_tags()
1270
 
        c = branch.get_config()
1271
 
        c.set_user_option('branch.fetch_tags', 'False')
 
1453
        c = branch.get_config_stack()
 
1454
        c.set('branch.fetch_tags', False)
1272
1455
        self.addCleanup(branch.lock_read().unlock)
1273
1456
        # Disable the heads_to_fetch verb
1274
1457
        verb = 'Branch.heads_to_fetch'
1445
1628
            'Branch.unlock', ('branch/', 'branch token', 'repo token'),
1446
1629
            'success', ('ok',))
1447
1630
        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
1631
        branch.lock_write()
1452
1632
        result = branch._set_last_revision(NULL_REVISION)
1453
1633
        branch.unlock()
1482
1662
            'Branch.unlock', ('branch/', 'branch token', 'repo token'),
1483
1663
            'success', ('ok',))
1484
1664
        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
1665
        # Lock the branch, reset the record of remote calls.
1489
1666
        branch.lock_write()
1490
1667
        result = branch._set_last_revision('rev-id2')
1557
1734
            'Branch.unlock', ('branch/', 'branch token', 'repo token'),
1558
1735
            'success', ('ok',))
1559
1736
        branch = self.make_remote_branch(transport, client)
1560
 
        branch._ensure_real = lambda: None
1561
1737
        branch.lock_write()
1562
1738
        # The 'TipChangeRejected' error response triggered by calling
1563
1739
        # set_last_revision_info causes a TipChangeRejected exception.
1826
2002
        self.addCleanup(branch.unlock)
1827
2003
        self.reset_smart_call_log()
1828
2004
        branch._get_config().set_option('value', 'name')
1829
 
        self.assertLength(10, self.hpss_calls)
 
2005
        self.assertLength(11, self.hpss_calls)
1830
2006
        self.assertEqual('value', branch._get_config().get_option('name'))
1831
2007
 
1832
2008
    def test_backwards_compat_set_option_with_dict(self):
1840
2016
        config = branch._get_config()
1841
2017
        value_dict = {'ascii': 'a', u'unicode \N{WATCH}': u'\N{INTERROBANG}'}
1842
2018
        config.set_option(value_dict, 'name')
1843
 
        self.assertLength(10, self.hpss_calls)
 
2019
        self.assertLength(11, self.hpss_calls)
1844
2020
        self.assertEqual(value_dict, branch._get_config().get_option('name'))
1845
2021
 
1846
2022
 
 
2023
class TestBranchGetPutConfigStore(RemoteBranchTestCase):
 
2024
 
 
2025
    def test_get_branch_conf(self):
 
2026
        # in an empty branch we decode the response properly
 
2027
        client = FakeClient()
 
2028
        client.add_expected_call(
 
2029
            'Branch.get_stacked_on_url', ('memory:///',),
 
2030
            'error', ('NotStacked',),)
 
2031
        client.add_success_response_with_body('# config file body', 'ok')
 
2032
        transport = MemoryTransport()
 
2033
        branch = self.make_remote_branch(transport, client)
 
2034
        config = branch.get_config_stack()
 
2035
        config.get("email")
 
2036
        config.get("log_format")
 
2037
        self.assertEqual(
 
2038
            [('call', 'Branch.get_stacked_on_url', ('memory:///',)),
 
2039
             ('call_expecting_body', 'Branch.get_config_file', ('memory:///',))],
 
2040
            client._calls)
 
2041
 
 
2042
    def test_set_branch_conf(self):
 
2043
        client = FakeClient()
 
2044
        client.add_expected_call(
 
2045
            'Branch.get_stacked_on_url', ('memory:///',),
 
2046
            'error', ('NotStacked',),)
 
2047
        client.add_expected_call(
 
2048
            'Branch.lock_write', ('memory:///', '', ''),
 
2049
            'success', ('ok', 'branch token', 'repo token'))
 
2050
        client.add_expected_call(
 
2051
            'Branch.get_config_file', ('memory:///', ),
 
2052
            'success', ('ok', ), "# line 1\n")
 
2053
        client.add_expected_call(
 
2054
            'Branch.put_config_file', ('memory:///', 'branch token',
 
2055
            'repo token'),
 
2056
            'success', ('ok',))
 
2057
        client.add_expected_call(
 
2058
            'Branch.unlock', ('memory:///', 'branch token', 'repo token'),
 
2059
            'success', ('ok',))
 
2060
        transport = MemoryTransport()
 
2061
        branch = self.make_remote_branch(transport, client)
 
2062
        branch.lock_write()
 
2063
        config = branch.get_config_stack()
 
2064
        config.set('email', 'The Dude <lebowski@example.com>')
 
2065
        branch.unlock()
 
2066
        self.assertFinished(client)
 
2067
        self.assertEqual(
 
2068
            [('call', 'Branch.get_stacked_on_url', ('memory:///',)),
 
2069
             ('call', 'Branch.lock_write', ('memory:///', '', '')),
 
2070
             ('call_expecting_body', 'Branch.get_config_file', ('memory:///',)),
 
2071
             ('call_with_body_bytes_expecting_body', 'Branch.put_config_file',
 
2072
                 ('memory:///', 'branch token', 'repo token'),
 
2073
                 '# line 1\nemail = The Dude <lebowski@example.com>\n'),
 
2074
             ('call', 'Branch.unlock', ('memory:///', 'branch token', 'repo token'))],
 
2075
            client._calls)
 
2076
 
 
2077
 
1847
2078
class TestBranchLockWrite(RemoteBranchTestCase):
1848
2079
 
1849
2080
    def test_lock_write_unlockable(self):
1862
2093
        self.assertFinished(client)
1863
2094
 
1864
2095
 
 
2096
class TestBranchRevisionIdToRevno(RemoteBranchTestCase):
 
2097
 
 
2098
    def test_simple(self):
 
2099
        transport = MemoryTransport()
 
2100
        client = FakeClient(transport.base)
 
2101
        client.add_expected_call(
 
2102
            'Branch.get_stacked_on_url', ('quack/',),
 
2103
            'error', ('NotStacked',),)
 
2104
        client.add_expected_call(
 
2105
            'Branch.revision_id_to_revno', ('quack/', 'null:'),
 
2106
            'success', ('ok', '0',),)
 
2107
        client.add_expected_call(
 
2108
            'Branch.revision_id_to_revno', ('quack/', 'unknown'),
 
2109
            'error', ('NoSuchRevision', 'unknown',),)
 
2110
        transport.mkdir('quack')
 
2111
        transport = transport.clone('quack')
 
2112
        branch = self.make_remote_branch(transport, client)
 
2113
        self.assertEquals(0, branch.revision_id_to_revno('null:'))
 
2114
        self.assertRaises(errors.NoSuchRevision,
 
2115
            branch.revision_id_to_revno, 'unknown')
 
2116
        self.assertFinished(client)
 
2117
 
 
2118
    def test_dotted(self):
 
2119
        transport = MemoryTransport()
 
2120
        client = FakeClient(transport.base)
 
2121
        client.add_expected_call(
 
2122
            'Branch.get_stacked_on_url', ('quack/',),
 
2123
            'error', ('NotStacked',),)
 
2124
        client.add_expected_call(
 
2125
            'Branch.revision_id_to_revno', ('quack/', 'null:'),
 
2126
            'success', ('ok', '0',),)
 
2127
        client.add_expected_call(
 
2128
            'Branch.revision_id_to_revno', ('quack/', 'unknown'),
 
2129
            'error', ('NoSuchRevision', 'unknown',),)
 
2130
        transport.mkdir('quack')
 
2131
        transport = transport.clone('quack')
 
2132
        branch = self.make_remote_branch(transport, client)
 
2133
        self.assertEquals((0, ), branch.revision_id_to_dotted_revno('null:'))
 
2134
        self.assertRaises(errors.NoSuchRevision,
 
2135
            branch.revision_id_to_dotted_revno, 'unknown')
 
2136
        self.assertFinished(client)
 
2137
 
 
2138
    def test_dotted_no_smart_verb(self):
 
2139
        self.setup_smart_server_with_call_log()
 
2140
        branch = self.make_branch('.')
 
2141
        self.disable_verb('Branch.revision_id_to_revno')
 
2142
        self.reset_smart_call_log()
 
2143
        self.assertEquals((0, ),
 
2144
            branch.revision_id_to_dotted_revno('null:'))
 
2145
        self.assertLength(8, self.hpss_calls)
 
2146
 
 
2147
 
1865
2148
class TestBzrDirGetSetConfig(RemoteBzrDirTestCase):
1866
2149
 
1867
2150
    def test__get_config(self):
1881
2164
        self.reset_smart_call_log()
1882
2165
        config = bzrdir.get_config()
1883
2166
        config.set_default_stack_on('/')
1884
 
        self.assertLength(3, self.hpss_calls)
 
2167
        self.assertLength(4, self.hpss_calls)
1885
2168
 
1886
2169
    def test_backwards_compat_get_option(self):
1887
2170
        self.setup_smart_server_with_call_log()
1891
2174
        self.reset_smart_call_log()
1892
2175
        self.assertEqual(None,
1893
2176
            bzrdir._get_config().get_option('default_stack_on'))
1894
 
        self.assertLength(3, self.hpss_calls)
 
2177
        self.assertLength(4, self.hpss_calls)
1895
2178
 
1896
2179
 
1897
2180
class TestTransportIsReadonly(tests.TestCase):
2024
2307
            remote_repo_format.get_format_description())
2025
2308
 
2026
2309
 
 
2310
class TestRepositoryAllRevisionIds(TestRemoteRepository):
 
2311
 
 
2312
    def test_empty(self):
 
2313
        transport_path = 'quack'
 
2314
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
2315
        client.add_success_response_with_body('', 'ok')
 
2316
        self.assertEquals([], repo.all_revision_ids())
 
2317
        self.assertEqual(
 
2318
            [('call_expecting_body', 'Repository.all_revision_ids',
 
2319
             ('quack/',))],
 
2320
            client._calls)
 
2321
 
 
2322
    def test_with_some_content(self):
 
2323
        transport_path = 'quack'
 
2324
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
2325
        client.add_success_response_with_body(
 
2326
            'rev1\nrev2\nanotherrev\n', 'ok')
 
2327
        self.assertEquals(["rev1", "rev2", "anotherrev"],
 
2328
            repo.all_revision_ids())
 
2329
        self.assertEqual(
 
2330
            [('call_expecting_body', 'Repository.all_revision_ids',
 
2331
             ('quack/',))],
 
2332
            client._calls)
 
2333
 
 
2334
 
2027
2335
class TestRepositoryGatherStats(TestRemoteRepository):
2028
2336
 
2029
2337
    def test_revid_none(self):
2082
2390
                         result)
2083
2391
 
2084
2392
 
 
2393
class TestRepositoryBreakLock(TestRemoteRepository):
 
2394
 
 
2395
    def test_break_lock(self):
 
2396
        transport_path = 'quack'
 
2397
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
2398
        client.add_success_response('ok')
 
2399
        repo.break_lock()
 
2400
        self.assertEqual(
 
2401
            [('call', 'Repository.break_lock', ('quack/',))],
 
2402
            client._calls)
 
2403
 
 
2404
 
 
2405
class TestRepositoryGetSerializerFormat(TestRemoteRepository):
 
2406
 
 
2407
    def test_get_serializer_format(self):
 
2408
        transport_path = 'hill'
 
2409
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
2410
        client.add_success_response('ok', '7')
 
2411
        self.assertEquals('7', repo.get_serializer_format())
 
2412
        self.assertEqual(
 
2413
            [('call', 'VersionedFileRepository.get_serializer_format',
 
2414
              ('hill/', ))],
 
2415
            client._calls)
 
2416
 
 
2417
 
 
2418
class TestRepositoryReconcile(TestRemoteRepository):
 
2419
 
 
2420
    def test_reconcile(self):
 
2421
        transport_path = 'hill'
 
2422
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
2423
        body = ("garbage_inventories: 2\n"
 
2424
                "inconsistent_parents: 3\n")
 
2425
        client.add_expected_call(
 
2426
            'Repository.lock_write', ('hill/', ''),
 
2427
            'success', ('ok', 'a token'))
 
2428
        client.add_success_response_with_body(body, 'ok')
 
2429
        reconciler = repo.reconcile()
 
2430
        self.assertEqual(
 
2431
            [('call', 'Repository.lock_write', ('hill/', '')),
 
2432
             ('call_expecting_body', 'Repository.reconcile',
 
2433
                ('hill/', 'a token'))],
 
2434
            client._calls)
 
2435
        self.assertEquals(2, reconciler.garbage_inventories)
 
2436
        self.assertEquals(3, reconciler.inconsistent_parents)
 
2437
 
 
2438
 
 
2439
class TestRepositoryGetRevisionSignatureText(TestRemoteRepository):
 
2440
 
 
2441
    def test_text(self):
 
2442
        # ('ok',), body with signature text
 
2443
        transport_path = 'quack'
 
2444
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
2445
        client.add_success_response_with_body(
 
2446
            'THETEXT', 'ok')
 
2447
        self.assertEquals("THETEXT", repo.get_signature_text("revid"))
 
2448
        self.assertEqual(
 
2449
            [('call_expecting_body', 'Repository.get_revision_signature_text',
 
2450
             ('quack/', 'revid'))],
 
2451
            client._calls)
 
2452
 
 
2453
    def test_no_signature(self):
 
2454
        transport_path = 'quick'
 
2455
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
2456
        client.add_error_response('nosuchrevision', 'unknown')
 
2457
        self.assertRaises(errors.NoSuchRevision, repo.get_signature_text,
 
2458
                "unknown")
 
2459
        self.assertEqual(
 
2460
            [('call_expecting_body', 'Repository.get_revision_signature_text',
 
2461
              ('quick/', 'unknown'))],
 
2462
            client._calls)
 
2463
 
 
2464
 
2085
2465
class TestRepositoryGetGraph(TestRemoteRepository):
2086
2466
 
2087
2467
    def test_get_graph(self):
2092
2472
        self.assertNotEqual(graph._parents_provider, repo)
2093
2473
 
2094
2474
 
 
2475
class TestRepositoryAddSignatureText(TestRemoteRepository):
 
2476
 
 
2477
    def test_add_signature_text(self):
 
2478
        transport_path = 'quack'
 
2479
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
2480
        client.add_expected_call(
 
2481
            'Repository.lock_write', ('quack/', ''),
 
2482
            'success', ('ok', 'a token'))
 
2483
        client.add_expected_call(
 
2484
            'Repository.start_write_group', ('quack/', 'a token'),
 
2485
            'success', ('ok', ('token1', )))
 
2486
        client.add_expected_call(
 
2487
            'Repository.add_signature_text', ('quack/', 'a token', 'rev1',
 
2488
                'token1'),
 
2489
            'success', ('ok', ), None)
 
2490
        repo.lock_write()
 
2491
        repo.start_write_group()
 
2492
        self.assertIs(None,
 
2493
            repo.add_signature_text("rev1", "every bloody emperor"))
 
2494
        self.assertEqual(
 
2495
            ('call_with_body_bytes_expecting_body',
 
2496
              'Repository.add_signature_text',
 
2497
                ('quack/', 'a token', 'rev1', 'token1'),
 
2498
              'every bloody emperor'),
 
2499
            client._calls[-1])
 
2500
 
 
2501
 
2095
2502
class TestRepositoryGetParentMap(TestRemoteRepository):
2096
2503
 
2097
2504
    def test_get_parent_map_caching(self):
2320
2727
        self.assertEqual({'rev1': ('null:',)}, graph.get_parent_map(['rev1']))
2321
2728
 
2322
2729
 
 
2730
class TestRepositoryGetRevisions(TestRemoteRepository):
 
2731
 
 
2732
    def test_hpss_missing_revision(self):
 
2733
        transport_path = 'quack'
 
2734
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
2735
        client.add_success_response_with_body(
 
2736
            '', 'ok', '10')
 
2737
        self.assertRaises(errors.NoSuchRevision, repo.get_revisions,
 
2738
            ['somerev1', 'anotherrev2'])
 
2739
        self.assertEqual(
 
2740
            [('call_with_body_bytes_expecting_body', 'Repository.iter_revisions',
 
2741
             ('quack/', ), "somerev1\nanotherrev2")],
 
2742
            client._calls)
 
2743
 
 
2744
    def test_hpss_get_single_revision(self):
 
2745
        transport_path = 'quack'
 
2746
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
2747
        somerev1 = Revision("somerev1")
 
2748
        somerev1.committer = "Joe Committer <joe@example.com>"
 
2749
        somerev1.timestamp = 1321828927
 
2750
        somerev1.timezone = -60
 
2751
        somerev1.inventory_sha1 = "691b39be74c67b1212a75fcb19c433aaed903c2b"
 
2752
        somerev1.message = "Message"
 
2753
        body = zlib.compress(chk_bencode_serializer.write_revision_to_string(
 
2754
            somerev1))
 
2755
        # Split up body into two bits to make sure the zlib compression object
 
2756
        # gets data fed twice.
 
2757
        client.add_success_response_with_body(
 
2758
                [body[:10], body[10:]], 'ok', '10')
 
2759
        revs = repo.get_revisions(['somerev1'])
 
2760
        self.assertEquals(revs, [somerev1])
 
2761
        self.assertEqual(
 
2762
            [('call_with_body_bytes_expecting_body', 'Repository.iter_revisions',
 
2763
             ('quack/', ), "somerev1")],
 
2764
            client._calls)
 
2765
 
 
2766
 
2323
2767
class TestRepositoryGetRevisionGraph(TestRemoteRepository):
2324
2768
 
2325
2769
    def test_null_revision(self):
2476
2920
                              call.call.method == verb])
2477
2921
 
2478
2922
 
 
2923
class TestRepositoryHasSignatureForRevisionId(TestRemoteRepository):
 
2924
 
 
2925
    def test_has_signature_for_revision_id(self):
 
2926
        # ('yes', ) for Repository.has_signature_for_revision_id -> 'True'.
 
2927
        transport_path = 'quack'
 
2928
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
2929
        client.add_success_response('yes')
 
2930
        result = repo.has_signature_for_revision_id('A')
 
2931
        self.assertEqual(
 
2932
            [('call', 'Repository.has_signature_for_revision_id',
 
2933
              ('quack/', 'A'))],
 
2934
            client._calls)
 
2935
        self.assertEqual(True, result)
 
2936
 
 
2937
    def test_is_not_shared(self):
 
2938
        # ('no', ) for Repository.has_signature_for_revision_id -> 'False'.
 
2939
        transport_path = 'qwack'
 
2940
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
2941
        client.add_success_response('no')
 
2942
        result = repo.has_signature_for_revision_id('A')
 
2943
        self.assertEqual(
 
2944
            [('call', 'Repository.has_signature_for_revision_id',
 
2945
              ('qwack/', 'A'))],
 
2946
            client._calls)
 
2947
        self.assertEqual(False, result)
 
2948
 
 
2949
 
 
2950
class TestRepositoryPhysicalLockStatus(TestRemoteRepository):
 
2951
 
 
2952
    def test_get_physical_lock_status_yes(self):
 
2953
        transport_path = 'qwack'
 
2954
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
2955
        client.add_success_response('yes')
 
2956
        result = repo.get_physical_lock_status()
 
2957
        self.assertEqual(
 
2958
            [('call', 'Repository.get_physical_lock_status',
 
2959
              ('qwack/', ))],
 
2960
            client._calls)
 
2961
        self.assertEqual(True, result)
 
2962
 
 
2963
    def test_get_physical_lock_status_no(self):
 
2964
        transport_path = 'qwack'
 
2965
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
2966
        client.add_success_response('no')
 
2967
        result = repo.get_physical_lock_status()
 
2968
        self.assertEqual(
 
2969
            [('call', 'Repository.get_physical_lock_status',
 
2970
              ('qwack/', ))],
 
2971
            client._calls)
 
2972
        self.assertEqual(False, result)
 
2973
 
 
2974
 
2479
2975
class TestRepositoryIsShared(TestRemoteRepository):
2480
2976
 
2481
2977
    def test_is_shared(self):
2501
2997
        self.assertEqual(False, result)
2502
2998
 
2503
2999
 
 
3000
class TestRepositoryMakeWorkingTrees(TestRemoteRepository):
 
3001
 
 
3002
    def test_make_working_trees(self):
 
3003
        # ('yes', ) for Repository.make_working_trees -> 'True'.
 
3004
        transport_path = 'quack'
 
3005
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
3006
        client.add_success_response('yes')
 
3007
        result = repo.make_working_trees()
 
3008
        self.assertEqual(
 
3009
            [('call', 'Repository.make_working_trees', ('quack/',))],
 
3010
            client._calls)
 
3011
        self.assertEqual(True, result)
 
3012
 
 
3013
    def test_no_working_trees(self):
 
3014
        # ('no', ) for Repository.make_working_trees -> 'False'.
 
3015
        transport_path = 'qwack'
 
3016
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
3017
        client.add_success_response('no')
 
3018
        result = repo.make_working_trees()
 
3019
        self.assertEqual(
 
3020
            [('call', 'Repository.make_working_trees', ('qwack/',))],
 
3021
            client._calls)
 
3022
        self.assertEqual(False, result)
 
3023
 
 
3024
 
2504
3025
class TestRepositoryLockWrite(TestRemoteRepository):
2505
3026
 
2506
3027
    def test_lock_write(self):
2532
3053
            client._calls)
2533
3054
 
2534
3055
 
 
3056
class TestRepositoryWriteGroups(TestRemoteRepository):
 
3057
 
 
3058
    def test_start_write_group(self):
 
3059
        transport_path = 'quack'
 
3060
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
3061
        client.add_expected_call(
 
3062
            'Repository.lock_write', ('quack/', ''),
 
3063
            'success', ('ok', 'a token'))
 
3064
        client.add_expected_call(
 
3065
            'Repository.start_write_group', ('quack/', 'a token'),
 
3066
            'success', ('ok', ('token1', )))
 
3067
        repo.lock_write()
 
3068
        repo.start_write_group()
 
3069
 
 
3070
    def test_start_write_group_unsuspendable(self):
 
3071
        # Some repositories do not support suspending write
 
3072
        # groups. For those, fall back to the "real" repository.
 
3073
        transport_path = 'quack'
 
3074
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
3075
        def stub_ensure_real():
 
3076
            client._calls.append(('_ensure_real',))
 
3077
            repo._real_repository = _StubRealPackRepository(client._calls)
 
3078
        repo._ensure_real = stub_ensure_real
 
3079
        client.add_expected_call(
 
3080
            'Repository.lock_write', ('quack/', ''),
 
3081
            'success', ('ok', 'a token'))
 
3082
        client.add_expected_call(
 
3083
            'Repository.start_write_group', ('quack/', 'a token'),
 
3084
            'error', ('UnsuspendableWriteGroup',))
 
3085
        repo.lock_write()
 
3086
        repo.start_write_group()
 
3087
        self.assertEquals(client._calls[-2:], [ 
 
3088
            ('_ensure_real',),
 
3089
            ('start_write_group',)])
 
3090
 
 
3091
    def test_commit_write_group(self):
 
3092
        transport_path = 'quack'
 
3093
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
3094
        client.add_expected_call(
 
3095
            'Repository.lock_write', ('quack/', ''),
 
3096
            'success', ('ok', 'a token'))
 
3097
        client.add_expected_call(
 
3098
            'Repository.start_write_group', ('quack/', 'a token'),
 
3099
            'success', ('ok', ['token1']))
 
3100
        client.add_expected_call(
 
3101
            'Repository.commit_write_group', ('quack/', 'a token', ['token1']),
 
3102
            'success', ('ok',))
 
3103
        repo.lock_write()
 
3104
        repo.start_write_group()
 
3105
        repo.commit_write_group()
 
3106
 
 
3107
    def test_abort_write_group(self):
 
3108
        transport_path = 'quack'
 
3109
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
3110
        client.add_expected_call(
 
3111
            'Repository.lock_write', ('quack/', ''),
 
3112
            'success', ('ok', 'a token'))
 
3113
        client.add_expected_call(
 
3114
            'Repository.start_write_group', ('quack/', 'a token'),
 
3115
            'success', ('ok', ['token1']))
 
3116
        client.add_expected_call(
 
3117
            'Repository.abort_write_group', ('quack/', 'a token', ['token1']),
 
3118
            'success', ('ok',))
 
3119
        repo.lock_write()
 
3120
        repo.start_write_group()
 
3121
        repo.abort_write_group(False)
 
3122
 
 
3123
    def test_suspend_write_group(self):
 
3124
        transport_path = 'quack'
 
3125
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
3126
        self.assertEquals([], repo.suspend_write_group())
 
3127
 
 
3128
    def test_resume_write_group(self):
 
3129
        transport_path = 'quack'
 
3130
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
3131
        client.add_expected_call(
 
3132
            'Repository.lock_write', ('quack/', ''),
 
3133
            'success', ('ok', 'a token'))
 
3134
        client.add_expected_call(
 
3135
            'Repository.check_write_group', ('quack/', 'a token', ['token1']),
 
3136
            'success', ('ok',))
 
3137
        repo.lock_write()
 
3138
        repo.resume_write_group(['token1'])
 
3139
 
 
3140
 
2535
3141
class TestRepositorySetMakeWorkingTrees(TestRemoteRepository):
2536
3142
 
2537
3143
    def test_backwards_compat(self):
2596
3202
        self.assertEqual([], client._calls)
2597
3203
 
2598
3204
 
 
3205
class TestRepositoryIterFilesBytes(TestRemoteRepository):
 
3206
    """Test Repository.iter_file_bytes."""
 
3207
 
 
3208
    def test_single(self):
 
3209
        transport_path = 'quack'
 
3210
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
3211
        client.add_expected_call(
 
3212
            'Repository.iter_files_bytes', ('quack/', ),
 
3213
            'success', ('ok',), iter(["ok\x000", "\n", zlib.compress("mydata" * 10)]))
 
3214
        for (identifier, byte_stream) in repo.iter_files_bytes([("somefile",
 
3215
                "somerev", "myid")]):
 
3216
            self.assertEquals("myid", identifier)
 
3217
            self.assertEquals("".join(byte_stream), "mydata" * 10)
 
3218
 
 
3219
    def test_missing(self):
 
3220
        transport_path = 'quack'
 
3221
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
3222
        client.add_expected_call(
 
3223
            'Repository.iter_files_bytes',
 
3224
                ('quack/', ),
 
3225
            'error', ('RevisionNotPresent', 'somefile', 'somerev'),
 
3226
            iter(["absent\0somefile\0somerev\n"]))
 
3227
        self.assertRaises(errors.RevisionNotPresent, list,
 
3228
                repo.iter_files_bytes(
 
3229
                [("somefile", "somerev", "myid")]))
 
3230
 
 
3231
 
2599
3232
class TestRepositoryInsertStreamBase(TestRemoteRepository):
2600
3233
    """Base class for Repository.insert_stream and .insert_stream_1.19
2601
3234
    tests.
2876
3509
        self.calls = calls
2877
3510
        self._pack_collection = _StubPackCollection(calls)
2878
3511
 
 
3512
    def start_write_group(self):
 
3513
        self.calls.append(('start_write_group',))
 
3514
 
2879
3515
    def is_in_write_group(self):
2880
3516
        return False
2881
3517
 
3319
3955
        revs = [r for (r,ps) in graph.iter_ancestry([tip])
3320
3956
                if r != NULL_REVISION]
3321
3957
        revs.reverse()
3322
 
        search = _mod_graph.PendingAncestryResult([tip], stacked.repository)
 
3958
        search = vf_search.PendingAncestryResult([tip], stacked.repository)
3323
3959
        self.reset_smart_call_log()
3324
3960
        stream = source.get_stream(search)
3325
3961
        # We trust that if a revision is in the stream the rest of the new
3431
4067
        self.hpss_calls = []
3432
4068
        local.repository.fetch(
3433
4069
            remote_branch.repository,
3434
 
            fetch_spec=_mod_graph.EverythingResult(remote_branch.repository))
 
4070
            fetch_spec=vf_search.EverythingResult(remote_branch.repository))
3435
4071
        self.assertEqual(['Repository.get_stream_1.19'], self.hpss_calls)
3436
4072
 
3437
4073
    def override_verb(self, verb_name, verb):
3438
4074
        request_handlers = request.request_handlers
3439
4075
        orig_verb = request_handlers.get(verb_name)
 
4076
        orig_info = request_handlers.get_info(verb_name)
3440
4077
        request_handlers.register(verb_name, verb, override_existing=True)
3441
4078
        self.addCleanup(request_handlers.register, verb_name, orig_verb,
3442
 
                override_existing=True)
 
4079
                override_existing=True, info=orig_info)
3443
4080
 
3444
4081
    def test_fetch_everything_backwards_compat(self):
3445
4082
        """Can fetch with EverythingResult even with pre 2.4 servers.
3470
4107
        self.hpss_calls = []
3471
4108
        local.repository.fetch(
3472
4109
            remote_branch.repository,
3473
 
            fetch_spec=_mod_graph.EverythingResult(remote_branch.repository))
 
4110
            fetch_spec=vf_search.EverythingResult(remote_branch.repository))
3474
4111
        # make sure the overridden verb was used
3475
4112
        self.assertLength(1, verb_log)
3476
4113
        # more than one HPSS call is needed, but because it's a VFS callback
3521
4158
        # interpretation
3522
4159
        self.make_master_and_checkout('mas~ter', 'checkout')
3523
4160
        self.assertUpdateSucceeds(self.bound_location.replace('%2E', '~', 1))
 
4161
 
 
4162
 
 
4163
class TestWithCustomErrorHandler(RemoteBranchTestCase):
 
4164
 
 
4165
    def test_no_context(self):
 
4166
        class OutOfCoffee(errors.BzrError):
 
4167
            """A dummy exception for testing."""
 
4168
 
 
4169
            def __init__(self, urgency):
 
4170
                self.urgency = urgency
 
4171
        remote.no_context_error_translators.register("OutOfCoffee",
 
4172
            lambda err: OutOfCoffee(err.error_args[0]))
 
4173
        transport = MemoryTransport()
 
4174
        client = FakeClient(transport.base)
 
4175
        client.add_expected_call(
 
4176
            'Branch.get_stacked_on_url', ('quack/',),
 
4177
            'error', ('NotStacked',))
 
4178
        client.add_expected_call(
 
4179
            'Branch.last_revision_info',
 
4180
            ('quack/',),
 
4181
            'error', ('OutOfCoffee', 'low'))
 
4182
        transport.mkdir('quack')
 
4183
        transport = transport.clone('quack')
 
4184
        branch = self.make_remote_branch(transport, client)
 
4185
        self.assertRaises(OutOfCoffee, branch.last_revision_info)
 
4186
        self.assertFinished(client)
 
4187
 
 
4188
    def test_with_context(self):
 
4189
        class OutOfTea(errors.BzrError):
 
4190
            def __init__(self, branch, urgency):
 
4191
                self.branch = branch
 
4192
                self.urgency = urgency
 
4193
        remote.error_translators.register("OutOfTea",
 
4194
            lambda err, find, path: OutOfTea(err.error_args[0],
 
4195
                find("branch")))
 
4196
        transport = MemoryTransport()
 
4197
        client = FakeClient(transport.base)
 
4198
        client.add_expected_call(
 
4199
            'Branch.get_stacked_on_url', ('quack/',),
 
4200
            'error', ('NotStacked',))
 
4201
        client.add_expected_call(
 
4202
            'Branch.last_revision_info',
 
4203
            ('quack/',),
 
4204
            'error', ('OutOfTea', 'low'))
 
4205
        transport.mkdir('quack')
 
4206
        transport = transport.clone('quack')
 
4207
        branch = self.make_remote_branch(transport, client)
 
4208
        self.assertRaises(OutOfTea, branch.last_revision_info)
 
4209
        self.assertFinished(client)
 
4210
 
 
4211
 
 
4212
class TestRepositoryPack(TestRemoteRepository):
 
4213
 
 
4214
    def test_pack(self):
 
4215
        transport_path = 'quack'
 
4216
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
4217
        client.add_expected_call(
 
4218
            'Repository.lock_write', ('quack/', ''),
 
4219
            'success', ('ok', 'token'))
 
4220
        client.add_expected_call(
 
4221
            'Repository.pack', ('quack/', 'token', 'False'),
 
4222
            'success', ('ok',), )
 
4223
        client.add_expected_call(
 
4224
            'Repository.unlock', ('quack/', 'token'),
 
4225
            'success', ('ok', ))
 
4226
        repo.pack()
 
4227
 
 
4228
    def test_pack_with_hint(self):
 
4229
        transport_path = 'quack'
 
4230
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
4231
        client.add_expected_call(
 
4232
            'Repository.lock_write', ('quack/', ''),
 
4233
            'success', ('ok', 'token'))
 
4234
        client.add_expected_call(
 
4235
            'Repository.pack', ('quack/', 'token', 'False'),
 
4236
            'success', ('ok',), )
 
4237
        client.add_expected_call(
 
4238
            'Repository.unlock', ('quack/', 'token', 'False'),
 
4239
            'success', ('ok', ))
 
4240
        repo.pack(['hinta', 'hintb'])
 
4241
 
 
4242
 
 
4243
class TestRepositoryIterInventories(TestRemoteRepository):
 
4244
    """Test Repository.iter_inventories."""
 
4245
 
 
4246
    def _serialize_inv_delta(self, old_name, new_name, delta):
 
4247
        serializer = inventory_delta.InventoryDeltaSerializer(True, False)
 
4248
        return "".join(serializer.delta_to_lines(old_name, new_name, delta))
 
4249
 
 
4250
    def test_single_empty(self):
 
4251
        transport_path = 'quack'
 
4252
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
4253
        fmt = bzrdir.format_registry.get('2a')().repository_format
 
4254
        repo._format = fmt
 
4255
        stream = [('inventory-deltas', [
 
4256
            versionedfile.FulltextContentFactory('somerevid', None, None,
 
4257
                self._serialize_inv_delta('null:', 'somerevid', []))])]
 
4258
        client.add_expected_call(
 
4259
            'VersionedFileRepository.get_inventories', ('quack/', 'unordered'),
 
4260
            'success', ('ok', ),
 
4261
            _stream_to_byte_stream(stream, fmt))
 
4262
        ret = list(repo.iter_inventories(["somerevid"]))
 
4263
        self.assertLength(1, ret)
 
4264
        inv = ret[0]
 
4265
        self.assertEquals("somerevid", inv.revision_id)
 
4266
 
 
4267
    def test_empty(self):
 
4268
        transport_path = 'quack'
 
4269
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
4270
        ret = list(repo.iter_inventories([]))
 
4271
        self.assertEquals(ret, [])
 
4272
 
 
4273
    def test_missing(self):
 
4274
        transport_path = 'quack'
 
4275
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
4276
        client.add_expected_call(
 
4277
            'VersionedFileRepository.get_inventories', ('quack/', 'unordered'),
 
4278
            'success', ('ok', ), iter([]))
 
4279
        self.assertRaises(errors.NoSuchRevision, list, repo.iter_inventories(
 
4280
            ["somerevid"]))