/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_branch.py

  • Committer: Robert Collins
  • Date: 2007-09-19 05:14:14 UTC
  • mto: (2835.1.1 ianc-integration)
  • mto: This revision was merged to the branch mainline in revision 2836.
  • Revision ID: robertc@robertcollins.net-20070919051414-2tgjqteg7k3ps4h0
* ``pull``, ``merge`` and ``push`` will no longer silently correct some
  repository index errors that occured as a result of the Weave disk format.
  Instead the ``reconcile`` command needs to be run to correct those
  problems if they exist (and it has been able to fix most such problems
  since bzr 0.8). Some new problems have been identified during this release
  and you should run ``bzr check`` once on every repository to see if you
  need to reconcile. If you cannot ``pull`` or ``merge`` from a remote
  repository due to mismatched parent errors - a symptom of index errors -
  you should simply take a full copy of that remote repository to a clean
  directory outside any local repositories, then run reconcile on it, and
  finally pull from it locally. (And naturally email the repositories owner
  to ask them to upgrade and run reconcile).
  (Robert Collins)

* ``VersionedFile.fix_parents`` has been removed as a harmful API.
  ``VersionedFile.join`` will no longer accept different parents on either
  side of a join - it will either ignore them, or error, depending on the
  implementation. See notes when upgrading for more information.
  (Robert Collins)

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
    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
    )
 
45
from bzrlib.bzrdir import (BzrDirMetaFormat1, BzrDirMeta1, 
 
46
                           BzrDir, BzrDirFormat)
 
47
from bzrlib.errors import (NotBranchError,
 
48
                           UnknownFormatError,
 
49
                           UnknownHook,
 
50
                           UnsupportedFormatError,
 
51
                           )
 
52
 
 
53
from bzrlib.tests import TestCase, TestCaseWithTransport
 
54
from bzrlib.transport import get_transport
 
55
 
 
56
class TestDefaultFormat(TestCase):
 
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
 
 
70
    def test_get_set_default_format(self):
 
71
        # set the format and then set it back again
 
72
        old_format = BranchFormat.get_default_format()
 
73
        BranchFormat.set_default_format(SampleBranchFormat())
 
74
        try:
 
75
            # the default branch format is used by the meta dir format
 
76
            # which is not the default bzrdir format at this point
 
77
            dir = BzrDirMetaFormat1().initialize('memory:///')
 
78
            result = dir.create_branch()
 
79
            self.assertEqual(result, 'A branch')
 
80
        finally:
 
81
            BranchFormat.set_default_format(old_format)
 
82
        self.assertEqual(old_format, BranchFormat.get_default_format())
 
83
 
 
84
 
 
85
class TestBranchFormat5(TestCaseWithTransport):
 
86
    """Tests specific to branch format 5"""
 
87
 
 
88
    def test_branch_format_5_uses_lockdir(self):
 
89
        url = self.get_url()
 
90
        bzrdir = BzrDirMetaFormat1().initialize(url)
 
91
        bzrdir.create_repository()
 
92
        branch = bzrdir.create_branch()
 
93
        t = self.get_transport()
 
94
        self.log("branch instance is %r" % branch)
 
95
        self.assert_(isinstance(branch, BzrBranch5))
 
96
        self.assertIsDirectory('.', t)
 
97
        self.assertIsDirectory('.bzr/branch', t)
 
98
        self.assertIsDirectory('.bzr/branch/lock', t)
 
99
        branch.lock_write()
 
100
        try:
 
101
            self.assertIsDirectory('.bzr/branch/lock/held', t)
 
102
        finally:
 
103
            branch.unlock()
 
104
 
 
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):
 
123
    """A sample format
 
124
 
 
125
    this format is initializable, unsupported to aid in testing the 
 
126
    open and open_downlevel routines.
 
127
    """
 
128
 
 
129
    def get_format_string(self):
 
130
        """See BzrBranchFormat.get_format_string()."""
 
131
        return "Sample branch format."
 
132
 
 
133
    def initialize(self, a_bzrdir):
 
134
        """Format 4 branches cannot be created."""
 
135
        t = a_bzrdir.get_branch_transport(self)
 
136
        t.put_bytes('format', self.get_format_string())
 
137
        return 'A branch'
 
138
 
 
139
    def is_supported(self):
 
140
        return False
 
141
 
 
142
    def open(self, transport, _found=False):
 
143
        return "opened branch."
 
144
 
 
145
 
 
146
class TestBzrBranchFormat(TestCaseWithTransport):
 
147
    """Tests for the BzrBranchFormat facility."""
 
148
 
 
149
    def test_find_format(self):
 
150
        # is the right format object found for a branch?
 
151
        # create a branch with a few known format objects.
 
152
        # this is not quite the same as 
 
153
        self.build_tree(["foo/", "bar/"])
 
154
        def check_format(format, url):
 
155
            dir = format._matchingbzrdir.initialize(url)
 
156
            dir.create_repository()
 
157
            format.initialize(dir)
 
158
            found_format = BranchFormat.find_format(dir)
 
159
            self.failUnless(isinstance(found_format, format.__class__))
 
160
        check_format(BzrBranchFormat5(), "bar")
 
161
        
 
162
    def test_find_format_not_branch(self):
 
163
        dir = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
 
164
        self.assertRaises(NotBranchError,
 
165
                          BranchFormat.find_format,
 
166
                          dir)
 
167
 
 
168
    def test_find_format_unknown_format(self):
 
169
        dir = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
 
170
        SampleBranchFormat().initialize(dir)
 
171
        self.assertRaises(UnknownFormatError,
 
172
                          BranchFormat.find_format,
 
173
                          dir)
 
174
 
 
175
    def test_register_unregister_format(self):
 
176
        format = SampleBranchFormat()
 
177
        # make a control dir
 
178
        dir = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
 
179
        # make a branch
 
180
        format.initialize(dir)
 
181
        # register a format for it.
 
182
        BranchFormat.register_format(format)
 
183
        # which branch.Open will refuse (not supported)
 
184
        self.assertRaises(UnsupportedFormatError, Branch.open, self.get_url())
 
185
        self.make_branch_and_tree('foo')
 
186
        # but open_downlevel will work
 
187
        self.assertEqual(format.open(dir), bzrdir.BzrDir.open(self.get_url()).open_branch(unsupported=True))
 
188
        # unregister the format
 
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')
 
286
 
 
287
class TestBranchReference(TestCaseWithTransport):
 
288
    """Tests for the branch reference facility."""
 
289
 
 
290
    def test_create_open_reference(self):
 
291
        bzrdirformat = bzrdir.BzrDirMetaFormat1()
 
292
        t = get_transport(self.get_url('.'))
 
293
        t.mkdir('repo')
 
294
        dir = bzrdirformat.initialize(self.get_url('repo'))
 
295
        dir.create_repository()
 
296
        target_branch = dir.create_branch()
 
297
        t.mkdir('branch')
 
298
        branch_dir = bzrdirformat.initialize(self.get_url('branch'))
 
299
        made_branch = BranchReferenceFormat().initialize(branch_dir, target_branch)
 
300
        self.assertEqual(made_branch.base, target_branch.base)
 
301
        opened_branch = branch_dir.open_branch()
 
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")