/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
2297.1.2 by Martin Pool
Cleanup imports
1
# Copyright (C) 2005, 2006, 2007 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
1534.4.7 by Robert Collins
Move downlevel check up to the Branch.open logic, removing it from the Branch constructor and deprecating relax_version_check to the same.
25
from StringIO 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,
1551.15.35 by Aaron Bentley
Warn when setting config values that will be masked (#122286)
32
    trace,
2230.3.3 by Aaron Bentley
Add more config testing
33
    urlutils,
34
    )
2297.1.2 by Martin Pool
Cleanup imports
35
from bzrlib.branch import (
36
    Branch,
37
    BranchHooks,
38
    BranchFormat,
39
    BranchReferenceFormat,
40
    BzrBranch5,
41
    BzrBranchFormat5,
2696.3.1 by Martin Pool
(broken) start switching format to dirstate-tags
42
    BzrBranchFormat6,
4599.4.38 by Robert Collins
Finish upgrading default branch format to 7.
43
    BzrBranchFormat7,
2297.1.3 by Martin Pool
PullResult can pretend to be an int for api compatibility with old .pull()
44
    PullResult,
3758.1.1 by Andrew Bennetts
Fix #230902 by being more careful not to squash a pre-existing exception when calling foo.unlock()
45
    _run_with_write_locked_target,
2297.1.2 by Martin Pool
Cleanup imports
46
    )
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
47
from bzrlib.bzrdir import (BzrDirMetaFormat1, BzrDirMeta1,
1553.5.71 by Martin Pool
Change branch format 5 to use LockDirs, not transport locks
48
                           BzrDir, BzrDirFormat)
1534.4.4 by Robert Collins
Make BzrBranchFormat.find_format take a transport not a url for efficiency.
49
from bzrlib.transport import get_transport
1534.4.3 by Robert Collins
Implement BranchTestProviderAdapter, so tests now run across all branch formats.
50
3445.2.1 by John Arbash Meinel
Add tests for Branch.missing_revisions and deprecate it.
51
5010.2.1 by Vincent Ladeuil
Fiux test/test_branch.py imports.
52
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.
53
2696.3.1 by Martin Pool
(broken) start switching format to dirstate-tags
54
    def test_default_format(self):
55
        # update this if you change the default branch format
56
        self.assertIsInstance(BranchFormat.get_default_format(),
4599.4.38 by Robert Collins
Finish upgrading default branch format to 7.
57
                BzrBranchFormat7)
2696.3.1 by Martin Pool
(broken) start switching format to dirstate-tags
58
2696.3.3 by Martin Pool
Start setting the default format to dirstate-tags
59
    def test_default_format_is_same_as_bzrdir_default(self):
60
        # 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
61
        # set, but at the moment that's not true -- mbp 20070814 --
2696.3.8 by Martin Pool
doc
62
        # https://bugs.launchpad.net/bzr/+bug/132376
2696.3.3 by Martin Pool
Start setting the default format to dirstate-tags
63
        self.assertEqual(BranchFormat.get_default_format(),
64
                BzrDirFormat.get_default_format().get_branch_format())
65
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
66
    def test_get_set_default_format(self):
2696.3.1 by Martin Pool
(broken) start switching format to dirstate-tags
67
        # set the format and then set it back again
2297.1.2 by Martin Pool
Cleanup imports
68
        old_format = BranchFormat.get_default_format()
69
        BranchFormat.set_default_format(SampleBranchFormat())
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
70
        try:
71
            # the default branch format is used by the meta dir format
72
            # which is not the default bzrdir format at this point
1685.1.42 by John Arbash Meinel
A couple more fixes to make sure memory:/// works correctly.
73
            dir = BzrDirMetaFormat1().initialize('memory:///')
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
74
            result = dir.create_branch()
75
            self.assertEqual(result, 'A branch')
76
        finally:
2297.1.2 by Martin Pool
Cleanup imports
77
            BranchFormat.set_default_format(old_format)
78
        self.assertEqual(old_format, BranchFormat.get_default_format())
1508.1.25 by Robert Collins
Update per review comments.
79
80
5010.2.1 by Vincent Ladeuil
Fiux test/test_branch.py imports.
81
class TestBranchFormat5(tests.TestCaseWithTransport):
1553.5.71 by Martin Pool
Change branch format 5 to use LockDirs, not transport locks
82
    """Tests specific to branch format 5"""
83
84
    def test_branch_format_5_uses_lockdir(self):
85
        url = self.get_url()
1553.5.72 by Martin Pool
Clean up test for Branch5 lockdirs
86
        bzrdir = BzrDirMetaFormat1().initialize(url)
87
        bzrdir.create_repository()
88
        branch = bzrdir.create_branch()
89
        t = self.get_transport()
90
        self.log("branch instance is %r" % branch)
91
        self.assert_(isinstance(branch, BzrBranch5))
92
        self.assertIsDirectory('.', t)
93
        self.assertIsDirectory('.bzr/branch', t)
94
        self.assertIsDirectory('.bzr/branch/lock', t)
1553.5.73 by Martin Pool
Additional test that Branch5 uses lockdir properly
95
        branch.lock_write()
1658.1.5 by Martin Pool
Release more locks taken during test suite
96
        try:
97
            self.assertIsDirectory('.bzr/branch/lock/held', t)
98
        finally:
99
            branch.unlock()
1553.5.71 by Martin Pool
Change branch format 5 to use LockDirs, not transport locks
100
2230.3.3 by Aaron Bentley
Add more config testing
101
    def test_set_push_location(self):
102
        from bzrlib.config import (locations_config_filename,
103
                                   ensure_config_dir_exists)
104
        ensure_config_dir_exists()
105
        fn = locations_config_filename()
2839.3.1 by Alexander Belchenko
provide non-empty locations.conf for test_branch.TestBranchFormat5.test_set_push_location
106
        # write correct newlines to locations.conf
107
        # by default ConfigObj uses native line-endings for new files
108
        # but uses already existing line-endings if file is not empty
109
        f = open(fn, 'wb')
110
        try:
111
            f.write('# comment\n')
112
        finally:
113
            f.close()
114
2230.3.3 by Aaron Bentley
Add more config testing
115
        branch = self.make_branch('.', format='knit')
116
        branch.set_push_location('foo')
117
        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
118
        self.assertFileEqual("# comment\n"
119
                             "[%s]\n"
2230.3.3 by Aaron Bentley
Add more config testing
120
                             "push_location = foo\n"
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
121
                             "push_location:policy = norecurse\n" % local_path,
2230.3.3 by Aaron Bentley
Add more config testing
122
                             fn)
123
2230.3.12 by Aaron Bentley
Clean up trailing whitespace
124
    # TODO RBC 20051029 test getting a push location from a branch in a
2230.3.3 by Aaron Bentley
Add more config testing
125
    # recursive section - that is, it appends the branch name.
126
1553.5.71 by Martin Pool
Change branch format 5 to use LockDirs, not transport locks
127
2297.1.2 by Martin Pool
Cleanup imports
128
class SampleBranchFormat(BranchFormat):
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
129
    """A sample format
130
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
131
    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.
132
    open and open_downlevel routines.
133
    """
134
135
    def get_format_string(self):
136
        """See BzrBranchFormat.get_format_string()."""
137
        return "Sample branch format."
138
139
    def initialize(self, a_bzrdir):
140
        """Format 4 branches cannot be created."""
141
        t = a_bzrdir.get_branch_transport(self)
1955.3.9 by John Arbash Meinel
Find more occurrances of put() and replace with put_file or put_bytes
142
        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.
143
        return 'A branch'
144
145
    def is_supported(self):
146
        return False
147
4160.2.16 by Andrew Bennetts
Update SampleBranchFormat in test_branch for ignore_fallbacks parameter.
148
    def open(self, transport, _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.
149
        return "opened branch."
150
151
5010.2.1 by Vincent Ladeuil
Fiux test/test_branch.py imports.
152
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.
153
    """Tests for the BzrBranchFormat facility."""
154
155
    def test_find_format(self):
156
        # is the right format object found for a branch?
157
        # create a branch with a few known format objects.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
158
        # 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.
159
        self.build_tree(["foo/", "bar/"])
160
        def check_format(format, url):
161
            dir = format._matchingbzrdir.initialize(url)
1534.4.47 by Robert Collins
Split out repository into .bzr/repository
162
            dir.create_repository()
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
163
            format.initialize(dir)
2297.1.2 by Martin Pool
Cleanup imports
164
            found_format = 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.
165
            self.failUnless(isinstance(found_format, format.__class__))
2297.1.2 by Martin Pool
Cleanup imports
166
        check_format(BzrBranchFormat5(), "bar")
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
167
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
168
    def test_find_format_not_branch(self):
169
        dir = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
5010.2.1 by Vincent Ladeuil
Fiux test/test_branch.py imports.
170
        self.assertRaises(errors.NotBranchError,
2297.1.2 by Martin Pool
Cleanup imports
171
                          BranchFormat.find_format,
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
172
                          dir)
173
174
    def test_find_format_unknown_format(self):
175
        dir = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
176
        SampleBranchFormat().initialize(dir)
5010.2.1 by Vincent Ladeuil
Fiux test/test_branch.py imports.
177
        self.assertRaises(errors.UnknownFormatError,
2297.1.2 by Martin Pool
Cleanup imports
178
                          BranchFormat.find_format,
1534.4.44 by Robert Collins
Make a new BzrDir format that uses a versioned branch format in a branch/ subdirectory.
179
                          dir)
180
181
    def test_register_unregister_format(self):
182
        format = SampleBranchFormat()
183
        # make a control dir
184
        dir = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
185
        # make a branch
186
        format.initialize(dir)
187
        # register a format for it.
2297.1.2 by Martin Pool
Cleanup imports
188
        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.
189
        # which branch.Open will refuse (not supported)
5010.2.1 by Vincent Ladeuil
Fiux test/test_branch.py imports.
190
        self.assertRaises(errors.UnsupportedFormatError,
191
                          Branch.open, self.get_url())
2230.3.22 by Aaron Bentley
Make test suite use format registry default, not BzrDir default
192
        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.
193
        # but open_downlevel will work
5010.2.1 by Vincent Ladeuil
Fiux test/test_branch.py imports.
194
        self.assertEqual(
195
            format.open(dir),
196
            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.
197
        # unregister the format
2297.1.2 by Martin Pool
Cleanup imports
198
        BranchFormat.unregister_format(format)
2230.3.22 by Aaron Bentley
Make test suite use format registry default, not BzrDir default
199
        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.
200
201
3221.11.2 by Robert Collins
Create basic stackable branch facility.
202
class TestBranch67(object):
203
    """Common tests for both branch 6 and 7 which are mostly the same."""
204
205
    def get_format_name(self):
206
        raise NotImplementedError(self.get_format_name)
207
208
    def get_format_name_subtree(self):
209
        raise NotImplementedError(self.get_format_name)
210
211
    def get_class(self):
212
        raise NotImplementedError(self.get_class)
2230.3.1 by Aaron Bentley
Get branch6 creation working
213
214
    def test_creation(self):
215
        format = BzrDirMetaFormat1()
2230.3.55 by Aaron Bentley
Updates from review
216
        format.set_branch_format(_mod_branch.BzrBranchFormat6())
2230.3.1 by Aaron Bentley
Get branch6 creation working
217
        branch = self.make_branch('a', format=format)
3221.11.2 by Robert Collins
Create basic stackable branch facility.
218
        self.assertIsInstance(branch, self.get_class())
219
        branch = self.make_branch('b', format=self.get_format_name())
220
        self.assertIsInstance(branch, self.get_class())
2230.3.1 by Aaron Bentley
Get branch6 creation working
221
        branch = _mod_branch.Branch.open('a')
3221.11.2 by Robert Collins
Create basic stackable branch facility.
222
        self.assertIsInstance(branch, self.get_class())
2230.3.1 by Aaron Bentley
Get branch6 creation working
223
224
    def test_layout(self):
3221.11.2 by Robert Collins
Create basic stackable branch facility.
225
        branch = self.make_branch('a', format=self.get_format_name())
2230.3.1 by Aaron Bentley
Get branch6 creation working
226
        self.failUnlessExists('a/.bzr/branch/last-revision')
227
        self.failIfExists('a/.bzr/branch/revision-history')
4273.1.12 by Aaron Bentley
Don't create reference files for older formats.
228
        self.failIfExists('a/.bzr/branch/references')
2230.3.1 by Aaron Bentley
Get branch6 creation working
229
2230.3.3 by Aaron Bentley
Add more config testing
230
    def test_config(self):
231
        """Ensure that all configuration data is stored in the branch"""
3221.11.2 by Robert Collins
Create basic stackable branch facility.
232
        branch = self.make_branch('a', format=self.get_format_name())
2230.3.3 by Aaron Bentley
Add more config testing
233
        branch.set_parent('http://bazaar-vcs.org')
234
        self.failIfExists('a/.bzr/branch/parent')
235
        self.assertEqual('http://bazaar-vcs.org', branch.get_parent())
236
        branch.set_push_location('sftp://bazaar-vcs.org')
237
        config = branch.get_config()._get_branch_data_config()
2230.3.12 by Aaron Bentley
Clean up trailing whitespace
238
        self.assertEqual('sftp://bazaar-vcs.org',
2230.3.3 by Aaron Bentley
Add more config testing
239
                         config.get_user_option('push_location'))
240
        branch.set_bound_location('ftp://bazaar-vcs.org')
241
        self.failIfExists('a/.bzr/branch/bound')
242
        self.assertEqual('ftp://bazaar-vcs.org', branch.get_bound_location())
243
2230.3.44 by Aaron Bentley
Change asserts to specific errors for left-hand history violations
244
    def test_set_revision_history(self):
3567.4.16 by John Arbash Meinel
Use the new BranchBuilder api in a Branch test
245
        builder = self.make_branch_builder('.', format=self.get_format_name())
246
        builder.build_snapshot('foo', None,
247
            [('add', ('', None, 'directory', None))],
248
            message='foo')
249
        builder.build_snapshot('bar', None, [], message='bar')
250
        branch = builder.get_branch()
251
        branch.lock_write()
252
        self.addCleanup(branch.unlock)
253
        branch.set_revision_history(['foo', 'bar'])
254
        branch.set_revision_history(['foo'])
255
        self.assertRaises(errors.NotLefthandHistory,
256
                          branch.set_revision_history, ['bar'])
2230.3.44 by Aaron Bentley
Change asserts to specific errors for left-hand history violations
257
2100.3.26 by Aaron Bentley
checkout type is maintained for subtrees
258
    def do_checkout_test(self, lightweight=False):
3221.11.2 by Robert Collins
Create basic stackable branch facility.
259
        tree = self.make_branch_and_tree('source',
260
            format=self.get_format_name_subtree())
2255.2.194 by Robert Collins
[BROKEN] Many updates to stop using experimental formats in tests.
261
        subtree = self.make_branch_and_tree('source/subtree',
3221.11.2 by Robert Collins
Create basic stackable branch facility.
262
            format=self.get_format_name_subtree())
2100.3.25 by Aaron Bentley
add subsubtree to test
263
        subsubtree = self.make_branch_and_tree('source/subtree/subsubtree',
3221.11.2 by Robert Collins
Create basic stackable branch facility.
264
            format=self.get_format_name_subtree())
2100.3.25 by Aaron Bentley
add subsubtree to test
265
        self.build_tree(['source/subtree/file',
266
                         'source/subtree/subsubtree/file'])
267
        subsubtree.add('file')
2100.3.21 by Aaron Bentley
Work on checking out by-reference trees
268
        subtree.add('file')
2100.3.25 by Aaron Bentley
add subsubtree to test
269
        subtree.add_reference(subsubtree)
2100.3.21 by Aaron Bentley
Work on checking out by-reference trees
270
        tree.add_reference(subtree)
271
        tree.commit('a revision')
2100.3.23 by Aaron Bentley
Nested checkouts kinda work
272
        subtree.commit('a subtree file')
2100.3.25 by Aaron Bentley
add subsubtree to test
273
        subsubtree.commit('a subsubtree file')
2100.3.26 by Aaron Bentley
checkout type is maintained for subtrees
274
        tree.branch.create_checkout('target', lightweight=lightweight)
2100.3.21 by Aaron Bentley
Work on checking out by-reference trees
275
        self.failUnlessExists('target')
276
        self.failUnlessExists('target/subtree')
277
        self.failUnlessExists('target/subtree/file')
2100.3.25 by Aaron Bentley
add subsubtree to test
278
        self.failUnlessExists('target/subtree/subsubtree/file')
2100.3.31 by Aaron Bentley
Merged bzr.dev (17 tests failing)
279
        subbranch = _mod_branch.Branch.open('target/subtree/subsubtree')
2100.3.26 by Aaron Bentley
checkout type is maintained for subtrees
280
        if lightweight:
281
            self.assertEndsWith(subbranch.base, 'source/subtree/subsubtree/')
282
        else:
283
            self.assertEndsWith(subbranch.base, 'target/subtree/subsubtree/')
284
285
    def test_checkout_with_references(self):
286
        self.do_checkout_test()
287
288
    def test_light_checkout_with_references(self):
289
        self.do_checkout_test(lightweight=True)
2230.3.51 by Aaron Bentley
Store revno for Branch6, set_last_revision -> set_last_revision_info
290
1551.15.35 by Aaron Bentley
Warn when setting config values that will be masked (#122286)
291
    def test_set_push(self):
3221.11.2 by Robert Collins
Create basic stackable branch facility.
292
        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)
293
        branch.get_config().set_user_option('push_location', 'old',
294
            store=config.STORE_LOCATION)
295
        warnings = []
296
        def warning(*args):
297
            warnings.append(args[0] % args[1:])
298
        _warning = trace.warning
299
        trace.warning = warning
300
        try:
301
            branch.set_push_location('new')
302
        finally:
303
            trace.warning = _warning
304
        self.assertEqual(warnings[0], 'Value "new" is masked by "old" from '
305
                         'locations.conf')
306
3445.2.1 by John Arbash Meinel
Add tests for Branch.missing_revisions and deprecate it.
307
5010.2.1 by Vincent Ladeuil
Fiux test/test_branch.py imports.
308
class TestBranch6(TestBranch67, tests.TestCaseWithTransport):
3221.11.2 by Robert Collins
Create basic stackable branch facility.
309
310
    def get_class(self):
311
        return _mod_branch.BzrBranch6
312
313
    def get_format_name(self):
314
        return "dirstate-tags"
315
316
    def get_format_name_subtree(self):
317
        return "dirstate-with-subtree"
318
3537.3.3 by Martin Pool
Rename Branch.set_stacked_on to set_stacked_on_url
319
    def test_set_stacked_on_url_errors(self):
3221.11.2 by Robert Collins
Create basic stackable branch facility.
320
        branch = self.make_branch('a', format=self.get_format_name())
321
        self.assertRaises(errors.UnstackableBranchFormat,
3537.3.3 by Martin Pool
Rename Branch.set_stacked_on to set_stacked_on_url
322
            branch.set_stacked_on_url, None)
3221.11.2 by Robert Collins
Create basic stackable branch facility.
323
324
    def test_default_stacked_location(self):
325
        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
326
        self.assertRaises(errors.UnstackableBranchFormat, branch.get_stacked_on_url)
3221.11.2 by Robert Collins
Create basic stackable branch facility.
327
328
5010.2.1 by Vincent Ladeuil
Fiux test/test_branch.py imports.
329
class TestBranch7(TestBranch67, tests.TestCaseWithTransport):
3221.11.2 by Robert Collins
Create basic stackable branch facility.
330
331
    def get_class(self):
332
        return _mod_branch.BzrBranch7
333
334
    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)
335
        return "1.9"
3221.11.2 by Robert Collins
Create basic stackable branch facility.
336
337
    def get_format_name_subtree(self):
338
        return "development-subtree"
339
3537.3.3 by Martin Pool
Rename Branch.set_stacked_on to set_stacked_on_url
340
    def test_set_stacked_on_url_unstackable_repo(self):
3221.11.6 by Robert Collins
Stackable branch fixes.
341
        repo = self.make_repository('a', format='dirstate-tags')
342
        control = repo.bzrdir
343
        branch = _mod_branch.BzrBranchFormat7().initialize(control)
3221.11.2 by Robert Collins
Create basic stackable branch facility.
344
        target = self.make_branch('b')
345
        self.assertRaises(errors.UnstackableRepositoryFormat,
3537.3.3 by Martin Pool
Rename Branch.set_stacked_on to set_stacked_on_url
346
            branch.set_stacked_on_url, target.base)
3221.11.2 by Robert Collins
Create basic stackable branch facility.
347
3242.3.21 by Jonathan Lange
Preserve stacking in clone
348
    def test_clone_stacked_on_unstackable_repo(self):
349
        repo = self.make_repository('a', format='dirstate-tags')
350
        control = repo.bzrdir
351
        branch = _mod_branch.BzrBranchFormat7().initialize(control)
352
        # Calling clone should not raise UnstackableRepositoryFormat.
353
        cloned_bzrdir = control.clone('cloned')
354
3221.11.2 by Robert Collins
Create basic stackable branch facility.
355
    def _test_default_stacked_location(self):
356
        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
357
        self.assertRaises(errors.NotStacked, branch.get_stacked_on_url)
3221.11.2 by Robert Collins
Create basic stackable branch facility.
358
3221.11.8 by Robert Collins
Minimally test stacking and unstacking a repository.
359
    def test_stack_and_unstack(self):
360
        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.
361
        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
362
        branch.set_stacked_on_url(target.branch.base)
3537.3.1 by Martin Pool
Rename branch.get_stacked_on to get_stacked_on_url
363
        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.
364
        revid = target.commit('foo')
365
        self.assertTrue(branch.repository.has_revision(revid))
3537.3.3 by Martin Pool
Rename Branch.set_stacked_on to set_stacked_on_url
366
        branch.set_stacked_on_url(None)
3537.3.1 by Martin Pool
Rename branch.get_stacked_on to get_stacked_on_url
367
        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.
368
        self.assertFalse(branch.repository.has_revision(revid))
3221.11.8 by Robert Collins
Minimally test stacking and unstacking a repository.
369
3221.11.11 by Robert Collins
Ensure opening a stacked branch gives a ready to use repository.
370
    def test_open_opens_stacked_reference(self):
371
        branch = self.make_branch('a', format=self.get_format_name())
372
        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
373
        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.
374
        branch = branch.bzrdir.open_branch()
375
        revid = target.commit('foo')
376
        self.assertTrue(branch.repository.has_revision(revid))
377
3221.11.2 by Robert Collins
Create basic stackable branch facility.
378
5010.2.1 by Vincent Ladeuil
Fiux test/test_branch.py imports.
379
class BzrBranch8(tests.TestCaseWithTransport):
4273.1.15 by Aaron Bentley
Add reference_info caching.
380
381
    def make_branch(self, location, format=None):
382
        if format is None:
383
            format = bzrdir.format_registry.make_bzrdir('1.9')
384
            format.set_branch_format(_mod_branch.BzrBranchFormat8())
5010.2.1 by Vincent Ladeuil
Fiux test/test_branch.py imports.
385
        return tests.TestCaseWithTransport.make_branch(
386
            self, location, format=format)
4273.1.15 by Aaron Bentley
Add reference_info caching.
387
388
    def create_branch_with_reference(self):
389
        branch = self.make_branch('branch')
390
        branch._set_all_reference_info({'file-id': ('path', 'location')})
391
        return branch
392
393
    @staticmethod
394
    def instrument_branch(branch, gets):
395
        old_get = branch._transport.get
396
        def get(*args, **kwargs):
397
            gets.append((args, kwargs))
398
            return old_get(*args, **kwargs)
399
        branch._transport.get = get
400
401
    def test_reference_info_caching_read_locked(self):
402
        gets = []
403
        branch = self.create_branch_with_reference()
404
        branch.lock_read()
405
        self.addCleanup(branch.unlock)
406
        self.instrument_branch(branch, gets)
407
        branch.get_reference_info('file-id')
408
        branch.get_reference_info('file-id')
409
        self.assertEqual(1, len(gets))
410
411
    def test_reference_info_caching_read_unlocked(self):
412
        gets = []
413
        branch = self.create_branch_with_reference()
414
        self.instrument_branch(branch, gets)
415
        branch.get_reference_info('file-id')
416
        branch.get_reference_info('file-id')
417
        self.assertEqual(2, len(gets))
418
419
    def test_reference_info_caching_write_locked(self):
420
        gets = []
421
        branch = self.make_branch('branch')
422
        branch.lock_write()
423
        self.instrument_branch(branch, gets)
424
        self.addCleanup(branch.unlock)
425
        branch._set_all_reference_info({'file-id': ('path2', 'location2')})
426
        path, location = branch.get_reference_info('file-id')
427
        self.assertEqual(0, len(gets))
428
        self.assertEqual('path2', path)
429
        self.assertEqual('location2', location)
430
431
    def test_reference_info_caches_cleared(self):
432
        branch = self.make_branch('branch')
433
        branch.lock_write()
434
        branch.set_reference_info('file-id', 'path2', 'location2')
435
        branch.unlock()
436
        doppelganger = Branch.open('branch')
437
        doppelganger.set_reference_info('file-id', 'path3', 'location3')
438
        self.assertEqual(('path3', 'location3'),
439
                         branch.get_reference_info('file-id'))
440
5010.2.1 by Vincent Ladeuil
Fiux test/test_branch.py imports.
441
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.
442
    """Tests for the branch reference facility."""
443
444
    def test_create_open_reference(self):
445
        bzrdirformat = bzrdir.BzrDirMetaFormat1()
446
        t = get_transport(self.get_url('.'))
447
        t.mkdir('repo')
448
        dir = bzrdirformat.initialize(self.get_url('repo'))
449
        dir.create_repository()
450
        target_branch = dir.create_branch()
451
        t.mkdir('branch')
452
        branch_dir = bzrdirformat.initialize(self.get_url('branch'))
2297.1.2 by Martin Pool
Cleanup imports
453
        made_branch = BranchReferenceFormat().initialize(branch_dir, 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.
454
        self.assertEqual(made_branch.base, target_branch.base)
455
        opened_branch = branch_dir.open_branch()
456
        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.
457
458
    def test_get_reference(self):
459
        """For a BranchReference, get_reference should reutrn the location."""
460
        branch = self.make_branch('target')
461
        checkout = branch.create_checkout('checkout', lightweight=True)
462
        reference_url = branch.bzrdir.root_transport.abspath('') + '/'
463
        # if the api for create_checkout changes to return different checkout types
464
        # then this file read will fail.
465
        self.assertFileEqual(reference_url, 'checkout/.bzr/branch/location')
466
        self.assertEqual(reference_url,
2018.5.97 by Andrew Bennetts
Fix more tests.
467
            _mod_branch.BranchReferenceFormat().get_reference(checkout.bzrdir))
2018.5.45 by Andrew Bennetts
Merge from bzr.dev
468
2245.1.1 by Robert Collins
New Branch hooks facility, with one initial hook 'set_rh' which triggers
469
5010.2.1 by Vincent Ladeuil
Fiux test/test_branch.py imports.
470
class TestHooks(tests.TestCase):
2245.1.1 by Robert Collins
New Branch hooks facility, with one initial hook 'set_rh' which triggers
471
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.
472
    def test_constructor(self):
473
        """Check that creating a BranchHooks instance has the right defaults."""
2297.1.2 by Martin Pool
Cleanup imports
474
        hooks = 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.
475
        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
476
        self.assertTrue("post_push" in hooks, "post_push not in %s" % hooks)
477
        self.assertTrue("post_commit" in hooks, "post_commit not in %s" % hooks)
2659.3.1 by NamNguyen
``Branch.hooks`` now supports ``pre_commit`` hook.
478
        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
479
        self.assertTrue("post_pull" in hooks, "post_pull not in %s" % hooks)
480
        self.assertTrue("post_uncommit" in hooks, "post_uncommit not in %s" % hooks)
3331.1.4 by James Henstridge
Adjust my tests to pass with Ian's API.
481
        self.assertTrue("post_change_branch_tip" in hooks,
482
                        "post_change_branch_tip not in %s" % hooks)
2245.1.1 by Robert Collins
New Branch hooks facility, with one initial hook 'set_rh' which triggers
483
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.
484
    def test_installed_hooks_are_BranchHooks(self):
485
        """The installed hooks object should be a BranchHooks."""
486
        # the installed hooks are saved in self._preserved_hooks.
4119.3.2 by Robert Collins
Migrate existing hooks over to the new HookPoint infrastructure.
487
        self.assertIsInstance(self._preserved_hooks[_mod_branch.Branch][1],
488
            BranchHooks)
2245.1.3 by Robert Collins
Add install_hook to the BranchHooks class as the official means for installing a hook.
489
2297.1.3 by Martin Pool
PullResult can pretend to be an int for api compatibility with old .pull()
490
5010.2.1 by Vincent Ladeuil
Fiux test/test_branch.py imports.
491
class TestPullResult(tests.TestCase):
2297.1.3 by Martin Pool
PullResult can pretend to be an int for api compatibility with old .pull()
492
493
    def test_pull_result_to_int(self):
494
        # to support old code, the pull result can be used as an int
495
        r = PullResult()
496
        r.old_revno = 10
497
        r.new_revno = 20
498
        # this usage of results is not recommended for new code (because it
499
        # doesn't describe very well what happened), but for api stability
500
        # it's still supported
501
        a = "%d revisions pulled" % r
502
        self.assertEqual(a, "10 revisions pulled")
3758.1.1 by Andrew Bennetts
Fix #230902 by being more careful not to squash a pre-existing exception when calling foo.unlock()
503
4672.4.1 by Jelmer Vernooij
Add two more tests for PullResult.
504
    def test_report_changed(self):
505
        r = PullResult()
506
        r.old_revid = "old-revid"
507
        r.old_revno = 10
508
        r.new_revid = "new-revid"
509
        r.new_revno = 20
510
        f = StringIO()
511
        r.report(f)
512
        self.assertEqual("Now on revision 20.\n", f.getvalue())
513
514
    def test_report_unchanged(self):
515
        r = PullResult()
516
        r.old_revid = "same-revid"
517
        r.new_revid = "same-revid"
518
        f = StringIO()
519
        r.report(f)
520
        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()
521
522
523
class _StubLockable(object):
524
    """Helper for TestRunWithWriteLockedTarget."""
525
526
    def __init__(self, calls, unlock_exc=None):
527
        self.calls = calls
528
        self.unlock_exc = unlock_exc
529
530
    def lock_write(self):
531
        self.calls.append('lock_write')
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
532
3758.1.1 by Andrew Bennetts
Fix #230902 by being more careful not to squash a pre-existing exception when calling foo.unlock()
533
    def unlock(self):
534
        self.calls.append('unlock')
535
        if self.unlock_exc is not None:
536
            raise self.unlock_exc
537
538
539
class _ErrorFromCallable(Exception):
540
    """Helper for TestRunWithWriteLockedTarget."""
541
542
543
class _ErrorFromUnlock(Exception):
544
    """Helper for TestRunWithWriteLockedTarget."""
545
546
5010.2.1 by Vincent Ladeuil
Fiux test/test_branch.py imports.
547
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()
548
    """Tests for _run_with_write_locked_target."""
549
550
    def setUp(self):
5010.2.1 by Vincent Ladeuil
Fiux test/test_branch.py imports.
551
        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()
552
        self._calls = []
553
554
    def func_that_returns_ok(self):
555
        self._calls.append('func called')
556
        return 'ok'
557
558
    def func_that_raises(self):
559
        self._calls.append('func called')
560
        raise _ErrorFromCallable()
561
562
    def test_success_unlocks(self):
563
        lockable = _StubLockable(self._calls)
564
        result = _run_with_write_locked_target(
565
            lockable, self.func_that_returns_ok)
566
        self.assertEqual('ok', result)
567
        self.assertEqual(['lock_write', 'func called', 'unlock'], self._calls)
568
569
    def test_exception_unlocks_and_propagates(self):
570
        lockable = _StubLockable(self._calls)
571
        self.assertRaises(_ErrorFromCallable,
572
            _run_with_write_locked_target, lockable, self.func_that_raises)
573
        self.assertEqual(['lock_write', 'func called', 'unlock'], self._calls)
574
575
    def test_callable_succeeds_but_error_during_unlock(self):
576
        lockable = _StubLockable(self._calls, unlock_exc=_ErrorFromUnlock())
577
        self.assertRaises(_ErrorFromUnlock,
578
            _run_with_write_locked_target, lockable, self.func_that_returns_ok)
579
        self.assertEqual(['lock_write', 'func called', 'unlock'], self._calls)
580
581
    def test_error_during_unlock_does_not_mask_original_error(self):
582
        lockable = _StubLockable(self._calls, unlock_exc=_ErrorFromUnlock())
583
        self.assertRaises(_ErrorFromCallable,
584
            _run_with_write_locked_target, lockable, self.func_that_raises)
585
        self.assertEqual(['lock_write', 'func called', 'unlock'], self._calls)
586
587