~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-07-10 06:46:10 UTC
  • mto: (4525.1.1 integration)
  • mto: This revision was merged to the branch mainline in revision 4526.
  • Revision ID: mbp@sourcefrog.net-20090710064610-sqviksbqp5i34sw2
Rename to per_interrepository

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
    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):
41
59
 
42
60
    def test_default_format(self):
43
61
        # update this if you change the default branch format
44
 
        self.assertIsInstance(_mod_branch.BranchFormat.get_default_format(),
45
 
                _mod_branch.BzrBranchFormat7)
 
62
        self.assertIsInstance(BranchFormat.get_default_format(),
 
63
                BzrBranchFormat6)
46
64
 
47
65
    def test_default_format_is_same_as_bzrdir_default(self):
48
66
        # XXX: it might be nice if there was only one place the default was
49
67
        # set, but at the moment that's not true -- mbp 20070814 --
50
68
        # 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())
 
69
        self.assertEqual(BranchFormat.get_default_format(),
 
70
                BzrDirFormat.get_default_format().get_branch_format())
54
71
 
55
72
    def test_get_set_default_format(self):
56
73
        # 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())
 
74
        old_format = BranchFormat.get_default_format()
 
75
        BranchFormat.set_default_format(SampleBranchFormat())
59
76
        try:
60
77
            # the default branch format is used by the meta dir format
61
78
            # which is not the default bzrdir format at this point
62
 
            dir = bzrdir.BzrDirMetaFormat1().initialize('memory:///')
 
79
            dir = BzrDirMetaFormat1().initialize('memory:///')
63
80
            result = dir.create_branch()
64
81
            self.assertEqual(result, 'A branch')
65
82
        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):
 
83
            BranchFormat.set_default_format(old_format)
 
84
        self.assertEqual(old_format, BranchFormat.get_default_format())
 
85
 
 
86
 
 
87
class TestBranchFormat5(TestCaseWithTransport):
72
88
    """Tests specific to branch format 5"""
73
89
 
74
90
    def test_branch_format_5_uses_lockdir(self):
75
91
        url = self.get_url()
76
 
        bdir = bzrdir.BzrDirMetaFormat1().initialize(url)
77
 
        bdir.create_repository()
78
 
        branch = bdir.create_branch()
 
92
        bzrdir = BzrDirMetaFormat1().initialize(url)
 
93
        bzrdir.create_repository()
 
94
        branch = bzrdir.create_branch()
79
95
        t = self.get_transport()
80
96
        self.log("branch instance is %r" % branch)
81
 
        self.assert_(isinstance(branch, _mod_branch.BzrBranch5))
 
97
        self.assert_(isinstance(branch, BzrBranch5))
82
98
        self.assertIsDirectory('.', t)
83
99
        self.assertIsDirectory('.bzr/branch', t)
84
100
        self.assertIsDirectory('.bzr/branch/lock', t)
85
101
        branch.lock_write()
86
 
        self.addCleanup(branch.unlock)
87
 
        self.assertIsDirectory('.bzr/branch/lock/held', t)
 
102
        try:
 
103
            self.assertIsDirectory('.bzr/branch/lock/held', t)
 
104
        finally:
 
105
            branch.unlock()
88
106
 
89
107
    def test_set_push_location(self):
90
 
        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()
91
120
 
92
121
        branch = self.make_branch('.', format='knit')
93
122
        branch.set_push_location('foo')
96
125
                             "[%s]\n"
97
126
                             "push_location = foo\n"
98
127
                             "push_location:policy = norecurse\n" % local_path,
99
 
                             config.locations_config_filename())
 
128
                             fn)
100
129
 
101
130
    # TODO RBC 20051029 test getting a push location from a branch in a
102
131
    # recursive section - that is, it appends the branch name.
103
132
 
104
133
 
105
 
class SampleBranchFormat(_mod_branch.BranchFormat):
 
134
class SampleBranchFormat(BranchFormat):
106
135
    """A sample format
107
136
 
108
137
    this format is initializable, unsupported to aid in testing the
113
142
        """See BzrBranchFormat.get_format_string()."""
114
143
        return "Sample branch format."
115
144
 
116
 
    def initialize(self, a_bzrdir, name=None):
 
145
    def initialize(self, a_bzrdir):
117
146
        """Format 4 branches cannot be created."""
118
 
        t = a_bzrdir.get_branch_transport(self, name=name)
 
147
        t = a_bzrdir.get_branch_transport(self)
119
148
        t.put_bytes('format', self.get_format_string())
120
149
        return 'A branch'
121
150
 
122
151
    def is_supported(self):
123
152
        return False
124
153
 
125
 
    def open(self, transport, name=None, _found=False, ignore_fallbacks=False):
 
154
    def open(self, transport, _found=False, ignore_fallbacks=False):
126
155
        return "opened branch."
127
156
 
128
157
 
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):
 
158
class TestBzrBranchFormat(TestCaseWithTransport):
151
159
    """Tests for the BzrBranchFormat facility."""
152
160
 
153
161
    def test_find_format(self):
159
167
            dir = format._matchingbzrdir.initialize(url)
160
168
            dir.create_repository()
161
169
            format.initialize(dir)
162
 
            found_format = _mod_branch.BranchFormat.find_format(dir)
 
170
            found_format = BranchFormat.find_format(dir)
163
171
            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.")
 
172
        check_format(BzrBranchFormat5(), "bar")
176
173
 
177
174
    def test_find_format_not_branch(self):
178
175
        dir = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
179
 
        self.assertRaises(errors.NotBranchError,
180
 
                          _mod_branch.BranchFormat.find_format,
 
176
        self.assertRaises(NotBranchError,
 
177
                          BranchFormat.find_format,
181
178
                          dir)
182
179
 
183
180
    def test_find_format_unknown_format(self):
184
181
        dir = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
185
182
        SampleBranchFormat().initialize(dir)
186
 
        self.assertRaises(errors.UnknownFormatError,
187
 
                          _mod_branch.BranchFormat.find_format,
 
183
        self.assertRaises(UnknownFormatError,
 
184
                          BranchFormat.find_format,
188
185
                          dir)
189
186
 
190
187
    def test_register_unregister_format(self):
194
191
        # make a branch
195
192
        format.initialize(dir)
196
193
        # register a format for it.
197
 
        _mod_branch.BranchFormat.register_format(format)
 
194
        BranchFormat.register_format(format)
198
195
        # which branch.Open will refuse (not supported)
199
 
        self.assertRaises(errors.UnsupportedFormatError,
200
 
                          _mod_branch.Branch.open, self.get_url())
 
196
        self.assertRaises(UnsupportedFormatError, Branch.open, self.get_url())
201
197
        self.make_branch_and_tree('foo')
202
198
        # but open_downlevel will work
203
 
        self.assertEqual(
204
 
            format.open(dir),
205
 
            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))
206
200
        # unregister the format
207
 
        _mod_branch.BranchFormat.unregister_format(format)
 
201
        BranchFormat.unregister_format(format)
208
202
        self.make_branch_and_tree('bar')
209
203
 
210
204
 
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
205
class TestBranch67(object):
240
206
    """Common tests for both branch 6 and 7 which are mostly the same."""
241
207
 
249
215
        raise NotImplementedError(self.get_class)
250
216
 
251
217
    def test_creation(self):
252
 
        format = bzrdir.BzrDirMetaFormat1()
 
218
        format = BzrDirMetaFormat1()
253
219
        format.set_branch_format(_mod_branch.BzrBranchFormat6())
254
220
        branch = self.make_branch('a', format=format)
255
221
        self.assertIsInstance(branch, self.get_class())
342
308
                         'locations.conf')
343
309
 
344
310
 
345
 
class TestBranch6(TestBranch67, tests.TestCaseWithTransport):
 
311
class TestBranch6(TestBranch67, TestCaseWithTransport):
346
312
 
347
313
    def get_class(self):
348
314
        return _mod_branch.BzrBranch6
363
329
        self.assertRaises(errors.UnstackableBranchFormat, branch.get_stacked_on_url)
364
330
 
365
331
 
366
 
class TestBranch7(TestBranch67, tests.TestCaseWithTransport):
 
332
class TestBranch7(TestBranch67, TestCaseWithTransport):
367
333
 
368
334
    def get_class(self):
369
335
        return _mod_branch.BzrBranch7
413
379
        self.assertTrue(branch.repository.has_revision(revid))
414
380
 
415
381
 
416
 
class BzrBranch8(tests.TestCaseWithTransport):
 
382
class BzrBranch8(TestCaseWithTransport):
417
383
 
418
384
    def make_branch(self, location, format=None):
419
385
        if format is None:
420
386
            format = bzrdir.format_registry.make_bzrdir('1.9')
421
387
            format.set_branch_format(_mod_branch.BzrBranchFormat8())
422
 
        return tests.TestCaseWithTransport.make_branch(
423
 
            self, location, format=format)
 
388
        return TestCaseWithTransport.make_branch(self, location, format=format)
424
389
 
425
390
    def create_branch_with_reference(self):
426
391
        branch = self.make_branch('branch')
470
435
        branch.lock_write()
471
436
        branch.set_reference_info('file-id', 'path2', 'location2')
472
437
        branch.unlock()
473
 
        doppelganger = _mod_branch.Branch.open('branch')
 
438
        doppelganger = Branch.open('branch')
474
439
        doppelganger.set_reference_info('file-id', 'path3', 'location3')
475
440
        self.assertEqual(('path3', 'location3'),
476
441
                         branch.get_reference_info('file-id'))
477
442
 
478
 
class TestBranchReference(tests.TestCaseWithTransport):
 
443
class TestBranchReference(TestCaseWithTransport):
479
444
    """Tests for the branch reference facility."""
480
445
 
481
446
    def test_create_open_reference(self):
482
447
        bzrdirformat = bzrdir.BzrDirMetaFormat1()
483
 
        t = transport.get_transport(self.get_url('.'))
 
448
        t = get_transport(self.get_url('.'))
484
449
        t.mkdir('repo')
485
450
        dir = bzrdirformat.initialize(self.get_url('repo'))
486
451
        dir.create_repository()
487
452
        target_branch = dir.create_branch()
488
453
        t.mkdir('branch')
489
454
        branch_dir = bzrdirformat.initialize(self.get_url('branch'))
490
 
        made_branch = _mod_branch.BranchReferenceFormat().initialize(
491
 
            branch_dir, target_branch=target_branch)
 
455
        made_branch = BranchReferenceFormat().initialize(branch_dir, target_branch)
492
456
        self.assertEqual(made_branch.base, target_branch.base)
493
457
        opened_branch = branch_dir.open_branch()
494
458
        self.assertEqual(opened_branch.base, target_branch.base)
505
469
            _mod_branch.BranchReferenceFormat().get_reference(checkout.bzrdir))
506
470
 
507
471
 
508
 
class TestHooks(tests.TestCaseWithTransport):
 
472
class TestHooks(TestCase):
509
473
 
510
474
    def test_constructor(self):
511
475
        """Check that creating a BranchHooks instance has the right defaults."""
512
 
        hooks = _mod_branch.BranchHooks()
 
476
        hooks = BranchHooks()
513
477
        self.assertTrue("set_rh" in hooks, "set_rh not in %s" % hooks)
514
478
        self.assertTrue("post_push" in hooks, "post_push not in %s" % hooks)
515
479
        self.assertTrue("post_commit" in hooks, "post_commit not in %s" % hooks)
516
480
        self.assertTrue("pre_commit" in hooks, "pre_commit not in %s" % hooks)
517
481
        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)
 
482
        self.assertTrue("post_uncommit" in hooks, "post_uncommit not in %s" % hooks)
520
483
        self.assertTrue("post_change_branch_tip" in hooks,
521
484
                        "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
485
 
527
486
    def test_installed_hooks_are_BranchHooks(self):
528
487
        """The installed hooks object should be a BranchHooks."""
529
488
        # the installed hooks are saved in self._preserved_hooks.
530
489
        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):
 
490
            BranchHooks)
 
491
 
 
492
 
 
493
class TestPullResult(TestCase):
617
494
 
618
495
    def test_pull_result_to_int(self):
619
496
        # to support old code, the pull result can be used as an int
620
 
        r = _mod_branch.PullResult()
 
497
        r = PullResult()
621
498
        r.old_revno = 10
622
499
        r.new_revno = 20
623
500
        # this usage of results is not recommended for new code (because it
624
501
        # doesn't describe very well what happened), but for api stability
625
502
        # 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())
 
503
        a = "%d revisions pulled" % r
 
504
        self.assertEqual(a, "10 revisions pulled")
 
505
 
648
506
 
649
507
 
650
508
class _StubLockable(object):
671
529
    """Helper for TestRunWithWriteLockedTarget."""
672
530
 
673
531
 
674
 
class TestRunWithWriteLockedTarget(tests.TestCase):
 
532
class TestRunWithWriteLockedTarget(TestCase):
675
533
    """Tests for _run_with_write_locked_target."""
676
534
 
677
535
    def setUp(self):
678
 
        tests.TestCase.setUp(self)
 
536
        TestCase.setUp(self)
679
537
        self._calls = []
680
538
 
681
539
    def func_that_returns_ok(self):
688
546
 
689
547
    def test_success_unlocks(self):
690
548
        lockable = _StubLockable(self._calls)
691
 
        result = _mod_branch._run_with_write_locked_target(
 
549
        result = _run_with_write_locked_target(
692
550
            lockable, self.func_that_returns_ok)
693
551
        self.assertEqual('ok', result)
694
552
        self.assertEqual(['lock_write', 'func called', 'unlock'], self._calls)
696
554
    def test_exception_unlocks_and_propagates(self):
697
555
        lockable = _StubLockable(self._calls)
698
556
        self.assertRaises(_ErrorFromCallable,
699
 
                          _mod_branch._run_with_write_locked_target,
700
 
                          lockable, self.func_that_raises)
 
557
            _run_with_write_locked_target, lockable, self.func_that_raises)
701
558
        self.assertEqual(['lock_write', 'func called', 'unlock'], self._calls)
702
559
 
703
560
    def test_callable_succeeds_but_error_during_unlock(self):
704
561
        lockable = _StubLockable(self._calls, unlock_exc=_ErrorFromUnlock())
705
562
        self.assertRaises(_ErrorFromUnlock,
706
 
                          _mod_branch._run_with_write_locked_target,
707
 
                          lockable, self.func_that_returns_ok)
 
563
            _run_with_write_locked_target, lockable, self.func_that_returns_ok)
708
564
        self.assertEqual(['lock_write', 'func called', 'unlock'], self._calls)
709
565
 
710
566
    def test_error_during_unlock_does_not_mask_original_error(self):
711
567
        lockable = _StubLockable(self._calls, unlock_exc=_ErrorFromUnlock())
712
568
        self.assertRaises(_ErrorFromCallable,
713
 
                          _mod_branch._run_with_write_locked_target,
714
 
                          lockable, self.func_that_raises)
 
569
            _run_with_write_locked_target, lockable, self.func_that_raises)
715
570
        self.assertEqual(['lock_write', 'func called', 'unlock'], self._calls)
716
571
 
717
572