/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
2245.1.1 by Robert Collins
New Branch hooks facility, with one initial hook 'set_rh' which triggers
1
# Copyright (C) 2007 Canonical Ltd
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
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
2245.1.2 by Robert Collins
Remove the static DefaultHooks method from Branch, replacing it with a derived dict BranchHooks object, which is easier to use and provides a place to put the policy-checking add method discussed on list.
17
"""Tests that branch classes implement hook callouts correctly."""
2245.1.1 by Robert Collins
New Branch hooks facility, with one initial hook 'set_rh' which triggers
18
3681.1.3 by Robert Collins
Update branch open tests to accomodate stacking.
19
from bzrlib.branch import Branch, ChangeBranchTipParams
3577.1.1 by Andrew Bennetts
Cherry-pick TipChangeRejected changes from pre-branch-tip-changed-hook loom.
20
from bzrlib.errors import HookFailed, TipChangeRejected
3681.1.3 by Robert Collins
Update branch open tests to accomodate stacking.
21
from bzrlib.remote import RemoteBranch
3331.1.2 by James Henstridge
Add calls to set_last_revision_info hook to both BzrBranch and
22
from bzrlib.revision import NULL_REVISION
2245.1.1 by Robert Collins
New Branch hooks facility, with one initial hook 'set_rh' which triggers
23
from bzrlib.tests import TestCaseWithMemoryTransport
24
25
4005.2.1 by Robert Collins
Fix RemoteBranch to be used correctly in tests using bzr+ssh, to fire off Branch hooks correctly, and improve the branch_implementations tests to check that making a branch gets the right format under test.
26
class ChangeBranchTipTestCase(TestCaseWithMemoryTransport):
27
    """Base TestCase for testing pre/post_change_branch_tip hooks."""
28
29
    def install_logging_hook(self, prefix):
30
        """Add a hook that logs calls made to it.
31
32
        :returns: the list that the calls will be appended to.
33
        """
34
        hook_calls = []
35
        Branch.hooks.install_named_hook(
36
            prefix + '_change_branch_tip', hook_calls.append, None)
37
        return hook_calls
38
39
    def make_branch_with_revision_ids(self, *revision_ids):
40
        """Makes a branch with the given commits."""
41
        tree = self.make_branch_and_memory_tree('source')
42
        tree.lock_write()
43
        tree.add('')
44
        for revision_id in revision_ids:
45
            tree.commit(u'Message of ' + revision_id.decode('utf8'),
46
                        rev_id=revision_id)
47
        tree.unlock()
48
        branch = tree.branch
49
        return branch
50
51
    def assertHookCalls(self, expected_params, branch, hook_calls=None,
52
        pre=False):
53
        if hook_calls is None:
54
            hook_calls = self.hook_calls
55
        if isinstance(branch, RemoteBranch):
56
            # For a remote branch, both the server and the client will raise
57
            # this hook, and we see both in the test environment. The remote
58
            # instance comes in between the clients - the client doe pre, the
59
            # server does pre, the server does post, the client does post.
60
            if pre:
61
                offset = 0
62
            else:
63
                offset = 1
64
            self.assertEqual(expected_params, hook_calls[offset])
65
            self.assertEqual(2, len(hook_calls))
66
        else:
67
            self.assertEqual([expected_params], hook_calls)
68
69
70
class TestSetRevisionHistoryHook(ChangeBranchTipTestCase):
2245.1.1 by Robert Collins
New Branch hooks facility, with one initial hook 'set_rh' which triggers
71
72
    def setUp(self):
73
        self.hook_calls = []
74
        TestCaseWithMemoryTransport.setUp(self)
75
76
    def capture_set_rh_hook(self, branch, rev_history):
2246.1.3 by Robert Collins
New branch hooks: post_push, post_pull, post_commit, post_uncommit. These
77
        """Capture post set-rh hook calls to self.hook_calls.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
78
2246.1.3 by Robert Collins
New branch hooks: post_push, post_pull, post_commit, post_uncommit. These
79
        The call is logged, as is some state of the branch.
2245.1.1 by Robert Collins
New Branch hooks facility, with one initial hook 'set_rh' which triggers
80
        """
81
        self.hook_calls.append(
82
            ('set_rh', branch, rev_history, branch.is_locked()))
83
84
    def test_set_rh_empty_history(self):
85
        branch = self.make_branch('source')
3256.2.15 by Daniel Watkins
Updated uses of Hooks.install_hook to Hooks.install_named_hook in tests.branch_implementation.test_hooks.
86
        Branch.hooks.install_named_hook('set_rh', self.capture_set_rh_hook,
87
                                        None)
2245.1.1 by Robert Collins
New Branch hooks facility, with one initial hook 'set_rh' which triggers
88
        branch.set_revision_history([])
4005.2.1 by Robert Collins
Fix RemoteBranch to be used correctly in tests using bzr+ssh, to fire off Branch hooks correctly, and improve the branch_implementations tests to check that making a branch gets the right format under test.
89
        expected_params = ('set_rh', branch, [], True)
90
        self.assertHookCalls(expected_params, branch)
2245.1.1 by Robert Collins
New Branch hooks facility, with one initial hook 'set_rh' which triggers
91
92
    def test_set_rh_nonempty_history(self):
2230.3.20 by Aaron Bentley
Add hooking for set_revision_history
93
        tree = self.make_branch_and_memory_tree('source')
94
        tree.lock_write()
95
        tree.add('')
2696.3.7 by Martin Pool
Update hook test to cope with branches that can't set their last revision to one that's not present
96
        tree.commit('another commit', rev_id='f\xc2\xb5')
2230.3.20 by Aaron Bentley
Add hooking for set_revision_history
97
        tree.commit('empty commit', rev_id='foo')
98
        tree.unlock()
99
        branch = tree.branch
3256.2.15 by Daniel Watkins
Updated uses of Hooks.install_hook to Hooks.install_named_hook in tests.branch_implementation.test_hooks.
100
        Branch.hooks.install_named_hook('set_rh', self.capture_set_rh_hook,
101
                                        None)
2696.3.7 by Martin Pool
Update hook test to cope with branches that can't set their last revision to one that's not present
102
        # some branches require that their history be set to a revision in the
103
        # repository
2309.4.10 by John Arbash Meinel
(fixed) Fix the last few tests that were explicitly passing around unicode ids
104
        branch.set_revision_history(['f\xc2\xb5'])
4005.2.1 by Robert Collins
Fix RemoteBranch to be used correctly in tests using bzr+ssh, to fire off Branch hooks correctly, and improve the branch_implementations tests to check that making a branch gets the right format under test.
105
        expected_params =('set_rh', branch, ['f\xc2\xb5'], True)
106
        self.assertHookCalls(expected_params, branch)
2245.1.1 by Robert Collins
New Branch hooks facility, with one initial hook 'set_rh' which triggers
107
108
    def test_set_rh_branch_is_locked(self):
109
        branch = self.make_branch('source')
3256.2.15 by Daniel Watkins
Updated uses of Hooks.install_hook to Hooks.install_named_hook in tests.branch_implementation.test_hooks.
110
        Branch.hooks.install_named_hook('set_rh', self.capture_set_rh_hook,
111
                                        None)
2245.1.1 by Robert Collins
New Branch hooks facility, with one initial hook 'set_rh' which triggers
112
        branch.set_revision_history([])
4005.2.1 by Robert Collins
Fix RemoteBranch to be used correctly in tests using bzr+ssh, to fire off Branch hooks correctly, and improve the branch_implementations tests to check that making a branch gets the right format under test.
113
        expected_params = ('set_rh', branch, [], True)
114
        self.assertHookCalls(expected_params, branch)
2245.1.1 by Robert Collins
New Branch hooks facility, with one initial hook 'set_rh' which triggers
115
116
    def test_set_rh_calls_all_hooks_no_errors(self):
117
        branch = self.make_branch('source')
3256.2.15 by Daniel Watkins
Updated uses of Hooks.install_hook to Hooks.install_named_hook in tests.branch_implementation.test_hooks.
118
        Branch.hooks.install_named_hook('set_rh', self.capture_set_rh_hook,
119
                                        None)
120
        Branch.hooks.install_named_hook('set_rh', self.capture_set_rh_hook,
121
                                        None)
2245.1.1 by Robert Collins
New Branch hooks facility, with one initial hook 'set_rh' which triggers
122
        branch.set_revision_history([])
4005.2.1 by Robert Collins
Fix RemoteBranch to be used correctly in tests using bzr+ssh, to fire off Branch hooks correctly, and improve the branch_implementations tests to check that making a branch gets the right format under test.
123
        expected_calls = [('set_rh', branch, [], True),
124
            ('set_rh', branch, [], True),
125
            ]
126
        if isinstance(branch, RemoteBranch):
127
            # For a remote branch, both the server and the client will raise
128
            # set_rh, and the server will do so first because that is where
129
            # the change takes place.
130
            self.assertEqual(expected_calls, self.hook_calls[2:])
131
            self.assertEqual(4, len(self.hook_calls))
132
        else:
133
            self.assertEqual(expected_calls, self.hook_calls)
3517.2.5 by Andrew Bennetts
Reduce duplication in test_hooks a little.
134
135
3681.1.1 by Robert Collins
Create a new hook Branch.open. (Robert Collins)
136
class TestOpen(TestCaseWithMemoryTransport):
137
138
    def capture_hook(self, branch):
139
        self.hook_calls.append(branch)
140
141
    def install_hook(self):
142
        self.hook_calls = []
143
        Branch.hooks.install_named_hook('open', self.capture_hook, None)
144
145
    def test_create(self):
146
        self.install_hook()
147
        b = self.make_branch('.')
4005.2.1 by Robert Collins
Fix RemoteBranch to be used correctly in tests using bzr+ssh, to fire off Branch hooks correctly, and improve the branch_implementations tests to check that making a branch gets the right format under test.
148
        if isinstance(b, RemoteBranch):
149
            # RemoteBranch creation:
150
            # - creates the branch via the VFS
151
            # - does a branch open (by creating a RemoteBranch object)
152
            # - this has the same behaviour as simple branch opening, with an
153
            # additional VFS open at the front.
154
            self.assertEqual(b._real_branch, self.hook_calls[0])
155
            self.assertOpenedRemoteBranch(self.hook_calls[1:], b)
156
        else:
157
            self.assertEqual([b], self.hook_calls)
3681.1.1 by Robert Collins
Create a new hook Branch.open. (Robert Collins)
158
159
    def test_open(self):
160
        branch_url = self.make_branch('.').bzrdir.root_transport.base
161
        self.install_hook()
162
        b = Branch.open(branch_url)
3681.1.3 by Robert Collins
Update branch open tests to accomodate stacking.
163
        if isinstance(b, RemoteBranch):
4005.2.1 by Robert Collins
Fix RemoteBranch to be used correctly in tests using bzr+ssh, to fire off Branch hooks correctly, and improve the branch_implementations tests to check that making a branch gets the right format under test.
164
            self.assertOpenedRemoteBranch(self.hook_calls, b)
3681.1.3 by Robert Collins
Update branch open tests to accomodate stacking.
165
        else:
166
            self.assertEqual([b], self.hook_calls)
3681.1.1 by Robert Collins
Create a new hook Branch.open. (Robert Collins)
167
4005.2.1 by Robert Collins
Fix RemoteBranch to be used correctly in tests using bzr+ssh, to fire off Branch hooks correctly, and improve the branch_implementations tests to check that making a branch gets the right format under test.
168
    def assertOpenedRemoteBranch(self, hook_calls, b):
169
        """Assert that the expected calls were recorded for opening 'b'."""
170
        # RemoteBranch open always opens the backing branch to get stacking
171
        # details. As that is done remotely we can't see the branch object
172
        # nor even compare base url's etc. So we just assert that the first
173
        # branch returned is the RemoteBranch, and that the second is a
174
        # Branch but not a RemoteBranch.
175
        self.assertEqual(2, len(hook_calls))
176
        self.assertEqual(b, hook_calls[0])
177
        self.assertIsInstance(hook_calls[1], Branch)
178
        self.assertFalse(isinstance(hook_calls[1], RemoteBranch))
179
3681.1.1 by Robert Collins
Create a new hook Branch.open. (Robert Collins)
180
3517.2.5 by Andrew Bennetts
Reduce duplication in test_hooks a little.
181
class TestPreChangeBranchTip(ChangeBranchTipTestCase):
3517.2.3 by Andrew Bennetts
Better tests for {pre,post}_change_branch_tip hooks.
182
    """Tests for pre_change_branch_tip hook.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
183
3517.2.3 by Andrew Bennetts
Better tests for {pre,post}_change_branch_tip hooks.
184
    Most of these tests are very similar to the tests in
185
    TestPostChangeBranchTip.
186
    """
187
188
    def test_hook_runs_before_change(self):
189
        """The hook runs *before* the branch's last_revision_info has changed.
190
        """
191
        branch = self.make_branch_with_revision_ids('revid-one')
192
        def assertBranchAtRevision1(params):
193
            self.assertEquals(
194
                (1, 'revid-one'), params.branch.last_revision_info())
195
        Branch.hooks.install_named_hook(
196
            'pre_change_branch_tip', assertBranchAtRevision1, None)
197
        branch.set_last_revision_info(0, NULL_REVISION)
198
3577.1.1 by Andrew Bennetts
Cherry-pick TipChangeRejected changes from pre-branch-tip-changed-hook loom.
199
    def test_hook_failure_prevents_change(self):
3517.2.3 by Andrew Bennetts
Better tests for {pre,post}_change_branch_tip hooks.
200
        """If a hook raises an exception, the change does not take effect.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
201
3577.1.1 by Andrew Bennetts
Cherry-pick TipChangeRejected changes from pre-branch-tip-changed-hook loom.
202
        Also, a HookFailed exception will be raised.
3517.2.3 by Andrew Bennetts
Better tests for {pre,post}_change_branch_tip hooks.
203
        """
3517.2.2 by Andrew Bennetts
Add test for a pre_change_branch_tip hook rejecting a change.
204
        branch = self.make_branch_with_revision_ids(
205
            'one-\xc2\xb5', 'two-\xc2\xb5')
206
        class PearShapedError(Exception):
207
            pass
208
        def hook_that_raises(params):
209
            raise PearShapedError()
210
        Branch.hooks.install_named_hook(
211
            'pre_change_branch_tip', hook_that_raises, None)
3577.1.1 by Andrew Bennetts
Cherry-pick TipChangeRejected changes from pre-branch-tip-changed-hook loom.
212
        hook_failed_exc = self.assertRaises(
213
            HookFailed, branch.set_last_revision_info, 0, NULL_REVISION)
214
        self.assertIsInstance(hook_failed_exc.exc_value, PearShapedError)
3517.2.2 by Andrew Bennetts
Add test for a pre_change_branch_tip hook rejecting a change.
215
        # The revision info is unchanged.
216
        self.assertEqual((2, 'two-\xc2\xb5'), branch.last_revision_info())
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
217
3517.2.5 by Andrew Bennetts
Reduce duplication in test_hooks a little.
218
    def test_empty_history(self):
3517.2.1 by Andrew Bennetts
Quick draft of pre_change_branch_tip hook.
219
        branch = self.make_branch('source')
3517.2.5 by Andrew Bennetts
Reduce duplication in test_hooks a little.
220
        hook_calls = self.install_logging_hook('pre')
3517.2.1 by Andrew Bennetts
Quick draft of pre_change_branch_tip hook.
221
        branch.set_last_revision_info(0, NULL_REVISION)
3517.2.3 by Andrew Bennetts
Better tests for {pre,post}_change_branch_tip hooks.
222
        expected_params = ChangeBranchTipParams(
223
            branch, 0, 0, NULL_REVISION, NULL_REVISION)
4005.2.1 by Robert Collins
Fix RemoteBranch to be used correctly in tests using bzr+ssh, to fire off Branch hooks correctly, and improve the branch_implementations tests to check that making a branch gets the right format under test.
224
        self.assertHookCalls(expected_params, branch, hook_calls, pre=True)
3517.2.1 by Andrew Bennetts
Quick draft of pre_change_branch_tip hook.
225
3517.2.5 by Andrew Bennetts
Reduce duplication in test_hooks a little.
226
    def test_nonempty_history(self):
3517.2.3 by Andrew Bennetts
Better tests for {pre,post}_change_branch_tip hooks.
227
        # some branches require that their history be set to a revision in the
228
        # repository, so we need to make a branch with non-empty history for
229
        # this test.
3517.2.2 by Andrew Bennetts
Add test for a pre_change_branch_tip hook rejecting a change.
230
        branch = self.make_branch_with_revision_ids(
231
            'one-\xc2\xb5', 'two-\xc2\xb5')
3517.2.5 by Andrew Bennetts
Reduce duplication in test_hooks a little.
232
        hook_calls = self.install_logging_hook('pre')
3517.2.2 by Andrew Bennetts
Add test for a pre_change_branch_tip hook rejecting a change.
233
        branch.set_last_revision_info(1, 'one-\xc2\xb5')
3517.2.3 by Andrew Bennetts
Better tests for {pre,post}_change_branch_tip hooks.
234
        expected_params = ChangeBranchTipParams(
235
            branch, 2, 1, 'two-\xc2\xb5', 'one-\xc2\xb5')
4005.2.1 by Robert Collins
Fix RemoteBranch to be used correctly in tests using bzr+ssh, to fire off Branch hooks correctly, and improve the branch_implementations tests to check that making a branch gets the right format under test.
236
        self.assertHookCalls(expected_params, branch, hook_calls, pre=True)
3517.2.1 by Andrew Bennetts
Quick draft of pre_change_branch_tip hook.
237
3517.2.5 by Andrew Bennetts
Reduce duplication in test_hooks a little.
238
    def test_branch_is_locked(self):
3517.2.1 by Andrew Bennetts
Quick draft of pre_change_branch_tip hook.
239
        branch = self.make_branch('source')
3517.2.3 by Andrew Bennetts
Better tests for {pre,post}_change_branch_tip hooks.
240
        def assertBranchIsLocked(params):
241
            self.assertTrue(params.branch.is_locked())
3517.2.1 by Andrew Bennetts
Quick draft of pre_change_branch_tip hook.
242
        Branch.hooks.install_named_hook(
3517.2.3 by Andrew Bennetts
Better tests for {pre,post}_change_branch_tip hooks.
243
            'pre_change_branch_tip', assertBranchIsLocked, None)
3517.2.1 by Andrew Bennetts
Quick draft of pre_change_branch_tip hook.
244
        branch.set_last_revision_info(0, NULL_REVISION)
245
3517.2.5 by Andrew Bennetts
Reduce duplication in test_hooks a little.
246
    def test_calls_all_hooks_no_errors(self):
247
        """If multiple hooks are registered, all are called (if none raise
248
        errors).
249
        """
3517.2.1 by Andrew Bennetts
Quick draft of pre_change_branch_tip hook.
250
        branch = self.make_branch('source')
3517.2.5 by Andrew Bennetts
Reduce duplication in test_hooks a little.
251
        hook_calls_1 = self.install_logging_hook('pre')
252
        hook_calls_2 = self.install_logging_hook('pre')
3517.2.3 by Andrew Bennetts
Better tests for {pre,post}_change_branch_tip hooks.
253
        self.assertIsNot(hook_calls_1, hook_calls_2)
3517.2.1 by Andrew Bennetts
Quick draft of pre_change_branch_tip hook.
254
        branch.set_last_revision_info(0, NULL_REVISION)
3517.2.3 by Andrew Bennetts
Better tests for {pre,post}_change_branch_tip hooks.
255
        # Both hooks are called.
4005.2.1 by Robert Collins
Fix RemoteBranch to be used correctly in tests using bzr+ssh, to fire off Branch hooks correctly, and improve the branch_implementations tests to check that making a branch gets the right format under test.
256
        if isinstance(branch, RemoteBranch):
257
            count = 2
258
        else:
259
            count = 1
260
        self.assertEqual(len(hook_calls_1), count)
261
        self.assertEqual(len(hook_calls_2), count)
3517.2.1 by Andrew Bennetts
Quick draft of pre_change_branch_tip hook.
262
3577.1.1 by Andrew Bennetts
Cherry-pick TipChangeRejected changes from pre-branch-tip-changed-hook loom.
263
    def test_explicit_reject_by_hook(self):
264
        """If a hook raises TipChangeRejected, the change does not take effect.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
265
3577.1.1 by Andrew Bennetts
Cherry-pick TipChangeRejected changes from pre-branch-tip-changed-hook loom.
266
        TipChangeRejected exceptions are propagated, not wrapped in HookFailed.
267
        """
268
        branch = self.make_branch_with_revision_ids(
269
            'one-\xc2\xb5', 'two-\xc2\xb5')
270
        def hook_that_rejects(params):
271
            raise TipChangeRejected('rejection message')
272
        Branch.hooks.install_named_hook(
273
            'pre_change_branch_tip', hook_that_rejects, None)
274
        self.assertRaises(
275
            TipChangeRejected, branch.set_last_revision_info, 0, NULL_REVISION)
276
        # The revision info is unchanged.
277
        self.assertEqual((2, 'two-\xc2\xb5'), branch.last_revision_info())
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
278
3517.2.1 by Andrew Bennetts
Quick draft of pre_change_branch_tip hook.
279
3517.2.5 by Andrew Bennetts
Reduce duplication in test_hooks a little.
280
class TestPostChangeBranchTip(ChangeBranchTipTestCase):
3517.2.3 by Andrew Bennetts
Better tests for {pre,post}_change_branch_tip hooks.
281
    """Tests for post_change_branch_tip hook.
282
283
    Most of these tests are very similar to the tests in
284
    TestPostChangeBranchTip.
285
    """
286
287
    def test_hook_runs_after_change(self):
288
        """The hook runs *after* the branch's last_revision_info has changed.
289
        """
290
        branch = self.make_branch_with_revision_ids('revid-one')
291
        def assertBranchAtRevision1(params):
292
            self.assertEquals(
293
                (0, NULL_REVISION), params.branch.last_revision_info())
3256.2.26 by Daniel Watkins
Updated tests to use install_named_hook.
294
        Branch.hooks.install_named_hook(
3517.2.3 by Andrew Bennetts
Better tests for {pre,post}_change_branch_tip hooks.
295
            'post_change_branch_tip', assertBranchAtRevision1, None)
296
        branch.set_last_revision_info(0, NULL_REVISION)
297
3517.2.5 by Andrew Bennetts
Reduce duplication in test_hooks a little.
298
    def test_empty_history(self):
3517.2.3 by Andrew Bennetts
Better tests for {pre,post}_change_branch_tip hooks.
299
        branch = self.make_branch('source')
3517.2.5 by Andrew Bennetts
Reduce duplication in test_hooks a little.
300
        hook_calls = self.install_logging_hook('post')
3517.2.3 by Andrew Bennetts
Better tests for {pre,post}_change_branch_tip hooks.
301
        branch.set_last_revision_info(0, NULL_REVISION)
302
        expected_params = ChangeBranchTipParams(
303
            branch, 0, 0, NULL_REVISION, NULL_REVISION)
4005.2.1 by Robert Collins
Fix RemoteBranch to be used correctly in tests using bzr+ssh, to fire off Branch hooks correctly, and improve the branch_implementations tests to check that making a branch gets the right format under test.
304
        self.assertHookCalls(expected_params, branch, hook_calls)
3517.2.3 by Andrew Bennetts
Better tests for {pre,post}_change_branch_tip hooks.
305
3517.2.5 by Andrew Bennetts
Reduce duplication in test_hooks a little.
306
    def test_nonempty_history(self):
3331.1.2 by James Henstridge
Add calls to set_last_revision_info hook to both BzrBranch and
307
        # some branches require that their history be set to a revision in the
3517.2.3 by Andrew Bennetts
Better tests for {pre,post}_change_branch_tip hooks.
308
        # repository, so we need to make a branch with non-empty history for
309
        # this test.
310
        branch = self.make_branch_with_revision_ids(
311
            'one-\xc2\xb5', 'two-\xc2\xb5')
3517.2.5 by Andrew Bennetts
Reduce duplication in test_hooks a little.
312
        hook_calls = self.install_logging_hook('post')
3517.2.3 by Andrew Bennetts
Better tests for {pre,post}_change_branch_tip hooks.
313
        branch.set_last_revision_info(1, 'one-\xc2\xb5')
314
        expected_params = ChangeBranchTipParams(
315
            branch, 2, 1, 'two-\xc2\xb5', 'one-\xc2\xb5')
4005.2.1 by Robert Collins
Fix RemoteBranch to be used correctly in tests using bzr+ssh, to fire off Branch hooks correctly, and improve the branch_implementations tests to check that making a branch gets the right format under test.
316
        self.assertHookCalls(expected_params, branch, hook_calls)
3517.2.3 by Andrew Bennetts
Better tests for {pre,post}_change_branch_tip hooks.
317
3517.2.5 by Andrew Bennetts
Reduce duplication in test_hooks a little.
318
    def test_branch_is_locked(self):
3517.2.3 by Andrew Bennetts
Better tests for {pre,post}_change_branch_tip hooks.
319
        """The branch passed to the hook is locked."""
320
        branch = self.make_branch('source')
321
        def assertBranchIsLocked(params):
322
            self.assertTrue(params.branch.is_locked())
323
        Branch.hooks.install_named_hook(
3517.2.4 by Andrew Bennetts
Fix typo.
324
            'post_change_branch_tip', assertBranchIsLocked, None)
3517.2.3 by Andrew Bennetts
Better tests for {pre,post}_change_branch_tip hooks.
325
        branch.set_last_revision_info(0, NULL_REVISION)
326
3517.2.5 by Andrew Bennetts
Reduce duplication in test_hooks a little.
327
    def test_calls_all_hooks_no_errors(self):
328
        """If multiple hooks are registered, all are called (if none raise
329
        errors).
330
        """
3517.2.3 by Andrew Bennetts
Better tests for {pre,post}_change_branch_tip hooks.
331
        branch = self.make_branch('source')
3517.2.5 by Andrew Bennetts
Reduce duplication in test_hooks a little.
332
        hook_calls_1 = self.install_logging_hook('post')
333
        hook_calls_2 = self.install_logging_hook('post')
3517.2.3 by Andrew Bennetts
Better tests for {pre,post}_change_branch_tip hooks.
334
        self.assertIsNot(hook_calls_1, hook_calls_2)
335
        branch.set_last_revision_info(0, NULL_REVISION)
336
        # Both hooks are called.
4005.2.1 by Robert Collins
Fix RemoteBranch to be used correctly in tests using bzr+ssh, to fire off Branch hooks correctly, and improve the branch_implementations tests to check that making a branch gets the right format under test.
337
        if isinstance(branch, RemoteBranch):
338
            count = 2
339
        else:
340
            count = 1
341
        self.assertEqual(len(hook_calls_1), count)
342
        self.assertEqual(len(hook_calls_2), count)
3577.1.1 by Andrew Bennetts
Cherry-pick TipChangeRejected changes from pre-branch-tip-changed-hook loom.
343
344
345
class TestAllMethodsThatChangeTipWillRunHooks(ChangeBranchTipTestCase):
346
    """Every method of Branch that changes a branch tip will invoke the
347
    pre/post_change_branch_tip hooks.
348
    """
349
350
    def setUp(self):
351
        ChangeBranchTipTestCase.setUp(self)
352
        self.installPreAndPostHooks()
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
353
3577.1.1 by Andrew Bennetts
Cherry-pick TipChangeRejected changes from pre-branch-tip-changed-hook loom.
354
    def installPreAndPostHooks(self):
355
        self.pre_hook_calls = self.install_logging_hook('pre')
356
        self.post_hook_calls = self.install_logging_hook('post')
357
358
    def resetHookCalls(self):
359
        del self.pre_hook_calls[:], self.post_hook_calls[:]
360
4005.2.1 by Robert Collins
Fix RemoteBranch to be used correctly in tests using bzr+ssh, to fire off Branch hooks correctly, and improve the branch_implementations tests to check that making a branch gets the right format under test.
361
    def assertPreAndPostHooksWereInvoked(self, branch, smart_enabled):
362
        """assert that both pre and post hooks were called
363
364
        :param smart_enabled: The method invoked is one that should be
365
            smart server ready.
366
        """
367
        # Check for the number of invocations expected. One invocation is
368
        # local, one is remote (if the branch is remote).
369
        if smart_enabled and isinstance(branch, RemoteBranch):
370
            length = 2
371
        else:
372
            length = 1
373
        self.assertEqual(length, len(self.pre_hook_calls))
374
        self.assertEqual(length, len(self.post_hook_calls))
3577.1.1 by Andrew Bennetts
Cherry-pick TipChangeRejected changes from pre-branch-tip-changed-hook loom.
375
376
    def test_set_revision_history(self):
377
        branch = self.make_branch('')
378
        branch.set_revision_history([])
4005.2.1 by Robert Collins
Fix RemoteBranch to be used correctly in tests using bzr+ssh, to fire off Branch hooks correctly, and improve the branch_implementations tests to check that making a branch gets the right format under test.
379
        self.assertPreAndPostHooksWereInvoked(branch, True)
3577.1.1 by Andrew Bennetts
Cherry-pick TipChangeRejected changes from pre-branch-tip-changed-hook loom.
380
381
    def test_set_last_revision_info(self):
382
        branch = self.make_branch('')
383
        branch.set_last_revision_info(0, NULL_REVISION)
4005.2.1 by Robert Collins
Fix RemoteBranch to be used correctly in tests using bzr+ssh, to fire off Branch hooks correctly, and improve the branch_implementations tests to check that making a branch gets the right format under test.
384
        self.assertPreAndPostHooksWereInvoked(branch, True)
3577.1.1 by Andrew Bennetts
Cherry-pick TipChangeRejected changes from pre-branch-tip-changed-hook loom.
385
386
    def test_generate_revision_history(self):
387
        branch = self.make_branch('')
388
        branch.generate_revision_history(NULL_REVISION)
4005.2.1 by Robert Collins
Fix RemoteBranch to be used correctly in tests using bzr+ssh, to fire off Branch hooks correctly, and improve the branch_implementations tests to check that making a branch gets the right format under test.
389
        # NB: for HPSS protocols < v3, the server does not invoke branch tip
390
        # change events on generate_revision_history, as the change is done
391
        # directly by the client over the VFS.
392
        self.assertPreAndPostHooksWereInvoked(branch, True)
3577.1.1 by Andrew Bennetts
Cherry-pick TipChangeRejected changes from pre-branch-tip-changed-hook loom.
393
394
    def test_pull(self):
395
        source_branch = self.make_branch_with_revision_ids('rev-1', 'rev-2')
396
        self.resetHookCalls()
397
        destination_branch = self.make_branch('destination')
398
        destination_branch.pull(source_branch)
4005.2.1 by Robert Collins
Fix RemoteBranch to be used correctly in tests using bzr+ssh, to fire off Branch hooks correctly, and improve the branch_implementations tests to check that making a branch gets the right format under test.
399
        self.assertPreAndPostHooksWereInvoked(destination_branch, False)
3577.1.1 by Andrew Bennetts
Cherry-pick TipChangeRejected changes from pre-branch-tip-changed-hook loom.
400
401
    def test_push(self):
402
        source_branch = self.make_branch_with_revision_ids('rev-1', 'rev-2')
403
        self.resetHookCalls()
404
        destination_branch = self.make_branch('destination')
405
        source_branch.push(destination_branch)
4005.2.1 by Robert Collins
Fix RemoteBranch to be used correctly in tests using bzr+ssh, to fire off Branch hooks correctly, and improve the branch_implementations tests to check that making a branch gets the right format under test.
406
        self.assertPreAndPostHooksWereInvoked(destination_branch, True)