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