~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: 2006-09-20 14:51:03 UTC
  • mfrom: (0.8.23 version_info)
  • mto: This revision was merged to the branch mainline in revision 2028.
  • Revision ID: john@arbash-meinel.com-20060920145103-02725c6d6c886040
[merge] version-info plugin, and cleanup for layout in bzr

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006-2011 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
12
12
#
13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
 
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
 
17
17
"""Tests for the Branch facility that are not interface  tests.
18
18
 
19
 
For interface tests see `tests/per_branch/*.py`.
 
19
For interface tests see tests/branch_implementations/*.py.
20
20
 
21
21
For concrete class tests see this file, and for meta-branch tests
22
22
also see this file.
23
23
"""
24
24
 
25
 
from cStringIO import StringIO
26
 
 
27
 
from bzrlib import (
28
 
    branch as _mod_branch,
29
 
    bzrdir,
30
 
    config,
31
 
    errors,
32
 
    symbol_versioning,
33
 
    tests,
34
 
    trace,
35
 
    urlutils,
36
 
    )
37
 
 
38
 
 
39
 
class TestDefaultFormat(tests.TestCase):
40
 
 
41
 
    def test_default_format(self):
42
 
        # update this if you change the default branch format
43
 
        self.assertIsInstance(_mod_branch.format_registry.get_default(),
44
 
                _mod_branch.BzrBranchFormat7)
45
 
 
46
 
    def test_default_format_is_same_as_bzrdir_default(self):
47
 
        # XXX: it might be nice if there was only one place the default was
48
 
        # set, but at the moment that's not true -- mbp 20070814 --
49
 
        # https://bugs.launchpad.net/bzr/+bug/132376
50
 
        self.assertEqual(
51
 
            _mod_branch.format_registry.get_default(),
52
 
            bzrdir.BzrDirFormat.get_default_format().get_branch_format())
 
25
from StringIO import StringIO
 
26
 
 
27
import bzrlib.branch
 
28
from bzrlib.branch import (BzrBranch5, 
 
29
                           BzrBranchFormat5)
 
30
import bzrlib.bzrdir as bzrdir
 
31
from bzrlib.bzrdir import (BzrDirMetaFormat1, BzrDirMeta1, 
 
32
                           BzrDir, BzrDirFormat)
 
33
from bzrlib.errors import (NotBranchError,
 
34
                           UnknownFormatError,
 
35
                           UnsupportedFormatError,
 
36
                           )
 
37
 
 
38
from bzrlib.tests import TestCase, TestCaseWithTransport
 
39
from bzrlib.transport import get_transport
 
40
 
 
41
class TestDefaultFormat(TestCase):
53
42
 
54
43
    def test_get_set_default_format(self):
55
 
        # set the format and then set it back again
56
 
        old_format = _mod_branch.format_registry.get_default()
57
 
        _mod_branch.format_registry.set_default(SampleBranchFormat())
 
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())
58
48
        try:
59
49
            # the default branch format is used by the meta dir format
60
50
            # which is not the default bzrdir format at this point
61
 
            dir = bzrdir.BzrDirMetaFormat1().initialize('memory:///')
 
51
            dir = BzrDirMetaFormat1().initialize('memory:///')
62
52
            result = dir.create_branch()
63
53
            self.assertEqual(result, 'A branch')
64
54
        finally:
65
 
            _mod_branch.format_registry.set_default(old_format)
66
 
        self.assertEqual(old_format,
67
 
                         _mod_branch.format_registry.get_default())
68
 
 
69
 
 
70
 
class TestBranchFormat5(tests.TestCaseWithTransport):
 
55
            bzrlib.branch.BranchFormat.set_default_format(old_format)
 
56
        self.assertEqual(old_format, bzrlib.branch.BranchFormat.get_default_format())
 
57
 
 
58
 
 
59
class TestBranchFormat5(TestCaseWithTransport):
71
60
    """Tests specific to branch format 5"""
72
61
 
73
62
    def test_branch_format_5_uses_lockdir(self):
74
63
        url = self.get_url()
75
 
        bdir = bzrdir.BzrDirMetaFormat1().initialize(url)
76
 
        bdir.create_repository()
77
 
        branch = _mod_branch.BzrBranchFormat5().initialize(bdir)
 
64
        bzrdir = BzrDirMetaFormat1().initialize(url)
 
65
        bzrdir.create_repository()
 
66
        branch = bzrdir.create_branch()
78
67
        t = self.get_transport()
79
68
        self.log("branch instance is %r" % branch)
80
 
        self.assert_(isinstance(branch, _mod_branch.BzrBranch5))
 
69
        self.assert_(isinstance(branch, BzrBranch5))
81
70
        self.assertIsDirectory('.', t)
82
71
        self.assertIsDirectory('.bzr/branch', t)
83
72
        self.assertIsDirectory('.bzr/branch/lock', t)
84
73
        branch.lock_write()
85
 
        self.addCleanup(branch.unlock)
86
 
        self.assertIsDirectory('.bzr/branch/lock/held', t)
87
 
 
88
 
    def test_set_push_location(self):
89
 
        conf = config.LocationConfig.from_string('# comment\n', '.', save=True)
90
 
 
91
 
        branch = self.make_branch('.', format='knit')
92
 
        branch.set_push_location('foo')
93
 
        local_path = urlutils.local_path_from_url(branch.base[:-1])
94
 
        self.assertFileEqual("# comment\n"
95
 
                             "[%s]\n"
96
 
                             "push_location = foo\n"
97
 
                             "push_location:policy = norecurse\n" % local_path,
98
 
                             config.locations_config_filename())
99
 
 
100
 
    # TODO RBC 20051029 test getting a push location from a branch in a
101
 
    # recursive section - that is, it appends the branch name.
102
 
 
103
 
 
104
 
class SampleBranchFormat(_mod_branch.BranchFormat):
 
74
        try:
 
75
            self.assertIsDirectory('.bzr/branch/lock/held', t)
 
76
        finally:
 
77
            branch.unlock()
 
78
 
 
79
 
 
80
class SampleBranchFormat(bzrlib.branch.BranchFormat):
105
81
    """A sample format
106
82
 
107
 
    this format is initializable, unsupported to aid in testing the
 
83
    this format is initializable, unsupported to aid in testing the 
108
84
    open and open_downlevel routines.
109
85
    """
110
86
 
112
88
        """See BzrBranchFormat.get_format_string()."""
113
89
        return "Sample branch format."
114
90
 
115
 
    def initialize(self, a_bzrdir, name=None, repository=None):
 
91
    def initialize(self, a_bzrdir):
116
92
        """Format 4 branches cannot be created."""
117
 
        t = a_bzrdir.get_branch_transport(self, name=name)
 
93
        t = a_bzrdir.get_branch_transport(self)
118
94
        t.put_bytes('format', self.get_format_string())
119
95
        return 'A branch'
120
96
 
121
97
    def is_supported(self):
122
98
        return False
123
99
 
124
 
    def open(self, transport, name=None, _found=False, ignore_fallbacks=False):
 
100
    def open(self, transport, _found=False):
125
101
        return "opened branch."
126
102
 
127
103
 
128
 
# Demonstrating how lazy loading is often implemented:
129
 
# A constant string is created.
130
 
SampleSupportedBranchFormatString = "Sample supported branch format."
131
 
 
132
 
# And the format class can then reference the constant to avoid skew.
133
 
class SampleSupportedBranchFormat(_mod_branch.BranchFormat):
134
 
    """A sample supported format."""
135
 
 
136
 
    def get_format_string(self):
137
 
        """See BzrBranchFormat.get_format_string()."""
138
 
        return SampleSupportedBranchFormatString
139
 
 
140
 
    def initialize(self, a_bzrdir, name=None):
141
 
        t = a_bzrdir.get_branch_transport(self, name=name)
142
 
        t.put_bytes('format', self.get_format_string())
143
 
        return 'A branch'
144
 
 
145
 
    def open(self, transport, name=None, _found=False, ignore_fallbacks=False):
146
 
        return "opened supported branch."
147
 
 
148
 
 
149
 
class SampleExtraBranchFormat(_mod_branch.BranchFormat):
150
 
    """A sample format that is not usable in a metadir."""
151
 
 
152
 
    def get_format_string(self):
153
 
        # This format is not usable in a metadir.
154
 
        return None
155
 
 
156
 
    def network_name(self):
157
 
        # Network name always has to be provided.
158
 
        return "extra"
159
 
 
160
 
    def initialize(self, a_bzrdir, name=None):
161
 
        raise NotImplementedError(self.initialize)
162
 
 
163
 
    def open(self, transport, name=None, _found=False, ignore_fallbacks=False):
164
 
        raise NotImplementedError(self.open)
165
 
 
166
 
 
167
 
class TestBzrBranchFormat(tests.TestCaseWithTransport):
 
104
class TestBzrBranchFormat(TestCaseWithTransport):
168
105
    """Tests for the BzrBranchFormat facility."""
169
106
 
170
107
    def test_find_format(self):
171
108
        # is the right format object found for a branch?
172
109
        # create a branch with a few known format objects.
173
 
        # this is not quite the same as
 
110
        # this is not quite the same as 
174
111
        self.build_tree(["foo/", "bar/"])
175
112
        def check_format(format, url):
176
113
            dir = format._matchingbzrdir.initialize(url)
177
114
            dir.create_repository()
178
115
            format.initialize(dir)
179
 
            found_format = _mod_branch.BranchFormat.find_format(dir)
180
 
            self.assertIsInstance(found_format, format.__class__)
181
 
        check_format(_mod_branch.BzrBranchFormat5(), "bar")
182
 
 
183
 
    def test_find_format_factory(self):
184
 
        dir = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
185
 
        SampleSupportedBranchFormat().initialize(dir)
186
 
        factory = _mod_branch.MetaDirBranchFormatFactory(
187
 
            SampleSupportedBranchFormatString,
188
 
            "bzrlib.tests.test_branch", "SampleSupportedBranchFormat")
189
 
        _mod_branch.format_registry.register(factory)
190
 
        self.addCleanup(_mod_branch.format_registry.remove, factory)
191
 
        b = _mod_branch.Branch.open(self.get_url())
192
 
        self.assertEqual(b, "opened supported branch.")
193
 
 
 
116
            found_format = bzrlib.branch.BranchFormat.find_format(dir)
 
117
            self.failUnless(isinstance(found_format, format.__class__))
 
118
        check_format(bzrlib.branch.BzrBranchFormat5(), "bar")
 
119
        
194
120
    def test_find_format_not_branch(self):
195
121
        dir = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
196
 
        self.assertRaises(errors.NotBranchError,
197
 
                          _mod_branch.BranchFormat.find_format,
 
122
        self.assertRaises(NotBranchError,
 
123
                          bzrlib.branch.BranchFormat.find_format,
198
124
                          dir)
199
125
 
200
126
    def test_find_format_unknown_format(self):
201
127
        dir = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
202
128
        SampleBranchFormat().initialize(dir)
203
 
        self.assertRaises(errors.UnknownFormatError,
204
 
                          _mod_branch.BranchFormat.find_format,
 
129
        self.assertRaises(UnknownFormatError,
 
130
                          bzrlib.branch.BranchFormat.find_format,
205
131
                          dir)
206
132
 
207
133
    def test_register_unregister_format(self):
208
 
        # Test the deprecated format registration functions
209
134
        format = SampleBranchFormat()
210
135
        # make a control dir
211
136
        dir = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
212
137
        # make a branch
213
138
        format.initialize(dir)
214
139
        # register a format for it.
215
 
        self.applyDeprecated(symbol_versioning.deprecated_in((2, 4, 0)),
216
 
            _mod_branch.BranchFormat.register_format, format)
 
140
        bzrlib.branch.BranchFormat.register_format(format)
217
141
        # which branch.Open will refuse (not supported)
218
 
        self.assertRaises(errors.UnsupportedFormatError,
219
 
                          _mod_branch.Branch.open, self.get_url())
220
 
        self.make_branch_and_tree('foo')
 
142
        self.assertRaises(UnsupportedFormatError, bzrlib.branch.Branch.open, self.get_url())
221
143
        # but open_downlevel will work
222
 
        self.assertEqual(
223
 
            format.open(dir),
224
 
            bzrdir.BzrDir.open(self.get_url()).open_branch(unsupported=True))
 
144
        self.assertEqual(format.open(dir), bzrdir.BzrDir.open(self.get_url()).open_branch(unsupported=True))
225
145
        # unregister the format
226
 
        self.applyDeprecated(symbol_versioning.deprecated_in((2, 4, 0)),
227
 
            _mod_branch.BranchFormat.unregister_format, format)
228
 
        self.make_branch_and_tree('bar')
229
 
 
230
 
 
231
 
class TestBranchFormatRegistry(tests.TestCase):
232
 
 
233
 
    def setUp(self):
234
 
        super(TestBranchFormatRegistry, self).setUp()
235
 
        self.registry = _mod_branch.BranchFormatRegistry()
236
 
 
237
 
    def test_default(self):
238
 
        self.assertIs(None, self.registry.get_default())
239
 
        format = SampleBranchFormat()
240
 
        self.registry.set_default(format)
241
 
        self.assertEquals(format, self.registry.get_default())
242
 
 
243
 
    def test_register_unregister_format(self):
244
 
        format = SampleBranchFormat()
245
 
        self.registry.register(format)
246
 
        self.assertEquals(format,
247
 
            self.registry.get("Sample branch format."))
248
 
        self.registry.remove(format)
249
 
        self.assertRaises(KeyError, self.registry.get,
250
 
            "Sample branch format.")
251
 
 
252
 
    def test_get_all(self):
253
 
        format = SampleBranchFormat()
254
 
        self.assertEquals([], self.registry._get_all())
255
 
        self.registry.register(format)
256
 
        self.assertEquals([format], self.registry._get_all())
257
 
 
258
 
    def test_register_extra(self):
259
 
        format = SampleExtraBranchFormat()
260
 
        self.assertEquals([], self.registry._get_all())
261
 
        self.registry.register_extra(format)
262
 
        self.assertEquals([format], self.registry._get_all())
263
 
 
264
 
    def test_register_extra_lazy(self):
265
 
        self.assertEquals([], self.registry._get_all())
266
 
        self.registry.register_extra_lazy("bzrlib.tests.test_branch",
267
 
            "SampleExtraBranchFormat")
268
 
        formats = self.registry._get_all()
269
 
        self.assertEquals(1, len(formats))
270
 
        self.assertIsInstance(formats[0], SampleExtraBranchFormat)
271
 
 
272
 
 
273
 
#Used by TestMetaDirBranchFormatFactory 
274
 
FakeLazyFormat = None
275
 
 
276
 
 
277
 
class TestMetaDirBranchFormatFactory(tests.TestCase):
278
 
 
279
 
    def test_get_format_string_does_not_load(self):
280
 
        """Formats have a static format string."""
281
 
        factory = _mod_branch.MetaDirBranchFormatFactory("yo", None, None)
282
 
        self.assertEqual("yo", factory.get_format_string())
283
 
 
284
 
    def test_call_loads(self):
285
 
        # __call__ is used by the network_format_registry interface to get a
286
 
        # Format.
287
 
        global FakeLazyFormat
288
 
        del FakeLazyFormat
289
 
        factory = _mod_branch.MetaDirBranchFormatFactory(None,
290
 
            "bzrlib.tests.test_branch", "FakeLazyFormat")
291
 
        self.assertRaises(AttributeError, factory)
292
 
 
293
 
    def test_call_returns_call_of_referenced_object(self):
294
 
        global FakeLazyFormat
295
 
        FakeLazyFormat = lambda:'called'
296
 
        factory = _mod_branch.MetaDirBranchFormatFactory(None,
297
 
            "bzrlib.tests.test_branch", "FakeLazyFormat")
298
 
        self.assertEqual('called', factory())
299
 
 
300
 
 
301
 
class TestBranch67(object):
302
 
    """Common tests for both branch 6 and 7 which are mostly the same."""
303
 
 
304
 
    def get_format_name(self):
305
 
        raise NotImplementedError(self.get_format_name)
306
 
 
307
 
    def get_format_name_subtree(self):
308
 
        raise NotImplementedError(self.get_format_name)
309
 
 
310
 
    def get_class(self):
311
 
        raise NotImplementedError(self.get_class)
312
 
 
313
 
    def test_creation(self):
314
 
        format = bzrdir.BzrDirMetaFormat1()
315
 
        format.set_branch_format(_mod_branch.BzrBranchFormat6())
316
 
        branch = self.make_branch('a', format=format)
317
 
        self.assertIsInstance(branch, self.get_class())
318
 
        branch = self.make_branch('b', format=self.get_format_name())
319
 
        self.assertIsInstance(branch, self.get_class())
320
 
        branch = _mod_branch.Branch.open('a')
321
 
        self.assertIsInstance(branch, self.get_class())
322
 
 
323
 
    def test_layout(self):
324
 
        branch = self.make_branch('a', format=self.get_format_name())
325
 
        self.assertPathExists('a/.bzr/branch/last-revision')
326
 
        self.assertPathDoesNotExist('a/.bzr/branch/revision-history')
327
 
        self.assertPathDoesNotExist('a/.bzr/branch/references')
328
 
 
329
 
    def test_config(self):
330
 
        """Ensure that all configuration data is stored in the branch"""
331
 
        branch = self.make_branch('a', format=self.get_format_name())
332
 
        branch.set_parent('http://example.com')
333
 
        self.assertPathDoesNotExist('a/.bzr/branch/parent')
334
 
        self.assertEqual('http://example.com', branch.get_parent())
335
 
        branch.set_push_location('sftp://example.com')
336
 
        config = branch.get_config()._get_branch_data_config()
337
 
        self.assertEqual('sftp://example.com',
338
 
                         config.get_user_option('push_location'))
339
 
        branch.set_bound_location('ftp://example.com')
340
 
        self.assertPathDoesNotExist('a/.bzr/branch/bound')
341
 
        self.assertEqual('ftp://example.com', branch.get_bound_location())
342
 
 
343
 
    def test_set_revision_history(self):
344
 
        builder = self.make_branch_builder('.', format=self.get_format_name())
345
 
        builder.build_snapshot('foo', None,
346
 
            [('add', ('', None, 'directory', None))],
347
 
            message='foo')
348
 
        builder.build_snapshot('bar', None, [], message='bar')
349
 
        branch = builder.get_branch()
350
 
        branch.lock_write()
351
 
        self.addCleanup(branch.unlock)
352
 
        self.applyDeprecated(symbol_versioning.deprecated_in((2, 4, 0)),
353
 
            branch.set_revision_history, ['foo', 'bar'])
354
 
        self.applyDeprecated(symbol_versioning.deprecated_in((2, 4, 0)),
355
 
                branch.set_revision_history, ['foo'])
356
 
        self.assertRaises(errors.NotLefthandHistory,
357
 
            self.applyDeprecated, symbol_versioning.deprecated_in((2, 4, 0)),
358
 
            branch.set_revision_history, ['bar'])
359
 
 
360
 
    def do_checkout_test(self, lightweight=False):
361
 
        tree = self.make_branch_and_tree('source',
362
 
            format=self.get_format_name_subtree())
363
 
        subtree = self.make_branch_and_tree('source/subtree',
364
 
            format=self.get_format_name_subtree())
365
 
        subsubtree = self.make_branch_and_tree('source/subtree/subsubtree',
366
 
            format=self.get_format_name_subtree())
367
 
        self.build_tree(['source/subtree/file',
368
 
                         'source/subtree/subsubtree/file'])
369
 
        subsubtree.add('file')
370
 
        subtree.add('file')
371
 
        subtree.add_reference(subsubtree)
372
 
        tree.add_reference(subtree)
373
 
        tree.commit('a revision')
374
 
        subtree.commit('a subtree file')
375
 
        subsubtree.commit('a subsubtree file')
376
 
        tree.branch.create_checkout('target', lightweight=lightweight)
377
 
        self.assertPathExists('target')
378
 
        self.assertPathExists('target/subtree')
379
 
        self.assertPathExists('target/subtree/file')
380
 
        self.assertPathExists('target/subtree/subsubtree/file')
381
 
        subbranch = _mod_branch.Branch.open('target/subtree/subsubtree')
382
 
        if lightweight:
383
 
            self.assertEndsWith(subbranch.base, 'source/subtree/subsubtree/')
384
 
        else:
385
 
            self.assertEndsWith(subbranch.base, 'target/subtree/subsubtree/')
386
 
 
387
 
    def test_checkout_with_references(self):
388
 
        self.do_checkout_test()
389
 
 
390
 
    def test_light_checkout_with_references(self):
391
 
        self.do_checkout_test(lightweight=True)
392
 
 
393
 
    def test_set_push(self):
394
 
        branch = self.make_branch('source', format=self.get_format_name())
395
 
        branch.get_config().set_user_option('push_location', 'old',
396
 
            store=config.STORE_LOCATION)
397
 
        warnings = []
398
 
        def warning(*args):
399
 
            warnings.append(args[0] % args[1:])
400
 
        _warning = trace.warning
401
 
        trace.warning = warning
402
 
        try:
403
 
            branch.set_push_location('new')
404
 
        finally:
405
 
            trace.warning = _warning
406
 
        self.assertEqual(warnings[0], 'Value "new" is masked by "old" from '
407
 
                         'locations.conf')
408
 
 
409
 
 
410
 
class TestBranch6(TestBranch67, tests.TestCaseWithTransport):
411
 
 
412
 
    def get_class(self):
413
 
        return _mod_branch.BzrBranch6
414
 
 
415
 
    def get_format_name(self):
416
 
        return "dirstate-tags"
417
 
 
418
 
    def get_format_name_subtree(self):
419
 
        return "dirstate-with-subtree"
420
 
 
421
 
    def test_set_stacked_on_url_errors(self):
422
 
        branch = self.make_branch('a', format=self.get_format_name())
423
 
        self.assertRaises(errors.UnstackableBranchFormat,
424
 
            branch.set_stacked_on_url, None)
425
 
 
426
 
    def test_default_stacked_location(self):
427
 
        branch = self.make_branch('a', format=self.get_format_name())
428
 
        self.assertRaises(errors.UnstackableBranchFormat, branch.get_stacked_on_url)
429
 
 
430
 
 
431
 
class TestBranch7(TestBranch67, tests.TestCaseWithTransport):
432
 
 
433
 
    def get_class(self):
434
 
        return _mod_branch.BzrBranch7
435
 
 
436
 
    def get_format_name(self):
437
 
        return "1.9"
438
 
 
439
 
    def get_format_name_subtree(self):
440
 
        return "development-subtree"
441
 
 
442
 
    def test_set_stacked_on_url_unstackable_repo(self):
443
 
        repo = self.make_repository('a', format='dirstate-tags')
444
 
        control = repo.bzrdir
445
 
        branch = _mod_branch.BzrBranchFormat7().initialize(control)
446
 
        target = self.make_branch('b')
447
 
        self.assertRaises(errors.UnstackableRepositoryFormat,
448
 
            branch.set_stacked_on_url, target.base)
449
 
 
450
 
    def test_clone_stacked_on_unstackable_repo(self):
451
 
        repo = self.make_repository('a', format='dirstate-tags')
452
 
        control = repo.bzrdir
453
 
        branch = _mod_branch.BzrBranchFormat7().initialize(control)
454
 
        # Calling clone should not raise UnstackableRepositoryFormat.
455
 
        cloned_bzrdir = control.clone('cloned')
456
 
 
457
 
    def _test_default_stacked_location(self):
458
 
        branch = self.make_branch('a', format=self.get_format_name())
459
 
        self.assertRaises(errors.NotStacked, branch.get_stacked_on_url)
460
 
 
461
 
    def test_stack_and_unstack(self):
462
 
        branch = self.make_branch('a', format=self.get_format_name())
463
 
        target = self.make_branch_and_tree('b', format=self.get_format_name())
464
 
        branch.set_stacked_on_url(target.branch.base)
465
 
        self.assertEqual(target.branch.base, branch.get_stacked_on_url())
466
 
        revid = target.commit('foo')
467
 
        self.assertTrue(branch.repository.has_revision(revid))
468
 
        branch.set_stacked_on_url(None)
469
 
        self.assertRaises(errors.NotStacked, branch.get_stacked_on_url)
470
 
        self.assertFalse(branch.repository.has_revision(revid))
471
 
 
472
 
    def test_open_opens_stacked_reference(self):
473
 
        branch = self.make_branch('a', format=self.get_format_name())
474
 
        target = self.make_branch_and_tree('b', format=self.get_format_name())
475
 
        branch.set_stacked_on_url(target.branch.base)
476
 
        branch = branch.bzrdir.open_branch()
477
 
        revid = target.commit('foo')
478
 
        self.assertTrue(branch.repository.has_revision(revid))
479
 
 
480
 
 
481
 
class BzrBranch8(tests.TestCaseWithTransport):
482
 
 
483
 
    def make_branch(self, location, format=None):
484
 
        if format is None:
485
 
            format = bzrdir.format_registry.make_bzrdir('1.9')
486
 
            format.set_branch_format(_mod_branch.BzrBranchFormat8())
487
 
        return tests.TestCaseWithTransport.make_branch(
488
 
            self, location, format=format)
489
 
 
490
 
    def create_branch_with_reference(self):
491
 
        branch = self.make_branch('branch')
492
 
        branch._set_all_reference_info({'file-id': ('path', 'location')})
493
 
        return branch
494
 
 
495
 
    @staticmethod
496
 
    def instrument_branch(branch, gets):
497
 
        old_get = branch._transport.get
498
 
        def get(*args, **kwargs):
499
 
            gets.append((args, kwargs))
500
 
            return old_get(*args, **kwargs)
501
 
        branch._transport.get = get
502
 
 
503
 
    def test_reference_info_caching_read_locked(self):
504
 
        gets = []
505
 
        branch = self.create_branch_with_reference()
506
 
        branch.lock_read()
507
 
        self.addCleanup(branch.unlock)
508
 
        self.instrument_branch(branch, gets)
509
 
        branch.get_reference_info('file-id')
510
 
        branch.get_reference_info('file-id')
511
 
        self.assertEqual(1, len(gets))
512
 
 
513
 
    def test_reference_info_caching_read_unlocked(self):
514
 
        gets = []
515
 
        branch = self.create_branch_with_reference()
516
 
        self.instrument_branch(branch, gets)
517
 
        branch.get_reference_info('file-id')
518
 
        branch.get_reference_info('file-id')
519
 
        self.assertEqual(2, len(gets))
520
 
 
521
 
    def test_reference_info_caching_write_locked(self):
522
 
        gets = []
523
 
        branch = self.make_branch('branch')
524
 
        branch.lock_write()
525
 
        self.instrument_branch(branch, gets)
526
 
        self.addCleanup(branch.unlock)
527
 
        branch._set_all_reference_info({'file-id': ('path2', 'location2')})
528
 
        path, location = branch.get_reference_info('file-id')
529
 
        self.assertEqual(0, len(gets))
530
 
        self.assertEqual('path2', path)
531
 
        self.assertEqual('location2', location)
532
 
 
533
 
    def test_reference_info_caches_cleared(self):
534
 
        branch = self.make_branch('branch')
535
 
        branch.lock_write()
536
 
        branch.set_reference_info('file-id', 'path2', 'location2')
537
 
        branch.unlock()
538
 
        doppelganger = _mod_branch.Branch.open('branch')
539
 
        doppelganger.set_reference_info('file-id', 'path3', 'location3')
540
 
        self.assertEqual(('path3', 'location3'),
541
 
                         branch.get_reference_info('file-id'))
542
 
 
543
 
class TestBranchReference(tests.TestCaseWithTransport):
 
146
        bzrlib.branch.BranchFormat.unregister_format(format)
 
147
 
 
148
 
 
149
class TestBranchReference(TestCaseWithTransport):
544
150
    """Tests for the branch reference facility."""
545
151
 
546
152
    def test_create_open_reference(self):
547
153
        bzrdirformat = bzrdir.BzrDirMetaFormat1()
548
 
        t = self.get_transport()
 
154
        t = get_transport(self.get_url('.'))
549
155
        t.mkdir('repo')
550
156
        dir = bzrdirformat.initialize(self.get_url('repo'))
551
157
        dir.create_repository()
552
158
        target_branch = dir.create_branch()
553
159
        t.mkdir('branch')
554
160
        branch_dir = bzrdirformat.initialize(self.get_url('branch'))
555
 
        made_branch = _mod_branch.BranchReferenceFormat().initialize(
556
 
            branch_dir, target_branch=target_branch)
 
161
        made_branch = bzrlib.branch.BranchReferenceFormat().initialize(branch_dir, target_branch)
557
162
        self.assertEqual(made_branch.base, target_branch.base)
558
163
        opened_branch = branch_dir.open_branch()
559
164
        self.assertEqual(opened_branch.base, target_branch.base)
560
 
 
561
 
    def test_get_reference(self):
562
 
        """For a BranchReference, get_reference should reutrn the location."""
563
 
        branch = self.make_branch('target')
564
 
        checkout = branch.create_checkout('checkout', lightweight=True)
565
 
        reference_url = branch.bzrdir.root_transport.abspath('') + '/'
566
 
        # if the api for create_checkout changes to return different checkout types
567
 
        # then this file read will fail.
568
 
        self.assertFileEqual(reference_url, 'checkout/.bzr/branch/location')
569
 
        self.assertEqual(reference_url,
570
 
            _mod_branch.BranchReferenceFormat().get_reference(checkout.bzrdir))
571
 
 
572
 
 
573
 
class TestHooks(tests.TestCaseWithTransport):
574
 
 
575
 
    def test_constructor(self):
576
 
        """Check that creating a BranchHooks instance has the right defaults."""
577
 
        hooks = _mod_branch.BranchHooks()
578
 
        self.assertTrue("set_rh" in hooks, "set_rh not in %s" % hooks)
579
 
        self.assertTrue("post_push" in hooks, "post_push not in %s" % hooks)
580
 
        self.assertTrue("post_commit" in hooks, "post_commit not in %s" % hooks)
581
 
        self.assertTrue("pre_commit" in hooks, "pre_commit not in %s" % hooks)
582
 
        self.assertTrue("post_pull" in hooks, "post_pull not in %s" % hooks)
583
 
        self.assertTrue("post_uncommit" in hooks,
584
 
                        "post_uncommit not in %s" % hooks)
585
 
        self.assertTrue("post_change_branch_tip" in hooks,
586
 
                        "post_change_branch_tip not in %s" % hooks)
587
 
        self.assertTrue("post_branch_init" in hooks,
588
 
                        "post_branch_init not in %s" % hooks)
589
 
        self.assertTrue("post_switch" in hooks,
590
 
                        "post_switch not in %s" % hooks)
591
 
 
592
 
    def test_installed_hooks_are_BranchHooks(self):
593
 
        """The installed hooks object should be a BranchHooks."""
594
 
        # the installed hooks are saved in self._preserved_hooks.
595
 
        self.assertIsInstance(self._preserved_hooks[_mod_branch.Branch][1],
596
 
                              _mod_branch.BranchHooks)
597
 
 
598
 
    def test_post_branch_init_hook(self):
599
 
        calls = []
600
 
        _mod_branch.Branch.hooks.install_named_hook('post_branch_init',
601
 
            calls.append, None)
602
 
        self.assertLength(0, calls)
603
 
        branch = self.make_branch('a')
604
 
        self.assertLength(1, calls)
605
 
        params = calls[0]
606
 
        self.assertIsInstance(params, _mod_branch.BranchInitHookParams)
607
 
        self.assertTrue(hasattr(params, 'bzrdir'))
608
 
        self.assertTrue(hasattr(params, 'branch'))
609
 
 
610
 
    def test_post_branch_init_hook_repr(self):
611
 
        param_reprs = []
612
 
        _mod_branch.Branch.hooks.install_named_hook('post_branch_init',
613
 
            lambda params: param_reprs.append(repr(params)), None)
614
 
        branch = self.make_branch('a')
615
 
        self.assertLength(1, param_reprs)
616
 
        param_repr = param_reprs[0]
617
 
        self.assertStartsWith(param_repr, '<BranchInitHookParams of ')
618
 
 
619
 
    def test_post_switch_hook(self):
620
 
        from bzrlib import switch
621
 
        calls = []
622
 
        _mod_branch.Branch.hooks.install_named_hook('post_switch',
623
 
            calls.append, None)
624
 
        tree = self.make_branch_and_tree('branch-1')
625
 
        self.build_tree(['branch-1/file-1'])
626
 
        tree.add('file-1')
627
 
        tree.commit('rev1')
628
 
        to_branch = tree.bzrdir.sprout('branch-2').open_branch()
629
 
        self.build_tree(['branch-1/file-2'])
630
 
        tree.add('file-2')
631
 
        tree.remove('file-1')
632
 
        tree.commit('rev2')
633
 
        checkout = tree.branch.create_checkout('checkout')
634
 
        self.assertLength(0, calls)
635
 
        switch.switch(checkout.bzrdir, to_branch)
636
 
        self.assertLength(1, calls)
637
 
        params = calls[0]
638
 
        self.assertIsInstance(params, _mod_branch.SwitchHookParams)
639
 
        self.assertTrue(hasattr(params, 'to_branch'))
640
 
        self.assertTrue(hasattr(params, 'revision_id'))
641
 
 
642
 
 
643
 
class TestBranchOptions(tests.TestCaseWithTransport):
644
 
 
645
 
    def setUp(self):
646
 
        super(TestBranchOptions, self).setUp()
647
 
        self.branch = self.make_branch('.')
648
 
        self.config = self.branch.get_config()
649
 
 
650
 
    def check_append_revisions_only(self, expected_value, value=None):
651
 
        """Set append_revisions_only in config and check its interpretation."""
652
 
        if value is not None:
653
 
            self.config.set_user_option('append_revisions_only', value)
654
 
        self.assertEqual(expected_value,
655
 
                         self.branch._get_append_revisions_only())
656
 
 
657
 
    def test_valid_append_revisions_only(self):
658
 
        self.assertEquals(None,
659
 
                          self.config.get_user_option('append_revisions_only'))
660
 
        self.check_append_revisions_only(None)
661
 
        self.check_append_revisions_only(False, 'False')
662
 
        self.check_append_revisions_only(True, 'True')
663
 
        # The following values will cause compatibility problems on projects
664
 
        # using older bzr versions (<2.2) but are accepted
665
 
        self.check_append_revisions_only(False, 'false')
666
 
        self.check_append_revisions_only(True, 'true')
667
 
 
668
 
    def test_invalid_append_revisions_only(self):
669
 
        """Ensure warning is noted on invalid settings"""
670
 
        self.warnings = []
671
 
        def warning(*args):
672
 
            self.warnings.append(args[0] % args[1:])
673
 
        self.overrideAttr(trace, 'warning', warning)
674
 
        self.check_append_revisions_only(None, 'not-a-bool')
675
 
        self.assertLength(1, self.warnings)
676
 
        self.assertEqual(
677
 
            'Value "not-a-bool" is not a boolean for "append_revisions_only"',
678
 
            self.warnings[0])
679
 
 
680
 
 
681
 
class TestPullResult(tests.TestCase):
682
 
 
683
 
    def test_pull_result_to_int(self):
684
 
        # to support old code, the pull result can be used as an int
685
 
        r = _mod_branch.PullResult()
686
 
        r.old_revno = 10
687
 
        r.new_revno = 20
688
 
        # this usage of results is not recommended for new code (because it
689
 
        # doesn't describe very well what happened), but for api stability
690
 
        # it's still supported
691
 
        self.assertEqual(self.applyDeprecated(
692
 
            symbol_versioning.deprecated_in((2, 3, 0)),
693
 
            r.__int__),
694
 
            10)
695
 
 
696
 
    def test_report_changed(self):
697
 
        r = _mod_branch.PullResult()
698
 
        r.old_revid = "old-revid"
699
 
        r.old_revno = 10
700
 
        r.new_revid = "new-revid"
701
 
        r.new_revno = 20
702
 
        f = StringIO()
703
 
        r.report(f)
704
 
        self.assertEqual("Now on revision 20.\n", f.getvalue())
705
 
 
706
 
    def test_report_unchanged(self):
707
 
        r = _mod_branch.PullResult()
708
 
        r.old_revid = "same-revid"
709
 
        r.new_revid = "same-revid"
710
 
        f = StringIO()
711
 
        r.report(f)
712
 
        self.assertEqual("No revisions to pull.\n", f.getvalue())
713