/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_branch.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2009-03-23 01:17:27 UTC
  • mfrom: (4165.3.2 ec2-ubuntu)
  • Revision ID: pqm@pqm.ubuntu.com-20090323011727-b4nl10tcxfo4jiwb
(robertc) Various tweaks to ec2 stuff,
        and make it less windows only. (Robert Collins)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006-2010 Canonical Ltd
 
1
# Copyright (C) 2005, 2006, 2007 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
12
12
#
13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
 
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
 
17
17
"""Tests for the Branch facility that are not interface  tests.
18
18
 
19
 
For interface tests see tests/per_branch/*.py.
 
19
For interface tests see tests/branch_implementations/*.py.
20
20
 
21
21
For concrete class tests see this file, and for meta-branch tests
22
22
also see this file.
23
23
"""
24
24
 
25
 
from cStringIO import StringIO
 
25
from StringIO import StringIO
26
26
 
27
27
from bzrlib import (
28
28
    branch as _mod_branch,
29
29
    bzrdir,
30
30
    config,
31
31
    errors,
32
 
    tests,
33
32
    trace,
34
 
    transport,
35
33
    urlutils,
36
34
    )
37
 
 
38
 
 
39
 
class TestDefaultFormat(tests.TestCase):
 
35
from bzrlib.branch import (
 
36
    Branch,
 
37
    BranchHooks,
 
38
    BranchFormat,
 
39
    BranchReferenceFormat,
 
40
    BzrBranch5,
 
41
    BzrBranchFormat5,
 
42
    BzrBranchFormat6,
 
43
    PullResult,
 
44
    _run_with_write_locked_target,
 
45
    )
 
46
from bzrlib.bzrdir import (BzrDirMetaFormat1, BzrDirMeta1,
 
47
                           BzrDir, BzrDirFormat)
 
48
from bzrlib.errors import (NotBranchError,
 
49
                           UnknownFormatError,
 
50
                           UnknownHook,
 
51
                           UnsupportedFormatError,
 
52
                           )
 
53
 
 
54
from bzrlib.tests import TestCase, TestCaseWithTransport
 
55
from bzrlib.transport import get_transport
 
56
 
 
57
 
 
58
class TestDefaultFormat(TestCase):
40
59
 
41
60
    def test_default_format(self):
42
61
        # update this if you change the default branch format
43
 
        self.assertIsInstance(_mod_branch.BranchFormat.get_default_format(),
44
 
                _mod_branch.BzrBranchFormat7)
 
62
        self.assertIsInstance(BranchFormat.get_default_format(),
 
63
                BzrBranchFormat6)
45
64
 
46
65
    def test_default_format_is_same_as_bzrdir_default(self):
47
66
        # XXX: it might be nice if there was only one place the default was
48
67
        # set, but at the moment that's not true -- mbp 20070814 --
49
68
        # https://bugs.launchpad.net/bzr/+bug/132376
50
 
        self.assertEqual(
51
 
            _mod_branch.BranchFormat.get_default_format(),
52
 
            bzrdir.BzrDirFormat.get_default_format().get_branch_format())
 
69
        self.assertEqual(BranchFormat.get_default_format(),
 
70
                BzrDirFormat.get_default_format().get_branch_format())
53
71
 
54
72
    def test_get_set_default_format(self):
55
73
        # set the format and then set it back again
56
 
        old_format = _mod_branch.BranchFormat.get_default_format()
57
 
        _mod_branch.BranchFormat.set_default_format(SampleBranchFormat())
 
74
        old_format = BranchFormat.get_default_format()
 
75
        BranchFormat.set_default_format(SampleBranchFormat())
58
76
        try:
59
77
            # the default branch format is used by the meta dir format
60
78
            # which is not the default bzrdir format at this point
61
 
            dir = bzrdir.BzrDirMetaFormat1().initialize('memory:///')
 
79
            dir = BzrDirMetaFormat1().initialize('memory:///')
62
80
            result = dir.create_branch()
63
81
            self.assertEqual(result, 'A branch')
64
82
        finally:
65
 
            _mod_branch.BranchFormat.set_default_format(old_format)
66
 
        self.assertEqual(old_format,
67
 
                         _mod_branch.BranchFormat.get_default_format())
68
 
 
69
 
 
70
 
class TestBranchFormat5(tests.TestCaseWithTransport):
 
83
            BranchFormat.set_default_format(old_format)
 
84
        self.assertEqual(old_format, BranchFormat.get_default_format())
 
85
 
 
86
 
 
87
class TestBranchFormat5(TestCaseWithTransport):
71
88
    """Tests specific to branch format 5"""
72
89
 
73
90
    def test_branch_format_5_uses_lockdir(self):
74
91
        url = self.get_url()
75
 
        bdir = bzrdir.BzrDirMetaFormat1().initialize(url)
76
 
        bdir.create_repository()
77
 
        branch = bdir.create_branch()
 
92
        bzrdir = BzrDirMetaFormat1().initialize(url)
 
93
        bzrdir.create_repository()
 
94
        branch = bzrdir.create_branch()
78
95
        t = self.get_transport()
79
96
        self.log("branch instance is %r" % branch)
80
 
        self.assert_(isinstance(branch, _mod_branch.BzrBranch5))
 
97
        self.assert_(isinstance(branch, BzrBranch5))
81
98
        self.assertIsDirectory('.', t)
82
99
        self.assertIsDirectory('.bzr/branch', t)
83
100
        self.assertIsDirectory('.bzr/branch/lock', t)
84
101
        branch.lock_write()
85
 
        self.addCleanup(branch.unlock)
86
 
        self.assertIsDirectory('.bzr/branch/lock/held', t)
 
102
        try:
 
103
            self.assertIsDirectory('.bzr/branch/lock/held', t)
 
104
        finally:
 
105
            branch.unlock()
87
106
 
88
107
    def test_set_push_location(self):
89
108
        from bzrlib.config import (locations_config_filename,
112
131
    # recursive section - that is, it appends the branch name.
113
132
 
114
133
 
115
 
class SampleBranchFormat(_mod_branch.BranchFormat):
 
134
class SampleBranchFormat(BranchFormat):
116
135
    """A sample format
117
136
 
118
137
    this format is initializable, unsupported to aid in testing the
123
142
        """See BzrBranchFormat.get_format_string()."""
124
143
        return "Sample branch format."
125
144
 
126
 
    def initialize(self, a_bzrdir, name=None):
 
145
    def initialize(self, a_bzrdir):
127
146
        """Format 4 branches cannot be created."""
128
 
        t = a_bzrdir.get_branch_transport(self, name=name)
 
147
        t = a_bzrdir.get_branch_transport(self)
129
148
        t.put_bytes('format', self.get_format_string())
130
149
        return 'A branch'
131
150
 
132
151
    def is_supported(self):
133
152
        return False
134
153
 
135
 
    def open(self, transport, name=None, _found=False, ignore_fallbacks=False):
 
154
    def open(self, transport, _found=False):
136
155
        return "opened branch."
137
156
 
138
157
 
139
 
class TestBzrBranchFormat(tests.TestCaseWithTransport):
 
158
class TestBzrBranchFormat(TestCaseWithTransport):
140
159
    """Tests for the BzrBranchFormat facility."""
141
160
 
142
161
    def test_find_format(self):
148
167
            dir = format._matchingbzrdir.initialize(url)
149
168
            dir.create_repository()
150
169
            format.initialize(dir)
151
 
            found_format = _mod_branch.BranchFormat.find_format(dir)
 
170
            found_format = BranchFormat.find_format(dir)
152
171
            self.failUnless(isinstance(found_format, format.__class__))
153
 
        check_format(_mod_branch.BzrBranchFormat5(), "bar")
 
172
        check_format(BzrBranchFormat5(), "bar")
154
173
 
155
174
    def test_find_format_not_branch(self):
156
175
        dir = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
157
 
        self.assertRaises(errors.NotBranchError,
158
 
                          _mod_branch.BranchFormat.find_format,
 
176
        self.assertRaises(NotBranchError,
 
177
                          BranchFormat.find_format,
159
178
                          dir)
160
179
 
161
180
    def test_find_format_unknown_format(self):
162
181
        dir = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
163
182
        SampleBranchFormat().initialize(dir)
164
 
        self.assertRaises(errors.UnknownFormatError,
165
 
                          _mod_branch.BranchFormat.find_format,
 
183
        self.assertRaises(UnknownFormatError,
 
184
                          BranchFormat.find_format,
166
185
                          dir)
167
186
 
168
187
    def test_register_unregister_format(self):
172
191
        # make a branch
173
192
        format.initialize(dir)
174
193
        # register a format for it.
175
 
        _mod_branch.BranchFormat.register_format(format)
 
194
        BranchFormat.register_format(format)
176
195
        # which branch.Open will refuse (not supported)
177
 
        self.assertRaises(errors.UnsupportedFormatError,
178
 
                          _mod_branch.Branch.open, self.get_url())
 
196
        self.assertRaises(UnsupportedFormatError, Branch.open, self.get_url())
179
197
        self.make_branch_and_tree('foo')
180
198
        # but open_downlevel will work
181
 
        self.assertEqual(
182
 
            format.open(dir),
183
 
            bzrdir.BzrDir.open(self.get_url()).open_branch(unsupported=True))
 
199
        self.assertEqual(format.open(dir), bzrdir.BzrDir.open(self.get_url()).open_branch(unsupported=True))
184
200
        # unregister the format
185
 
        _mod_branch.BranchFormat.unregister_format(format)
 
201
        BranchFormat.unregister_format(format)
186
202
        self.make_branch_and_tree('bar')
187
203
 
188
204
 
199
215
        raise NotImplementedError(self.get_class)
200
216
 
201
217
    def test_creation(self):
202
 
        format = bzrdir.BzrDirMetaFormat1()
 
218
        format = BzrDirMetaFormat1()
203
219
        format.set_branch_format(_mod_branch.BzrBranchFormat6())
204
220
        branch = self.make_branch('a', format=format)
205
221
        self.assertIsInstance(branch, self.get_class())
212
228
        branch = self.make_branch('a', format=self.get_format_name())
213
229
        self.failUnlessExists('a/.bzr/branch/last-revision')
214
230
        self.failIfExists('a/.bzr/branch/revision-history')
215
 
        self.failIfExists('a/.bzr/branch/references')
216
231
 
217
232
    def test_config(self):
218
233
        """Ensure that all configuration data is stored in the branch"""
292
307
                         'locations.conf')
293
308
 
294
309
 
295
 
class TestBranch6(TestBranch67, tests.TestCaseWithTransport):
 
310
class TestBranch6(TestBranch67, TestCaseWithTransport):
296
311
 
297
312
    def get_class(self):
298
313
        return _mod_branch.BzrBranch6
313
328
        self.assertRaises(errors.UnstackableBranchFormat, branch.get_stacked_on_url)
314
329
 
315
330
 
316
 
class TestBranch7(TestBranch67, tests.TestCaseWithTransport):
 
331
class TestBranch7(TestBranch67, TestCaseWithTransport):
317
332
 
318
333
    def get_class(self):
319
334
        return _mod_branch.BzrBranch7
320
335
 
321
336
    def get_format_name(self):
322
 
        return "1.9"
 
337
        return "development"
323
338
 
324
339
    def get_format_name_subtree(self):
325
340
        return "development-subtree"
363
378
        self.assertTrue(branch.repository.has_revision(revid))
364
379
 
365
380
 
366
 
class BzrBranch8(tests.TestCaseWithTransport):
367
 
 
368
 
    def make_branch(self, location, format=None):
369
 
        if format is None:
370
 
            format = bzrdir.format_registry.make_bzrdir('1.9')
371
 
            format.set_branch_format(_mod_branch.BzrBranchFormat8())
372
 
        return tests.TestCaseWithTransport.make_branch(
373
 
            self, location, format=format)
374
 
 
375
 
    def create_branch_with_reference(self):
376
 
        branch = self.make_branch('branch')
377
 
        branch._set_all_reference_info({'file-id': ('path', 'location')})
378
 
        return branch
379
 
 
380
 
    @staticmethod
381
 
    def instrument_branch(branch, gets):
382
 
        old_get = branch._transport.get
383
 
        def get(*args, **kwargs):
384
 
            gets.append((args, kwargs))
385
 
            return old_get(*args, **kwargs)
386
 
        branch._transport.get = get
387
 
 
388
 
    def test_reference_info_caching_read_locked(self):
389
 
        gets = []
390
 
        branch = self.create_branch_with_reference()
391
 
        branch.lock_read()
392
 
        self.addCleanup(branch.unlock)
393
 
        self.instrument_branch(branch, gets)
394
 
        branch.get_reference_info('file-id')
395
 
        branch.get_reference_info('file-id')
396
 
        self.assertEqual(1, len(gets))
397
 
 
398
 
    def test_reference_info_caching_read_unlocked(self):
399
 
        gets = []
400
 
        branch = self.create_branch_with_reference()
401
 
        self.instrument_branch(branch, gets)
402
 
        branch.get_reference_info('file-id')
403
 
        branch.get_reference_info('file-id')
404
 
        self.assertEqual(2, len(gets))
405
 
 
406
 
    def test_reference_info_caching_write_locked(self):
407
 
        gets = []
408
 
        branch = self.make_branch('branch')
409
 
        branch.lock_write()
410
 
        self.instrument_branch(branch, gets)
411
 
        self.addCleanup(branch.unlock)
412
 
        branch._set_all_reference_info({'file-id': ('path2', 'location2')})
413
 
        path, location = branch.get_reference_info('file-id')
414
 
        self.assertEqual(0, len(gets))
415
 
        self.assertEqual('path2', path)
416
 
        self.assertEqual('location2', location)
417
 
 
418
 
    def test_reference_info_caches_cleared(self):
419
 
        branch = self.make_branch('branch')
420
 
        branch.lock_write()
421
 
        branch.set_reference_info('file-id', 'path2', 'location2')
422
 
        branch.unlock()
423
 
        doppelganger = _mod_branch.Branch.open('branch')
424
 
        doppelganger.set_reference_info('file-id', 'path3', 'location3')
425
 
        self.assertEqual(('path3', 'location3'),
426
 
                         branch.get_reference_info('file-id'))
427
 
 
428
 
class TestBranchReference(tests.TestCaseWithTransport):
 
381
class TestBranchReference(TestCaseWithTransport):
429
382
    """Tests for the branch reference facility."""
430
383
 
431
384
    def test_create_open_reference(self):
432
385
        bzrdirformat = bzrdir.BzrDirMetaFormat1()
433
 
        t = transport.get_transport(self.get_url('.'))
 
386
        t = get_transport(self.get_url('.'))
434
387
        t.mkdir('repo')
435
388
        dir = bzrdirformat.initialize(self.get_url('repo'))
436
389
        dir.create_repository()
437
390
        target_branch = dir.create_branch()
438
391
        t.mkdir('branch')
439
392
        branch_dir = bzrdirformat.initialize(self.get_url('branch'))
440
 
        made_branch = _mod_branch.BranchReferenceFormat().initialize(
441
 
            branch_dir, target_branch=target_branch)
 
393
        made_branch = BranchReferenceFormat().initialize(branch_dir, target_branch)
442
394
        self.assertEqual(made_branch.base, target_branch.base)
443
395
        opened_branch = branch_dir.open_branch()
444
396
        self.assertEqual(opened_branch.base, target_branch.base)
455
407
            _mod_branch.BranchReferenceFormat().get_reference(checkout.bzrdir))
456
408
 
457
409
 
458
 
class TestHooks(tests.TestCaseWithTransport):
 
410
class TestHooks(TestCase):
459
411
 
460
412
    def test_constructor(self):
461
413
        """Check that creating a BranchHooks instance has the right defaults."""
462
 
        hooks = _mod_branch.BranchHooks()
 
414
        hooks = BranchHooks()
463
415
        self.assertTrue("set_rh" in hooks, "set_rh not in %s" % hooks)
464
416
        self.assertTrue("post_push" in hooks, "post_push not in %s" % hooks)
465
417
        self.assertTrue("post_commit" in hooks, "post_commit not in %s" % hooks)
466
418
        self.assertTrue("pre_commit" in hooks, "pre_commit not in %s" % hooks)
467
419
        self.assertTrue("post_pull" in hooks, "post_pull not in %s" % hooks)
468
 
        self.assertTrue("post_uncommit" in hooks,
469
 
                        "post_uncommit not in %s" % hooks)
 
420
        self.assertTrue("post_uncommit" in hooks, "post_uncommit not in %s" % hooks)
470
421
        self.assertTrue("post_change_branch_tip" in hooks,
471
422
                        "post_change_branch_tip not in %s" % hooks)
472
 
        self.assertTrue("post_branch_init" in hooks,
473
 
                        "post_branch_init not in %s" % hooks)
474
 
        self.assertTrue("post_switch" in hooks,
475
 
                        "post_switch not in %s" % hooks)
476
423
 
477
424
    def test_installed_hooks_are_BranchHooks(self):
478
425
        """The installed hooks object should be a BranchHooks."""
479
426
        # the installed hooks are saved in self._preserved_hooks.
480
427
        self.assertIsInstance(self._preserved_hooks[_mod_branch.Branch][1],
481
 
                              _mod_branch.BranchHooks)
482
 
 
483
 
    def test_post_branch_init_hook(self):
484
 
        calls = []
485
 
        _mod_branch.Branch.hooks.install_named_hook('post_branch_init',
486
 
            calls.append, None)
487
 
        self.assertLength(0, calls)
488
 
        branch = self.make_branch('a')
489
 
        self.assertLength(1, calls)
490
 
        params = calls[0]
491
 
        self.assertIsInstance(params, _mod_branch.BranchInitHookParams)
492
 
        self.assertTrue(hasattr(params, 'bzrdir'))
493
 
        self.assertTrue(hasattr(params, 'branch'))
494
 
 
495
 
    def test_post_switch_hook(self):
496
 
        from bzrlib import switch
497
 
        calls = []
498
 
        _mod_branch.Branch.hooks.install_named_hook('post_switch',
499
 
            calls.append, None)
500
 
        tree = self.make_branch_and_tree('branch-1')
501
 
        self.build_tree(['branch-1/file-1'])
502
 
        tree.add('file-1')
503
 
        tree.commit('rev1')
504
 
        to_branch = tree.bzrdir.sprout('branch-2').open_branch()
505
 
        self.build_tree(['branch-1/file-2'])
506
 
        tree.add('file-2')
507
 
        tree.remove('file-1')
508
 
        tree.commit('rev2')
509
 
        checkout = tree.branch.create_checkout('checkout')
510
 
        self.assertLength(0, calls)
511
 
        switch.switch(checkout.bzrdir, to_branch)
512
 
        self.assertLength(1, calls)
513
 
        params = calls[0]
514
 
        self.assertIsInstance(params, _mod_branch.SwitchHookParams)
515
 
        self.assertTrue(hasattr(params, 'to_branch'))
516
 
        self.assertTrue(hasattr(params, 'revision_id'))
517
 
 
518
 
 
519
 
class TestBranchOptions(tests.TestCaseWithTransport):
520
 
 
521
 
    def setUp(self):
522
 
        super(TestBranchOptions, self).setUp()
523
 
        self.branch = self.make_branch('.')
524
 
        self.config = self.branch.get_config()
525
 
 
526
 
    def check_append_revisions_only(self, expected_value, value=None):
527
 
        """Set append_revisions_only in config and check its interpretation."""
528
 
        if value is not None:
529
 
            self.config.set_user_option('append_revisions_only', value)
530
 
        self.assertEqual(expected_value,
531
 
                         self.branch._get_append_revisions_only())
532
 
 
533
 
    def test_valid_append_revisions_only(self):
534
 
        self.assertEquals(None,
535
 
                          self.config.get_user_option('append_revisions_only'))
536
 
        self.check_append_revisions_only(None)
537
 
        self.check_append_revisions_only(False, 'False')
538
 
        self.check_append_revisions_only(True, 'True')
539
 
        # The following values will cause compatibility problems on projects
540
 
        # using older bzr versions (<2.2) but are accepted
541
 
        self.check_append_revisions_only(False, 'false')
542
 
        self.check_append_revisions_only(True, 'true')
543
 
 
544
 
    def test_invalid_append_revisions_only(self):
545
 
        """Ensure warning is noted on invalid settings"""
546
 
        self.warnings = []
547
 
        def warning(*args):
548
 
            self.warnings.append(args[0] % args[1:])
549
 
        self.overrideAttr(trace, 'warning', warning)
550
 
        self.check_append_revisions_only(None, 'not-a-bool')
551
 
        self.assertLength(1, self.warnings)
552
 
        self.assertEqual(
553
 
            'Value "not-a-bool" is not a boolean for "append_revisions_only"',
554
 
            self.warnings[0])
555
 
 
556
 
 
557
 
class TestPullResult(tests.TestCase):
 
428
            BranchHooks)
 
429
 
 
430
 
 
431
class TestPullResult(TestCase):
558
432
 
559
433
    def test_pull_result_to_int(self):
560
434
        # to support old code, the pull result can be used as an int
561
 
        r = _mod_branch.PullResult()
 
435
        r = PullResult()
562
436
        r.old_revno = 10
563
437
        r.new_revno = 20
564
438
        # this usage of results is not recommended for new code (because it
567
441
        a = "%d revisions pulled" % r
568
442
        self.assertEqual(a, "10 revisions pulled")
569
443
 
570
 
    def test_report_changed(self):
571
 
        r = _mod_branch.PullResult()
572
 
        r.old_revid = "old-revid"
573
 
        r.old_revno = 10
574
 
        r.new_revid = "new-revid"
575
 
        r.new_revno = 20
576
 
        f = StringIO()
577
 
        r.report(f)
578
 
        self.assertEqual("Now on revision 20.\n", f.getvalue())
579
 
 
580
 
    def test_report_unchanged(self):
581
 
        r = _mod_branch.PullResult()
582
 
        r.old_revid = "same-revid"
583
 
        r.new_revid = "same-revid"
584
 
        f = StringIO()
585
 
        r.report(f)
586
 
        self.assertEqual("No revisions to pull.\n", f.getvalue())
587
444
 
588
445
 
589
446
class _StubLockable(object):
610
467
    """Helper for TestRunWithWriteLockedTarget."""
611
468
 
612
469
 
613
 
class TestRunWithWriteLockedTarget(tests.TestCase):
 
470
class TestRunWithWriteLockedTarget(TestCase):
614
471
    """Tests for _run_with_write_locked_target."""
615
472
 
616
473
    def setUp(self):
617
 
        tests.TestCase.setUp(self)
 
474
        TestCase.setUp(self)
618
475
        self._calls = []
619
476
 
620
477
    def func_that_returns_ok(self):
627
484
 
628
485
    def test_success_unlocks(self):
629
486
        lockable = _StubLockable(self._calls)
630
 
        result = _mod_branch._run_with_write_locked_target(
 
487
        result = _run_with_write_locked_target(
631
488
            lockable, self.func_that_returns_ok)
632
489
        self.assertEqual('ok', result)
633
490
        self.assertEqual(['lock_write', 'func called', 'unlock'], self._calls)
635
492
    def test_exception_unlocks_and_propagates(self):
636
493
        lockable = _StubLockable(self._calls)
637
494
        self.assertRaises(_ErrorFromCallable,
638
 
                          _mod_branch._run_with_write_locked_target,
639
 
                          lockable, self.func_that_raises)
 
495
            _run_with_write_locked_target, lockable, self.func_that_raises)
640
496
        self.assertEqual(['lock_write', 'func called', 'unlock'], self._calls)
641
497
 
642
498
    def test_callable_succeeds_but_error_during_unlock(self):
643
499
        lockable = _StubLockable(self._calls, unlock_exc=_ErrorFromUnlock())
644
500
        self.assertRaises(_ErrorFromUnlock,
645
 
                          _mod_branch._run_with_write_locked_target,
646
 
                          lockable, self.func_that_returns_ok)
 
501
            _run_with_write_locked_target, lockable, self.func_that_returns_ok)
647
502
        self.assertEqual(['lock_write', 'func called', 'unlock'], self._calls)
648
503
 
649
504
    def test_error_during_unlock_does_not_mask_original_error(self):
650
505
        lockable = _StubLockable(self._calls, unlock_exc=_ErrorFromUnlock())
651
506
        self.assertRaises(_ErrorFromCallable,
652
 
                          _mod_branch._run_with_write_locked_target,
653
 
                          lockable, self.func_that_raises)
 
507
            _run_with_write_locked_target, lockable, self.func_that_raises)
654
508
        self.assertEqual(['lock_write', 'func called', 'unlock'], self._calls)
655
509
 
656
510