/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
5557.1.7 by John Arbash Meinel
Merge in the bzr.dev 5582
1
# Copyright (C) 2006-2011 Canonical Ltd
1553.5.71 by Martin Pool
Change branch format 5 to use LockDirs, not transport locks
2
#
1534.4.3 by Robert Collins
Implement BranchTestProviderAdapter, so tests now run across all branch formats.
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.
1553.5.71 by Martin Pool
Change branch format 5 to use LockDirs, not transport locks
7
#
1534.4.3 by Robert Collins
Implement BranchTestProviderAdapter, so tests now run across all branch formats.
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.
1553.5.71 by Martin Pool
Change branch format 5 to use LockDirs, not transport locks
12
#
1534.4.3 by Robert Collins
Implement BranchTestProviderAdapter, so tests now run across all branch formats.
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
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1534.4.3 by Robert Collins
Implement BranchTestProviderAdapter, so tests now run across all branch formats.
16
17
"""Tests for the Branch facility that are not interface  tests.
18
4523.1.1 by Martin Pool
Rename tests.branch_implementations to per_branch
19
For interface tests see tests/per_branch/*.py.
1534.4.3 by Robert Collins
Implement BranchTestProviderAdapter, so tests now run across all branch formats.
20
21
For concrete class tests see this file, and for meta-branch tests
22
also see this file.
23
"""
24
5010.2.26 by Vincent Ladeuil
Fix imports in test_branch.py.
25
from cStringIO import StringIO
1534.4.3 by Robert Collins
Implement BranchTestProviderAdapter, so tests now run across all branch formats.
26
2230.3.3 by Aaron Bentley
Add more config testing
27
from bzrlib import (
28
    branch as _mod_branch,
2230.3.44 by Aaron Bentley
Change asserts to specific errors for left-hand history violations
29
    bzrdir,
1551.15.35 by Aaron Bentley
Warn when setting config values that will be masked (#122286)
30
    config,
2230.3.44 by Aaron Bentley
Change asserts to specific errors for left-hand history violations
31
    errors,
5348.1.2 by Martin Pool
Deprecate casting PushResult and PullResult to int to get the relative revno change
32
    symbol_versioning,
5010.2.26 by Vincent Ladeuil
Fix imports in test_branch.py.
33
    tests,
1551.15.35 by Aaron Bentley
Warn when setting config values that will be masked (#122286)
34
    trace,
2230.3.3 by Aaron Bentley
Add more config testing
35
    urlutils,
36
    )
1534.4.3 by Robert Collins
Implement BranchTestProviderAdapter, so tests now run across all branch formats.
37
5705.2.5 by Jelmer Vernooij
Make sure branch format 4 only works in BzrDirFormat6, not meta dirs.
38
from bzrlib.branch_weave import (
39
    BzrBranchFormat4,
40
    )
41
3445.2.1 by John Arbash Meinel
Add tests for Branch.missing_revisions and deprecate it.
42
5010.2.1 by Vincent Ladeuil
Fiux test/test_branch.py imports.
43
class TestDefaultFormat(tests.TestCase):
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
44
2696.3.1 by Martin Pool
(broken) start switching format to dirstate-tags
45
    def test_default_format(self):
46
        # update this if you change the default branch format
5662.2.2 by Jelmer Vernooij
Move most format registration functions to BranchFormatRegistry.
47
        self.assertIsInstance(_mod_branch.format_registry.get_default(),
5010.2.26 by Vincent Ladeuil
Fix imports in test_branch.py.
48
                _mod_branch.BzrBranchFormat7)
2696.3.1 by Martin Pool
(broken) start switching format to dirstate-tags
49
2696.3.3 by Martin Pool
Start setting the default format to dirstate-tags
50
    def test_default_format_is_same_as_bzrdir_default(self):
51
        # XXX: it might be nice if there was only one place the default was
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
52
        # set, but at the moment that's not true -- mbp 20070814 --
2696.3.8 by Martin Pool
doc
53
        # https://bugs.launchpad.net/bzr/+bug/132376
5010.2.26 by Vincent Ladeuil
Fix imports in test_branch.py.
54
        self.assertEqual(
5662.2.2 by Jelmer Vernooij
Move most format registration functions to BranchFormatRegistry.
55
            _mod_branch.format_registry.get_default(),
5010.2.26 by Vincent Ladeuil
Fix imports in test_branch.py.
56
            bzrdir.BzrDirFormat.get_default_format().get_branch_format())
2696.3.3 by Martin Pool
Start setting the default format to dirstate-tags
57
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
58
    def test_get_set_default_format(self):
2696.3.1 by Martin Pool
(broken) start switching format to dirstate-tags
59
        # set the format and then set it back again
5662.2.2 by Jelmer Vernooij
Move most format registration functions to BranchFormatRegistry.
60
        old_format = _mod_branch.format_registry.get_default()
5662.2.6 by Jelmer Vernooij
add more tests.
61
        _mod_branch.format_registry.set_default(SampleBranchFormat())
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
62
        try:
63
            # the default branch format is used by the meta dir format
64
            # which is not the default bzrdir format at this point
5010.2.26 by Vincent Ladeuil
Fix imports in test_branch.py.
65
            dir = bzrdir.BzrDirMetaFormat1().initialize('memory:///')
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
66
            result = dir.create_branch()
67
            self.assertEqual(result, 'A branch')
68
        finally:
5662.2.6 by Jelmer Vernooij
add more tests.
69
            _mod_branch.format_registry.set_default(old_format)
5010.2.26 by Vincent Ladeuil
Fix imports in test_branch.py.
70
        self.assertEqual(old_format,
5662.2.2 by Jelmer Vernooij
Move most format registration functions to BranchFormatRegistry.
71
                         _mod_branch.format_registry.get_default())
1508.1.25 by Robert Collins
Update per review comments.
72
73
5705.2.5 by Jelmer Vernooij
Make sure branch format 4 only works in BzrDirFormat6, not meta dirs.
74
class TestBranchFormat4(tests.TestCaseWithTransport):
75
    """Tests specific to branch format 4"""
76
77
    def test_no_metadir_support(self):
78
        url = self.get_url()
79
        bdir = bzrdir.BzrDirMetaFormat1().initialize(url)
80
        bdir.create_repository()
81
        self.assertRaises(errors.IncompatibleFormat,
82
            BzrBranchFormat4().initialize, bdir)
83
84
    def test_supports_bzrdir_6(self):
85
        url = self.get_url()
86
        bdir = bzrdir.BzrDirFormat6().initialize(url)
87
        bdir.create_repository()
88
        BzrBranchFormat4().initialize(bdir)
89
90
5010.2.1 by Vincent Ladeuil
Fiux test/test_branch.py imports.
91
class TestBranchFormat5(tests.TestCaseWithTransport):
1553.5.71 by Martin Pool
Change branch format 5 to use LockDirs, not transport locks
92
    """Tests specific to branch format 5"""
93
94
    def test_branch_format_5_uses_lockdir(self):
95
        url = self.get_url()
5010.2.26 by Vincent Ladeuil
Fix imports in test_branch.py.
96
        bdir = bzrdir.BzrDirMetaFormat1().initialize(url)
97
        bdir.create_repository()
98
        branch = bdir.create_branch()
1553.5.72 by Martin Pool
Clean up test for Branch5 lockdirs
99
        t = self.get_transport()
100
        self.log("branch instance is %r" % branch)
5010.2.26 by Vincent Ladeuil
Fix imports in test_branch.py.
101
        self.assert_(isinstance(branch, _mod_branch.BzrBranch5))
1553.5.72 by Martin Pool
Clean up test for Branch5 lockdirs
102
        self.assertIsDirectory('.', t)
103
        self.assertIsDirectory('.bzr/branch', t)
104
        self.assertIsDirectory('.bzr/branch/lock', t)
1553.5.73 by Martin Pool
Additional test that Branch5 uses lockdir properly
105
        branch.lock_write()
5010.2.26 by Vincent Ladeuil
Fix imports in test_branch.py.
106
        self.addCleanup(branch.unlock)
107
        self.assertIsDirectory('.bzr/branch/lock/held', t)
1553.5.71 by Martin Pool
Change branch format 5 to use LockDirs, not transport locks
108
2230.3.3 by Aaron Bentley
Add more config testing
109
    def test_set_push_location(self):
5345.1.26 by Vincent Ladeuil
Merge lockable-config-files into remove-gratuitous-ensure-config-dir-exist-calls resolving conflicts
110
        conf = config.LocationConfig.from_string('# comment\n', '.', save=True)
2839.3.1 by Alexander Belchenko
provide non-empty locations.conf for test_branch.TestBranchFormat5.test_set_push_location
111
2230.3.3 by Aaron Bentley
Add more config testing
112
        branch = self.make_branch('.', format='knit')
113
        branch.set_push_location('foo')
114
        local_path = urlutils.local_path_from_url(branch.base[:-1])
2839.3.1 by Alexander Belchenko
provide non-empty locations.conf for test_branch.TestBranchFormat5.test_set_push_location
115
        self.assertFileEqual("# comment\n"
116
                             "[%s]\n"
2230.3.3 by Aaron Bentley
Add more config testing
117
                             "push_location = foo\n"
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
118
                             "push_location:policy = norecurse\n" % local_path,
5345.1.11 by Vincent Ladeuil
Cleanup bt.test_branch.
119
                             config.locations_config_filename())
2230.3.3 by Aaron Bentley
Add more config testing
120
2230.3.12 by Aaron Bentley
Clean up trailing whitespace
121
    # TODO RBC 20051029 test getting a push location from a branch in a
2230.3.3 by Aaron Bentley
Add more config testing
122
    # recursive section - that is, it appends the branch name.
123
1553.5.71 by Martin Pool
Change branch format 5 to use LockDirs, not transport locks
124
5010.2.26 by Vincent Ladeuil
Fix imports in test_branch.py.
125
class SampleBranchFormat(_mod_branch.BranchFormat):
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
126
    """A sample format
127
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
128
    this format is initializable, unsupported to aid in testing the
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
129
    open and open_downlevel routines.
130
    """
131
132
    def get_format_string(self):
133
        """See BzrBranchFormat.get_format_string()."""
134
        return "Sample branch format."
135
5535.3.19 by Andrew Bennetts
Fix a test failure.
136
    def initialize(self, a_bzrdir, name=None, repository=None):
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
137
        """Format 4 branches cannot be created."""
5051.3.10 by Jelmer Vernooij
Pass colocated branch name around in more places.
138
        t = a_bzrdir.get_branch_transport(self, name=name)
1955.3.9 by John Arbash Meinel
Find more occurrances of put() and replace with put_file or put_bytes
139
        t.put_bytes('format', self.get_format_string())
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
140
        return 'A branch'
141
142
    def is_supported(self):
143
        return False
144
5051.3.16 by Jelmer Vernooij
Fix tests - missing argument.
145
    def open(self, transport, name=None, _found=False, ignore_fallbacks=False):
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
146
        return "opened branch."
147
148
5305.1.2 by Robert Collins
More clarity about how to use the lazy registration feature.
149
# Demonstrating how lazy loading is often implemented:
150
# A constant string is created.
151
SampleSupportedBranchFormatString = "Sample supported branch format."
152
153
# And the format class can then reference the constant to avoid skew.
5305.1.1 by Robert Collins
``Branch`` formats can now be loaded lazily by registering a
154
class SampleSupportedBranchFormat(_mod_branch.BranchFormat):
155
    """A sample supported format."""
156
157
    def get_format_string(self):
158
        """See BzrBranchFormat.get_format_string()."""
5305.1.2 by Robert Collins
More clarity about how to use the lazy registration feature.
159
        return SampleSupportedBranchFormatString
5305.1.1 by Robert Collins
``Branch`` formats can now be loaded lazily by registering a
160
161
    def initialize(self, a_bzrdir, name=None):
162
        t = a_bzrdir.get_branch_transport(self, name=name)
163
        t.put_bytes('format', self.get_format_string())
164
        return 'A branch'
165
166
    def open(self, transport, name=None, _found=False, ignore_fallbacks=False):
167
        return "opened supported branch."
168
169
5642.2.1 by Jelmer Vernooij
Allow the registration of non-metadir branch formats.
170
class SampleExtraBranchFormat(_mod_branch.BranchFormat):
171
    """A sample format that is not usable in a metadir."""
172
173
    def get_format_string(self):
174
        # This format is not usable in a metadir.
175
        return None
176
177
    def network_name(self):
178
        # Network name always has to be provided.
179
        return "extra"
180
181
    def initialize(self, a_bzrdir, name=None):
182
        raise NotImplementedError(self.initialize)
183
184
    def open(self, transport, name=None, _found=False, ignore_fallbacks=False):
185
        raise NotImplementedError(self.open)
186
187
5010.2.1 by Vincent Ladeuil
Fiux test/test_branch.py imports.
188
class TestBzrBranchFormat(tests.TestCaseWithTransport):
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
189
    """Tests for the BzrBranchFormat facility."""
190
191
    def test_find_format(self):
192
        # is the right format object found for a branch?
193
        # create a branch with a few known format objects.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
194
        # this is not quite the same as
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
195
        self.build_tree(["foo/", "bar/"])
196
        def check_format(format, url):
197
            dir = format._matchingbzrdir.initialize(url)
1534.4.47 by Robert Collins
Split out repository into .bzr/repository
198
            dir.create_repository()
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
199
            format.initialize(dir)
5010.2.26 by Vincent Ladeuil
Fix imports in test_branch.py.
200
            found_format = _mod_branch.BranchFormat.find_format(dir)
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
201
            self.failUnless(isinstance(found_format, format.__class__))
5010.2.26 by Vincent Ladeuil
Fix imports in test_branch.py.
202
        check_format(_mod_branch.BzrBranchFormat5(), "bar")
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
203
5305.1.1 by Robert Collins
``Branch`` formats can now be loaded lazily by registering a
204
    def test_find_format_factory(self):
205
        dir = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
206
        SampleSupportedBranchFormat().initialize(dir)
207
        factory = _mod_branch.MetaDirBranchFormatFactory(
5305.1.2 by Robert Collins
More clarity about how to use the lazy registration feature.
208
            SampleSupportedBranchFormatString,
5305.1.1 by Robert Collins
``Branch`` formats can now be loaded lazily by registering a
209
            "bzrlib.tests.test_branch", "SampleSupportedBranchFormat")
5662.2.6 by Jelmer Vernooij
add more tests.
210
        _mod_branch.format_registry.register(factory)
211
        self.addCleanup(_mod_branch.format_registry.remove, factory)
5305.1.1 by Robert Collins
``Branch`` formats can now be loaded lazily by registering a
212
        b = _mod_branch.Branch.open(self.get_url())
213
        self.assertEqual(b, "opened supported branch.")
214
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
215
    def test_find_format_not_branch(self):
216
        dir = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
5010.2.1 by Vincent Ladeuil
Fiux test/test_branch.py imports.
217
        self.assertRaises(errors.NotBranchError,
5010.2.26 by Vincent Ladeuil
Fix imports in test_branch.py.
218
                          _mod_branch.BranchFormat.find_format,
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
219
                          dir)
220
221
    def test_find_format_unknown_format(self):
222
        dir = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
223
        SampleBranchFormat().initialize(dir)
5010.2.1 by Vincent Ladeuil
Fiux test/test_branch.py imports.
224
        self.assertRaises(errors.UnknownFormatError,
5010.2.26 by Vincent Ladeuil
Fix imports in test_branch.py.
225
                          _mod_branch.BranchFormat.find_format,
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
226
                          dir)
227
228
    def test_register_unregister_format(self):
5662.2.6 by Jelmer Vernooij
add more tests.
229
        # Test the deprecated format registration functions
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
230
        format = SampleBranchFormat()
231
        # make a control dir
232
        dir = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
233
        # make a branch
234
        format.initialize(dir)
235
        # register a format for it.
5662.2.6 by Jelmer Vernooij
add more tests.
236
        self.applyDeprecated(symbol_versioning.deprecated_in((2, 4, 0)),
237
            _mod_branch.BranchFormat.register_format, format)
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
238
        # which branch.Open will refuse (not supported)
5010.2.1 by Vincent Ladeuil
Fiux test/test_branch.py imports.
239
        self.assertRaises(errors.UnsupportedFormatError,
5010.2.26 by Vincent Ladeuil
Fix imports in test_branch.py.
240
                          _mod_branch.Branch.open, self.get_url())
2230.3.22 by Aaron Bentley
Make test suite use format registry default, not BzrDir default
241
        self.make_branch_and_tree('foo')
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
242
        # but open_downlevel will work
5010.2.1 by Vincent Ladeuil
Fiux test/test_branch.py imports.
243
        self.assertEqual(
244
            format.open(dir),
245
            bzrdir.BzrDir.open(self.get_url()).open_branch(unsupported=True))
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
246
        # unregister the format
5662.2.6 by Jelmer Vernooij
add more tests.
247
        self.applyDeprecated(symbol_versioning.deprecated_in((2, 4, 0)),
248
            _mod_branch.BranchFormat.unregister_format, format)
2230.3.22 by Aaron Bentley
Make test suite use format registry default, not BzrDir default
249
        self.make_branch_and_tree('bar')
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
250
251
5662.2.6 by Jelmer Vernooij
add more tests.
252
class TestBranchFormatRegistry(tests.TestCase):
253
254
    def setUp(self):
255
        super(TestBranchFormatRegistry, self).setUp()
256
        self.registry = _mod_branch.BranchFormatRegistry()
257
258
    def test_default(self):
259
        self.assertIs(None, self.registry.get_default())
260
        format = SampleBranchFormat()
261
        self.registry.set_default(format)
262
        self.assertEquals(format, self.registry.get_default())
263
264
    def test_register_unregister_format(self):
265
        format = SampleBranchFormat()
266
        self.registry.register(format)
267
        self.assertEquals(format,
268
            self.registry.get("Sample branch format."))
269
        self.registry.remove(format)
270
        self.assertRaises(KeyError, self.registry.get,
271
            "Sample branch format.")
272
273
    def test_get_all(self):
274
        format = SampleBranchFormat()
275
        self.assertEquals([], self.registry._get_all())
276
        self.registry.register(format)
277
        self.assertEquals([format], self.registry._get_all())
278
279
    def test_register_extra(self):
280
        format = SampleExtraBranchFormat()
281
        self.assertEquals([], self.registry._get_all())
282
        self.registry.register_extra(format)
283
        self.assertEquals([format], self.registry._get_all())
284
285
    def test_register_extra_lazy(self):
286
        self.assertEquals([], self.registry._get_all())
287
        self.registry.register_extra_lazy("bzrlib.tests.test_branch",
288
            "SampleExtraBranchFormat")
289
        formats = self.registry._get_all()
290
        self.assertEquals(1, len(formats))
291
        self.assertIsInstance(formats[0], SampleExtraBranchFormat)
292
293
5305.1.1 by Robert Collins
``Branch`` formats can now be loaded lazily by registering a
294
#Used by TestMetaDirBranchFormatFactory 
295
FakeLazyFormat = None
296
297
298
class TestMetaDirBranchFormatFactory(tests.TestCase):
299
300
    def test_get_format_string_does_not_load(self):
301
        """Formats have a static format string."""
302
        factory = _mod_branch.MetaDirBranchFormatFactory("yo", None, None)
303
        self.assertEqual("yo", factory.get_format_string())
304
305
    def test_call_loads(self):
306
        # __call__ is used by the network_format_registry interface to get a
307
        # Format.
308
        global FakeLazyFormat
309
        del FakeLazyFormat
310
        factory = _mod_branch.MetaDirBranchFormatFactory(None,
311
            "bzrlib.tests.test_branch", "FakeLazyFormat")
312
        self.assertRaises(AttributeError, factory)
313
314
    def test_call_returns_call_of_referenced_object(self):
315
        global FakeLazyFormat
316
        FakeLazyFormat = lambda:'called'
317
        factory = _mod_branch.MetaDirBranchFormatFactory(None,
318
            "bzrlib.tests.test_branch", "FakeLazyFormat")
319
        self.assertEqual('called', factory())
320
321
3221.11.2 by Robert Collins
Create basic stackable branch facility.
322
class TestBranch67(object):
323
    """Common tests for both branch 6 and 7 which are mostly the same."""
324
325
    def get_format_name(self):
326
        raise NotImplementedError(self.get_format_name)
327
328
    def get_format_name_subtree(self):
329
        raise NotImplementedError(self.get_format_name)
330
331
    def get_class(self):
332
        raise NotImplementedError(self.get_class)
2230.3.1 by Aaron Bentley
Get branch6 creation working
333
334
    def test_creation(self):
5010.2.26 by Vincent Ladeuil
Fix imports in test_branch.py.
335
        format = bzrdir.BzrDirMetaFormat1()
2230.3.55 by Aaron Bentley
Updates from review
336
        format.set_branch_format(_mod_branch.BzrBranchFormat6())
2230.3.1 by Aaron Bentley
Get branch6 creation working
337
        branch = self.make_branch('a', format=format)
3221.11.2 by Robert Collins
Create basic stackable branch facility.
338
        self.assertIsInstance(branch, self.get_class())
339
        branch = self.make_branch('b', format=self.get_format_name())
340
        self.assertIsInstance(branch, self.get_class())
2230.3.1 by Aaron Bentley
Get branch6 creation working
341
        branch = _mod_branch.Branch.open('a')
3221.11.2 by Robert Collins
Create basic stackable branch facility.
342
        self.assertIsInstance(branch, self.get_class())
2230.3.1 by Aaron Bentley
Get branch6 creation working
343
344
    def test_layout(self):
3221.11.2 by Robert Collins
Create basic stackable branch facility.
345
        branch = self.make_branch('a', format=self.get_format_name())
2230.3.1 by Aaron Bentley
Get branch6 creation working
346
        self.failUnlessExists('a/.bzr/branch/last-revision')
347
        self.failIfExists('a/.bzr/branch/revision-history')
4273.1.12 by Aaron Bentley
Don't create reference files for older formats.
348
        self.failIfExists('a/.bzr/branch/references')
2230.3.1 by Aaron Bentley
Get branch6 creation working
349
2230.3.3 by Aaron Bentley
Add more config testing
350
    def test_config(self):
351
        """Ensure that all configuration data is stored in the branch"""
3221.11.2 by Robert Collins
Create basic stackable branch facility.
352
        branch = self.make_branch('a', format=self.get_format_name())
5560.2.1 by Vincent Ladeuil
Fix the remaining references to http://bazaar-vcs.org (except the explicitly historical ones).
353
        branch.set_parent('http://example.com')
2230.3.3 by Aaron Bentley
Add more config testing
354
        self.failIfExists('a/.bzr/branch/parent')
5560.2.1 by Vincent Ladeuil
Fix the remaining references to http://bazaar-vcs.org (except the explicitly historical ones).
355
        self.assertEqual('http://example.com', branch.get_parent())
356
        branch.set_push_location('sftp://example.com')
2230.3.3 by Aaron Bentley
Add more config testing
357
        config = branch.get_config()._get_branch_data_config()
5560.2.1 by Vincent Ladeuil
Fix the remaining references to http://bazaar-vcs.org (except the explicitly historical ones).
358
        self.assertEqual('sftp://example.com',
2230.3.3 by Aaron Bentley
Add more config testing
359
                         config.get_user_option('push_location'))
5560.2.1 by Vincent Ladeuil
Fix the remaining references to http://bazaar-vcs.org (except the explicitly historical ones).
360
        branch.set_bound_location('ftp://example.com')
2230.3.3 by Aaron Bentley
Add more config testing
361
        self.failIfExists('a/.bzr/branch/bound')
5560.2.1 by Vincent Ladeuil
Fix the remaining references to http://bazaar-vcs.org (except the explicitly historical ones).
362
        self.assertEqual('ftp://example.com', branch.get_bound_location())
2230.3.3 by Aaron Bentley
Add more config testing
363
2230.3.44 by Aaron Bentley
Change asserts to specific errors for left-hand history violations
364
    def test_set_revision_history(self):
3567.4.16 by John Arbash Meinel
Use the new BranchBuilder api in a Branch test
365
        builder = self.make_branch_builder('.', format=self.get_format_name())
366
        builder.build_snapshot('foo', None,
367
            [('add', ('', None, 'directory', None))],
368
            message='foo')
369
        builder.build_snapshot('bar', None, [], message='bar')
370
        branch = builder.get_branch()
371
        branch.lock_write()
372
        self.addCleanup(branch.unlock)
373
        branch.set_revision_history(['foo', 'bar'])
374
        branch.set_revision_history(['foo'])
375
        self.assertRaises(errors.NotLefthandHistory,
376
                          branch.set_revision_history, ['bar'])
2230.3.44 by Aaron Bentley
Change asserts to specific errors for left-hand history violations
377
2100.3.26 by Aaron Bentley
checkout type is maintained for subtrees
378
    def do_checkout_test(self, lightweight=False):
3221.11.2 by Robert Collins
Create basic stackable branch facility.
379
        tree = self.make_branch_and_tree('source',
380
            format=self.get_format_name_subtree())
2255.2.194 by Robert Collins
[BROKEN] Many updates to stop using experimental formats in tests.
381
        subtree = self.make_branch_and_tree('source/subtree',
3221.11.2 by Robert Collins
Create basic stackable branch facility.
382
            format=self.get_format_name_subtree())
2100.3.25 by Aaron Bentley
add subsubtree to test
383
        subsubtree = self.make_branch_and_tree('source/subtree/subsubtree',
3221.11.2 by Robert Collins
Create basic stackable branch facility.
384
            format=self.get_format_name_subtree())
2100.3.25 by Aaron Bentley
add subsubtree to test
385
        self.build_tree(['source/subtree/file',
386
                         'source/subtree/subsubtree/file'])
387
        subsubtree.add('file')
2100.3.21 by Aaron Bentley
Work on checking out by-reference trees
388
        subtree.add('file')
2100.3.25 by Aaron Bentley
add subsubtree to test
389
        subtree.add_reference(subsubtree)
2100.3.21 by Aaron Bentley
Work on checking out by-reference trees
390
        tree.add_reference(subtree)
391
        tree.commit('a revision')
2100.3.23 by Aaron Bentley
Nested checkouts kinda work
392
        subtree.commit('a subtree file')
2100.3.25 by Aaron Bentley
add subsubtree to test
393
        subsubtree.commit('a subsubtree file')
2100.3.26 by Aaron Bentley
checkout type is maintained for subtrees
394
        tree.branch.create_checkout('target', lightweight=lightweight)
2100.3.21 by Aaron Bentley
Work on checking out by-reference trees
395
        self.failUnlessExists('target')
396
        self.failUnlessExists('target/subtree')
397
        self.failUnlessExists('target/subtree/file')
2100.3.25 by Aaron Bentley
add subsubtree to test
398
        self.failUnlessExists('target/subtree/subsubtree/file')
2100.3.31 by Aaron Bentley
Merged bzr.dev (17 tests failing)
399
        subbranch = _mod_branch.Branch.open('target/subtree/subsubtree')
2100.3.26 by Aaron Bentley
checkout type is maintained for subtrees
400
        if lightweight:
401
            self.assertEndsWith(subbranch.base, 'source/subtree/subsubtree/')
402
        else:
403
            self.assertEndsWith(subbranch.base, 'target/subtree/subsubtree/')
404
405
    def test_checkout_with_references(self):
406
        self.do_checkout_test()
407
408
    def test_light_checkout_with_references(self):
409
        self.do_checkout_test(lightweight=True)
2230.3.51 by Aaron Bentley
Store revno for Branch6, set_last_revision -> set_last_revision_info
410
1551.15.35 by Aaron Bentley
Warn when setting config values that will be masked (#122286)
411
    def test_set_push(self):
3221.11.2 by Robert Collins
Create basic stackable branch facility.
412
        branch = self.make_branch('source', format=self.get_format_name())
1551.15.35 by Aaron Bentley
Warn when setting config values that will be masked (#122286)
413
        branch.get_config().set_user_option('push_location', 'old',
414
            store=config.STORE_LOCATION)
415
        warnings = []
416
        def warning(*args):
417
            warnings.append(args[0] % args[1:])
418
        _warning = trace.warning
419
        trace.warning = warning
420
        try:
421
            branch.set_push_location('new')
422
        finally:
423
            trace.warning = _warning
424
        self.assertEqual(warnings[0], 'Value "new" is masked by "old" from '
425
                         'locations.conf')
426
3445.2.1 by John Arbash Meinel
Add tests for Branch.missing_revisions and deprecate it.
427
5010.2.1 by Vincent Ladeuil
Fiux test/test_branch.py imports.
428
class TestBranch6(TestBranch67, tests.TestCaseWithTransport):
3221.11.2 by Robert Collins
Create basic stackable branch facility.
429
430
    def get_class(self):
431
        return _mod_branch.BzrBranch6
432
433
    def get_format_name(self):
434
        return "dirstate-tags"
435
436
    def get_format_name_subtree(self):
437
        return "dirstate-with-subtree"
438
3537.3.3 by Martin Pool
Rename Branch.set_stacked_on to set_stacked_on_url
439
    def test_set_stacked_on_url_errors(self):
3221.11.2 by Robert Collins
Create basic stackable branch facility.
440
        branch = self.make_branch('a', format=self.get_format_name())
441
        self.assertRaises(errors.UnstackableBranchFormat,
3537.3.3 by Martin Pool
Rename Branch.set_stacked_on to set_stacked_on_url
442
            branch.set_stacked_on_url, None)
3221.11.2 by Robert Collins
Create basic stackable branch facility.
443
444
    def test_default_stacked_location(self):
445
        branch = self.make_branch('a', format=self.get_format_name())
3537.3.1 by Martin Pool
Rename branch.get_stacked_on to get_stacked_on_url
446
        self.assertRaises(errors.UnstackableBranchFormat, branch.get_stacked_on_url)
3221.11.2 by Robert Collins
Create basic stackable branch facility.
447
448
5010.2.1 by Vincent Ladeuil
Fiux test/test_branch.py imports.
449
class TestBranch7(TestBranch67, tests.TestCaseWithTransport):
3221.11.2 by Robert Collins
Create basic stackable branch facility.
450
451
    def get_class(self):
452
        return _mod_branch.BzrBranch7
453
454
    def get_format_name(self):
4241.6.8 by Robert Collins, John Arbash Meinel, Ian Clatworthy, Vincent Ladeuil
Add --development6-rich-root, disabling the legacy and unneeded development2 format, and activating the tests for CHK features disabled pending this format. (Robert Collins, John Arbash Meinel, Ian Clatworthy, Vincent Ladeuil)
455
        return "1.9"
3221.11.2 by Robert Collins
Create basic stackable branch facility.
456
457
    def get_format_name_subtree(self):
458
        return "development-subtree"
459
3537.3.3 by Martin Pool
Rename Branch.set_stacked_on to set_stacked_on_url
460
    def test_set_stacked_on_url_unstackable_repo(self):
3221.11.6 by Robert Collins
Stackable branch fixes.
461
        repo = self.make_repository('a', format='dirstate-tags')
462
        control = repo.bzrdir
463
        branch = _mod_branch.BzrBranchFormat7().initialize(control)
3221.11.2 by Robert Collins
Create basic stackable branch facility.
464
        target = self.make_branch('b')
465
        self.assertRaises(errors.UnstackableRepositoryFormat,
3537.3.3 by Martin Pool
Rename Branch.set_stacked_on to set_stacked_on_url
466
            branch.set_stacked_on_url, target.base)
3221.11.2 by Robert Collins
Create basic stackable branch facility.
467
3242.3.21 by Jonathan Lange
Preserve stacking in clone
468
    def test_clone_stacked_on_unstackable_repo(self):
469
        repo = self.make_repository('a', format='dirstate-tags')
470
        control = repo.bzrdir
471
        branch = _mod_branch.BzrBranchFormat7().initialize(control)
472
        # Calling clone should not raise UnstackableRepositoryFormat.
473
        cloned_bzrdir = control.clone('cloned')
474
3221.11.2 by Robert Collins
Create basic stackable branch facility.
475
    def _test_default_stacked_location(self):
476
        branch = self.make_branch('a', format=self.get_format_name())
3537.3.1 by Martin Pool
Rename branch.get_stacked_on to get_stacked_on_url
477
        self.assertRaises(errors.NotStacked, branch.get_stacked_on_url)
3221.11.2 by Robert Collins
Create basic stackable branch facility.
478
3221.11.8 by Robert Collins
Minimally test stacking and unstacking a repository.
479
    def test_stack_and_unstack(self):
480
        branch = self.make_branch('a', format=self.get_format_name())
3221.11.10 by Robert Collins
Extend set_stacked_on to update the repository with the right external references.
481
        target = self.make_branch_and_tree('b', format=self.get_format_name())
3537.3.3 by Martin Pool
Rename Branch.set_stacked_on to set_stacked_on_url
482
        branch.set_stacked_on_url(target.branch.base)
3537.3.1 by Martin Pool
Rename branch.get_stacked_on to get_stacked_on_url
483
        self.assertEqual(target.branch.base, branch.get_stacked_on_url())
3221.11.10 by Robert Collins
Extend set_stacked_on to update the repository with the right external references.
484
        revid = target.commit('foo')
485
        self.assertTrue(branch.repository.has_revision(revid))
3537.3.3 by Martin Pool
Rename Branch.set_stacked_on to set_stacked_on_url
486
        branch.set_stacked_on_url(None)
3537.3.1 by Martin Pool
Rename branch.get_stacked_on to get_stacked_on_url
487
        self.assertRaises(errors.NotStacked, branch.get_stacked_on_url)
3221.11.10 by Robert Collins
Extend set_stacked_on to update the repository with the right external references.
488
        self.assertFalse(branch.repository.has_revision(revid))
3221.11.8 by Robert Collins
Minimally test stacking and unstacking a repository.
489
3221.11.11 by Robert Collins
Ensure opening a stacked branch gives a ready to use repository.
490
    def test_open_opens_stacked_reference(self):
491
        branch = self.make_branch('a', format=self.get_format_name())
492
        target = self.make_branch_and_tree('b', format=self.get_format_name())
3537.3.3 by Martin Pool
Rename Branch.set_stacked_on to set_stacked_on_url
493
        branch.set_stacked_on_url(target.branch.base)
3221.11.11 by Robert Collins
Ensure opening a stacked branch gives a ready to use repository.
494
        branch = branch.bzrdir.open_branch()
495
        revid = target.commit('foo')
496
        self.assertTrue(branch.repository.has_revision(revid))
497
3221.11.2 by Robert Collins
Create basic stackable branch facility.
498
5010.2.1 by Vincent Ladeuil
Fiux test/test_branch.py imports.
499
class BzrBranch8(tests.TestCaseWithTransport):
4273.1.15 by Aaron Bentley
Add reference_info caching.
500
501
    def make_branch(self, location, format=None):
502
        if format is None:
503
            format = bzrdir.format_registry.make_bzrdir('1.9')
504
            format.set_branch_format(_mod_branch.BzrBranchFormat8())
5010.2.1 by Vincent Ladeuil
Fiux test/test_branch.py imports.
505
        return tests.TestCaseWithTransport.make_branch(
506
            self, location, format=format)
4273.1.15 by Aaron Bentley
Add reference_info caching.
507
508
    def create_branch_with_reference(self):
509
        branch = self.make_branch('branch')
510
        branch._set_all_reference_info({'file-id': ('path', 'location')})
511
        return branch
512
513
    @staticmethod
514
    def instrument_branch(branch, gets):
515
        old_get = branch._transport.get
516
        def get(*args, **kwargs):
517
            gets.append((args, kwargs))
518
            return old_get(*args, **kwargs)
519
        branch._transport.get = get
520
521
    def test_reference_info_caching_read_locked(self):
522
        gets = []
523
        branch = self.create_branch_with_reference()
524
        branch.lock_read()
525
        self.addCleanup(branch.unlock)
526
        self.instrument_branch(branch, gets)
527
        branch.get_reference_info('file-id')
528
        branch.get_reference_info('file-id')
529
        self.assertEqual(1, len(gets))
530
531
    def test_reference_info_caching_read_unlocked(self):
532
        gets = []
533
        branch = self.create_branch_with_reference()
534
        self.instrument_branch(branch, gets)
535
        branch.get_reference_info('file-id')
536
        branch.get_reference_info('file-id')
537
        self.assertEqual(2, len(gets))
538
539
    def test_reference_info_caching_write_locked(self):
540
        gets = []
541
        branch = self.make_branch('branch')
542
        branch.lock_write()
543
        self.instrument_branch(branch, gets)
544
        self.addCleanup(branch.unlock)
545
        branch._set_all_reference_info({'file-id': ('path2', 'location2')})
546
        path, location = branch.get_reference_info('file-id')
547
        self.assertEqual(0, len(gets))
548
        self.assertEqual('path2', path)
549
        self.assertEqual('location2', location)
550
551
    def test_reference_info_caches_cleared(self):
552
        branch = self.make_branch('branch')
553
        branch.lock_write()
554
        branch.set_reference_info('file-id', 'path2', 'location2')
555
        branch.unlock()
5010.2.26 by Vincent Ladeuil
Fix imports in test_branch.py.
556
        doppelganger = _mod_branch.Branch.open('branch')
4273.1.15 by Aaron Bentley
Add reference_info caching.
557
        doppelganger.set_reference_info('file-id', 'path3', 'location3')
558
        self.assertEqual(('path3', 'location3'),
559
                         branch.get_reference_info('file-id'))
560
5010.2.1 by Vincent Ladeuil
Fiux test/test_branch.py imports.
561
class TestBranchReference(tests.TestCaseWithTransport):
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
562
    """Tests for the branch reference facility."""
563
564
    def test_create_open_reference(self):
565
        bzrdirformat = bzrdir.BzrDirMetaFormat1()
5609.9.4 by Vincent Ladeuil
Use self.get_transport instead of transport.get_transport where possible.
566
        t = self.get_transport()
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
567
        t.mkdir('repo')
568
        dir = bzrdirformat.initialize(self.get_url('repo'))
569
        dir.create_repository()
570
        target_branch = dir.create_branch()
571
        t.mkdir('branch')
572
        branch_dir = bzrdirformat.initialize(self.get_url('branch'))
5010.2.26 by Vincent Ladeuil
Fix imports in test_branch.py.
573
        made_branch = _mod_branch.BranchReferenceFormat().initialize(
5051.3.10 by Jelmer Vernooij
Pass colocated branch name around in more places.
574
            branch_dir, target_branch=target_branch)
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
575
        self.assertEqual(made_branch.base, target_branch.base)
576
        opened_branch = branch_dir.open_branch()
577
        self.assertEqual(opened_branch.base, target_branch.base)
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
578
579
    def test_get_reference(self):
580
        """For a BranchReference, get_reference should reutrn the location."""
581
        branch = self.make_branch('target')
582
        checkout = branch.create_checkout('checkout', lightweight=True)
583
        reference_url = branch.bzrdir.root_transport.abspath('') + '/'
584
        # if the api for create_checkout changes to return different checkout types
585
        # then this file read will fail.
586
        self.assertFileEqual(reference_url, 'checkout/.bzr/branch/location')
587
        self.assertEqual(reference_url,
2018.5.97 by Andrew Bennetts
Fix more tests.
588
            _mod_branch.BranchReferenceFormat().get_reference(checkout.bzrdir))
2018.5.45 by Andrew Bennetts
Merge from bzr.dev
589
2245.1.1 by Robert Collins
New Branch hooks facility, with one initial hook 'set_rh' which triggers
590
5107.3.1 by Marco Pantaleoni
Added the new hooks 'post_branch', 'post_switch' and 'post_repo_init',
591
class TestHooks(tests.TestCaseWithTransport):
2245.1.1 by Robert Collins
New Branch hooks facility, with one initial hook 'set_rh' which triggers
592
2245.1.2 by Robert Collins
Remove the static DefaultHooks method from Branch, replacing it with a derived dict BranchHooks object, which is easier to use and provides a place to put the policy-checking add method discussed on list.
593
    def test_constructor(self):
594
        """Check that creating a BranchHooks instance has the right defaults."""
5010.2.26 by Vincent Ladeuil
Fix imports in test_branch.py.
595
        hooks = _mod_branch.BranchHooks()
2245.1.2 by Robert Collins
Remove the static DefaultHooks method from Branch, replacing it with a derived dict BranchHooks object, which is easier to use and provides a place to put the policy-checking add method discussed on list.
596
        self.assertTrue("set_rh" in hooks, "set_rh not in %s" % hooks)
2246.1.3 by Robert Collins
New branch hooks: post_push, post_pull, post_commit, post_uncommit. These
597
        self.assertTrue("post_push" in hooks, "post_push not in %s" % hooks)
598
        self.assertTrue("post_commit" in hooks, "post_commit not in %s" % hooks)
2659.3.1 by NamNguyen
``Branch.hooks`` now supports ``pre_commit`` hook.
599
        self.assertTrue("pre_commit" in hooks, "pre_commit not in %s" % hooks)
2246.1.3 by Robert Collins
New branch hooks: post_push, post_pull, post_commit, post_uncommit. These
600
        self.assertTrue("post_pull" in hooks, "post_pull not in %s" % hooks)
5010.2.26 by Vincent Ladeuil
Fix imports in test_branch.py.
601
        self.assertTrue("post_uncommit" in hooks,
602
                        "post_uncommit not in %s" % hooks)
3331.1.4 by James Henstridge
Adjust my tests to pass with Ian's API.
603
        self.assertTrue("post_change_branch_tip" in hooks,
604
                        "post_change_branch_tip not in %s" % hooks)
5107.3.2 by Marco Pantaleoni
Renamed 'post_branch' hook to 'post_branch_init', for more consistency,
605
        self.assertTrue("post_branch_init" in hooks,
606
                        "post_branch_init not in %s" % hooks)
5107.3.1 by Marco Pantaleoni
Added the new hooks 'post_branch', 'post_switch' and 'post_repo_init',
607
        self.assertTrue("post_switch" in hooks,
608
                        "post_switch not in %s" % hooks)
2245.1.1 by Robert Collins
New Branch hooks facility, with one initial hook 'set_rh' which triggers
609
2245.1.2 by Robert Collins
Remove the static DefaultHooks method from Branch, replacing it with a derived dict BranchHooks object, which is easier to use and provides a place to put the policy-checking add method discussed on list.
610
    def test_installed_hooks_are_BranchHooks(self):
611
        """The installed hooks object should be a BranchHooks."""
612
        # the installed hooks are saved in self._preserved_hooks.
4119.3.2 by Robert Collins
Migrate existing hooks over to the new HookPoint infrastructure.
613
        self.assertIsInstance(self._preserved_hooks[_mod_branch.Branch][1],
5010.2.26 by Vincent Ladeuil
Fix imports in test_branch.py.
614
                              _mod_branch.BranchHooks)
2245.1.3 by Robert Collins
Add install_hook to the BranchHooks class as the official means for installing a hook.
615
5107.3.2 by Marco Pantaleoni
Renamed 'post_branch' hook to 'post_branch_init', for more consistency,
616
    def test_post_branch_init_hook(self):
5107.3.1 by Marco Pantaleoni
Added the new hooks 'post_branch', 'post_switch' and 'post_repo_init',
617
        calls = []
5107.3.4 by Marco Pantaleoni
Applied suggestions from merge reviewer (John A Meinel):
618
        _mod_branch.Branch.hooks.install_named_hook('post_branch_init',
619
            calls.append, None)
5107.3.1 by Marco Pantaleoni
Added the new hooks 'post_branch', 'post_switch' and 'post_repo_init',
620
        self.assertLength(0, calls)
621
        branch = self.make_branch('a')
622
        self.assertLength(1, calls)
623
        params = calls[0]
5107.3.2 by Marco Pantaleoni
Renamed 'post_branch' hook to 'post_branch_init', for more consistency,
624
        self.assertIsInstance(params, _mod_branch.BranchInitHookParams)
5107.3.1 by Marco Pantaleoni
Added the new hooks 'post_branch', 'post_switch' and 'post_repo_init',
625
        self.assertTrue(hasattr(params, 'bzrdir'))
626
        self.assertTrue(hasattr(params, 'branch'))
627
5050.21.1 by Andrew Bennetts
Remove broken and apparently unused code path from BranchInitHookParams.__repr__.
628
    def test_post_branch_init_hook_repr(self):
629
        param_reprs = []
630
        _mod_branch.Branch.hooks.install_named_hook('post_branch_init',
631
            lambda params: param_reprs.append(repr(params)), None)
632
        branch = self.make_branch('a')
633
        self.assertLength(1, param_reprs)
634
        param_repr = param_reprs[0]
635
        self.assertStartsWith(param_repr, '<BranchInitHookParams of ')
636
5107.3.1 by Marco Pantaleoni
Added the new hooks 'post_branch', 'post_switch' and 'post_repo_init',
637
    def test_post_switch_hook(self):
638
        from bzrlib import switch
639
        calls = []
5107.3.4 by Marco Pantaleoni
Applied suggestions from merge reviewer (John A Meinel):
640
        _mod_branch.Branch.hooks.install_named_hook('post_switch',
641
            calls.append, None)
5107.3.1 by Marco Pantaleoni
Added the new hooks 'post_branch', 'post_switch' and 'post_repo_init',
642
        tree = self.make_branch_and_tree('branch-1')
643
        self.build_tree(['branch-1/file-1'])
644
        tree.add('file-1')
645
        tree.commit('rev1')
646
        to_branch = tree.bzrdir.sprout('branch-2').open_branch()
647
        self.build_tree(['branch-1/file-2'])
648
        tree.add('file-2')
649
        tree.remove('file-1')
650
        tree.commit('rev2')
651
        checkout = tree.branch.create_checkout('checkout')
652
        self.assertLength(0, calls)
653
        switch.switch(checkout.bzrdir, to_branch)
654
        self.assertLength(1, calls)
655
        params = calls[0]
656
        self.assertIsInstance(params, _mod_branch.SwitchHookParams)
657
        self.assertTrue(hasattr(params, 'to_branch'))
658
        self.assertTrue(hasattr(params, 'revision_id'))
2297.1.3 by Martin Pool
PullResult can pretend to be an int for api compatibility with old .pull()
659
5176.1.1 by Vincent Ladeuil
Warn if a config variable can't be interpreted as a boolean
660
661
class TestBranchOptions(tests.TestCaseWithTransport):
4989.2.1 by Brian de Alwis
The 'append_revisions_only' option is now case-insensitive,
662
4989.2.5 by Vincent Ladeuil
Clarify tests.
663
    def setUp(self):
664
        super(TestBranchOptions, self).setUp()
665
        self.branch = self.make_branch('.')
666
        self.config = self.branch.get_config()
667
4989.2.15 by Vincent Ladeuil
Fixed as per Andrew's review.
668
    def check_append_revisions_only(self, expected_value, value=None):
669
        """Set append_revisions_only in config and check its interpretation."""
4989.2.5 by Vincent Ladeuil
Clarify tests.
670
        if value is not None:
671
            self.config.set_user_option('append_revisions_only', value)
672
        self.assertEqual(expected_value,
673
                         self.branch._get_append_revisions_only())
674
675
    def test_valid_append_revisions_only(self):
676
        self.assertEquals(None,
677
                          self.config.get_user_option('append_revisions_only'))
4989.2.15 by Vincent Ladeuil
Fixed as per Andrew's review.
678
        self.check_append_revisions_only(None)
679
        self.check_append_revisions_only(False, 'False')
680
        self.check_append_revisions_only(True, 'True')
4989.2.13 by Vincent Ladeuil
append_revisions_only accept all valid booleans, update doc to
681
        # The following values will cause compatibility problems on projects
682
        # using older bzr versions (<2.2) but are accepted
4989.2.15 by Vincent Ladeuil
Fixed as per Andrew's review.
683
        self.check_append_revisions_only(False, 'false')
684
        self.check_append_revisions_only(True, 'true')
4989.2.5 by Vincent Ladeuil
Clarify tests.
685
686
    def test_invalid_append_revisions_only(self):
4989.2.9 by Brian de Alwis
Revert append_revisions_only to only allow 'True' and 'False' to
687
        """Ensure warning is noted on invalid settings"""
4989.2.15 by Vincent Ladeuil
Fixed as per Andrew's review.
688
        self.warnings = []
689
        def warning(*args):
690
            self.warnings.append(args[0] % args[1:])
691
        self.overrideAttr(trace, 'warning', warning)
692
        self.check_append_revisions_only(None, 'not-a-bool')
693
        self.assertLength(1, self.warnings)
694
        self.assertEqual(
695
            'Value "not-a-bool" is not a boolean for "append_revisions_only"',
696
            self.warnings[0])
4989.2.5 by Vincent Ladeuil
Clarify tests.
697
4989.2.1 by Brian de Alwis
The 'append_revisions_only' option is now case-insensitive,
698
5010.2.1 by Vincent Ladeuil
Fiux test/test_branch.py imports.
699
class TestPullResult(tests.TestCase):
2297.1.3 by Martin Pool
PullResult can pretend to be an int for api compatibility with old .pull()
700
701
    def test_pull_result_to_int(self):
702
        # to support old code, the pull result can be used as an int
5010.2.26 by Vincent Ladeuil
Fix imports in test_branch.py.
703
        r = _mod_branch.PullResult()
2297.1.3 by Martin Pool
PullResult can pretend to be an int for api compatibility with old .pull()
704
        r.old_revno = 10
705
        r.new_revno = 20
706
        # this usage of results is not recommended for new code (because it
707
        # doesn't describe very well what happened), but for api stability
708
        # it's still supported
5348.1.2 by Martin Pool
Deprecate casting PushResult and PullResult to int to get the relative revno change
709
        self.assertEqual(self.applyDeprecated(
710
            symbol_versioning.deprecated_in((2, 3, 0)),
711
            r.__int__),
712
            10)
3758.1.1 by Andrew Bennetts
Fix #230902 by being more careful not to squash a pre-existing exception when calling foo.unlock()
713
4672.4.1 by Jelmer Vernooij
Add two more tests for PullResult.
714
    def test_report_changed(self):
5010.2.26 by Vincent Ladeuil
Fix imports in test_branch.py.
715
        r = _mod_branch.PullResult()
4672.4.1 by Jelmer Vernooij
Add two more tests for PullResult.
716
        r.old_revid = "old-revid"
717
        r.old_revno = 10
718
        r.new_revid = "new-revid"
719
        r.new_revno = 20
720
        f = StringIO()
721
        r.report(f)
722
        self.assertEqual("Now on revision 20.\n", f.getvalue())
723
724
    def test_report_unchanged(self):
5010.2.26 by Vincent Ladeuil
Fix imports in test_branch.py.
725
        r = _mod_branch.PullResult()
4672.4.1 by Jelmer Vernooij
Add two more tests for PullResult.
726
        r.old_revid = "same-revid"
727
        r.new_revid = "same-revid"
728
        f = StringIO()
729
        r.report(f)
730
        self.assertEqual("No revisions to pull.\n", f.getvalue())
3758.1.1 by Andrew Bennetts
Fix #230902 by being more careful not to squash a pre-existing exception when calling foo.unlock()
731
732
733
class _StubLockable(object):
734
    """Helper for TestRunWithWriteLockedTarget."""
735
736
    def __init__(self, calls, unlock_exc=None):
737
        self.calls = calls
738
        self.unlock_exc = unlock_exc
739
740
    def lock_write(self):
741
        self.calls.append('lock_write')
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
742
3758.1.1 by Andrew Bennetts
Fix #230902 by being more careful not to squash a pre-existing exception when calling foo.unlock()
743
    def unlock(self):
744
        self.calls.append('unlock')
745
        if self.unlock_exc is not None:
746
            raise self.unlock_exc
747
748
749
class _ErrorFromCallable(Exception):
750
    """Helper for TestRunWithWriteLockedTarget."""
751
752
753
class _ErrorFromUnlock(Exception):
754
    """Helper for TestRunWithWriteLockedTarget."""
755
756
5010.2.1 by Vincent Ladeuil
Fiux test/test_branch.py imports.
757
class TestRunWithWriteLockedTarget(tests.TestCase):
3758.1.1 by Andrew Bennetts
Fix #230902 by being more careful not to squash a pre-existing exception when calling foo.unlock()
758
    """Tests for _run_with_write_locked_target."""
759
760
    def setUp(self):
5010.2.1 by Vincent Ladeuil
Fiux test/test_branch.py imports.
761
        tests.TestCase.setUp(self)
3758.1.1 by Andrew Bennetts
Fix #230902 by being more careful not to squash a pre-existing exception when calling foo.unlock()
762
        self._calls = []
763
764
    def func_that_returns_ok(self):
765
        self._calls.append('func called')
766
        return 'ok'
767
768
    def func_that_raises(self):
769
        self._calls.append('func called')
770
        raise _ErrorFromCallable()
771
772
    def test_success_unlocks(self):
773
        lockable = _StubLockable(self._calls)
5010.2.26 by Vincent Ladeuil
Fix imports in test_branch.py.
774
        result = _mod_branch._run_with_write_locked_target(
3758.1.1 by Andrew Bennetts
Fix #230902 by being more careful not to squash a pre-existing exception when calling foo.unlock()
775
            lockable, self.func_that_returns_ok)
776
        self.assertEqual('ok', result)
777
        self.assertEqual(['lock_write', 'func called', 'unlock'], self._calls)
778
779
    def test_exception_unlocks_and_propagates(self):
780
        lockable = _StubLockable(self._calls)
781
        self.assertRaises(_ErrorFromCallable,
5010.2.26 by Vincent Ladeuil
Fix imports in test_branch.py.
782
                          _mod_branch._run_with_write_locked_target,
783
                          lockable, self.func_that_raises)
3758.1.1 by Andrew Bennetts
Fix #230902 by being more careful not to squash a pre-existing exception when calling foo.unlock()
784
        self.assertEqual(['lock_write', 'func called', 'unlock'], self._calls)
785
786
    def test_callable_succeeds_but_error_during_unlock(self):
787
        lockable = _StubLockable(self._calls, unlock_exc=_ErrorFromUnlock())
788
        self.assertRaises(_ErrorFromUnlock,
5010.2.26 by Vincent Ladeuil
Fix imports in test_branch.py.
789
                          _mod_branch._run_with_write_locked_target,
790
                          lockable, self.func_that_returns_ok)
3758.1.1 by Andrew Bennetts
Fix #230902 by being more careful not to squash a pre-existing exception when calling foo.unlock()
791
        self.assertEqual(['lock_write', 'func called', 'unlock'], self._calls)
792
793
    def test_error_during_unlock_does_not_mask_original_error(self):
794
        lockable = _StubLockable(self._calls, unlock_exc=_ErrorFromUnlock())
795
        self.assertRaises(_ErrorFromCallable,
5010.2.26 by Vincent Ladeuil
Fix imports in test_branch.py.
796
                          _mod_branch._run_with_write_locked_target,
797
                          lockable, self.func_that_raises)
3758.1.1 by Andrew Bennetts
Fix #230902 by being more careful not to squash a pre-existing exception when calling foo.unlock()
798
        self.assertEqual(['lock_write', 'func called', 'unlock'], self._calls)