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