17
17
"""Tests that branch classes implement hook callouts correctly."""
19
from bzrlib.errors import HookFailed, TipChangeRejected
19
20
from bzrlib.branch import Branch, ChangeBranchTipParams
20
21
from bzrlib.revision import NULL_REVISION
21
22
from bzrlib.tests import TestCaseWithMemoryTransport
92
93
Branch.hooks.install_named_hook(
93
'pre_change_branch_tip', hook_calls.append, None)
94
prefix + '_change_branch_tip', hook_calls.append, None)
96
97
def make_branch_with_revision_ids(self, *revision_ids):
124
125
'pre_change_branch_tip', assertBranchAtRevision1, None)
125
126
branch.set_last_revision_info(0, NULL_REVISION)
127
def test_reject_by_hook(self):
128
def test_hook_failure_prevents_change(self):
128
129
"""If a hook raises an exception, the change does not take effect.
130
Also, the exception will be propogated.
131
Also, a HookFailed exception will be raised.
132
133
branch = self.make_branch_with_revision_ids(
133
134
'one-\xc2\xb5', 'two-\xc2\xb5')
137
138
raise PearShapedError()
138
139
Branch.hooks.install_named_hook(
139
140
'pre_change_branch_tip', hook_that_raises, None)
141
PearShapedError, branch.set_last_revision_info, 0, NULL_REVISION)
141
hook_failed_exc = self.assertRaises(
142
HookFailed, branch.set_last_revision_info, 0, NULL_REVISION)
143
self.assertIsInstance(hook_failed_exc.exc_value, PearShapedError)
142
144
# The revision info is unchanged.
143
145
self.assertEqual((2, 'two-\xc2\xb5'), branch.last_revision_info())
183
185
self.assertEqual(len(hook_calls_1), 1)
184
186
self.assertEqual(len(hook_calls_2), 1)
188
def test_explicit_reject_by_hook(self):
189
"""If a hook raises TipChangeRejected, the change does not take effect.
191
TipChangeRejected exceptions are propagated, not wrapped in HookFailed.
193
branch = self.make_branch_with_revision_ids(
194
'one-\xc2\xb5', 'two-\xc2\xb5')
195
def hook_that_rejects(params):
196
raise TipChangeRejected('rejection message')
197
Branch.hooks.install_named_hook(
198
'pre_change_branch_tip', hook_that_rejects, None)
200
TipChangeRejected, branch.set_last_revision_info, 0, NULL_REVISION)
201
# The revision info is unchanged.
202
self.assertEqual((2, 'two-\xc2\xb5'), branch.last_revision_info())
187
205
class TestPostChangeBranchTip(ChangeBranchTipTestCase):
188
206
"""Tests for post_change_branch_tip hook.
243
261
# Both hooks are called.
244
262
self.assertEqual(len(hook_calls_1), 1)
245
263
self.assertEqual(len(hook_calls_2), 1)
266
class TestAllMethodsThatChangeTipWillRunHooks(ChangeBranchTipTestCase):
267
"""Every method of Branch that changes a branch tip will invoke the
268
pre/post_change_branch_tip hooks.
272
ChangeBranchTipTestCase.setUp(self)
273
self.installPreAndPostHooks()
275
def installPreAndPostHooks(self):
276
self.pre_hook_calls = self.install_logging_hook('pre')
277
self.post_hook_calls = self.install_logging_hook('post')
279
def resetHookCalls(self):
280
del self.pre_hook_calls[:], self.post_hook_calls[:]
282
def assertPreAndPostHooksWereInvoked(self):
283
# Check for len == 1, because the hooks should only be be invoked once
285
self.assertEqual(1, len(self.pre_hook_calls))
286
self.assertEqual(1, len(self.post_hook_calls))
288
def test_set_revision_history(self):
289
branch = self.make_branch('')
290
branch.set_revision_history([])
291
self.assertPreAndPostHooksWereInvoked()
293
def test_set_last_revision_info(self):
294
branch = self.make_branch('')
295
branch.set_last_revision_info(0, NULL_REVISION)
296
self.assertPreAndPostHooksWereInvoked()
298
def test_generate_revision_history(self):
299
branch = self.make_branch('')
300
branch.generate_revision_history(NULL_REVISION)
301
self.assertPreAndPostHooksWereInvoked()
304
source_branch = self.make_branch_with_revision_ids('rev-1', 'rev-2')
305
self.resetHookCalls()
306
destination_branch = self.make_branch('destination')
307
destination_branch.pull(source_branch)
308
self.assertPreAndPostHooksWereInvoked()
311
source_branch = self.make_branch_with_revision_ids('rev-1', 'rev-2')
312
self.resetHookCalls()
313
destination_branch = self.make_branch('destination')
314
source_branch.push(destination_branch)
315
self.assertPreAndPostHooksWereInvoked()