# Copyright (C) 2006-2010 Canonical Ltd
# Authors: Robert Collins <robert.collins@canonical.com>
# and others
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
"""Branch implementation tests for bzr.
These test the conformance of all the branch variations to the expected API.
Specific tests for individual formats are in the tests/test_branch file
rather than in tests/per_branch/*.py.
"""
from bzrlib import (
errors,
tests,
)
from bzrlib.branch import (BranchFormat
_legacy_formats,
)
from bzrlib.remote import RemoteBranchFormat,RemoteBzrDirFormat
from bzrlib.tests import test_server
from bzrlib.tests.per_bzrdir.test_bzrdir import TestCaseWithBzrDir
from bzrlib.transport import memory
def make_scenarios(transport_server, transport_readonly_server,
formats, vfs_transport_factory=None, name_suffix=''):
"""Transform the input formats to a list of scenarios.
:param formats: A list of (branch_format, bzrdir_format).
"""
result = []
for branch_format, bzrdir_format in formats:
# some branches don't have separate format objects.
# so we have a conditional here to handle them.
scenario_name = getattr(branch_format, '__name__',
branch_format.__class__.__name__)
scenario_name += name_suffix
scenario = (scenario_name, {
"transport_server":transport_server,
"transport_readonly_server":transport_readonly_server,
"bzrdir_format":bzrdir_format,
"branch_format":branch_format,
})
result.append(scenario)
return result
class TestCaseWithBranch(TestCaseWithBzrDir):
"""This helper will be parameterised in each per_branch test."""
def setUp(self):
super(TestCaseWithBranch, self).setUp()
self.branch = None
def get_branch(self):
if self.branch is None:
self.branch = self.make_branch('')
return self.branch
def make_branch(self, relpath, format=None):
if format is not None:
return TestCaseWithBzrDir.make_branch(self, relpath, format)
repo = self.make_repository(relpath)
# fixme RBC 20060210 this isnt necessarily a fixable thing,
# Skipped is the wrong exception to raise.
try:
return self.branch_format.initialize(repo.bzrdir)
except errors.UninitializableFormat:
raise tests.TestSkipped('Uninitializable branch format')
def make_branch_builder(self, relpath, format=None):
if format is None:
format = self.branch_format._matchingbzrdir
return super(TestCaseWithBranch, self).make_branch_builder(
relpath, format=format)
def make_repository(self, relpath, shared=False, format=None):
made_control = self.make_bzrdir(relpath, format=format)
return made_control.create_repository(shared=shared)
def create_tree_with_merge(self):
"""Create a branch with a simple ancestry.
The graph should look like:
digraph H {
"rev-1" -> "rev-2" -> "rev-3";
"rev-1" -> "rev-1.1.1" -> "rev-3";
}
Or in ASCII:
1
|\
2 1.1.1
|/
3
"""
tree = self.make_branch_and_memory_tree('tree')
tree.lock_write()
try:
tree.add('')
tree.commit('first', rev_id='rev-1')
tree.commit('second', rev_id='rev-1.1.1')
# Uncommit that last commit and switch to the other line
tree.branch.set_last_revision_info(1, 'rev-1')
tree.set_parent_ids(['rev-1'])
tree.commit('alt-second', rev_id='rev-2')
tree.set_parent_ids(['rev-2', 'rev-1.1.1'])
tree.commit('third', rev_id='rev-3')
finally:
tree.unlock()
return tree
def branch_scenarios():
""" """
# Generate a list of branch formats and their associated bzrdir formats to
# use.
combinations = [(format, format._matchingbzrdir) for format in
BranchFormat._formats.values() + _legacy_formats]
scenarios = make_scenarios(
# None here will cause the default vfs transport server to be used.
None,
# None here will cause a readonly decorator to be created
# by the TestCaseWithTransport.get_readonly_transport method.
None,
combinations)
# Add RemoteBranch tests, which need a special server.
remote_branch_format = RemoteBranchFormat()
scenarios.extend(make_scenarios(
test_server.SmartTCPServer_for_testing,
test_server.ReadonlySmartTCPServer_for_testing,
[(remote_branch_format, remote_branch_format._matchingbzrdir)],
memory.MemoryServer,
name_suffix='-default'))
# Also add tests for RemoteBranch with HPSS protocol v2 (i.e. bzr <1.6)
# server.
scenarios.extend(make_scenarios(
test_server.SmartTCPServer_for_testing_v2_only,
test_server.ReadonlySmartTCPServer_for_testing_v2_only,
[(remote_branch_format, remote_branch_format._matchingbzrdir)],
memory.MemoryServer,
name_suffix='-v2'))
return scenarios
def load_tests(standard_tests, module, loader):
per_branch_mod_names = [
'bound_sftp',
'branch',
'break_lock',
'check',
'config',
'create_checkout',
'create_clone',
'commit',
'dotted_revno_to_revision_id',
'get_revision_id_to_revno_map',
'hooks',
'http',
'iter_merge_sorted_revisions',
'last_revision_info',
'locking',
'parent',
'permissions',
'pull',
'push',
'reconcile',
'revision_history',
'revision_id_to_dotted_revno',
'revision_id_to_revno',
'sprout',
'stacking',
'tags',
'uncommit',
'update',
]
sub_tests = loader.loadTestsFromModuleNames(
['bzrlib.tests.per_branch.test_' + name
for name in per_branch_mod_names])
return tests.multiply_tests(sub_tests, branch_scenarios(), standard_tests)
|