~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_branch.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2011-08-17 18:13:57 UTC
  • mfrom: (5268.7.29 transport-segments)
  • Revision ID: pqm@pqm.ubuntu.com-20110817181357-y5q5eth1hk8bl3om
(jelmer) Allow specifying the colocated branch to use in the branch URL,
 and retrieving the branch name using ControlDir._get_selected_branch.
 (Jelmer Vernooij)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2006, 2007 Canonical Ltd
 
1
# Copyright (C) 2006-2011 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
17
17
"""Tests for the Branch facility that are not interface  tests.
18
18
 
19
 
For interface tests see tests/branch_implementations/*.py.
 
19
For interface tests see `tests/per_branch/*.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 StringIO import StringIO
 
25
from cStringIO import StringIO
26
26
 
27
27
from bzrlib import (
28
28
    branch as _mod_branch,
29
29
    bzrdir,
30
30
    config,
31
31
    errors,
 
32
    symbol_versioning,
 
33
    tests,
32
34
    trace,
33
35
    urlutils,
34
36
    )
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
 
 
57
 
class TestDefaultFormat(TestCase):
 
37
 
 
38
 
 
39
class TestDefaultFormat(tests.TestCase):
58
40
 
59
41
    def test_default_format(self):
60
42
        # update this if you change the default branch format
61
 
        self.assertIsInstance(BranchFormat.get_default_format(),
62
 
                BzrBranchFormat6)
 
43
        self.assertIsInstance(_mod_branch.format_registry.get_default(),
 
44
                _mod_branch.BzrBranchFormat7)
63
45
 
64
46
    def test_default_format_is_same_as_bzrdir_default(self):
65
47
        # 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 -- 
 
48
        # set, but at the moment that's not true -- mbp 20070814 --
67
49
        # https://bugs.launchpad.net/bzr/+bug/132376
68
 
        self.assertEqual(BranchFormat.get_default_format(),
69
 
                BzrDirFormat.get_default_format().get_branch_format())
 
50
        self.assertEqual(
 
51
            _mod_branch.format_registry.get_default(),
 
52
            bzrdir.BzrDirFormat.get_default_format().get_branch_format())
70
53
 
71
54
    def test_get_set_default_format(self):
72
55
        # set the format and then set it back again
73
 
        old_format = BranchFormat.get_default_format()
74
 
        BranchFormat.set_default_format(SampleBranchFormat())
 
56
        old_format = _mod_branch.format_registry.get_default()
 
57
        _mod_branch.format_registry.set_default(SampleBranchFormat())
75
58
        try:
76
59
            # the default branch format is used by the meta dir format
77
60
            # which is not the default bzrdir format at this point
78
 
            dir = BzrDirMetaFormat1().initialize('memory:///')
 
61
            dir = bzrdir.BzrDirMetaFormat1().initialize('memory:///')
79
62
            result = dir.create_branch()
80
63
            self.assertEqual(result, 'A branch')
81
64
        finally:
82
 
            BranchFormat.set_default_format(old_format)
83
 
        self.assertEqual(old_format, BranchFormat.get_default_format())
84
 
 
85
 
 
86
 
class TestBranchFormat5(TestCaseWithTransport):
 
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):
87
71
    """Tests specific to branch format 5"""
88
72
 
89
73
    def test_branch_format_5_uses_lockdir(self):
90
74
        url = self.get_url()
91
 
        bzrdir = BzrDirMetaFormat1().initialize(url)
92
 
        bzrdir.create_repository()
93
 
        branch = bzrdir.create_branch()
 
75
        bdir = bzrdir.BzrDirMetaFormat1().initialize(url)
 
76
        bdir.create_repository()
 
77
        branch = _mod_branch.BzrBranchFormat5().initialize(bdir)
94
78
        t = self.get_transport()
95
79
        self.log("branch instance is %r" % branch)
96
 
        self.assert_(isinstance(branch, BzrBranch5))
 
80
        self.assert_(isinstance(branch, _mod_branch.BzrBranch5))
97
81
        self.assertIsDirectory('.', t)
98
82
        self.assertIsDirectory('.bzr/branch', t)
99
83
        self.assertIsDirectory('.bzr/branch/lock', t)
100
84
        branch.lock_write()
101
 
        try:
102
 
            self.assertIsDirectory('.bzr/branch/lock/held', t)
103
 
        finally:
104
 
            branch.unlock()
 
85
        self.addCleanup(branch.unlock)
 
86
        self.assertIsDirectory('.bzr/branch/lock/held', t)
105
87
 
106
88
    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()
 
89
        conf = config.LocationConfig.from_string('# comment\n', '.', save=True)
119
90
 
120
91
        branch = self.make_branch('.', format='knit')
121
92
        branch.set_push_location('foo')
124
95
                             "[%s]\n"
125
96
                             "push_location = foo\n"
126
97
                             "push_location:policy = norecurse\n" % local_path,
127
 
                             fn)
 
98
                             config.locations_config_filename())
128
99
 
129
100
    # TODO RBC 20051029 test getting a push location from a branch in a
130
101
    # recursive section - that is, it appends the branch name.
131
102
 
132
103
 
133
 
class SampleBranchFormat(BranchFormat):
 
104
class SampleBranchFormat(_mod_branch.BranchFormat):
134
105
    """A sample format
135
106
 
136
 
    this format is initializable, unsupported to aid in testing the 
 
107
    this format is initializable, unsupported to aid in testing the
137
108
    open and open_downlevel routines.
138
109
    """
139
110
 
141
112
        """See BzrBranchFormat.get_format_string()."""
142
113
        return "Sample branch format."
143
114
 
144
 
    def initialize(self, a_bzrdir):
 
115
    def initialize(self, a_bzrdir, name=None, repository=None):
145
116
        """Format 4 branches cannot be created."""
146
 
        t = a_bzrdir.get_branch_transport(self)
 
117
        t = a_bzrdir.get_branch_transport(self, name=name)
147
118
        t.put_bytes('format', self.get_format_string())
148
119
        return 'A branch'
149
120
 
150
121
    def is_supported(self):
151
122
        return False
152
123
 
153
 
    def open(self, transport, _found=False):
 
124
    def open(self, transport, name=None, _found=False, ignore_fallbacks=False):
154
125
        return "opened branch."
155
126
 
156
127
 
157
 
class TestBzrBranchFormat(TestCaseWithTransport):
 
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):
158
168
    """Tests for the BzrBranchFormat facility."""
159
169
 
160
170
    def test_find_format(self):
161
171
        # is the right format object found for a branch?
162
172
        # create a branch with a few known format objects.
163
 
        # this is not quite the same as 
 
173
        # this is not quite the same as
164
174
        self.build_tree(["foo/", "bar/"])
165
175
        def check_format(format, url):
166
176
            dir = format._matchingbzrdir.initialize(url)
167
177
            dir.create_repository()
168
178
            format.initialize(dir)
169
 
            found_format = BranchFormat.find_format(dir)
170
 
            self.failUnless(isinstance(found_format, format.__class__))
171
 
        check_format(BzrBranchFormat5(), "bar")
172
 
        
 
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
 
173
194
    def test_find_format_not_branch(self):
174
195
        dir = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
175
 
        self.assertRaises(NotBranchError,
176
 
                          BranchFormat.find_format,
 
196
        self.assertRaises(errors.NotBranchError,
 
197
                          _mod_branch.BranchFormat.find_format,
177
198
                          dir)
178
199
 
179
200
    def test_find_format_unknown_format(self):
180
201
        dir = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
181
202
        SampleBranchFormat().initialize(dir)
182
 
        self.assertRaises(UnknownFormatError,
183
 
                          BranchFormat.find_format,
 
203
        self.assertRaises(errors.UnknownFormatError,
 
204
                          _mod_branch.BranchFormat.find_format,
184
205
                          dir)
185
206
 
186
207
    def test_register_unregister_format(self):
 
208
        # Test the deprecated format registration functions
187
209
        format = SampleBranchFormat()
188
210
        # make a control dir
189
211
        dir = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
190
212
        # make a branch
191
213
        format.initialize(dir)
192
214
        # register a format for it.
193
 
        BranchFormat.register_format(format)
 
215
        self.applyDeprecated(symbol_versioning.deprecated_in((2, 4, 0)),
 
216
            _mod_branch.BranchFormat.register_format, format)
194
217
        # which branch.Open will refuse (not supported)
195
 
        self.assertRaises(UnsupportedFormatError, Branch.open, self.get_url())
 
218
        self.assertRaises(errors.UnsupportedFormatError,
 
219
                          _mod_branch.Branch.open, self.get_url())
196
220
        self.make_branch_and_tree('foo')
197
221
        # but open_downlevel will work
198
 
        self.assertEqual(format.open(dir), bzrdir.BzrDir.open(self.get_url()).open_branch(unsupported=True))
 
222
        self.assertEqual(
 
223
            format.open(dir),
 
224
            bzrdir.BzrDir.open(self.get_url()).open_branch(unsupported=True))
199
225
        # unregister the format
200
 
        BranchFormat.unregister_format(format)
 
226
        self.applyDeprecated(symbol_versioning.deprecated_in((2, 4, 0)),
 
227
            _mod_branch.BranchFormat.unregister_format, format)
201
228
        self.make_branch_and_tree('bar')
202
229
 
203
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
 
204
301
class TestBranch67(object):
205
302
    """Common tests for both branch 6 and 7 which are mostly the same."""
206
303
 
214
311
        raise NotImplementedError(self.get_class)
215
312
 
216
313
    def test_creation(self):
217
 
        format = BzrDirMetaFormat1()
 
314
        format = bzrdir.BzrDirMetaFormat1()
218
315
        format.set_branch_format(_mod_branch.BzrBranchFormat6())
219
316
        branch = self.make_branch('a', format=format)
220
317
        self.assertIsInstance(branch, self.get_class())
225
322
 
226
323
    def test_layout(self):
227
324
        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')
 
325
        self.assertPathExists('a/.bzr/branch/last-revision')
 
326
        self.assertPathDoesNotExist('a/.bzr/branch/revision-history')
 
327
        self.assertPathDoesNotExist('a/.bzr/branch/references')
230
328
 
231
329
    def test_config(self):
232
330
        """Ensure that all configuration data is stored in the branch"""
233
331
        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')
 
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')
238
336
        config = branch.get_config()._get_branch_data_config()
239
 
        self.assertEqual('sftp://bazaar-vcs.org',
 
337
        self.assertEqual('sftp://example.com',
240
338
                         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())
 
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())
244
342
 
245
343
    def test_set_revision_history(self):
246
344
        builder = self.make_branch_builder('.', format=self.get_format_name())
251
349
        branch = builder.get_branch()
252
350
        branch.lock_write()
253
351
        self.addCleanup(branch.unlock)
254
 
        branch.set_revision_history(['foo', 'bar'])
255
 
        branch.set_revision_history(['foo'])
 
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'])
256
356
        self.assertRaises(errors.NotLefthandHistory,
257
 
                          branch.set_revision_history, ['bar'])
 
357
            self.applyDeprecated, symbol_versioning.deprecated_in((2, 4, 0)),
 
358
            branch.set_revision_history, ['bar'])
258
359
 
259
360
    def do_checkout_test(self, lightweight=False):
260
361
        tree = self.make_branch_and_tree('source',
273
374
        subtree.commit('a subtree file')
274
375
        subsubtree.commit('a subsubtree file')
275
376
        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')
 
377
        self.assertPathExists('target')
 
378
        self.assertPathExists('target/subtree')
 
379
        self.assertPathExists('target/subtree/file')
 
380
        self.assertPathExists('target/subtree/subsubtree/file')
280
381
        subbranch = _mod_branch.Branch.open('target/subtree/subsubtree')
281
382
        if lightweight:
282
383
            self.assertEndsWith(subbranch.base, 'source/subtree/subsubtree/')
306
407
                         'locations.conf')
307
408
 
308
409
 
309
 
class TestBranch6(TestBranch67, TestCaseWithTransport):
 
410
class TestBranch6(TestBranch67, tests.TestCaseWithTransport):
310
411
 
311
412
    def get_class(self):
312
413
        return _mod_branch.BzrBranch6
327
428
        self.assertRaises(errors.UnstackableBranchFormat, branch.get_stacked_on_url)
328
429
 
329
430
 
330
 
class TestBranch7(TestBranch67, TestCaseWithTransport):
 
431
class TestBranch7(TestBranch67, tests.TestCaseWithTransport):
331
432
 
332
433
    def get_class(self):
333
434
        return _mod_branch.BzrBranch7
334
435
 
335
436
    def get_format_name(self):
336
 
        return "development"
 
437
        return "1.9"
337
438
 
338
439
    def get_format_name_subtree(self):
339
440
        return "development-subtree"
377
478
        self.assertTrue(branch.repository.has_revision(revid))
378
479
 
379
480
 
380
 
class TestBranchReference(TestCaseWithTransport):
 
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):
381
544
    """Tests for the branch reference facility."""
382
545
 
383
546
    def test_create_open_reference(self):
384
547
        bzrdirformat = bzrdir.BzrDirMetaFormat1()
385
 
        t = get_transport(self.get_url('.'))
 
548
        t = self.get_transport()
386
549
        t.mkdir('repo')
387
550
        dir = bzrdirformat.initialize(self.get_url('repo'))
388
551
        dir.create_repository()
389
552
        target_branch = dir.create_branch()
390
553
        t.mkdir('branch')
391
554
        branch_dir = bzrdirformat.initialize(self.get_url('branch'))
392
 
        made_branch = BranchReferenceFormat().initialize(branch_dir, target_branch)
 
555
        made_branch = _mod_branch.BranchReferenceFormat().initialize(
 
556
            branch_dir, target_branch=target_branch)
393
557
        self.assertEqual(made_branch.base, target_branch.base)
394
558
        opened_branch = branch_dir.open_branch()
395
559
        self.assertEqual(opened_branch.base, target_branch.base)
406
570
            _mod_branch.BranchReferenceFormat().get_reference(checkout.bzrdir))
407
571
 
408
572
 
409
 
class TestHooks(TestCase):
 
573
class TestHooks(tests.TestCaseWithTransport):
410
574
 
411
575
    def test_constructor(self):
412
576
        """Check that creating a BranchHooks instance has the right defaults."""
413
 
        hooks = BranchHooks()
 
577
        hooks = _mod_branch.BranchHooks()
414
578
        self.assertTrue("set_rh" in hooks, "set_rh not in %s" % hooks)
415
579
        self.assertTrue("post_push" in hooks, "post_push not in %s" % hooks)
416
580
        self.assertTrue("post_commit" in hooks, "post_commit not in %s" % hooks)
417
581
        self.assertTrue("pre_commit" in hooks, "pre_commit not in %s" % hooks)
418
582
        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)
 
583
        self.assertTrue("post_uncommit" in hooks,
 
584
                        "post_uncommit not in %s" % hooks)
420
585
        self.assertTrue("post_change_branch_tip" in hooks,
421
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)
422
591
 
423
592
    def test_installed_hooks_are_BranchHooks(self):
424
593
        """The installed hooks object should be a BranchHooks."""
425
594
        # 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):
 
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):
430
682
 
431
683
    def test_pull_result_to_int(self):
432
684
        # to support old code, the pull result can be used as an int
433
 
        r = PullResult()
 
685
        r = _mod_branch.PullResult()
434
686
        r.old_revno = 10
435
687
        r.new_revno = 20
436
688
        # this usage of results is not recommended for new code (because it
437
689
        # doesn't describe very well what happened), but for api stability
438
690
        # it's still supported
439
 
        a = "%d revisions pulled" % r
440
 
        self.assertEqual(a, "10 revisions pulled")
 
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