~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_branch.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2009-05-07 00:59:42 UTC
  • mfrom: (4340.1.1 bzr.dev)
  • Revision ID: pqm@pqm.ubuntu.com-20090507005942-wnvvomd3130f1vph
(Jelmer) Mention --force in the error message when unable to access
        in the master branch in 'bzr switch'.

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
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
 
        conf = config.LocationConfig.from_string('# comment\n', '.', save=True)
 
108
        from bzrlib.config import (locations_config_filename,
 
109
                                   ensure_config_dir_exists)
 
110
        ensure_config_dir_exists()
 
111
        fn = locations_config_filename()
 
112
        # write correct newlines to locations.conf
 
113
        # by default ConfigObj uses native line-endings for new files
 
114
        # but uses already existing line-endings if file is not empty
 
115
        f = open(fn, 'wb')
 
116
        try:
 
117
            f.write('# comment\n')
 
118
        finally:
 
119
            f.close()
90
120
 
91
121
        branch = self.make_branch('.', format='knit')
92
122
        branch.set_push_location('foo')
95
125
                             "[%s]\n"
96
126
                             "push_location = foo\n"
97
127
                             "push_location:policy = norecurse\n" % local_path,
98
 
                             config.locations_config_filename())
 
128
                             fn)
99
129
 
100
130
    # TODO RBC 20051029 test getting a push location from a branch in a
101
131
    # recursive section - that is, it appends the branch name.
102
132
 
103
133
 
104
 
class SampleBranchFormat(_mod_branch.BranchFormat):
 
134
class SampleBranchFormat(BranchFormat):
105
135
    """A sample format
106
136
 
107
137
    this format is initializable, unsupported to aid in testing the
112
142
        """See BzrBranchFormat.get_format_string()."""
113
143
        return "Sample branch format."
114
144
 
115
 
    def initialize(self, a_bzrdir, name=None):
 
145
    def initialize(self, a_bzrdir):
116
146
        """Format 4 branches cannot be created."""
117
 
        t = a_bzrdir.get_branch_transport(self, name=name)
 
147
        t = a_bzrdir.get_branch_transport(self)
118
148
        t.put_bytes('format', self.get_format_string())
119
149
        return 'A branch'
120
150
 
121
151
    def is_supported(self):
122
152
        return False
123
153
 
124
 
    def open(self, transport, name=None, _found=False, ignore_fallbacks=False):
 
154
    def open(self, transport, _found=False, ignore_fallbacks=False):
125
155
        return "opened branch."
126
156
 
127
157
 
128
 
# Demonstrating how lazy loading is often implemented:
129
 
# A constant string is created.
130
 
SampleSupportedBranchFormatString = "Sample supported branch format."
131
 
 
132
 
# And the format class can then reference the constant to avoid skew.
133
 
class SampleSupportedBranchFormat(_mod_branch.BranchFormat):
134
 
    """A sample supported format."""
135
 
 
136
 
    def get_format_string(self):
137
 
        """See BzrBranchFormat.get_format_string()."""
138
 
        return SampleSupportedBranchFormatString
139
 
 
140
 
    def initialize(self, a_bzrdir, name=None):
141
 
        t = a_bzrdir.get_branch_transport(self, name=name)
142
 
        t.put_bytes('format', self.get_format_string())
143
 
        return 'A branch'
144
 
 
145
 
    def open(self, transport, name=None, _found=False, ignore_fallbacks=False):
146
 
        return "opened supported branch."
147
 
 
148
 
 
149
 
class TestBzrBranchFormat(tests.TestCaseWithTransport):
 
158
class TestBzrBranchFormat(TestCaseWithTransport):
150
159
    """Tests for the BzrBranchFormat facility."""
151
160
 
152
161
    def test_find_format(self):
158
167
            dir = format._matchingbzrdir.initialize(url)
159
168
            dir.create_repository()
160
169
            format.initialize(dir)
161
 
            found_format = _mod_branch.BranchFormat.find_format(dir)
 
170
            found_format = BranchFormat.find_format(dir)
162
171
            self.failUnless(isinstance(found_format, format.__class__))
163
 
        check_format(_mod_branch.BzrBranchFormat5(), "bar")
164
 
 
165
 
    def test_find_format_factory(self):
166
 
        dir = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
167
 
        SampleSupportedBranchFormat().initialize(dir)
168
 
        factory = _mod_branch.MetaDirBranchFormatFactory(
169
 
            SampleSupportedBranchFormatString,
170
 
            "bzrlib.tests.test_branch", "SampleSupportedBranchFormat")
171
 
        _mod_branch.BranchFormat.register_format(factory)
172
 
        self.addCleanup(_mod_branch.BranchFormat.unregister_format, factory)
173
 
        b = _mod_branch.Branch.open(self.get_url())
174
 
        self.assertEqual(b, "opened supported branch.")
 
172
        check_format(BzrBranchFormat5(), "bar")
175
173
 
176
174
    def test_find_format_not_branch(self):
177
175
        dir = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
178
 
        self.assertRaises(errors.NotBranchError,
179
 
                          _mod_branch.BranchFormat.find_format,
 
176
        self.assertRaises(NotBranchError,
 
177
                          BranchFormat.find_format,
180
178
                          dir)
181
179
 
182
180
    def test_find_format_unknown_format(self):
183
181
        dir = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
184
182
        SampleBranchFormat().initialize(dir)
185
 
        self.assertRaises(errors.UnknownFormatError,
186
 
                          _mod_branch.BranchFormat.find_format,
 
183
        self.assertRaises(UnknownFormatError,
 
184
                          BranchFormat.find_format,
187
185
                          dir)
188
186
 
189
187
    def test_register_unregister_format(self):
193
191
        # make a branch
194
192
        format.initialize(dir)
195
193
        # register a format for it.
196
 
        _mod_branch.BranchFormat.register_format(format)
 
194
        BranchFormat.register_format(format)
197
195
        # which branch.Open will refuse (not supported)
198
 
        self.assertRaises(errors.UnsupportedFormatError,
199
 
                          _mod_branch.Branch.open, self.get_url())
 
196
        self.assertRaises(UnsupportedFormatError, Branch.open, self.get_url())
200
197
        self.make_branch_and_tree('foo')
201
198
        # but open_downlevel will work
202
 
        self.assertEqual(
203
 
            format.open(dir),
204
 
            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))
205
200
        # unregister the format
206
 
        _mod_branch.BranchFormat.unregister_format(format)
 
201
        BranchFormat.unregister_format(format)
207
202
        self.make_branch_and_tree('bar')
208
203
 
209
204
 
210
 
#Used by TestMetaDirBranchFormatFactory 
211
 
FakeLazyFormat = None
212
 
 
213
 
 
214
 
class TestMetaDirBranchFormatFactory(tests.TestCase):
215
 
 
216
 
    def test_get_format_string_does_not_load(self):
217
 
        """Formats have a static format string."""
218
 
        factory = _mod_branch.MetaDirBranchFormatFactory("yo", None, None)
219
 
        self.assertEqual("yo", factory.get_format_string())
220
 
 
221
 
    def test_call_loads(self):
222
 
        # __call__ is used by the network_format_registry interface to get a
223
 
        # Format.
224
 
        global FakeLazyFormat
225
 
        del FakeLazyFormat
226
 
        factory = _mod_branch.MetaDirBranchFormatFactory(None,
227
 
            "bzrlib.tests.test_branch", "FakeLazyFormat")
228
 
        self.assertRaises(AttributeError, factory)
229
 
 
230
 
    def test_call_returns_call_of_referenced_object(self):
231
 
        global FakeLazyFormat
232
 
        FakeLazyFormat = lambda:'called'
233
 
        factory = _mod_branch.MetaDirBranchFormatFactory(None,
234
 
            "bzrlib.tests.test_branch", "FakeLazyFormat")
235
 
        self.assertEqual('called', factory())
236
 
 
237
 
 
238
205
class TestBranch67(object):
239
206
    """Common tests for both branch 6 and 7 which are mostly the same."""
240
207
 
248
215
        raise NotImplementedError(self.get_class)
249
216
 
250
217
    def test_creation(self):
251
 
        format = bzrdir.BzrDirMetaFormat1()
 
218
        format = BzrDirMetaFormat1()
252
219
        format.set_branch_format(_mod_branch.BzrBranchFormat6())
253
220
        branch = self.make_branch('a', format=format)
254
221
        self.assertIsInstance(branch, self.get_class())
341
308
                         'locations.conf')
342
309
 
343
310
 
344
 
class TestBranch6(TestBranch67, tests.TestCaseWithTransport):
 
311
class TestBranch6(TestBranch67, TestCaseWithTransport):
345
312
 
346
313
    def get_class(self):
347
314
        return _mod_branch.BzrBranch6
362
329
        self.assertRaises(errors.UnstackableBranchFormat, branch.get_stacked_on_url)
363
330
 
364
331
 
365
 
class TestBranch7(TestBranch67, tests.TestCaseWithTransport):
 
332
class TestBranch7(TestBranch67, TestCaseWithTransport):
366
333
 
367
334
    def get_class(self):
368
335
        return _mod_branch.BzrBranch7
412
379
        self.assertTrue(branch.repository.has_revision(revid))
413
380
 
414
381
 
415
 
class BzrBranch8(tests.TestCaseWithTransport):
 
382
class BzrBranch8(TestCaseWithTransport):
416
383
 
417
384
    def make_branch(self, location, format=None):
418
385
        if format is None:
419
386
            format = bzrdir.format_registry.make_bzrdir('1.9')
420
387
            format.set_branch_format(_mod_branch.BzrBranchFormat8())
421
 
        return tests.TestCaseWithTransport.make_branch(
422
 
            self, location, format=format)
 
388
        return TestCaseWithTransport.make_branch(self, location, format=format)
423
389
 
424
390
    def create_branch_with_reference(self):
425
391
        branch = self.make_branch('branch')
469
435
        branch.lock_write()
470
436
        branch.set_reference_info('file-id', 'path2', 'location2')
471
437
        branch.unlock()
472
 
        doppelganger = _mod_branch.Branch.open('branch')
 
438
        doppelganger = Branch.open('branch')
473
439
        doppelganger.set_reference_info('file-id', 'path3', 'location3')
474
440
        self.assertEqual(('path3', 'location3'),
475
441
                         branch.get_reference_info('file-id'))
476
442
 
477
 
class TestBranchReference(tests.TestCaseWithTransport):
 
443
class TestBranchReference(TestCaseWithTransport):
478
444
    """Tests for the branch reference facility."""
479
445
 
480
446
    def test_create_open_reference(self):
481
447
        bzrdirformat = bzrdir.BzrDirMetaFormat1()
482
 
        t = transport.get_transport(self.get_url('.'))
 
448
        t = get_transport(self.get_url('.'))
483
449
        t.mkdir('repo')
484
450
        dir = bzrdirformat.initialize(self.get_url('repo'))
485
451
        dir.create_repository()
486
452
        target_branch = dir.create_branch()
487
453
        t.mkdir('branch')
488
454
        branch_dir = bzrdirformat.initialize(self.get_url('branch'))
489
 
        made_branch = _mod_branch.BranchReferenceFormat().initialize(
490
 
            branch_dir, target_branch=target_branch)
 
455
        made_branch = BranchReferenceFormat().initialize(branch_dir, target_branch)
491
456
        self.assertEqual(made_branch.base, target_branch.base)
492
457
        opened_branch = branch_dir.open_branch()
493
458
        self.assertEqual(opened_branch.base, target_branch.base)
504
469
            _mod_branch.BranchReferenceFormat().get_reference(checkout.bzrdir))
505
470
 
506
471
 
507
 
class TestHooks(tests.TestCaseWithTransport):
 
472
class TestHooks(TestCase):
508
473
 
509
474
    def test_constructor(self):
510
475
        """Check that creating a BranchHooks instance has the right defaults."""
511
 
        hooks = _mod_branch.BranchHooks()
 
476
        hooks = BranchHooks()
512
477
        self.assertTrue("set_rh" in hooks, "set_rh not in %s" % hooks)
513
478
        self.assertTrue("post_push" in hooks, "post_push not in %s" % hooks)
514
479
        self.assertTrue("post_commit" in hooks, "post_commit not in %s" % hooks)
515
480
        self.assertTrue("pre_commit" in hooks, "pre_commit not in %s" % hooks)
516
481
        self.assertTrue("post_pull" in hooks, "post_pull not in %s" % hooks)
517
 
        self.assertTrue("post_uncommit" in hooks,
518
 
                        "post_uncommit not in %s" % hooks)
 
482
        self.assertTrue("post_uncommit" in hooks, "post_uncommit not in %s" % hooks)
519
483
        self.assertTrue("post_change_branch_tip" in hooks,
520
484
                        "post_change_branch_tip not in %s" % hooks)
521
 
        self.assertTrue("post_branch_init" in hooks,
522
 
                        "post_branch_init not in %s" % hooks)
523
 
        self.assertTrue("post_switch" in hooks,
524
 
                        "post_switch not in %s" % hooks)
525
485
 
526
486
    def test_installed_hooks_are_BranchHooks(self):
527
487
        """The installed hooks object should be a BranchHooks."""
528
488
        # the installed hooks are saved in self._preserved_hooks.
529
489
        self.assertIsInstance(self._preserved_hooks[_mod_branch.Branch][1],
530
 
                              _mod_branch.BranchHooks)
531
 
 
532
 
    def test_post_branch_init_hook(self):
533
 
        calls = []
534
 
        _mod_branch.Branch.hooks.install_named_hook('post_branch_init',
535
 
            calls.append, None)
536
 
        self.assertLength(0, calls)
537
 
        branch = self.make_branch('a')
538
 
        self.assertLength(1, calls)
539
 
        params = calls[0]
540
 
        self.assertIsInstance(params, _mod_branch.BranchInitHookParams)
541
 
        self.assertTrue(hasattr(params, 'bzrdir'))
542
 
        self.assertTrue(hasattr(params, 'branch'))
543
 
 
544
 
    def test_post_branch_init_hook_repr(self):
545
 
        param_reprs = []
546
 
        _mod_branch.Branch.hooks.install_named_hook('post_branch_init',
547
 
            lambda params: param_reprs.append(repr(params)), None)
548
 
        branch = self.make_branch('a')
549
 
        self.assertLength(1, param_reprs)
550
 
        param_repr = param_reprs[0]
551
 
        self.assertStartsWith(param_repr, '<BranchInitHookParams of ')
552
 
 
553
 
    def test_post_switch_hook(self):
554
 
        from bzrlib import switch
555
 
        calls = []
556
 
        _mod_branch.Branch.hooks.install_named_hook('post_switch',
557
 
            calls.append, None)
558
 
        tree = self.make_branch_and_tree('branch-1')
559
 
        self.build_tree(['branch-1/file-1'])
560
 
        tree.add('file-1')
561
 
        tree.commit('rev1')
562
 
        to_branch = tree.bzrdir.sprout('branch-2').open_branch()
563
 
        self.build_tree(['branch-1/file-2'])
564
 
        tree.add('file-2')
565
 
        tree.remove('file-1')
566
 
        tree.commit('rev2')
567
 
        checkout = tree.branch.create_checkout('checkout')
568
 
        self.assertLength(0, calls)
569
 
        switch.switch(checkout.bzrdir, to_branch)
570
 
        self.assertLength(1, calls)
571
 
        params = calls[0]
572
 
        self.assertIsInstance(params, _mod_branch.SwitchHookParams)
573
 
        self.assertTrue(hasattr(params, 'to_branch'))
574
 
        self.assertTrue(hasattr(params, 'revision_id'))
575
 
 
576
 
 
577
 
class TestBranchOptions(tests.TestCaseWithTransport):
578
 
 
579
 
    def setUp(self):
580
 
        super(TestBranchOptions, self).setUp()
581
 
        self.branch = self.make_branch('.')
582
 
        self.config = self.branch.get_config()
583
 
 
584
 
    def check_append_revisions_only(self, expected_value, value=None):
585
 
        """Set append_revisions_only in config and check its interpretation."""
586
 
        if value is not None:
587
 
            self.config.set_user_option('append_revisions_only', value)
588
 
        self.assertEqual(expected_value,
589
 
                         self.branch._get_append_revisions_only())
590
 
 
591
 
    def test_valid_append_revisions_only(self):
592
 
        self.assertEquals(None,
593
 
                          self.config.get_user_option('append_revisions_only'))
594
 
        self.check_append_revisions_only(None)
595
 
        self.check_append_revisions_only(False, 'False')
596
 
        self.check_append_revisions_only(True, 'True')
597
 
        # The following values will cause compatibility problems on projects
598
 
        # using older bzr versions (<2.2) but are accepted
599
 
        self.check_append_revisions_only(False, 'false')
600
 
        self.check_append_revisions_only(True, 'true')
601
 
 
602
 
    def test_invalid_append_revisions_only(self):
603
 
        """Ensure warning is noted on invalid settings"""
604
 
        self.warnings = []
605
 
        def warning(*args):
606
 
            self.warnings.append(args[0] % args[1:])
607
 
        self.overrideAttr(trace, 'warning', warning)
608
 
        self.check_append_revisions_only(None, 'not-a-bool')
609
 
        self.assertLength(1, self.warnings)
610
 
        self.assertEqual(
611
 
            'Value "not-a-bool" is not a boolean for "append_revisions_only"',
612
 
            self.warnings[0])
613
 
 
614
 
 
615
 
class TestPullResult(tests.TestCase):
 
490
            BranchHooks)
 
491
 
 
492
 
 
493
class TestPullResult(TestCase):
616
494
 
617
495
    def test_pull_result_to_int(self):
618
496
        # to support old code, the pull result can be used as an int
619
 
        r = _mod_branch.PullResult()
 
497
        r = PullResult()
620
498
        r.old_revno = 10
621
499
        r.new_revno = 20
622
500
        # this usage of results is not recommended for new code (because it
625
503
        a = "%d revisions pulled" % r
626
504
        self.assertEqual(a, "10 revisions pulled")
627
505
 
628
 
    def test_report_changed(self):
629
 
        r = _mod_branch.PullResult()
630
 
        r.old_revid = "old-revid"
631
 
        r.old_revno = 10
632
 
        r.new_revid = "new-revid"
633
 
        r.new_revno = 20
634
 
        f = StringIO()
635
 
        r.report(f)
636
 
        self.assertEqual("Now on revision 20.\n", f.getvalue())
637
 
 
638
 
    def test_report_unchanged(self):
639
 
        r = _mod_branch.PullResult()
640
 
        r.old_revid = "same-revid"
641
 
        r.new_revid = "same-revid"
642
 
        f = StringIO()
643
 
        r.report(f)
644
 
        self.assertEqual("No revisions to pull.\n", f.getvalue())
645
506
 
646
507
 
647
508
class _StubLockable(object):
668
529
    """Helper for TestRunWithWriteLockedTarget."""
669
530
 
670
531
 
671
 
class TestRunWithWriteLockedTarget(tests.TestCase):
 
532
class TestRunWithWriteLockedTarget(TestCase):
672
533
    """Tests for _run_with_write_locked_target."""
673
534
 
674
535
    def setUp(self):
675
 
        tests.TestCase.setUp(self)
 
536
        TestCase.setUp(self)
676
537
        self._calls = []
677
538
 
678
539
    def func_that_returns_ok(self):
685
546
 
686
547
    def test_success_unlocks(self):
687
548
        lockable = _StubLockable(self._calls)
688
 
        result = _mod_branch._run_with_write_locked_target(
 
549
        result = _run_with_write_locked_target(
689
550
            lockable, self.func_that_returns_ok)
690
551
        self.assertEqual('ok', result)
691
552
        self.assertEqual(['lock_write', 'func called', 'unlock'], self._calls)
693
554
    def test_exception_unlocks_and_propagates(self):
694
555
        lockable = _StubLockable(self._calls)
695
556
        self.assertRaises(_ErrorFromCallable,
696
 
                          _mod_branch._run_with_write_locked_target,
697
 
                          lockable, self.func_that_raises)
 
557
            _run_with_write_locked_target, lockable, self.func_that_raises)
698
558
        self.assertEqual(['lock_write', 'func called', 'unlock'], self._calls)
699
559
 
700
560
    def test_callable_succeeds_but_error_during_unlock(self):
701
561
        lockable = _StubLockable(self._calls, unlock_exc=_ErrorFromUnlock())
702
562
        self.assertRaises(_ErrorFromUnlock,
703
 
                          _mod_branch._run_with_write_locked_target,
704
 
                          lockable, self.func_that_returns_ok)
 
563
            _run_with_write_locked_target, lockable, self.func_that_returns_ok)
705
564
        self.assertEqual(['lock_write', 'func called', 'unlock'], self._calls)
706
565
 
707
566
    def test_error_during_unlock_does_not_mask_original_error(self):
708
567
        lockable = _StubLockable(self._calls, unlock_exc=_ErrorFromUnlock())
709
568
        self.assertRaises(_ErrorFromCallable,
710
 
                          _mod_branch._run_with_write_locked_target,
711
 
                          lockable, self.func_that_raises)
 
569
            _run_with_write_locked_target, lockable, self.func_that_raises)
712
570
        self.assertEqual(['lock_write', 'func called', 'unlock'], self._calls)
713
571
 
714
572