~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_branch.py

  • Committer: Alexander Belchenko
  • Date: 2006-07-31 16:12:57 UTC
  • mto: (1711.2.111 jam-integration)
  • mto: This revision was merged to the branch mainline in revision 1906.
  • Revision ID: bialix@ukr.net-20060731161257-91a231523255332c
new official bzr.ico

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2006, 2007 Canonical Ltd
 
1
# Copyright (C) 2005, 2006 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
 
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
 
    PullResult,
43
 
    )
 
27
import bzrlib.branch
 
28
from bzrlib.branch import (BzrBranch5, 
 
29
                           BzrBranchFormat5)
 
30
import bzrlib.bzrdir as bzrdir
44
31
from bzrlib.bzrdir import (BzrDirMetaFormat1, BzrDirMeta1, 
45
32
                           BzrDir, BzrDirFormat)
46
33
from bzrlib.errors import (NotBranchError,
47
34
                           UnknownFormatError,
48
 
                           UnknownHook,
49
35
                           UnsupportedFormatError,
50
36
                           )
51
37
 
55
41
class TestDefaultFormat(TestCase):
56
42
 
57
43
    def test_get_set_default_format(self):
58
 
        old_format = BranchFormat.get_default_format()
 
44
        old_format = bzrlib.branch.BranchFormat.get_default_format()
59
45
        # default is 5
60
 
        self.assertTrue(isinstance(old_format, BzrBranchFormat5))
61
 
        BranchFormat.set_default_format(SampleBranchFormat())
 
46
        self.assertTrue(isinstance(old_format, bzrlib.branch.BzrBranchFormat5))
 
47
        bzrlib.branch.BranchFormat.set_default_format(SampleBranchFormat())
62
48
        try:
63
49
            # the default branch format is used by the meta dir format
64
50
            # which is not the default bzrdir format at this point
66
52
            result = dir.create_branch()
67
53
            self.assertEqual(result, 'A branch')
68
54
        finally:
69
 
            BranchFormat.set_default_format(old_format)
70
 
        self.assertEqual(old_format, BranchFormat.get_default_format())
 
55
            bzrlib.branch.BranchFormat.set_default_format(old_format)
 
56
        self.assertEqual(old_format, bzrlib.branch.BranchFormat.get_default_format())
71
57
 
72
58
 
73
59
class TestBranchFormat5(TestCaseWithTransport):
90
76
        finally:
91
77
            branch.unlock()
92
78
 
93
 
    def test_set_push_location(self):
94
 
        from bzrlib.config import (locations_config_filename,
95
 
                                   ensure_config_dir_exists)
96
 
        ensure_config_dir_exists()
97
 
        fn = locations_config_filename()
98
 
        branch = self.make_branch('.', format='knit')
99
 
        branch.set_push_location('foo')
100
 
        local_path = urlutils.local_path_from_url(branch.base[:-1])
101
 
        self.assertFileEqual("[%s]\n"
102
 
                             "push_location = foo\n"
103
 
                             "push_location:policy = norecurse" % local_path,
104
 
                             fn)
105
 
 
106
 
    # TODO RBC 20051029 test getting a push location from a branch in a
107
 
    # recursive section - that is, it appends the branch name.
108
 
 
109
 
 
110
 
class SampleBranchFormat(BranchFormat):
 
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):
111
118
    """A sample format
112
119
 
113
120
    this format is initializable, unsupported to aid in testing the 
121
128
    def initialize(self, a_bzrdir):
122
129
        """Format 4 branches cannot be created."""
123
130
        t = a_bzrdir.get_branch_transport(self)
124
 
        t.put_bytes('format', self.get_format_string())
 
131
        t.put('format', StringIO(self.get_format_string()))
125
132
        return 'A branch'
126
133
 
127
134
    def is_supported(self):
143
150
            dir = format._matchingbzrdir.initialize(url)
144
151
            dir.create_repository()
145
152
            format.initialize(dir)
146
 
            found_format = BranchFormat.find_format(dir)
 
153
            found_format = bzrlib.branch.BranchFormat.find_format(dir)
147
154
            self.failUnless(isinstance(found_format, format.__class__))
148
 
        check_format(BzrBranchFormat5(), "bar")
 
155
        check_format(bzrlib.branch.BzrBranchFormat5(), "bar")
149
156
        
150
157
    def test_find_format_not_branch(self):
151
158
        dir = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
152
159
        self.assertRaises(NotBranchError,
153
 
                          BranchFormat.find_format,
 
160
                          bzrlib.branch.BranchFormat.find_format,
154
161
                          dir)
155
162
 
156
163
    def test_find_format_unknown_format(self):
157
164
        dir = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
158
165
        SampleBranchFormat().initialize(dir)
159
166
        self.assertRaises(UnknownFormatError,
160
 
                          BranchFormat.find_format,
 
167
                          bzrlib.branch.BranchFormat.find_format,
161
168
                          dir)
162
169
 
163
170
    def test_register_unregister_format(self):
167
174
        # make a branch
168
175
        format.initialize(dir)
169
176
        # register a format for it.
170
 
        BranchFormat.register_format(format)
 
177
        bzrlib.branch.BranchFormat.register_format(format)
171
178
        # which branch.Open will refuse (not supported)
172
 
        self.assertRaises(UnsupportedFormatError, Branch.open, self.get_url())
173
 
        self.make_branch_and_tree('foo')
 
179
        self.assertRaises(UnsupportedFormatError, bzrlib.branch.Branch.open, self.get_url())
174
180
        # but open_downlevel will work
175
181
        self.assertEqual(format.open(dir), bzrdir.BzrDir.open(self.get_url()).open_branch(unsupported=True))
176
182
        # unregister the format
177
 
        BranchFormat.unregister_format(format)
178
 
        self.make_branch_and_tree('bar')
179
 
 
180
 
 
181
 
class TestBranch6(TestCaseWithTransport):
182
 
 
183
 
    def test_creation(self):
184
 
        format = BzrDirMetaFormat1()
185
 
        format.set_branch_format(_mod_branch.BzrBranchFormat6())
186
 
        branch = self.make_branch('a', format=format)
187
 
        self.assertIsInstance(branch, _mod_branch.BzrBranch6)
188
 
        branch = self.make_branch('b', format='dirstate-tags')
189
 
        self.assertIsInstance(branch, _mod_branch.BzrBranch6)
190
 
        branch = _mod_branch.Branch.open('a')
191
 
        self.assertIsInstance(branch, _mod_branch.BzrBranch6)
192
 
 
193
 
    def test_layout(self):
194
 
        branch = self.make_branch('a', format='dirstate-tags')
195
 
        self.failUnlessExists('a/.bzr/branch/last-revision')
196
 
        self.failIfExists('a/.bzr/branch/revision-history')
197
 
 
198
 
    def test_config(self):
199
 
        """Ensure that all configuration data is stored in the branch"""
200
 
        branch = self.make_branch('a', format='dirstate-tags')
201
 
        branch.set_parent('http://bazaar-vcs.org')
202
 
        self.failIfExists('a/.bzr/branch/parent')
203
 
        self.assertEqual('http://bazaar-vcs.org', branch.get_parent())
204
 
        branch.set_push_location('sftp://bazaar-vcs.org')
205
 
        config = branch.get_config()._get_branch_data_config()
206
 
        self.assertEqual('sftp://bazaar-vcs.org',
207
 
                         config.get_user_option('push_location'))
208
 
        branch.set_bound_location('ftp://bazaar-vcs.org')
209
 
        self.failIfExists('a/.bzr/branch/bound')
210
 
        self.assertEqual('ftp://bazaar-vcs.org', branch.get_bound_location())
211
 
 
212
 
    def test_set_revision_history(self):
213
 
        tree = self.make_branch_and_memory_tree('.',
214
 
            format='dirstate-tags')
215
 
        tree.lock_write()
216
 
        try:
217
 
            tree.add('.')
218
 
            tree.commit('foo', rev_id='foo')
219
 
            tree.commit('bar', rev_id='bar')
220
 
            tree.branch.set_revision_history(['foo', 'bar'])
221
 
            tree.branch.set_revision_history(['foo'])
222
 
            self.assertRaises(errors.NotLefthandHistory,
223
 
                              tree.branch.set_revision_history, ['bar'])
224
 
        finally:
225
 
            tree.unlock()
226
 
 
227
 
    def test_append_revision(self):
228
 
        tree = self.make_branch_and_tree('branch1',
229
 
            format='dirstate-tags')
230
 
        tree.lock_write()
231
 
        try:
232
 
            tree.commit('foo', rev_id='foo')
233
 
            tree.commit('bar', rev_id='bar')
234
 
            tree.commit('baz', rev_id='baz')
235
 
            tree.set_last_revision('bar')
236
 
            tree.branch.set_last_revision_info(2, 'bar')
237
 
            tree.commit('qux', rev_id='qux')
238
 
            tree.add_parent_tree_id('baz')
239
 
            tree.commit('qux', rev_id='quxx')
240
 
            tree.branch.set_last_revision_info(0, 'null:')
241
 
            self.assertRaises(errors.NotLeftParentDescendant,
242
 
                              tree.branch.append_revision, 'bar')
243
 
            tree.branch.append_revision('foo')
244
 
            self.assertRaises(errors.NotLeftParentDescendant,
245
 
                              tree.branch.append_revision, 'baz')
246
 
            tree.branch.append_revision('bar')
247
 
            tree.branch.append_revision('baz')
248
 
            self.assertRaises(errors.NotLeftParentDescendant,
249
 
                              tree.branch.append_revision, 'quxx')
250
 
        finally:
251
 
            tree.unlock()
252
 
 
253
 
    def do_checkout_test(self, lightweight=False):
254
 
        tree = self.make_branch_and_tree('source', format='dirstate-with-subtree')
255
 
        subtree = self.make_branch_and_tree('source/subtree',
256
 
            format='dirstate-with-subtree')
257
 
        subsubtree = self.make_branch_and_tree('source/subtree/subsubtree',
258
 
            format='dirstate-with-subtree')
259
 
        self.build_tree(['source/subtree/file',
260
 
                         'source/subtree/subsubtree/file'])
261
 
        subsubtree.add('file')
262
 
        subtree.add('file')
263
 
        subtree.add_reference(subsubtree)
264
 
        tree.add_reference(subtree)
265
 
        tree.commit('a revision')
266
 
        subtree.commit('a subtree file')
267
 
        subsubtree.commit('a subsubtree file')
268
 
        tree.branch.create_checkout('target', lightweight=lightweight)
269
 
        self.failUnlessExists('target')
270
 
        self.failUnlessExists('target/subtree')
271
 
        self.failUnlessExists('target/subtree/file')
272
 
        self.failUnlessExists('target/subtree/subsubtree/file')
273
 
        subbranch = _mod_branch.Branch.open('target/subtree/subsubtree')
274
 
        if lightweight:
275
 
            self.assertEndsWith(subbranch.base, 'source/subtree/subsubtree/')
276
 
        else:
277
 
            self.assertEndsWith(subbranch.base, 'target/subtree/subsubtree/')
278
 
 
279
 
 
280
 
    def test_checkout_with_references(self):
281
 
        self.do_checkout_test()
282
 
 
283
 
    def test_light_checkout_with_references(self):
284
 
        self.do_checkout_test(lightweight=True)
285
 
 
286
 
    def test_set_push(self):
287
 
        branch = self.make_branch('source', format='dirstate-tags')
288
 
        branch.get_config().set_user_option('push_location', 'old',
289
 
            store=config.STORE_LOCATION)
290
 
        warnings = []
291
 
        def warning(*args):
292
 
            warnings.append(args[0] % args[1:])
293
 
        _warning = trace.warning
294
 
        trace.warning = warning
295
 
        try:
296
 
            branch.set_push_location('new')
297
 
        finally:
298
 
            trace.warning = _warning
299
 
        self.assertEqual(warnings[0], 'Value "new" is masked by "old" from '
300
 
                         'locations.conf')
 
183
        bzrlib.branch.BranchFormat.unregister_format(format)
 
184
 
301
185
 
302
186
class TestBranchReference(TestCaseWithTransport):
303
187
    """Tests for the branch reference facility."""
311
195
        target_branch = dir.create_branch()
312
196
        t.mkdir('branch')
313
197
        branch_dir = bzrdirformat.initialize(self.get_url('branch'))
314
 
        made_branch = BranchReferenceFormat().initialize(branch_dir, target_branch)
 
198
        made_branch = bzrlib.branch.BranchReferenceFormat().initialize(branch_dir, target_branch)
315
199
        self.assertEqual(made_branch.base, target_branch.base)
316
200
        opened_branch = branch_dir.open_branch()
317
201
        self.assertEqual(opened_branch.base, target_branch.base)
318
 
 
319
 
    def test_get_reference(self):
320
 
        """For a BranchReference, get_reference should reutrn the location."""
321
 
        branch = self.make_branch('target')
322
 
        checkout = branch.create_checkout('checkout', lightweight=True)
323
 
        reference_url = branch.bzrdir.root_transport.abspath('') + '/'
324
 
        # if the api for create_checkout changes to return different checkout types
325
 
        # then this file read will fail.
326
 
        self.assertFileEqual(reference_url, 'checkout/.bzr/branch/location')
327
 
        self.assertEqual(reference_url,
328
 
            _mod_branch.BranchReferenceFormat().get_reference(checkout.bzrdir))
329
 
 
330
 
 
331
 
class TestHooks(TestCase):
332
 
 
333
 
    def test_constructor(self):
334
 
        """Check that creating a BranchHooks instance has the right defaults."""
335
 
        hooks = BranchHooks()
336
 
        self.assertTrue("set_rh" in hooks, "set_rh not in %s" % hooks)
337
 
        self.assertTrue("post_push" in hooks, "post_push not in %s" % hooks)
338
 
        self.assertTrue("post_commit" in hooks, "post_commit not in %s" % hooks)
339
 
        self.assertTrue("post_pull" in hooks, "post_pull not in %s" % hooks)
340
 
        self.assertTrue("post_uncommit" in hooks, "post_uncommit not in %s" % hooks)
341
 
 
342
 
    def test_installed_hooks_are_BranchHooks(self):
343
 
        """The installed hooks object should be a BranchHooks."""
344
 
        # the installed hooks are saved in self._preserved_hooks.
345
 
        self.assertIsInstance(self._preserved_hooks[_mod_branch.Branch], BranchHooks)
346
 
 
347
 
 
348
 
class TestPullResult(TestCase):
349
 
 
350
 
    def test_pull_result_to_int(self):
351
 
        # to support old code, the pull result can be used as an int
352
 
        r = PullResult()
353
 
        r.old_revno = 10
354
 
        r.new_revno = 20
355
 
        # this usage of results is not recommended for new code (because it
356
 
        # doesn't describe very well what happened), but for api stability
357
 
        # it's still supported
358
 
        a = "%d revisions pulled" % r
359
 
        self.assertEqual(a, "10 revisions pulled")