~bzr-pqm/bzr/bzr.dev

5273.1.5 by Vincent Ladeuil
Merge bzr.dev into cleanup
1
# Copyright (C) 2009, 2010 Canonical Ltd
4000.5.11 by Jelmer Vernooij
Improve tests for InterBranch.pull.
2
#
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
4000.5.16 by Jelmer Vernooij
Fix FSF address.
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
4000.5.11 by Jelmer Vernooij
Improve tests for InterBranch.pull.
16
17
"""Tests for InterBranch.pull behaviour."""
18
19
from bzrlib.branch import Branch
20
from bzrlib.bzrdir import BzrDir
21
from bzrlib import errors
22
from bzrlib.memorytree import MemoryTree
23
from bzrlib.revision import NULL_REVISION
24
from bzrlib.tests.per_interbranch import TestCaseWithInterBranch
25
26
4000.5.23 by Jelmer Vernooij
Review feedback from Ian; add some comments about origin of tests, comment on further work in pull.
27
# The tests here are based on the tests in 
4523.1.1 by Martin Pool
Rename tests.branch_implementations to per_branch
28
# bzrlib.tests.per_branch.test_pull
4000.5.23 by Jelmer Vernooij
Review feedback from Ian; add some comments about origin of tests, comment on further work in pull.
29
30
4000.5.11 by Jelmer Vernooij
Improve tests for InterBranch.pull.
31
class TestPull(TestCaseWithInterBranch):
32
33
    def test_pull_convergence_simple(self):
34
        # when revisions are pulled, the left-most accessible parents must
35
        # become the revision-history.
4000.5.20 by Jelmer Vernooij
Fix InterBranch.pull tests.
36
        parent = self.make_from_branch_and_tree('parent')
4000.5.11 by Jelmer Vernooij
Improve tests for InterBranch.pull.
37
        parent.commit('1st post', rev_id='P1', allow_pointless=True)
38
        mine = self.sprout_to(parent.bzrdir, 'mine').open_workingtree()
39
        mine.commit('my change', rev_id='M1', allow_pointless=True)
40
        parent.merge_from_branch(mine.branch)
41
        parent.commit('merge my change', rev_id='P2')
42
        mine.pull(parent.branch)
6165.2.1 by Jelmer Vernooij
Avoid using revision_history in the testsuite, in preparation of deprecating it.
43
        self.assertEqual('P2', mine.branch.last_revision())
4000.5.11 by Jelmer Vernooij
Improve tests for InterBranch.pull.
44
45
    def test_pull_merged_indirect(self):
46
        # it should be possible to do a pull from one branch into another
47
        # when the tip of the target was merged into the source branch
48
        # via a third branch - so its buried in the ancestry and is not
49
        # directly accessible.
4000.5.20 by Jelmer Vernooij
Fix InterBranch.pull tests.
50
        parent = self.make_from_branch_and_tree('parent')
4000.5.11 by Jelmer Vernooij
Improve tests for InterBranch.pull.
51
        parent.commit('1st post', rev_id='P1', allow_pointless=True)
52
        mine = self.sprout_to(parent.bzrdir, 'mine').open_workingtree()
53
        mine.commit('my change', rev_id='M1', allow_pointless=True)
4000.5.20 by Jelmer Vernooij
Fix InterBranch.pull tests.
54
        other = self.sprout_to(parent.bzrdir, 'other').open_workingtree()
4000.5.11 by Jelmer Vernooij
Improve tests for InterBranch.pull.
55
        other.merge_from_branch(mine.branch)
56
        other.commit('merge my change', rev_id='O2')
57
        parent.merge_from_branch(other.branch)
58
        parent.commit('merge other', rev_id='P2')
59
        mine.pull(parent.branch)
6165.2.1 by Jelmer Vernooij
Avoid using revision_history in the testsuite, in preparation of deprecating it.
60
        self.assertEqual('P2', mine.branch.last_revision())
4000.5.11 by Jelmer Vernooij
Improve tests for InterBranch.pull.
61
62
    def test_pull_updates_checkout_and_master(self):
63
        """Pulling into a checkout updates the checkout and the master branch"""
4000.5.20 by Jelmer Vernooij
Fix InterBranch.pull tests.
64
        master_tree = self.make_from_branch_and_tree('master')
4000.5.11 by Jelmer Vernooij
Improve tests for InterBranch.pull.
65
        rev1 = master_tree.commit('master')
66
        checkout = master_tree.branch.create_checkout('checkout')
4000.5.20 by Jelmer Vernooij
Fix InterBranch.pull tests.
67
        other = self.sprout_to(master_tree.branch.bzrdir, 'other').open_workingtree()
4000.5.11 by Jelmer Vernooij
Improve tests for InterBranch.pull.
68
        rev2 = other.commit('other commit')
69
        # now pull, which should update both checkout and master.
70
        checkout.branch.pull(other.branch)
6165.2.1 by Jelmer Vernooij
Avoid using revision_history in the testsuite, in preparation of deprecating it.
71
        self.assertEqual(rev2, checkout.branch.last_revision())
72
        self.assertEqual(rev2, master_tree.branch.last_revision())
4000.5.11 by Jelmer Vernooij
Improve tests for InterBranch.pull.
73
74
    def test_pull_raises_specific_error_on_master_connection_error(self):
4000.5.20 by Jelmer Vernooij
Fix InterBranch.pull tests.
75
        master_tree = self.make_from_branch_and_tree('master')
4000.5.11 by Jelmer Vernooij
Improve tests for InterBranch.pull.
76
        checkout = master_tree.branch.create_checkout('checkout')
5284.4.1 by Robert Collins
* Fetching was slightly confused about the best code to use and was
77
        other = self.sprout_to(master_tree.branch.bzrdir, 'other').open_branch()
4000.5.11 by Jelmer Vernooij
Improve tests for InterBranch.pull.
78
        # move the branch out of the way on disk to cause a connection
79
        # error.
6155.1.3 by Jelmer Vernooij
Use standard mechanism for destroying branch.
80
        master_tree.branch.bzrdir.destroy_branch()
4000.5.11 by Jelmer Vernooij
Improve tests for InterBranch.pull.
81
        # try to pull, which should raise a BoundBranchConnectionFailure.
82
        self.assertRaises(errors.BoundBranchConnectionFailure,
5284.4.1 by Robert Collins
* Fetching was slightly confused about the best code to use and was
83
                checkout.branch.pull, other)
4000.5.11 by Jelmer Vernooij
Improve tests for InterBranch.pull.
84
85
    def test_pull_returns_result(self):
4000.5.20 by Jelmer Vernooij
Fix InterBranch.pull tests.
86
        parent = self.make_from_branch_and_tree('parent')
4000.5.11 by Jelmer Vernooij
Improve tests for InterBranch.pull.
87
        parent.commit('1st post', rev_id='P1')
88
        mine = self.sprout_to(parent.bzrdir, 'mine').open_workingtree()
89
        mine.commit('my change', rev_id='M1')
90
        result = parent.branch.pull(mine.branch)
91
        self.assertIsNot(None, result)
92
        self.assertIs(mine.branch, result.source_branch)
93
        self.assertIs(parent.branch, result.target_branch)
94
        self.assertIs(parent.branch, result.master_branch)
95
        self.assertIs(None, result.local_branch)
96
        self.assertEqual(1, result.old_revno)
97
        self.assertEqual('P1', result.old_revid)
98
        self.assertEqual(2, result.new_revno)
99
        self.assertEqual('M1', result.new_revid)
6112.4.7 by Jelmer Vernooij
Fix tests.
100
        self.assertEqual([], result.tag_conflicts)
4000.5.11 by Jelmer Vernooij
Improve tests for InterBranch.pull.
101
102
    def test_pull_overwrite(self):
4000.5.20 by Jelmer Vernooij
Fix InterBranch.pull tests.
103
        tree_a = self.make_from_branch_and_tree('tree_a')
4000.5.11 by Jelmer Vernooij
Improve tests for InterBranch.pull.
104
        tree_a.commit('message 1')
105
        tree_b = self.sprout_to(tree_a.bzrdir, 'tree_b').open_workingtree()
106
        tree_a.commit('message 2', rev_id='rev2a')
107
        tree_b.commit('message 2', rev_id='rev2b')
108
        self.assertRaises(errors.DivergedBranches, tree_a.pull, tree_b.branch)
109
        self.assertRaises(errors.DivergedBranches,
110
                          tree_a.branch.pull, tree_b.branch,
111
                          overwrite=False, stop_revision='rev2b')
112
        # It should not have updated the branch tip, but it should have fetched
113
        # the revision
114
        self.assertEqual('rev2a', tree_a.branch.last_revision())
115
        self.assertTrue(tree_a.branch.repository.has_revision('rev2b'))
116
        tree_a.branch.pull(tree_b.branch, overwrite=True,
117
                           stop_revision='rev2b')
118
        self.assertEqual('rev2b', tree_a.branch.last_revision())
6165.2.1 by Jelmer Vernooij
Avoid using revision_history in the testsuite, in preparation of deprecating it.
119
        self.assertEqual(tree_b.branch.last_revision(),
120
                         tree_a.branch.last_revision())
4000.5.11 by Jelmer Vernooij
Improve tests for InterBranch.pull.
121
122
123
class TestPullHook(TestCaseWithInterBranch):
124
125
    def setUp(self):
126
        self.hook_calls = []
127
        TestCaseWithInterBranch.setUp(self)
128
129
    def capture_post_pull_hook(self, result):
130
        """Capture post pull hook calls to self.hook_calls.
131
132
        The call is logged, as is some state of the two branches.
133
        """
134
        if result.local_branch:
135
            local_locked = result.local_branch.is_locked()
136
            local_base = result.local_branch.base
137
        else:
138
            local_locked = None
139
            local_base = None
140
        self.hook_calls.append(
141
            ('post_pull', result.source_branch, local_base,
142
             result.master_branch.base, result.old_revno,
143
             result.old_revid,
144
             result.new_revno, result.new_revid,
145
             result.source_branch.is_locked(), local_locked,
146
             result.master_branch.is_locked()))
147
148
    def test_post_pull_empty_history(self):
149
        target = self.make_to_branch('target')
4000.5.20 by Jelmer Vernooij
Fix InterBranch.pull tests.
150
        source = self.make_from_branch('source')
4000.5.11 by Jelmer Vernooij
Improve tests for InterBranch.pull.
151
        Branch.hooks.install_named_hook('post_pull',
152
            self.capture_post_pull_hook, None)
153
        target.pull(source)
154
        # with nothing there we should still get a notification, and
155
        # have both branches locked at the notification time.
156
        self.assertEqual([
157
            ('post_pull', source, None, target.base, 0, NULL_REVISION,
158
             0, NULL_REVISION, True, None, True)
159
            ],
160
            self.hook_calls)
161
162
    def test_post_pull_bound_branch(self):
163
        # pulling to a bound branch should pass in the master branch to the
164
        # hook, allowing the correct number of emails to be sent, while still
165
        # allowing hooks that want to modify the target to do so to both
166
        # instances.
167
        target = self.make_to_branch('target')
4000.5.20 by Jelmer Vernooij
Fix InterBranch.pull tests.
168
        local = self.make_from_branch('local')
4000.5.11 by Jelmer Vernooij
Improve tests for InterBranch.pull.
169
        try:
170
            local.bind(target)
171
        except errors.UpgradeRequired:
172
            # We can't bind this format to itself- typically it is the local
173
            # branch that doesn't support binding.  As of May 2007
174
            # remotebranches can't be bound.  Let's instead make a new local
175
            # branch of the default type, which does allow binding.
176
            # See https://bugs.launchpad.net/bzr/+bug/112020
177
            local = BzrDir.create_branch_convenience('local2')
178
            local.bind(target)
4000.5.20 by Jelmer Vernooij
Fix InterBranch.pull tests.
179
        source = self.make_from_branch('source')
4000.5.11 by Jelmer Vernooij
Improve tests for InterBranch.pull.
180
        Branch.hooks.install_named_hook('post_pull',
181
            self.capture_post_pull_hook, None)
182
        local.pull(source)
183
        # with nothing there we should still get a notification, and
184
        # have both branches locked at the notification time.
185
        self.assertEqual([
186
            ('post_pull', source, local.base, target.base, 0, NULL_REVISION,
187
             0, NULL_REVISION, True, True, True)
188
            ],
189
            self.hook_calls)
190
191
    def test_post_pull_nonempty_history(self):
192
        target = self.make_to_branch_and_memory_tree('target')
193
        target.lock_write()
194
        target.add('')
195
        rev1 = target.commit('rev 1')
196
        target.unlock()
197
        sourcedir = target.bzrdir.clone(self.get_url('source'))
198
        source = MemoryTree.create_on_branch(sourcedir.open_branch())
199
        rev2 = source.commit('rev 2')
200
        Branch.hooks.install_named_hook('post_pull',
201
            self.capture_post_pull_hook, None)
202
        target.branch.pull(source.branch)
203
        # with nothing there we should still get a notification, and
204
        # have both branches locked at the notification time.
205
        self.assertEqual([
206
            ('post_pull', source.branch, None, target.branch.base, 1, rev1,
207
             2, rev2, True, None, True)
208
            ],
209
            self.hook_calls)