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