~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: 2008-08-18 22:34:21 UTC
  • mto: (3606.5.6 1.6)
  • mto: This revision was merged to the branch mainline in revision 3641.
  • Revision ID: john@arbash-meinel.com-20080818223421-todjny24vj4faj4t
Add tests for the fetching behavior.

The proper parameter passed is 'unordered' add an assert for it, and
fix callers that were passing 'unsorted' instead.
Add tests that we make the right get_record_stream call based
on the value of _fetch_uses_deltas.
Fix the fetch request for signatures.

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
 
38
53
from bzrlib.tests import TestCase, TestCaseWithTransport
39
54
from bzrlib.transport import get_transport
40
55
 
 
56
 
41
57
class TestDefaultFormat(TestCase):
42
58
 
 
59
    def test_default_format(self):
 
60
        # update this if you change the default branch format
 
61
        self.assertIsInstance(BranchFormat.get_default_format(),
 
62
                BzrBranchFormat6)
 
63
 
 
64
    def test_default_format_is_same_as_bzrdir_default(self):
 
65
        # XXX: it might be nice if there was only one place the default was
 
66
        # set, but at the moment that's not true -- mbp 20070814 -- 
 
67
        # https://bugs.launchpad.net/bzr/+bug/132376
 
68
        self.assertEqual(BranchFormat.get_default_format(),
 
69
                BzrDirFormat.get_default_format().get_branch_format())
 
70
 
43
71
    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())
 
72
        # set the format and then set it back again
 
73
        old_format = BranchFormat.get_default_format()
 
74
        BranchFormat.set_default_format(SampleBranchFormat())
48
75
        try:
49
76
            # the default branch format is used by the meta dir format
50
77
            # which is not the default bzrdir format at this point
52
79
            result = dir.create_branch()
53
80
            self.assertEqual(result, 'A branch')
54
81
        finally:
55
 
            bzrlib.branch.BranchFormat.set_default_format(old_format)
56
 
        self.assertEqual(old_format, bzrlib.branch.BranchFormat.get_default_format())
 
82
            BranchFormat.set_default_format(old_format)
 
83
        self.assertEqual(old_format, BranchFormat.get_default_format())
57
84
 
58
85
 
59
86
class TestBranchFormat5(TestCaseWithTransport):
76
103
        finally:
77
104
            branch.unlock()
78
105
 
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):
 
106
    def test_set_push_location(self):
 
107
        from bzrlib.config import (locations_config_filename,
 
108
                                   ensure_config_dir_exists)
 
109
        ensure_config_dir_exists()
 
110
        fn = locations_config_filename()
 
111
        # write correct newlines to locations.conf
 
112
        # by default ConfigObj uses native line-endings for new files
 
113
        # but uses already existing line-endings if file is not empty
 
114
        f = open(fn, 'wb')
 
115
        try:
 
116
            f.write('# comment\n')
 
117
        finally:
 
118
            f.close()
 
119
 
 
120
        branch = self.make_branch('.', format='knit')
 
121
        branch.set_push_location('foo')
 
122
        local_path = urlutils.local_path_from_url(branch.base[:-1])
 
123
        self.assertFileEqual("# comment\n"
 
124
                             "[%s]\n"
 
125
                             "push_location = foo\n"
 
126
                             "push_location:policy = norecurse\n" % local_path,
 
127
                             fn)
 
128
 
 
129
    # TODO RBC 20051029 test getting a push location from a branch in a
 
130
    # recursive section - that is, it appends the branch name.
 
131
 
 
132
 
 
133
class SampleBranchFormat(BranchFormat):
118
134
    """A sample format
119
135
 
120
136
    this format is initializable, unsupported to aid in testing the 
128
144
    def initialize(self, a_bzrdir):
129
145
        """Format 4 branches cannot be created."""
130
146
        t = a_bzrdir.get_branch_transport(self)
131
 
        t.put('format', StringIO(self.get_format_string()))
 
147
        t.put_bytes('format', self.get_format_string())
132
148
        return 'A branch'
133
149
 
134
150
    def is_supported(self):
150
166
            dir = format._matchingbzrdir.initialize(url)
151
167
            dir.create_repository()
152
168
            format.initialize(dir)
153
 
            found_format = bzrlib.branch.BranchFormat.find_format(dir)
 
169
            found_format = BranchFormat.find_format(dir)
154
170
            self.failUnless(isinstance(found_format, format.__class__))
155
 
        check_format(bzrlib.branch.BzrBranchFormat5(), "bar")
 
171
        check_format(BzrBranchFormat5(), "bar")
156
172
        
157
173
    def test_find_format_not_branch(self):
158
174
        dir = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
159
175
        self.assertRaises(NotBranchError,
160
 
                          bzrlib.branch.BranchFormat.find_format,
 
176
                          BranchFormat.find_format,
161
177
                          dir)
162
178
 
163
179
    def test_find_format_unknown_format(self):
164
180
        dir = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
165
181
        SampleBranchFormat().initialize(dir)
166
182
        self.assertRaises(UnknownFormatError,
167
 
                          bzrlib.branch.BranchFormat.find_format,
 
183
                          BranchFormat.find_format,
168
184
                          dir)
169
185
 
170
186
    def test_register_unregister_format(self):
174
190
        # make a branch
175
191
        format.initialize(dir)
176
192
        # register a format for it.
177
 
        bzrlib.branch.BranchFormat.register_format(format)
 
193
        BranchFormat.register_format(format)
178
194
        # which branch.Open will refuse (not supported)
179
 
        self.assertRaises(UnsupportedFormatError, bzrlib.branch.Branch.open, self.get_url())
 
195
        self.assertRaises(UnsupportedFormatError, Branch.open, self.get_url())
 
196
        self.make_branch_and_tree('foo')
180
197
        # but open_downlevel will work
181
198
        self.assertEqual(format.open(dir), bzrdir.BzrDir.open(self.get_url()).open_branch(unsupported=True))
182
199
        # unregister the format
183
 
        bzrlib.branch.BranchFormat.unregister_format(format)
 
200
        BranchFormat.unregister_format(format)
 
201
        self.make_branch_and_tree('bar')
 
202
 
 
203
 
 
204
class TestBranch67(object):
 
205
    """Common tests for both branch 6 and 7 which are mostly the same."""
 
206
 
 
207
    def get_format_name(self):
 
208
        raise NotImplementedError(self.get_format_name)
 
209
 
 
210
    def get_format_name_subtree(self):
 
211
        raise NotImplementedError(self.get_format_name)
 
212
 
 
213
    def get_class(self):
 
214
        raise NotImplementedError(self.get_class)
 
215
 
 
216
    def test_creation(self):
 
217
        format = BzrDirMetaFormat1()
 
218
        format.set_branch_format(_mod_branch.BzrBranchFormat6())
 
219
        branch = self.make_branch('a', format=format)
 
220
        self.assertIsInstance(branch, self.get_class())
 
221
        branch = self.make_branch('b', format=self.get_format_name())
 
222
        self.assertIsInstance(branch, self.get_class())
 
223
        branch = _mod_branch.Branch.open('a')
 
224
        self.assertIsInstance(branch, self.get_class())
 
225
 
 
226
    def test_layout(self):
 
227
        branch = self.make_branch('a', format=self.get_format_name())
 
228
        self.failUnlessExists('a/.bzr/branch/last-revision')
 
229
        self.failIfExists('a/.bzr/branch/revision-history')
 
230
 
 
231
    def test_config(self):
 
232
        """Ensure that all configuration data is stored in the branch"""
 
233
        branch = self.make_branch('a', format=self.get_format_name())
 
234
        branch.set_parent('http://bazaar-vcs.org')
 
235
        self.failIfExists('a/.bzr/branch/parent')
 
236
        self.assertEqual('http://bazaar-vcs.org', branch.get_parent())
 
237
        branch.set_push_location('sftp://bazaar-vcs.org')
 
238
        config = branch.get_config()._get_branch_data_config()
 
239
        self.assertEqual('sftp://bazaar-vcs.org',
 
240
                         config.get_user_option('push_location'))
 
241
        branch.set_bound_location('ftp://bazaar-vcs.org')
 
242
        self.failIfExists('a/.bzr/branch/bound')
 
243
        self.assertEqual('ftp://bazaar-vcs.org', branch.get_bound_location())
 
244
 
 
245
    def test_set_revision_history(self):
 
246
        builder = self.make_branch_builder('.', format=self.get_format_name())
 
247
        builder.build_snapshot('foo', None,
 
248
            [('add', ('', None, 'directory', None))],
 
249
            message='foo')
 
250
        builder.build_snapshot('bar', None, [], message='bar')
 
251
        branch = builder.get_branch()
 
252
        branch.lock_write()
 
253
        self.addCleanup(branch.unlock)
 
254
        branch.set_revision_history(['foo', 'bar'])
 
255
        branch.set_revision_history(['foo'])
 
256
        self.assertRaises(errors.NotLefthandHistory,
 
257
                          branch.set_revision_history, ['bar'])
 
258
 
 
259
    def do_checkout_test(self, lightweight=False):
 
260
        tree = self.make_branch_and_tree('source',
 
261
            format=self.get_format_name_subtree())
 
262
        subtree = self.make_branch_and_tree('source/subtree',
 
263
            format=self.get_format_name_subtree())
 
264
        subsubtree = self.make_branch_and_tree('source/subtree/subsubtree',
 
265
            format=self.get_format_name_subtree())
 
266
        self.build_tree(['source/subtree/file',
 
267
                         'source/subtree/subsubtree/file'])
 
268
        subsubtree.add('file')
 
269
        subtree.add('file')
 
270
        subtree.add_reference(subsubtree)
 
271
        tree.add_reference(subtree)
 
272
        tree.commit('a revision')
 
273
        subtree.commit('a subtree file')
 
274
        subsubtree.commit('a subsubtree file')
 
275
        tree.branch.create_checkout('target', lightweight=lightweight)
 
276
        self.failUnlessExists('target')
 
277
        self.failUnlessExists('target/subtree')
 
278
        self.failUnlessExists('target/subtree/file')
 
279
        self.failUnlessExists('target/subtree/subsubtree/file')
 
280
        subbranch = _mod_branch.Branch.open('target/subtree/subsubtree')
 
281
        if lightweight:
 
282
            self.assertEndsWith(subbranch.base, 'source/subtree/subsubtree/')
 
283
        else:
 
284
            self.assertEndsWith(subbranch.base, 'target/subtree/subsubtree/')
 
285
 
 
286
    def test_checkout_with_references(self):
 
287
        self.do_checkout_test()
 
288
 
 
289
    def test_light_checkout_with_references(self):
 
290
        self.do_checkout_test(lightweight=True)
 
291
 
 
292
    def test_set_push(self):
 
293
        branch = self.make_branch('source', format=self.get_format_name())
 
294
        branch.get_config().set_user_option('push_location', 'old',
 
295
            store=config.STORE_LOCATION)
 
296
        warnings = []
 
297
        def warning(*args):
 
298
            warnings.append(args[0] % args[1:])
 
299
        _warning = trace.warning
 
300
        trace.warning = warning
 
301
        try:
 
302
            branch.set_push_location('new')
 
303
        finally:
 
304
            trace.warning = _warning
 
305
        self.assertEqual(warnings[0], 'Value "new" is masked by "old" from '
 
306
                         'locations.conf')
 
307
 
 
308
 
 
309
class TestBranch6(TestBranch67, TestCaseWithTransport):
 
310
 
 
311
    def get_class(self):
 
312
        return _mod_branch.BzrBranch6
 
313
 
 
314
    def get_format_name(self):
 
315
        return "dirstate-tags"
 
316
 
 
317
    def get_format_name_subtree(self):
 
318
        return "dirstate-with-subtree"
 
319
 
 
320
    def test_set_stacked_on_url_errors(self):
 
321
        branch = self.make_branch('a', format=self.get_format_name())
 
322
        self.assertRaises(errors.UnstackableBranchFormat,
 
323
            branch.set_stacked_on_url, None)
 
324
 
 
325
    def test_default_stacked_location(self):
 
326
        branch = self.make_branch('a', format=self.get_format_name())
 
327
        self.assertRaises(errors.UnstackableBranchFormat, branch.get_stacked_on_url)
 
328
 
 
329
 
 
330
class TestBranch7(TestBranch67, TestCaseWithTransport):
 
331
 
 
332
    def get_class(self):
 
333
        return _mod_branch.BzrBranch7
 
334
 
 
335
    def get_format_name(self):
 
336
        return "development"
 
337
 
 
338
    def get_format_name_subtree(self):
 
339
        return "development-subtree"
 
340
 
 
341
    def test_set_stacked_on_url_unstackable_repo(self):
 
342
        repo = self.make_repository('a', format='dirstate-tags')
 
343
        control = repo.bzrdir
 
344
        branch = _mod_branch.BzrBranchFormat7().initialize(control)
 
345
        target = self.make_branch('b')
 
346
        self.assertRaises(errors.UnstackableRepositoryFormat,
 
347
            branch.set_stacked_on_url, target.base)
 
348
 
 
349
    def test_clone_stacked_on_unstackable_repo(self):
 
350
        repo = self.make_repository('a', format='dirstate-tags')
 
351
        control = repo.bzrdir
 
352
        branch = _mod_branch.BzrBranchFormat7().initialize(control)
 
353
        # Calling clone should not raise UnstackableRepositoryFormat.
 
354
        cloned_bzrdir = control.clone('cloned')
 
355
 
 
356
    def _test_default_stacked_location(self):
 
357
        branch = self.make_branch('a', format=self.get_format_name())
 
358
        self.assertRaises(errors.NotStacked, branch.get_stacked_on_url)
 
359
 
 
360
    def test_stack_and_unstack(self):
 
361
        branch = self.make_branch('a', format=self.get_format_name())
 
362
        target = self.make_branch_and_tree('b', format=self.get_format_name())
 
363
        branch.set_stacked_on_url(target.branch.base)
 
364
        self.assertEqual(target.branch.base, branch.get_stacked_on_url())
 
365
        revid = target.commit('foo')
 
366
        self.assertTrue(branch.repository.has_revision(revid))
 
367
        branch.set_stacked_on_url(None)
 
368
        self.assertRaises(errors.NotStacked, branch.get_stacked_on_url)
 
369
        self.assertFalse(branch.repository.has_revision(revid))
 
370
 
 
371
    def test_open_opens_stacked_reference(self):
 
372
        branch = self.make_branch('a', format=self.get_format_name())
 
373
        target = self.make_branch_and_tree('b', format=self.get_format_name())
 
374
        branch.set_stacked_on_url(target.branch.base)
 
375
        branch = branch.bzrdir.open_branch()
 
376
        revid = target.commit('foo')
 
377
        self.assertTrue(branch.repository.has_revision(revid))
184
378
 
185
379
 
186
380
class TestBranchReference(TestCaseWithTransport):
195
389
        target_branch = dir.create_branch()
196
390
        t.mkdir('branch')
197
391
        branch_dir = bzrdirformat.initialize(self.get_url('branch'))
198
 
        made_branch = bzrlib.branch.BranchReferenceFormat().initialize(branch_dir, target_branch)
 
392
        made_branch = BranchReferenceFormat().initialize(branch_dir, target_branch)
199
393
        self.assertEqual(made_branch.base, target_branch.base)
200
394
        opened_branch = branch_dir.open_branch()
201
395
        self.assertEqual(opened_branch.base, target_branch.base)
 
396
 
 
397
    def test_get_reference(self):
 
398
        """For a BranchReference, get_reference should reutrn the location."""
 
399
        branch = self.make_branch('target')
 
400
        checkout = branch.create_checkout('checkout', lightweight=True)
 
401
        reference_url = branch.bzrdir.root_transport.abspath('') + '/'
 
402
        # if the api for create_checkout changes to return different checkout types
 
403
        # then this file read will fail.
 
404
        self.assertFileEqual(reference_url, 'checkout/.bzr/branch/location')
 
405
        self.assertEqual(reference_url,
 
406
            _mod_branch.BranchReferenceFormat().get_reference(checkout.bzrdir))
 
407
 
 
408
 
 
409
class TestHooks(TestCase):
 
410
 
 
411
    def test_constructor(self):
 
412
        """Check that creating a BranchHooks instance has the right defaults."""
 
413
        hooks = BranchHooks()
 
414
        self.assertTrue("set_rh" in hooks, "set_rh not in %s" % hooks)
 
415
        self.assertTrue("post_push" in hooks, "post_push not in %s" % hooks)
 
416
        self.assertTrue("post_commit" in hooks, "post_commit not in %s" % hooks)
 
417
        self.assertTrue("pre_commit" in hooks, "pre_commit not in %s" % hooks)
 
418
        self.assertTrue("post_pull" in hooks, "post_pull not in %s" % hooks)
 
419
        self.assertTrue("post_uncommit" in hooks, "post_uncommit not in %s" % hooks)
 
420
        self.assertTrue("post_change_branch_tip" in hooks,
 
421
                        "post_change_branch_tip not in %s" % hooks)
 
422
 
 
423
    def test_installed_hooks_are_BranchHooks(self):
 
424
        """The installed hooks object should be a BranchHooks."""
 
425
        # the installed hooks are saved in self._preserved_hooks.
 
426
        self.assertIsInstance(self._preserved_hooks[_mod_branch.Branch], BranchHooks)
 
427
 
 
428
 
 
429
class TestPullResult(TestCase):
 
430
 
 
431
    def test_pull_result_to_int(self):
 
432
        # to support old code, the pull result can be used as an int
 
433
        r = PullResult()
 
434
        r.old_revno = 10
 
435
        r.new_revno = 20
 
436
        # this usage of results is not recommended for new code (because it
 
437
        # doesn't describe very well what happened), but for api stability
 
438
        # it's still supported
 
439
        a = "%d revisions pulled" % r
 
440
        self.assertEqual(a, "10 revisions pulled")