17
17
"""Tests for Branch.get_stacked_on_url and set_stacked_on_url."""
19
19
from bzrlib import (
23
24
from bzrlib.revision import NULL_REVISION
25
from bzrlib.smart import server
24
26
from bzrlib.tests import TestNotApplicable, KnownFailure
25
27
from bzrlib.tests.branch_implementations import TestCaseWithBranch
28
from bzrlib.transport import get_transport
28
31
class TestStacking(TestCaseWithBranch):
33
def check_lines_added_or_present(self, stacked_branch, revid):
34
# similar to a failure seen in bug 288751 by mbp 20081120
35
stacked_repo = stacked_branch.repository
36
stacked_repo.lock_read()
38
list(stacked_repo.inventories.iter_lines_added_or_present_in_keys(
30
43
def test_get_set_stacked_on_url(self):
31
44
# branches must either:
32
45
# raise UnstackableBranchFormat or
115
128
self.assertRevisionNotInRepository('mainline', new_branch_revid)
116
129
self.assertRevisionInRepository('newbranch', new_branch_revid)
131
# XXX: this helper probably belongs on TestCaseWithTransport
132
def make_smart_server(self, path):
133
smart_server = server.SmartTCPServer_for_testing()
134
smart_server.setUp(self.get_server())
135
remote_transport = get_transport(smart_server.get_url()).clone(path)
136
self.addCleanup(smart_server.tearDown)
137
return remote_transport
139
def test_sprout_stacked_from_smart_server(self):
140
if isinstance(self.branch_format, branch.BzrBranchFormat4):
141
raise TestNotApplicable('Branch format 4 is not usable via HPSS.')
143
trunk_tree = self.make_branch_and_tree('mainline')
144
trunk_revid = trunk_tree.commit('mainline')
145
# Make sure that we can make a stacked branch from it
147
trunk_tree.bzrdir.sprout('testbranch', stacked=True)
148
except (errors.UnstackableBranchFormat,
149
errors.UnstackableRepositoryFormat), e:
150
raise TestNotApplicable(e)
151
# Now serve the original mainline from a smart server
152
remote_transport = self.make_smart_server('mainline')
153
remote_bzrdir = bzrdir.BzrDir.open_from_transport(remote_transport)
154
# and make branch from the smart server which is stacked
155
new_dir = remote_bzrdir.sprout('newbranch', stacked=True)
157
self.assertRevisionNotInRepository('newbranch', trunk_revid)
158
new_tree = new_dir.open_workingtree()
159
new_branch_revid = new_tree.commit('something local')
160
self.assertRevisionNotInRepository('mainline', new_branch_revid)
161
self.assertRevisionInRepository('newbranch', new_branch_revid)
118
163
def test_unstack_fetches(self):
119
164
"""Removing the stacked-on branch pulls across all data"""
120
165
# We have a mainline
258
303
unstacked.fetch(stacked.branch.repository, 'rev2')
259
304
unstacked.get_revision('rev1')
260
305
unstacked.get_revision('rev2')
306
self.check_lines_added_or_present(stacked.branch, 'rev1')
307
self.check_lines_added_or_present(stacked.branch, 'rev2')
262
309
def test_autopack_when_stacked(self):
263
310
# in bzr.dev as of 20080730, autopack was reported to fail in stacked
299
346
other_tree = other_dir.open_workingtree()
300
347
text_lines[9] = 'changed in other\n'
301
348
self.build_tree_contents([('other/a', ''.join(text_lines))])
302
other_tree.commit('commit in other')
349
stacked_revid = other_tree.commit('commit in other')
303
350
# this should have generated a delta; try to pull that across
304
351
# bug 252821 caused a RevisionNotPresent here...
305
352
stacked_tree.pull(other_tree.branch)
306
353
stacked_tree.branch.repository.pack()
307
354
stacked_tree.branch.check()
355
self.check_lines_added_or_present(stacked_tree.branch, stacked_revid)
309
357
def test_fetch_revisions_with_file_changes(self):
310
358
# Fetching revisions including file changes into a stacked branch
336
384
rtree.lock_read()
337
385
self.addCleanup(rtree.unlock)
338
386
self.assertEqual('new content', rtree.get_file_by_path('a').read())
387
self.check_lines_added_or_present(target, 'rev2')
389
def test_transform_fallback_location_hook(self):
390
# The 'transform_fallback_location' branch hook allows us to inspect
391
# and transform the URL of the fallback location for the branch.
392
stack_on = self.make_branch('stack-on')
393
stacked = self.make_branch('stacked')
395
stacked.set_stacked_on_url('../stack-on')
396
except (errors.UnstackableRepositoryFormat,
397
errors.UnstackableBranchFormat):
398
raise TestNotApplicable('Format does not support stacking.')
399
self.get_transport().rename('stack-on', 'new-stack-on')
401
def hook(stacked_branch, url):
402
hook_calls.append(url)
403
return '../new-stack-on'
404
branch.Branch.hooks.install_named_hook(
405
'transform_fallback_location', hook, None)
406
branch.Branch.open('stacked')
407
self.assertEqual(['../stack-on'], hook_calls)
409
def test_stack_on_repository_branch(self):
410
# Stacking should work when the repo isn't co-located with the
413
repo = self.make_repository('repo', shared=True)
414
except errors.IncompatibleFormat:
415
raise TestNotApplicable()
416
# Avoid make_branch, which produces standalone branches.
417
bzrdir = self.make_bzrdir('repo/stack-on')
419
b = bzrdir.create_branch()
420
except errors.UninitializableFormat:
421
raise TestNotApplicable()
422
transport = self.get_transport('stacked')
423
b.bzrdir.clone_on_transport(transport, stacked_on=b.base)
424
# Ensure that opening the branch doesn't raise.
425
branch.Branch.open(transport.base)