~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_branch.py

  • Committer: Aaron Bentley
  • Date: 2007-03-07 23:15:10 UTC
  • mto: (1551.19.24 Aaron's mergeable stuff)
  • mto: This revision was merged to the branch mainline in revision 2325.
  • Revision ID: abentley@panoramicfeedback.com-20070307231510-jae63zsli83db3eb
Make ChangeReporter private

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