~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_branch.py

  • Committer: John Arbash Meinel
  • Date: 2007-03-15 22:35:35 UTC
  • mto: This revision was merged to the branch mainline in revision 2363.
  • Revision ID: john@arbash-meinel.com-20070315223535-d3d4964oe1hc8zhg
Add an overzealous test, for Unicode support of _iter_changes.
For both knowns and unknowns.
And include a basic, if suboptimal, fix.
I would rather defer the decoding until we've determined that we are going to return the tuple.
There is still something broken with added files, but I'll get to that.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2005, 2006, 2007 Canonical Ltd
 
2
#
 
3
# This program is free software; you can redistribute it and/or modify
 
4
# it under the terms of the GNU General Public License as published by
 
5
# the Free Software Foundation; either version 2 of the License, or
 
6
# (at your option) any later version.
 
7
#
 
8
# This program is distributed in the hope that it will be useful,
 
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
# GNU General Public License for more details.
 
12
#
 
13
# You should have received a copy of the GNU General Public License
 
14
# along with this program; if not, write to the Free Software
 
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
16
 
 
17
"""Tests for the Branch facility that are not interface  tests.
 
18
 
 
19
For interface tests see tests/branch_implementations/*.py.
 
20
 
 
21
For concrete class tests see this file, and for meta-branch tests
 
22
also see this file.
 
23
"""
 
24
 
 
25
from StringIO import StringIO
 
26
 
 
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
    )
 
42
from bzrlib.bzrdir import (BzrDirMetaFormat1, BzrDirMeta1, 
 
43
                           BzrDir, BzrDirFormat)
 
44
from bzrlib.errors import (NotBranchError,
 
45
                           UnknownFormatError,
 
46
                           UnknownHook,
 
47
                           UnsupportedFormatError,
 
48
                           )
 
49
 
 
50
from bzrlib.tests import TestCase, TestCaseWithTransport
 
51
from bzrlib.transport import get_transport
 
52
 
 
53
class TestDefaultFormat(TestCase):
 
54
 
 
55
    def test_get_set_default_format(self):
 
56
        old_format = BranchFormat.get_default_format()
 
57
        # default is 5
 
58
        self.assertTrue(isinstance(old_format, BzrBranchFormat5))
 
59
        BranchFormat.set_default_format(SampleBranchFormat())
 
60
        try:
 
61
            # the default branch format is used by the meta dir format
 
62
            # which is not the default bzrdir format at this point
 
63
            dir = BzrDirMetaFormat1().initialize('memory:///')
 
64
            result = dir.create_branch()
 
65
            self.assertEqual(result, 'A branch')
 
66
        finally:
 
67
            BranchFormat.set_default_format(old_format)
 
68
        self.assertEqual(old_format, BranchFormat.get_default_format())
 
69
 
 
70
 
 
71
class TestBranchFormat5(TestCaseWithTransport):
 
72
    """Tests specific to branch format 5"""
 
73
 
 
74
    def test_branch_format_5_uses_lockdir(self):
 
75
        url = self.get_url()
 
76
        bzrdir = BzrDirMetaFormat1().initialize(url)
 
77
        bzrdir.create_repository()
 
78
        branch = bzrdir.create_branch()
 
79
        t = self.get_transport()
 
80
        self.log("branch instance is %r" % branch)
 
81
        self.assert_(isinstance(branch, BzrBranch5))
 
82
        self.assertIsDirectory('.', t)
 
83
        self.assertIsDirectory('.bzr/branch', t)
 
84
        self.assertIsDirectory('.bzr/branch/lock', t)
 
85
        branch.lock_write()
 
86
        try:
 
87
            self.assertIsDirectory('.bzr/branch/lock/held', t)
 
88
        finally:
 
89
            branch.unlock()
 
90
 
 
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):
 
109
    """A sample format
 
110
 
 
111
    this format is initializable, unsupported to aid in testing the 
 
112
    open and open_downlevel routines.
 
113
    """
 
114
 
 
115
    def get_format_string(self):
 
116
        """See BzrBranchFormat.get_format_string()."""
 
117
        return "Sample branch format."
 
118
 
 
119
    def initialize(self, a_bzrdir):
 
120
        """Format 4 branches cannot be created."""
 
121
        t = a_bzrdir.get_branch_transport(self)
 
122
        t.put_bytes('format', self.get_format_string())
 
123
        return 'A branch'
 
124
 
 
125
    def is_supported(self):
 
126
        return False
 
127
 
 
128
    def open(self, transport, _found=False):
 
129
        return "opened branch."
 
130
 
 
131
 
 
132
class TestBzrBranchFormat(TestCaseWithTransport):
 
133
    """Tests for the BzrBranchFormat facility."""
 
134
 
 
135
    def test_find_format(self):
 
136
        # is the right format object found for a branch?
 
137
        # create a branch with a few known format objects.
 
138
        # this is not quite the same as 
 
139
        self.build_tree(["foo/", "bar/"])
 
140
        def check_format(format, url):
 
141
            dir = format._matchingbzrdir.initialize(url)
 
142
            dir.create_repository()
 
143
            format.initialize(dir)
 
144
            found_format = BranchFormat.find_format(dir)
 
145
            self.failUnless(isinstance(found_format, format.__class__))
 
146
        check_format(BzrBranchFormat5(), "bar")
 
147
        
 
148
    def test_find_format_not_branch(self):
 
149
        dir = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
 
150
        self.assertRaises(NotBranchError,
 
151
                          BranchFormat.find_format,
 
152
                          dir)
 
153
 
 
154
    def test_find_format_unknown_format(self):
 
155
        dir = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
 
156
        SampleBranchFormat().initialize(dir)
 
157
        self.assertRaises(UnknownFormatError,
 
158
                          BranchFormat.find_format,
 
159
                          dir)
 
160
 
 
161
    def test_register_unregister_format(self):
 
162
        format = SampleBranchFormat()
 
163
        # make a control dir
 
164
        dir = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
 
165
        # make a branch
 
166
        format.initialize(dir)
 
167
        # register a format for it.
 
168
        BranchFormat.register_format(format)
 
169
        # which branch.Open will refuse (not supported)
 
170
        self.assertRaises(UnsupportedFormatError, Branch.open, self.get_url())
 
171
        self.make_branch_and_tree('foo')
 
172
        # but open_downlevel will work
 
173
        self.assertEqual(format.open(dir), bzrdir.BzrDir.open(self.get_url()).open_branch(unsupported=True))
 
174
        # unregister the format
 
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-tags')
 
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-tags')
 
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-tags')
 
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-tags')
 
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-tags')
 
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)
 
290
 
 
291
class TestBranchReference(TestCaseWithTransport):
 
292
    """Tests for the branch reference facility."""
 
293
 
 
294
    def test_create_open_reference(self):
 
295
        bzrdirformat = bzrdir.BzrDirMetaFormat1()
 
296
        t = get_transport(self.get_url('.'))
 
297
        t.mkdir('repo')
 
298
        dir = bzrdirformat.initialize(self.get_url('repo'))
 
299
        dir.create_repository()
 
300
        target_branch = dir.create_branch()
 
301
        t.mkdir('branch')
 
302
        branch_dir = bzrdirformat.initialize(self.get_url('branch'))
 
303
        made_branch = BranchReferenceFormat().initialize(branch_dir, target_branch)
 
304
        self.assertEqual(made_branch.base, target_branch.base)
 
305
        opened_branch = branch_dir.open_branch()
 
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")