25
25
from bzrlib import (
30
from bzrlib.controldir import ControlDir
30
from bzrlib.branch import BzrBranchFormat7
31
from bzrlib.bzrdir import BzrDir
32
from bzrlib.repofmt.pack_repo import RepositoryFormatKnitPack6
31
33
from bzrlib.tests import multiply_tests
32
34
from bzrlib.tests.per_repository import (
33
35
all_repository_format_scenarios,
38
40
class TestCaseWithExternalReferenceRepository(TestCaseWithRepository):
40
def make_referring(self, relpath, a_repository):
42
def make_referring(self, relpath, target_path):
41
43
"""Get a new repository that refers to a_repository.
43
45
:param relpath: The path to create the repository at.
44
46
:param a_repository: A repository to refer to.
46
48
repo = self.make_repository(relpath)
47
repo.add_fallback_repository(self.readonly_repository(a_repository))
49
repo.add_fallback_repository(self.readonly_repository(target_path))
50
def readonly_repository(self, repo):
51
relpath = urlutils.basename(repo.bzrdir.user_url.rstrip('/'))
52
return ControlDir.open_from_transport(
52
def readonly_repository(self, relpath):
53
return BzrDir.open_from_transport(
53
54
self.get_readonly_transport(relpath)).open_repository()
60
61
# because developers use this api to setup the tree, branch and
61
62
# repository for their tests: having it not give the right repository
62
63
# type would invalidate the tests.
63
tree = self.make_branch_and_tree('repo')
64
repo = self.make_referring('referring', tree.branch.repository)
64
self.make_branch_and_tree('repo')
65
repo = self.make_referring('referring', 'repo')
65
66
self.assertIsInstance(repo._format,
66
67
self.repository_format.__class__)
69
70
class TestIncompatibleStacking(TestCaseWithRepository):
71
def make_repo_and_incompatible_fallback(self):
72
referring = self.make_repository('referring')
73
if referring._format.supports_chks:
72
def test_add_fallback_repository_rejects_incompatible(self):
73
# Repository.add_fallback_repository raises IncompatibleRepositories if
74
# you take two repositories in different serializations and try to
76
if self.make_repository('test')._format.supports_chks:
74
77
different_fmt = '1.9'
76
79
different_fmt = '2a'
77
fallback = self.make_repository('fallback', format=different_fmt)
78
return referring, fallback
80
def test_add_fallback_repository_rejects_incompatible(self):
81
# Repository.add_fallback_repository raises IncompatibleRepositories
82
# if you take two repositories in different serializations and try to
84
referring, fallback = self.make_repo_and_incompatible_fallback()
85
self.assertRaises(errors.IncompatibleRepositories,
86
referring.add_fallback_repository, fallback)
88
def test_add_fallback_doesnt_leave_fallback_locked(self):
89
# Bug #835035. If the referring repository is locked, it wants to lock
90
# the fallback repository. But if they are incompatible, the referring
91
# repository won't take ownership of the fallback, and thus should not
92
# leave the repository in a locked state.
93
referring, fallback = self.make_repo_and_incompatible_fallback()
94
self.addCleanup(referring.lock_read().unlock)
95
# Assert precondition.
96
self.assertFalse(fallback.is_locked())
98
self.assertRaises(errors.IncompatibleRepositories,
99
referring.add_fallback_repository, fallback)
100
# Assert postcondition.
101
self.assertFalse(fallback.is_locked())
80
repo = self.make_repository('repo', format=different_fmt)
81
referring = self.make_repository('referring')
82
self.assertRaises(errors.IncompatibleRepositories,
83
referring.add_fallback_repository, repo)
104
86
def external_reference_test_scenarios():
108
90
for test_name, scenario_info in all_repository_format_scenarios():
109
91
format = scenario_info['repository_format']
110
if (isinstance(format, remote.RemoteRepositoryFormat)
111
or format.supports_external_lookups):
92
if isinstance(format, remote.RemoteRepositoryFormat):
93
# This is a RemoteRepositoryFormat scenario. Force the scenario to
94
# use real branch and repository formats that support references.
95
scenario_info = dict(scenario_info)
96
format = remote.RemoteRepositoryFormat()
97
format._custom_format = RepositoryFormatKnitPack6()
98
scenario_info['repository_format'] = format
99
bzrdir_format = remote.RemoteBzrDirFormat()
100
bzrdir_format.repository_format = format
101
bzrdir_format.set_branch_format(BzrBranchFormat7())
102
scenario_info['bzrdir_format'] = bzrdir_format
103
if format.supports_external_lookups:
112
104
result.append((test_name, scenario_info))
121
113
'bzrlib.tests.per_repository_reference.test_all_revision_ids',
122
114
'bzrlib.tests.per_repository_reference.test_break_lock',
123
115
'bzrlib.tests.per_repository_reference.test_check',
124
'bzrlib.tests.per_repository_reference.test_commit_with_stacking',
125
116
'bzrlib.tests.per_repository_reference.test_default_stacking',
126
117
'bzrlib.tests.per_repository_reference.test_fetch',
127
118
'bzrlib.tests.per_repository_reference.test_get_record_stream',
128
119
'bzrlib.tests.per_repository_reference.test_get_rev_id_for_revno',
129
'bzrlib.tests.per_repository_reference.test_graph',
130
120
'bzrlib.tests.per_repository_reference.test_initialize',
131
'bzrlib.tests.per_repository_reference.test__make_parents_provider',
132
121
'bzrlib.tests.per_repository_reference.test_unlock',
134
123
# Parameterize per_repository_reference test modules by format.