~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: 2007-09-20 02:40:52 UTC
  • mfrom: (2835.1.1 ianc-integration)
  • Revision ID: pqm@pqm.ubuntu.com-20070920024052-y2l7r5o00zrpnr73
No longer propagate index differences automatically (Robert Collins)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2006 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
24
24
 
25
25
from StringIO import StringIO
26
26
 
27
 
import bzrlib.branch
28
 
from bzrlib.branch import (BzrBranch5, 
29
 
                           BzrBranchFormat5)
30
 
import bzrlib.bzrdir as bzrdir
 
27
from bzrlib import (
 
28
    branch as _mod_branch,
 
29
    bzrdir,
 
30
    config,
 
31
    errors,
 
32
    trace,
 
33
    urlutils,
 
34
    )
 
35
from bzrlib.branch import (
 
36
    Branch,
 
37
    BranchHooks,
 
38
    BranchFormat,
 
39
    BranchReferenceFormat,
 
40
    BzrBranch5,
 
41
    BzrBranchFormat5,
 
42
    BzrBranchFormat6,
 
43
    PullResult,
 
44
    )
31
45
from bzrlib.bzrdir import (BzrDirMetaFormat1, BzrDirMeta1, 
32
46
                           BzrDir, BzrDirFormat)
33
47
from bzrlib.errors import (NotBranchError,
34
48
                           UnknownFormatError,
 
49
                           UnknownHook,
35
50
                           UnsupportedFormatError,
36
51
                           )
37
52
 
40
55
 
41
56
class TestDefaultFormat(TestCase):
42
57
 
 
58
    def test_default_format(self):
 
59
        # update this if you change the default branch format
 
60
        self.assertIsInstance(BranchFormat.get_default_format(),
 
61
                BzrBranchFormat6)
 
62
 
 
63
    def test_default_format_is_same_as_bzrdir_default(self):
 
64
        # XXX: it might be nice if there was only one place the default was
 
65
        # set, but at the moment that's not true -- mbp 20070814 -- 
 
66
        # https://bugs.launchpad.net/bzr/+bug/132376
 
67
        self.assertEqual(BranchFormat.get_default_format(),
 
68
                BzrDirFormat.get_default_format().get_branch_format())
 
69
 
43
70
    def test_get_set_default_format(self):
44
 
        old_format = bzrlib.branch.BranchFormat.get_default_format()
45
 
        # default is 5
46
 
        self.assertTrue(isinstance(old_format, bzrlib.branch.BzrBranchFormat5))
47
 
        bzrlib.branch.BranchFormat.set_default_format(SampleBranchFormat())
 
71
        # set the format and then set it back again
 
72
        old_format = BranchFormat.get_default_format()
 
73
        BranchFormat.set_default_format(SampleBranchFormat())
48
74
        try:
49
75
            # the default branch format is used by the meta dir format
50
76
            # which is not the default bzrdir format at this point
51
 
            dir = BzrDirMetaFormat1().initialize('memory:/')
 
77
            dir = BzrDirMetaFormat1().initialize('memory:///')
52
78
            result = dir.create_branch()
53
79
            self.assertEqual(result, 'A branch')
54
80
        finally:
55
 
            bzrlib.branch.BranchFormat.set_default_format(old_format)
56
 
        self.assertEqual(old_format, bzrlib.branch.BranchFormat.get_default_format())
 
81
            BranchFormat.set_default_format(old_format)
 
82
        self.assertEqual(old_format, BranchFormat.get_default_format())
57
83
 
58
84
 
59
85
class TestBranchFormat5(TestCaseWithTransport):
76
102
        finally:
77
103
            branch.unlock()
78
104
 
79
 
 
80
 
class TestBranchEscaping(TestCaseWithTransport):
81
 
    """Test a branch can be correctly stored and used on a vfat-like transport
82
 
    
83
 
    Makes sure we have proper escaping of invalid characters, etc.
84
 
 
85
 
    It'd be better to test all operations on the FakeVFATTransportDecorator,
86
 
    but working trees go straight to the os not through the Transport layer.
87
 
    Therefore we build some history first in the regular way and then 
88
 
    check it's safe to access for vfat.
89
 
    """
90
 
 
91
 
    FOO_ID = 'foo<:>ID'
92
 
    REV_ID = 'revid-1'
93
 
 
94
 
    def setUp(self):
95
 
        super(TestBranchEscaping, self).setUp()
96
 
        from bzrlib.repository import RepositoryFormatKnit1
97
 
        bzrdir = BzrDirMetaFormat1().initialize(self.get_url())
98
 
        repo = RepositoryFormatKnit1().initialize(bzrdir)
99
 
        branch = bzrdir.create_branch()
100
 
        wt = bzrdir.create_workingtree()
101
 
        self.build_tree_contents([("foo", "contents of foo")])
102
 
        # add file with id containing wierd characters
103
 
        wt.add(['foo'], [self.FOO_ID])
104
 
        wt.commit('this is my new commit', rev_id=self.REV_ID)
105
 
 
106
 
    def test_branch_on_vfat(self):
107
 
        from bzrlib.transport.fakevfat import FakeVFATTransportDecorator
108
 
        # now access over vfat; should be safe
109
 
        transport = FakeVFATTransportDecorator('vfat+' + self.get_url())
110
 
        bzrdir, junk = BzrDir.open_containing_from_transport(transport)
111
 
        branch = bzrdir.open_branch()
112
 
        revtree = branch.repository.revision_tree(self.REV_ID)
113
 
        contents = revtree.get_file_text(self.FOO_ID)
114
 
        self.assertEqual(contents, 'contents of foo')
115
 
 
116
 
 
117
 
class SampleBranchFormat(bzrlib.branch.BranchFormat):
 
105
    def test_set_push_location(self):
 
106
        from bzrlib.config import (locations_config_filename,
 
107
                                   ensure_config_dir_exists)
 
108
        ensure_config_dir_exists()
 
109
        fn = locations_config_filename()
 
110
        branch = self.make_branch('.', format='knit')
 
111
        branch.set_push_location('foo')
 
112
        local_path = urlutils.local_path_from_url(branch.base[:-1])
 
113
        self.assertFileEqual("[%s]\n"
 
114
                             "push_location = foo\n"
 
115
                             "push_location:policy = norecurse" % local_path,
 
116
                             fn)
 
117
 
 
118
    # TODO RBC 20051029 test getting a push location from a branch in a
 
119
    # recursive section - that is, it appends the branch name.
 
120
 
 
121
 
 
122
class SampleBranchFormat(BranchFormat):
118
123
    """A sample format
119
124
 
120
125
    this format is initializable, unsupported to aid in testing the 
128
133
    def initialize(self, a_bzrdir):
129
134
        """Format 4 branches cannot be created."""
130
135
        t = a_bzrdir.get_branch_transport(self)
131
 
        t.put('format', StringIO(self.get_format_string()))
 
136
        t.put_bytes('format', self.get_format_string())
132
137
        return 'A branch'
133
138
 
134
139
    def is_supported(self):
150
155
            dir = format._matchingbzrdir.initialize(url)
151
156
            dir.create_repository()
152
157
            format.initialize(dir)
153
 
            found_format = bzrlib.branch.BranchFormat.find_format(dir)
 
158
            found_format = BranchFormat.find_format(dir)
154
159
            self.failUnless(isinstance(found_format, format.__class__))
155
 
        check_format(bzrlib.branch.BzrBranchFormat5(), "bar")
 
160
        check_format(BzrBranchFormat5(), "bar")
156
161
        
157
162
    def test_find_format_not_branch(self):
158
163
        dir = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
159
164
        self.assertRaises(NotBranchError,
160
 
                          bzrlib.branch.BranchFormat.find_format,
 
165
                          BranchFormat.find_format,
161
166
                          dir)
162
167
 
163
168
    def test_find_format_unknown_format(self):
164
169
        dir = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
165
170
        SampleBranchFormat().initialize(dir)
166
171
        self.assertRaises(UnknownFormatError,
167
 
                          bzrlib.branch.BranchFormat.find_format,
 
172
                          BranchFormat.find_format,
168
173
                          dir)
169
174
 
170
175
    def test_register_unregister_format(self):
174
179
        # make a branch
175
180
        format.initialize(dir)
176
181
        # register a format for it.
177
 
        bzrlib.branch.BranchFormat.register_format(format)
 
182
        BranchFormat.register_format(format)
178
183
        # which branch.Open will refuse (not supported)
179
 
        self.assertRaises(UnsupportedFormatError, bzrlib.branch.Branch.open, self.get_url())
 
184
        self.assertRaises(UnsupportedFormatError, Branch.open, self.get_url())
 
185
        self.make_branch_and_tree('foo')
180
186
        # but open_downlevel will work
181
187
        self.assertEqual(format.open(dir), bzrdir.BzrDir.open(self.get_url()).open_branch(unsupported=True))
182
188
        # unregister the format
183
 
        bzrlib.branch.BranchFormat.unregister_format(format)
184
 
 
 
189
        BranchFormat.unregister_format(format)
 
190
        self.make_branch_and_tree('bar')
 
191
 
 
192
 
 
193
class TestBranch6(TestCaseWithTransport):
 
194
 
 
195
    def test_creation(self):
 
196
        format = BzrDirMetaFormat1()
 
197
        format.set_branch_format(_mod_branch.BzrBranchFormat6())
 
198
        branch = self.make_branch('a', format=format)
 
199
        self.assertIsInstance(branch, _mod_branch.BzrBranch6)
 
200
        branch = self.make_branch('b', format='dirstate-tags')
 
201
        self.assertIsInstance(branch, _mod_branch.BzrBranch6)
 
202
        branch = _mod_branch.Branch.open('a')
 
203
        self.assertIsInstance(branch, _mod_branch.BzrBranch6)
 
204
 
 
205
    def test_layout(self):
 
206
        branch = self.make_branch('a', format='dirstate-tags')
 
207
        self.failUnlessExists('a/.bzr/branch/last-revision')
 
208
        self.failIfExists('a/.bzr/branch/revision-history')
 
209
 
 
210
    def test_config(self):
 
211
        """Ensure that all configuration data is stored in the branch"""
 
212
        branch = self.make_branch('a', format='dirstate-tags')
 
213
        branch.set_parent('http://bazaar-vcs.org')
 
214
        self.failIfExists('a/.bzr/branch/parent')
 
215
        self.assertEqual('http://bazaar-vcs.org', branch.get_parent())
 
216
        branch.set_push_location('sftp://bazaar-vcs.org')
 
217
        config = branch.get_config()._get_branch_data_config()
 
218
        self.assertEqual('sftp://bazaar-vcs.org',
 
219
                         config.get_user_option('push_location'))
 
220
        branch.set_bound_location('ftp://bazaar-vcs.org')
 
221
        self.failIfExists('a/.bzr/branch/bound')
 
222
        self.assertEqual('ftp://bazaar-vcs.org', branch.get_bound_location())
 
223
 
 
224
    def test_set_revision_history(self):
 
225
        tree = self.make_branch_and_memory_tree('.',
 
226
            format='dirstate-tags')
 
227
        tree.lock_write()
 
228
        try:
 
229
            tree.add('.')
 
230
            tree.commit('foo', rev_id='foo')
 
231
            tree.commit('bar', rev_id='bar')
 
232
            tree.branch.set_revision_history(['foo', 'bar'])
 
233
            tree.branch.set_revision_history(['foo'])
 
234
            self.assertRaises(errors.NotLefthandHistory,
 
235
                              tree.branch.set_revision_history, ['bar'])
 
236
        finally:
 
237
            tree.unlock()
 
238
 
 
239
    def do_checkout_test(self, lightweight=False):
 
240
        tree = self.make_branch_and_tree('source', format='dirstate-with-subtree')
 
241
        subtree = self.make_branch_and_tree('source/subtree',
 
242
            format='dirstate-with-subtree')
 
243
        subsubtree = self.make_branch_and_tree('source/subtree/subsubtree',
 
244
            format='dirstate-with-subtree')
 
245
        self.build_tree(['source/subtree/file',
 
246
                         'source/subtree/subsubtree/file'])
 
247
        subsubtree.add('file')
 
248
        subtree.add('file')
 
249
        subtree.add_reference(subsubtree)
 
250
        tree.add_reference(subtree)
 
251
        tree.commit('a revision')
 
252
        subtree.commit('a subtree file')
 
253
        subsubtree.commit('a subsubtree file')
 
254
        tree.branch.create_checkout('target', lightweight=lightweight)
 
255
        self.failUnlessExists('target')
 
256
        self.failUnlessExists('target/subtree')
 
257
        self.failUnlessExists('target/subtree/file')
 
258
        self.failUnlessExists('target/subtree/subsubtree/file')
 
259
        subbranch = _mod_branch.Branch.open('target/subtree/subsubtree')
 
260
        if lightweight:
 
261
            self.assertEndsWith(subbranch.base, 'source/subtree/subsubtree/')
 
262
        else:
 
263
            self.assertEndsWith(subbranch.base, 'target/subtree/subsubtree/')
 
264
 
 
265
    def test_checkout_with_references(self):
 
266
        self.do_checkout_test()
 
267
 
 
268
    def test_light_checkout_with_references(self):
 
269
        self.do_checkout_test(lightweight=True)
 
270
 
 
271
    def test_set_push(self):
 
272
        branch = self.make_branch('source', format='dirstate-tags')
 
273
        branch.get_config().set_user_option('push_location', 'old',
 
274
            store=config.STORE_LOCATION)
 
275
        warnings = []
 
276
        def warning(*args):
 
277
            warnings.append(args[0] % args[1:])
 
278
        _warning = trace.warning
 
279
        trace.warning = warning
 
280
        try:
 
281
            branch.set_push_location('new')
 
282
        finally:
 
283
            trace.warning = _warning
 
284
        self.assertEqual(warnings[0], 'Value "new" is masked by "old" from '
 
285
                         'locations.conf')
185
286
 
186
287
class TestBranchReference(TestCaseWithTransport):
187
288
    """Tests for the branch reference facility."""
195
296
        target_branch = dir.create_branch()
196
297
        t.mkdir('branch')
197
298
        branch_dir = bzrdirformat.initialize(self.get_url('branch'))
198
 
        made_branch = bzrlib.branch.BranchReferenceFormat().initialize(branch_dir, target_branch)
 
299
        made_branch = BranchReferenceFormat().initialize(branch_dir, target_branch)
199
300
        self.assertEqual(made_branch.base, target_branch.base)
200
301
        opened_branch = branch_dir.open_branch()
201
302
        self.assertEqual(opened_branch.base, target_branch.base)
 
303
 
 
304
    def test_get_reference(self):
 
305
        """For a BranchReference, get_reference should reutrn the location."""
 
306
        branch = self.make_branch('target')
 
307
        checkout = branch.create_checkout('checkout', lightweight=True)
 
308
        reference_url = branch.bzrdir.root_transport.abspath('') + '/'
 
309
        # if the api for create_checkout changes to return different checkout types
 
310
        # then this file read will fail.
 
311
        self.assertFileEqual(reference_url, 'checkout/.bzr/branch/location')
 
312
        self.assertEqual(reference_url,
 
313
            _mod_branch.BranchReferenceFormat().get_reference(checkout.bzrdir))
 
314
 
 
315
 
 
316
class TestHooks(TestCase):
 
317
 
 
318
    def test_constructor(self):
 
319
        """Check that creating a BranchHooks instance has the right defaults."""
 
320
        hooks = BranchHooks()
 
321
        self.assertTrue("set_rh" in hooks, "set_rh not in %s" % hooks)
 
322
        self.assertTrue("post_push" in hooks, "post_push not in %s" % hooks)
 
323
        self.assertTrue("post_commit" in hooks, "post_commit not in %s" % hooks)
 
324
        self.assertTrue("pre_commit" in hooks, "pre_commit not in %s" % hooks)
 
325
        self.assertTrue("post_pull" in hooks, "post_pull not in %s" % hooks)
 
326
        self.assertTrue("post_uncommit" in hooks, "post_uncommit not in %s" % hooks)
 
327
 
 
328
    def test_installed_hooks_are_BranchHooks(self):
 
329
        """The installed hooks object should be a BranchHooks."""
 
330
        # the installed hooks are saved in self._preserved_hooks.
 
331
        self.assertIsInstance(self._preserved_hooks[_mod_branch.Branch], BranchHooks)
 
332
 
 
333
 
 
334
class TestPullResult(TestCase):
 
335
 
 
336
    def test_pull_result_to_int(self):
 
337
        # to support old code, the pull result can be used as an int
 
338
        r = PullResult()
 
339
        r.old_revno = 10
 
340
        r.new_revno = 20
 
341
        # this usage of results is not recommended for new code (because it
 
342
        # doesn't describe very well what happened), but for api stability
 
343
        # it's still supported
 
344
        a = "%d revisions pulled" % r
 
345
        self.assertEqual(a, "10 revisions pulled")