~bzr-pqm/bzr/bzr.dev

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