/brz/remove-bazaar

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