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