/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
2241.1.1 by Martin Pool
Change RepositoryFormat to use a Registry rather than ad-hoc dictionary
1
# Copyright (C) 2006, 2007 Canonical Ltd
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
2
# Authors: Robert Collins <robert.collins@canonical.com>
2241.1.1 by Martin Pool
Change RepositoryFormat to use a Registry rather than ad-hoc dictionary
3
#          and others
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
4
#
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
5
# This program is free software; you can redistribute it and/or modify
6
# it under the terms of the GNU General Public License as published by
7
# the Free Software Foundation; either version 2 of the License, or
8
# (at your option) any later version.
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
9
#
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
10
# This program is distributed in the hope that it will be useful,
11
# but WITHOUT ANY WARRANTY; without even the implied warranty of
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
# GNU General Public License for more details.
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
14
#
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
15
# You should have received a copy of the GNU General Public License
16
# along with this program; if not, write to the Free Software
17
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
19
1904.2.5 by Martin Pool
Fix format warning inside test suite and add test
20
"""Repository implementation tests for bzr.
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
21
22
These test the conformance of all the repository variations to the expected API.
23
Specific tests for individual formats are in the tests/test_repository.py file 
24
rather than in tests/branch_implementations/*.py.
25
"""
26
2241.1.2 by Martin Pool
change to using external Repository format registry
27
from bzrlib import (
28
    repository,
29
    )
2988.1.3 by Robert Collins
Add a new repositoy method _generate_text_key_index for use by reconcile/check.
30
from bzrlib.revision import NULL_REVISION
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
31
from bzrlib.repofmt import (
32
    weaverepo,
33
    )
2745.6.54 by Andrew Bennetts
Tidy test parameterisation in repository_implementations.
34
from bzrlib.remote import RemoteBzrDirFormat, RemoteRepositoryFormat
35
from bzrlib.smart.server import (
36
    SmartTCPServer_for_testing,
37
    ReadonlySmartTCPServer_for_testing,
38
    )
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
39
from bzrlib.tests import (
2745.6.57 by Andrew Bennetts
Some improvements suggested by Martin's review.
40
                          adapt_modules,
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
41
                          default_transport,
2745.6.54 by Andrew Bennetts
Tidy test parameterisation in repository_implementations.
42
                          iter_suite_tests,
2745.6.58 by Andrew Bennetts
Slightly neater test parameterisation in repository_implementations; extract a 'multiply_scenarios' function.
43
                          multiply_scenarios,
44
                          multiply_tests_from_modules,
2553.2.3 by Robert Collins
Split out the common test scenario support from the repository implementation specific code.
45
                          TestScenarioApplier,
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
46
                          TestLoader,
47
                          TestSuite,
48
                          )
2485.7.1 by Robert Collins
Relocate TestCaseWithRepository to be more central.
49
from bzrlib.tests.bzrdir_implementations.test_bzrdir import TestCaseWithBzrDir
2018.5.66 by Wouter van Heyst
Fix repository test parameterization for RemoteRepository.
50
from bzrlib.transport.memory import MemoryServer
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
51
52
2553.2.3 by Robert Collins
Split out the common test scenario support from the repository implementation specific code.
53
class RepositoryTestProviderAdapter(TestScenarioApplier):
2553.2.2 by Robert Collins
Move RepositoryTestProviderAdapter into the tests part of the code base.
54
    """A tool to generate a suite testing multiple repository formats at once.
55
56
    This is done by copying the test once for each transport and injecting
57
    the transport_server, transport_readonly_server, and bzrdir_format and
58
    repository_format classes into each copy. Each copy is also given a new id()
59
    to make it easy to identify.
60
    """
61
62
    def __init__(self, transport_server, transport_readonly_server, formats,
63
                 vfs_transport_factory=None):
2553.2.3 by Robert Collins
Split out the common test scenario support from the repository implementation specific code.
64
        TestScenarioApplier.__init__(self)
2553.2.2 by Robert Collins
Move RepositoryTestProviderAdapter into the tests part of the code base.
65
        self._transport_server = transport_server
66
        self._transport_readonly_server = transport_readonly_server
67
        self._vfs_transport_factory = vfs_transport_factory
68
        self.scenarios = self.formats_to_scenarios(formats)
69
    
70
    def formats_to_scenarios(self, formats):
71
        """Transform the input formats to a list of scenarios.
72
73
        :param formats: A list of (repository_format, bzrdir_format).
74
        """
75
        result = []
76
        for repository_format, bzrdir_format in formats:
77
            scenario = (repository_format.__class__.__name__,
78
                {"transport_server":self._transport_server,
79
                 "transport_readonly_server":self._transport_readonly_server,
80
                 "bzrdir_format":bzrdir_format,
81
                 "repository_format":repository_format,
82
                 })
83
            # Only override the test's vfs_transport_factory if one was
84
            # specified, otherwise just leave the default in place.
85
            if self._vfs_transport_factory:
86
                scenario[1]['vfs_transport_factory'] = self._vfs_transport_factory
87
            result.append(scenario)
88
        return result
89
90
2485.7.1 by Robert Collins
Relocate TestCaseWithRepository to be more central.
91
class TestCaseWithRepository(TestCaseWithBzrDir):
92
93
    def make_repository(self, relpath, format=None):
94
        if format is None:
95
            # Create a repository of the type we are trying to test.
96
            made_control = self.make_bzrdir(relpath)
2553.2.1 by Robert Collins
Overhaul RepositoryTestAdapter to be cleaner and more modular.
97
            repo = self.repository_format.initialize(made_control)
2553.2.2 by Robert Collins
Move RepositoryTestProviderAdapter into the tests part of the code base.
98
            if getattr(self, "repository_to_test_repository", None):
2553.2.1 by Robert Collins
Overhaul RepositoryTestAdapter to be cleaner and more modular.
99
                repo = self.repository_to_test_repository(repo)
100
            return repo
2485.7.1 by Robert Collins
Relocate TestCaseWithRepository to be more central.
101
        else:
102
            return super(TestCaseWithRepository, self).make_repository(
2671.1.1 by Andrew Bennetts
Add support for comparing Repositories with == and != operators.
103
                relpath, format=format)
2485.7.1 by Robert Collins
Relocate TestCaseWithRepository to be more central.
104
105
2745.6.43 by Andrew Bennetts
Tidy imports, docstrings, comments and variable names.
106
class BrokenRepoScenario(object):
107
    """Base class for defining scenarios for testing check and reconcile.
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
108
2745.6.43 by Andrew Bennetts
Tidy imports, docstrings, comments and variable names.
109
    A subclass needs to define the following methods:
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
110
        :populate_repository: a method to use to populate a repository with
111
            sample revisions, inventories and file versions.
2927.2.14 by Andrew Bennetts
Tweaks suggested by review.
112
        :all_versions_after_reconcile: all the versions in repository after
113
            reconcile.  run_test verifies that the text of each of these
114
            versions of the file is unchanged by the reconcile.
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
115
        :populated_parents: a list of (parents list, revision).  Each version
116
            of the file is verified to have the given parents before running
117
            the reconcile.  i.e. this is used to assert that the repo from the
118
            factory is what we expect.
119
        :corrected_parents: a list of (parents list, revision).  Each version
120
            of the file is verified to have the given parents after the
121
            reconcile.  i.e. this is used to assert that reconcile made the
122
            changes we expect it to make.
2927.2.5 by Andrew Bennetts
Remove corrected_inventories, add proper description of corrected_fulltexts.
123
    
124
    A subclass may define the following optional method as well:
125
        :corrected_fulltexts: a list of file versions that should be stored as
126
            fulltexts (not deltas) after reconcile.  run_test will verify that
127
            this occurs.
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
128
    """
129
130
    def __init__(self, test_case):
131
        self.test_case = test_case
132
133
    def make_one_file_inventory(self, repo, revision, parents,
2927.2.3 by Andrew Bennetts
Add fulltexts to avoid bug 155730.
134
                                inv_revision=None, root_revision=None,
2927.2.4 by Andrew Bennetts
Don't create a 'rev3' file version in the test.
135
                                file_contents=None, make_file_version=True):
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
136
        return self.test_case.make_one_file_inventory(
137
            repo, revision, parents, inv_revision=inv_revision,
2927.2.4 by Andrew Bennetts
Don't create a 'rev3' file version in the test.
138
            root_revision=root_revision, file_contents=file_contents,
139
            make_file_version=make_file_version)
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
140
141
    def add_revision(self, repo, revision_id, inv, parent_ids):
142
        return self.test_case.add_revision(repo, revision_id, inv, parent_ids)
143
2927.2.3 by Andrew Bennetts
Add fulltexts to avoid bug 155730.
144
    def corrected_fulltexts(self):
145
        return []
146
2988.1.3 by Robert Collins
Add a new repositoy method _generate_text_key_index for use by reconcile/check.
147
    def repository_text_key_index(self):
148
        result = {}
149
        if self.versioned_root:
150
            result.update(self.versioned_repository_text_keys())
151
        result.update(self.repository_text_keys())
152
        return result
153
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
154
2745.6.50 by Andrew Bennetts
Remove find_bad_ancestors; it's not needed anymore.
155
class UndamagedRepositoryScenario(BrokenRepoScenario):
156
    """A scenario where the repository has no damage.
157
158
    It has a single revision, 'rev1a', with a single file.
159
    """
160
2927.2.14 by Andrew Bennetts
Tweaks suggested by review.
161
    def all_versions_after_reconcile(self):
2592.3.214 by Robert Collins
Merge bzr.dev.
162
        return ('rev1a', )
2745.6.50 by Andrew Bennetts
Remove find_bad_ancestors; it's not needed anymore.
163
164
    def populated_parents(self):
2592.3.214 by Robert Collins
Merge bzr.dev.
165
        return (((), 'rev1a'), )
2745.6.50 by Andrew Bennetts
Remove find_bad_ancestors; it's not needed anymore.
166
167
    def corrected_parents(self):
168
        # Same as the populated parents, because there was nothing wrong.
169
        return self.populated_parents()
170
2951.1.6 by Robert Collins
All check/reconcile tests passing now.
171
    def check_regexes(self, repo):
2988.1.8 by Robert Collins
Change check and reconcile to use the new _generate_text_key_index rather
172
        return ["0 unreferenced text versions"]
2745.6.50 by Andrew Bennetts
Remove find_bad_ancestors; it's not needed anymore.
173
174
    def populate_repository(self, repo):
175
        # make rev1a: A well-formed revision, containing 'a-file'
176
        inv = self.make_one_file_inventory(
177
            repo, 'rev1a', [], root_revision='rev1a')
178
        self.add_revision(repo, 'rev1a', inv, [])
2988.1.2 by Robert Collins
New Repository API find_text_key_references for use by reconcile and check.
179
        self.versioned_root = repo.supports_rich_root()
180
181
    def repository_text_key_references(self):
182
        result = {}
183
        if self.versioned_root:
184
            result.update({('TREE_ROOT', 'rev1a'): True})
185
        result.update({('a-file-id', 'rev1a'): True})
186
        return result
2745.6.50 by Andrew Bennetts
Remove find_bad_ancestors; it's not needed anymore.
187
2988.1.3 by Robert Collins
Add a new repositoy method _generate_text_key_index for use by reconcile/check.
188
    def repository_text_keys(self):
189
        return {('a-file-id', 'rev1a'):[NULL_REVISION]}
190
191
    def versioned_repository_text_keys(self):
192
        return {('TREE_ROOT', 'rev1a'):[NULL_REVISION]}
193
2745.6.50 by Andrew Bennetts
Remove find_bad_ancestors; it's not needed anymore.
194
2745.6.43 by Andrew Bennetts
Tidy imports, docstrings, comments and variable names.
195
class FileParentIsNotInRevisionAncestryScenario(BrokenRepoScenario):
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
196
    """A scenario where a revision 'rev2' has 'a-file' with a
197
    parent 'rev1b' that is not in the revision ancestry.
198
    
199
    Reconcile should remove 'rev1b' from the parents list of 'a-file' in
200
    'rev2', preserving 'rev1a' as a parent.
201
    """
202
2927.2.14 by Andrew Bennetts
Tweaks suggested by review.
203
    def all_versions_after_reconcile(self):
2988.1.8 by Robert Collins
Change check and reconcile to use the new _generate_text_key_index rather
204
        return ('rev1a', 'rev2')
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
205
206
    def populated_parents(self):
2592.3.214 by Robert Collins
Merge bzr.dev.
207
        return (
208
            ((), 'rev1a'),
2988.1.8 by Robert Collins
Change check and reconcile to use the new _generate_text_key_index rather
209
            ((), 'rev1b'), # Will be gc'd
210
            (('rev1a', 'rev1b'), 'rev2')) # Will have parents trimmed
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
211
212
    def corrected_parents(self):
2592.3.214 by Robert Collins
Merge bzr.dev.
213
        return (
214
            ((), 'rev1a'),
2988.1.8 by Robert Collins
Change check and reconcile to use the new _generate_text_key_index rather
215
            (None, 'rev1b'),
2592.3.214 by Robert Collins
Merge bzr.dev.
216
            (('rev1a',), 'rev2'))
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
217
2951.1.6 by Robert Collins
All check/reconcile tests passing now.
218
    def check_regexes(self, repo):
2592.3.214 by Robert Collins
Merge bzr.dev.
219
        return [r"\* a-file-id version rev2 has parents \('rev1a', 'rev1b'\) "
220
                r"but should have \('rev1a',\)",
2988.1.8 by Robert Collins
Change check and reconcile to use the new _generate_text_key_index rather
221
                "0 unreferenced text versions",
2745.6.50 by Andrew Bennetts
Remove find_bad_ancestors; it's not needed anymore.
222
                ]
2745.6.41 by Andrew Bennetts
Test repo.check against all_scenarios.
223
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
224
    def populate_repository(self, repo):
225
        # make rev1a: A well-formed revision, containing 'a-file'
226
        inv = self.make_one_file_inventory(
227
            repo, 'rev1a', [], root_revision='rev1a')
228
        self.add_revision(repo, 'rev1a', inv, [])
229
230
        # make rev1b, which has no Revision, but has an Inventory, and
231
        # a-file
232
        inv = self.make_one_file_inventory(
233
            repo, 'rev1b', [], root_revision='rev1b')
234
        repo.add_inventory('rev1b', inv, [])
235
236
        # make rev2, with a-file.
237
        # a-file has 'rev1b' as an ancestor, even though this is not
238
        # mentioned by 'rev1a', making it an unreferenced ancestor
239
        inv = self.make_one_file_inventory(
240
            repo, 'rev2', ['rev1a', 'rev1b'])
241
        self.add_revision(repo, 'rev2', inv, ['rev1a'])
2988.1.2 by Robert Collins
New Repository API find_text_key_references for use by reconcile and check.
242
        self.versioned_root = repo.supports_rich_root()
243
244
    def repository_text_key_references(self):
245
        result = {}
246
        if self.versioned_root:
247
            result.update({('TREE_ROOT', 'rev1a'): True,
248
                           ('TREE_ROOT', 'rev2'): True})
249
        result.update({('a-file-id', 'rev1a'): True,
250
                       ('a-file-id', 'rev2'): True})
251
        return result
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
252
2988.1.3 by Robert Collins
Add a new repositoy method _generate_text_key_index for use by reconcile/check.
253
    def repository_text_keys(self):
254
        return {('a-file-id', 'rev1a'):[NULL_REVISION],
255
                ('a-file-id', 'rev2'):[('a-file-id', 'rev1a')]}
256
257
    def versioned_repository_text_keys(self):
258
        return {('TREE_ROOT', 'rev1a'):[NULL_REVISION],
259
                ('TREE_ROOT', 'rev2'):[('TREE_ROOT', 'rev1a')]}
260
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
261
2745.6.43 by Andrew Bennetts
Tidy imports, docstrings, comments and variable names.
262
class FileParentHasInaccessibleInventoryScenario(BrokenRepoScenario):
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
263
    """A scenario where a revision 'rev3' containing 'a-file' modified in
264
    'rev3', and with a parent which is in the revision ancestory, but whose
265
    inventory cannot be accessed at all.
266
267
    Reconcile should remove the file version parent whose inventory is
268
    inaccessbile (i.e. remove 'rev1c' from the parents of a-file's rev3).
269
    """
270
2927.2.14 by Andrew Bennetts
Tweaks suggested by review.
271
    def all_versions_after_reconcile(self):
2592.3.214 by Robert Collins
Merge bzr.dev.
272
        return ('rev2', 'rev3')
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
273
274
    def populated_parents(self):
2592.3.214 by Robert Collins
Merge bzr.dev.
275
        return (
276
            ((), 'rev2'),
277
            (('rev1c',), 'rev3'))
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
278
279
    def corrected_parents(self):
2592.3.214 by Robert Collins
Merge bzr.dev.
280
        return (
281
            ((), 'rev2'),
282
            ((), 'rev3'))
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
283
2951.1.6 by Robert Collins
All check/reconcile tests passing now.
284
    def check_regexes(self, repo):
2745.6.43 by Andrew Bennetts
Tidy imports, docstrings, comments and variable names.
285
        return [r"\* a-file-id version rev3 has parents "
2592.3.214 by Robert Collins
Merge bzr.dev.
286
                r"\('rev1c',\) but should have \(\)",
2745.6.50 by Andrew Bennetts
Remove find_bad_ancestors; it's not needed anymore.
287
                ]
2745.6.41 by Andrew Bennetts
Test repo.check against all_scenarios.
288
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
289
    def populate_repository(self, repo):
290
        # make rev2, with a-file
291
        # a-file is sane
292
        inv = self.make_one_file_inventory(repo, 'rev2', [])
293
        self.add_revision(repo, 'rev2', inv, [])
294
295
        # make ghost revision rev1c, with a version of a-file present so
296
        # that we generate a knit delta against this version.  In real life
297
        # the ghost might never have been present or rev3 might have been
298
        # generated against a revision that was present at the time.  So
299
        # currently we have the full history of a-file present even though
300
        # the inventory and revision objects are not.
301
        self.make_one_file_inventory(repo, 'rev1c', [])
302
303
        # make rev3 with a-file
304
        # a-file refers to 'rev1c', which is a ghost in this repository, so
305
        # a-file cannot have rev1c as its ancestor.
306
        inv = self.make_one_file_inventory(repo, 'rev3', ['rev1c'])
307
        self.add_revision(repo, 'rev3', inv, ['rev1c', 'rev1a'])
2988.1.2 by Robert Collins
New Repository API find_text_key_references for use by reconcile and check.
308
        self.versioned_root = repo.supports_rich_root()
309
310
    def repository_text_key_references(self):
311
        result = {}
312
        if self.versioned_root:
313
            result.update({('TREE_ROOT', 'rev2'): True,
314
                           ('TREE_ROOT', 'rev3'): True})
315
        result.update({('a-file-id', 'rev2'): True,
316
                       ('a-file-id', 'rev3'): True})
317
        return result
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
318
2988.1.3 by Robert Collins
Add a new repositoy method _generate_text_key_index for use by reconcile/check.
319
    def repository_text_keys(self):
320
        return {('a-file-id', 'rev2'):[NULL_REVISION],
321
                ('a-file-id', 'rev3'):[NULL_REVISION]}
322
323
    def versioned_repository_text_keys(self):
324
        return {('TREE_ROOT', 'rev2'):[NULL_REVISION],
325
                ('TREE_ROOT', 'rev3'):[NULL_REVISION]}
326
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
327
2745.6.43 by Andrew Bennetts
Tidy imports, docstrings, comments and variable names.
328
class FileParentsNotReferencedByAnyInventoryScenario(BrokenRepoScenario):
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
329
    """A scenario where a repository with file 'a-file' which has extra
330
    per-file versions that are not referenced by any inventory (even though
331
    they have the same ID as actual revisions).  The inventory of 'rev2'
332
    references 'rev1a' of 'a-file', but there is a 'rev2' of 'some-file' stored
333
    and erroneously referenced by later per-file versions (revisions 'rev4' and
334
    'rev5').
335
336
    Reconcile should remove the file parents that are not referenced by any
337
    inventory.
338
    """
339
2927.2.14 by Andrew Bennetts
Tweaks suggested by review.
340
    def all_versions_after_reconcile(self):
2927.2.11 by Andrew Bennetts
Merge from bzr.dev.
341
        return ('rev1a', 'rev2c', 'rev4', 'rev5')
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
342
343
    def populated_parents(self):
344
        return [
2927.2.11 by Andrew Bennetts
Merge from bzr.dev.
345
            (('rev1a',), 'rev2'),
346
            (('rev1a',), 'rev2b'),
2592.3.214 by Robert Collins
Merge bzr.dev.
347
            (('rev2',), 'rev3'),
348
            (('rev2',), 'rev4'),
2927.2.11 by Andrew Bennetts
Merge from bzr.dev.
349
            (('rev2', 'rev2c'), 'rev5')]
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
350
351
    def corrected_parents(self):
2592.3.214 by Robert Collins
Merge bzr.dev.
352
        return (
2927.2.8 by Andrew Bennetts
Remove totally unreferenced file versions. All reconcile tests passing.
353
            # rev2 and rev2b have been removed.
354
            (None, 'rev2'),
355
            (None, 'rev2b'),
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
356
            # rev3's accessible parent inventories all have rev1a as the last
357
            # modifier.
2592.3.214 by Robert Collins
Merge bzr.dev.
358
            (('rev1a',), 'rev3'),
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
359
            # rev1a features in both rev4's parents but should only appear once
360
            # in the result
2592.3.214 by Robert Collins
Merge bzr.dev.
361
            (('rev1a',), 'rev4'),
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
362
            # rev2c is the head of rev1a and rev2c, the inventory provided
363
            # per-file last-modified revisions.
2592.3.214 by Robert Collins
Merge bzr.dev.
364
            (('rev2c',), 'rev5'))
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
365
2951.1.6 by Robert Collins
All check/reconcile tests passing now.
366
    def check_regexes(self, repo):
367
        if repo.supports_rich_root():
368
            # TREE_ROOT will be wrong; but we're not testing it. so just adjust
369
            # the expected count of errors.
2988.1.8 by Robert Collins
Change check and reconcile to use the new _generate_text_key_index rather
370
            count = 9
2951.1.6 by Robert Collins
All check/reconcile tests passing now.
371
        else:
2988.1.8 by Robert Collins
Change check and reconcile to use the new _generate_text_key_index rather
372
            count = 3
2745.6.41 by Andrew Bennetts
Test repo.check against all_scenarios.
373
        return [
2951.1.6 by Robert Collins
All check/reconcile tests passing now.
374
            "%d inconsistent parents" % count,
2988.1.8 by Robert Collins
Change check and reconcile to use the new _generate_text_key_index rather
375
            # will be gc'd
376
            r"unreferenced version: {rev2} in a-file-id",
377
            r"unreferenced version: {rev2b} in a-file-id",
378
            # will be corrected
2592.3.214 by Robert Collins
Merge bzr.dev.
379
            r"a-file-id version rev3 has parents \('rev2',\) "
380
            r"but should have \('rev1a',\)",
381
            r"a-file-id version rev5 has parents \('rev2', 'rev2c'\) "
382
            r"but should have \('rev2c',\)",
383
            r"a-file-id version rev4 has parents \('rev2',\) "
384
            r"but should have \('rev1a',\)",
2745.6.41 by Andrew Bennetts
Test repo.check against all_scenarios.
385
            ]
386
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
387
    def populate_repository(self, repo):
388
        # make rev1a: A well-formed revision, containing 'a-file'
389
        inv = self.make_one_file_inventory(
390
            repo, 'rev1a', [], root_revision='rev1a')
391
        self.add_revision(repo, 'rev1a', inv, [])
392
393
        # make rev2, with a-file.
2927.2.3 by Andrew Bennetts
Add fulltexts to avoid bug 155730.
394
        # a-file is unmodified from rev1a, and an unreferenced rev2 file
395
        # version is present in the repository.
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
396
        self.make_one_file_inventory(
397
            repo, 'rev2', ['rev1a'], inv_revision='rev1a')
398
        self.add_revision(repo, 'rev2', inv, ['rev1a'])
399
400
        # make rev3 with a-file
401
        # a-file has 'rev2' as its ancestor, but the revision in 'rev2' was
402
        # rev1a so this is inconsistent with rev2's inventory - it should
403
        # be rev1a, and at the revision level 1c is not present - it is a
404
        # ghost, so only the details from rev1a are available for
405
        # determining whether a delta is acceptable, or a full is needed,
2745.6.43 by Andrew Bennetts
Tidy imports, docstrings, comments and variable names.
406
        # and what the correct parents are.
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
407
        inv = self.make_one_file_inventory(repo, 'rev3', ['rev2'])
2745.6.43 by Andrew Bennetts
Tidy imports, docstrings, comments and variable names.
408
        self.add_revision(repo, 'rev3', inv, ['rev1c', 'rev1a'])
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
409
410
        # In rev2b, the true last-modifying-revision of a-file is rev1a,
411
        # inherited from rev2, but there is a version rev2b of the file, which
412
        # reconcile could remove, leaving no rev2b.  Most importantly,
413
        # revisions descending from rev2b should not have per-file parents of
414
        # a-file-rev2b.
415
        # ??? This is to test deduplication in fixing rev4
416
        inv = self.make_one_file_inventory(
417
            repo, 'rev2b', ['rev1a'], inv_revision='rev1a')
418
        self.add_revision(repo, 'rev2b', inv, ['rev1a'])
419
420
        # rev4 is for testing that when the last modified of a file in
421
        # multiple parent revisions is the same, that it only appears once
422
        # in the generated per file parents list: rev2 and rev2b both
423
        # descend from 1a and do not change the file a-file, so there should
424
        # be no version of a-file 'rev2' or 'rev2b', but rev4 does change
425
        # a-file, and is a merge of rev2 and rev2b, so it should end up with
426
        # a parent of just rev1a - the starting file parents list is simply
427
        # completely wrong.
428
        inv = self.make_one_file_inventory(repo, 'rev4', ['rev2'])
429
        self.add_revision(repo, 'rev4', inv, ['rev2', 'rev2b'])
430
431
        # rev2c changes a-file from rev1a, so the version it of a-file it
432
        # introduces is a head revision when rev5 is checked.
433
        inv = self.make_one_file_inventory(repo, 'rev2c', ['rev1a'])
434
        self.add_revision(repo, 'rev2c', inv, ['rev1a'])
435
436
        # rev5 descends from rev2 and rev2c; as rev2 does not alter a-file,
437
        # but rev2c does, this should use rev2c as the parent for the per
438
        # file history, even though more than one per-file parent is
439
        # available, because we use the heads of the revision parents for
440
        # the inventory modification revisions of the file to determine the
441
        # parents for the per file graph.
442
        inv = self.make_one_file_inventory(repo, 'rev5', ['rev2', 'rev2c'])
443
        self.add_revision(repo, 'rev5', inv, ['rev2', 'rev2c'])
2988.1.2 by Robert Collins
New Repository API find_text_key_references for use by reconcile and check.
444
        self.versioned_root = repo.supports_rich_root()
445
446
    def repository_text_key_references(self):
447
        result = {}
448
        if self.versioned_root:
449
            result.update({('TREE_ROOT', 'rev1a'): True,
450
                           ('TREE_ROOT', 'rev2'): True,
451
                           ('TREE_ROOT', 'rev2b'): True,
452
                           ('TREE_ROOT', 'rev2c'): True,
453
                           ('TREE_ROOT', 'rev3'): True,
454
                           ('TREE_ROOT', 'rev4'): True,
455
                           ('TREE_ROOT', 'rev5'): True})
456
        result.update({('a-file-id', 'rev1a'): True,
457
                       ('a-file-id', 'rev2c'): True,
458
                       ('a-file-id', 'rev3'): True,
459
                       ('a-file-id', 'rev4'): True,
460
                       ('a-file-id', 'rev5'): True})
461
        return result
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
462
2988.1.3 by Robert Collins
Add a new repositoy method _generate_text_key_index for use by reconcile/check.
463
    def repository_text_keys(self):
464
        return {('a-file-id', 'rev1a'): [NULL_REVISION],
465
                 ('a-file-id', 'rev2c'): [('a-file-id', 'rev1a')],
466
                 ('a-file-id', 'rev3'): [('a-file-id', 'rev1a')],
467
                 ('a-file-id', 'rev4'): [('a-file-id', 'rev1a')],
468
                 ('a-file-id', 'rev5'): [('a-file-id', 'rev2c')]}
469
470
    def versioned_repository_text_keys(self):
471
        return {('TREE_ROOT', 'rev1a'): [NULL_REVISION],
472
                ('TREE_ROOT', 'rev2'): [('TREE_ROOT', 'rev1a')],
473
                ('TREE_ROOT', 'rev2b'): [('TREE_ROOT', 'rev1a')],
474
                ('TREE_ROOT', 'rev2c'): [('TREE_ROOT', 'rev1a')],
475
                ('TREE_ROOT', 'rev3'): [('TREE_ROOT', 'rev1a')],
476
                ('TREE_ROOT', 'rev4'):
477
                    [('TREE_ROOT', 'rev2'), ('TREE_ROOT', 'rev2b')],
478
                ('TREE_ROOT', 'rev5'):
479
                    [('TREE_ROOT', 'rev2'), ('TREE_ROOT', 'rev2c')]}
480
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
481
2927.2.3 by Andrew Bennetts
Add fulltexts to avoid bug 155730.
482
class UnreferencedFileParentsFromNoOpMergeScenario(BrokenRepoScenario):
483
    """
484
    rev1a and rev1b with identical contents
485
    rev2 revision has parents of [rev1a, rev1b]
486
    There is a a-file:rev2 file version, not referenced by the inventory.
487
    """
488
2927.2.14 by Andrew Bennetts
Tweaks suggested by review.
489
    def all_versions_after_reconcile(self):
2927.2.11 by Andrew Bennetts
Merge from bzr.dev.
490
        return ('rev1a', 'rev1b', 'rev2', 'rev4')
2927.2.3 by Andrew Bennetts
Add fulltexts to avoid bug 155730.
491
492
    def populated_parents(self):
2927.2.11 by Andrew Bennetts
Merge from bzr.dev.
493
        return (
494
            ((), 'rev1a'),
495
            ((), 'rev1b'),
496
            (('rev1a', 'rev1b'), 'rev2'),
2927.2.4 by Andrew Bennetts
Don't create a 'rev3' file version in the test.
497
            (None, 'rev3'),
2927.2.11 by Andrew Bennetts
Merge from bzr.dev.
498
            (('rev2',), 'rev4'),
499
            )
2927.2.3 by Andrew Bennetts
Add fulltexts to avoid bug 155730.
500
501
    def corrected_parents(self):
2927.2.11 by Andrew Bennetts
Merge from bzr.dev.
502
        return (
503
            ((), 'rev1a'),
504
            ((), 'rev1b'),
505
            ((), 'rev2'),
2927.2.4 by Andrew Bennetts
Don't create a 'rev3' file version in the test.
506
            (None, 'rev3'),
2927.2.11 by Andrew Bennetts
Merge from bzr.dev.
507
            (('rev2',), 'rev4'),
508
            )
2927.2.3 by Andrew Bennetts
Add fulltexts to avoid bug 155730.
509
510
    def corrected_fulltexts(self):
2988.1.8 by Robert Collins
Change check and reconcile to use the new _generate_text_key_index rather
511
        return ['rev2']
2927.2.3 by Andrew Bennetts
Add fulltexts to avoid bug 155730.
512
2951.1.6 by Robert Collins
All check/reconcile tests passing now.
513
    def check_regexes(self, repo):
2927.2.3 by Andrew Bennetts
Add fulltexts to avoid bug 155730.
514
        return []
515
516
    def populate_repository(self, repo):
517
        # make rev1a: A well-formed revision, containing 'a-file'
518
        inv1a = self.make_one_file_inventory(
519
            repo, 'rev1a', [], root_revision='rev1a')
520
        self.add_revision(repo, 'rev1a', inv1a, [])
521
522
        # make rev1b: A well-formed revision, containing 'a-file'
523
        # rev1b of a-file has the exact same contents as rev1a.
524
        file_contents = repo.revision_tree('rev1a').get_file_text('a-file-id')
525
        inv = self.make_one_file_inventory(
526
            repo, 'rev1b', [], root_revision='rev1b',
527
            file_contents=file_contents)
528
        self.add_revision(repo, 'rev1b', inv, [])
529
530
        # make rev2, a merge of rev1a and rev1b, with a-file.
531
        # a-file is unmodified from rev1a and rev1b, but a new version is
532
        # wrongly present anyway.
533
        inv = self.make_one_file_inventory(
534
            repo, 'rev2', ['rev1a', 'rev1b'], inv_revision='rev1a',
535
            file_contents=file_contents)
536
        self.add_revision(repo, 'rev2', inv, ['rev1a', 'rev1b'])
537
538
        # rev3: a-file unchanged from rev2, but wrongly referencing rev2 of the
539
        # file in its inventory.
540
        inv = self.make_one_file_inventory(
541
            repo, 'rev3', ['rev2'], inv_revision='rev2',
2927.2.4 by Andrew Bennetts
Don't create a 'rev3' file version in the test.
542
            file_contents=file_contents, make_file_version=False)
2927.2.3 by Andrew Bennetts
Add fulltexts to avoid bug 155730.
543
        self.add_revision(repo, 'rev3', inv, ['rev2'])
544
545
        # rev4: a modification of a-file on top of rev3.
2927.2.4 by Andrew Bennetts
Don't create a 'rev3' file version in the test.
546
        inv = self.make_one_file_inventory(repo, 'rev4', ['rev2'])
2927.2.3 by Andrew Bennetts
Add fulltexts to avoid bug 155730.
547
        self.add_revision(repo, 'rev4', inv, ['rev3'])
2988.1.2 by Robert Collins
New Repository API find_text_key_references for use by reconcile and check.
548
        self.versioned_root = repo.supports_rich_root()
549
550
    def repository_text_key_references(self):
551
        result = {}
552
        if self.versioned_root:
553
            result.update({('TREE_ROOT', 'rev1a'): True,
554
                           ('TREE_ROOT', 'rev1b'): True,
555
                           ('TREE_ROOT', 'rev2'): True,
556
                           ('TREE_ROOT', 'rev3'): True,
557
                           ('TREE_ROOT', 'rev4'): True})
558
        result.update({('a-file-id', 'rev1a'): True,
559
                       ('a-file-id', 'rev1b'): True,
560
                       ('a-file-id', 'rev2'): False,
561
                       ('a-file-id', 'rev4'): True})
562
        return result
2927.2.3 by Andrew Bennetts
Add fulltexts to avoid bug 155730.
563
2988.1.3 by Robert Collins
Add a new repositoy method _generate_text_key_index for use by reconcile/check.
564
    def repository_text_keys(self):
565
        return {('a-file-id', 'rev1a'): [NULL_REVISION],
566
                ('a-file-id', 'rev1b'): [NULL_REVISION],
567
                ('a-file-id', 'rev2'): [NULL_REVISION],
568
                ('a-file-id', 'rev4'): [('a-file-id', 'rev2')]}
569
570
    def versioned_repository_text_keys(self):
571
        return {('TREE_ROOT', 'rev1a'): [NULL_REVISION],
572
                ('TREE_ROOT', 'rev1b'): [NULL_REVISION],
573
                ('TREE_ROOT', 'rev2'):
574
                    [('TREE_ROOT', 'rev1a'), ('TREE_ROOT', 'rev1b')],
575
                ('TREE_ROOT', 'rev3'): [('TREE_ROOT', 'rev2')],
576
                ('TREE_ROOT', 'rev4'): [('TREE_ROOT', 'rev3')]}
577
2927.2.3 by Andrew Bennetts
Add fulltexts to avoid bug 155730.
578
2745.6.43 by Andrew Bennetts
Tidy imports, docstrings, comments and variable names.
579
class TooManyParentsScenario(BrokenRepoScenario):
2745.6.39 by Andrew Bennetts
Use scenario in test_check too, and make check actually report inconsistent parents to the end user.
580
    """A scenario where 'broken-revision' of 'a-file' claims to have parents
581
    ['good-parent', 'bad-parent'].  However 'bad-parent' is in the ancestry of
582
    'good-parent', so the correct parent list for that file version are is just
583
    ['good-parent'].
584
    """
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
585
2927.2.14 by Andrew Bennetts
Tweaks suggested by review.
586
    def all_versions_after_reconcile(self):
2592.3.214 by Robert Collins
Merge bzr.dev.
587
        return ('bad-parent', 'good-parent', 'broken-revision')
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
588
589
    def populated_parents(self):
2592.3.214 by Robert Collins
Merge bzr.dev.
590
        return (
591
            ((), 'bad-parent'),
592
            (('bad-parent',), 'good-parent'),
593
            (('good-parent', 'bad-parent'), 'broken-revision'))
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
594
595
    def corrected_parents(self):
2592.3.214 by Robert Collins
Merge bzr.dev.
596
        return (
597
            ((), 'bad-parent'),
598
            (('bad-parent',), 'good-parent'),
599
            (('good-parent',), 'broken-revision'))
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
600
2951.1.6 by Robert Collins
All check/reconcile tests passing now.
601
    def check_regexes(self, repo):
602
        if repo.supports_rich_root():
603
            # TREE_ROOT will be wrong; but we're not testing it. so just adjust
604
            # the expected count of errors.
605
            count = 3
606
        else:
607
            count = 1
2592.3.214 by Robert Collins
Merge bzr.dev.
608
        return (
2951.1.6 by Robert Collins
All check/reconcile tests passing now.
609
            '     %d inconsistent parents' % count,
2745.6.39 by Andrew Bennetts
Use scenario in test_check too, and make check actually report inconsistent parents to the end user.
610
            (r"      \* a-file-id version broken-revision has parents "
2592.3.214 by Robert Collins
Merge bzr.dev.
611
             r"\('good-parent', 'bad-parent'\) but "
612
             r"should have \('good-parent',\)"))
2745.6.39 by Andrew Bennetts
Use scenario in test_check too, and make check actually report inconsistent parents to the end user.
613
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
614
    def populate_repository(self, repo):
615
        inv = self.make_one_file_inventory(
2592.3.214 by Robert Collins
Merge bzr.dev.
616
            repo, 'bad-parent', (), root_revision='bad-parent')
617
        self.add_revision(repo, 'bad-parent', inv, ())
618
        
619
        inv = self.make_one_file_inventory(
620
            repo, 'good-parent', ('bad-parent',))
621
        self.add_revision(repo, 'good-parent', inv, ('bad-parent',))
622
        
623
        inv = self.make_one_file_inventory(
624
            repo, 'broken-revision', ('good-parent', 'bad-parent'))
625
        self.add_revision(repo, 'broken-revision', inv, ('good-parent',))
2988.1.2 by Robert Collins
New Repository API find_text_key_references for use by reconcile and check.
626
        self.versioned_root = repo.supports_rich_root()
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
627
2988.1.2 by Robert Collins
New Repository API find_text_key_references for use by reconcile and check.
628
    def repository_text_key_references(self):
629
        result = {}
630
        if self.versioned_root:
631
            result.update({('TREE_ROOT', 'bad-parent'): True,
632
                           ('TREE_ROOT', 'broken-revision'): True,
633
                           ('TREE_ROOT', 'good-parent'): True})
634
        result.update({('a-file-id', 'bad-parent'): True,
635
                       ('a-file-id', 'broken-revision'): True,
636
                       ('a-file-id', 'good-parent'): True})
637
        return result
638
             
2988.1.3 by Robert Collins
Add a new repositoy method _generate_text_key_index for use by reconcile/check.
639
    def repository_text_keys(self):
640
        return {('a-file-id', 'bad-parent'): [NULL_REVISION],
641
                ('a-file-id', 'broken-revision'):
642
                    [('a-file-id', 'good-parent')],
643
                ('a-file-id', 'good-parent'): [('a-file-id', 'bad-parent')]}
644
645
    def versioned_repository_text_keys(self):
646
        return {('TREE_ROOT', 'bad-parent'): [NULL_REVISION],
647
                ('TREE_ROOT', 'broken-revision'):
648
                    [('TREE_ROOT', 'good-parent')],
649
                ('TREE_ROOT', 'good-parent'): [('TREE_ROOT', 'bad-parent')]}
650
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
651
2745.6.43 by Andrew Bennetts
Tidy imports, docstrings, comments and variable names.
652
class ClaimedFileParentDidNotModifyFileScenario(BrokenRepoScenario):
653
    """A scenario where the file parent is the same as the revision parent, but
654
    should not be because that revision did not modify the file.
655
656
    Specifically, the parent revision of 'current' is
657
    'modified-something-else', which does not modify 'a-file', but the
658
    'current' version of 'a-file' erroneously claims that
659
    'modified-something-else' is the parent file version.
660
    """
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
661
2927.2.14 by Andrew Bennetts
Tweaks suggested by review.
662
    def all_versions_after_reconcile(self):
2927.2.11 by Andrew Bennetts
Merge from bzr.dev.
663
        return ('basis', 'current')
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
664
665
    def populated_parents(self):
2592.3.214 by Robert Collins
Merge bzr.dev.
666
        return (
667
            ((), 'basis'),
668
            (('basis',), 'modified-something-else'),
669
            (('modified-something-else',), 'current'))
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
670
671
    def corrected_parents(self):
2592.3.214 by Robert Collins
Merge bzr.dev.
672
        return (
673
            ((), 'basis'),
2927.2.8 by Andrew Bennetts
Remove totally unreferenced file versions. All reconcile tests passing.
674
            (None, 'modified-something-else'),
2592.3.214 by Robert Collins
Merge bzr.dev.
675
            (('basis',), 'current'))
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
676
2951.1.6 by Robert Collins
All check/reconcile tests passing now.
677
    def check_regexes(self, repo):
678
        if repo.supports_rich_root():
679
            # TREE_ROOT will be wrong; but we're not testing it. so just adjust
680
            # the expected count of errors.
2988.1.8 by Robert Collins
Change check and reconcile to use the new _generate_text_key_index rather
681
            count = 3
2951.1.6 by Robert Collins
All check/reconcile tests passing now.
682
        else:
2988.1.8 by Robert Collins
Change check and reconcile to use the new _generate_text_key_index rather
683
            count = 1
2592.3.214 by Robert Collins
Merge bzr.dev.
684
        return (
2951.1.6 by Robert Collins
All check/reconcile tests passing now.
685
            "%d inconsistent parents" % count,
2745.6.41 by Andrew Bennetts
Test repo.check against all_scenarios.
686
            r"\* a-file-id version current has parents "
2927.2.11 by Andrew Bennetts
Merge from bzr.dev.
687
            r"\('modified-something-else',\) but should have \('basis',\)",
688
            )
2745.6.41 by Andrew Bennetts
Test repo.check against all_scenarios.
689
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
690
    def populate_repository(self, repo):
2592.3.214 by Robert Collins
Merge bzr.dev.
691
        inv = self.make_one_file_inventory(repo, 'basis', ())
692
        self.add_revision(repo, 'basis', inv, ())
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
693
2745.6.43 by Andrew Bennetts
Tidy imports, docstrings, comments and variable names.
694
        # 'modified-something-else' is a correctly recorded revision, but it
695
        # does not modify the file we are looking at, so the inventory for that
696
        # file in this revision points to 'basis'.
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
697
        inv = self.make_one_file_inventory(
2592.3.214 by Robert Collins
Merge bzr.dev.
698
            repo, 'modified-something-else', ('basis',), inv_revision='basis')
699
        self.add_revision(repo, 'modified-something-else', inv, ('basis',))
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
700
2745.6.43 by Andrew Bennetts
Tidy imports, docstrings, comments and variable names.
701
        # The 'current' revision has 'modified-something-else' as its parent,
702
        # but the 'current' version of 'a-file' should have 'basis' as its
703
        # parent.
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
704
        inv = self.make_one_file_inventory(
2592.3.214 by Robert Collins
Merge bzr.dev.
705
            repo, 'current', ('modified-something-else',))
706
        self.add_revision(repo, 'current', inv, ('modified-something-else',))
2988.1.2 by Robert Collins
New Repository API find_text_key_references for use by reconcile and check.
707
        self.versioned_root = repo.supports_rich_root()
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
708
2988.1.2 by Robert Collins
New Repository API find_text_key_references for use by reconcile and check.
709
    def repository_text_key_references(self):
710
        result = {}
711
        if self.versioned_root:
712
            result.update({('TREE_ROOT', 'basis'): True,
713
                           ('TREE_ROOT', 'current'): True,
714
                           ('TREE_ROOT', 'modified-something-else'): True})
715
        result.update({('a-file-id', 'basis'): True,
716
                       ('a-file-id', 'current'): True})
717
        return result
2988.1.3 by Robert Collins
Add a new repositoy method _generate_text_key_index for use by reconcile/check.
718
719
    def repository_text_keys(self):
720
        return {('a-file-id', 'basis'): [NULL_REVISION],
721
                ('a-file-id', 'current'): [('a-file-id', 'basis')]}
722
723
    def versioned_repository_text_keys(self):
724
        return {('TREE_ROOT', 'basis'): ['null:'],
725
                ('TREE_ROOT', 'current'):
726
                    [('TREE_ROOT', 'modified-something-else')],
727
                ('TREE_ROOT', 'modified-something-else'):
728
                    [('TREE_ROOT', 'basis')]}
2988.1.2 by Robert Collins
New Repository API find_text_key_references for use by reconcile and check.
729
            
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
730
2745.6.43 by Andrew Bennetts
Tidy imports, docstrings, comments and variable names.
731
class IncorrectlyOrderedParentsScenario(BrokenRepoScenario):
732
    """A scenario where the set parents of a version of a file are correct, but
733
    the order of those parents is incorrect.
734
735
    This defines a 'broken-revision-1-2' and a 'broken-revision-2-1' which both
736
    have their file version parents reversed compared to the revision parents,
737
    which is invalid.  (We use two revisions with opposite orderings of the
738
    same parents to make sure that accidentally relying on dictionary/set
739
    ordering cannot make the test pass; the assumption is that while dict/set
740
    iteration order is arbitrary, it is also consistent within a single test).
741
    """
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
742
2927.2.14 by Andrew Bennetts
Tweaks suggested by review.
743
    def all_versions_after_reconcile(self):
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
744
        return ['parent-1', 'parent-2', 'broken-revision-1-2',
745
                'broken-revision-2-1']
746
747
    def populated_parents(self):
2592.3.214 by Robert Collins
Merge bzr.dev.
748
        return (
749
            ((), 'parent-1'),
750
            ((), 'parent-2'),
751
            (('parent-2', 'parent-1'), 'broken-revision-1-2'),
752
            (('parent-1', 'parent-2'), 'broken-revision-2-1'))
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
753
754
    def corrected_parents(self):
2592.3.214 by Robert Collins
Merge bzr.dev.
755
        return (
756
            ((), 'parent-1'),
757
            ((), 'parent-2'),
758
            (('parent-1', 'parent-2'), 'broken-revision-1-2'),
759
            (('parent-2', 'parent-1'), 'broken-revision-2-1'))
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
760
2951.1.6 by Robert Collins
All check/reconcile tests passing now.
761
    def check_regexes(self, repo):
762
        if repo.supports_rich_root():
763
            # TREE_ROOT will be wrong; but we're not testing it. so just adjust
764
            # the expected count of errors.
765
            count = 4
766
        else:
767
            count = 2
2592.3.214 by Robert Collins
Merge bzr.dev.
768
        return (
2951.1.6 by Robert Collins
All check/reconcile tests passing now.
769
            "%d inconsistent parents" % count,
2745.6.41 by Andrew Bennetts
Test repo.check against all_scenarios.
770
            r"\* a-file-id version broken-revision-1-2 has parents "
2592.3.214 by Robert Collins
Merge bzr.dev.
771
            r"\('parent-2', 'parent-1'\) but should have "
772
            r"\('parent-1', 'parent-2'\)",
2745.6.41 by Andrew Bennetts
Test repo.check against all_scenarios.
773
            r"\* a-file-id version broken-revision-2-1 has parents "
2592.3.214 by Robert Collins
Merge bzr.dev.
774
            r"\('parent-1', 'parent-2'\) but should have "
775
            r"\('parent-2', 'parent-1'\)")
2745.6.41 by Andrew Bennetts
Test repo.check against all_scenarios.
776
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
777
    def populate_repository(self, repo):
778
        inv = self.make_one_file_inventory(repo, 'parent-1', [])
779
        self.add_revision(repo, 'parent-1', inv, [])
780
781
        inv = self.make_one_file_inventory(repo, 'parent-2', [])
782
        self.add_revision(repo, 'parent-2', inv, [])
783
784
        inv = self.make_one_file_inventory(
785
            repo, 'broken-revision-1-2', ['parent-2', 'parent-1'])
786
        self.add_revision(
787
            repo, 'broken-revision-1-2', inv, ['parent-1', 'parent-2'])
788
789
        inv = self.make_one_file_inventory(
790
            repo, 'broken-revision-2-1', ['parent-1', 'parent-2'])
791
        self.add_revision(
792
            repo, 'broken-revision-2-1', inv, ['parent-2', 'parent-1'])
2988.1.2 by Robert Collins
New Repository API find_text_key_references for use by reconcile and check.
793
        self.versioned_root = repo.supports_rich_root()
2745.6.32 by Andrew Bennetts
Some testing notes, test reorganisation, XXX comments and some failing tests.
794
2988.1.2 by Robert Collins
New Repository API find_text_key_references for use by reconcile and check.
795
    def repository_text_key_references(self):
796
        result = {}
797
        if self.versioned_root:
798
            result.update({('TREE_ROOT', 'broken-revision-1-2'): True,
799
                           ('TREE_ROOT', 'broken-revision-2-1'): True,
800
                           ('TREE_ROOT', 'parent-1'): True,
801
                           ('TREE_ROOT', 'parent-2'): True})
802
        result.update({('a-file-id', 'broken-revision-1-2'): True,
803
                       ('a-file-id', 'broken-revision-2-1'): True,
804
                       ('a-file-id', 'parent-1'): True,
805
                       ('a-file-id', 'parent-2'): True})
806
        return result
2988.1.3 by Robert Collins
Add a new repositoy method _generate_text_key_index for use by reconcile/check.
807
808
    def repository_text_keys(self):
809
        return {('a-file-id', 'broken-revision-1-2'):
810
                    [('a-file-id', 'parent-1'), ('a-file-id', 'parent-2')],
811
                ('a-file-id', 'broken-revision-2-1'):
812
                    [('a-file-id', 'parent-2'), ('a-file-id', 'parent-1')],
813
                ('a-file-id', 'parent-1'): [NULL_REVISION],
814
                ('a-file-id', 'parent-2'): [NULL_REVISION]}
815
816
    def versioned_repository_text_keys(self):
817
        return {('TREE_ROOT', 'broken-revision-1-2'):
818
                    [('TREE_ROOT', 'parent-1'), ('TREE_ROOT', 'parent-2')],
819
                ('TREE_ROOT', 'broken-revision-2-1'):
820
                    [('TREE_ROOT', 'parent-2'), ('TREE_ROOT', 'parent-1')],
821
                ('TREE_ROOT', 'parent-1'): [NULL_REVISION],
822
                ('TREE_ROOT', 'parent-2'): [NULL_REVISION]}
2988.1.2 by Robert Collins
New Repository API find_text_key_references for use by reconcile and check.
823
               
2485.7.1 by Robert Collins
Relocate TestCaseWithRepository to be more central.
824
2745.6.58 by Andrew Bennetts
Slightly neater test parameterisation in repository_implementations; extract a 'multiply_scenarios' function.
825
all_broken_scenario_classes = [
2745.6.54 by Andrew Bennetts
Tidy test parameterisation in repository_implementations.
826
    UndamagedRepositoryScenario,
827
    FileParentIsNotInRevisionAncestryScenario,
828
    FileParentHasInaccessibleInventoryScenario,
829
    FileParentsNotReferencedByAnyInventoryScenario,
830
    TooManyParentsScenario,
831
    ClaimedFileParentDidNotModifyFileScenario,
832
    IncorrectlyOrderedParentsScenario,
2927.2.3 by Andrew Bennetts
Add fulltexts to avoid bug 155730.
833
    UnreferencedFileParentsFromNoOpMergeScenario,
2745.6.54 by Andrew Bennetts
Tidy test parameterisation in repository_implementations.
834
    ]
835
    
2745.6.42 by Andrew Bennetts
Use TestScenarioApplier to more cleanly parameterise check and reconcile tests.
836
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
837
def test_suite():
2241.1.11 by Martin Pool
Get rid of RepositoryFormat*_instance objects. Instead the format
838
    registry = repository.format_registry
839
    all_formats = [registry.get(k) for k in registry.keys()]
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
840
    all_formats.extend(weaverepo._legacy_formats)
2745.6.54 by Andrew Bennetts
Tidy test parameterisation in repository_implementations.
841
    disk_format_adapter = RepositoryTestProviderAdapter(
2018.5.30 by Robert Collins
Reenable the stock repository implementations for testing.
842
        default_transport,
843
        # None here will cause a readonly decorator to be created
844
        # by the TestCaseWithTransport.get_readonly_transport method.
845
        None,
2241.1.1 by Martin Pool
Change RepositoryFormat to use a Registry rather than ad-hoc dictionary
846
        [(format, format._matchingbzrdir) for format in all_formats])
2018.5.30 by Robert Collins
Reenable the stock repository implementations for testing.
847
2745.6.54 by Andrew Bennetts
Tidy test parameterisation in repository_implementations.
848
    remote_repo_adapter = RepositoryTestProviderAdapter(
2018.5.30 by Robert Collins
Reenable the stock repository implementations for testing.
849
        SmartTCPServer_for_testing,
850
        ReadonlySmartTCPServer_for_testing,
2018.5.66 by Wouter van Heyst
Fix repository test parameterization for RemoteRepository.
851
        [(RemoteRepositoryFormat(), RemoteBzrDirFormat())],
852
        MemoryServer
853
        )
2745.6.54 by Andrew Bennetts
Tidy test parameterisation in repository_implementations.
854
2745.6.58 by Andrew Bennetts
Slightly neater test parameterisation in repository_implementations; extract a 'multiply_scenarios' function.
855
    # format_scenarios is all the implementations of Repository; i.e. all disk
856
    # formats plus RemoteRepository.
857
    format_scenarios = (disk_format_adapter.scenarios +
858
                        remote_repo_adapter.scenarios)
2745.6.54 by Andrew Bennetts
Tidy test parameterisation in repository_implementations.
859
860
    prefix = 'bzrlib.tests.repository_implementations.'
2745.6.58 by Andrew Bennetts
Slightly neater test parameterisation in repository_implementations; extract a 'multiply_scenarios' function.
861
    test_repository_modules = [
2745.6.57 by Andrew Bennetts
Some improvements suggested by Martin's review.
862
        'test_break_lock',
863
        'test_check',
2745.6.58 by Andrew Bennetts
Slightly neater test parameterisation in repository_implementations; extract a 'multiply_scenarios' function.
864
        # test_check_reconcile is intentionally omitted, see below.
2745.6.57 by Andrew Bennetts
Some improvements suggested by Martin's review.
865
        'test_commit_builder',
866
        'test_fetch',
867
        'test_fileid_involved',
2988.1.2 by Robert Collins
New Repository API find_text_key_references for use by reconcile and check.
868
        'test_find_text_key_references',
2988.1.3 by Robert Collins
Add a new repositoy method _generate_text_key_index for use by reconcile/check.
869
        'test__generate_text_key_index',
2745.6.57 by Andrew Bennetts
Some improvements suggested by Martin's review.
870
        'test_has_same_location',
2904.1.2 by Robert Collins
Merge bzr.dev
871
        'test_is_write_locked',
2745.6.57 by Andrew Bennetts
Some improvements suggested by Martin's review.
872
        'test_iter_reverse_revision_history',
873
        'test_pack',
874
        'test_reconcile',
875
        'test_repository',
876
        'test_revision',
877
        'test_statistics',
878
        'test_write_group',
2745.6.54 by Andrew Bennetts
Tidy test parameterisation in repository_implementations.
879
        ]
2745.6.58 by Andrew Bennetts
Slightly neater test parameterisation in repository_implementations; extract a 'multiply_scenarios' function.
880
    module_name_list = [prefix + module_name
881
                        for module_name in test_repository_modules]
882
883
    # Parameterise repository_implementations test modules by format.
884
    result = multiply_tests_from_modules(module_name_list, format_scenarios)
885
886
    # test_check_reconcile needs to be parameterised by format *and* by broken
887
    # repository scenario.
888
    broken_scenarios = [(s.__name__, {'scenario_class': s})
889
                        for s in all_broken_scenario_classes]
890
    broken_scenarios_for_all_formats = multiply_scenarios(
891
        format_scenarios, broken_scenarios)
892
    broken_scenario_applier = TestScenarioApplier()
893
    broken_scenario_applier.scenarios = broken_scenarios_for_all_formats
2745.6.54 by Andrew Bennetts
Tidy test parameterisation in repository_implementations.
894
    loader = TestLoader()
2745.6.57 by Andrew Bennetts
Some improvements suggested by Martin's review.
895
    adapt_modules(
896
        [prefix + 'test_check_reconcile'],
897
        broken_scenario_applier, loader, result)
2745.6.54 by Andrew Bennetts
Tidy test parameterisation in repository_implementations.
898
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
899
    return result