~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_branch.py

  • Committer: Martin Pool
  • Date: 2009-09-14 02:30:23 UTC
  • mto: This revision was merged to the branch mainline in revision 4693.
  • Revision ID: mbp@sourcefrog.net-20090914023023-ros0f3ndo04j3bww
Clearer docs about bzr help.  (Thanks to Naoki)

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