/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
1
# (C) 2005, 2006 Canonical Ltd
2
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.
7
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.
12
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 bzrdir implementations - tests a bzrdir format."""
18
19
import os
1666.1.6 by Robert Collins
Make knit the default format.
20
import re
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
21
import sys
22
1534.1.31 by Robert Collins
Deprecated fetch.fetch and fetch.greedy_fetch for branch.fetch, and move the Repository.fetch internals to InterRepo and InterWeaveRepo.
23
import bzrlib
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
24
import bzrlib.bzrdir as bzrdir
25
from bzrlib.branch import Branch, needs_read_lock, needs_write_lock
26
from bzrlib.commit import commit
27
import bzrlib.errors as errors
28
from bzrlib.errors import (FileExists,
29
                           NoSuchRevision,
30
                           NoSuchFile,
31
                           UninitializableFormat,
32
                           NotBranchError,
33
                           )
34
import bzrlib.repository as repository
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
35
from bzrlib.revision import NULL_REVISION
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
36
from bzrlib.tests import TestCase, TestCaseWithTransport, TestSkipped
37
from bzrlib.tests.bzrdir_implementations.test_bzrdir import TestCaseWithBzrDir
38
from bzrlib.trace import mutter
39
import bzrlib.transactions as transactions
40
from bzrlib.transport import get_transport
41
from bzrlib.upgrade import upgrade
42
from bzrlib.workingtree import WorkingTree
43
44
45
class TestCaseWithRepository(TestCaseWithBzrDir):
46
47
    def setUp(self):
48
        super(TestCaseWithRepository, self).setUp()
49
1666.1.4 by Robert Collins
* 'Metadir' is now the default disk format. This improves behaviour in
50
    def make_branch(self, relpath, format=None):
51
        repo = self.make_repository(relpath, format=None)
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
52
        return repo.bzrdir.create_branch()
53
1666.1.4 by Robert Collins
* 'Metadir' is now the default disk format. This improves behaviour in
54
    def make_repository(self, relpath, format=None):
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
55
        made_control = self.make_bzrdir(relpath)
56
        return self.repository_format.initialize(made_control)
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
57
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
58
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
59
class TestRepository(TestCaseWithRepository):
60
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
61
    def test_clone_to_default_format(self):
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
62
        #TODO: Test that cloning a repository preserves all the information
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
63
        # such as signatures[not tested yet] etc etc.
64
        # when changing to the current default format.
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
65
        tree_a = self.make_branch_and_tree('a')
66
        self.build_tree(['a/foo'])
67
        tree_a.add('foo', 'file1')
68
        tree_a.commit('rev1', rev_id='rev1')
69
        bzrdirb = self.make_bzrdir('b')
70
        repo_b = tree_a.branch.repository.clone(bzrdirb)
71
        tree_b = repo_b.revision_tree('rev1')
72
        tree_b.get_file_text('file1')
73
        rev1 = repo_b.get_revision('rev1')
74
75
    def test_clone_specific_format(self):
76
        """todo"""
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
77
78
    def test_format_initialize_find_open(self):
79
        # loopback test to check the current format initializes to itself.
80
        if not self.repository_format.is_supported():
81
            # unsupported formats are not loopback testable
82
            # because the default open will not open them and
83
            # they may not be initializable.
84
            return
85
        # supported formats must be able to init and open
86
        t = get_transport(self.get_url())
87
        readonly_t = get_transport(self.get_readonly_url())
88
        made_control = self.bzrdir_format.initialize(t.base)
89
        made_repo = self.repository_format.initialize(made_control)
90
        self.failUnless(isinstance(made_repo, repository.Repository))
91
        self.assertEqual(made_control, made_repo.bzrdir)
92
93
        # find it via bzrdir opening:
94
        opened_control = bzrdir.BzrDir.open(readonly_t.base)
95
        direct_opened_repo = opened_control.open_repository()
96
        self.assertEqual(direct_opened_repo.__class__, made_repo.__class__)
97
        self.assertEqual(opened_control, direct_opened_repo.bzrdir)
98
99
        self.failUnless(isinstance(direct_opened_repo._format,
100
                        self.repository_format.__class__))
101
        # find it via Repository.open
102
        opened_repo = repository.Repository.open(readonly_t.base)
103
        self.failUnless(isinstance(opened_repo, made_repo.__class__))
104
        self.assertEqual(made_repo._format.__class__,
105
                         opened_repo._format.__class__)
106
        # if it has a unique id string, can we probe for it ?
107
        try:
108
            self.repository_format.get_format_string()
109
        except NotImplementedError:
110
            return
111
        self.assertEqual(self.repository_format,
112
                         repository.RepositoryFormat.find_format(opened_control))
113
114
    def test_create_repository(self):
1534.6.1 by Robert Collins
allow API creation of shared repositories
115
        # bzrdir can construct a repository for itself.
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
116
        if not self.bzrdir_format.is_supported():
117
            # unsupported formats are not loopback testable
118
            # because the default open will not open them and
119
            # they may not be initializable.
120
            return
121
        t = get_transport(self.get_url())
122
        made_control = self.bzrdir_format.initialize(t.base)
123
        made_repo = made_control.create_repository()
124
        self.failUnless(isinstance(made_repo, repository.Repository))
125
        self.assertEqual(made_control, made_repo.bzrdir)
1534.6.1 by Robert Collins
allow API creation of shared repositories
126
        
127
    def test_create_repository_shared(self):
128
        # bzrdir can construct a shared repository.
129
        if not self.bzrdir_format.is_supported():
130
            # unsupported formats are not loopback testable
131
            # because the default open will not open them and
132
            # they may not be initializable.
133
            return
134
        t = get_transport(self.get_url())
135
        made_control = self.bzrdir_format.initialize(t.base)
136
        try:
137
            made_repo = made_control.create_repository(shared=True)
138
        except errors.IncompatibleFormat:
139
            # not all repository formats understand being shared, or
140
            # may only be shared in some circumstances.
141
            return
142
        self.failUnless(isinstance(made_repo, repository.Repository))
143
        self.assertEqual(made_control, made_repo.bzrdir)
1534.6.3 by Robert Collins
find_repository sufficiently robust.
144
        self.assertTrue(made_repo.is_shared())
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
145
146
    def test_revision_tree(self):
147
        wt = self.make_branch_and_tree('.')
148
        wt.commit('lala!', rev_id='revision-1', allow_pointless=True)
149
        tree = wt.branch.repository.revision_tree('revision-1')
150
        self.assertEqual(list(tree.list_files()), [])
151
        tree = wt.branch.repository.revision_tree(None)
152
        self.assertEqual(len(tree.list_files()), 0)
153
        tree = wt.branch.repository.revision_tree(NULL_REVISION)
154
        self.assertEqual(len(tree.list_files()), 0)
155
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
156
    def test_fetch(self):
1534.1.29 by Robert Collins
Add a test environment for InterRepository objects, and remove the fetch corner case tests from test_repository.
157
        # smoke test fetch to ensure that the convenience function works.
158
        # it is defined as a convenience function with the underlying 
159
        # functionality provided by an InterRepository
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
160
        tree_a = self.make_branch_and_tree('a')
161
        self.build_tree(['a/foo'])
162
        tree_a.add('foo', 'file1')
163
        tree_a.commit('rev1', rev_id='rev1')
1534.1.29 by Robert Collins
Add a test environment for InterRepository objects, and remove the fetch corner case tests from test_repository.
164
        # fetch with a default limit (grab everything)
165
        repo = bzrdir.BzrDir.create_repository(self.get_url('b'))
1534.1.31 by Robert Collins
Deprecated fetch.fetch and fetch.greedy_fetch for branch.fetch, and move the Repository.fetch internals to InterRepo and InterWeaveRepo.
166
        repo.fetch(tree_a.branch.repository,
167
                   revision_id=None,
168
                   pb=bzrlib.progress.DummyProgress())
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
169
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
170
    def test_clone_bzrdir_repository_revision(self):
171
        # make a repository with some revisions,
172
        # and clone it, this should not have unreferenced revisions.
173
        # also: test cloning with a revision id of NULL_REVISION -> empty repo.
174
        raise TestSkipped('revision limiting is not implemented yet.')
175
176
    def test_clone_repository_basis_revision(self):
177
        raise TestSkipped('the use of a basis should not add noise data to the result.')
178
179
    def test_clone_repository_incomplete_source_with_basis(self):
180
        # ensure that basis really does grab from the basis by having incomplete source
181
        tree = self.make_branch_and_tree('commit_tree')
182
        self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
183
        tree.add('foo')
184
        tree.commit('revision 1', rev_id='1')
185
        source = self.make_repository('source')
186
        # this gives us an incomplete repository
187
        tree.bzrdir.open_repository().copy_content_into(source)
188
        tree.commit('revision 2', rev_id='2', allow_pointless=True)
189
        self.assertFalse(source.has_revision('2'))
190
        target = source.bzrdir.clone(self.get_url('target'), basis=tree.bzrdir)
191
        self.assertTrue(target.open_repository().has_revision('2'))
192
1534.6.5 by Robert Collins
Cloning of repos preserves shared and make-working-tree attributes.
193
    def test_clone_shared_no_tree(self):
194
        # cloning a shared repository keeps it shared
195
        # and preserves the make_working_tree setting.
196
        made_control = self.make_bzrdir('source')
197
        try:
198
            made_repo = made_control.create_repository(shared=True)
199
        except errors.IncompatibleFormat:
200
            # not all repository formats understand being shared, or
201
            # may only be shared in some circumstances.
202
            return
203
        made_repo.set_make_working_trees(False)
204
        result = made_control.clone(self.get_url('target'))
205
        self.failUnless(isinstance(made_repo, repository.Repository))
206
        self.assertEqual(made_control, made_repo.bzrdir)
207
        self.assertTrue(result.open_repository().is_shared())
208
        self.assertFalse(result.open_repository().make_working_trees())
209
1556.1.4 by Robert Collins
Add a new format for what will become knit, and the surrounding logic to upgrade repositories within metadirs, and tests for the same.
210
    def test_upgrade_preserves_signatures(self):
211
        wt = self.make_branch_and_tree('source')
212
        wt.commit('A', allow_pointless=True, rev_id='A')
213
        wt.branch.repository.sign_revision('A',
214
            bzrlib.gpg.LoopbackGPGStrategy(None))
1563.2.31 by Robert Collins
Convert Knit repositories to use knits.
215
        old_signature = wt.branch.repository.get_signature_text('A')
1556.1.4 by Robert Collins
Add a new format for what will become knit, and the surrounding logic to upgrade repositories within metadirs, and tests for the same.
216
        try:
217
            old_format = bzrdir.BzrDirFormat.get_default_format()
218
            # This gives metadir branches something they can convert to.
219
            # it would be nice to have a 'latest' vs 'default' concept.
220
            bzrdir.BzrDirFormat.set_default_format(bzrdir.BzrDirMetaFormat1())
221
            try:
222
                upgrade(wt.basedir)
223
            finally:
224
                bzrdir.BzrDirFormat.set_default_format(old_format)
225
        except errors.UpToDateFormat:
226
            # this is in the most current format already.
227
            return
228
        wt = WorkingTree.open(wt.basedir)
1563.2.31 by Robert Collins
Convert Knit repositories to use knits.
229
        new_signature = wt.branch.repository.get_signature_text('A')
1556.1.4 by Robert Collins
Add a new format for what will become knit, and the surrounding logic to upgrade repositories within metadirs, and tests for the same.
230
        self.assertEqual(old_signature, new_signature)
231
1594.2.23 by Robert Collins
Test versioned file storage handling of clean/dirty status for accessed versioned files.
232
    def test_exposed_versioned_files_are_marked_dirty(self):
233
        repo = self.make_repository('.')
234
        repo.lock_write()
235
        inv = repo.get_inventory_weave()
236
        repo.unlock()
237
        self.assertRaises(errors.OutSideTransaction, inv.add_lines, 'foo', [], [])
238
1624.3.19 by Olaf Conradi
New call get_format_description to give a user-friendly description of a
239
    def test_format_description(self):
240
        repo = self.make_repository('.')
241
        text = repo._format.get_format_description()
242
        self.failUnless(len(text))
243
1666.1.6 by Robert Collins
Make knit the default format.
244
    def assertMessageRoundtrips(self, message):
245
        """Assert that message roundtrips to a repository and back intact."""
246
        tree = self.make_branch_and_tree('.')
247
        tree.commit(message, rev_id='a', allow_pointless=True)
248
        rev = tree.branch.repository.get_revision('a')
249
        # we have to manually escape this as we dont try to
250
        # roundtrip xml invalid characters at this point.
251
        # when escaping is moved to the serialiser, this test
252
        # can check against the literal message rather than
253
        # this escaped version.
254
        escaped_message, escape_count = re.subn(
255
            u'[^\x09\x0A\x0D\u0020-\uD7FF\uE000-\uFFFD]+',
256
            lambda match: match.group(0).encode('unicode_escape'),
257
            message)
258
        escaped_message= re.sub('\r', '\n', escaped_message)
259
        self.assertEqual(rev.message, escaped_message)
260
        # insist the class is unicode no matter what came in for 
261
        # consistency.
262
        self.assertIsInstance(rev.message, unicode)
263
264
    def test_commit_unicode_message(self):
265
        # a siple unicode message should be preserved
266
        self.assertMessageRoundtrips(u'foo bar gamm\xae plop')
267
268
    def test_commit_unicode_control_characters(self):
269
        # a unicode message with control characters should roundtrip too.
270
        self.assertMessageRoundtrips(
271
            "All 8-bit chars: " +  ''.join([unichr(x) for x in range(256)]))
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
272
273
class TestCaseWithComplexRepository(TestCaseWithRepository):
274
275
    def setUp(self):
276
        super(TestCaseWithComplexRepository, self).setUp()
277
        tree_a = self.make_branch_and_tree('a')
278
        self.bzrdir = tree_a.branch.bzrdir
279
        # add a corrupt inventory 'orphan'
1534.1.34 by Robert Collins
Move missing_revision_ids from Repository to InterRepository, and eliminate the now unused Repository._compatible_formats method.
280
        # this may need some generalising for knits.
1563.2.10 by Robert Collins
Change weave store to be a versioned store, using WeaveFiles which maintain integrity without needing explicit 'put' operations.
281
        inv_file = tree_a.branch.repository.control_weaves.get_weave(
282
            'inventory', 
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
283
            tree_a.branch.repository.get_transaction())
1563.2.10 by Robert Collins
Change weave store to be a versioned store, using WeaveFiles which maintain integrity without needing explicit 'put' operations.
284
        inv_file.add_lines('orphan', [], [])
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
285
        # add a real revision 'rev1'
286
        tree_a.commit('rev1', rev_id='rev1', allow_pointless=True)
287
        # add a real revision 'rev2' based on rev1
288
        tree_a.commit('rev2', rev_id='rev2', allow_pointless=True)
1594.2.3 by Robert Collins
bugfix revision.MultipleRevisionSources.get_revision_graph to integrate ghosts between sources. [slow on weaves, fast on knits.
289
        # add a reference to a ghost
290
        tree_a.add_pending_merge('ghost1')
291
        tree_a.commit('rev3', rev_id='rev3', allow_pointless=True)
292
        # add another reference to a ghost, and a second ghost.
293
        tree_a.add_pending_merge('ghost1')
294
        tree_a.add_pending_merge('ghost2')
295
        tree_a.commit('rev4', rev_id='rev4', allow_pointless=True)
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
296
297
    def test_all_revision_ids(self):
298
        # all_revision_ids -> all revisions
1594.2.3 by Robert Collins
bugfix revision.MultipleRevisionSources.get_revision_graph to integrate ghosts between sources. [slow on weaves, fast on knits.
299
        self.assertEqual(['rev1', 'rev2', 'rev3', 'rev4'],
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
300
                         self.bzrdir.open_repository().all_revision_ids())
301
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
302
    def test_get_ancestry_missing_revision(self):
1534.1.34 by Robert Collins
Move missing_revision_ids from Repository to InterRepository, and eliminate the now unused Repository._compatible_formats method.
303
        # get_ancestry(revision that is in some data but not fully installed
304
        # -> NoSuchRevision
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
305
        self.assertRaises(errors.NoSuchRevision,
306
                          self.bzrdir.open_repository().get_ancestry, 'orphan')
1570.1.13 by Robert Collins
Check for incorrect revision parentage in the weave during revision access.
307
1590.1.1 by Robert Collins
Improve common_ancestor performance.
308
    def test_get_revision_graph(self):
309
        # we can get a mapping of id->parents for the entire revision graph or bits thereof.
1594.2.3 by Robert Collins
bugfix revision.MultipleRevisionSources.get_revision_graph to integrate ghosts between sources. [slow on weaves, fast on knits.
310
        self.assertEqual({'rev1':[],
311
                          'rev2':['rev1'],
312
                          'rev3':['rev2'],
313
                          'rev4':['rev3'],
314
                          },
1590.1.1 by Robert Collins
Improve common_ancestor performance.
315
                         self.bzrdir.open_repository().get_revision_graph(None))
316
        self.assertEqual({'rev1':[]},
317
                         self.bzrdir.open_repository().get_revision_graph('rev1'))
1594.2.3 by Robert Collins
bugfix revision.MultipleRevisionSources.get_revision_graph to integrate ghosts between sources. [slow on weaves, fast on knits.
318
        self.assertEqual({'rev1':[],
319
                          'rev2':['rev1']},
1590.1.1 by Robert Collins
Improve common_ancestor performance.
320
                         self.bzrdir.open_repository().get_revision_graph('rev2'))
321
        self.assertRaises(NoSuchRevision,
322
                          self.bzrdir.open_repository().get_revision_graph,
323
                          'orphan')
1594.2.3 by Robert Collins
bugfix revision.MultipleRevisionSources.get_revision_graph to integrate ghosts between sources. [slow on weaves, fast on knits.
324
        # and ghosts are not mentioned
325
        self.assertEqual({'rev1':[],
326
                          'rev2':['rev1'],
327
                          'rev3':['rev2'],
328
                          },
329
                         self.bzrdir.open_repository().get_revision_graph('rev3'))
330
331
    def test_get_revision_graph_with_ghosts(self):
332
        # we can get a graph object with roots, ghosts, ancestors and
333
        # descendants.
334
        repo = self.bzrdir.open_repository()
335
        graph = repo.get_revision_graph_with_ghosts([])
336
        self.assertEqual(set(['rev1']), graph.roots)
337
        self.assertEqual(set(['ghost1', 'ghost2']), graph.ghosts)
338
        self.assertEqual({'rev1':[],
339
                          'rev2':['rev1'],
340
                          'rev3':['rev2', 'ghost1'],
341
                          'rev4':['rev3', 'ghost1', 'ghost2'],
342
                          },
343
                          graph.get_ancestors())
344
        self.assertEqual({'ghost1':{'rev3':1, 'rev4':1},
345
                          'ghost2':{'rev4':1},
346
                          'rev1':{'rev2':1},
347
                          'rev2':{'rev3':1},
348
                          'rev3':{'rev4':1},
349
                          'rev4':{},
350
                          },
351
                          graph.get_descendants())
1590.1.1 by Robert Collins
Improve common_ancestor performance.
352
1570.1.13 by Robert Collins
Check for incorrect revision parentage in the weave during revision access.
353
354
class TestCaseWithCorruptRepository(TestCaseWithRepository):
355
356
    def setUp(self):
357
        super(TestCaseWithCorruptRepository, self).setUp()
358
        # a inventory with no parents and the revision has parents..
359
        # i.e. a ghost.
360
        repo = self.make_repository('inventory_with_unnecessary_ghost')
361
        inv = bzrlib.tree.EmptyTree().inventory
362
        sha1 = repo.add_inventory('ghost', inv, [])
363
        rev = bzrlib.revision.Revision(timestamp=0,
364
                                       timezone=None,
365
                                       committer="Foo Bar <foo@example.com>",
366
                                       message="Message",
367
                                       inventory_sha1=sha1,
368
                                       revision_id='ghost')
369
        rev.parent_ids = ['the_ghost']
370
        repo.add_revision('ghost', rev)
371
         
372
        sha1 = repo.add_inventory('the_ghost', inv, [])
373
        rev = bzrlib.revision.Revision(timestamp=0,
374
                                       timezone=None,
375
                                       committer="Foo Bar <foo@example.com>",
376
                                       message="Message",
377
                                       inventory_sha1=sha1,
378
                                       revision_id='the_ghost')
379
        rev.parent_ids = []
380
        repo.add_revision('the_ghost', rev)
381
        # check its setup usefully
382
        inv_weave = repo.get_inventory_weave()
1563.2.30 by Robert Collins
Remove all but fetch references to revision_store, making the repository references that are weave specific use the RevisionTextStore.text_store attribute.
383
        self.assertEqual(['ghost'], inv_weave.get_ancestry(['ghost']))
1570.1.13 by Robert Collins
Check for incorrect revision parentage in the weave during revision access.
384
1594.2.10 by Robert Collins
Teach knit fetching and branching to only duplicate relevant data avoiding unnecessary reconciles.
385
    def test_corrupt_revision_access_asserts_if_reported_wrong(self):
1570.1.13 by Robert Collins
Check for incorrect revision parentage in the weave during revision access.
386
        repo = repository.Repository.open('inventory_with_unnecessary_ghost')
1594.2.10 by Robert Collins
Teach knit fetching and branching to only duplicate relevant data avoiding unnecessary reconciles.
387
        reported_wrong = False
388
        try:
389
            if repo.get_ancestry('ghost') != [None, 'the_ghost', 'ghost']:
390
                reported_wrong = True
391
        except errors.CorruptRepository:
392
            # caught the bad data:
393
            return
394
        if not reported_wrong:
395
            return
1570.1.13 by Robert Collins
Check for incorrect revision parentage in the weave during revision access.
396
        self.assertRaises(errors.CorruptRepository, repo.get_revision, 'ghost')
397
1594.2.3 by Robert Collins
bugfix revision.MultipleRevisionSources.get_revision_graph to integrate ghosts between sources. [slow on weaves, fast on knits.
398
    def test_corrupt_revision_get_revision_reconcile(self):
1570.1.13 by Robert Collins
Check for incorrect revision parentage in the weave during revision access.
399
        repo = repository.Repository.open('inventory_with_unnecessary_ghost')
400
        repo.get_revision_reconcile('ghost')