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