21
21
import bzrlib.errors as errors
22
22
from bzrlib.reconcile import reconcile, Reconciler
23
23
from bzrlib.revision import Revision
24
from bzrlib.tests import TestSkipped
24
25
from bzrlib.tests.repository_implementations.test_repository import TestCaseWithRepository
25
26
from bzrlib.transport import get_transport
26
27
from bzrlib.tree import EmptyTree
28
from bzrlib.uncommit import uncommit
27
29
from bzrlib.workingtree import WorkingTree
30
class TestsNeedingReweave(TestCaseWithRepository):
32
class TestReconcile(TestCaseWithRepository):
34
def checkUnreconciled(self, d, reconciler):
35
"""Check that d did not get reconciled."""
36
# nothing should have been fixed yet:
37
self.assertEqual(0, reconciler.inconsistent_parents)
38
# and no garbage inventories
39
self.assertEqual(0, reconciler.garbage_inventories)
40
self.checkNoBackupInventory(d)
42
def checkNoBackupInventory(self, aBzrDir):
43
"""Check that there is no backup inventory in aBzrDir."""
44
repo = aBzrDir.open_repository()
45
self.assertRaises(errors.NoSuchFile,
46
repo.control_weaves.get_weave,
48
repo.get_transaction())
51
class TestsNeedingReweave(TestReconcile):
33
54
super(TestsNeedingReweave, self).setUp()
206
218
self.assertEqual([None, 'the_ghost', 'ghost'], repo.get_ancestry('ghost'))
207
219
self.assertEqual([None, 'the_ghost'], repo.get_ancestry('the_ghost'))
209
def checkUnreconciled(self, d, reconciler):
210
"""Check that d did not get reconciled."""
211
# nothing should have been fixed yet:
212
self.assertEqual(0, reconciler.inconsistent_parents)
222
class TestReconcileWithIncorrectRevisionCache(TestReconcile):
223
"""Ancestry data gets cached in knits and weaves should be reconcilable.
225
This class tests that reconcile can correct invalid caches (such as after
230
super(TestReconcileWithIncorrectRevisionCache, self).setUp()
232
t = get_transport(self.get_url())
233
# we need a revision with two parents in the wrong order
234
# which should trigger reinsertion.
235
# and another with the first one correct but the other two not
236
# which should not trigger reinsertion.
237
# these need to be in different repositories so that we don't
238
# trigger a reconcile based on the other case.
239
# there is no api to construct a broken knit repository at
240
# this point. if we ever encounter a bad graph in a knit repo
241
# we should add a lower level api to allow constructing such cases.
243
# first off the common logic:
244
tree = self.make_branch_and_tree('wrong-first-parent')
245
tree.commit('1', rev_id='1')
246
uncommit(tree.branch, tree=tree)
247
tree.commit('2', rev_id='2')
248
uncommit(tree.branch, tree=tree)
249
tree.commit('3', rev_id='3')
250
uncommit(tree.branch, tree=tree)
251
repo_secondary = tree.bzrdir.clone(
252
'reversed-secondary-parents').open_repository()
254
# now setup the wrong-first parent case
255
repo = tree.branch.repository
256
inv = EmptyTree().inventory
257
sha1 = repo.add_inventory('wrong-first-parent', inv, ['2', '1'])
258
rev = Revision(timestamp=0,
260
committer="Foo Bar <foo@example.com>",
263
revision_id='wrong-first-parent')
264
rev.parent_ids = ['1', '2']
265
repo.add_revision('wrong-first-parent', rev)
267
# now setup the wrong-secondary parent case
268
repo = repo_secondary
269
inv = EmptyTree().inventory
270
sha1 = repo.add_inventory('wrong-secondary-parent', inv, ['1', '3', '2'])
271
rev = Revision(timestamp=0,
273
committer="Foo Bar <foo@example.com>",
276
revision_id='wrong-secondary-parent')
277
rev.parent_ids = ['1', '2', '3']
278
repo.add_revision('wrong-secondary-parent', rev)
280
def test_reconcile_wrong_order(self):
281
# a wrong order in primary parents is optionally correctable
282
d = bzrlib.bzrdir.BzrDir.open('wrong-first-parent')
283
repo = d.open_repository()
284
g = repo.get_revision_graph()
285
if g['wrong-first-parent'] == ['1', '2']:
286
raise TestSkipped('wrong-first-parent is not setup for testing')
287
self.checkUnreconciled(d, repo.reconcile())
288
# nothing should have been altered yet : inventories without
289
# revisions are not data loss incurring for current format
290
reconciler = repo.reconcile(thorough=True)
291
# these show up as inconsistent parents
292
self.assertEqual(1, reconciler.inconsistent_parents)
213
293
# and no garbage inventories
214
294
self.assertEqual(0, reconciler.garbage_inventories)
215
self.checkNoBackupInventory(d)
295
# and should have been fixed:
296
g = repo.get_revision_graph()
297
self.assertEqual(['1', '2'], g['wrong-first-parent'])
299
def test_reconcile_wrong_order_secondary(self):
300
# a wrong order in secondary parents is ignored.
301
d = bzrlib.bzrdir.BzrDir.open('reversed-secondary-parents')
302
repo = d.open_repository()
303
self.checkUnreconciled(d, repo.reconcile())
304
self.checkUnreconciled(d, repo.reconcile(thorough=True))