~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_remote.py

  • Committer: Patch Queue Manager
  • Date: 2012-02-25 15:28:53 UTC
  • mfrom: (6475.1.1 bzr.dev)
  • Revision ID: pqm@pqm.ubuntu.com-20120225152853-nz1w2gsfv7lc1yq4
(jelmer) Update documentation to mention command hooks landed in bzr 2.6
 rather than 2.5. (Brian de Alwis)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006-2011 Canonical Ltd
 
1
# Copyright (C) 2006-2012 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
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
    )
67
74
from bzrlib.symbol_versioning import deprecated_in
68
75
from bzrlib.tests import (
168
175
    def test_remote_branch_set_append_revisions_only(self):
169
176
        # Make a format 1.9 branch, which supports append_revisions_only
170
177
        branch = self.make_branch('branch', format='1.9')
171
 
        config = branch.get_config()
172
178
        branch.set_append_revisions_only(True)
 
179
        config = branch.get_config_stack()
173
180
        self.assertEqual(
174
 
            'True', config.get_user_option('append_revisions_only'))
 
181
            True, config.get('append_revisions_only'))
175
182
        branch.set_append_revisions_only(False)
 
183
        config = branch.get_config_stack()
176
184
        self.assertEqual(
177
 
            'False', config.get_user_option('append_revisions_only'))
 
185
            False, config.get('append_revisions_only'))
178
186
 
179
187
    def test_remote_branch_set_append_revisions_only_upgrade_reqd(self):
180
188
        branch = self.make_branch('branch', format='knit')
181
 
        config = branch.get_config()
182
189
        self.assertRaises(
183
190
            errors.UpgradeRequired, branch.set_append_revisions_only, True)
184
191
 
484
491
        self.assertEqual(None, result._branch_format)
485
492
        self.assertFinished(client)
486
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
 
487
631
 
488
632
class TestBzrDirOpen(TestRemote):
489
633
 
613
757
        # _get_tree_branch is a form of open_branch, but it should only ask for
614
758
        # branch opening, not any other network requests.
615
759
        calls = []
616
 
        def open_branch(name=None):
 
760
        def open_branch(name=None, possible_transports=None):
617
761
            calls.append("Called")
618
762
            return "a-branch"
619
763
        transport = MemoryTransport()
811
955
        # name.
812
956
        client.add_success_response_with_body(
813
957
            "Bazaar-NG meta directory, format 1\n", 'ok')
 
958
        client.add_success_response('stat', '0', '65535')
814
959
        client.add_success_response_with_body(
815
960
            reference_format.get_format_string(), 'ok')
816
961
        # PackRepository wants to do a stat
825
970
             ('call', 'BzrDir.find_repositoryV2', ('quack/',)),
826
971
             ('call', 'BzrDir.find_repository', ('quack/',)),
827
972
             ('call_expecting_body', 'get', ('/quack/.bzr/branch-format',)),
 
973
             ('call', 'stat', ('/quack/.bzr',)),
828
974
             ('call_expecting_body', 'get', ('/quack/.bzr/repository/format',)),
829
975
             ('call', 'stat', ('/quack/.bzr/repository',)),
830
976
             ],
844
990
        # name.
845
991
        client.add_success_response_with_body(
846
992
            "Bazaar-NG meta directory, format 1\n", 'ok')
 
993
        client.add_success_response('stat', '0', '65535')
847
994
        client.add_success_response_with_body(
848
995
            reference_format.get_format_string(), 'ok')
849
996
        # PackRepository wants to do a stat
857
1004
            [('call', 'BzrDir.find_repositoryV3', ('quack/',)),
858
1005
             ('call', 'BzrDir.find_repositoryV2', ('quack/',)),
859
1006
             ('call_expecting_body', 'get', ('/quack/.bzr/branch-format',)),
 
1007
             ('call', 'stat', ('/quack/.bzr',)),
860
1008
             ('call_expecting_body', 'get', ('/quack/.bzr/repository/format',)),
861
1009
             ('call', 'stat', ('/quack/.bzr/repository',)),
862
1010
             ],
999
1147
        return RemoteBranch(bzrdir, repo, _client=client, format=format)
1000
1148
 
1001
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
 
1002
1204
class TestBranchGetParent(RemoteBranchTestCase):
1003
1205
 
1004
1206
    def test_no_parent(self):
1094
1296
        verb = 'Branch.set_parent_location'
1095
1297
        self.disable_verb(verb)
1096
1298
        branch.set_parent('http://foo/')
1097
 
        self.assertLength(12, self.hpss_calls)
 
1299
        self.assertLength(14, self.hpss_calls)
1098
1300
 
1099
1301
 
1100
1302
class TestBranchGetTagsBytes(RemoteBranchTestCase):
1253
1455
        return branch
1254
1456
 
1255
1457
    def test_backwards_compatible(self):
1256
 
        branch = self.make_branch_with_tags()
1257
 
        c = branch.get_config()
1258
 
        c.set_user_option('branch.fetch_tags', 'True')
1259
 
        self.addCleanup(branch.lock_read().unlock)
 
1458
        br = self.make_branch_with_tags()
 
1459
        br.get_config_stack().set('branch.fetch_tags', True)
 
1460
        self.addCleanup(br.lock_read().unlock)
1260
1461
        # Disable the heads_to_fetch verb
1261
1462
        verb = 'Branch.heads_to_fetch'
1262
1463
        self.disable_verb(verb)
1263
1464
        self.reset_smart_call_log()
1264
 
        result = branch.heads_to_fetch()
 
1465
        result = br.heads_to_fetch()
1265
1466
        self.assertEqual((set(['tip']), set(['rev-1', 'rev-2'])), result)
1266
1467
        self.assertEqual(
1267
 
            ['Branch.last_revision_info', 'Branch.get_config_file',
1268
 
             'Branch.get_tags_bytes'],
 
1468
            ['Branch.last_revision_info', 'Branch.get_tags_bytes'],
1269
1469
            [call.call.method for call in self.hpss_calls])
1270
1470
 
1271
1471
    def test_backwards_compatible_no_tags(self):
1272
 
        branch = self.make_branch_with_tags()
1273
 
        c = branch.get_config()
1274
 
        c.set_user_option('branch.fetch_tags', 'False')
1275
 
        self.addCleanup(branch.lock_read().unlock)
 
1472
        br = self.make_branch_with_tags()
 
1473
        br.get_config_stack().set('branch.fetch_tags', False)
 
1474
        self.addCleanup(br.lock_read().unlock)
1276
1475
        # Disable the heads_to_fetch verb
1277
1476
        verb = 'Branch.heads_to_fetch'
1278
1477
        self.disable_verb(verb)
1279
1478
        self.reset_smart_call_log()
1280
 
        result = branch.heads_to_fetch()
 
1479
        result = br.heads_to_fetch()
1281
1480
        self.assertEqual((set(['tip']), set()), result)
1282
1481
        self.assertEqual(
1283
 
            ['Branch.last_revision_info', 'Branch.get_config_file'],
 
1482
            ['Branch.last_revision_info'],
1284
1483
            [call.call.method for call in self.hpss_calls])
1285
1484
 
1286
1485
 
1448
1647
            'Branch.unlock', ('branch/', 'branch token', 'repo token'),
1449
1648
            'success', ('ok',))
1450
1649
        branch = self.make_remote_branch(transport, client)
1451
 
        # This is a hack to work around the problem that RemoteBranch currently
1452
 
        # unnecessarily invokes _ensure_real upon a call to lock_write.
1453
 
        branch._ensure_real = lambda: None
1454
1650
        branch.lock_write()
1455
1651
        result = branch._set_last_revision(NULL_REVISION)
1456
1652
        branch.unlock()
1485
1681
            'Branch.unlock', ('branch/', 'branch token', 'repo token'),
1486
1682
            'success', ('ok',))
1487
1683
        branch = self.make_remote_branch(transport, client)
1488
 
        # This is a hack to work around the problem that RemoteBranch currently
1489
 
        # unnecessarily invokes _ensure_real upon a call to lock_write.
1490
 
        branch._ensure_real = lambda: None
1491
1684
        # Lock the branch, reset the record of remote calls.
1492
1685
        branch.lock_write()
1493
1686
        result = branch._set_last_revision('rev-id2')
1560
1753
            'Branch.unlock', ('branch/', 'branch token', 'repo token'),
1561
1754
            'success', ('ok',))
1562
1755
        branch = self.make_remote_branch(transport, client)
1563
 
        branch._ensure_real = lambda: None
1564
1756
        branch.lock_write()
1565
1757
        # The 'TipChangeRejected' error response triggered by calling
1566
1758
        # set_last_revision_info causes a TipChangeRejected exception.
1829
2021
        self.addCleanup(branch.unlock)
1830
2022
        self.reset_smart_call_log()
1831
2023
        branch._get_config().set_option('value', 'name')
1832
 
        self.assertLength(10, self.hpss_calls)
 
2024
        self.assertLength(11, self.hpss_calls)
1833
2025
        self.assertEqual('value', branch._get_config().get_option('name'))
1834
2026
 
1835
2027
    def test_backwards_compat_set_option_with_dict(self):
1843
2035
        config = branch._get_config()
1844
2036
        value_dict = {'ascii': 'a', u'unicode \N{WATCH}': u'\N{INTERROBANG}'}
1845
2037
        config.set_option(value_dict, 'name')
1846
 
        self.assertLength(10, self.hpss_calls)
 
2038
        self.assertLength(11, self.hpss_calls)
1847
2039
        self.assertEqual(value_dict, branch._get_config().get_option('name'))
1848
2040
 
1849
2041
 
 
2042
class TestBranchGetPutConfigStore(RemoteBranchTestCase):
 
2043
 
 
2044
    def test_get_branch_conf(self):
 
2045
        # in an empty branch we decode the response properly
 
2046
        client = FakeClient()
 
2047
        client.add_expected_call(
 
2048
            'Branch.get_stacked_on_url', ('memory:///',),
 
2049
            'error', ('NotStacked',),)
 
2050
        client.add_success_response_with_body('# config file body', 'ok')
 
2051
        transport = MemoryTransport()
 
2052
        branch = self.make_remote_branch(transport, client)
 
2053
        config = branch.get_config_stack()
 
2054
        config.get("email")
 
2055
        config.get("log_format")
 
2056
        self.assertEqual(
 
2057
            [('call', 'Branch.get_stacked_on_url', ('memory:///',)),
 
2058
             ('call_expecting_body', 'Branch.get_config_file', ('memory:///',))],
 
2059
            client._calls)
 
2060
 
 
2061
    def test_set_branch_conf(self):
 
2062
        client = FakeClient()
 
2063
        client.add_expected_call(
 
2064
            'Branch.get_stacked_on_url', ('memory:///',),
 
2065
            'error', ('NotStacked',),)
 
2066
        client.add_expected_call(
 
2067
            'Branch.lock_write', ('memory:///', '', ''),
 
2068
            'success', ('ok', 'branch token', 'repo token'))
 
2069
        client.add_expected_call(
 
2070
            'Branch.get_config_file', ('memory:///', ),
 
2071
            'success', ('ok', ), "# line 1\n")
 
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_expecting_body', 'Branch.get_config_file', ('memory:///',)),
 
2094
             ('call_with_body_bytes_expecting_body', 'Branch.put_config_file',
 
2095
                 ('memory:///', 'branch token', 'repo token'),
 
2096
                 '# line 1\nemail = The Dude <lebowski@example.com>\n'),
 
2097
             ('call', 'Branch.unlock', ('memory:///', 'branch token', 'repo token'))],
 
2098
            client._calls)
 
2099
 
 
2100
 
1850
2101
class TestBranchLockWrite(RemoteBranchTestCase):
1851
2102
 
1852
2103
    def test_lock_write_unlockable(self):
1865
2116
        self.assertFinished(client)
1866
2117
 
1867
2118
 
 
2119
class TestBranchRevisionIdToRevno(RemoteBranchTestCase):
 
2120
 
 
2121
    def test_simple(self):
 
2122
        transport = MemoryTransport()
 
2123
        client = FakeClient(transport.base)
 
2124
        client.add_expected_call(
 
2125
            'Branch.get_stacked_on_url', ('quack/',),
 
2126
            'error', ('NotStacked',),)
 
2127
        client.add_expected_call(
 
2128
            'Branch.revision_id_to_revno', ('quack/', 'null:'),
 
2129
            'success', ('ok', '0',),)
 
2130
        client.add_expected_call(
 
2131
            'Branch.revision_id_to_revno', ('quack/', 'unknown'),
 
2132
            'error', ('NoSuchRevision', 'unknown',),)
 
2133
        transport.mkdir('quack')
 
2134
        transport = transport.clone('quack')
 
2135
        branch = self.make_remote_branch(transport, client)
 
2136
        self.assertEquals(0, branch.revision_id_to_revno('null:'))
 
2137
        self.assertRaises(errors.NoSuchRevision,
 
2138
            branch.revision_id_to_revno, 'unknown')
 
2139
        self.assertFinished(client)
 
2140
 
 
2141
    def test_dotted(self):
 
2142
        transport = MemoryTransport()
 
2143
        client = FakeClient(transport.base)
 
2144
        client.add_expected_call(
 
2145
            'Branch.get_stacked_on_url', ('quack/',),
 
2146
            'error', ('NotStacked',),)
 
2147
        client.add_expected_call(
 
2148
            'Branch.revision_id_to_revno', ('quack/', 'null:'),
 
2149
            'success', ('ok', '0',),)
 
2150
        client.add_expected_call(
 
2151
            'Branch.revision_id_to_revno', ('quack/', 'unknown'),
 
2152
            'error', ('NoSuchRevision', 'unknown',),)
 
2153
        transport.mkdir('quack')
 
2154
        transport = transport.clone('quack')
 
2155
        branch = self.make_remote_branch(transport, client)
 
2156
        self.assertEquals((0, ), branch.revision_id_to_dotted_revno('null:'))
 
2157
        self.assertRaises(errors.NoSuchRevision,
 
2158
            branch.revision_id_to_dotted_revno, 'unknown')
 
2159
        self.assertFinished(client)
 
2160
 
 
2161
    def test_dotted_no_smart_verb(self):
 
2162
        self.setup_smart_server_with_call_log()
 
2163
        branch = self.make_branch('.')
 
2164
        self.disable_verb('Branch.revision_id_to_revno')
 
2165
        self.reset_smart_call_log()
 
2166
        self.assertEquals((0, ),
 
2167
            branch.revision_id_to_dotted_revno('null:'))
 
2168
        self.assertLength(8, self.hpss_calls)
 
2169
 
 
2170
 
1868
2171
class TestBzrDirGetSetConfig(RemoteBzrDirTestCase):
1869
2172
 
1870
2173
    def test__get_config(self):
1884
2187
        self.reset_smart_call_log()
1885
2188
        config = bzrdir.get_config()
1886
2189
        config.set_default_stack_on('/')
1887
 
        self.assertLength(3, self.hpss_calls)
 
2190
        self.assertLength(4, self.hpss_calls)
1888
2191
 
1889
2192
    def test_backwards_compat_get_option(self):
1890
2193
        self.setup_smart_server_with_call_log()
1894
2197
        self.reset_smart_call_log()
1895
2198
        self.assertEqual(None,
1896
2199
            bzrdir._get_config().get_option('default_stack_on'))
1897
 
        self.assertLength(3, self.hpss_calls)
 
2200
        self.assertLength(4, self.hpss_calls)
1898
2201
 
1899
2202
 
1900
2203
class TestTransportIsReadonly(tests.TestCase):
2027
2330
            remote_repo_format.get_format_description())
2028
2331
 
2029
2332
 
 
2333
class TestRepositoryAllRevisionIds(TestRemoteRepository):
 
2334
 
 
2335
    def test_empty(self):
 
2336
        transport_path = 'quack'
 
2337
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
2338
        client.add_success_response_with_body('', 'ok')
 
2339
        self.assertEquals([], repo.all_revision_ids())
 
2340
        self.assertEqual(
 
2341
            [('call_expecting_body', 'Repository.all_revision_ids',
 
2342
             ('quack/',))],
 
2343
            client._calls)
 
2344
 
 
2345
    def test_with_some_content(self):
 
2346
        transport_path = 'quack'
 
2347
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
2348
        client.add_success_response_with_body(
 
2349
            'rev1\nrev2\nanotherrev\n', 'ok')
 
2350
        self.assertEquals(["rev1", "rev2", "anotherrev"],
 
2351
            repo.all_revision_ids())
 
2352
        self.assertEqual(
 
2353
            [('call_expecting_body', 'Repository.all_revision_ids',
 
2354
             ('quack/',))],
 
2355
            client._calls)
 
2356
 
 
2357
 
2030
2358
class TestRepositoryGatherStats(TestRemoteRepository):
2031
2359
 
2032
2360
    def test_revid_none(self):
2085
2413
                         result)
2086
2414
 
2087
2415
 
 
2416
class TestRepositoryBreakLock(TestRemoteRepository):
 
2417
 
 
2418
    def test_break_lock(self):
 
2419
        transport_path = 'quack'
 
2420
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
2421
        client.add_success_response('ok')
 
2422
        repo.break_lock()
 
2423
        self.assertEqual(
 
2424
            [('call', 'Repository.break_lock', ('quack/',))],
 
2425
            client._calls)
 
2426
 
 
2427
 
 
2428
class TestRepositoryGetSerializerFormat(TestRemoteRepository):
 
2429
 
 
2430
    def test_get_serializer_format(self):
 
2431
        transport_path = 'hill'
 
2432
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
2433
        client.add_success_response('ok', '7')
 
2434
        self.assertEquals('7', repo.get_serializer_format())
 
2435
        self.assertEqual(
 
2436
            [('call', 'VersionedFileRepository.get_serializer_format',
 
2437
              ('hill/', ))],
 
2438
            client._calls)
 
2439
 
 
2440
 
 
2441
class TestRepositoryReconcile(TestRemoteRepository):
 
2442
 
 
2443
    def test_reconcile(self):
 
2444
        transport_path = 'hill'
 
2445
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
2446
        body = ("garbage_inventories: 2\n"
 
2447
                "inconsistent_parents: 3\n")
 
2448
        client.add_expected_call(
 
2449
            'Repository.lock_write', ('hill/', ''),
 
2450
            'success', ('ok', 'a token'))
 
2451
        client.add_success_response_with_body(body, 'ok')
 
2452
        reconciler = repo.reconcile()
 
2453
        self.assertEqual(
 
2454
            [('call', 'Repository.lock_write', ('hill/', '')),
 
2455
             ('call_expecting_body', 'Repository.reconcile',
 
2456
                ('hill/', 'a token'))],
 
2457
            client._calls)
 
2458
        self.assertEquals(2, reconciler.garbage_inventories)
 
2459
        self.assertEquals(3, reconciler.inconsistent_parents)
 
2460
 
 
2461
 
 
2462
class TestRepositoryGetRevisionSignatureText(TestRemoteRepository):
 
2463
 
 
2464
    def test_text(self):
 
2465
        # ('ok',), body with signature text
 
2466
        transport_path = 'quack'
 
2467
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
2468
        client.add_success_response_with_body(
 
2469
            'THETEXT', 'ok')
 
2470
        self.assertEquals("THETEXT", repo.get_signature_text("revid"))
 
2471
        self.assertEqual(
 
2472
            [('call_expecting_body', 'Repository.get_revision_signature_text',
 
2473
             ('quack/', 'revid'))],
 
2474
            client._calls)
 
2475
 
 
2476
    def test_no_signature(self):
 
2477
        transport_path = 'quick'
 
2478
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
2479
        client.add_error_response('nosuchrevision', 'unknown')
 
2480
        self.assertRaises(errors.NoSuchRevision, repo.get_signature_text,
 
2481
                "unknown")
 
2482
        self.assertEqual(
 
2483
            [('call_expecting_body', 'Repository.get_revision_signature_text',
 
2484
              ('quick/', 'unknown'))],
 
2485
            client._calls)
 
2486
 
 
2487
 
2088
2488
class TestRepositoryGetGraph(TestRemoteRepository):
2089
2489
 
2090
2490
    def test_get_graph(self):
2095
2495
        self.assertNotEqual(graph._parents_provider, repo)
2096
2496
 
2097
2497
 
 
2498
class TestRepositoryAddSignatureText(TestRemoteRepository):
 
2499
 
 
2500
    def test_add_signature_text(self):
 
2501
        transport_path = 'quack'
 
2502
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
2503
        client.add_expected_call(
 
2504
            'Repository.lock_write', ('quack/', ''),
 
2505
            'success', ('ok', 'a token'))
 
2506
        client.add_expected_call(
 
2507
            'Repository.start_write_group', ('quack/', 'a token'),
 
2508
            'success', ('ok', ('token1', )))
 
2509
        client.add_expected_call(
 
2510
            'Repository.add_signature_text', ('quack/', 'a token', 'rev1',
 
2511
                'token1'),
 
2512
            'success', ('ok', ), None)
 
2513
        repo.lock_write()
 
2514
        repo.start_write_group()
 
2515
        self.assertIs(None,
 
2516
            repo.add_signature_text("rev1", "every bloody emperor"))
 
2517
        self.assertEqual(
 
2518
            ('call_with_body_bytes_expecting_body',
 
2519
              'Repository.add_signature_text',
 
2520
                ('quack/', 'a token', 'rev1', 'token1'),
 
2521
              'every bloody emperor'),
 
2522
            client._calls[-1])
 
2523
 
 
2524
 
2098
2525
class TestRepositoryGetParentMap(TestRemoteRepository):
2099
2526
 
2100
2527
    def test_get_parent_map_caching(self):
2323
2750
        self.assertEqual({'rev1': ('null:',)}, graph.get_parent_map(['rev1']))
2324
2751
 
2325
2752
 
 
2753
class TestRepositoryGetRevisions(TestRemoteRepository):
 
2754
 
 
2755
    def test_hpss_missing_revision(self):
 
2756
        transport_path = 'quack'
 
2757
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
2758
        client.add_success_response_with_body(
 
2759
            '', 'ok', '10')
 
2760
        self.assertRaises(errors.NoSuchRevision, repo.get_revisions,
 
2761
            ['somerev1', 'anotherrev2'])
 
2762
        self.assertEqual(
 
2763
            [('call_with_body_bytes_expecting_body', 'Repository.iter_revisions',
 
2764
             ('quack/', ), "somerev1\nanotherrev2")],
 
2765
            client._calls)
 
2766
 
 
2767
    def test_hpss_get_single_revision(self):
 
2768
        transport_path = 'quack'
 
2769
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
2770
        somerev1 = Revision("somerev1")
 
2771
        somerev1.committer = "Joe Committer <joe@example.com>"
 
2772
        somerev1.timestamp = 1321828927
 
2773
        somerev1.timezone = -60
 
2774
        somerev1.inventory_sha1 = "691b39be74c67b1212a75fcb19c433aaed903c2b"
 
2775
        somerev1.message = "Message"
 
2776
        body = zlib.compress(chk_bencode_serializer.write_revision_to_string(
 
2777
            somerev1))
 
2778
        # Split up body into two bits to make sure the zlib compression object
 
2779
        # gets data fed twice.
 
2780
        client.add_success_response_with_body(
 
2781
                [body[:10], body[10:]], 'ok', '10')
 
2782
        revs = repo.get_revisions(['somerev1'])
 
2783
        self.assertEquals(revs, [somerev1])
 
2784
        self.assertEqual(
 
2785
            [('call_with_body_bytes_expecting_body', 'Repository.iter_revisions',
 
2786
             ('quack/', ), "somerev1")],
 
2787
            client._calls)
 
2788
 
 
2789
 
2326
2790
class TestRepositoryGetRevisionGraph(TestRemoteRepository):
2327
2791
 
2328
2792
    def test_null_revision(self):
2479
2943
                              call.call.method == verb])
2480
2944
 
2481
2945
 
 
2946
class TestRepositoryHasSignatureForRevisionId(TestRemoteRepository):
 
2947
 
 
2948
    def test_has_signature_for_revision_id(self):
 
2949
        # ('yes', ) for Repository.has_signature_for_revision_id -> 'True'.
 
2950
        transport_path = 'quack'
 
2951
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
2952
        client.add_success_response('yes')
 
2953
        result = repo.has_signature_for_revision_id('A')
 
2954
        self.assertEqual(
 
2955
            [('call', 'Repository.has_signature_for_revision_id',
 
2956
              ('quack/', 'A'))],
 
2957
            client._calls)
 
2958
        self.assertEqual(True, result)
 
2959
 
 
2960
    def test_is_not_shared(self):
 
2961
        # ('no', ) for Repository.has_signature_for_revision_id -> 'False'.
 
2962
        transport_path = 'qwack'
 
2963
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
2964
        client.add_success_response('no')
 
2965
        result = repo.has_signature_for_revision_id('A')
 
2966
        self.assertEqual(
 
2967
            [('call', 'Repository.has_signature_for_revision_id',
 
2968
              ('qwack/', 'A'))],
 
2969
            client._calls)
 
2970
        self.assertEqual(False, result)
 
2971
 
 
2972
 
 
2973
class TestRepositoryPhysicalLockStatus(TestRemoteRepository):
 
2974
 
 
2975
    def test_get_physical_lock_status_yes(self):
 
2976
        transport_path = 'qwack'
 
2977
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
2978
        client.add_success_response('yes')
 
2979
        result = repo.get_physical_lock_status()
 
2980
        self.assertEqual(
 
2981
            [('call', 'Repository.get_physical_lock_status',
 
2982
              ('qwack/', ))],
 
2983
            client._calls)
 
2984
        self.assertEqual(True, result)
 
2985
 
 
2986
    def test_get_physical_lock_status_no(self):
 
2987
        transport_path = 'qwack'
 
2988
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
2989
        client.add_success_response('no')
 
2990
        result = repo.get_physical_lock_status()
 
2991
        self.assertEqual(
 
2992
            [('call', 'Repository.get_physical_lock_status',
 
2993
              ('qwack/', ))],
 
2994
            client._calls)
 
2995
        self.assertEqual(False, result)
 
2996
 
 
2997
 
2482
2998
class TestRepositoryIsShared(TestRemoteRepository):
2483
2999
 
2484
3000
    def test_is_shared(self):
2504
3020
        self.assertEqual(False, result)
2505
3021
 
2506
3022
 
 
3023
class TestRepositoryMakeWorkingTrees(TestRemoteRepository):
 
3024
 
 
3025
    def test_make_working_trees(self):
 
3026
        # ('yes', ) for Repository.make_working_trees -> 'True'.
 
3027
        transport_path = 'quack'
 
3028
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
3029
        client.add_success_response('yes')
 
3030
        result = repo.make_working_trees()
 
3031
        self.assertEqual(
 
3032
            [('call', 'Repository.make_working_trees', ('quack/',))],
 
3033
            client._calls)
 
3034
        self.assertEqual(True, result)
 
3035
 
 
3036
    def test_no_working_trees(self):
 
3037
        # ('no', ) for Repository.make_working_trees -> 'False'.
 
3038
        transport_path = 'qwack'
 
3039
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
3040
        client.add_success_response('no')
 
3041
        result = repo.make_working_trees()
 
3042
        self.assertEqual(
 
3043
            [('call', 'Repository.make_working_trees', ('qwack/',))],
 
3044
            client._calls)
 
3045
        self.assertEqual(False, result)
 
3046
 
 
3047
 
2507
3048
class TestRepositoryLockWrite(TestRemoteRepository):
2508
3049
 
2509
3050
    def test_lock_write(self):
2535
3076
            client._calls)
2536
3077
 
2537
3078
 
 
3079
class TestRepositoryWriteGroups(TestRemoteRepository):
 
3080
 
 
3081
    def test_start_write_group(self):
 
3082
        transport_path = 'quack'
 
3083
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
3084
        client.add_expected_call(
 
3085
            'Repository.lock_write', ('quack/', ''),
 
3086
            'success', ('ok', 'a token'))
 
3087
        client.add_expected_call(
 
3088
            'Repository.start_write_group', ('quack/', 'a token'),
 
3089
            'success', ('ok', ('token1', )))
 
3090
        repo.lock_write()
 
3091
        repo.start_write_group()
 
3092
 
 
3093
    def test_start_write_group_unsuspendable(self):
 
3094
        # Some repositories do not support suspending write
 
3095
        # groups. For those, fall back to the "real" repository.
 
3096
        transport_path = 'quack'
 
3097
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
3098
        def stub_ensure_real():
 
3099
            client._calls.append(('_ensure_real',))
 
3100
            repo._real_repository = _StubRealPackRepository(client._calls)
 
3101
        repo._ensure_real = stub_ensure_real
 
3102
        client.add_expected_call(
 
3103
            'Repository.lock_write', ('quack/', ''),
 
3104
            'success', ('ok', 'a token'))
 
3105
        client.add_expected_call(
 
3106
            'Repository.start_write_group', ('quack/', 'a token'),
 
3107
            'error', ('UnsuspendableWriteGroup',))
 
3108
        repo.lock_write()
 
3109
        repo.start_write_group()
 
3110
        self.assertEquals(client._calls[-2:], [ 
 
3111
            ('_ensure_real',),
 
3112
            ('start_write_group',)])
 
3113
 
 
3114
    def test_commit_write_group(self):
 
3115
        transport_path = 'quack'
 
3116
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
3117
        client.add_expected_call(
 
3118
            'Repository.lock_write', ('quack/', ''),
 
3119
            'success', ('ok', 'a token'))
 
3120
        client.add_expected_call(
 
3121
            'Repository.start_write_group', ('quack/', 'a token'),
 
3122
            'success', ('ok', ['token1']))
 
3123
        client.add_expected_call(
 
3124
            'Repository.commit_write_group', ('quack/', 'a token', ['token1']),
 
3125
            'success', ('ok',))
 
3126
        repo.lock_write()
 
3127
        repo.start_write_group()
 
3128
        repo.commit_write_group()
 
3129
 
 
3130
    def test_abort_write_group(self):
 
3131
        transport_path = 'quack'
 
3132
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
3133
        client.add_expected_call(
 
3134
            'Repository.lock_write', ('quack/', ''),
 
3135
            'success', ('ok', 'a token'))
 
3136
        client.add_expected_call(
 
3137
            'Repository.start_write_group', ('quack/', 'a token'),
 
3138
            'success', ('ok', ['token1']))
 
3139
        client.add_expected_call(
 
3140
            'Repository.abort_write_group', ('quack/', 'a token', ['token1']),
 
3141
            'success', ('ok',))
 
3142
        repo.lock_write()
 
3143
        repo.start_write_group()
 
3144
        repo.abort_write_group(False)
 
3145
 
 
3146
    def test_suspend_write_group(self):
 
3147
        transport_path = 'quack'
 
3148
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
3149
        self.assertEquals([], repo.suspend_write_group())
 
3150
 
 
3151
    def test_resume_write_group(self):
 
3152
        transport_path = 'quack'
 
3153
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
3154
        client.add_expected_call(
 
3155
            'Repository.lock_write', ('quack/', ''),
 
3156
            'success', ('ok', 'a token'))
 
3157
        client.add_expected_call(
 
3158
            'Repository.check_write_group', ('quack/', 'a token', ['token1']),
 
3159
            'success', ('ok',))
 
3160
        repo.lock_write()
 
3161
        repo.resume_write_group(['token1'])
 
3162
 
 
3163
 
2538
3164
class TestRepositorySetMakeWorkingTrees(TestRemoteRepository):
2539
3165
 
2540
3166
    def test_backwards_compat(self):
2599
3225
        self.assertEqual([], client._calls)
2600
3226
 
2601
3227
 
 
3228
class TestRepositoryIterFilesBytes(TestRemoteRepository):
 
3229
    """Test Repository.iter_file_bytes."""
 
3230
 
 
3231
    def test_single(self):
 
3232
        transport_path = 'quack'
 
3233
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
3234
        client.add_expected_call(
 
3235
            'Repository.iter_files_bytes', ('quack/', ),
 
3236
            'success', ('ok',), iter(["ok\x000", "\n", zlib.compress("mydata" * 10)]))
 
3237
        for (identifier, byte_stream) in repo.iter_files_bytes([("somefile",
 
3238
                "somerev", "myid")]):
 
3239
            self.assertEquals("myid", identifier)
 
3240
            self.assertEquals("".join(byte_stream), "mydata" * 10)
 
3241
 
 
3242
    def test_missing(self):
 
3243
        transport_path = 'quack'
 
3244
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
3245
        client.add_expected_call(
 
3246
            'Repository.iter_files_bytes',
 
3247
                ('quack/', ),
 
3248
            'error', ('RevisionNotPresent', 'somefile', 'somerev'),
 
3249
            iter(["absent\0somefile\0somerev\n"]))
 
3250
        self.assertRaises(errors.RevisionNotPresent, list,
 
3251
                repo.iter_files_bytes(
 
3252
                [("somefile", "somerev", "myid")]))
 
3253
 
 
3254
 
2602
3255
class TestRepositoryInsertStreamBase(TestRemoteRepository):
2603
3256
    """Base class for Repository.insert_stream and .insert_stream_1.19
2604
3257
    tests.
2879
3532
        self.calls = calls
2880
3533
        self._pack_collection = _StubPackCollection(calls)
2881
3534
 
 
3535
    def start_write_group(self):
 
3536
        self.calls.append(('start_write_group',))
 
3537
 
2882
3538
    def is_in_write_group(self):
2883
3539
        return False
2884
3540
 
3322
3978
        revs = [r for (r,ps) in graph.iter_ancestry([tip])
3323
3979
                if r != NULL_REVISION]
3324
3980
        revs.reverse()
3325
 
        search = _mod_graph.PendingAncestryResult([tip], stacked.repository)
 
3981
        search = vf_search.PendingAncestryResult([tip], stacked.repository)
3326
3982
        self.reset_smart_call_log()
3327
3983
        stream = source.get_stream(search)
3328
3984
        # We trust that if a revision is in the stream the rest of the new
3434
4090
        self.hpss_calls = []
3435
4091
        local.repository.fetch(
3436
4092
            remote_branch.repository,
3437
 
            fetch_spec=_mod_graph.EverythingResult(remote_branch.repository))
 
4093
            fetch_spec=vf_search.EverythingResult(remote_branch.repository))
3438
4094
        self.assertEqual(['Repository.get_stream_1.19'], self.hpss_calls)
3439
4095
 
3440
4096
    def override_verb(self, verb_name, verb):
3441
4097
        request_handlers = request.request_handlers
3442
4098
        orig_verb = request_handlers.get(verb_name)
 
4099
        orig_info = request_handlers.get_info(verb_name)
3443
4100
        request_handlers.register(verb_name, verb, override_existing=True)
3444
4101
        self.addCleanup(request_handlers.register, verb_name, orig_verb,
3445
 
                override_existing=True)
 
4102
                override_existing=True, info=orig_info)
3446
4103
 
3447
4104
    def test_fetch_everything_backwards_compat(self):
3448
4105
        """Can fetch with EverythingResult even with pre 2.4 servers.
3473
4130
        self.hpss_calls = []
3474
4131
        local.repository.fetch(
3475
4132
            remote_branch.repository,
3476
 
            fetch_spec=_mod_graph.EverythingResult(remote_branch.repository))
 
4133
            fetch_spec=vf_search.EverythingResult(remote_branch.repository))
3477
4134
        # make sure the overridden verb was used
3478
4135
        self.assertLength(1, verb_log)
3479
4136
        # more than one HPSS call is needed, but because it's a VFS callback
3524
4181
        # interpretation
3525
4182
        self.make_master_and_checkout('mas~ter', 'checkout')
3526
4183
        self.assertUpdateSucceeds(self.bound_location.replace('%2E', '~', 1))
 
4184
 
 
4185
 
 
4186
class TestWithCustomErrorHandler(RemoteBranchTestCase):
 
4187
 
 
4188
    def test_no_context(self):
 
4189
        class OutOfCoffee(errors.BzrError):
 
4190
            """A dummy exception for testing."""
 
4191
 
 
4192
            def __init__(self, urgency):
 
4193
                self.urgency = urgency
 
4194
        remote.no_context_error_translators.register("OutOfCoffee",
 
4195
            lambda err: OutOfCoffee(err.error_args[0]))
 
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', ('OutOfCoffee', 'low'))
 
4205
        transport.mkdir('quack')
 
4206
        transport = transport.clone('quack')
 
4207
        branch = self.make_remote_branch(transport, client)
 
4208
        self.assertRaises(OutOfCoffee, branch.last_revision_info)
 
4209
        self.assertFinished(client)
 
4210
 
 
4211
    def test_with_context(self):
 
4212
        class OutOfTea(errors.BzrError):
 
4213
            def __init__(self, branch, urgency):
 
4214
                self.branch = branch
 
4215
                self.urgency = urgency
 
4216
        remote.error_translators.register("OutOfTea",
 
4217
            lambda err, find, path: OutOfTea(err.error_args[0],
 
4218
                find("branch")))
 
4219
        transport = MemoryTransport()
 
4220
        client = FakeClient(transport.base)
 
4221
        client.add_expected_call(
 
4222
            'Branch.get_stacked_on_url', ('quack/',),
 
4223
            'error', ('NotStacked',))
 
4224
        client.add_expected_call(
 
4225
            'Branch.last_revision_info',
 
4226
            ('quack/',),
 
4227
            'error', ('OutOfTea', 'low'))
 
4228
        transport.mkdir('quack')
 
4229
        transport = transport.clone('quack')
 
4230
        branch = self.make_remote_branch(transport, client)
 
4231
        self.assertRaises(OutOfTea, branch.last_revision_info)
 
4232
        self.assertFinished(client)
 
4233
 
 
4234
 
 
4235
class TestRepositoryPack(TestRemoteRepository):
 
4236
 
 
4237
    def test_pack(self):
 
4238
        transport_path = 'quack'
 
4239
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
4240
        client.add_expected_call(
 
4241
            'Repository.lock_write', ('quack/', ''),
 
4242
            'success', ('ok', 'token'))
 
4243
        client.add_expected_call(
 
4244
            'Repository.pack', ('quack/', 'token', 'False'),
 
4245
            'success', ('ok',), )
 
4246
        client.add_expected_call(
 
4247
            'Repository.unlock', ('quack/', 'token'),
 
4248
            'success', ('ok', ))
 
4249
        repo.pack()
 
4250
 
 
4251
    def test_pack_with_hint(self):
 
4252
        transport_path = 'quack'
 
4253
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
4254
        client.add_expected_call(
 
4255
            'Repository.lock_write', ('quack/', ''),
 
4256
            'success', ('ok', 'token'))
 
4257
        client.add_expected_call(
 
4258
            'Repository.pack', ('quack/', 'token', 'False'),
 
4259
            'success', ('ok',), )
 
4260
        client.add_expected_call(
 
4261
            'Repository.unlock', ('quack/', 'token', 'False'),
 
4262
            'success', ('ok', ))
 
4263
        repo.pack(['hinta', 'hintb'])
 
4264
 
 
4265
 
 
4266
class TestRepositoryIterInventories(TestRemoteRepository):
 
4267
    """Test Repository.iter_inventories."""
 
4268
 
 
4269
    def _serialize_inv_delta(self, old_name, new_name, delta):
 
4270
        serializer = inventory_delta.InventoryDeltaSerializer(True, False)
 
4271
        return "".join(serializer.delta_to_lines(old_name, new_name, delta))
 
4272
 
 
4273
    def test_single_empty(self):
 
4274
        transport_path = 'quack'
 
4275
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
4276
        fmt = bzrdir.format_registry.get('2a')().repository_format
 
4277
        repo._format = fmt
 
4278
        stream = [('inventory-deltas', [
 
4279
            versionedfile.FulltextContentFactory('somerevid', None, None,
 
4280
                self._serialize_inv_delta('null:', 'somerevid', []))])]
 
4281
        client.add_expected_call(
 
4282
            'VersionedFileRepository.get_inventories', ('quack/', 'unordered'),
 
4283
            'success', ('ok', ),
 
4284
            _stream_to_byte_stream(stream, fmt))
 
4285
        ret = list(repo.iter_inventories(["somerevid"]))
 
4286
        self.assertLength(1, ret)
 
4287
        inv = ret[0]
 
4288
        self.assertEquals("somerevid", inv.revision_id)
 
4289
 
 
4290
    def test_empty(self):
 
4291
        transport_path = 'quack'
 
4292
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
4293
        ret = list(repo.iter_inventories([]))
 
4294
        self.assertEquals(ret, [])
 
4295
 
 
4296
    def test_missing(self):
 
4297
        transport_path = 'quack'
 
4298
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
4299
        client.add_expected_call(
 
4300
            'VersionedFileRepository.get_inventories', ('quack/', 'unordered'),
 
4301
            'success', ('ok', ), iter([]))
 
4302
        self.assertRaises(errors.NoSuchRevision, list, repo.iter_inventories(
 
4303
            ["somerevid"]))