/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
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
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
19
from breezy.branch import Branch
20
from breezy.controldir import ControlDir
21
from breezy import errors
22
from breezy.memorytree import MemoryTree
23
from breezy.revision import NULL_REVISION
6874.1.2 by Jelmer Vernooij
Consistently use Branch.user_url.
24
from breezy.tests import TestNotApplicable
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
25
from breezy.tests.per_interbranch import TestCaseWithInterBranch
4000.5.11 by Jelmer Vernooij
Improve tests for InterBranch.pull.
26
27
4000.5.23 by Jelmer Vernooij
Review feedback from Ian; add some comments about origin of tests, comment on further work in pull.
28
# The tests here are based on the tests in 
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
29
# breezy.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.
30
31
4000.5.11 by Jelmer Vernooij
Improve tests for InterBranch.pull.
32
class TestPull(TestCaseWithInterBranch):
33
34
    def test_pull_convergence_simple(self):
35
        # when revisions are pulled, the left-most accessible parents must
36
        # become the revision-history.
4000.5.20 by Jelmer Vernooij
Fix InterBranch.pull tests.
37
        parent = self.make_from_branch_and_tree('parent')
6747.3.1 by Jelmer Vernooij
Avoid more uses of revision_id.
38
        parent.commit('1st post', allow_pointless=True)
6883.21.1 by Jelmer Vernooij
Allow InterBranch formats to raise NoRoundtrippingSupport.
39
        try:
40
            mine = self.sprout_to(parent.controldir, 'mine').open_workingtree()
41
        except errors.NoRoundtrippingSupport:
42
            raise TestNotApplicable(
43
                'lossless push between %r and %r not supported' %
44
                (self.branch_format_from, self.branch_format_to))
6747.3.1 by Jelmer Vernooij
Avoid more uses of revision_id.
45
        mine.commit('my change', allow_pointless=True)
6883.21.2 by Jelmer Vernooij
One more.
46
        try:
47
            parent.merge_from_branch(mine.branch)
48
        except errors.NoRoundtrippingSupport:
49
            raise TestNotApplicable(
50
                'lossless push between %r and %r not supported' %
51
                (self.branch_format_from, self.branch_format_to))
6747.3.1 by Jelmer Vernooij
Avoid more uses of revision_id.
52
        p2 = parent.commit('merge my change')
4000.5.11 by Jelmer Vernooij
Improve tests for InterBranch.pull.
53
        mine.pull(parent.branch)
6747.3.1 by Jelmer Vernooij
Avoid more uses of revision_id.
54
        self.assertEqual(p2, mine.branch.last_revision())
4000.5.11 by Jelmer Vernooij
Improve tests for InterBranch.pull.
55
56
    def test_pull_merged_indirect(self):
57
        # it should be possible to do a pull from one branch into another
58
        # when the tip of the target was merged into the source branch
59
        # via a third branch - so its buried in the ancestry and is not
60
        # directly accessible.
4000.5.20 by Jelmer Vernooij
Fix InterBranch.pull tests.
61
        parent = self.make_from_branch_and_tree('parent')
6747.3.1 by Jelmer Vernooij
Avoid more uses of revision_id.
62
        parent.commit('1st post', allow_pointless=True)
6883.21.1 by Jelmer Vernooij
Allow InterBranch formats to raise NoRoundtrippingSupport.
63
        try:
64
            mine = self.sprout_to(parent.controldir, 'mine').open_workingtree()
65
        except errors.NoRoundtrippingSupport:
66
            raise TestNotApplicable(
67
                'lossless push between %r and %r not supported' %
68
                (self.branch_format_from, self.branch_format_to))
6747.3.1 by Jelmer Vernooij
Avoid more uses of revision_id.
69
        mine.commit('my change', allow_pointless=True)
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
70
        other = self.sprout_to(parent.controldir, 'other').open_workingtree()
4000.5.11 by Jelmer Vernooij
Improve tests for InterBranch.pull.
71
        other.merge_from_branch(mine.branch)
6747.3.1 by Jelmer Vernooij
Avoid more uses of revision_id.
72
        other.commit('merge my change')
6883.21.2 by Jelmer Vernooij
One more.
73
        try:
74
            parent.merge_from_branch(other.branch)
75
        except errors.NoRoundtrippingSupport:
76
            raise TestNotApplicable(
77
                'lossless push between %r and %r not supported' %
78
                (self.branch_format_from, self.branch_format_to))
6747.3.1 by Jelmer Vernooij
Avoid more uses of revision_id.
79
        p2 = parent.commit('merge other')
4000.5.11 by Jelmer Vernooij
Improve tests for InterBranch.pull.
80
        mine.pull(parent.branch)
6747.3.1 by Jelmer Vernooij
Avoid more uses of revision_id.
81
        self.assertEqual(p2, mine.branch.last_revision())
4000.5.11 by Jelmer Vernooij
Improve tests for InterBranch.pull.
82
83
    def test_pull_updates_checkout_and_master(self):
84
        """Pulling into a checkout updates the checkout and the master branch"""
4000.5.20 by Jelmer Vernooij
Fix InterBranch.pull tests.
85
        master_tree = self.make_from_branch_and_tree('master')
6747.3.1 by Jelmer Vernooij
Avoid more uses of revision_id.
86
        master_tree.commit('master')
4000.5.11 by Jelmer Vernooij
Improve tests for InterBranch.pull.
87
        checkout = master_tree.branch.create_checkout('checkout')
6883.21.2 by Jelmer Vernooij
One more.
88
        try:
89
            other = self.sprout_to(master_tree.branch.controldir, 'other').open_workingtree()
90
        except errors.NoRoundtrippingSupport:
91
            raise TestNotApplicable(
92
                'lossless push between %r and %r not supported' %
93
                (self.branch_format_from, self.branch_format_to))
4000.5.11 by Jelmer Vernooij
Improve tests for InterBranch.pull.
94
        rev2 = other.commit('other commit')
95
        # now pull, which should update both checkout and master.
6883.21.3 by Jelmer Vernooij
Some more.
96
        try:
97
            checkout.branch.pull(other.branch)
98
        except errors.NoRoundtrippingSupport:
99
            raise TestNotApplicable(
100
                'lossless push between %r and %r not supported' %
101
                (self.branch_format_from, self.branch_format_to))
6165.4.4 by Jelmer Vernooij
Avoid .revision_history().
102
        self.assertEqual(rev2, checkout.branch.last_revision())
103
        self.assertEqual(rev2, master_tree.branch.last_revision())
4000.5.11 by Jelmer Vernooij
Improve tests for InterBranch.pull.
104
105
    def test_pull_raises_specific_error_on_master_connection_error(self):
4000.5.20 by Jelmer Vernooij
Fix InterBranch.pull tests.
106
        master_tree = self.make_from_branch_and_tree('master')
4000.5.11 by Jelmer Vernooij
Improve tests for InterBranch.pull.
107
        checkout = master_tree.branch.create_checkout('checkout')
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
108
        other = self.sprout_to(master_tree.branch.controldir, 'other').open_branch()
4000.5.11 by Jelmer Vernooij
Improve tests for InterBranch.pull.
109
        # move the branch out of the way on disk to cause a connection
110
        # error.
6874.1.2 by Jelmer Vernooij
Consistently use Branch.user_url.
111
        try:
112
            master_tree.branch.controldir.destroy_branch()
113
        except errors.UnsupportedOperation:
114
            raise TestNotApplicable(
115
                'control format does not support destroying default branch')
4000.5.11 by Jelmer Vernooij
Improve tests for InterBranch.pull.
116
        # try to pull, which should raise a BoundBranchConnectionFailure.
117
        self.assertRaises(errors.BoundBranchConnectionFailure,
6747.3.1 by Jelmer Vernooij
Avoid more uses of revision_id.
118
                          checkout.branch.pull, other)
4000.5.11 by Jelmer Vernooij
Improve tests for InterBranch.pull.
119
120
    def test_pull_returns_result(self):
4000.5.20 by Jelmer Vernooij
Fix InterBranch.pull tests.
121
        parent = self.make_from_branch_and_tree('parent')
6747.3.1 by Jelmer Vernooij
Avoid more uses of revision_id.
122
        p1 = parent.commit('1st post')
6883.21.1 by Jelmer Vernooij
Allow InterBranch formats to raise NoRoundtrippingSupport.
123
        try:
124
            mine = self.sprout_to(parent.controldir, 'mine').open_workingtree()
125
        except errors.NoRoundtrippingSupport:
126
            raise TestNotApplicable(
127
                'lossless push between %r and %r not supported' %
128
                (self.branch_format_from, self.branch_format_to))
6747.3.1 by Jelmer Vernooij
Avoid more uses of revision_id.
129
        m1 = mine.commit('my change')
6883.21.2 by Jelmer Vernooij
One more.
130
        try:
131
            result = parent.branch.pull(mine.branch)
132
        except errors.NoRoundtrippingSupport:
133
            raise TestNotApplicable(
134
                'lossless push between %r and %r not supported' %
135
                (self.branch_format_from, self.branch_format_to))
4000.5.11 by Jelmer Vernooij
Improve tests for InterBranch.pull.
136
        self.assertIsNot(None, result)
137
        self.assertIs(mine.branch, result.source_branch)
138
        self.assertIs(parent.branch, result.target_branch)
139
        self.assertIs(parent.branch, result.master_branch)
140
        self.assertIs(None, result.local_branch)
141
        self.assertEqual(1, result.old_revno)
6747.3.1 by Jelmer Vernooij
Avoid more uses of revision_id.
142
        self.assertEqual(p1, result.old_revid)
4000.5.11 by Jelmer Vernooij
Improve tests for InterBranch.pull.
143
        self.assertEqual(2, result.new_revno)
6747.3.1 by Jelmer Vernooij
Avoid more uses of revision_id.
144
        self.assertEqual(m1, result.new_revid)
6112.4.7 by Jelmer Vernooij
Fix tests.
145
        self.assertEqual([], result.tag_conflicts)
4000.5.11 by Jelmer Vernooij
Improve tests for InterBranch.pull.
146
147
    def test_pull_overwrite(self):
4000.5.20 by Jelmer Vernooij
Fix InterBranch.pull tests.
148
        tree_a = self.make_from_branch_and_tree('tree_a')
4000.5.11 by Jelmer Vernooij
Improve tests for InterBranch.pull.
149
        tree_a.commit('message 1')
6883.21.1 by Jelmer Vernooij
Allow InterBranch formats to raise NoRoundtrippingSupport.
150
        try:
151
            tree_b = self.sprout_to(tree_a.controldir, 'tree_b').open_workingtree()
152
        except errors.NoRoundtrippingSupport:
153
            raise TestNotApplicable(
154
                'lossless push between %r and %r not supported' %
155
                (self.branch_format_from, self.branch_format_to))
156
6862.1.1 by Jelmer Vernooij
Add some uniqueness to commit messages.
157
        rev2a = tree_a.commit('message 2a')
158
        rev2b = tree_b.commit('message 2b')
6883.21.3 by Jelmer Vernooij
Some more.
159
        try:
160
            self.assertRaises(errors.DivergedBranches, tree_a.pull, tree_b.branch)
161
        except errors.NoRoundtrippingSupport:
162
            raise TestNotApplicable(
163
                'lossless push between %r and %r not supported' %
164
                (self.branch_format_from, self.branch_format_to))
4000.5.11 by Jelmer Vernooij
Improve tests for InterBranch.pull.
165
        self.assertRaises(errors.DivergedBranches,
166
                          tree_a.branch.pull, tree_b.branch,
6747.3.1 by Jelmer Vernooij
Avoid more uses of revision_id.
167
                          overwrite=False, stop_revision=rev2b)
4000.5.11 by Jelmer Vernooij
Improve tests for InterBranch.pull.
168
        # It should not have updated the branch tip, but it should have fetched
6217.4.1 by Jelmer Vernooij
Add RepositoryFormat.supports_invisible_revisions.
169
        # the revision if the repository supports "invisible" revisions.
6747.3.1 by Jelmer Vernooij
Avoid more uses of revision_id.
170
        self.assertEqual(rev2a, tree_a.branch.last_revision())
6217.4.2 by Jelmer Vernooij
s/invisible/unreferenced.
171
        if tree_a.branch.repository._format.supports_unreferenced_revisions:
6747.3.1 by Jelmer Vernooij
Avoid more uses of revision_id.
172
            self.assertTrue(tree_a.branch.repository.has_revision(rev2b))
4000.5.11 by Jelmer Vernooij
Improve tests for InterBranch.pull.
173
        tree_a.branch.pull(tree_b.branch, overwrite=True,
6747.3.1 by Jelmer Vernooij
Avoid more uses of revision_id.
174
                           stop_revision=rev2b)
175
        self.assertEqual(rev2b, tree_a.branch.last_revision())
6165.4.4 by Jelmer Vernooij
Avoid .revision_history().
176
        self.assertEqual(tree_b.branch.last_revision(),
177
                         tree_a.branch.last_revision())
4000.5.11 by Jelmer Vernooij
Improve tests for InterBranch.pull.
178
179
180
class TestPullHook(TestCaseWithInterBranch):
181
182
    def setUp(self):
183
        self.hook_calls = []
6552.1.4 by Vincent Ladeuil
Remaining tests matching setup(self) that can be rewritten with super().
184
        super(TestPullHook, self).setUp()
4000.5.11 by Jelmer Vernooij
Improve tests for InterBranch.pull.
185
186
    def capture_post_pull_hook(self, result):
187
        """Capture post pull hook calls to self.hook_calls.
188
189
        The call is logged, as is some state of the two branches.
190
        """
191
        if result.local_branch:
192
            local_locked = result.local_branch.is_locked()
193
            local_base = result.local_branch.base
194
        else:
195
            local_locked = None
196
            local_base = None
197
        self.hook_calls.append(
198
            ('post_pull', result.source_branch, local_base,
199
             result.master_branch.base, result.old_revno,
200
             result.old_revid,
201
             result.new_revno, result.new_revid,
202
             result.source_branch.is_locked(), local_locked,
203
             result.master_branch.is_locked()))
204
205
    def test_post_pull_empty_history(self):
206
        target = self.make_to_branch('target')
4000.5.20 by Jelmer Vernooij
Fix InterBranch.pull tests.
207
        source = self.make_from_branch('source')
4000.5.11 by Jelmer Vernooij
Improve tests for InterBranch.pull.
208
        Branch.hooks.install_named_hook('post_pull',
209
            self.capture_post_pull_hook, None)
210
        target.pull(source)
211
        # with nothing there we should still get a notification, and
212
        # have both branches locked at the notification time.
213
        self.assertEqual([
214
            ('post_pull', source, None, target.base, 0, NULL_REVISION,
215
             0, NULL_REVISION, True, None, True)
216
            ],
217
            self.hook_calls)
218
219
    def test_post_pull_bound_branch(self):
220
        # pulling to a bound branch should pass in the master branch to the
221
        # hook, allowing the correct number of emails to be sent, while still
222
        # allowing hooks that want to modify the target to do so to both
223
        # instances.
224
        target = self.make_to_branch('target')
4000.5.20 by Jelmer Vernooij
Fix InterBranch.pull tests.
225
        local = self.make_from_branch('local')
4000.5.11 by Jelmer Vernooij
Improve tests for InterBranch.pull.
226
        try:
227
            local.bind(target)
228
        except errors.UpgradeRequired:
229
            # We can't bind this format to itself- typically it is the local
230
            # branch that doesn't support binding.  As of May 2007
231
            # remotebranches can't be bound.  Let's instead make a new local
232
            # branch of the default type, which does allow binding.
233
            # See https://bugs.launchpad.net/bzr/+bug/112020
6472.2.2 by Jelmer Vernooij
Use controldir rather than bzrdir in a couple more places.
234
            local = ControlDir.create_branch_convenience('local2')
4000.5.11 by Jelmer Vernooij
Improve tests for InterBranch.pull.
235
            local.bind(target)
4000.5.20 by Jelmer Vernooij
Fix InterBranch.pull tests.
236
        source = self.make_from_branch('source')
4000.5.11 by Jelmer Vernooij
Improve tests for InterBranch.pull.
237
        Branch.hooks.install_named_hook('post_pull',
238
            self.capture_post_pull_hook, None)
239
        local.pull(source)
240
        # with nothing there we should still get a notification, and
241
        # have both branches locked at the notification time.
242
        self.assertEqual([
243
            ('post_pull', source, local.base, target.base, 0, NULL_REVISION,
244
             0, NULL_REVISION, True, True, True)
245
            ],
246
            self.hook_calls)
247
248
    def test_post_pull_nonempty_history(self):
249
        target = self.make_to_branch_and_memory_tree('target')
250
        target.lock_write()
251
        target.add('')
252
        rev1 = target.commit('rev 1')
253
        target.unlock()
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
254
        sourcedir = target.controldir.clone(self.get_url('source'))
4000.5.11 by Jelmer Vernooij
Improve tests for InterBranch.pull.
255
        source = MemoryTree.create_on_branch(sourcedir.open_branch())
256
        rev2 = source.commit('rev 2')
257
        Branch.hooks.install_named_hook('post_pull',
258
            self.capture_post_pull_hook, None)
259
        target.branch.pull(source.branch)
260
        # with nothing there we should still get a notification, and
261
        # have both branches locked at the notification time.
262
        self.assertEqual([
263
            ('post_pull', source.branch, None, target.branch.base, 1, rev1,
264
             2, rev2, True, None, True)
265
            ],
266
            self.hook_calls)