~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_remote.py

  • Committer: Jelmer Vernooij
  • Date: 2011-12-16 19:18:39 UTC
  • mto: This revision was merged to the branch mainline in revision 6391.
  • Revision ID: jelmer@samba.org-20111216191839-eg681lxqibi1qxu1
Fix remaining tests.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006-2010 Canonical Ltd
 
1
# Copyright (C) 2006-2011 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 (
30
31
    branch,
32
33
    config,
33
34
    controldir,
34
35
    errors,
35
 
    graph,
 
36
    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,
54
57
    RemoteBzrDir,
 
58
    RemoteBzrDirFormat,
55
59
    RemoteRepository,
56
60
    RemoteRepositoryFormat,
57
61
    )
58
 
from bzrlib.repofmt import groupcompress_repo, pack_repo
59
 
from bzrlib.revision import NULL_REVISION
60
 
from bzrlib.smart import medium
 
62
from bzrlib.repofmt import groupcompress_repo, knitpack_repo
 
63
from bzrlib.revision import (
 
64
    NULL_REVISION,
 
65
    Revision,
 
66
    )
 
67
from bzrlib.smart import medium, request
61
68
from bzrlib.smart.client import _SmartClient
62
 
from bzrlib.smart.repository import SmartServerRepositoryGetParentMap
 
69
from bzrlib.smart.repository import (
 
70
    SmartServerRepositoryGetParentMap,
 
71
    SmartServerRepositoryGetStream_1_19,
 
72
    _stream_to_byte_stream,
 
73
    )
 
74
from bzrlib.symbol_versioning import deprecated_in
63
75
from bzrlib.tests import (
64
 
    condition_isinstance,
65
 
    split_suite_by_condition,
66
 
    multiply_tests,
67
76
    test_server,
68
77
    )
 
78
from bzrlib.tests.scenarios import load_tests_apply_scenarios
69
79
from bzrlib.transport.memory import MemoryTransport
70
80
from bzrlib.transport.remote import (
71
81
    RemoteTransport,
72
82
    RemoteSSHTransport,
73
83
    RemoteTCPTransport,
74
 
)
75
 
 
76
 
def load_tests(standard_tests, module, loader):
77
 
    to_adapt, result = split_suite_by_condition(
78
 
        standard_tests, condition_isinstance(BasicRemoteObjectTests))
79
 
    smart_server_version_scenarios = [
 
84
    )
 
85
 
 
86
 
 
87
load_tests = load_tests_apply_scenarios
 
88
 
 
89
 
 
90
class BasicRemoteObjectTests(tests.TestCaseWithTransport):
 
91
 
 
92
    scenarios = [
80
93
        ('HPSS-v2',
81
 
         {'transport_server': test_server.SmartTCPServer_for_testing_v2_only}),
 
94
            {'transport_server': test_server.SmartTCPServer_for_testing_v2_only}),
82
95
        ('HPSS-v3',
83
 
         {'transport_server': test_server.SmartTCPServer_for_testing})]
84
 
    return multiply_tests(to_adapt, smart_server_version_scenarios, result)
85
 
 
86
 
 
87
 
class BasicRemoteObjectTests(tests.TestCaseWithTransport):
 
96
            {'transport_server': test_server.SmartTCPServer_for_testing})]
 
97
 
88
98
 
89
99
    def setUp(self):
90
100
        super(BasicRemoteObjectTests, self).setUp()
94
104
        self.addCleanup(self.transport.disconnect)
95
105
 
96
106
    def test_create_remote_bzrdir(self):
97
 
        b = remote.RemoteBzrDir(self.transport, remote.RemoteBzrDirFormat())
 
107
        b = remote.RemoteBzrDir(self.transport, RemoteBzrDirFormat())
98
108
        self.assertIsInstance(b, BzrDir)
99
109
 
100
110
    def test_open_remote_branch(self):
101
111
        # open a standalone branch in the working directory
102
 
        b = remote.RemoteBzrDir(self.transport, remote.RemoteBzrDirFormat())
 
112
        b = remote.RemoteBzrDir(self.transport, RemoteBzrDirFormat())
103
113
        branch = b.open_branch()
104
114
        self.assertIsInstance(branch, Branch)
105
115
 
113
123
 
114
124
    def test_remote_branch_revision_history(self):
115
125
        b = BzrDir.open_from_transport(self.transport).open_branch()
116
 
        self.assertEqual([], b.revision_history())
 
126
        self.assertEqual([],
 
127
            self.applyDeprecated(deprecated_in((2, 5, 0)), b.revision_history))
117
128
        r1 = self.local_wt.commit('1st commit')
118
129
        r2 = self.local_wt.commit('1st commit', rev_id=u'\xc8'.encode('utf8'))
119
 
        self.assertEqual([r1, r2], b.revision_history())
 
130
        self.assertEqual([r1, r2],
 
131
            self.applyDeprecated(deprecated_in((2, 5, 0)), b.revision_history))
120
132
 
121
133
    def test_find_correct_format(self):
122
134
        """Should open a RemoteBzrDir over a RemoteTransport"""
123
135
        fmt = BzrDirFormat.find_format(self.transport)
124
136
        self.assertTrue(bzrdir.RemoteBzrProber
125
137
                        in controldir.ControlDirFormat._server_probers)
126
 
        self.assertIsInstance(fmt, remote.RemoteBzrDirFormat)
 
138
        self.assertIsInstance(fmt, RemoteBzrDirFormat)
127
139
 
128
140
    def test_open_detected_smart_format(self):
129
141
        fmt = BzrDirFormat.find_format(self.transport)
163
175
    def test_remote_branch_set_append_revisions_only(self):
164
176
        # Make a format 1.9 branch, which supports append_revisions_only
165
177
        branch = self.make_branch('branch', format='1.9')
166
 
        config = branch.get_config()
167
178
        branch.set_append_revisions_only(True)
 
179
        config = branch.get_config_stack()
168
180
        self.assertEqual(
169
 
            'True', config.get_user_option('append_revisions_only'))
 
181
            True, config.get('append_revisions_only'))
170
182
        branch.set_append_revisions_only(False)
 
183
        config = branch.get_config_stack()
171
184
        self.assertEqual(
172
 
            'False', config.get_user_option('append_revisions_only'))
 
185
            False, config.get('append_revisions_only'))
173
186
 
174
187
    def test_remote_branch_set_append_revisions_only_upgrade_reqd(self):
175
188
        branch = self.make_branch('branch', format='knit')
176
 
        config = branch.get_config()
177
189
        self.assertRaises(
178
190
            errors.UpgradeRequired, branch.set_append_revisions_only, True)
179
191
 
449
461
        client.add_expected_call(
450
462
            'BzrDir.open_branchV3', ('quack/',),
451
463
            'success', ('ref', self.get_url('referenced'))),
452
 
        a_bzrdir = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
 
464
        a_bzrdir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
453
465
            _client=client)
454
466
        result = a_bzrdir.cloning_metadir()
455
467
        # We should have got a control dir matching the referenced branch.
468
480
        client.add_expected_call(
469
481
            'BzrDir.cloning_metadir', ('quack/', 'False'),
470
482
            'success', (control_name, '', ('branch', ''))),
471
 
        a_bzrdir = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
 
483
        a_bzrdir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
472
484
            _client=client)
473
485
        result = a_bzrdir.cloning_metadir()
474
486
        # We should have got a reference control dir with default branch and
479
491
        self.assertEqual(None, result._branch_format)
480
492
        self.assertFinished(client)
481
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
 
482
609
 
483
610
class TestBzrDirOpen(TestRemote):
484
611
 
494
621
        client.add_expected_call(
495
622
            'BzrDir.open_2.1', ('quack/',), 'success', ('no',))
496
623
        self.assertRaises(errors.NotBranchError, RemoteBzrDir, transport,
497
 
                remote.RemoteBzrDirFormat(), _client=client, _force_probe=True)
 
624
                RemoteBzrDirFormat(), _client=client, _force_probe=True)
498
625
        self.assertFinished(client)
499
626
 
500
627
    def test_present_without_workingtree(self):
501
628
        client, transport = self.make_fake_client_and_transport()
502
629
        client.add_expected_call(
503
630
            'BzrDir.open_2.1', ('quack/',), 'success', ('yes', 'no'))
504
 
        bd = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
 
631
        bd = RemoteBzrDir(transport, RemoteBzrDirFormat(),
505
632
            _client=client, _force_probe=True)
506
633
        self.assertIsInstance(bd, RemoteBzrDir)
507
634
        self.assertFalse(bd.has_workingtree())
512
639
        client, transport = self.make_fake_client_and_transport()
513
640
        client.add_expected_call(
514
641
            'BzrDir.open_2.1', ('quack/',), 'success', ('yes', 'yes'))
515
 
        bd = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
 
642
        bd = RemoteBzrDir(transport, RemoteBzrDirFormat(),
516
643
            _client=client, _force_probe=True)
517
644
        self.assertIsInstance(bd, RemoteBzrDir)
518
645
        self.assertTrue(bd.has_workingtree())
525
652
            'BzrDir.open_2.1', ('quack/',), 'unknown', ('BzrDir.open_2.1',))
526
653
        client.add_expected_call(
527
654
            'BzrDir.open', ('quack/',), 'success', ('yes',))
528
 
        bd = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
 
655
        bd = RemoteBzrDir(transport, RemoteBzrDirFormat(),
529
656
            _client=client, _force_probe=True)
530
657
        self.assertIsInstance(bd, RemoteBzrDir)
531
658
        self.assertFinished(client)
547
674
            'BzrDir.open_2.1', ('quack/',), 'unknown', ('BzrDir.open_2.1',))
548
675
        client.add_expected_call(
549
676
            'BzrDir.open', ('quack/',), 'success', ('yes',))
550
 
        bd = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
 
677
        bd = RemoteBzrDir(transport, RemoteBzrDirFormat(),
551
678
            _client=client, _force_probe=True)
552
679
        self.assertIsInstance(bd, RemoteBzrDir)
553
680
        self.assertFinished(client)
584
711
        client.add_expected_call(
585
712
            'Branch.get_stacked_on_url', ('quack/',),
586
713
            'error', ('NotStacked',))
587
 
        bzrdir = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
 
714
        bzrdir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
588
715
            _client=client)
589
716
        result = bzrdir.open_branch()
590
717
        self.assertIsInstance(result, RemoteBranch)
597
724
        transport = transport.clone('quack')
598
725
        client = FakeClient(transport.base)
599
726
        client.add_error_response('nobranch')
600
 
        bzrdir = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
 
727
        bzrdir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
601
728
            _client=client)
602
729
        self.assertRaises(errors.NotBranchError, bzrdir.open_branch)
603
730
        self.assertEqual(
608
735
        # _get_tree_branch is a form of open_branch, but it should only ask for
609
736
        # branch opening, not any other network requests.
610
737
        calls = []
611
 
        def open_branch(name=None):
 
738
        def open_branch(name=None, possible_transports=None):
612
739
            calls.append("Called")
613
740
            return "a-branch"
614
741
        transport = MemoryTransport()
615
742
        # no requests on the network - catches other api calls being made.
616
743
        client = FakeClient(transport.base)
617
 
        bzrdir = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
 
744
        bzrdir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
618
745
            _client=client)
619
746
        # patch the open_branch call to record that it was called.
620
747
        bzrdir.open_branch = open_branch
639
766
        client.add_expected_call(
640
767
            'Branch.get_stacked_on_url', ('~hello/',),
641
768
            'error', ('NotStacked',))
642
 
        bzrdir = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
 
769
        bzrdir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
643
770
            _client=client)
644
771
        result = bzrdir.open_branch()
645
772
        self.assertFinished(client)
662
789
        client.add_success_response(
663
790
            'ok', '', rich_response, subtree_response, external_lookup,
664
791
            network_name)
665
 
        bzrdir = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
 
792
        bzrdir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
666
793
            _client=client)
667
794
        result = bzrdir.open_repository()
668
795
        self.assertEqual(
714
841
            'BzrDir.create_branch', ('quack/', network_name),
715
842
            'success', ('ok', network_name, '', 'no', 'no', 'yes',
716
843
            reference_repo_name))
717
 
        a_bzrdir = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
 
844
        a_bzrdir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
718
845
            _client=client)
719
846
        branch = a_bzrdir.create_branch()
720
847
        # We should have got a remote branch
723
850
        format = branch._format
724
851
        self.assertEqual(network_name, format.network_name())
725
852
 
 
853
    def test_already_open_repo_and_reused_medium(self):
 
854
        """Bug 726584: create_branch(..., repository=repo) should work
 
855
        regardless of what the smart medium's base URL is.
 
856
        """
 
857
        self.transport_server = test_server.SmartTCPServer_for_testing
 
858
        transport = self.get_transport('.')
 
859
        repo = self.make_repository('quack')
 
860
        # Client's medium rooted a transport root (not at the bzrdir)
 
861
        client = FakeClient(transport.base)
 
862
        transport = transport.clone('quack')
 
863
        reference_bzrdir_format = bzrdir.format_registry.get('default')()
 
864
        reference_format = reference_bzrdir_format.get_branch_format()
 
865
        network_name = reference_format.network_name()
 
866
        reference_repo_fmt = reference_bzrdir_format.repository_format
 
867
        reference_repo_name = reference_repo_fmt.network_name()
 
868
        client.add_expected_call(
 
869
            'BzrDir.create_branch', ('extra/quack/', network_name),
 
870
            'success', ('ok', network_name, '', 'no', 'no', 'yes',
 
871
            reference_repo_name))
 
872
        a_bzrdir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
 
873
            _client=client)
 
874
        branch = a_bzrdir.create_branch(repository=repo)
 
875
        # We should have got a remote branch
 
876
        self.assertIsInstance(branch, remote.RemoteBranch)
 
877
        # its format should have the settings from the response
 
878
        format = branch._format
 
879
        self.assertEqual(network_name, format.network_name())
 
880
 
726
881
 
727
882
class TestBzrDirCreateRepository(TestRemote):
728
883
 
749
904
                'Bazaar repository format 2a (needs bzr 1.16 or later)\n',
750
905
                'False'),
751
906
            'success', ('ok', 'yes', 'yes', 'yes', network_name))
752
 
        a_bzrdir = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
 
907
        a_bzrdir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
753
908
            _client=client)
754
909
        repo = a_bzrdir.create_repository()
755
910
        # We should have got a remote repository
784
939
        client.add_success_response('stat', '0', '65535')
785
940
        remote_transport = RemoteTransport(server_url + 'quack/', medium=False,
786
941
            _client=client)
787
 
        bzrdir = RemoteBzrDir(remote_transport, remote.RemoteBzrDirFormat(),
 
942
        bzrdir = RemoteBzrDir(remote_transport, RemoteBzrDirFormat(),
788
943
            _client=client)
789
944
        repo = bzrdir.open_repository()
790
945
        self.assertEqual(
817
972
        client.add_success_response('stat', '0', '65535')
818
973
        remote_transport = RemoteTransport(server_url + 'quack/', medium=False,
819
974
            _client=client)
820
 
        bzrdir = RemoteBzrDir(remote_transport, remote.RemoteBzrDirFormat(),
 
975
        bzrdir = RemoteBzrDir(remote_transport, RemoteBzrDirFormat(),
821
976
            _client=client)
822
977
        repo = bzrdir.open_repository()
823
978
        self.assertEqual(
838
993
        transport = transport.clone('quack')
839
994
        client = FakeClient(transport.base)
840
995
        client.add_success_response('ok', '', 'no', 'no', 'no', network_name)
841
 
        bzrdir = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
 
996
        bzrdir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
842
997
            _client=client)
843
998
        repo = bzrdir.open_repository()
844
999
        self.assertEqual(
851
1006
 
852
1007
    def test_success(self):
853
1008
        """Simple test for typical successful call."""
854
 
        fmt = bzrdir.RemoteBzrDirFormat()
 
1009
        fmt = RemoteBzrDirFormat()
855
1010
        default_format_name = BzrDirFormat.get_default_format().network_name()
856
1011
        transport = self.get_transport()
857
1012
        client = FakeClient(transport.base)
873
1028
        """Error responses are translated, e.g. 'PermissionDenied' raises the
874
1029
        corresponding error from the client.
875
1030
        """
876
 
        fmt = bzrdir.RemoteBzrDirFormat()
 
1031
        fmt = RemoteBzrDirFormat()
877
1032
        default_format_name = BzrDirFormat.get_default_format().network_name()
878
1033
        transport = self.get_transport()
879
1034
        client = FakeClient(transport.base)
897
1052
        """Integration test for error translation."""
898
1053
        transport = self.make_smart_server('foo')
899
1054
        transport = transport.clone('no-such-path')
900
 
        fmt = bzrdir.RemoteBzrDirFormat()
 
1055
        fmt = RemoteBzrDirFormat()
901
1056
        err = self.assertRaises(errors.NoSuchFile,
902
1057
            fmt.initialize_on_transport_ex, transport, create_prefix=False)
903
1058
 
934
1089
 
935
1090
    def make_remote_bzrdir(self, transport, client):
936
1091
        """Make a RemotebzrDir using 'client' as the _client."""
937
 
        return RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
 
1092
        return RemoteBzrDir(transport, RemoteBzrDirFormat(),
938
1093
            _client=client)
939
1094
 
940
1095
 
966
1121
        return RemoteBranch(bzrdir, repo, _client=client, format=format)
967
1122
 
968
1123
 
 
1124
class TestBranchBreakLock(RemoteBranchTestCase):
 
1125
 
 
1126
    def test_break_lock(self):
 
1127
        transport_path = 'quack'
 
1128
        transport = MemoryTransport()
 
1129
        client = FakeClient(transport.base)
 
1130
        client.add_expected_call(
 
1131
            'Branch.get_stacked_on_url', ('quack/',),
 
1132
            'error', ('NotStacked',))
 
1133
        client.add_expected_call(
 
1134
            'Branch.break_lock', ('quack/',),
 
1135
            'success', ('ok',))
 
1136
        transport.mkdir('quack')
 
1137
        transport = transport.clone('quack')
 
1138
        branch = self.make_remote_branch(transport, client)
 
1139
        branch.break_lock()
 
1140
        self.assertFinished(client)
 
1141
 
 
1142
 
 
1143
class TestBranchGetPhysicalLockStatus(RemoteBranchTestCase):
 
1144
 
 
1145
    def test_get_physical_lock_status_yes(self):
 
1146
        transport = MemoryTransport()
 
1147
        client = FakeClient(transport.base)
 
1148
        client.add_expected_call(
 
1149
            'Branch.get_stacked_on_url', ('quack/',),
 
1150
            'error', ('NotStacked',))
 
1151
        client.add_expected_call(
 
1152
            'Branch.get_physical_lock_status', ('quack/',),
 
1153
            'success', ('yes',))
 
1154
        transport.mkdir('quack')
 
1155
        transport = transport.clone('quack')
 
1156
        branch = self.make_remote_branch(transport, client)
 
1157
        result = branch.get_physical_lock_status()
 
1158
        self.assertFinished(client)
 
1159
        self.assertEqual(True, result)
 
1160
 
 
1161
    def test_get_physical_lock_status_no(self):
 
1162
        transport = MemoryTransport()
 
1163
        client = FakeClient(transport.base)
 
1164
        client.add_expected_call(
 
1165
            'Branch.get_stacked_on_url', ('quack/',),
 
1166
            'error', ('NotStacked',))
 
1167
        client.add_expected_call(
 
1168
            'Branch.get_physical_lock_status', ('quack/',),
 
1169
            'success', ('no',))
 
1170
        transport.mkdir('quack')
 
1171
        transport = transport.clone('quack')
 
1172
        branch = self.make_remote_branch(transport, client)
 
1173
        result = branch.get_physical_lock_status()
 
1174
        self.assertFinished(client)
 
1175
        self.assertEqual(False, result)
 
1176
 
 
1177
 
969
1178
class TestBranchGetParent(RemoteBranchTestCase):
970
1179
 
971
1180
    def test_no_parent(self):
1142
1351
            [('set_tags_bytes', 'tags bytes')] * 2, real_branch.calls)
1143
1352
 
1144
1353
 
 
1354
class TestBranchHeadsToFetch(RemoteBranchTestCase):
 
1355
 
 
1356
    def test_uses_last_revision_info_and_tags_by_default(self):
 
1357
        transport = MemoryTransport()
 
1358
        client = FakeClient(transport.base)
 
1359
        client.add_expected_call(
 
1360
            'Branch.get_stacked_on_url', ('quack/',),
 
1361
            'error', ('NotStacked',))
 
1362
        client.add_expected_call(
 
1363
            'Branch.last_revision_info', ('quack/',),
 
1364
            'success', ('ok', '1', 'rev-tip'))
 
1365
        client.add_expected_call(
 
1366
            'Branch.get_config_file', ('quack/',),
 
1367
            'success', ('ok',), '')
 
1368
        transport.mkdir('quack')
 
1369
        transport = transport.clone('quack')
 
1370
        branch = self.make_remote_branch(transport, client)
 
1371
        result = branch.heads_to_fetch()
 
1372
        self.assertFinished(client)
 
1373
        self.assertEqual((set(['rev-tip']), set()), result)
 
1374
 
 
1375
    def test_uses_last_revision_info_and_tags_when_set(self):
 
1376
        transport = MemoryTransport()
 
1377
        client = FakeClient(transport.base)
 
1378
        client.add_expected_call(
 
1379
            'Branch.get_stacked_on_url', ('quack/',),
 
1380
            'error', ('NotStacked',))
 
1381
        client.add_expected_call(
 
1382
            'Branch.last_revision_info', ('quack/',),
 
1383
            'success', ('ok', '1', 'rev-tip'))
 
1384
        client.add_expected_call(
 
1385
            'Branch.get_config_file', ('quack/',),
 
1386
            'success', ('ok',), 'branch.fetch_tags = True')
 
1387
        # XXX: this will break if the default format's serialization of tags
 
1388
        # changes, or if the RPC for fetching tags changes from get_tags_bytes.
 
1389
        client.add_expected_call(
 
1390
            'Branch.get_tags_bytes', ('quack/',),
 
1391
            'success', ('d5:tag-17:rev-foo5:tag-27:rev-bare',))
 
1392
        transport.mkdir('quack')
 
1393
        transport = transport.clone('quack')
 
1394
        branch = self.make_remote_branch(transport, client)
 
1395
        result = branch.heads_to_fetch()
 
1396
        self.assertFinished(client)
 
1397
        self.assertEqual(
 
1398
            (set(['rev-tip']), set(['rev-foo', 'rev-bar'])), result)
 
1399
 
 
1400
    def test_uses_rpc_for_formats_with_non_default_heads_to_fetch(self):
 
1401
        transport = MemoryTransport()
 
1402
        client = FakeClient(transport.base)
 
1403
        client.add_expected_call(
 
1404
            'Branch.get_stacked_on_url', ('quack/',),
 
1405
            'error', ('NotStacked',))
 
1406
        client.add_expected_call(
 
1407
            'Branch.heads_to_fetch', ('quack/',),
 
1408
            'success', (['tip'], ['tagged-1', 'tagged-2']))
 
1409
        transport.mkdir('quack')
 
1410
        transport = transport.clone('quack')
 
1411
        branch = self.make_remote_branch(transport, client)
 
1412
        branch._format._use_default_local_heads_to_fetch = lambda: False
 
1413
        result = branch.heads_to_fetch()
 
1414
        self.assertFinished(client)
 
1415
        self.assertEqual((set(['tip']), set(['tagged-1', 'tagged-2'])), result)
 
1416
 
 
1417
    def make_branch_with_tags(self):
 
1418
        self.setup_smart_server_with_call_log()
 
1419
        # Make a branch with a single revision.
 
1420
        builder = self.make_branch_builder('foo')
 
1421
        builder.start_series()
 
1422
        builder.build_snapshot('tip', None, [
 
1423
            ('add', ('', 'root-id', 'directory', ''))])
 
1424
        builder.finish_series()
 
1425
        branch = builder.get_branch()
 
1426
        # Add two tags to that branch
 
1427
        branch.tags.set_tag('tag-1', 'rev-1')
 
1428
        branch.tags.set_tag('tag-2', 'rev-2')
 
1429
        return branch
 
1430
 
 
1431
    def test_backwards_compatible(self):
 
1432
        branch = self.make_branch_with_tags()
 
1433
        c = branch.get_config()
 
1434
        c.set_user_option('branch.fetch_tags', 'True')
 
1435
        self.addCleanup(branch.lock_read().unlock)
 
1436
        # Disable the heads_to_fetch verb
 
1437
        verb = 'Branch.heads_to_fetch'
 
1438
        self.disable_verb(verb)
 
1439
        self.reset_smart_call_log()
 
1440
        result = branch.heads_to_fetch()
 
1441
        self.assertEqual((set(['tip']), set(['rev-1', 'rev-2'])), result)
 
1442
        self.assertEqual(
 
1443
            ['Branch.last_revision_info', 'Branch.get_config_file',
 
1444
             'Branch.get_tags_bytes'],
 
1445
            [call.call.method for call in self.hpss_calls])
 
1446
 
 
1447
    def test_backwards_compatible_no_tags(self):
 
1448
        branch = self.make_branch_with_tags()
 
1449
        c = branch.get_config()
 
1450
        c.set_user_option('branch.fetch_tags', 'False')
 
1451
        self.addCleanup(branch.lock_read().unlock)
 
1452
        # Disable the heads_to_fetch verb
 
1453
        verb = 'Branch.heads_to_fetch'
 
1454
        self.disable_verb(verb)
 
1455
        self.reset_smart_call_log()
 
1456
        result = branch.heads_to_fetch()
 
1457
        self.assertEqual((set(['tip']), set()), result)
 
1458
        self.assertEqual(
 
1459
            ['Branch.last_revision_info', 'Branch.get_config_file'],
 
1460
            [call.call.method for call in self.hpss_calls])
 
1461
 
 
1462
 
1145
1463
class TestBranchLastRevisionInfo(RemoteBranchTestCase):
1146
1464
 
1147
1465
    def test_empty_branch(self):
1202
1520
        client.add_expected_call(
1203
1521
            'Branch.get_stacked_on_url', ('stacked/',),
1204
1522
            'success', ('ok', vfs_url))
1205
 
        bzrdir = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
 
1523
        bzrdir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
1206
1524
            _client=client)
1207
1525
        repo_fmt = remote.RemoteRepositoryFormat()
1208
1526
        repo_fmt._custom_format = stacked_branch.repository._format
1235
1553
        # this will also do vfs access, but that goes direct to the transport
1236
1554
        # and isn't seen by the FakeClient.
1237
1555
        bzrdir = RemoteBzrDir(self.get_transport('stacked'),
1238
 
            remote.RemoteBzrDirFormat(), _client=client)
 
1556
            RemoteBzrDirFormat(), _client=client)
1239
1557
        branch = bzrdir.open_branch()
1240
1558
        result = branch.get_stacked_on_url()
1241
1559
        self.assertEqual('../base', result)
1268
1586
            'Branch.get_stacked_on_url', ('stacked/',),
1269
1587
            'success', ('ok', '../base'))
1270
1588
        bzrdir = RemoteBzrDir(self.get_transport('stacked'),
1271
 
            remote.RemoteBzrDirFormat(), _client=client)
 
1589
            RemoteBzrDirFormat(), _client=client)
1272
1590
        branch = bzrdir.open_branch()
1273
1591
        result = branch.get_stacked_on_url()
1274
1592
        self.assertEqual('../base', result)
1282
1600
class TestBranchSetLastRevision(RemoteBranchTestCase):
1283
1601
 
1284
1602
    def test_set_empty(self):
1285
 
        # set_revision_history([]) is translated to calling
 
1603
        # _set_last_revision_info('null:') is translated to calling
1286
1604
        # Branch.set_last_revision(path, '') on the wire.
1287
1605
        transport = MemoryTransport()
1288
1606
        transport.mkdir('branch')
1306
1624
            'Branch.unlock', ('branch/', 'branch token', 'repo token'),
1307
1625
            'success', ('ok',))
1308
1626
        branch = self.make_remote_branch(transport, client)
1309
 
        # This is a hack to work around the problem that RemoteBranch currently
1310
 
        # unnecessarily invokes _ensure_real upon a call to lock_write.
1311
 
        branch._ensure_real = lambda: None
1312
1627
        branch.lock_write()
1313
 
        result = branch.set_revision_history([])
 
1628
        result = branch._set_last_revision(NULL_REVISION)
1314
1629
        branch.unlock()
1315
1630
        self.assertEqual(None, result)
1316
1631
        self.assertFinished(client)
1317
1632
 
1318
1633
    def test_set_nonempty(self):
1319
 
        # set_revision_history([rev-id1, ..., rev-idN]) is translated to calling
 
1634
        # set_last_revision_info(N, rev-idN) is translated to calling
1320
1635
        # Branch.set_last_revision(path, rev-idN) on the wire.
1321
1636
        transport = MemoryTransport()
1322
1637
        transport.mkdir('branch')
1343
1658
            'Branch.unlock', ('branch/', 'branch token', 'repo token'),
1344
1659
            'success', ('ok',))
1345
1660
        branch = self.make_remote_branch(transport, client)
1346
 
        # This is a hack to work around the problem that RemoteBranch currently
1347
 
        # unnecessarily invokes _ensure_real upon a call to lock_write.
1348
 
        branch._ensure_real = lambda: None
1349
1661
        # Lock the branch, reset the record of remote calls.
1350
1662
        branch.lock_write()
1351
 
        result = branch.set_revision_history(['rev-id1', 'rev-id2'])
 
1663
        result = branch._set_last_revision('rev-id2')
1352
1664
        branch.unlock()
1353
1665
        self.assertEqual(None, result)
1354
1666
        self.assertFinished(client)
1384
1696
        branch = self.make_remote_branch(transport, client)
1385
1697
        branch.lock_write()
1386
1698
        self.assertRaises(
1387
 
            errors.NoSuchRevision, branch.set_revision_history, ['rev-id'])
 
1699
            errors.NoSuchRevision, branch._set_last_revision, 'rev-id')
1388
1700
        branch.unlock()
1389
1701
        self.assertFinished(client)
1390
1702
 
1418
1730
            'Branch.unlock', ('branch/', 'branch token', 'repo token'),
1419
1731
            'success', ('ok',))
1420
1732
        branch = self.make_remote_branch(transport, client)
1421
 
        branch._ensure_real = lambda: None
1422
1733
        branch.lock_write()
1423
1734
        # The 'TipChangeRejected' error response triggered by calling
1424
 
        # set_revision_history causes a TipChangeRejected exception.
 
1735
        # set_last_revision_info causes a TipChangeRejected exception.
1425
1736
        err = self.assertRaises(
1426
 
            errors.TipChangeRejected, branch.set_revision_history, ['rev-id'])
 
1737
            errors.TipChangeRejected,
 
1738
            branch._set_last_revision, 'rev-id')
1427
1739
        # The UTF-8 message from the response has been decoded into a unicode
1428
1740
        # object.
1429
1741
        self.assertIsInstance(err.msg, unicode)
1704
2016
        self.assertEqual(value_dict, branch._get_config().get_option('name'))
1705
2017
 
1706
2018
 
 
2019
class TestBranchGetPutConfigStore(RemoteBranchTestCase):
 
2020
 
 
2021
    def test_get_branch_conf(self):
 
2022
        # in an empty branch we decode the response properly
 
2023
        client = FakeClient()
 
2024
        client.add_expected_call(
 
2025
            'Branch.get_stacked_on_url', ('memory:///',),
 
2026
            'error', ('NotStacked',),)
 
2027
        client.add_success_response_with_body('# config file body', 'ok')
 
2028
        transport = MemoryTransport()
 
2029
        branch = self.make_remote_branch(transport, client)
 
2030
        config = branch.get_config_stack()
 
2031
        config.get("email")
 
2032
        config.get("log_format")
 
2033
        self.assertEqual(
 
2034
            [('call', 'Branch.get_stacked_on_url', ('memory:///',)),
 
2035
             ('call_expecting_body', 'Branch.get_config_file', ('memory:///',))],
 
2036
            client._calls)
 
2037
 
 
2038
    def test_set_branch_conf(self):
 
2039
        client = FakeClient()
 
2040
        client.add_expected_call(
 
2041
            'Branch.get_stacked_on_url', ('memory:///',),
 
2042
            'error', ('NotStacked',),)
 
2043
        client.add_expected_call(
 
2044
            'Branch.lock_write', ('memory:///', '', ''),
 
2045
            'success', ('ok', 'branch token', 'repo token'))
 
2046
        client.add_expected_call(
 
2047
            'Branch.get_config_file', ('memory:///', ),
 
2048
            'success', ('ok', ), "# line 1\n")
 
2049
        client.add_expected_call(
 
2050
            'Branch.put_config_file', ('memory:///', 'branch token',
 
2051
            'repo token'),
 
2052
            'success', ('ok',))
 
2053
        client.add_expected_call(
 
2054
            'Branch.unlock', ('memory:///', 'branch token', 'repo token'),
 
2055
            'success', ('ok',))
 
2056
        transport = MemoryTransport()
 
2057
        branch = self.make_remote_branch(transport, client)
 
2058
        branch.lock_write()
 
2059
        config = branch.get_config_stack()
 
2060
        config.set('email', 'The Dude <lebowski@example.com>')
 
2061
        branch.unlock()
 
2062
        self.assertFinished(client)
 
2063
        self.assertEqual(
 
2064
            [('call', 'Branch.get_stacked_on_url', ('memory:///',)),
 
2065
             ('call', 'Branch.lock_write', ('memory:///', '', '')),
 
2066
             ('call_expecting_body', 'Branch.get_config_file', ('memory:///',)),
 
2067
             ('call_with_body_bytes_expecting_body', 'Branch.put_config_file',
 
2068
                 ('memory:///', 'branch token', 'repo token'),
 
2069
                 '# line 1\nemail = The Dude <lebowski@example.com>\n'),
 
2070
             ('call', 'Branch.unlock', ('memory:///', 'branch token', 'repo token'))],
 
2071
            client._calls)
 
2072
 
 
2073
 
1707
2074
class TestBranchLockWrite(RemoteBranchTestCase):
1708
2075
 
1709
2076
    def test_lock_write_unlockable(self):
1722
2089
        self.assertFinished(client)
1723
2090
 
1724
2091
 
 
2092
class TestBranchRevisionIdToRevno(RemoteBranchTestCase):
 
2093
 
 
2094
    def test_simple(self):
 
2095
        transport = MemoryTransport()
 
2096
        client = FakeClient(transport.base)
 
2097
        client.add_expected_call(
 
2098
            'Branch.get_stacked_on_url', ('quack/',),
 
2099
            'error', ('NotStacked',),)
 
2100
        client.add_expected_call(
 
2101
            'Branch.revision_id_to_revno', ('quack/', 'null:'),
 
2102
            'success', ('ok', '0',),)
 
2103
        client.add_expected_call(
 
2104
            'Branch.revision_id_to_revno', ('quack/', 'unknown'),
 
2105
            'error', ('NoSuchRevision', 'unknown',),)
 
2106
        transport.mkdir('quack')
 
2107
        transport = transport.clone('quack')
 
2108
        branch = self.make_remote_branch(transport, client)
 
2109
        self.assertEquals(0, branch.revision_id_to_revno('null:'))
 
2110
        self.assertRaises(errors.NoSuchRevision,
 
2111
            branch.revision_id_to_revno, 'unknown')
 
2112
        self.assertFinished(client)
 
2113
 
 
2114
    def test_dotted(self):
 
2115
        transport = MemoryTransport()
 
2116
        client = FakeClient(transport.base)
 
2117
        client.add_expected_call(
 
2118
            'Branch.get_stacked_on_url', ('quack/',),
 
2119
            'error', ('NotStacked',),)
 
2120
        client.add_expected_call(
 
2121
            'Branch.revision_id_to_revno', ('quack/', 'null:'),
 
2122
            'success', ('ok', '0',),)
 
2123
        client.add_expected_call(
 
2124
            'Branch.revision_id_to_revno', ('quack/', 'unknown'),
 
2125
            'error', ('NoSuchRevision', 'unknown',),)
 
2126
        transport.mkdir('quack')
 
2127
        transport = transport.clone('quack')
 
2128
        branch = self.make_remote_branch(transport, client)
 
2129
        self.assertEquals((0, ), branch.revision_id_to_dotted_revno('null:'))
 
2130
        self.assertRaises(errors.NoSuchRevision,
 
2131
            branch.revision_id_to_dotted_revno, 'unknown')
 
2132
        self.assertFinished(client)
 
2133
 
 
2134
    def test_dotted_no_smart_verb(self):
 
2135
        self.setup_smart_server_with_call_log()
 
2136
        branch = self.make_branch('.')
 
2137
        self.disable_verb('Branch.revision_id_to_revno')
 
2138
        self.reset_smart_call_log()
 
2139
        self.assertEquals((0, ),
 
2140
            branch.revision_id_to_dotted_revno('null:'))
 
2141
        self.assertLength(7, self.hpss_calls)
 
2142
 
 
2143
 
1725
2144
class TestBzrDirGetSetConfig(RemoteBzrDirTestCase):
1726
2145
 
1727
2146
    def test__get_config(self):
1844
2263
        client = FakeClient(transport.base)
1845
2264
        transport = transport.clone(transport_path)
1846
2265
        # we do not want bzrdir to make any remote calls
1847
 
        bzrdir = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
 
2266
        bzrdir = RemoteBzrDir(transport, RemoteBzrDirFormat(),
1848
2267
            _client=False)
1849
2268
        repo = RemoteRepository(bzrdir, None, _client=client)
1850
2269
        return repo, client
1858
2277
 
1859
2278
    def test_get_format_description(self):
1860
2279
        remote_format = RemoteBranchFormat()
1861
 
        real_format = branch.BranchFormat.get_default_format()
 
2280
        real_format = branch.format_registry.get_default()
1862
2281
        remote_format._network_name = real_format.network_name()
1863
2282
        self.assertEqual(remoted_description(real_format),
1864
2283
            remote_format.get_format_description())
1867
2286
class TestRepositoryFormat(TestRemoteRepository):
1868
2287
 
1869
2288
    def test_fast_delta(self):
1870
 
        true_name = groupcompress_repo.RepositoryFormatCHK1().network_name()
 
2289
        true_name = groupcompress_repo.RepositoryFormat2a().network_name()
1871
2290
        true_format = RemoteRepositoryFormat()
1872
2291
        true_format._network_name = true_name
1873
2292
        self.assertEqual(True, true_format.fast_deltas)
1874
 
        false_name = pack_repo.RepositoryFormatKnitPack1().network_name()
 
2293
        false_name = knitpack_repo.RepositoryFormatKnitPack1().network_name()
1875
2294
        false_format = RemoteRepositoryFormat()
1876
2295
        false_format._network_name = false_name
1877
2296
        self.assertEqual(False, false_format.fast_deltas)
1878
2297
 
1879
2298
    def test_get_format_description(self):
1880
2299
        remote_repo_format = RemoteRepositoryFormat()
1881
 
        real_format = repository.RepositoryFormat.get_default_format()
 
2300
        real_format = repository.format_registry.get_default()
1882
2301
        remote_repo_format._network_name = real_format.network_name()
1883
2302
        self.assertEqual(remoted_description(real_format),
1884
2303
            remote_repo_format.get_format_description())
1885
2304
 
1886
2305
 
 
2306
class TestRepositoryAllRevisionIds(TestRemoteRepository):
 
2307
 
 
2308
    def test_empty(self):
 
2309
        transport_path = 'quack'
 
2310
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
2311
        client.add_success_response_with_body('', 'ok')
 
2312
        self.assertEquals([], repo.all_revision_ids())
 
2313
        self.assertEqual(
 
2314
            [('call_expecting_body', 'Repository.all_revision_ids',
 
2315
             ('quack/',))],
 
2316
            client._calls)
 
2317
 
 
2318
    def test_with_some_content(self):
 
2319
        transport_path = 'quack'
 
2320
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
2321
        client.add_success_response_with_body(
 
2322
            'rev1\nrev2\nanotherrev\n', 'ok')
 
2323
        self.assertEquals(["rev1", "rev2", "anotherrev"],
 
2324
            repo.all_revision_ids())
 
2325
        self.assertEqual(
 
2326
            [('call_expecting_body', 'Repository.all_revision_ids',
 
2327
             ('quack/',))],
 
2328
            client._calls)
 
2329
 
 
2330
 
1887
2331
class TestRepositoryGatherStats(TestRemoteRepository):
1888
2332
 
1889
2333
    def test_revid_none(self):
1942
2386
                         result)
1943
2387
 
1944
2388
 
 
2389
class TestRepositoryBreakLock(TestRemoteRepository):
 
2390
 
 
2391
    def test_break_lock(self):
 
2392
        transport_path = 'quack'
 
2393
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
2394
        client.add_success_response('ok')
 
2395
        repo.break_lock()
 
2396
        self.assertEqual(
 
2397
            [('call', 'Repository.break_lock', ('quack/',))],
 
2398
            client._calls)
 
2399
 
 
2400
 
 
2401
class TestRepositoryGetSerializerFormat(TestRemoteRepository):
 
2402
 
 
2403
    def test_get_serializer_format(self):
 
2404
        transport_path = 'hill'
 
2405
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
2406
        client.add_success_response('ok', '7')
 
2407
        self.assertEquals('7', repo.get_serializer_format())
 
2408
        self.assertEqual(
 
2409
            [('call', 'VersionedFileRepository.get_serializer_format',
 
2410
              ('hill/', ))],
 
2411
            client._calls)
 
2412
 
 
2413
 
 
2414
class TestRepositoryReconcile(TestRemoteRepository):
 
2415
 
 
2416
    def test_reconcile(self):
 
2417
        transport_path = 'hill'
 
2418
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
2419
        body = ("garbage_inventories: 2\n"
 
2420
                "inconsistent_parents: 3\n")
 
2421
        client.add_expected_call(
 
2422
            'Repository.lock_write', ('hill/', ''),
 
2423
            'success', ('ok', 'a token'))
 
2424
        client.add_success_response_with_body(body, 'ok')
 
2425
        reconciler = repo.reconcile()
 
2426
        self.assertEqual(
 
2427
            [('call', 'Repository.lock_write', ('hill/', '')),
 
2428
             ('call_expecting_body', 'Repository.reconcile',
 
2429
                ('hill/', 'a token'))],
 
2430
            client._calls)
 
2431
        self.assertEquals(2, reconciler.garbage_inventories)
 
2432
        self.assertEquals(3, reconciler.inconsistent_parents)
 
2433
 
 
2434
 
 
2435
class TestRepositoryGetRevisionSignatureText(TestRemoteRepository):
 
2436
 
 
2437
    def test_text(self):
 
2438
        # ('ok',), body with signature text
 
2439
        transport_path = 'quack'
 
2440
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
2441
        client.add_success_response_with_body(
 
2442
            'THETEXT', 'ok')
 
2443
        self.assertEquals("THETEXT", repo.get_signature_text("revid"))
 
2444
        self.assertEqual(
 
2445
            [('call_expecting_body', 'Repository.get_revision_signature_text',
 
2446
             ('quack/', 'revid'))],
 
2447
            client._calls)
 
2448
 
 
2449
    def test_no_signature(self):
 
2450
        transport_path = 'quick'
 
2451
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
2452
        client.add_error_response('nosuchrevision', 'unknown')
 
2453
        self.assertRaises(errors.NoSuchRevision, repo.get_signature_text,
 
2454
                "unknown")
 
2455
        self.assertEqual(
 
2456
            [('call_expecting_body', 'Repository.get_revision_signature_text',
 
2457
              ('quick/', 'unknown'))],
 
2458
            client._calls)
 
2459
 
 
2460
 
1945
2461
class TestRepositoryGetGraph(TestRemoteRepository):
1946
2462
 
1947
2463
    def test_get_graph(self):
1952
2468
        self.assertNotEqual(graph._parents_provider, repo)
1953
2469
 
1954
2470
 
 
2471
class TestRepositoryAddSignatureText(TestRemoteRepository):
 
2472
 
 
2473
    def test_add_signature_text(self):
 
2474
        transport_path = 'quack'
 
2475
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
2476
        client.add_expected_call(
 
2477
            'Repository.lock_write', ('quack/', ''),
 
2478
            'success', ('ok', 'a token'))
 
2479
        client.add_expected_call(
 
2480
            'Repository.start_write_group', ('quack/', 'a token'),
 
2481
            'success', ('ok', ('token1', )))
 
2482
        client.add_expected_call(
 
2483
            'Repository.add_signature_text', ('quack/', 'a token', 'rev1',
 
2484
                'token1'),
 
2485
            'success', ('ok', ), None)
 
2486
        repo.lock_write()
 
2487
        repo.start_write_group()
 
2488
        self.assertIs(None,
 
2489
            repo.add_signature_text("rev1", "every bloody emperor"))
 
2490
        self.assertEqual(
 
2491
            ('call_with_body_bytes_expecting_body',
 
2492
              'Repository.add_signature_text',
 
2493
                ('quack/', 'a token', 'rev1', 'token1'),
 
2494
              'every bloody emperor'),
 
2495
            client._calls[-1])
 
2496
 
 
2497
 
1955
2498
class TestRepositoryGetParentMap(TestRemoteRepository):
1956
2499
 
1957
2500
    def test_get_parent_map_caching(self):
2007
2550
        parents = repo.get_parent_map([rev_id])
2008
2551
        self.assertEqual(
2009
2552
            [('call_with_body_bytes_expecting_body',
2010
 
              'Repository.get_parent_map', ('quack/', 'include-missing:',
2011
 
              rev_id), '\n\n0'),
 
2553
              'Repository.get_parent_map',
 
2554
              ('quack/', 'include-missing:', rev_id), '\n\n0'),
2012
2555
             ('disconnect medium',),
2013
2556
             ('call_expecting_body', 'Repository.get_revision_graph',
2014
2557
              ('quack/', ''))],
2134
2677
        self.assertEqual({}, repo.get_parent_map(['non-existant']))
2135
2678
        self.assertLength(0, self.hpss_calls)
2136
2679
 
 
2680
    def test_exposes_get_cached_parent_map(self):
 
2681
        """RemoteRepository exposes get_cached_parent_map from
 
2682
        _unstacked_provider
 
2683
        """
 
2684
        r1 = u'\u0e33'.encode('utf8')
 
2685
        r2 = u'\u0dab'.encode('utf8')
 
2686
        lines = [' '.join([r2, r1]), r1]
 
2687
        encoded_body = bz2.compress('\n'.join(lines))
 
2688
 
 
2689
        transport_path = 'quack'
 
2690
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
2691
        client.add_success_response_with_body(encoded_body, 'ok')
 
2692
        repo.lock_read()
 
2693
        # get_cached_parent_map should *not* trigger an RPC
 
2694
        self.assertEqual({}, repo.get_cached_parent_map([r1]))
 
2695
        self.assertEqual([], client._calls)
 
2696
        self.assertEqual({r2: (r1,)}, repo.get_parent_map([r2]))
 
2697
        self.assertEqual({r1: (NULL_REVISION,)},
 
2698
            repo.get_cached_parent_map([r1]))
 
2699
        self.assertEqual(
 
2700
            [('call_with_body_bytes_expecting_body',
 
2701
              'Repository.get_parent_map', ('quack/', 'include-missing:', r2),
 
2702
              '\n\n0')],
 
2703
            client._calls)
 
2704
        repo.unlock()
 
2705
 
2137
2706
 
2138
2707
class TestGetParentMapAllowsNew(tests.TestCaseWithTransport):
2139
2708
 
2154
2723
        self.assertEqual({'rev1': ('null:',)}, graph.get_parent_map(['rev1']))
2155
2724
 
2156
2725
 
 
2726
class TestRepositoryGetRevisions(TestRemoteRepository):
 
2727
 
 
2728
    def test_hpss_missing_revision(self):
 
2729
        transport_path = 'quack'
 
2730
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
2731
        client.add_success_response_with_body(
 
2732
            '', 'ok', '10')
 
2733
        self.assertRaises(errors.NoSuchRevision, repo.get_revisions,
 
2734
            ['somerev1', 'anotherrev2'])
 
2735
        self.assertEqual(
 
2736
            [('call_with_body_bytes_expecting_body', 'Repository.iter_revisions',
 
2737
             ('quack/', ), "somerev1\nanotherrev2")],
 
2738
            client._calls)
 
2739
 
 
2740
    def test_hpss_get_single_revision(self):
 
2741
        transport_path = 'quack'
 
2742
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
2743
        somerev1 = Revision("somerev1")
 
2744
        somerev1.committer = "Joe Committer <joe@example.com>"
 
2745
        somerev1.timestamp = 1321828927
 
2746
        somerev1.timezone = -60
 
2747
        somerev1.inventory_sha1 = "691b39be74c67b1212a75fcb19c433aaed903c2b"
 
2748
        somerev1.message = "Message"
 
2749
        body = zlib.compress(chk_bencode_serializer.write_revision_to_string(
 
2750
            somerev1))
 
2751
        # Split up body into two bits to make sure the zlib compression object
 
2752
        # gets data fed twice.
 
2753
        client.add_success_response_with_body(
 
2754
                [body[:10], body[10:]], 'ok', '10')
 
2755
        revs = repo.get_revisions(['somerev1'])
 
2756
        self.assertEquals(revs, [somerev1])
 
2757
        self.assertEqual(
 
2758
            [('call_with_body_bytes_expecting_body', 'Repository.iter_revisions',
 
2759
             ('quack/', ), "somerev1")],
 
2760
            client._calls)
 
2761
 
 
2762
 
2157
2763
class TestRepositoryGetRevisionGraph(TestRemoteRepository):
2158
2764
 
2159
2765
    def test_null_revision(self):
2310
2916
                              call.call.method == verb])
2311
2917
 
2312
2918
 
 
2919
class TestRepositoryHasSignatureForRevisionId(TestRemoteRepository):
 
2920
 
 
2921
    def test_has_signature_for_revision_id(self):
 
2922
        # ('yes', ) for Repository.has_signature_for_revision_id -> 'True'.
 
2923
        transport_path = 'quack'
 
2924
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
2925
        client.add_success_response('yes')
 
2926
        result = repo.has_signature_for_revision_id('A')
 
2927
        self.assertEqual(
 
2928
            [('call', 'Repository.has_signature_for_revision_id',
 
2929
              ('quack/', 'A'))],
 
2930
            client._calls)
 
2931
        self.assertEqual(True, result)
 
2932
 
 
2933
    def test_is_not_shared(self):
 
2934
        # ('no', ) for Repository.has_signature_for_revision_id -> 'False'.
 
2935
        transport_path = 'qwack'
 
2936
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
2937
        client.add_success_response('no')
 
2938
        result = repo.has_signature_for_revision_id('A')
 
2939
        self.assertEqual(
 
2940
            [('call', 'Repository.has_signature_for_revision_id',
 
2941
              ('qwack/', 'A'))],
 
2942
            client._calls)
 
2943
        self.assertEqual(False, result)
 
2944
 
 
2945
 
 
2946
class TestRepositoryPhysicalLockStatus(TestRemoteRepository):
 
2947
 
 
2948
    def test_get_physical_lock_status_yes(self):
 
2949
        transport_path = 'qwack'
 
2950
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
2951
        client.add_success_response('yes')
 
2952
        result = repo.get_physical_lock_status()
 
2953
        self.assertEqual(
 
2954
            [('call', 'Repository.get_physical_lock_status',
 
2955
              ('qwack/', ))],
 
2956
            client._calls)
 
2957
        self.assertEqual(True, result)
 
2958
 
 
2959
    def test_get_physical_lock_status_no(self):
 
2960
        transport_path = 'qwack'
 
2961
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
2962
        client.add_success_response('no')
 
2963
        result = repo.get_physical_lock_status()
 
2964
        self.assertEqual(
 
2965
            [('call', 'Repository.get_physical_lock_status',
 
2966
              ('qwack/', ))],
 
2967
            client._calls)
 
2968
        self.assertEqual(False, result)
 
2969
 
 
2970
 
2313
2971
class TestRepositoryIsShared(TestRemoteRepository):
2314
2972
 
2315
2973
    def test_is_shared(self):
2335
2993
        self.assertEqual(False, result)
2336
2994
 
2337
2995
 
 
2996
class TestRepositoryMakeWorkingTrees(TestRemoteRepository):
 
2997
 
 
2998
    def test_make_working_trees(self):
 
2999
        # ('yes', ) for Repository.make_working_trees -> 'True'.
 
3000
        transport_path = 'quack'
 
3001
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
3002
        client.add_success_response('yes')
 
3003
        result = repo.make_working_trees()
 
3004
        self.assertEqual(
 
3005
            [('call', 'Repository.make_working_trees', ('quack/',))],
 
3006
            client._calls)
 
3007
        self.assertEqual(True, result)
 
3008
 
 
3009
    def test_no_working_trees(self):
 
3010
        # ('no', ) for Repository.make_working_trees -> 'False'.
 
3011
        transport_path = 'qwack'
 
3012
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
3013
        client.add_success_response('no')
 
3014
        result = repo.make_working_trees()
 
3015
        self.assertEqual(
 
3016
            [('call', 'Repository.make_working_trees', ('qwack/',))],
 
3017
            client._calls)
 
3018
        self.assertEqual(False, result)
 
3019
 
 
3020
 
2338
3021
class TestRepositoryLockWrite(TestRemoteRepository):
2339
3022
 
2340
3023
    def test_lock_write(self):
2366
3049
            client._calls)
2367
3050
 
2368
3051
 
 
3052
class TestRepositoryWriteGroups(TestRemoteRepository):
 
3053
 
 
3054
    def test_start_write_group(self):
 
3055
        transport_path = 'quack'
 
3056
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
3057
        client.add_expected_call(
 
3058
            'Repository.lock_write', ('quack/', ''),
 
3059
            'success', ('ok', 'a token'))
 
3060
        client.add_expected_call(
 
3061
            'Repository.start_write_group', ('quack/', 'a token'),
 
3062
            'success', ('ok', ('token1', )))
 
3063
        repo.lock_write()
 
3064
        repo.start_write_group()
 
3065
 
 
3066
    def test_start_write_group_unsuspendable(self):
 
3067
        # Some repositories do not support suspending write
 
3068
        # groups. For those, fall back to the "real" repository.
 
3069
        transport_path = 'quack'
 
3070
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
3071
        def stub_ensure_real():
 
3072
            client._calls.append(('_ensure_real',))
 
3073
            repo._real_repository = _StubRealPackRepository(client._calls)
 
3074
        repo._ensure_real = stub_ensure_real
 
3075
        client.add_expected_call(
 
3076
            'Repository.lock_write', ('quack/', ''),
 
3077
            'success', ('ok', 'a token'))
 
3078
        client.add_expected_call(
 
3079
            'Repository.start_write_group', ('quack/', 'a token'),
 
3080
            'error', ('UnsuspendableWriteGroup',))
 
3081
        repo.lock_write()
 
3082
        repo.start_write_group()
 
3083
        self.assertEquals(client._calls[-2:], [ 
 
3084
            ('_ensure_real',),
 
3085
            ('start_write_group',)])
 
3086
 
 
3087
    def test_commit_write_group(self):
 
3088
        transport_path = 'quack'
 
3089
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
3090
        client.add_expected_call(
 
3091
            'Repository.lock_write', ('quack/', ''),
 
3092
            'success', ('ok', 'a token'))
 
3093
        client.add_expected_call(
 
3094
            'Repository.start_write_group', ('quack/', 'a token'),
 
3095
            'success', ('ok', ['token1']))
 
3096
        client.add_expected_call(
 
3097
            'Repository.commit_write_group', ('quack/', 'a token', ['token1']),
 
3098
            'success', ('ok',))
 
3099
        repo.lock_write()
 
3100
        repo.start_write_group()
 
3101
        repo.commit_write_group()
 
3102
 
 
3103
    def test_abort_write_group(self):
 
3104
        transport_path = 'quack'
 
3105
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
3106
        client.add_expected_call(
 
3107
            'Repository.lock_write', ('quack/', ''),
 
3108
            'success', ('ok', 'a token'))
 
3109
        client.add_expected_call(
 
3110
            'Repository.start_write_group', ('quack/', 'a token'),
 
3111
            'success', ('ok', ['token1']))
 
3112
        client.add_expected_call(
 
3113
            'Repository.abort_write_group', ('quack/', 'a token', ['token1']),
 
3114
            'success', ('ok',))
 
3115
        repo.lock_write()
 
3116
        repo.start_write_group()
 
3117
        repo.abort_write_group(False)
 
3118
 
 
3119
    def test_suspend_write_group(self):
 
3120
        transport_path = 'quack'
 
3121
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
3122
        self.assertEquals([], repo.suspend_write_group())
 
3123
 
 
3124
    def test_resume_write_group(self):
 
3125
        transport_path = 'quack'
 
3126
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
3127
        client.add_expected_call(
 
3128
            'Repository.lock_write', ('quack/', ''),
 
3129
            'success', ('ok', 'a token'))
 
3130
        client.add_expected_call(
 
3131
            'Repository.check_write_group', ('quack/', 'a token', ['token1']),
 
3132
            'success', ('ok',))
 
3133
        repo.lock_write()
 
3134
        repo.resume_write_group(['token1'])
 
3135
 
 
3136
 
2369
3137
class TestRepositorySetMakeWorkingTrees(TestRemoteRepository):
2370
3138
 
2371
3139
    def test_backwards_compat(self):
2430
3198
        self.assertEqual([], client._calls)
2431
3199
 
2432
3200
 
 
3201
class TestRepositoryIterFilesBytes(TestRemoteRepository):
 
3202
    """Test Repository.iter_file_bytes."""
 
3203
 
 
3204
    def test_single(self):
 
3205
        transport_path = 'quack'
 
3206
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
3207
        client.add_expected_call(
 
3208
            'Repository.iter_files_bytes', ('quack/', ),
 
3209
            'success', ('ok',), iter(["ok\x000", "\n", zlib.compress("mydata" * 10)]))
 
3210
        for (identifier, byte_stream) in repo.iter_files_bytes([("somefile",
 
3211
                "somerev", "myid")]):
 
3212
            self.assertEquals("myid", identifier)
 
3213
            self.assertEquals("".join(byte_stream), "mydata" * 10)
 
3214
 
 
3215
    def test_missing(self):
 
3216
        transport_path = 'quack'
 
3217
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
3218
        client.add_expected_call(
 
3219
            'Repository.iter_files_bytes',
 
3220
                ('quack/', ),
 
3221
            'error', ('RevisionNotPresent', 'somefile', 'somerev'),
 
3222
            iter(["absent\0somefile\0somerev\n"]))
 
3223
        self.assertRaises(errors.RevisionNotPresent, list,
 
3224
                repo.iter_files_bytes(
 
3225
                [("somefile", "somerev", "myid")]))
 
3226
 
 
3227
 
2433
3228
class TestRepositoryInsertStreamBase(TestRemoteRepository):
2434
3229
    """Base class for Repository.insert_stream and .insert_stream_1.19
2435
3230
    tests.
2442
3237
        the client is finished.
2443
3238
        """
2444
3239
        sink = repo._get_sink()
2445
 
        fmt = repository.RepositoryFormat.get_default_format()
 
3240
        fmt = repository.format_registry.get_default()
2446
3241
        resume_tokens, missing_keys = sink.insert_stream([], fmt, [])
2447
3242
        self.assertEqual([], resume_tokens)
2448
3243
        self.assertEqual(set(), missing_keys)
2548
3343
                return True
2549
3344
        repo._real_repository = FakeRealRepository()
2550
3345
        sink = repo._get_sink()
2551
 
        fmt = repository.RepositoryFormat.get_default_format()
 
3346
        fmt = repository.format_registry.get_default()
2552
3347
        stream = self.make_stream_with_inv_deltas(fmt)
2553
3348
        resume_tokens, missing_keys = sink.insert_stream(stream, fmt, [])
2554
3349
        # Every record from the first inventory delta should have been sent to
2710
3505
        self.calls = calls
2711
3506
        self._pack_collection = _StubPackCollection(calls)
2712
3507
 
 
3508
    def start_write_group(self):
 
3509
        self.calls.append(('start_write_group',))
 
3510
 
2713
3511
    def is_in_write_group(self):
2714
3512
        return False
2715
3513
 
2774
3572
             ('pack collection autopack',)],
2775
3573
            client._calls)
2776
3574
 
 
3575
    def test_oom_error_reporting(self):
 
3576
        """An out-of-memory condition on the server is reported clearly"""
 
3577
        transport_path = 'quack'
 
3578
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
3579
        client.add_expected_call(
 
3580
            'PackRepository.autopack', ('quack/',),
 
3581
            'error', ('MemoryError',))
 
3582
        err = self.assertRaises(errors.BzrError, repo.autopack)
 
3583
        self.assertContainsRe(str(err), "^remote server out of mem")
 
3584
 
2777
3585
 
2778
3586
class TestErrorTranslationBase(tests.TestCaseWithMemoryTransport):
2779
3587
    """Base class for unit tests for bzrlib.remote._translate_error."""
2852
3660
            detail='extra detail')
2853
3661
        self.assertEqual(expected_error, translated_error)
2854
3662
 
 
3663
    def test_norepository(self):
 
3664
        bzrdir = self.make_bzrdir('')
 
3665
        translated_error = self.translateTuple(('norepository',),
 
3666
            bzrdir=bzrdir)
 
3667
        expected_error = errors.NoRepositoryPresent(bzrdir)
 
3668
        self.assertEqual(expected_error, translated_error)
 
3669
 
2855
3670
    def test_LockContention(self):
2856
3671
        translated_error = self.translateTuple(('LockContention',))
2857
3672
        expected_error = errors.LockContention('(remote lock)')
2885
3700
        expected_error = errors.DivergedBranches(branch, other_branch)
2886
3701
        self.assertEqual(expected_error, translated_error)
2887
3702
 
 
3703
    def test_NotStacked(self):
 
3704
        branch = self.make_branch('')
 
3705
        translated_error = self.translateTuple(('NotStacked',), branch=branch)
 
3706
        expected_error = errors.NotStacked(branch)
 
3707
        self.assertEqual(expected_error, translated_error)
 
3708
 
2888
3709
    def test_ReadError_no_args(self):
2889
3710
        path = 'a path'
2890
3711
        translated_error = self.translateTuple(('ReadError',), path=path)
2906
3727
 
2907
3728
    def test_PermissionDenied_no_args(self):
2908
3729
        path = 'a path'
2909
 
        translated_error = self.translateTuple(('PermissionDenied',), path=path)
 
3730
        translated_error = self.translateTuple(('PermissionDenied',),
 
3731
            path=path)
2910
3732
        expected_error = errors.PermissionDenied(path)
2911
3733
        self.assertEqual(expected_error, translated_error)
2912
3734
 
2935
3757
        expected_error = errors.PermissionDenied(path, extra)
2936
3758
        self.assertEqual(expected_error, translated_error)
2937
3759
 
 
3760
    # GZ 2011-03-02: TODO test for PermissionDenied with non-ascii 'extra'
 
3761
 
 
3762
    def test_NoSuchFile_context_path(self):
 
3763
        local_path = "local path"
 
3764
        translated_error = self.translateTuple(('ReadError', "remote path"),
 
3765
            path=local_path)
 
3766
        expected_error = errors.ReadError(local_path)
 
3767
        self.assertEqual(expected_error, translated_error)
 
3768
 
 
3769
    def test_NoSuchFile_without_context(self):
 
3770
        remote_path = "remote path"
 
3771
        translated_error = self.translateTuple(('ReadError', remote_path))
 
3772
        expected_error = errors.ReadError(remote_path)
 
3773
        self.assertEqual(expected_error, translated_error)
 
3774
 
 
3775
    def test_ReadOnlyError(self):
 
3776
        translated_error = self.translateTuple(('ReadOnlyError',))
 
3777
        expected_error = errors.TransportNotPossible("readonly transport")
 
3778
        self.assertEqual(expected_error, translated_error)
 
3779
 
 
3780
    def test_MemoryError(self):
 
3781
        translated_error = self.translateTuple(('MemoryError',))
 
3782
        self.assertStartsWith(str(translated_error),
 
3783
            "remote server out of memory")
 
3784
 
 
3785
    def test_generic_IndexError_no_classname(self):
 
3786
        err = errors.ErrorFromSmartServer(('error', "list index out of range"))
 
3787
        translated_error = self.translateErrorFromSmartServer(err)
 
3788
        expected_error = errors.UnknownErrorFromSmartServer(err)
 
3789
        self.assertEqual(expected_error, translated_error)
 
3790
 
 
3791
    # GZ 2011-03-02: TODO test generic non-ascii error string
 
3792
 
 
3793
    def test_generic_KeyError(self):
 
3794
        err = errors.ErrorFromSmartServer(('error', 'KeyError', "1"))
 
3795
        translated_error = self.translateErrorFromSmartServer(err)
 
3796
        expected_error = errors.UnknownErrorFromSmartServer(err)
 
3797
        self.assertEqual(expected_error, translated_error)
 
3798
 
2938
3799
 
2939
3800
class TestErrorTranslationRobustness(TestErrorTranslationBase):
2940
3801
    """Unit tests for bzrlib.remote._translate_error's robustness.
3085
3946
        _, stacked = branch_factory()
3086
3947
        source = stacked.repository._get_source(target_repository_format)
3087
3948
        tip = stacked.last_revision()
3088
 
        revs = stacked.repository.get_ancestry(tip)
3089
 
        search = graph.PendingAncestryResult([tip], stacked.repository)
 
3949
        stacked.repository._ensure_real()
 
3950
        graph = stacked.repository.get_graph()
 
3951
        revs = [r for (r,ps) in graph.iter_ancestry([tip])
 
3952
                if r != NULL_REVISION]
 
3953
        revs.reverse()
 
3954
        search = vf_search.PendingAncestryResult([tip], stacked.repository)
3090
3955
        self.reset_smart_call_log()
3091
3956
        stream = source.get_stream(search)
3092
 
        if None in revs:
3093
 
            revs.remove(None)
3094
3957
        # We trust that if a revision is in the stream the rest of the new
3095
3958
        # content for it is too, as per our main fetch tests; here we are
3096
3959
        # checking that the revisions are actually included at all, and their
3135
3998
        self.assertEqual(expected_revs, rev_ord)
3136
3999
        # Getting topological sort requires VFS calls still - one of which is
3137
4000
        # pushing up from the bound branch.
3138
 
        self.assertLength(13, self.hpss_calls)
 
4001
        self.assertLength(14, self.hpss_calls)
3139
4002
 
3140
4003
    def test_stacked_get_stream_groupcompress(self):
3141
4004
        # Repository._get_source.get_stream() from a stacked repository with
3182
4045
 
3183
4046
    def test_copy_content_into_avoids_revision_history(self):
3184
4047
        local = self.make_branch('local')
3185
 
        remote_backing_tree = self.make_branch_and_tree('remote')
3186
 
        remote_backing_tree.commit("Commit.")
 
4048
        builder = self.make_branch_builder('remote')
 
4049
        builder.build_commit(message="Commit.")
3187
4050
        remote_branch_url = self.smart_server.get_url() + 'remote'
3188
4051
        remote_branch = bzrdir.BzrDir.open(remote_branch_url).open_branch()
3189
4052
        local.repository.fetch(remote_branch.repository)
3190
4053
        self.hpss_calls = []
3191
4054
        remote_branch.copy_content_into(local)
3192
4055
        self.assertFalse('Branch.revision_history' in self.hpss_calls)
 
4056
 
 
4057
    def test_fetch_everything_needs_just_one_call(self):
 
4058
        local = self.make_branch('local')
 
4059
        builder = self.make_branch_builder('remote')
 
4060
        builder.build_commit(message="Commit.")
 
4061
        remote_branch_url = self.smart_server.get_url() + 'remote'
 
4062
        remote_branch = bzrdir.BzrDir.open(remote_branch_url).open_branch()
 
4063
        self.hpss_calls = []
 
4064
        local.repository.fetch(
 
4065
            remote_branch.repository,
 
4066
            fetch_spec=vf_search.EverythingResult(remote_branch.repository))
 
4067
        self.assertEqual(['Repository.get_stream_1.19'], self.hpss_calls)
 
4068
 
 
4069
    def override_verb(self, verb_name, verb):
 
4070
        request_handlers = request.request_handlers
 
4071
        orig_verb = request_handlers.get(verb_name)
 
4072
        orig_info = request_handlers.get_info(verb_name)
 
4073
        request_handlers.register(verb_name, verb, override_existing=True)
 
4074
        self.addCleanup(request_handlers.register, verb_name, orig_verb,
 
4075
                override_existing=True, info=orig_info)
 
4076
 
 
4077
    def test_fetch_everything_backwards_compat(self):
 
4078
        """Can fetch with EverythingResult even with pre 2.4 servers.
 
4079
        
 
4080
        Pre-2.4 do not support 'everything' searches with the
 
4081
        Repository.get_stream_1.19 verb.
 
4082
        """
 
4083
        verb_log = []
 
4084
        class OldGetStreamVerb(SmartServerRepositoryGetStream_1_19):
 
4085
            """A version of the Repository.get_stream_1.19 verb patched to
 
4086
            reject 'everything' searches the way 2.3 and earlier do.
 
4087
            """
 
4088
            def recreate_search(self, repository, search_bytes,
 
4089
                                discard_excess=False):
 
4090
                verb_log.append(search_bytes.split('\n', 1)[0])
 
4091
                if search_bytes == 'everything':
 
4092
                    return (None,
 
4093
                            request.FailedSmartServerResponse(('BadSearch',)))
 
4094
                return super(OldGetStreamVerb,
 
4095
                        self).recreate_search(repository, search_bytes,
 
4096
                            discard_excess=discard_excess)
 
4097
        self.override_verb('Repository.get_stream_1.19', OldGetStreamVerb)
 
4098
        local = self.make_branch('local')
 
4099
        builder = self.make_branch_builder('remote')
 
4100
        builder.build_commit(message="Commit.")
 
4101
        remote_branch_url = self.smart_server.get_url() + 'remote'
 
4102
        remote_branch = bzrdir.BzrDir.open(remote_branch_url).open_branch()
 
4103
        self.hpss_calls = []
 
4104
        local.repository.fetch(
 
4105
            remote_branch.repository,
 
4106
            fetch_spec=vf_search.EverythingResult(remote_branch.repository))
 
4107
        # make sure the overridden verb was used
 
4108
        self.assertLength(1, verb_log)
 
4109
        # more than one HPSS call is needed, but because it's a VFS callback
 
4110
        # its hard to predict exactly how many.
 
4111
        self.assertTrue(len(self.hpss_calls) > 1)
 
4112
 
 
4113
 
 
4114
class TestUpdateBoundBranchWithModifiedBoundLocation(
 
4115
    tests.TestCaseWithTransport):
 
4116
    """Ensure correct handling of bound_location modifications.
 
4117
 
 
4118
    This is tested against a smart server as http://pad.lv/786980 was about a
 
4119
    ReadOnlyError (write attempt during a read-only transaction) which can only
 
4120
    happen in this context.
 
4121
    """
 
4122
 
 
4123
    def setUp(self):
 
4124
        super(TestUpdateBoundBranchWithModifiedBoundLocation, self).setUp()
 
4125
        self.transport_server = test_server.SmartTCPServer_for_testing
 
4126
 
 
4127
    def make_master_and_checkout(self, master_name, checkout_name):
 
4128
        # Create the master branch and its associated checkout
 
4129
        self.master = self.make_branch_and_tree(master_name)
 
4130
        self.checkout = self.master.branch.create_checkout(checkout_name)
 
4131
        # Modify the master branch so there is something to update
 
4132
        self.master.commit('add stuff')
 
4133
        self.last_revid = self.master.commit('even more stuff')
 
4134
        self.bound_location = self.checkout.branch.get_bound_location()
 
4135
 
 
4136
    def assertUpdateSucceeds(self, new_location):
 
4137
        self.checkout.branch.set_bound_location(new_location)
 
4138
        self.checkout.update()
 
4139
        self.assertEquals(self.last_revid, self.checkout.last_revision())
 
4140
 
 
4141
    def test_without_final_slash(self):
 
4142
        self.make_master_and_checkout('master', 'checkout')
 
4143
        # For unclear reasons some users have a bound_location without a final
 
4144
        # '/', simulate that by forcing such a value
 
4145
        self.assertEndsWith(self.bound_location, '/')
 
4146
        self.assertUpdateSucceeds(self.bound_location.rstrip('/'))
 
4147
 
 
4148
    def test_plus_sign(self):
 
4149
        self.make_master_and_checkout('+master', 'checkout')
 
4150
        self.assertUpdateSucceeds(self.bound_location.replace('%2B', '+', 1))
 
4151
 
 
4152
    def test_tilda(self):
 
4153
        # Embed ~ in the middle of the path just to avoid any $HOME
 
4154
        # interpretation
 
4155
        self.make_master_and_checkout('mas~ter', 'checkout')
 
4156
        self.assertUpdateSucceeds(self.bound_location.replace('%2E', '~', 1))
 
4157
 
 
4158
 
 
4159
class TestWithCustomErrorHandler(RemoteBranchTestCase):
 
4160
 
 
4161
    def test_no_context(self):
 
4162
        class OutOfCoffee(errors.BzrError):
 
4163
            """A dummy exception for testing."""
 
4164
 
 
4165
            def __init__(self, urgency):
 
4166
                self.urgency = urgency
 
4167
        remote.no_context_error_translators.register("OutOfCoffee",
 
4168
            lambda err: OutOfCoffee(err.error_args[0]))
 
4169
        transport = MemoryTransport()
 
4170
        client = FakeClient(transport.base)
 
4171
        client.add_expected_call(
 
4172
            'Branch.get_stacked_on_url', ('quack/',),
 
4173
            'error', ('NotStacked',))
 
4174
        client.add_expected_call(
 
4175
            'Branch.last_revision_info',
 
4176
            ('quack/',),
 
4177
            'error', ('OutOfCoffee', 'low'))
 
4178
        transport.mkdir('quack')
 
4179
        transport = transport.clone('quack')
 
4180
        branch = self.make_remote_branch(transport, client)
 
4181
        self.assertRaises(OutOfCoffee, branch.last_revision_info)
 
4182
        self.assertFinished(client)
 
4183
 
 
4184
    def test_with_context(self):
 
4185
        class OutOfTea(errors.BzrError):
 
4186
            def __init__(self, branch, urgency):
 
4187
                self.branch = branch
 
4188
                self.urgency = urgency
 
4189
        remote.error_translators.register("OutOfTea",
 
4190
            lambda err, find, path: OutOfTea(err.error_args[0],
 
4191
                find("branch")))
 
4192
        transport = MemoryTransport()
 
4193
        client = FakeClient(transport.base)
 
4194
        client.add_expected_call(
 
4195
            'Branch.get_stacked_on_url', ('quack/',),
 
4196
            'error', ('NotStacked',))
 
4197
        client.add_expected_call(
 
4198
            'Branch.last_revision_info',
 
4199
            ('quack/',),
 
4200
            'error', ('OutOfTea', 'low'))
 
4201
        transport.mkdir('quack')
 
4202
        transport = transport.clone('quack')
 
4203
        branch = self.make_remote_branch(transport, client)
 
4204
        self.assertRaises(OutOfTea, branch.last_revision_info)
 
4205
        self.assertFinished(client)
 
4206
 
 
4207
 
 
4208
class TestRepositoryPack(TestRemoteRepository):
 
4209
 
 
4210
    def test_pack(self):
 
4211
        transport_path = 'quack'
 
4212
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
4213
        client.add_expected_call(
 
4214
            'Repository.lock_write', ('quack/', ''),
 
4215
            'success', ('ok', 'token'))
 
4216
        client.add_expected_call(
 
4217
            'Repository.pack', ('quack/', 'token', 'False'),
 
4218
            'success', ('ok',), )
 
4219
        client.add_expected_call(
 
4220
            'Repository.unlock', ('quack/', 'token'),
 
4221
            'success', ('ok', ))
 
4222
        repo.pack()
 
4223
 
 
4224
    def test_pack_with_hint(self):
 
4225
        transport_path = 'quack'
 
4226
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
4227
        client.add_expected_call(
 
4228
            'Repository.lock_write', ('quack/', ''),
 
4229
            'success', ('ok', 'token'))
 
4230
        client.add_expected_call(
 
4231
            'Repository.pack', ('quack/', 'token', 'False'),
 
4232
            'success', ('ok',), )
 
4233
        client.add_expected_call(
 
4234
            'Repository.unlock', ('quack/', 'token', 'False'),
 
4235
            'success', ('ok', ))
 
4236
        repo.pack(['hinta', 'hintb'])
 
4237
 
 
4238
 
 
4239
class TestRepositoryIterInventories(TestRemoteRepository):
 
4240
    """Test Repository.iter_inventories."""
 
4241
 
 
4242
    def _serialize_inv_delta(self, old_name, new_name, delta):
 
4243
        serializer = inventory_delta.InventoryDeltaSerializer(True, False)
 
4244
        return "".join(serializer.delta_to_lines(old_name, new_name, delta))
 
4245
 
 
4246
    def test_single_empty(self):
 
4247
        transport_path = 'quack'
 
4248
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
4249
        fmt = bzrdir.format_registry.get('2a')().repository_format
 
4250
        repo._format = fmt
 
4251
        stream = [('inventory-deltas', [
 
4252
            versionedfile.FulltextContentFactory('somerevid', None, None,
 
4253
                self._serialize_inv_delta('null:', 'somerevid', []))])]
 
4254
        client.add_expected_call(
 
4255
            'VersionedFileRepository.get_inventories', ('quack/', 'unordered'),
 
4256
            'success', ('ok', ),
 
4257
            _stream_to_byte_stream(stream, fmt))
 
4258
        ret = list(repo.iter_inventories(["somerevid"]))
 
4259
        self.assertLength(1, ret)
 
4260
        inv = ret[0]
 
4261
        self.assertEquals("somerevid", inv.revision_id)
 
4262
 
 
4263
    def test_empty(self):
 
4264
        transport_path = 'quack'
 
4265
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
4266
        ret = list(repo.iter_inventories([]))
 
4267
        self.assertEquals(ret, [])
 
4268
 
 
4269
    def test_missing(self):
 
4270
        transport_path = 'quack'
 
4271
        repo, client = self.setup_fake_client_and_repository(transport_path)
 
4272
        client.add_expected_call(
 
4273
            'VersionedFileRepository.get_inventories', ('quack/', 'unordered'),
 
4274
            'success', ('ok', ), iter([]))
 
4275
        self.assertRaises(errors.NoSuchRevision, list, repo.iter_inventories(
 
4276
            ["somerevid"]))