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