13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
17
"""Tests for InterRepository implementastions."""
22
import bzrlib.bzrdir as bzrdir
23
from bzrlib.branch import Branch, needs_read_lock, needs_write_lock
22
24
import bzrlib.errors as errors
24
26
from bzrlib.inventory import Inventory
25
from bzrlib.revision import NULL_REVISION
27
import bzrlib.repofmt.weaverepo as weaverepo
28
import bzrlib.repository as repository
29
from bzrlib.revision import NULL_REVISION, Revision
30
from bzrlib.symbol_versioning import one_two
26
31
from bzrlib.tests import (
33
TestCaseWithTransport,
30
from bzrlib.tests.matchers import MatchesAncestry
31
from bzrlib.tests.per_interrepository import (
37
from bzrlib.tests.interrepository_implementations import (
32
38
TestCaseWithInterRepository,
42
def check_old_format_lock_error(repository_format):
43
"""Potentially ignore LockError on old formats.
45
On win32, with the old OS locks, we get a failure of double-lock when
46
we open a object in 2 objects and try to lock both.
48
On new formats, LockError would be invalid, but for old formats
49
this was not supported on Win32.
51
if sys.platform != 'win32':
54
description = repository_format.get_format_description()
55
if description in ("Repository format 4",
56
"Weave repository format 5",
57
"Weave repository format 6"):
59
# win32 OS locks are not re-entrant. So one process cannot
60
# open the same repository twice and lock them both.
61
raise TestSkipped('%s on win32 cannot open the same'
62
' repository twice in different objects'
36
67
def check_repo_format_for_funky_id_on_win32(repo):
37
if not repo._format.supports_funky_characters and sys.platform == 'win32':
38
raise TestSkipped("funky chars not allowed on this platform in repository"
39
" %s" % repo.__class__.__name__)
68
if (isinstance(repo, (weaverepo.AllInOneRepository,
69
weaverepo.WeaveMetaDirRepository))
70
and sys.platform == 'win32'):
71
raise TestSkipped("funky chars does not permitted"
72
" on this platform in repository"
73
" %s" % repo.__class__.__name__)
42
76
class TestInterRepository(TestCaseWithInterRepository):
78
112
tree_a.branch.repository.lock_write()
79
113
tree_a.branch.repository.start_write_group()
80
tree_a.branch.repository.sign_revision('rev2',
81
bzrlib.gpg.LoopbackGPGStrategy(None))
114
tree_a.branch.repository.sign_revision('rev2', bzrlib.gpg.LoopbackGPGStrategy(None))
82
115
tree_a.branch.repository.commit_write_group()
83
116
tree_a.branch.repository.unlock()
118
def test_missing_revision_ids_is_deprecated(self):
119
repo_b = self.make_to_repository('rev1_only')
120
repo_a = self.bzrdir.open_repository()
121
repo_b.fetch(repo_a, 'rev1')
122
# check the test will be valid
123
self.assertFalse(repo_b.has_revision('rev2'))
124
self.assertEqual(['rev2'],
125
self.applyDeprecated(one_two, repo_b.missing_revision_ids, repo_a))
126
inter = repository.InterRepository.get(repo_a, repo_b)
127
self.assertEqual(['rev2'],
128
self.applyDeprecated(one_two, inter.missing_revision_ids, None,
85
131
def test_search_missing_revision_ids(self):
86
132
# revision ids in repository A but not B are returned, fake ones
87
# are stripped. (fake meaning no revision object, but an inventory
133
# are stripped. (fake meaning no revision object, but an inventory
88
134
# as some formats keyed off inventory data in the past.)
89
135
# make a repository to compare against that claims to have rev1
90
136
repo_b = self.make_to_repository('rev1_only')
94
140
self.assertFalse(repo_b.has_revision('rev2'))
95
141
result = repo_b.search_missing_revision_ids(repo_a)
96
142
self.assertEqual(set(['rev2']), result.get_keys())
97
self.assertEqual(('search', set(['rev2']), set(['rev1']), 1),
143
self.assertEqual((set(['rev2']), set(['rev1']), 1), result.get_recipe())
100
145
def test_search_missing_revision_ids_absent_requested_raises(self):
101
146
# Asking for missing revisions with a tip that is itself absent in the
107
152
self.assertFalse(repo_b.has_revision('pizza'))
108
153
# Asking specifically for an absent revision errors.
109
154
self.assertRaises(errors.NoSuchRevision,
110
repo_b.search_missing_revision_ids, repo_a, revision_ids=['pizza'],
155
repo_b.search_missing_revision_ids, repo_a, revision_id='pizza',
111
156
find_ghosts=True)
112
157
self.assertRaises(errors.NoSuchRevision,
113
repo_b.search_missing_revision_ids, repo_a, revision_ids=['pizza'],
116
['search_missing_revision_ids(revision_id=...) was deprecated in '
117
'2.4. Use revision_ids=[...] instead.'],
118
self.assertRaises, errors.NoSuchRevision,
119
158
repo_b.search_missing_revision_ids, repo_a, revision_id='pizza',
120
159
find_ghosts=False)
125
164
# make a repository to compare against that is empty
126
165
repo_b = self.make_to_repository('empty')
127
166
repo_a = self.bzrdir.open_repository()
128
result = repo_b.search_missing_revision_ids(
129
repo_a, revision_ids=['rev1'])
167
result = repo_b.search_missing_revision_ids(repo_a, revision_id='rev1')
130
168
self.assertEqual(set(['rev1']), result.get_keys())
131
self.assertEqual(('search', set(['rev1']), set([NULL_REVISION]), 1),
134
def test_search_missing_revision_ids_limit(self):
135
# The limit= argument makes fetch() limit
136
# the results to the first X topo-sorted revisions.
137
repo_b = self.make_to_repository('rev1_only')
138
repo_a = self.bzrdir.open_repository()
139
# check the test will be valid
140
self.assertFalse(repo_b.has_revision('rev2'))
141
result = repo_b.search_missing_revision_ids(repo_a, limit=1)
142
self.assertEqual(('search', set(['rev1']), set(['null:']), 1),
169
self.assertEqual((set(['rev1']), set([NULL_REVISION]), 1),
145
172
def test_fetch_fetches_signatures_too(self):
146
173
from_repo = self.bzrdir.open_repository()
147
174
from_signature = from_repo.get_signature_text('rev2')
201
228
rev = missing_ghost.get_revision('ghost')
202
229
inv = missing_ghost.get_inventory('ghost')
203
230
# rev must not be corrupt now
204
self.assertThat(['ghost', 'references', 'tip'],
205
MatchesAncestry(missing_ghost, 'tip'))
231
self.assertEqual([None, 'ghost', 'references', 'tip'],
232
missing_ghost.get_ancestry('tip'))