/brz/remove-bazaar

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