~bzr-pqm/bzr/bzr.dev

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