~bzr-pqm/bzr/bzr.dev

5273.1.7 by Vincent Ladeuil
No more use of the get_transport imported *symbol*, all uses are through
1
# Copyright (C) 2008, 2009, 2010 Canonical Ltd
3221.11.3 by Robert Collins
Add missing test script.
2
#
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.
7
#
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.
12
#
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
3221.11.3 by Robert Collins
Add missing test script.
16
3537.3.3 by Martin Pool
Rename Branch.set_stacked_on to set_stacked_on_url
17
"""Tests for Branch.get_stacked_on_url and set_stacked_on_url."""
3221.11.3 by Robert Collins
Add missing test script.
18
3517.4.12 by Martin Pool
Clearer per-branch-format tests for stacking
19
from bzrlib import (
3770.2.1 by Michael Hudson
test and feature
20
    branch,
3517.4.12 by Martin Pool
Clearer per-branch-format tests for stacking
21
    bzrdir,
4332.3.35 by Robert Collins
Fix failing tests.
22
    check,
3517.4.12 by Martin Pool
Clearer per-branch-format tests for stacking
23
    errors,
24
    )
25
from bzrlib.revision import NULL_REVISION
5325.1.6 by Andrew Bennetts
Fix test_clone_from_branch_stacked_on_relative_url_preserve_stacking failure by making it use get_url so that it tests RemoteBranch* cases the same as others. Also remove some unused imports.
26
from bzrlib.tests import TestNotApplicable, transport_util
4523.1.1 by Martin Pool
Rename tests.branch_implementations to per_branch
27
from bzrlib.tests.per_branch import TestCaseWithBranch
3221.11.3 by Robert Collins
Add missing test script.
28
29
3928.3.3 by John Arbash Meinel
Change the name of 'old_format_errors' to 'unstackable_format_errors'
30
unstackable_format_errors = (
3928.3.1 by John Arbash Meinel
Fix Branch.open() so that for stacked branches we don't open multiple connections.
31
    errors.UnstackableBranchFormat,
32
    errors.UnstackableRepositoryFormat,
33
    )
34
35
3221.11.3 by Robert Collins
Add missing test script.
36
class TestStacking(TestCaseWithBranch):
37
3830.3.16 by Martin Pool
Add passing tests for iter_lines_added_or_present in stacked repos
38
    def check_lines_added_or_present(self, stacked_branch, revid):
39
        # similar to a failure seen in bug 288751 by mbp 20081120
40
        stacked_repo = stacked_branch.repository
41
        stacked_repo.lock_read()
42
        try:
43
            list(stacked_repo.inventories.iter_lines_added_or_present_in_keys(
44
                    [(revid,)]))
45
        finally:
46
            stacked_repo.unlock()
47
3537.3.3 by Martin Pool
Rename Branch.set_stacked_on to set_stacked_on_url
48
    def test_get_set_stacked_on_url(self):
3221.11.3 by Robert Collins
Add missing test script.
49
        # branches must either:
50
        # raise UnstackableBranchFormat or
51
        # raise UnstackableRepositoryFormat or
52
        # permit stacking to be done and then return the stacked location.
53
        branch = self.make_branch('branch')
54
        target = self.make_branch('target')
55
        try:
3537.3.3 by Martin Pool
Rename Branch.set_stacked_on to set_stacked_on_url
56
            branch.set_stacked_on_url(target.base)
3928.3.3 by John Arbash Meinel
Change the name of 'old_format_errors' to 'unstackable_format_errors'
57
        except unstackable_format_errors:
3221.11.3 by Robert Collins
Add missing test script.
58
            # if the set failed, so must the get
3928.3.3 by John Arbash Meinel
Change the name of 'old_format_errors' to 'unstackable_format_errors'
59
            self.assertRaises(unstackable_format_errors, branch.get_stacked_on_url)
4103.2.3 by Andrew Bennetts
Other tests for good luck.
60
            self.assertFalse(branch._format.supports_stacking())
3221.11.3 by Robert Collins
Add missing test script.
61
            return
4103.2.3 by Andrew Bennetts
Other tests for good luck.
62
        self.assertTrue(branch._format.supports_stacking())
3221.11.3 by Robert Collins
Add missing test script.
63
        # now we have a stacked branch:
3537.3.1 by Martin Pool
Rename branch.get_stacked_on to get_stacked_on_url
64
        self.assertEqual(target.base, branch.get_stacked_on_url())
3537.3.3 by Martin Pool
Rename Branch.set_stacked_on to set_stacked_on_url
65
        branch.set_stacked_on_url(None)
3537.3.1 by Martin Pool
Rename branch.get_stacked_on to get_stacked_on_url
66
        self.assertRaises(errors.NotStacked, branch.get_stacked_on_url)
3221.13.2 by Robert Collins
Add a shallow parameter to bzrdir.sprout, which involved fixing a lateny bug in pack to pack fetching with ghost discovery.
67
3242.5.1 by Jonathan Lange
Allow stacked-on branch locations to be stored as relative URLs.
68
    def test_get_set_stacked_on_relative(self):
69
        # Branches can be stacked on other branches using relative paths.
70
        branch = self.make_branch('branch')
71
        target = self.make_branch('target')
72
        try:
3537.3.5 by Martin Pool
merge trunk including stacking policy
73
            branch.set_stacked_on_url('../target')
3928.3.3 by John Arbash Meinel
Change the name of 'old_format_errors' to 'unstackable_format_errors'
74
        except unstackable_format_errors:
3242.5.1 by Jonathan Lange
Allow stacked-on branch locations to be stored as relative URLs.
75
            # if the set failed, so must the get
3928.3.3 by John Arbash Meinel
Change the name of 'old_format_errors' to 'unstackable_format_errors'
76
            self.assertRaises(unstackable_format_errors, branch.get_stacked_on_url)
3242.5.1 by Jonathan Lange
Allow stacked-on branch locations to be stored as relative URLs.
77
            return
3537.3.5 by Martin Pool
merge trunk including stacking policy
78
        self.assertEqual('../target', branch.get_stacked_on_url())
3242.5.1 by Jonathan Lange
Allow stacked-on branch locations to be stored as relative URLs.
79
4462.3.2 by Robert Collins
Do not stack on the same branch/repository anymore. This was never supported and would generally result in infinite recursion. Fixes bug 376243.
80
    def test_set_stacked_on_same_branch_raises(self):
81
        # Stacking on the same branch silently raises and doesn't execute the
82
        # change. Reported in bug 376243.
83
        branch = self.make_branch('branch')
84
        try:
85
            self.assertRaises(errors.UnstackableLocationError,
86
                branch.set_stacked_on_url, '../branch')
87
        except unstackable_format_errors:
88
            # if the set failed, so must the get
89
            self.assertRaises(unstackable_format_errors, branch.get_stacked_on_url)
90
            return
91
        self.assertRaises(errors.NotStacked, branch.get_stacked_on_url)
92
93
    def test_set_stacked_on_same_branch_after_being_stacked_raises(self):
94
        # Stacking on the same branch silently raises and doesn't execute the
95
        # change.
96
        branch = self.make_branch('branch')
97
        target = self.make_branch('target')
98
        try:
99
            branch.set_stacked_on_url('../target')
100
        except unstackable_format_errors:
101
            # if the set failed, so must the get
102
            self.assertRaises(unstackable_format_errors, branch.get_stacked_on_url)
103
            return
104
        self.assertRaises(errors.UnstackableLocationError,
105
            branch.set_stacked_on_url, '../branch')
106
        self.assertEqual('../target', branch.get_stacked_on_url())
107
3517.4.12 by Martin Pool
Clearer per-branch-format tests for stacking
108
    def assertRevisionInRepository(self, repo_path, revid):
109
        """Check that a revision is in a repository, disregarding stacking."""
110
        repo = bzrdir.BzrDir.open(repo_path).open_repository()
111
        self.assertTrue(repo.has_revision(revid))
112
113
    def assertRevisionNotInRepository(self, repo_path, revid):
114
        """Check that a revision is not in a repository, disregarding stacking."""
115
        repo = bzrdir.BzrDir.open(repo_path).open_repository()
116
        self.assertFalse(repo.has_revision(revid))
117
118
    def test_get_graph_stacked(self):
119
        """A stacked repository shows the graph of its parent."""
120
        trunk_tree = self.make_branch_and_tree('mainline')
121
        trunk_revid = trunk_tree.commit('mainline')
122
        # make a new branch, and stack on the existing one.  we don't use
123
        # sprout(stacked=True) here because if that is buggy and copies data
124
        # it would cause a false pass of this test.
125
        new_branch = self.make_branch('new_branch')
126
        try:
3537.3.3 by Martin Pool
Rename Branch.set_stacked_on to set_stacked_on_url
127
            new_branch.set_stacked_on_url(trunk_tree.branch.base)
3928.3.3 by John Arbash Meinel
Change the name of 'old_format_errors' to 'unstackable_format_errors'
128
        except unstackable_format_errors, e:
3517.4.12 by Martin Pool
Clearer per-branch-format tests for stacking
129
            raise TestNotApplicable(e)
130
        # reading the graph from the stacked branch's repository should see
131
        # data from the stacked-on branch
132
        new_repo = new_branch.repository
133
        new_repo.lock_read()
134
        try:
135
            self.assertEqual(new_repo.get_parent_map([trunk_revid]),
136
                {trunk_revid: (NULL_REVISION, )})
137
        finally:
138
            new_repo.unlock()
139
140
    def test_sprout_stacked(self):
3221.13.2 by Robert Collins
Add a shallow parameter to bzrdir.sprout, which involved fixing a lateny bug in pack to pack fetching with ghost discovery.
141
        # We have a mainline
142
        trunk_tree = self.make_branch_and_tree('mainline')
143
        trunk_revid = trunk_tree.commit('mainline')
3221.18.4 by Ian Clatworthy
shallow -> stacked
144
        # and make branch from it which is stacked
3221.13.2 by Robert Collins
Add a shallow parameter to bzrdir.sprout, which involved fixing a lateny bug in pack to pack fetching with ghost discovery.
145
        try:
3221.18.4 by Ian Clatworthy
shallow -> stacked
146
            new_dir = trunk_tree.bzrdir.sprout('newbranch', stacked=True)
3928.3.3 by John Arbash Meinel
Change the name of 'old_format_errors' to 'unstackable_format_errors'
147
        except unstackable_format_errors, e:
3517.4.12 by Martin Pool
Clearer per-branch-format tests for stacking
148
            raise TestNotApplicable(e)
149
        # stacked repository
150
        self.assertRevisionNotInRepository('newbranch', trunk_revid)
4595.4.4 by Robert Collins
Disable committing directly to stacked branches from lightweight checkouts.
151
        tree = new_dir.open_branch().create_checkout('local')
152
        new_branch_revid = tree.commit('something local')
3537.3.4 by Martin Pool
Improved branch stacking tests
153
        self.assertRevisionNotInRepository('mainline', new_branch_revid)
154
        self.assertRevisionInRepository('newbranch', new_branch_revid)
155
3793.1.2 by Andrew Bennetts
Add test showing that stacking from the smart server works.
156
    def test_sprout_stacked_from_smart_server(self):
157
        if isinstance(self.branch_format, branch.BzrBranchFormat4):
158
            raise TestNotApplicable('Branch format 4 is not usable via HPSS.')
159
        # We have a mainline
160
        trunk_tree = self.make_branch_and_tree('mainline')
161
        trunk_revid = trunk_tree.commit('mainline')
162
        # Make sure that we can make a stacked branch from it
163
        try:
164
            trunk_tree.bzrdir.sprout('testbranch', stacked=True)
3928.3.3 by John Arbash Meinel
Change the name of 'old_format_errors' to 'unstackable_format_errors'
165
        except unstackable_format_errors, e:
3793.1.2 by Andrew Bennetts
Add test showing that stacking from the smart server works.
166
            raise TestNotApplicable(e)
167
        # Now serve the original mainline from a smart server
168
        remote_transport = self.make_smart_server('mainline')
169
        remote_bzrdir = bzrdir.BzrDir.open_from_transport(remote_transport)
170
        # and make branch from the smart server which is stacked
171
        new_dir = remote_bzrdir.sprout('newbranch', stacked=True)
172
        # stacked repository
173
        self.assertRevisionNotInRepository('newbranch', trunk_revid)
4595.4.4 by Robert Collins
Disable committing directly to stacked branches from lightweight checkouts.
174
        tree = new_dir.open_branch().create_checkout('local')
175
        new_branch_revid = tree.commit('something local')
3793.1.2 by Andrew Bennetts
Add test showing that stacking from the smart server works.
176
        self.assertRevisionNotInRepository('mainline', new_branch_revid)
177
        self.assertRevisionInRepository('newbranch', new_branch_revid)
178
3537.3.4 by Martin Pool
Improved branch stacking tests
179
    def test_unstack_fetches(self):
180
        """Removing the stacked-on branch pulls across all data"""
181
        # We have a mainline
182
        trunk_tree = self.make_branch_and_tree('mainline')
183
        trunk_revid = trunk_tree.commit('revision on mainline')
184
        # and make branch from it which is stacked
185
        try:
4509.3.17 by Martin Pool
test_unstack_fetches must put the stacked branch on the right transport to test remote formats
186
            new_dir = trunk_tree.bzrdir.sprout(self.get_url('newbranch'),
187
                stacked=True)
3928.3.3 by John Arbash Meinel
Change the name of 'old_format_errors' to 'unstackable_format_errors'
188
        except unstackable_format_errors, e:
3537.3.4 by Martin Pool
Improved branch stacking tests
189
            raise TestNotApplicable(e)
190
        # stacked repository
191
        self.assertRevisionNotInRepository('newbranch', trunk_revid)
4509.3.17 by Martin Pool
test_unstack_fetches must put the stacked branch on the right transport to test remote formats
192
        # TODO: we'd like to commit in the stacked repository; that requires
193
        # some care (maybe a BranchBuilder) if it's remote and has no
194
        # workingtree
195
        ##newbranch_revid = new_dir.open_workingtree().commit('revision in '
196
            ##'newbranch')
3537.3.4 by Martin Pool
Improved branch stacking tests
197
        # now when we unstack that should implicitly fetch, to make sure that
198
        # the branch will still work
199
        new_branch = new_dir.open_branch()
200
        new_branch.set_stacked_on_url(None)
201
        self.assertRevisionInRepository('newbranch', trunk_revid)
202
        # of course it's still in the mainline
203
        self.assertRevisionInRepository('mainline', trunk_revid)
204
        # and now we're no longer stacked
3537.3.5 by Martin Pool
merge trunk including stacking policy
205
        self.assertRaises(errors.NotStacked,
206
            new_branch.get_stacked_on_url)
3221.13.2 by Robert Collins
Add a shallow parameter to bzrdir.sprout, which involved fixing a lateny bug in pack to pack fetching with ghost discovery.
207
5325.1.4 by Andrew Bennetts
Improve comments.
208
    def test_unstack_already_locked(self):
5325.1.1 by Andrew Bennetts
Add failing test.
209
        """Removing the stacked-on branch with an already write-locked branch
210
        works.
211
212
        This was bug 551525.
213
        """
214
        try:
215
            stacked_bzrdir = self.make_stacked_bzrdir()
216
        except unstackable_format_errors, e:
217
            raise TestNotApplicable(e)
218
        stacked_branch = stacked_bzrdir.open_branch()
219
        stacked_branch.lock_write()
220
        stacked_branch.set_stacked_on_url(None)
221
        stacked_branch.unlock()
222
5325.1.4 by Andrew Bennetts
Improve comments.
223
    def test_unstack_already_multiple_locked(self):
224
        """Unstacking a branch preserves the lock count (even though it
225
        replaces the br.repository object).
226
227
        This is a more extreme variation of test_unstack_already_locked.
228
        """
5325.1.2 by Andrew Bennetts
Add another failing test.
229
        try:
230
            stacked_bzrdir = self.make_stacked_bzrdir()
231
        except unstackable_format_errors, e:
232
            raise TestNotApplicable(e)
233
        stacked_branch = stacked_bzrdir.open_branch()
234
        stacked_branch.lock_write()
235
        stacked_branch.lock_write()
236
        stacked_branch.lock_write()
237
        stacked_branch.set_stacked_on_url(None)
238
        stacked_branch.unlock()
239
        stacked_branch.unlock()
240
        stacked_branch.unlock()
241
3567.3.4 by Michael Hudson
make test a lot better
242
    def make_stacked_bzrdir(self, in_directory=None):
3567.3.7 by Michael Hudson
better docstring
243
        """Create a stacked branch and return its bzrdir.
3567.3.4 by Michael Hudson
make test a lot better
244
245
        :param in_directory: If not None, create a directory of this
246
            name and create the stacking and stacked-on bzrdirs in
247
            this directory.
248
        """
249
        if in_directory is not None:
250
            self.get_transport().mkdir(in_directory)
251
            prefix = in_directory + '/'
252
        else:
253
            prefix = ''
254
        tree = self.make_branch_and_tree(prefix + 'stacked-on')
3242.3.40 by Aaron Bentley
Turn failing test into KnownFailure
255
        tree.commit('Added foo')
256
        stacked_bzrdir = tree.branch.bzrdir.sprout(
5325.1.1 by Andrew Bennetts
Add failing test.
257
            self.get_url(prefix + 'stacked'), tree.branch.last_revision(),
258
            stacked=True)
3242.3.40 by Aaron Bentley
Turn failing test into KnownFailure
259
        return stacked_bzrdir
260
261
    def test_clone_from_stacked_branch_preserve_stacking(self):
3242.3.24 by Aaron Bentley
Fix test failures
262
        # We can clone from the bzrdir of a stacked branch. If
263
        # preserve_stacking is True, the cloned branch is stacked on the
264
        # same branch as the original.
3242.3.21 by Jonathan Lange
Preserve stacking in clone
265
        try:
3567.3.4 by Michael Hudson
make test a lot better
266
            stacked_bzrdir = self.make_stacked_bzrdir()
3928.3.3 by John Arbash Meinel
Change the name of 'old_format_errors' to 'unstackable_format_errors'
267
        except unstackable_format_errors, e:
3567.3.5 by Michael Hudson
use TestNotApplicable in all the stacking clone() tests.
268
            raise TestNotApplicable(e)
3242.3.24 by Aaron Bentley
Fix test failures
269
        cloned_bzrdir = stacked_bzrdir.clone('cloned', preserve_stacking=True)
3242.3.21 by Jonathan Lange
Preserve stacking in clone
270
        try:
271
            self.assertEqual(
3537.3.5 by Martin Pool
merge trunk including stacking policy
272
                stacked_bzrdir.open_branch().get_stacked_on_url(),
273
                cloned_bzrdir.open_branch().get_stacked_on_url())
3928.3.3 by John Arbash Meinel
Change the name of 'old_format_errors' to 'unstackable_format_errors'
274
        except unstackable_format_errors, e:
3242.3.21 by Jonathan Lange
Preserve stacking in clone
275
            pass
3242.3.40 by Aaron Bentley
Turn failing test into KnownFailure
276
3567.3.4 by Michael Hudson
make test a lot better
277
    def test_clone_from_branch_stacked_on_relative_url_preserve_stacking(self):
278
        # If a branch's stacked-on url is relative, we can still clone
279
        # from it with preserve_stacking True and get a branch stacked
280
        # on an appropriately adjusted relative url.
3567.3.3 by Michael Hudson
very hackish test
281
        try:
3567.3.4 by Michael Hudson
make test a lot better
282
            stacked_bzrdir = self.make_stacked_bzrdir(in_directory='dir')
3928.3.3 by John Arbash Meinel
Change the name of 'old_format_errors' to 'unstackable_format_errors'
283
        except unstackable_format_errors, e:
3567.3.5 by Michael Hudson
use TestNotApplicable in all the stacking clone() tests.
284
            raise TestNotApplicable(e)
3567.3.4 by Michael Hudson
make test a lot better
285
        stacked_bzrdir.open_branch().set_stacked_on_url('../stacked-on')
5325.1.6 by Andrew Bennetts
Fix test_clone_from_branch_stacked_on_relative_url_preserve_stacking failure by making it use get_url so that it tests RemoteBranch* cases the same as others. Also remove some unused imports.
286
        cloned_bzrdir = stacked_bzrdir.clone(
287
            self.get_url('cloned'), preserve_stacking=True)
3567.3.4 by Michael Hudson
make test a lot better
288
        self.assertEqual(
289
            '../dir/stacked-on',
290
            cloned_bzrdir.open_branch().get_stacked_on_url())
3567.3.3 by Michael Hudson
very hackish test
291
3242.3.40 by Aaron Bentley
Turn failing test into KnownFailure
292
    def test_clone_from_stacked_branch_no_preserve_stacking(self):
293
        try:
3567.3.4 by Michael Hudson
make test a lot better
294
            stacked_bzrdir = self.make_stacked_bzrdir()
3928.3.3 by John Arbash Meinel
Change the name of 'old_format_errors' to 'unstackable_format_errors'
295
        except unstackable_format_errors, e:
3242.3.40 by Aaron Bentley
Turn failing test into KnownFailure
296
            # not a testable combination.
3567.3.5 by Michael Hudson
use TestNotApplicable in all the stacking clone() tests.
297
            raise TestNotApplicable(e)
1551.19.46 by Aaron Bentley
Fix fetch from stacked respositories (#248506)
298
        cloned_unstacked_bzrdir = stacked_bzrdir.clone('cloned-unstacked',
299
            preserve_stacking=False)
3242.3.24 by Aaron Bentley
Fix test failures
300
        unstacked_branch = cloned_unstacked_bzrdir.open_branch()
3242.3.37 by Aaron Bentley
Updates from reviews
301
        self.assertRaises((errors.NotStacked, errors.UnstackableBranchFormat),
3537.3.5 by Martin Pool
merge trunk including stacking policy
302
                          unstacked_branch.get_stacked_on_url)
3242.3.37 by Aaron Bentley
Updates from reviews
303
304
    def test_no_op_preserve_stacking(self):
305
        """With no stacking, preserve_stacking should be a no-op."""
306
        branch = self.make_branch('source')
307
        cloned_bzrdir = branch.bzrdir.clone('cloned', preserve_stacking=True)
308
        self.assertRaises((errors.NotStacked, errors.UnstackableBranchFormat),
3537.3.5 by Martin Pool
merge trunk including stacking policy
309
                          cloned_bzrdir.open_branch().get_stacked_on_url)
3242.3.37 by Aaron Bentley
Updates from reviews
310
4617.3.1 by Robert Collins
Fix test_stacking tests for 2a as a default format. The change to 2a exposed some actual bugs, both in tests and bzrdir/branch code.
311
    def make_stacked_on_matching(self, source):
312
        if source.repository.supports_rich_root():
313
            if source.repository._format.supports_chks:
314
                format = "2a"
315
            else:
316
                format = "1.9-rich-root"
317
        else:
318
            format = "1.9"
319
        return self.make_branch('stack-on', format)
320
3242.3.37 by Aaron Bentley
Updates from reviews
321
    def test_sprout_stacking_policy_handling(self):
322
        """Obey policy where possible, ignore otherwise."""
4617.3.1 by Robert Collins
Fix test_stacking tests for 2a as a default format. The change to 2a exposed some actual bugs, both in tests and bzrdir/branch code.
323
        if isinstance(self.branch_format, branch.BzrBranchFormat4):
324
            raise TestNotApplicable('Branch format 4 does not autoupgrade.')
325
        source = self.make_branch('source')
326
        stack_on = self.make_stacked_on_matching(source)
3242.3.37 by Aaron Bentley
Updates from reviews
327
        parent_bzrdir = self.make_bzrdir('.', format='default')
328
        parent_bzrdir.get_config().set_default_stack_on('stack-on')
329
        target = source.bzrdir.sprout('target').open_branch()
4617.3.1 by Robert Collins
Fix test_stacking tests for 2a as a default format. The change to 2a exposed some actual bugs, both in tests and bzrdir/branch code.
330
        # When we sprout we upgrade the branch when there is a default stack_on
331
        # set by a config *and* the targeted branch supports stacking.
332
        if stack_on._format.supports_stacking():
3641.1.1 by John Arbash Meinel
Merge in 1.6rc5 and revert disabling default stack on policy
333
            self.assertEqual('../stack-on', target.get_stacked_on_url())
4103.2.1 by Andrew Bennetts
Make clone/sprout stacking policy tests a little more precise.
334
        else:
335
            self.assertRaises(
336
                errors.UnstackableBranchFormat, target.get_stacked_on_url)
3242.3.38 by Aaron Bentley
Enhance tests
337
338
    def test_clone_stacking_policy_handling(self):
339
        """Obey policy where possible, ignore otherwise."""
4617.3.1 by Robert Collins
Fix test_stacking tests for 2a as a default format. The change to 2a exposed some actual bugs, both in tests and bzrdir/branch code.
340
        if isinstance(self.branch_format, branch.BzrBranchFormat4):
341
            raise TestNotApplicable('Branch format 4 does not autoupgrade.')
342
        source = self.make_branch('source')
343
        stack_on = self.make_stacked_on_matching(source)
3242.3.38 by Aaron Bentley
Enhance tests
344
        parent_bzrdir = self.make_bzrdir('.', format='default')
345
        parent_bzrdir.get_config().set_default_stack_on('stack-on')
346
        target = source.bzrdir.clone('target').open_branch()
4617.3.1 by Robert Collins
Fix test_stacking tests for 2a as a default format. The change to 2a exposed some actual bugs, both in tests and bzrdir/branch code.
347
        # When we clone we upgrade the branch when there is a default stack_on
348
        # set by a config *and* the targeted branch supports stacking.
349
        if stack_on._format.supports_stacking():
3641.1.1 by John Arbash Meinel
Merge in 1.6rc5 and revert disabling default stack on policy
350
            self.assertEqual('../stack-on', target.get_stacked_on_url())
4103.2.1 by Andrew Bennetts
Make clone/sprout stacking policy tests a little more precise.
351
        else:
352
            self.assertRaises(
353
                errors.UnstackableBranchFormat, target.get_stacked_on_url)
1551.19.46 by Aaron Bentley
Fix fetch from stacked respositories (#248506)
354
4103.2.3 by Andrew Bennetts
Other tests for good luck.
355
    def test_sprout_to_smart_server_stacking_policy_handling(self):
356
        """Obey policy where possible, ignore otherwise."""
357
        if isinstance(self.branch_format, branch.BzrBranchFormat4):
358
            raise TestNotApplicable('Branch format 4 is not usable via HPSS.')
4617.3.1 by Robert Collins
Fix test_stacking tests for 2a as a default format. The change to 2a exposed some actual bugs, both in tests and bzrdir/branch code.
359
        source = self.make_branch('source')
360
        stack_on = self.make_stacked_on_matching(source)
4103.2.3 by Andrew Bennetts
Other tests for good luck.
361
        parent_bzrdir = self.make_bzrdir('.', format='default')
362
        parent_bzrdir.get_config().set_default_stack_on('stack-on')
363
        url = self.make_smart_server('target').base
364
        target = source.bzrdir.sprout(url).open_branch()
4617.3.1 by Robert Collins
Fix test_stacking tests for 2a as a default format. The change to 2a exposed some actual bugs, both in tests and bzrdir/branch code.
365
        # When we sprout we upgrade the branch when there is a default stack_on
366
        # set by a config *and* the targeted branch supports stacking.
367
        if stack_on._format.supports_stacking():
4103.2.3 by Andrew Bennetts
Other tests for good luck.
368
            self.assertEqual('../stack-on', target.get_stacked_on_url())
369
        else:
370
            self.assertRaises(
371
                errors.UnstackableBranchFormat, target.get_stacked_on_url)
372
1551.19.47 by Aaron Bentley
Add test per JAM
373
    def prepare_stacked_on_fetch(self):
1551.19.46 by Aaron Bentley
Fix fetch from stacked respositories (#248506)
374
        stack_on = self.make_branch_and_tree('stack-on')
375
        stack_on.commit('first commit', rev_id='rev1')
376
        try:
377
            stacked_dir = stack_on.bzrdir.sprout('stacked', stacked=True)
3928.3.3 by John Arbash Meinel
Change the name of 'old_format_errors' to 'unstackable_format_errors'
378
        except unstackable_format_errors, e:
1551.19.46 by Aaron Bentley
Fix fetch from stacked respositories (#248506)
379
            raise TestNotApplicable('Format does not support stacking.')
380
        unstacked = self.make_repository('unstacked')
1551.19.47 by Aaron Bentley
Add test per JAM
381
        return stacked_dir.open_workingtree(), unstacked
382
383
    def test_fetch_copies_from_stacked_on(self):
384
        stacked, unstacked = self.prepare_stacked_on_fetch()
385
        unstacked.fetch(stacked.branch.repository, 'rev1')
386
        unstacked.get_revision('rev1')
387
388
    def test_fetch_copies_from_stacked_on_and_stacked(self):
389
        stacked, unstacked = self.prepare_stacked_on_fetch()
4595.4.4 by Robert Collins
Disable committing directly to stacked branches from lightweight checkouts.
390
        tree = stacked.branch.create_checkout('local')
391
        tree.commit('second commit', rev_id='rev2')
1551.19.47 by Aaron Bentley
Add test per JAM
392
        unstacked.fetch(stacked.branch.repository, 'rev2')
393
        unstacked.get_revision('rev1')
394
        unstacked.get_revision('rev2')
3830.3.16 by Martin Pool
Add passing tests for iter_lines_added_or_present in stacked repos
395
        self.check_lines_added_or_present(stacked.branch, 'rev1')
396
        self.check_lines_added_or_present(stacked.branch, 'rev2')
3582.2.1 by Jonathan Lange
Fix up problems with fetching revisions. Almost entirely abentley's work.
397
3582.1.8 by Martin Pool
Add test for repeated commits into packed repository
398
    def test_autopack_when_stacked(self):
399
        # in bzr.dev as of 20080730, autopack was reported to fail in stacked
400
        # repositories because of problems with text deltas spanning physical
3582.1.10 by Martin Pool
Add failing tets for pull into stacked repository
401
        # repository boundaries.  however, i didn't actually get this test to
402
        # fail on that code. -- mbp
3582.1.11 by Martin Pool
doc
403
        # see https://bugs.launchpad.net/bzr/+bug/252821
4617.3.1 by Robert Collins
Fix test_stacking tests for 2a as a default format. The change to 2a exposed some actual bugs, both in tests and bzrdir/branch code.
404
        stack_on = self.make_branch_and_tree('stack-on')
405
        if not stack_on.branch._format.supports_stacking():
3582.1.8 by Martin Pool
Add test for repeated commits into packed repository
406
            raise TestNotApplicable("%r does not support stacking"
407
                % self.branch_format)
3582.1.9 by Martin Pool
Make autopack-stacked test use larger files; still does not fail
408
        text_lines = ['line %d blah blah blah\n' % i for i in range(20)]
409
        self.build_tree_contents([('stack-on/a', ''.join(text_lines))])
3582.1.8 by Martin Pool
Add test for repeated commits into packed repository
410
        stack_on.add('a')
411
        stack_on.commit('base commit')
412
        stacked_dir = stack_on.bzrdir.sprout('stacked', stacked=True)
4595.4.4 by Robert Collins
Disable committing directly to stacked branches from lightweight checkouts.
413
        stacked_branch = stacked_dir.open_branch()
414
        local_tree = stack_on.bzrdir.sprout('local').open_workingtree()
3582.1.8 by Martin Pool
Add test for repeated commits into packed repository
415
        for i in range(20):
3582.1.9 by Martin Pool
Make autopack-stacked test use larger files; still does not fail
416
            text_lines[0] = 'changed in %d\n' % i
4595.4.4 by Robert Collins
Disable committing directly to stacked branches from lightweight checkouts.
417
            self.build_tree_contents([('local/a', ''.join(text_lines))])
418
            local_tree.commit('commit %d' % i)
419
            local_tree.branch.push(stacked_branch)
420
        stacked_branch.repository.pack()
421
        check.check_dwim(stacked_branch.base, False, True, True)
3582.1.10 by Martin Pool
Add failing tets for pull into stacked repository
422
423
    def test_pull_delta_when_stacked(self):
424
        if not self.branch_format.supports_stacking():
425
            raise TestNotApplicable("%r does not support stacking"
426
                % self.branch_format)
427
        stack_on = self.make_branch_and_tree('stack-on')
428
        text_lines = ['line %d blah blah blah\n' % i for i in range(20)]
429
        self.build_tree_contents([('stack-on/a', ''.join(text_lines))])
430
        stack_on.add('a')
431
        stack_on.commit('base commit')
432
        # make a stacked branch from the mainline
433
        stacked_dir = stack_on.bzrdir.sprout('stacked', stacked=True)
434
        stacked_tree = stacked_dir.open_workingtree()
435
        # make a second non-stacked branch from the mainline
436
        other_dir = stack_on.bzrdir.sprout('other')
437
        other_tree = other_dir.open_workingtree()
438
        text_lines[9] = 'changed in other\n'
439
        self.build_tree_contents([('other/a', ''.join(text_lines))])
3830.3.16 by Martin Pool
Add passing tests for iter_lines_added_or_present in stacked repos
440
        stacked_revid = other_tree.commit('commit in other')
3582.1.10 by Martin Pool
Add failing tets for pull into stacked repository
441
        # this should have generated a delta; try to pull that across
3582.1.15 by Martin Pool
Comments and tests for repository stacking
442
        # bug 252821 caused a RevisionNotPresent here...
443
        stacked_tree.pull(other_tree.branch)
3582.1.10 by Martin Pool
Add failing tets for pull into stacked repository
444
        stacked_tree.branch.repository.pack()
4332.3.35 by Robert Collins
Fix failing tests.
445
        check.check_dwim(stacked_tree.branch.base, False, True, True)
3830.3.16 by Martin Pool
Add passing tests for iter_lines_added_or_present in stacked repos
446
        self.check_lines_added_or_present(stacked_tree.branch, stacked_revid)
3582.1.12 by Martin Pool
merge from trunk
447
3582.2.1 by Jonathan Lange
Fix up problems with fetching revisions. Almost entirely abentley's work.
448
    def test_fetch_revisions_with_file_changes(self):
449
        # Fetching revisions including file changes into a stacked branch
450
        # works without error.
451
        # Make the source tree.
452
        src_tree = self.make_branch_and_tree('src')
453
        self.build_tree_contents([('src/a', 'content')])
454
        src_tree.add('a')
455
        src_tree.commit('first commit')
456
457
        # Make the stacked-on branch.
458
        src_tree.bzrdir.sprout('stacked-on')
459
460
        # Make a branch stacked on it.
461
        target = self.make_branch('target')
462
        try:
463
            target.set_stacked_on_url('../stacked-on')
3928.3.3 by John Arbash Meinel
Change the name of 'old_format_errors' to 'unstackable_format_errors'
464
        except unstackable_format_errors, e:
3582.2.1 by Jonathan Lange
Fix up problems with fetching revisions. Almost entirely abentley's work.
465
            raise TestNotApplicable('Format does not support stacking.')
466
467
        # Change the source branch.
468
        self.build_tree_contents([('src/a', 'new content')])
469
        src_tree.commit('second commit', rev_id='rev2')
470
471
        # Fetch changes to the target.
472
        target.fetch(src_tree.branch)
473
        rtree = target.repository.revision_tree('rev2')
474
        rtree.lock_read()
475
        self.addCleanup(rtree.unlock)
476
        self.assertEqual('new content', rtree.get_file_by_path('a').read())
3830.3.16 by Martin Pool
Add passing tests for iter_lines_added_or_present in stacked repos
477
        self.check_lines_added_or_present(target, 'rev2')
3770.2.1 by Michael Hudson
test and feature
478
479
    def test_transform_fallback_location_hook(self):
480
        # The 'transform_fallback_location' branch hook allows us to inspect
481
        # and transform the URL of the fallback location for the branch.
482
        stack_on = self.make_branch('stack-on')
483
        stacked = self.make_branch('stacked')
484
        try:
485
            stacked.set_stacked_on_url('../stack-on')
3928.3.3 by John Arbash Meinel
Change the name of 'old_format_errors' to 'unstackable_format_errors'
486
        except unstackable_format_errors, e:
3770.2.1 by Michael Hudson
test and feature
487
            raise TestNotApplicable('Format does not support stacking.')
488
        self.get_transport().rename('stack-on', 'new-stack-on')
489
        hook_calls = []
490
        def hook(stacked_branch, url):
491
            hook_calls.append(url)
492
            return '../new-stack-on'
493
        branch.Branch.hooks.install_named_hook(
494
            'transform_fallback_location', hook, None)
495
        branch.Branch.open('stacked')
496
        self.assertEqual(['../stack-on'], hook_calls)
3830.2.1 by Aaron Bentley
Fix HPSS with branch stacked on repository branch
497
498
    def test_stack_on_repository_branch(self):
499
        # Stacking should work when the repo isn't co-located with the
500
        # stack-on branch.
501
        try:
502
            repo = self.make_repository('repo', shared=True)
503
        except errors.IncompatibleFormat:
504
            raise TestNotApplicable()
505
        # Avoid make_branch, which produces standalone branches.
506
        bzrdir = self.make_bzrdir('repo/stack-on')
3834.5.4 by John Arbash Meinel
Skip the stack_on_repository test for BranchReference branches.
507
        try:
508
            b = bzrdir.create_branch()
509
        except errors.UninitializableFormat:
510
            raise TestNotApplicable()
3830.2.1 by Aaron Bentley
Fix HPSS with branch stacked on repository branch
511
        transport = self.get_transport('stacked')
512
        b.bzrdir.clone_on_transport(transport, stacked_on=b.base)
3830.2.2 by Aaron Bentley
Add explanatory comment.
513
        # Ensure that opening the branch doesn't raise.
3830.2.1 by Aaron Bentley
Fix HPSS with branch stacked on repository branch
514
        branch.Branch.open(transport.base)
3928.3.1 by John Arbash Meinel
Fix Branch.open() so that for stacked branches we don't open multiple connections.
515
4419.1.2 by Andrew Bennetts
Add branch_implementations test for revision_history() on a stacked branch.
516
    def test_revision_history_of_stacked(self):
4419.1.6 by Andrew Bennetts
Add comments requested by Martin's review.
517
        # See <https://launchpad.net/bugs/380314>.
4419.1.2 by Andrew Bennetts
Add branch_implementations test for revision_history() on a stacked branch.
518
        stack_on = self.make_branch_and_tree('stack-on')
519
        stack_on.commit('first commit', rev_id='rev1')
520
        try:
521
            stacked_dir = stack_on.bzrdir.sprout(
522
                self.get_url('stacked'), stacked=True)
523
        except unstackable_format_errors, e:
524
            raise TestNotApplicable('Format does not support stacking.')
525
        try:
526
            stacked = stacked_dir.open_workingtree()
527
        except errors.NoWorkingTree:
528
            stacked = stacked_dir.open_branch().create_checkout(
529
                'stacked-checkout', lightweight=True)
4595.4.4 by Robert Collins
Disable committing directly to stacked branches from lightweight checkouts.
530
        tree = stacked.branch.create_checkout('local')
531
        tree.commit('second commit', rev_id='rev2')
4419.1.2 by Andrew Bennetts
Add branch_implementations test for revision_history() on a stacked branch.
532
        # Sanity check: stacked's repo should not contain rev1, otherwise this
533
        # test isn't testing what it's supposed to.
534
        repo = stacked.branch.repository.bzrdir.open_repository()
535
        repo.lock_read()
536
        self.addCleanup(repo.unlock)
537
        self.assertEqual({}, repo.get_parent_map(['rev1']))
538
        # revision_history should work, even though the history is spread over
539
        # multiple repositories.
540
        self.assertLength(2, stacked.branch.revision_history())
541
3928.3.1 by John Arbash Meinel
Fix Branch.open() so that for stacked branches we don't open multiple connections.
542
543
class TestStackingConnections(
544
    transport_util.TestCaseWithConnectionHookedTransport):
545
546
    def setUp(self):
547
        super(TestStackingConnections, self).setUp()
548
        try:
549
            base_tree = self.make_branch_and_tree('base',
550
                                                  format=self.bzrdir_format)
551
        except errors.UninitializableFormat, e:
552
            raise TestNotApplicable(e)
553
        stacked = self.make_branch('stacked', format=self.bzrdir_format)
554
        try:
555
            stacked.set_stacked_on_url(base_tree.branch.base)
3928.3.3 by John Arbash Meinel
Change the name of 'old_format_errors' to 'unstackable_format_errors'
556
        except unstackable_format_errors, e:
3928.3.1 by John Arbash Meinel
Fix Branch.open() so that for stacked branches we don't open multiple connections.
557
            raise TestNotApplicable(e)
558
        base_tree.commit('first', rev_id='rev-base')
559
        stacked.set_last_revision_info(1, 'rev-base')
560
        stacked_relative = self.make_branch('stacked_relative',
561
                                            format=self.bzrdir_format)
562
        stacked_relative.set_stacked_on_url('../base')
563
        stacked.set_last_revision_info(1, 'rev-base')
564
        self.start_logging_connections()
565
566
    def test_open_stacked(self):
567
        b = branch.Branch.open(self.get_url('stacked'))
568
        rev = b.repository.get_revision('rev-base')
569
        self.assertEqual(1, len(self.connections))
570
571
    def test_open_stacked_relative(self):
572
        b = branch.Branch.open(self.get_url('stacked_relative'))
573
        rev = b.repository.get_revision('rev-base')
574
        self.assertEqual(1, len(self.connections))