/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
2052.3.2 by John Arbash Meinel
Change Copyright .. by Canonical to Copyright ... Canonical
1
# Copyright (C) 2006 Canonical Ltd
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
2
#
1570.1.2 by Robert Collins
Import bzrtools' 'fix' command as 'bzr reconcile.'
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
7
#
1570.1.2 by Robert Collins
Import bzrtools' 'fix' command as 'bzr reconcile.'
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
12
#
1570.1.2 by Robert Collins
Import bzrtools' 'fix' command as 'bzr reconcile.'
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
17
"""Tests for reconiliation of repositories."""
18
19
20
import bzrlib
21
import bzrlib.errors as errors
1731.1.1 by Aaron Bentley
Make root entry an InventoryDirectory, make EmptyTree really empty
22
from bzrlib.inventory import Inventory
1594.2.7 by Robert Collins
Add versionedfile.fix_parents api for correcting data post hoc.
23
from bzrlib.reconcile import reconcile, Reconciler
1570.1.2 by Robert Collins
Import bzrtools' 'fix' command as 'bzr reconcile.'
24
from bzrlib.revision import Revision
1692.1.2 by Robert Collins
Teach reconcile to check the left-most parent is correct in the revision graph.
25
from bzrlib.tests import TestSkipped
1570.1.2 by Robert Collins
Import bzrtools' 'fix' command as 'bzr reconcile.'
26
from bzrlib.tests.repository_implementations.test_repository import TestCaseWithRepository
27
from bzrlib.transport import get_transport
1692.1.2 by Robert Collins
Teach reconcile to check the left-most parent is correct in the revision graph.
28
from bzrlib.uncommit import uncommit
1570.1.2 by Robert Collins
Import bzrtools' 'fix' command as 'bzr reconcile.'
29
from bzrlib.workingtree import WorkingTree
30
31
1692.1.2 by Robert Collins
Teach reconcile to check the left-most parent is correct in the revision graph.
32
class TestReconcile(TestCaseWithRepository):
33
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)
41
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,
47
                          'inventory.backup',
48
                          repo.get_transaction())
49
50
51
class TestsNeedingReweave(TestReconcile):
1570.1.2 by Robert Collins
Import bzrtools' 'fix' command as 'bzr reconcile.'
52
53
    def setUp(self):
1570.1.8 by Robert Collins
Only reconcile if doing so will perform gc or correct ancestry.
54
        super(TestsNeedingReweave, self).setUp()
1570.1.2 by Robert Collins
Import bzrtools' 'fix' command as 'bzr reconcile.'
55
        
56
        t = get_transport(self.get_url())
57
        # an empty inventory with no revision for testing with.
1692.1.3 by Robert Collins
Finish the reconcile tweak: filled in ghosts are a data loss issue and need to be checked during fast reconciles.
58
        repo = self.make_repository('inventory_without_revision')
2617.6.4 by Robert Collins
Update tests with things that break when a repository requires write groups to be used.
59
        repo.lock_write()
60
        repo.start_write_group()
1910.2.23 by Aaron Bentley
Fix up test cases that manually construct inventories
61
        inv = Inventory(revision_id='missing')
62
        inv.root.revision = 'missing'
1692.1.3 by Robert Collins
Finish the reconcile tweak: filled in ghosts are a data loss issue and need to be checked during fast reconciles.
63
        repo.add_inventory('missing', inv, [])
2617.6.4 by Robert Collins
Update tests with things that break when a repository requires write groups to be used.
64
        repo.commit_write_group()
65
        repo.unlock()
1692.1.3 by Robert Collins
Finish the reconcile tweak: filled in ghosts are a data loss issue and need to be checked during fast reconciles.
66
67
        # an empty inventory with no revision for testing with.
1570.1.14 by Robert Collins
Enforce repository consistency during 'fetch' operations.
68
        # this is referenced by 'references_missing' to let us test
69
        # that all the cached data is correctly converted into ghost links
70
        # and the referenced inventory still cleaned.
1692.1.3 by Robert Collins
Finish the reconcile tweak: filled in ghosts are a data loss issue and need to be checked during fast reconciles.
71
        repo = self.make_repository('inventory_without_revision_and_ghost')
2617.6.4 by Robert Collins
Update tests with things that break when a repository requires write groups to be used.
72
        repo.lock_write()
73
        repo.start_write_group()
1570.1.2 by Robert Collins
Import bzrtools' 'fix' command as 'bzr reconcile.'
74
        repo.add_inventory('missing', inv, [])
1910.2.23 by Aaron Bentley
Fix up test cases that manually construct inventories
75
        inv = Inventory(revision_id='references_missing')
76
        inv.root.revision = 'references_missing'
1570.1.14 by Robert Collins
Enforce repository consistency during 'fetch' operations.
77
        sha1 = repo.add_inventory('references_missing', inv, ['missing'])
78
        rev = Revision(timestamp=0,
79
                       timezone=None,
80
                       committer="Foo Bar <foo@example.com>",
81
                       message="Message",
82
                       inventory_sha1=sha1,
83
                       revision_id='references_missing')
84
        rev.parent_ids = ['missing']
85
        repo.add_revision('references_missing', rev)
2617.6.4 by Robert Collins
Update tests with things that break when a repository requires write groups to be used.
86
        repo.commit_write_group()
87
        repo.unlock()
1570.1.2 by Robert Collins
Import bzrtools' 'fix' command as 'bzr reconcile.'
88
89
        # a inventory with no parents and the revision has parents..
90
        # i.e. a ghost.
1570.1.8 by Robert Collins
Only reconcile if doing so will perform gc or correct ancestry.
91
        repo = self.make_repository('inventory_one_ghost')
2617.6.4 by Robert Collins
Update tests with things that break when a repository requires write groups to be used.
92
        repo.lock_write()
93
        repo.start_write_group()
1910.2.23 by Aaron Bentley
Fix up test cases that manually construct inventories
94
        inv = Inventory(revision_id='ghost')
95
        inv.root.revision = 'ghost'
1570.1.2 by Robert Collins
Import bzrtools' 'fix' command as 'bzr reconcile.'
96
        sha1 = repo.add_inventory('ghost', inv, [])
97
        rev = Revision(timestamp=0,
98
                       timezone=None,
99
                       committer="Foo Bar <foo@example.com>",
100
                       message="Message",
101
                       inventory_sha1=sha1,
102
                       revision_id='ghost')
103
        rev.parent_ids = ['the_ghost']
104
        repo.add_revision('ghost', rev)
2617.6.4 by Robert Collins
Update tests with things that break when a repository requires write groups to be used.
105
        repo.commit_write_group()
106
        repo.unlock()
1570.1.2 by Robert Collins
Import bzrtools' 'fix' command as 'bzr reconcile.'
107
         
108
        # a inventory with a ghost that can be corrected now.
109
        t.copy_tree('inventory_one_ghost', 'inventory_ghost_present')
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
110
        bzrdir_url = self.get_url('inventory_ghost_present')
111
        bzrdir = bzrlib.bzrdir.BzrDir.open(bzrdir_url)
112
        repo = bzrdir.open_repository()
2617.6.4 by Robert Collins
Update tests with things that break when a repository requires write groups to be used.
113
        repo.lock_write()
114
        repo.start_write_group()
1910.2.23 by Aaron Bentley
Fix up test cases that manually construct inventories
115
        inv = Inventory(revision_id='the_ghost')
116
        inv.root.revision = 'the_ghost'
1570.1.2 by Robert Collins
Import bzrtools' 'fix' command as 'bzr reconcile.'
117
        sha1 = repo.add_inventory('the_ghost', inv, [])
118
        rev = Revision(timestamp=0,
119
                       timezone=None,
120
                       committer="Foo Bar <foo@example.com>",
121
                       message="Message",
122
                       inventory_sha1=sha1,
123
                       revision_id='the_ghost')
124
        rev.parent_ids = []
125
        repo.add_revision('the_ghost', rev)
2617.6.4 by Robert Collins
Update tests with things that break when a repository requires write groups to be used.
126
        repo.commit_write_group()
127
        repo.unlock()
1570.1.2 by Robert Collins
Import bzrtools' 'fix' command as 'bzr reconcile.'
128
1692.1.1 by Robert Collins
* Repository.reconcile now takes a thorough keyword parameter to allow
129
    def checkEmptyReconcile(self, **kwargs):
130
        """Check a reconcile on an empty repository."""
1570.1.2 by Robert Collins
Import bzrtools' 'fix' command as 'bzr reconcile.'
131
        self.make_repository('empty')
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
132
        d = bzrlib.bzrdir.BzrDir.open(self.get_url('empty'))
1570.1.14 by Robert Collins
Enforce repository consistency during 'fetch' operations.
133
        # calling on a empty repository should do nothing
1692.1.1 by Robert Collins
* Repository.reconcile now takes a thorough keyword parameter to allow
134
        reconciler = d.find_repository().reconcile(**kwargs)
1570.1.8 by Robert Collins
Only reconcile if doing so will perform gc or correct ancestry.
135
        # no inconsistent parents should have been found
136
        self.assertEqual(0, reconciler.inconsistent_parents)
137
        # and no garbage inventories
138
        self.assertEqual(0, reconciler.garbage_inventories)
139
        # and no backup weave should have been needed/made.
1692.1.1 by Robert Collins
* Repository.reconcile now takes a thorough keyword parameter to allow
140
        self.checkNoBackupInventory(d)
141
142
    def test_reconile_empty(self):
143
        # in an empty repo, theres nothing to do.
144
        self.checkEmptyReconcile()
145
146
    def test_reconcile_empty_thorough(self):
147
        # reconcile should accept thorough=True
148
        self.checkEmptyReconcile(thorough=True)
1570.1.2 by Robert Collins
Import bzrtools' 'fix' command as 'bzr reconcile.'
149
1692.1.3 by Robert Collins
Finish the reconcile tweak: filled in ghosts are a data loss issue and need to be checked during fast reconciles.
150
    def test_convenience_reconcile_inventory_without_revision_reconcile(self):
1570.1.14 by Robert Collins
Enforce repository consistency during 'fetch' operations.
151
        # smoke test for the all in one ui tool
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
152
        bzrdir_url = self.get_url('inventory_without_revision')
153
        bzrdir = bzrlib.bzrdir.BzrDir.open(bzrdir_url)
154
        reconcile(bzrdir)
1570.1.14 by Robert Collins
Enforce repository consistency during 'fetch' operations.
155
        # now the backup should have it but not the current inventory
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
156
        repo = bzrdir.open_repository()
1692.1.3 by Robert Collins
Finish the reconcile tweak: filled in ghosts are a data loss issue and need to be checked during fast reconciles.
157
        self.check_missing_was_removed(repo)
158
159
    def test_reweave_inventory_without_revision(self):
160
        # an excess inventory on its own is only reconciled by using thorough
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
161
        d_url = self.get_url('inventory_without_revision')
162
        d = bzrlib.bzrdir.BzrDir.open(d_url)
1692.1.3 by Robert Collins
Finish the reconcile tweak: filled in ghosts are a data loss issue and need to be checked during fast reconciles.
163
        repo = d.open_repository()
164
        self.checkUnreconciled(d, repo.reconcile())
165
        reconciler = repo.reconcile(thorough=True)
166
        # no bad parents
167
        self.assertEqual(0, reconciler.inconsistent_parents)
168
        # and one garbage inventoriy
169
        self.assertEqual(1, reconciler.garbage_inventories)
170
        self.check_missing_was_removed(repo)
1570.1.14 by Robert Collins
Enforce repository consistency during 'fetch' operations.
171
1692.1.1 by Robert Collins
* Repository.reconcile now takes a thorough keyword parameter to allow
172
    def check_thorough_reweave_missing_revision(self, aBzrDir, reconcile,
173
            **kwargs):
1570.1.14 by Robert Collins
Enforce repository consistency during 'fetch' operations.
174
        # actual low level test.
1692.1.1 by Robert Collins
* Repository.reconcile now takes a thorough keyword parameter to allow
175
        repo = aBzrDir.open_repository()
1594.2.9 by Robert Collins
Teach Knit repositories how to handle ghosts without corrupting at all.
176
        if ([None, 'missing', 'references_missing'] 
177
            != repo.get_ancestry('references_missing')):
178
            # the repo handles ghosts without corruption, so reconcile has
179
            # nothing to do here
180
            expected_inconsistent_parents = 0
181
        else:
182
            expected_inconsistent_parents = 1
1692.1.1 by Robert Collins
* Repository.reconcile now takes a thorough keyword parameter to allow
183
        reconciler = reconcile(**kwargs)
1594.2.9 by Robert Collins
Teach Knit repositories how to handle ghosts without corrupting at all.
184
        # some number of inconsistent parents should have been found
185
        self.assertEqual(expected_inconsistent_parents,
186
                         reconciler.inconsistent_parents)
1570.1.8 by Robert Collins
Only reconcile if doing so will perform gc or correct ancestry.
187
        # and one garbage inventories
188
        self.assertEqual(1, reconciler.garbage_inventories)
1570.1.2 by Robert Collins
Import bzrtools' 'fix' command as 'bzr reconcile.'
189
        # now the backup should have it but not the current inventory
1692.1.1 by Robert Collins
* Repository.reconcile now takes a thorough keyword parameter to allow
190
        repo = aBzrDir.open_repository()
1692.1.3 by Robert Collins
Finish the reconcile tweak: filled in ghosts are a data loss issue and need to be checked during fast reconciles.
191
        self.check_missing_was_removed(repo)
1570.1.14 by Robert Collins
Enforce repository consistency during 'fetch' operations.
192
        # and the parent list for 'references_missing' should have that
193
        # revision a ghost now.
194
        self.assertEqual([None, 'references_missing'],
195
                         repo.get_ancestry('references_missing'))
1570.1.2 by Robert Collins
Import bzrtools' 'fix' command as 'bzr reconcile.'
196
1692.1.3 by Robert Collins
Finish the reconcile tweak: filled in ghosts are a data loss issue and need to be checked during fast reconciles.
197
    def check_missing_was_removed(self, repo):
198
        backup = repo.control_weaves.get_weave('inventory.backup',
199
                                               repo.get_transaction())
200
        self.assertTrue('missing' in backup.versions())
201
        self.assertRaises(errors.RevisionNotPresent,
202
                          repo.get_inventory, 'missing')
203
1692.1.1 by Robert Collins
* Repository.reconcile now takes a thorough keyword parameter to allow
204
    def test_reweave_inventory_without_revision_reconciler(self):
205
        # smoke test for the all in one Reconciler class,
206
        # other tests use the lower level repo.reconcile()
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
207
        d_url = self.get_url('inventory_without_revision_and_ghost')
208
        d = bzrlib.bzrdir.BzrDir.open(d_url)
1692.1.1 by Robert Collins
* Repository.reconcile now takes a thorough keyword parameter to allow
209
        def reconcile():
210
            reconciler = Reconciler(d)
211
            reconciler.reconcile()
212
            return reconciler
213
        self.check_thorough_reweave_missing_revision(d, reconcile)
214
1692.1.3 by Robert Collins
Finish the reconcile tweak: filled in ghosts are a data loss issue and need to be checked during fast reconciles.
215
    def test_reweave_inventory_without_revision_and_ghost(self):
1692.1.1 by Robert Collins
* Repository.reconcile now takes a thorough keyword parameter to allow
216
        # actual low level test.
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
217
        d_url = self.get_url('inventory_without_revision_and_ghost')
218
        d = bzrlib.bzrdir.BzrDir.open(d_url)
1692.1.1 by Robert Collins
* Repository.reconcile now takes a thorough keyword parameter to allow
219
        repo = d.open_repository()
220
        # nothing should have been altered yet : inventories without
221
        # revisions are not data loss incurring for current format
222
        self.check_thorough_reweave_missing_revision(d, repo.reconcile,
223
            thorough=True)
224
1570.1.2 by Robert Collins
Import bzrtools' 'fix' command as 'bzr reconcile.'
225
    def test_reweave_inventory_preserves_a_revision_with_ghosts(self):
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
226
        d = bzrlib.bzrdir.BzrDir.open(self.get_url('inventory_one_ghost'))
1692.1.1 by Robert Collins
* Repository.reconcile now takes a thorough keyword parameter to allow
227
        reconciler = d.open_repository().reconcile(thorough=True)
1570.1.8 by Robert Collins
Only reconcile if doing so will perform gc or correct ancestry.
228
        # no inconsistent parents should have been found: 
229
        # the lack of a parent for ghost is normal
230
        self.assertEqual(0, reconciler.inconsistent_parents)
231
        # and one garbage inventories
232
        self.assertEqual(0, reconciler.garbage_inventories)
1570.1.2 by Robert Collins
Import bzrtools' 'fix' command as 'bzr reconcile.'
233
        # now the current inventory should still have 'ghost'
234
        repo = d.open_repository()
235
        repo.get_inventory('ghost')
236
        self.assertEqual([None, 'ghost'], repo.get_ancestry('ghost'))
237
        
238
    def test_reweave_inventory_fixes_ancestryfor_a_present_ghost(self):
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
239
        d = bzrlib.bzrdir.BzrDir.open(self.get_url('inventory_ghost_present'))
1570.1.2 by Robert Collins
Import bzrtools' 'fix' command as 'bzr reconcile.'
240
        repo = d.open_repository()
1594.2.9 by Robert Collins
Teach Knit repositories how to handle ghosts without corrupting at all.
241
        ghost_ancestry = repo.get_ancestry('ghost')
242
        if ghost_ancestry == [None, 'the_ghost', 'ghost']:
243
            # the repo handles ghosts without corruption, so reconcile has
244
            # nothing to do
245
            return
246
        self.assertEqual([None, 'ghost'], ghost_ancestry)
1594.2.7 by Robert Collins
Add versionedfile.fix_parents api for correcting data post hoc.
247
        reconciler = repo.reconcile()
1692.1.3 by Robert Collins
Finish the reconcile tweak: filled in ghosts are a data loss issue and need to be checked during fast reconciles.
248
        # this is a data corrupting error, so a normal reconcile should fix it.
1570.1.8 by Robert Collins
Only reconcile if doing so will perform gc or correct ancestry.
249
        # one inconsistent parents should have been found : the
250
        # available but not reference parent for ghost.
251
        self.assertEqual(1, reconciler.inconsistent_parents)
252
        # and no garbage inventories
253
        self.assertEqual(0, reconciler.garbage_inventories)
1570.1.2 by Robert Collins
Import bzrtools' 'fix' command as 'bzr reconcile.'
254
        # now the current inventory should still have 'ghost'
255
        repo = d.open_repository()
256
        repo.get_inventory('ghost')
257
        repo.get_inventory('the_ghost')
258
        self.assertEqual([None, 'the_ghost', 'ghost'], repo.get_ancestry('ghost'))
259
        self.assertEqual([None, 'the_ghost'], repo.get_ancestry('the_ghost'))
1692.1.1 by Robert Collins
* Repository.reconcile now takes a thorough keyword parameter to allow
260
1692.1.2 by Robert Collins
Teach reconcile to check the left-most parent is correct in the revision graph.
261
262
class TestReconcileWithIncorrectRevisionCache(TestReconcile):
263
    """Ancestry data gets cached in knits and weaves should be reconcilable.
264
265
    This class tests that reconcile can correct invalid caches (such as after
266
    a reconcile).
267
    """
268
269
    def setUp(self):
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
270
        self.reduceLockdirTimeout()
1692.1.2 by Robert Collins
Teach reconcile to check the left-most parent is correct in the revision graph.
271
        super(TestReconcileWithIncorrectRevisionCache, self).setUp()
272
        
273
        t = get_transport(self.get_url())
274
        # we need a revision with two parents in the wrong order
275
        # which should trigger reinsertion.
276
        # and another with the first one correct but the other two not
277
        # which should not trigger reinsertion.
278
        # these need to be in different repositories so that we don't
279
        # trigger a reconcile based on the other case.
280
        # there is no api to construct a broken knit repository at
281
        # this point. if we ever encounter a bad graph in a knit repo
282
        # we should add a lower level api to allow constructing such cases.
283
        
284
        # first off the common logic:
285
        tree = self.make_branch_and_tree('wrong-first-parent')
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
286
        second_tree = self.make_branch_and_tree('reversed-secondary-parents')
287
        for t in [tree, second_tree]:
288
            t.commit('1', rev_id='1')
289
            uncommit(t.branch, tree=t)
290
            t.commit('2', rev_id='2')
291
            uncommit(t.branch, tree=t)
292
            t.commit('3', rev_id='3')
293
            uncommit(t.branch, tree=t)
294
        #second_tree = self.make_branch_and_tree('reversed-secondary-parents')
295
        #second_tree.pull(tree) # XXX won't copy the repo?
296
        repo_secondary = second_tree.branch.repository
1692.1.2 by Robert Collins
Teach reconcile to check the left-most parent is correct in the revision graph.
297
298
        # now setup the wrong-first parent case
299
        repo = tree.branch.repository
2617.6.4 by Robert Collins
Update tests with things that break when a repository requires write groups to be used.
300
        repo.lock_write()
301
        repo.start_write_group()
1910.2.23 by Aaron Bentley
Fix up test cases that manually construct inventories
302
        inv = Inventory(revision_id='wrong-first-parent')
303
        inv.root.revision = 'wrong-first-parent'
1692.1.2 by Robert Collins
Teach reconcile to check the left-most parent is correct in the revision graph.
304
        sha1 = repo.add_inventory('wrong-first-parent', inv, ['2', '1'])
305
        rev = Revision(timestamp=0,
306
                       timezone=None,
307
                       committer="Foo Bar <foo@example.com>",
308
                       message="Message",
309
                       inventory_sha1=sha1,
310
                       revision_id='wrong-first-parent')
311
        rev.parent_ids = ['1', '2']
312
        repo.add_revision('wrong-first-parent', rev)
2617.6.4 by Robert Collins
Update tests with things that break when a repository requires write groups to be used.
313
        repo.commit_write_group()
314
        repo.unlock()
1692.1.2 by Robert Collins
Teach reconcile to check the left-most parent is correct in the revision graph.
315
316
        # now setup the wrong-secondary parent case
317
        repo = repo_secondary
2617.6.4 by Robert Collins
Update tests with things that break when a repository requires write groups to be used.
318
        repo.lock_write()
319
        repo.start_write_group()
1910.2.23 by Aaron Bentley
Fix up test cases that manually construct inventories
320
        inv = Inventory(revision_id='wrong-secondary-parent')
321
        inv.root.revision = 'wrong-secondary-parent'
1692.1.2 by Robert Collins
Teach reconcile to check the left-most parent is correct in the revision graph.
322
        sha1 = repo.add_inventory('wrong-secondary-parent', inv, ['1', '3', '2'])
323
        rev = Revision(timestamp=0,
324
                       timezone=None,
325
                       committer="Foo Bar <foo@example.com>",
326
                       message="Message",
327
                       inventory_sha1=sha1,
328
                       revision_id='wrong-secondary-parent')
329
        rev.parent_ids = ['1', '2', '3']
330
        repo.add_revision('wrong-secondary-parent', rev)
2617.6.4 by Robert Collins
Update tests with things that break when a repository requires write groups to be used.
331
        repo.commit_write_group()
332
        repo.unlock()
1692.1.2 by Robert Collins
Teach reconcile to check the left-most parent is correct in the revision graph.
333
334
    def test_reconcile_wrong_order(self):
335
        # a wrong order in primary parents is optionally correctable
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
336
        t = get_transport(self.get_url()).clone('wrong-first-parent')
337
        d = bzrlib.bzrdir.BzrDir.open_from_transport(t)
1692.1.2 by Robert Collins
Teach reconcile to check the left-most parent is correct in the revision graph.
338
        repo = d.open_repository()
339
        g = repo.get_revision_graph()
2625.8.1 by Robert Collins
LIBRARY API BREAKS:
340
        if tuple(g['wrong-first-parent']) == ('1', '2'):
1692.1.2 by Robert Collins
Teach reconcile to check the left-most parent is correct in the revision graph.
341
            raise TestSkipped('wrong-first-parent is not setup for testing')
342
        self.checkUnreconciled(d, repo.reconcile())
343
        # nothing should have been altered yet : inventories without
344
        # revisions are not data loss incurring for current format
345
        reconciler = repo.reconcile(thorough=True)
346
        # these show up as inconsistent parents
347
        self.assertEqual(1, reconciler.inconsistent_parents)
1692.1.1 by Robert Collins
* Repository.reconcile now takes a thorough keyword parameter to allow
348
        # and no garbage inventories
349
        self.assertEqual(0, reconciler.garbage_inventories)
1692.1.2 by Robert Collins
Teach reconcile to check the left-most parent is correct in the revision graph.
350
        # and should have been fixed:
351
        g = repo.get_revision_graph()
2625.8.1 by Robert Collins
LIBRARY API BREAKS:
352
        self.assertEqual(('1', '2'), g['wrong-first-parent'])
1692.1.2 by Robert Collins
Teach reconcile to check the left-most parent is correct in the revision graph.
353
354
    def test_reconcile_wrong_order_secondary(self):
355
        # a wrong order in secondary parents is ignored.
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
356
        t = get_transport(self.get_url()).clone('reversed-secondary-parents')
357
        d = bzrlib.bzrdir.BzrDir.open_from_transport(t)
1692.1.2 by Robert Collins
Teach reconcile to check the left-most parent is correct in the revision graph.
358
        repo = d.open_repository()
359
        self.checkUnreconciled(d, repo.reconcile())
360
        self.checkUnreconciled(d, repo.reconcile(thorough=True))