/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')
1910.2.23 by Aaron Bentley
Fix up test cases that manually construct inventories
59
        inv = Inventory(revision_id='missing')
60
        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.
61
        repo.add_inventory('missing', inv, [])
62
63
        # an empty inventory with no revision for testing with.
1570.1.14 by Robert Collins
Enforce repository consistency during 'fetch' operations.
64
        # this is referenced by 'references_missing' to let us test
65
        # that all the cached data is correctly converted into ghost links
66
        # 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.
67
        repo = self.make_repository('inventory_without_revision_and_ghost')
1570.1.2 by Robert Collins
Import bzrtools' 'fix' command as 'bzr reconcile.'
68
        repo.add_inventory('missing', inv, [])
1910.2.23 by Aaron Bentley
Fix up test cases that manually construct inventories
69
        inv = Inventory(revision_id='references_missing')
70
        inv.root.revision = 'references_missing'
1570.1.14 by Robert Collins
Enforce repository consistency during 'fetch' operations.
71
        sha1 = repo.add_inventory('references_missing', inv, ['missing'])
72
        rev = Revision(timestamp=0,
73
                       timezone=None,
74
                       committer="Foo Bar <foo@example.com>",
75
                       message="Message",
76
                       inventory_sha1=sha1,
77
                       revision_id='references_missing')
78
        rev.parent_ids = ['missing']
79
        repo.add_revision('references_missing', rev)
1570.1.2 by Robert Collins
Import bzrtools' 'fix' command as 'bzr reconcile.'
80
81
        # a inventory with no parents and the revision has parents..
82
        # i.e. a ghost.
1570.1.8 by Robert Collins
Only reconcile if doing so will perform gc or correct ancestry.
83
        repo = self.make_repository('inventory_one_ghost')
1910.2.23 by Aaron Bentley
Fix up test cases that manually construct inventories
84
        inv = Inventory(revision_id='ghost')
85
        inv.root.revision = 'ghost'
1570.1.2 by Robert Collins
Import bzrtools' 'fix' command as 'bzr reconcile.'
86
        sha1 = repo.add_inventory('ghost', inv, [])
87
        rev = Revision(timestamp=0,
88
                       timezone=None,
89
                       committer="Foo Bar <foo@example.com>",
90
                       message="Message",
91
                       inventory_sha1=sha1,
92
                       revision_id='ghost')
93
        rev.parent_ids = ['the_ghost']
94
        repo.add_revision('ghost', rev)
95
         
96
        # a inventory with a ghost that can be corrected now.
97
        t.copy_tree('inventory_one_ghost', 'inventory_ghost_present')
2381.1.1 by Robert Collins
Split out hpss test fixes which dont depend on new or altered API's.
98
        bzrdir_url = self.get_url('inventory_ghost_present')
99
        bzrdir = bzrlib.bzrdir.BzrDir.open(bzrdir_url)
100
        repo = bzrdir.open_repository()
1910.2.23 by Aaron Bentley
Fix up test cases that manually construct inventories
101
        inv = Inventory(revision_id='the_ghost')
102
        inv.root.revision = 'the_ghost'
1570.1.2 by Robert Collins
Import bzrtools' 'fix' command as 'bzr reconcile.'
103
        sha1 = repo.add_inventory('the_ghost', inv, [])
104
        rev = Revision(timestamp=0,
105
                       timezone=None,
106
                       committer="Foo Bar <foo@example.com>",
107
                       message="Message",
108
                       inventory_sha1=sha1,
109
                       revision_id='the_ghost')
110
        rev.parent_ids = []
111
        repo.add_revision('the_ghost', rev)
112
1692.1.1 by Robert Collins
* Repository.reconcile now takes a thorough keyword parameter to allow
113
    def checkEmptyReconcile(self, **kwargs):
114
        """Check a reconcile on an empty repository."""
1570.1.2 by Robert Collins
Import bzrtools' 'fix' command as 'bzr reconcile.'
115
        self.make_repository('empty')
2381.1.1 by Robert Collins
Split out hpss test fixes which dont depend on new or altered API's.
116
        d = bzrlib.bzrdir.BzrDir.open(self.get_url('empty'))
1570.1.14 by Robert Collins
Enforce repository consistency during 'fetch' operations.
117
        # calling on a empty repository should do nothing
1692.1.1 by Robert Collins
* Repository.reconcile now takes a thorough keyword parameter to allow
118
        reconciler = d.find_repository().reconcile(**kwargs)
1570.1.8 by Robert Collins
Only reconcile if doing so will perform gc or correct ancestry.
119
        # no inconsistent parents should have been found
120
        self.assertEqual(0, reconciler.inconsistent_parents)
121
        # and no garbage inventories
122
        self.assertEqual(0, reconciler.garbage_inventories)
123
        # 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
124
        self.checkNoBackupInventory(d)
125
126
    def test_reconile_empty(self):
127
        # in an empty repo, theres nothing to do.
128
        self.checkEmptyReconcile()
129
130
    def test_reconcile_empty_thorough(self):
131
        # reconcile should accept thorough=True
132
        self.checkEmptyReconcile(thorough=True)
1570.1.2 by Robert Collins
Import bzrtools' 'fix' command as 'bzr reconcile.'
133
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.
134
    def test_convenience_reconcile_inventory_without_revision_reconcile(self):
1570.1.14 by Robert Collins
Enforce repository consistency during 'fetch' operations.
135
        # smoke test for the all in one ui tool
2381.1.1 by Robert Collins
Split out hpss test fixes which dont depend on new or altered API's.
136
        bzrdir_url = self.get_url('inventory_without_revision')
137
        bzrdir = bzrlib.bzrdir.BzrDir.open(bzrdir_url)
138
        reconcile(bzrdir)
1570.1.14 by Robert Collins
Enforce repository consistency during 'fetch' operations.
139
        # now the backup should have it but not the current inventory
2381.1.1 by Robert Collins
Split out hpss test fixes which dont depend on new or altered API's.
140
        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.
141
        self.check_missing_was_removed(repo)
142
143
    def test_reweave_inventory_without_revision(self):
144
        # an excess inventory on its own is only reconciled by using thorough
2381.1.1 by Robert Collins
Split out hpss test fixes which dont depend on new or altered API's.
145
        d_url = self.get_url('inventory_without_revision')
146
        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.
147
        repo = d.open_repository()
148
        self.checkUnreconciled(d, repo.reconcile())
149
        reconciler = repo.reconcile(thorough=True)
150
        # no bad parents
151
        self.assertEqual(0, reconciler.inconsistent_parents)
152
        # and one garbage inventoriy
153
        self.assertEqual(1, reconciler.garbage_inventories)
154
        self.check_missing_was_removed(repo)
1570.1.14 by Robert Collins
Enforce repository consistency during 'fetch' operations.
155
1692.1.1 by Robert Collins
* Repository.reconcile now takes a thorough keyword parameter to allow
156
    def check_thorough_reweave_missing_revision(self, aBzrDir, reconcile,
157
            **kwargs):
1570.1.14 by Robert Collins
Enforce repository consistency during 'fetch' operations.
158
        # actual low level test.
1692.1.1 by Robert Collins
* Repository.reconcile now takes a thorough keyword parameter to allow
159
        repo = aBzrDir.open_repository()
1594.2.9 by Robert Collins
Teach Knit repositories how to handle ghosts without corrupting at all.
160
        if ([None, 'missing', 'references_missing'] 
161
            != repo.get_ancestry('references_missing')):
162
            # the repo handles ghosts without corruption, so reconcile has
163
            # nothing to do here
164
            expected_inconsistent_parents = 0
165
        else:
166
            expected_inconsistent_parents = 1
1692.1.1 by Robert Collins
* Repository.reconcile now takes a thorough keyword parameter to allow
167
        reconciler = reconcile(**kwargs)
1594.2.9 by Robert Collins
Teach Knit repositories how to handle ghosts without corrupting at all.
168
        # some number of inconsistent parents should have been found
169
        self.assertEqual(expected_inconsistent_parents,
170
                         reconciler.inconsistent_parents)
1570.1.8 by Robert Collins
Only reconcile if doing so will perform gc or correct ancestry.
171
        # and one garbage inventories
172
        self.assertEqual(1, reconciler.garbage_inventories)
1570.1.2 by Robert Collins
Import bzrtools' 'fix' command as 'bzr reconcile.'
173
        # 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
174
        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.
175
        self.check_missing_was_removed(repo)
1570.1.14 by Robert Collins
Enforce repository consistency during 'fetch' operations.
176
        # and the parent list for 'references_missing' should have that
177
        # revision a ghost now.
178
        self.assertEqual([None, 'references_missing'],
179
                         repo.get_ancestry('references_missing'))
1570.1.2 by Robert Collins
Import bzrtools' 'fix' command as 'bzr reconcile.'
180
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.
181
    def check_missing_was_removed(self, repo):
182
        backup = repo.control_weaves.get_weave('inventory.backup',
183
                                               repo.get_transaction())
184
        self.assertTrue('missing' in backup.versions())
185
        self.assertRaises(errors.RevisionNotPresent,
186
                          repo.get_inventory, 'missing')
187
1692.1.1 by Robert Collins
* Repository.reconcile now takes a thorough keyword parameter to allow
188
    def test_reweave_inventory_without_revision_reconciler(self):
189
        # smoke test for the all in one Reconciler class,
190
        # other tests use the lower level repo.reconcile()
2381.1.1 by Robert Collins
Split out hpss test fixes which dont depend on new or altered API's.
191
        d_url = self.get_url('inventory_without_revision_and_ghost')
192
        d = bzrlib.bzrdir.BzrDir.open(d_url)
1692.1.1 by Robert Collins
* Repository.reconcile now takes a thorough keyword parameter to allow
193
        def reconcile():
194
            reconciler = Reconciler(d)
195
            reconciler.reconcile()
196
            return reconciler
197
        self.check_thorough_reweave_missing_revision(d, reconcile)
198
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.
199
    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
200
        # actual low level test.
2381.1.1 by Robert Collins
Split out hpss test fixes which dont depend on new or altered API's.
201
        d_url = self.get_url('inventory_without_revision_and_ghost')
202
        d = bzrlib.bzrdir.BzrDir.open(d_url)
1692.1.1 by Robert Collins
* Repository.reconcile now takes a thorough keyword parameter to allow
203
        repo = d.open_repository()
204
        # nothing should have been altered yet : inventories without
205
        # revisions are not data loss incurring for current format
206
        self.check_thorough_reweave_missing_revision(d, repo.reconcile,
207
            thorough=True)
208
1570.1.2 by Robert Collins
Import bzrtools' 'fix' command as 'bzr reconcile.'
209
    def test_reweave_inventory_preserves_a_revision_with_ghosts(self):
2381.1.1 by Robert Collins
Split out hpss test fixes which dont depend on new or altered API's.
210
        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
211
        reconciler = d.open_repository().reconcile(thorough=True)
1570.1.8 by Robert Collins
Only reconcile if doing so will perform gc or correct ancestry.
212
        # no inconsistent parents should have been found: 
213
        # the lack of a parent for ghost is normal
214
        self.assertEqual(0, reconciler.inconsistent_parents)
215
        # and one garbage inventories
216
        self.assertEqual(0, reconciler.garbage_inventories)
1570.1.2 by Robert Collins
Import bzrtools' 'fix' command as 'bzr reconcile.'
217
        # now the current inventory should still have 'ghost'
218
        repo = d.open_repository()
219
        repo.get_inventory('ghost')
220
        self.assertEqual([None, 'ghost'], repo.get_ancestry('ghost'))
221
        
222
    def test_reweave_inventory_fixes_ancestryfor_a_present_ghost(self):
2381.1.1 by Robert Collins
Split out hpss test fixes which dont depend on new or altered API's.
223
        d = bzrlib.bzrdir.BzrDir.open(self.get_url('inventory_ghost_present'))
1570.1.2 by Robert Collins
Import bzrtools' 'fix' command as 'bzr reconcile.'
224
        repo = d.open_repository()
1594.2.9 by Robert Collins
Teach Knit repositories how to handle ghosts without corrupting at all.
225
        ghost_ancestry = repo.get_ancestry('ghost')
226
        if ghost_ancestry == [None, 'the_ghost', 'ghost']:
227
            # the repo handles ghosts without corruption, so reconcile has
228
            # nothing to do
229
            return
230
        self.assertEqual([None, 'ghost'], ghost_ancestry)
1594.2.7 by Robert Collins
Add versionedfile.fix_parents api for correcting data post hoc.
231
        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.
232
        # 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.
233
        # one inconsistent parents should have been found : the
234
        # available but not reference parent for ghost.
235
        self.assertEqual(1, reconciler.inconsistent_parents)
236
        # and no garbage inventories
237
        self.assertEqual(0, reconciler.garbage_inventories)
1570.1.2 by Robert Collins
Import bzrtools' 'fix' command as 'bzr reconcile.'
238
        # now the current inventory should still have 'ghost'
239
        repo = d.open_repository()
240
        repo.get_inventory('ghost')
241
        repo.get_inventory('the_ghost')
242
        self.assertEqual([None, 'the_ghost', 'ghost'], repo.get_ancestry('ghost'))
243
        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
244
1692.1.2 by Robert Collins
Teach reconcile to check the left-most parent is correct in the revision graph.
245
246
class TestReconcileWithIncorrectRevisionCache(TestReconcile):
247
    """Ancestry data gets cached in knits and weaves should be reconcilable.
248
249
    This class tests that reconcile can correct invalid caches (such as after
250
    a reconcile).
251
    """
252
253
    def setUp(self):
2381.1.1 by Robert Collins
Split out hpss test fixes which dont depend on new or altered API's.
254
        self.reduceLockdirTimeout()
1692.1.2 by Robert Collins
Teach reconcile to check the left-most parent is correct in the revision graph.
255
        super(TestReconcileWithIncorrectRevisionCache, self).setUp()
256
        
257
        t = get_transport(self.get_url())
258
        # we need a revision with two parents in the wrong order
259
        # which should trigger reinsertion.
260
        # and another with the first one correct but the other two not
261
        # which should not trigger reinsertion.
262
        # these need to be in different repositories so that we don't
263
        # trigger a reconcile based on the other case.
264
        # there is no api to construct a broken knit repository at
265
        # this point. if we ever encounter a bad graph in a knit repo
266
        # we should add a lower level api to allow constructing such cases.
267
        
268
        # first off the common logic:
269
        tree = self.make_branch_and_tree('wrong-first-parent')
2381.1.1 by Robert Collins
Split out hpss test fixes which dont depend on new or altered API's.
270
        second_tree = self.make_branch_and_tree('reversed-secondary-parents')
271
        for t in [tree, second_tree]:
272
            t.commit('1', rev_id='1')
273
            uncommit(t.branch, tree=t)
274
            t.commit('2', rev_id='2')
275
            uncommit(t.branch, tree=t)
276
            t.commit('3', rev_id='3')
277
            uncommit(t.branch, tree=t)
278
        #second_tree = self.make_branch_and_tree('reversed-secondary-parents')
279
        #second_tree.pull(tree) # XXX won't copy the repo?
280
        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.
281
282
        # now setup the wrong-first parent case
283
        repo = tree.branch.repository
1910.2.23 by Aaron Bentley
Fix up test cases that manually construct inventories
284
        inv = Inventory(revision_id='wrong-first-parent')
285
        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.
286
        sha1 = repo.add_inventory('wrong-first-parent', inv, ['2', '1'])
287
        rev = Revision(timestamp=0,
288
                       timezone=None,
289
                       committer="Foo Bar <foo@example.com>",
290
                       message="Message",
291
                       inventory_sha1=sha1,
292
                       revision_id='wrong-first-parent')
293
        rev.parent_ids = ['1', '2']
294
        repo.add_revision('wrong-first-parent', rev)
295
296
        # now setup the wrong-secondary parent case
297
        repo = repo_secondary
1910.2.23 by Aaron Bentley
Fix up test cases that manually construct inventories
298
        inv = Inventory(revision_id='wrong-secondary-parent')
299
        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.
300
        sha1 = repo.add_inventory('wrong-secondary-parent', inv, ['1', '3', '2'])
301
        rev = Revision(timestamp=0,
302
                       timezone=None,
303
                       committer="Foo Bar <foo@example.com>",
304
                       message="Message",
305
                       inventory_sha1=sha1,
306
                       revision_id='wrong-secondary-parent')
307
        rev.parent_ids = ['1', '2', '3']
308
        repo.add_revision('wrong-secondary-parent', rev)
309
310
    def test_reconcile_wrong_order(self):
311
        # a wrong order in primary parents is optionally correctable
2381.1.1 by Robert Collins
Split out hpss test fixes which dont depend on new or altered API's.
312
        t = get_transport(self.get_url()).clone('wrong-first-parent')
313
        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.
314
        repo = d.open_repository()
315
        g = repo.get_revision_graph()
316
        if g['wrong-first-parent'] == ['1', '2']:
317
            raise TestSkipped('wrong-first-parent is not setup for testing')
318
        self.checkUnreconciled(d, repo.reconcile())
319
        # nothing should have been altered yet : inventories without
320
        # revisions are not data loss incurring for current format
321
        reconciler = repo.reconcile(thorough=True)
322
        # these show up as inconsistent parents
323
        self.assertEqual(1, reconciler.inconsistent_parents)
1692.1.1 by Robert Collins
* Repository.reconcile now takes a thorough keyword parameter to allow
324
        # and no garbage inventories
325
        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.
326
        # and should have been fixed:
327
        g = repo.get_revision_graph()
328
        self.assertEqual(['1', '2'], g['wrong-first-parent'])
329
330
    def test_reconcile_wrong_order_secondary(self):
331
        # a wrong order in secondary parents is ignored.
2381.1.1 by Robert Collins
Split out hpss test fixes which dont depend on new or altered API's.
332
        t = get_transport(self.get_url()).clone('reversed-secondary-parents')
333
        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.
334
        repo = d.open_repository()
335
        self.checkUnreconciled(d, repo.reconcile())
336
        self.checkUnreconciled(d, repo.reconcile(thorough=True))