~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_branch.py

  • Committer: Jelmer Vernooij
  • Date: 2011-12-16 19:18:39 UTC
  • mto: This revision was merged to the branch mainline in revision 6391.
  • Revision ID: jelmer@samba.org-20111216191839-eg681lxqibi1qxu1
Fix remaining tests.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006-2010 Canonical Ltd
 
1
# Copyright (C) 2006-2011 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/per_branch/*.py`.
20
20
 
21
21
For concrete class tests see this file, and for meta-branch tests
22
22
also see this file.
32
32
    symbol_versioning,
33
33
    tests,
34
34
    trace,
35
 
    transport,
36
35
    urlutils,
37
36
    )
38
37
 
41
40
 
42
41
    def test_default_format(self):
43
42
        # update this if you change the default branch format
44
 
        self.assertIsInstance(_mod_branch.BranchFormat.get_default_format(),
 
43
        self.assertIsInstance(_mod_branch.format_registry.get_default(),
45
44
                _mod_branch.BzrBranchFormat7)
46
45
 
47
46
    def test_default_format_is_same_as_bzrdir_default(self):
49
48
        # set, but at the moment that's not true -- mbp 20070814 --
50
49
        # https://bugs.launchpad.net/bzr/+bug/132376
51
50
        self.assertEqual(
52
 
            _mod_branch.BranchFormat.get_default_format(),
 
51
            _mod_branch.format_registry.get_default(),
53
52
            bzrdir.BzrDirFormat.get_default_format().get_branch_format())
54
53
 
55
54
    def test_get_set_default_format(self):
56
55
        # 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())
 
56
        old_format = _mod_branch.format_registry.get_default()
 
57
        _mod_branch.format_registry.set_default(SampleBranchFormat())
59
58
        try:
60
59
            # the default branch format is used by the meta dir format
61
60
            # which is not the default bzrdir format at this point
63
62
            result = dir.create_branch()
64
63
            self.assertEqual(result, 'A branch')
65
64
        finally:
66
 
            _mod_branch.BranchFormat.set_default_format(old_format)
 
65
            _mod_branch.format_registry.set_default(old_format)
67
66
        self.assertEqual(old_format,
68
 
                         _mod_branch.BranchFormat.get_default_format())
 
67
                         _mod_branch.format_registry.get_default())
69
68
 
70
69
 
71
70
class TestBranchFormat5(tests.TestCaseWithTransport):
75
74
        url = self.get_url()
76
75
        bdir = bzrdir.BzrDirMetaFormat1().initialize(url)
77
76
        bdir.create_repository()
78
 
        branch = bdir.create_branch()
 
77
        branch = _mod_branch.BzrBranchFormat5().initialize(bdir)
79
78
        t = self.get_transport()
80
79
        self.log("branch instance is %r" % branch)
81
80
        self.assert_(isinstance(branch, _mod_branch.BzrBranch5))
102
101
    # recursive section - that is, it appends the branch name.
103
102
 
104
103
 
105
 
class SampleBranchFormat(_mod_branch.BranchFormat):
 
104
class SampleBranchFormat(_mod_branch.BranchFormatMetadir):
106
105
    """A sample format
107
106
 
108
107
    this format is initializable, unsupported to aid in testing the
109
108
    open and open_downlevel routines.
110
109
    """
111
110
 
112
 
    def get_format_string(self):
 
111
    @classmethod
 
112
    def get_format_string(cls):
113
113
        """See BzrBranchFormat.get_format_string()."""
114
114
        return "Sample branch format."
115
115
 
116
 
    def initialize(self, a_bzrdir, name=None):
 
116
    def initialize(self, a_bzrdir, name=None, repository=None,
 
117
                   append_revisions_only=None):
117
118
        """Format 4 branches cannot be created."""
118
119
        t = a_bzrdir.get_branch_transport(self, name=name)
119
120
        t.put_bytes('format', self.get_format_string())
122
123
    def is_supported(self):
123
124
        return False
124
125
 
125
 
    def open(self, transport, name=None, _found=False, ignore_fallbacks=False):
 
126
    def open(self, transport, name=None, _found=False, ignore_fallbacks=False,
 
127
             possible_transports=None):
126
128
        return "opened branch."
127
129
 
128
130
 
131
133
SampleSupportedBranchFormatString = "Sample supported branch format."
132
134
 
133
135
# And the format class can then reference the constant to avoid skew.
134
 
class SampleSupportedBranchFormat(_mod_branch.BranchFormat):
 
136
class SampleSupportedBranchFormat(_mod_branch.BranchFormatMetadir):
135
137
    """A sample supported format."""
136
138
 
137
 
    def get_format_string(self):
 
139
    @classmethod
 
140
    def get_format_string(cls):
138
141
        """See BzrBranchFormat.get_format_string()."""
139
142
        return SampleSupportedBranchFormatString
140
143
 
141
 
    def initialize(self, a_bzrdir, name=None):
 
144
    def initialize(self, a_bzrdir, name=None, append_revisions_only=None):
142
145
        t = a_bzrdir.get_branch_transport(self, name=name)
143
146
        t.put_bytes('format', self.get_format_string())
144
147
        return 'A branch'
145
148
 
146
 
    def open(self, transport, name=None, _found=False, ignore_fallbacks=False):
 
149
    def open(self, transport, name=None, _found=False, ignore_fallbacks=False,
 
150
             possible_transports=None):
147
151
        return "opened supported branch."
148
152
 
149
153
 
 
154
class SampleExtraBranchFormat(_mod_branch.BranchFormat):
 
155
    """A sample format that is not usable in a metadir."""
 
156
 
 
157
    def get_format_string(self):
 
158
        # This format is not usable in a metadir.
 
159
        return None
 
160
 
 
161
    def network_name(self):
 
162
        # Network name always has to be provided.
 
163
        return "extra"
 
164
 
 
165
    def initialize(self, a_bzrdir, name=None):
 
166
        raise NotImplementedError(self.initialize)
 
167
 
 
168
    def open(self, transport, name=None, _found=False, ignore_fallbacks=False,
 
169
             possible_transports=None):
 
170
        raise NotImplementedError(self.open)
 
171
 
 
172
 
150
173
class TestBzrBranchFormat(tests.TestCaseWithTransport):
151
174
    """Tests for the BzrBranchFormat facility."""
152
175
 
159
182
            dir = format._matchingbzrdir.initialize(url)
160
183
            dir.create_repository()
161
184
            format.initialize(dir)
162
 
            found_format = _mod_branch.BranchFormat.find_format(dir)
163
 
            self.failUnless(isinstance(found_format, format.__class__))
 
185
            found_format = _mod_branch.BranchFormatMetadir.find_format(dir)
 
186
            self.assertIsInstance(found_format, format.__class__)
164
187
        check_format(_mod_branch.BzrBranchFormat5(), "bar")
165
188
 
166
189
    def test_find_format_factory(self):
169
192
        factory = _mod_branch.MetaDirBranchFormatFactory(
170
193
            SampleSupportedBranchFormatString,
171
194
            "bzrlib.tests.test_branch", "SampleSupportedBranchFormat")
172
 
        _mod_branch.BranchFormat.register_format(factory)
173
 
        self.addCleanup(_mod_branch.BranchFormat.unregister_format, factory)
 
195
        _mod_branch.format_registry.register(factory)
 
196
        self.addCleanup(_mod_branch.format_registry.remove, factory)
174
197
        b = _mod_branch.Branch.open(self.get_url())
175
198
        self.assertEqual(b, "opened supported branch.")
176
199
 
 
200
    def test_from_string(self):
 
201
        self.assertIsInstance(
 
202
            SampleBranchFormat.from_string("Sample branch format."),
 
203
            SampleBranchFormat)
 
204
        self.assertRaises(ValueError,
 
205
            SampleBranchFormat.from_string, "Different branch format.")
 
206
 
177
207
    def test_find_format_not_branch(self):
178
208
        dir = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
179
209
        self.assertRaises(errors.NotBranchError,
180
 
                          _mod_branch.BranchFormat.find_format,
 
210
                          _mod_branch.BranchFormatMetadir.find_format,
181
211
                          dir)
182
212
 
183
213
    def test_find_format_unknown_format(self):
184
214
        dir = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
185
215
        SampleBranchFormat().initialize(dir)
186
216
        self.assertRaises(errors.UnknownFormatError,
187
 
                          _mod_branch.BranchFormat.find_format,
 
217
                          _mod_branch.BranchFormatMetadir.find_format,
188
218
                          dir)
189
219
 
190
220
    def test_register_unregister_format(self):
 
221
        # Test the deprecated format registration functions
191
222
        format = SampleBranchFormat()
192
223
        # make a control dir
193
224
        dir = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
194
225
        # make a branch
195
226
        format.initialize(dir)
196
227
        # register a format for it.
197
 
        _mod_branch.BranchFormat.register_format(format)
 
228
        self.applyDeprecated(symbol_versioning.deprecated_in((2, 4, 0)),
 
229
            _mod_branch.BranchFormat.register_format, format)
198
230
        # which branch.Open will refuse (not supported)
199
231
        self.assertRaises(errors.UnsupportedFormatError,
200
232
                          _mod_branch.Branch.open, self.get_url())
204
236
            format.open(dir),
205
237
            bzrdir.BzrDir.open(self.get_url()).open_branch(unsupported=True))
206
238
        # unregister the format
207
 
        _mod_branch.BranchFormat.unregister_format(format)
 
239
        self.applyDeprecated(symbol_versioning.deprecated_in((2, 4, 0)),
 
240
            _mod_branch.BranchFormat.unregister_format, format)
208
241
        self.make_branch_and_tree('bar')
209
242
 
210
243
 
 
244
class TestBranchFormatRegistry(tests.TestCase):
 
245
 
 
246
    def setUp(self):
 
247
        super(TestBranchFormatRegistry, self).setUp()
 
248
        self.registry = _mod_branch.BranchFormatRegistry()
 
249
 
 
250
    def test_default(self):
 
251
        self.assertIs(None, self.registry.get_default())
 
252
        format = SampleBranchFormat()
 
253
        self.registry.set_default(format)
 
254
        self.assertEquals(format, self.registry.get_default())
 
255
 
 
256
    def test_register_unregister_format(self):
 
257
        format = SampleBranchFormat()
 
258
        self.registry.register(format)
 
259
        self.assertEquals(format,
 
260
            self.registry.get("Sample branch format."))
 
261
        self.registry.remove(format)
 
262
        self.assertRaises(KeyError, self.registry.get,
 
263
            "Sample branch format.")
 
264
 
 
265
    def test_get_all(self):
 
266
        format = SampleBranchFormat()
 
267
        self.assertEquals([], self.registry._get_all())
 
268
        self.registry.register(format)
 
269
        self.assertEquals([format], self.registry._get_all())
 
270
 
 
271
    def test_register_extra(self):
 
272
        format = SampleExtraBranchFormat()
 
273
        self.assertEquals([], self.registry._get_all())
 
274
        self.registry.register_extra(format)
 
275
        self.assertEquals([format], self.registry._get_all())
 
276
 
 
277
    def test_register_extra_lazy(self):
 
278
        self.assertEquals([], self.registry._get_all())
 
279
        self.registry.register_extra_lazy("bzrlib.tests.test_branch",
 
280
            "SampleExtraBranchFormat")
 
281
        formats = self.registry._get_all()
 
282
        self.assertEquals(1, len(formats))
 
283
        self.assertIsInstance(formats[0], SampleExtraBranchFormat)
 
284
 
 
285
 
211
286
#Used by TestMetaDirBranchFormatFactory 
212
287
FakeLazyFormat = None
213
288
 
260
335
 
261
336
    def test_layout(self):
262
337
        branch = self.make_branch('a', format=self.get_format_name())
263
 
        self.failUnlessExists('a/.bzr/branch/last-revision')
264
 
        self.failIfExists('a/.bzr/branch/revision-history')
265
 
        self.failIfExists('a/.bzr/branch/references')
 
338
        self.assertPathExists('a/.bzr/branch/last-revision')
 
339
        self.assertPathDoesNotExist('a/.bzr/branch/revision-history')
 
340
        self.assertPathDoesNotExist('a/.bzr/branch/references')
266
341
 
267
342
    def test_config(self):
268
343
        """Ensure that all configuration data is stored in the branch"""
269
344
        branch = self.make_branch('a', format=self.get_format_name())
270
 
        branch.set_parent('http://bazaar-vcs.org')
271
 
        self.failIfExists('a/.bzr/branch/parent')
272
 
        self.assertEqual('http://bazaar-vcs.org', branch.get_parent())
273
 
        branch.set_push_location('sftp://bazaar-vcs.org')
 
345
        branch.set_parent('http://example.com')
 
346
        self.assertPathDoesNotExist('a/.bzr/branch/parent')
 
347
        self.assertEqual('http://example.com', branch.get_parent())
 
348
        branch.set_push_location('sftp://example.com')
274
349
        config = branch.get_config()._get_branch_data_config()
275
 
        self.assertEqual('sftp://bazaar-vcs.org',
 
350
        self.assertEqual('sftp://example.com',
276
351
                         config.get_user_option('push_location'))
277
 
        branch.set_bound_location('ftp://bazaar-vcs.org')
278
 
        self.failIfExists('a/.bzr/branch/bound')
279
 
        self.assertEqual('ftp://bazaar-vcs.org', branch.get_bound_location())
 
352
        branch.set_bound_location('ftp://example.com')
 
353
        self.assertPathDoesNotExist('a/.bzr/branch/bound')
 
354
        self.assertEqual('ftp://example.com', branch.get_bound_location())
280
355
 
281
356
    def test_set_revision_history(self):
282
357
        builder = self.make_branch_builder('.', format=self.get_format_name())
287
362
        branch = builder.get_branch()
288
363
        branch.lock_write()
289
364
        self.addCleanup(branch.unlock)
290
 
        branch.set_revision_history(['foo', 'bar'])
291
 
        branch.set_revision_history(['foo'])
 
365
        self.applyDeprecated(symbol_versioning.deprecated_in((2, 4, 0)),
 
366
            branch.set_revision_history, ['foo', 'bar'])
 
367
        self.applyDeprecated(symbol_versioning.deprecated_in((2, 4, 0)),
 
368
                branch.set_revision_history, ['foo'])
292
369
        self.assertRaises(errors.NotLefthandHistory,
293
 
                          branch.set_revision_history, ['bar'])
 
370
            self.applyDeprecated, symbol_versioning.deprecated_in((2, 4, 0)),
 
371
            branch.set_revision_history, ['bar'])
294
372
 
295
373
    def do_checkout_test(self, lightweight=False):
296
374
        tree = self.make_branch_and_tree('source',
309
387
        subtree.commit('a subtree file')
310
388
        subsubtree.commit('a subsubtree file')
311
389
        tree.branch.create_checkout('target', lightweight=lightweight)
312
 
        self.failUnlessExists('target')
313
 
        self.failUnlessExists('target/subtree')
314
 
        self.failUnlessExists('target/subtree/file')
315
 
        self.failUnlessExists('target/subtree/subsubtree/file')
 
390
        self.assertPathExists('target')
 
391
        self.assertPathExists('target/subtree')
 
392
        self.assertPathExists('target/subtree/file')
 
393
        self.assertPathExists('target/subtree/subsubtree/file')
316
394
        subbranch = _mod_branch.Branch.open('target/subtree/subsubtree')
317
395
        if lightweight:
318
396
            self.assertEndsWith(subbranch.base, 'source/subtree/subsubtree/')
475
553
        self.assertEqual(('path3', 'location3'),
476
554
                         branch.get_reference_info('file-id'))
477
555
 
 
556
    def _recordParentMapCalls(self, repo):
 
557
        self._parent_map_calls = []
 
558
        orig_get_parent_map = repo.revisions.get_parent_map
 
559
        def get_parent_map(q):
 
560
            q = list(q)
 
561
            self._parent_map_calls.extend([e[0] for e in q])
 
562
            return orig_get_parent_map(q)
 
563
        repo.revisions.get_parent_map = get_parent_map
 
564
 
 
565
 
478
566
class TestBranchReference(tests.TestCaseWithTransport):
479
567
    """Tests for the branch reference facility."""
480
568
 
481
569
    def test_create_open_reference(self):
482
570
        bzrdirformat = bzrdir.BzrDirMetaFormat1()
483
 
        t = transport.get_transport(self.get_url('.'))
 
571
        t = self.get_transport()
484
572
        t.mkdir('repo')
485
573
        dir = bzrdirformat.initialize(self.get_url('repo'))
486
574
        dir.create_repository()
580
668
    def setUp(self):
581
669
        super(TestBranchOptions, self).setUp()
582
670
        self.branch = self.make_branch('.')
583
 
        self.config = self.branch.get_config()
 
671
        self.config_stack = self.branch.get_config_stack()
584
672
 
585
673
    def check_append_revisions_only(self, expected_value, value=None):
586
674
        """Set append_revisions_only in config and check its interpretation."""
587
675
        if value is not None:
588
 
            self.config.set_user_option('append_revisions_only', value)
 
676
            self.config_stack.set('append_revisions_only', value)
589
677
        self.assertEqual(expected_value,
590
 
                         self.branch._get_append_revisions_only())
 
678
                         self.branch.get_append_revisions_only())
591
679
 
592
680
    def test_valid_append_revisions_only(self):
593
681
        self.assertEquals(None,
594
 
                          self.config.get_user_option('append_revisions_only'))
 
682
                          self.config_stack.get('append_revisions_only'))
595
683
        self.check_append_revisions_only(None)
596
684
        self.check_append_revisions_only(False, 'False')
597
685
        self.check_append_revisions_only(True, 'True')
609
697
        self.check_append_revisions_only(None, 'not-a-bool')
610
698
        self.assertLength(1, self.warnings)
611
699
        self.assertEqual(
612
 
            'Value "not-a-bool" is not a boolean for "append_revisions_only"',
 
700
            'Value "not-a-bool" is not valid for "append_revisions_only"',
613
701
            self.warnings[0])
614
702
 
615
703
 
637
725
        f = StringIO()
638
726
        r.report(f)
639
727
        self.assertEqual("Now on revision 20.\n", f.getvalue())
 
728
        self.assertEqual("Now on revision 20.\n", f.getvalue())
640
729
 
641
730
    def test_report_unchanged(self):
642
731
        r = _mod_branch.PullResult()
644
733
        r.new_revid = "same-revid"
645
734
        f = StringIO()
646
735
        r.report(f)
647
 
        self.assertEqual("No revisions to pull.\n", f.getvalue())
648
 
 
649
 
 
650
 
class _StubLockable(object):
651
 
    """Helper for TestRunWithWriteLockedTarget."""
652
 
 
653
 
    def __init__(self, calls, unlock_exc=None):
654
 
        self.calls = calls
655
 
        self.unlock_exc = unlock_exc
656
 
 
657
 
    def lock_write(self):
658
 
        self.calls.append('lock_write')
659
 
 
660
 
    def unlock(self):
661
 
        self.calls.append('unlock')
662
 
        if self.unlock_exc is not None:
663
 
            raise self.unlock_exc
664
 
 
665
 
 
666
 
class _ErrorFromCallable(Exception):
667
 
    """Helper for TestRunWithWriteLockedTarget."""
668
 
 
669
 
 
670
 
class _ErrorFromUnlock(Exception):
671
 
    """Helper for TestRunWithWriteLockedTarget."""
672
 
 
673
 
 
674
 
class TestRunWithWriteLockedTarget(tests.TestCase):
675
 
    """Tests for _run_with_write_locked_target."""
676
 
 
677
 
    def setUp(self):
678
 
        tests.TestCase.setUp(self)
679
 
        self._calls = []
680
 
 
681
 
    def func_that_returns_ok(self):
682
 
        self._calls.append('func called')
683
 
        return 'ok'
684
 
 
685
 
    def func_that_raises(self):
686
 
        self._calls.append('func called')
687
 
        raise _ErrorFromCallable()
688
 
 
689
 
    def test_success_unlocks(self):
690
 
        lockable = _StubLockable(self._calls)
691
 
        result = _mod_branch._run_with_write_locked_target(
692
 
            lockable, self.func_that_returns_ok)
693
 
        self.assertEqual('ok', result)
694
 
        self.assertEqual(['lock_write', 'func called', 'unlock'], self._calls)
695
 
 
696
 
    def test_exception_unlocks_and_propagates(self):
697
 
        lockable = _StubLockable(self._calls)
698
 
        self.assertRaises(_ErrorFromCallable,
699
 
                          _mod_branch._run_with_write_locked_target,
700
 
                          lockable, self.func_that_raises)
701
 
        self.assertEqual(['lock_write', 'func called', 'unlock'], self._calls)
702
 
 
703
 
    def test_callable_succeeds_but_error_during_unlock(self):
704
 
        lockable = _StubLockable(self._calls, unlock_exc=_ErrorFromUnlock())
705
 
        self.assertRaises(_ErrorFromUnlock,
706
 
                          _mod_branch._run_with_write_locked_target,
707
 
                          lockable, self.func_that_returns_ok)
708
 
        self.assertEqual(['lock_write', 'func called', 'unlock'], self._calls)
709
 
 
710
 
    def test_error_during_unlock_does_not_mask_original_error(self):
711
 
        lockable = _StubLockable(self._calls, unlock_exc=_ErrorFromUnlock())
712
 
        self.assertRaises(_ErrorFromCallable,
713
 
                          _mod_branch._run_with_write_locked_target,
714
 
                          lockable, self.func_that_raises)
715
 
        self.assertEqual(['lock_write', 'func called', 'unlock'], self._calls)
716
 
 
 
736
        self.assertEqual("No revisions or tags to pull.\n", f.getvalue())
717
737