/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
    )
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
30
from bzrlib.repofmt import (
31
    weaverepo,
32
    )
2745.6.54 by Andrew Bennetts
Tidy test parameterisation in repository_implementations.
33
from bzrlib.remote import RemoteBzrDirFormat, RemoteRepositoryFormat
34
from bzrlib.smart.server import (
35
    SmartTCPServer_for_testing,
36
    ReadonlySmartTCPServer_for_testing,
37
    )
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
38
from bzrlib.tests import (
2745.6.57 by Andrew Bennetts
Some improvements suggested by Martin's review.
39
                          adapt_modules,
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
40
                          default_transport,
2745.6.54 by Andrew Bennetts
Tidy test parameterisation in repository_implementations.
41
                          iter_suite_tests,
2745.6.58 by Andrew Bennetts
Slightly neater test parameterisation in repository_implementations; extract a 'multiply_scenarios' function.
42
                          multiply_scenarios,
43
                          multiply_tests_from_modules,
2553.2.3 by Robert Collins
Split out the common test scenario support from the repository implementation specific code.
44
                          TestScenarioApplier,
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
45
                          TestLoader,
46
                          TestSuite,
47
                          )
2485.7.1 by Robert Collins
Relocate TestCaseWithRepository to be more central.
48
from bzrlib.tests.bzrdir_implementations.test_bzrdir import TestCaseWithBzrDir
2018.5.66 by Wouter van Heyst
Fix repository test parameterization for RemoteRepository.
49
from bzrlib.transport.memory import MemoryServer
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
50
51
2553.2.3 by Robert Collins
Split out the common test scenario support from the repository implementation specific code.
52
class RepositoryTestProviderAdapter(TestScenarioApplier):
2553.2.2 by Robert Collins
Move RepositoryTestProviderAdapter into the tests part of the code base.
53
    """A tool to generate a suite testing multiple repository formats at once.
54
55
    This is done by copying the test once for each transport and injecting
56
    the transport_server, transport_readonly_server, and bzrdir_format and
57
    repository_format classes into each copy. Each copy is also given a new id()
58
    to make it easy to identify.
59
    """
60
61
    def __init__(self, transport_server, transport_readonly_server, formats,
62
                 vfs_transport_factory=None):
2553.2.3 by Robert Collins
Split out the common test scenario support from the repository implementation specific code.
63
        TestScenarioApplier.__init__(self)
2553.2.2 by Robert Collins
Move RepositoryTestProviderAdapter into the tests part of the code base.
64
        self._transport_server = transport_server
65
        self._transport_readonly_server = transport_readonly_server
66
        self._vfs_transport_factory = vfs_transport_factory
67
        self.scenarios = self.formats_to_scenarios(formats)
68
    
69
    def formats_to_scenarios(self, formats):
70
        """Transform the input formats to a list of scenarios.
71
72
        :param formats: A list of (repository_format, bzrdir_format).
73
        """
74
        result = []
75
        for repository_format, bzrdir_format in formats:
76
            scenario = (repository_format.__class__.__name__,
77
                {"transport_server":self._transport_server,
78
                 "transport_readonly_server":self._transport_readonly_server,
79
                 "bzrdir_format":bzrdir_format,
80
                 "repository_format":repository_format,
81
                 })
82
            # Only override the test's vfs_transport_factory if one was
83
            # specified, otherwise just leave the default in place.
84
            if self._vfs_transport_factory:
85
                scenario[1]['vfs_transport_factory'] = self._vfs_transport_factory
86
            result.append(scenario)
87
        return result
88
89
2485.7.1 by Robert Collins
Relocate TestCaseWithRepository to be more central.
90
class TestCaseWithRepository(TestCaseWithBzrDir):
91
92
    def make_repository(self, relpath, format=None):
93
        if format is None:
94
            # Create a repository of the type we are trying to test.
95
            made_control = self.make_bzrdir(relpath)
2553.2.1 by Robert Collins
Overhaul RepositoryTestAdapter to be cleaner and more modular.
96
            repo = self.repository_format.initialize(made_control)
2553.2.2 by Robert Collins
Move RepositoryTestProviderAdapter into the tests part of the code base.
97
            if getattr(self, "repository_to_test_repository", None):
2553.2.1 by Robert Collins
Overhaul RepositoryTestAdapter to be cleaner and more modular.
98
                repo = self.repository_to_test_repository(repo)
99
            return repo
2485.7.1 by Robert Collins
Relocate TestCaseWithRepository to be more central.
100
        else:
101
            return super(TestCaseWithRepository, self).make_repository(
2671.1.1 by Andrew Bennetts
Add support for comparing Repositories with == and != operators.
102
                relpath, format=format)
2485.7.1 by Robert Collins
Relocate TestCaseWithRepository to be more central.
103
104
2745.6.43 by Andrew Bennetts
Tidy imports, docstrings, comments and variable names.
105
class BrokenRepoScenario(object):
106
    """Base class for defining scenarios for testing check and reconcile.
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
107
2745.6.43 by Andrew Bennetts
Tidy imports, docstrings, comments and variable names.
108
    A subclass needs to define the following methods:
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
109
        :populate_repository: a method to use to populate a repository with
110
            sample revisions, inventories and file versions.
2927.2.14 by Andrew Bennetts
Tweaks suggested by review.
111
        :all_versions_after_reconcile: all the versions in repository after
112
            reconcile.  run_test verifies that the text of each of these
113
            versions of the file is unchanged by the reconcile.
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
114
        :populated_parents: a list of (parents list, revision).  Each version
115
            of the file is verified to have the given parents before running
116
            the reconcile.  i.e. this is used to assert that the repo from the
117
            factory is what we expect.
118
        :corrected_parents: a list of (parents list, revision).  Each version
119
            of the file is verified to have the given parents after the
120
            reconcile.  i.e. this is used to assert that reconcile made the
121
            changes we expect it to make.
2927.2.5 by Andrew Bennetts
Remove corrected_inventories, add proper description of corrected_fulltexts.
122
    
123
    A subclass may define the following optional method as well:
124
        :corrected_fulltexts: a list of file versions that should be stored as
125
            fulltexts (not deltas) after reconcile.  run_test will verify that
126
            this occurs.
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
127
    """
128
129
    def __init__(self, test_case):
130
        self.test_case = test_case
131
132
    def make_one_file_inventory(self, repo, revision, parents,
2927.2.3 by Andrew Bennetts
Add fulltexts to avoid bug 155730.
133
                                inv_revision=None, root_revision=None,
2927.2.4 by Andrew Bennetts
Don't create a 'rev3' file version in the test.
134
                                file_contents=None, make_file_version=True):
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
135
        return self.test_case.make_one_file_inventory(
136
            repo, revision, parents, inv_revision=inv_revision,
2927.2.4 by Andrew Bennetts
Don't create a 'rev3' file version in the test.
137
            root_revision=root_revision, file_contents=file_contents,
138
            make_file_version=make_file_version)
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
139
140
    def add_revision(self, repo, revision_id, inv, parent_ids):
141
        return self.test_case.add_revision(repo, revision_id, inv, parent_ids)
142
2927.2.3 by Andrew Bennetts
Add fulltexts to avoid bug 155730.
143
    def corrected_fulltexts(self):
144
        return []
145
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
146
2745.6.50 by Andrew Bennetts
Remove find_bad_ancestors; it's not needed anymore.
147
class UndamagedRepositoryScenario(BrokenRepoScenario):
148
    """A scenario where the repository has no damage.
149
150
    It has a single revision, 'rev1a', with a single file.
151
    """
152
2927.2.14 by Andrew Bennetts
Tweaks suggested by review.
153
    def all_versions_after_reconcile(self):
2592.3.214 by Robert Collins
Merge bzr.dev.
154
        return ('rev1a', )
2745.6.50 by Andrew Bennetts
Remove find_bad_ancestors; it's not needed anymore.
155
156
    def populated_parents(self):
2592.3.214 by Robert Collins
Merge bzr.dev.
157
        return (((), 'rev1a'), )
2745.6.50 by Andrew Bennetts
Remove find_bad_ancestors; it's not needed anymore.
158
159
    def corrected_parents(self):
160
        # Same as the populated parents, because there was nothing wrong.
161
        return self.populated_parents()
162
163
    def check_regexes(self):
164
        return ["0 unreferenced text ancestors"]
165
166
    def populate_repository(self, repo):
167
        # make rev1a: A well-formed revision, containing 'a-file'
168
        inv = self.make_one_file_inventory(
169
            repo, 'rev1a', [], root_revision='rev1a')
170
        self.add_revision(repo, 'rev1a', inv, [])
171
172
2745.6.43 by Andrew Bennetts
Tidy imports, docstrings, comments and variable names.
173
class FileParentIsNotInRevisionAncestryScenario(BrokenRepoScenario):
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
174
    """A scenario where a revision 'rev2' has 'a-file' with a
175
    parent 'rev1b' that is not in the revision ancestry.
176
    
177
    Reconcile should remove 'rev1b' from the parents list of 'a-file' in
178
    'rev2', preserving 'rev1a' as a parent.
179
    """
180
2927.2.14 by Andrew Bennetts
Tweaks suggested by review.
181
    def all_versions_after_reconcile(self):
2592.3.214 by Robert Collins
Merge bzr.dev.
182
        return ('rev1a', 'rev1b', 'rev2')
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
183
184
    def populated_parents(self):
2592.3.214 by Robert Collins
Merge bzr.dev.
185
        return (
186
            ((), 'rev1a'),
187
            ((), 'rev1b'),
188
            (('rev1a', 'rev1b'), 'rev2'))
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
189
190
    def corrected_parents(self):
2592.3.214 by Robert Collins
Merge bzr.dev.
191
        return (
192
            ((), 'rev1a'),
193
            ((), 'rev1b'),
194
            (('rev1a',), 'rev2'))
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
195
2745.6.41 by Andrew Bennetts
Test repo.check against all_scenarios.
196
    def check_regexes(self):
2592.3.214 by Robert Collins
Merge bzr.dev.
197
        return [r"\* a-file-id version rev2 has parents \('rev1a', 'rev1b'\) "
198
                r"but should have \('rev1a',\)",
2745.6.50 by Andrew Bennetts
Remove find_bad_ancestors; it's not needed anymore.
199
                "1 unreferenced text ancestors",
200
                ]
2745.6.41 by Andrew Bennetts
Test repo.check against all_scenarios.
201
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
202
    def populate_repository(self, repo):
203
        # make rev1a: A well-formed revision, containing 'a-file'
204
        inv = self.make_one_file_inventory(
205
            repo, 'rev1a', [], root_revision='rev1a')
206
        self.add_revision(repo, 'rev1a', inv, [])
207
208
        # make rev1b, which has no Revision, but has an Inventory, and
209
        # a-file
210
        inv = self.make_one_file_inventory(
211
            repo, 'rev1b', [], root_revision='rev1b')
212
        repo.add_inventory('rev1b', inv, [])
213
214
        # make rev2, with a-file.
215
        # a-file has 'rev1b' as an ancestor, even though this is not
216
        # mentioned by 'rev1a', making it an unreferenced ancestor
217
        inv = self.make_one_file_inventory(
218
            repo, 'rev2', ['rev1a', 'rev1b'])
219
        self.add_revision(repo, 'rev2', inv, ['rev1a'])
220
221
2745.6.43 by Andrew Bennetts
Tidy imports, docstrings, comments and variable names.
222
class FileParentHasInaccessibleInventoryScenario(BrokenRepoScenario):
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
223
    """A scenario where a revision 'rev3' containing 'a-file' modified in
224
    'rev3', and with a parent which is in the revision ancestory, but whose
225
    inventory cannot be accessed at all.
226
227
    Reconcile should remove the file version parent whose inventory is
228
    inaccessbile (i.e. remove 'rev1c' from the parents of a-file's rev3).
229
    """
230
2927.2.14 by Andrew Bennetts
Tweaks suggested by review.
231
    def all_versions_after_reconcile(self):
2592.3.214 by Robert Collins
Merge bzr.dev.
232
        return ('rev2', 'rev3')
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
233
234
    def populated_parents(self):
2592.3.214 by Robert Collins
Merge bzr.dev.
235
        return (
236
            ((), 'rev2'),
237
            (('rev1c',), 'rev3'))
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
238
239
    def corrected_parents(self):
2592.3.214 by Robert Collins
Merge bzr.dev.
240
        return (
241
            ((), 'rev2'),
242
            ((), 'rev3'))
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
243
2745.6.41 by Andrew Bennetts
Test repo.check against all_scenarios.
244
    def check_regexes(self):
2745.6.43 by Andrew Bennetts
Tidy imports, docstrings, comments and variable names.
245
        return [r"\* a-file-id version rev3 has parents "
2592.3.214 by Robert Collins
Merge bzr.dev.
246
                r"\('rev1c',\) but should have \(\)",
2745.6.50 by Andrew Bennetts
Remove find_bad_ancestors; it's not needed anymore.
247
                # Also check reporting of unreferenced ancestors
248
                r"unreferenced ancestor: {rev1c} in a-file-id",
249
                ]
2745.6.41 by Andrew Bennetts
Test repo.check against all_scenarios.
250
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
251
    def populate_repository(self, repo):
252
        # make rev2, with a-file
253
        # a-file is sane
254
        inv = self.make_one_file_inventory(repo, 'rev2', [])
255
        self.add_revision(repo, 'rev2', inv, [])
256
257
        # make ghost revision rev1c, with a version of a-file present so
258
        # that we generate a knit delta against this version.  In real life
259
        # the ghost might never have been present or rev3 might have been
260
        # generated against a revision that was present at the time.  So
261
        # currently we have the full history of a-file present even though
262
        # the inventory and revision objects are not.
263
        self.make_one_file_inventory(repo, 'rev1c', [])
264
265
        # make rev3 with a-file
266
        # a-file refers to 'rev1c', which is a ghost in this repository, so
267
        # a-file cannot have rev1c as its ancestor.
268
        inv = self.make_one_file_inventory(repo, 'rev3', ['rev1c'])
269
        self.add_revision(repo, 'rev3', inv, ['rev1c', 'rev1a'])
270
271
2745.6.43 by Andrew Bennetts
Tidy imports, docstrings, comments and variable names.
272
class FileParentsNotReferencedByAnyInventoryScenario(BrokenRepoScenario):
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
273
    """A scenario where a repository with file 'a-file' which has extra
274
    per-file versions that are not referenced by any inventory (even though
275
    they have the same ID as actual revisions).  The inventory of 'rev2'
276
    references 'rev1a' of 'a-file', but there is a 'rev2' of 'some-file' stored
277
    and erroneously referenced by later per-file versions (revisions 'rev4' and
278
    'rev5').
279
280
    Reconcile should remove the file parents that are not referenced by any
281
    inventory.
282
    """
283
2927.2.14 by Andrew Bennetts
Tweaks suggested by review.
284
    def all_versions_after_reconcile(self):
2927.2.11 by Andrew Bennetts
Merge from bzr.dev.
285
        return ('rev1a', 'rev2c', 'rev4', 'rev5')
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
286
287
    def populated_parents(self):
288
        return [
2927.2.11 by Andrew Bennetts
Merge from bzr.dev.
289
            (('rev1a',), 'rev2'),
290
            (('rev1a',), 'rev2b'),
2592.3.214 by Robert Collins
Merge bzr.dev.
291
            (('rev2',), 'rev3'),
292
            (('rev2',), 'rev4'),
2927.2.11 by Andrew Bennetts
Merge from bzr.dev.
293
            (('rev2', 'rev2c'), 'rev5')]
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
294
295
    def corrected_parents(self):
2592.3.214 by Robert Collins
Merge bzr.dev.
296
        return (
2927.2.8 by Andrew Bennetts
Remove totally unreferenced file versions. All reconcile tests passing.
297
            # rev2 and rev2b have been removed.
298
            (None, 'rev2'),
299
            (None, 'rev2b'),
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
300
            # rev3's accessible parent inventories all have rev1a as the last
301
            # modifier.
2592.3.214 by Robert Collins
Merge bzr.dev.
302
            (('rev1a',), 'rev3'),
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
303
            # rev1a features in both rev4's parents but should only appear once
304
            # in the result
2592.3.214 by Robert Collins
Merge bzr.dev.
305
            (('rev1a',), 'rev4'),
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
306
            # rev2c is the head of rev1a and rev2c, the inventory provided
307
            # per-file last-modified revisions.
2592.3.214 by Robert Collins
Merge bzr.dev.
308
            (('rev2c',), 'rev5'))
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
309
2745.6.41 by Andrew Bennetts
Test repo.check against all_scenarios.
310
    def check_regexes(self):
311
        return [
2927.2.9 by Andrew Bennetts
Adjust expected 'check' output in test scenarios. All test_check_reconcile now passes.
312
            "5 inconsistent parents",
2927.2.11 by Andrew Bennetts
Merge from bzr.dev.
313
            r"a-file-id version rev2 has parents \('rev1a',\) "
314
            r"but should have \(\)",
315
            r"a-file-id version rev2b has parents \('rev1a',\) "
316
            r"but should have \(\)",
2592.3.214 by Robert Collins
Merge bzr.dev.
317
            r"a-file-id version rev3 has parents \('rev2',\) "
318
            r"but should have \('rev1a',\)",
319
            r"a-file-id version rev5 has parents \('rev2', 'rev2c'\) "
320
            r"but should have \('rev2c',\)",
321
            r"a-file-id version rev4 has parents \('rev2',\) "
322
            r"but should have \('rev1a',\)",
2927.2.13 by Andrew Bennetts
Display number of file versions not referenced by their corresponding inventory (i.e. dangling versions) in bzr check output.
323
            "2 file versions are not referenced by their inventory",
2745.6.41 by Andrew Bennetts
Test repo.check against all_scenarios.
324
            ]
325
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
326
    def populate_repository(self, repo):
327
        # make rev1a: A well-formed revision, containing 'a-file'
328
        inv = self.make_one_file_inventory(
329
            repo, 'rev1a', [], root_revision='rev1a')
330
        self.add_revision(repo, 'rev1a', inv, [])
331
332
        # make rev2, with a-file.
2927.2.3 by Andrew Bennetts
Add fulltexts to avoid bug 155730.
333
        # a-file is unmodified from rev1a, and an unreferenced rev2 file
334
        # version is present in the repository.
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
335
        self.make_one_file_inventory(
336
            repo, 'rev2', ['rev1a'], inv_revision='rev1a')
337
        self.add_revision(repo, 'rev2', inv, ['rev1a'])
338
339
        # make rev3 with a-file
340
        # a-file has 'rev2' as its ancestor, but the revision in 'rev2' was
341
        # rev1a so this is inconsistent with rev2's inventory - it should
342
        # be rev1a, and at the revision level 1c is not present - it is a
343
        # ghost, so only the details from rev1a are available for
344
        # determining whether a delta is acceptable, or a full is needed,
2745.6.43 by Andrew Bennetts
Tidy imports, docstrings, comments and variable names.
345
        # and what the correct parents are.
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
346
        inv = self.make_one_file_inventory(repo, 'rev3', ['rev2'])
2745.6.43 by Andrew Bennetts
Tidy imports, docstrings, comments and variable names.
347
        self.add_revision(repo, 'rev3', inv, ['rev1c', 'rev1a'])
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
348
349
        # In rev2b, the true last-modifying-revision of a-file is rev1a,
350
        # inherited from rev2, but there is a version rev2b of the file, which
351
        # reconcile could remove, leaving no rev2b.  Most importantly,
352
        # revisions descending from rev2b should not have per-file parents of
353
        # a-file-rev2b.
354
        # ??? This is to test deduplication in fixing rev4
355
        inv = self.make_one_file_inventory(
356
            repo, 'rev2b', ['rev1a'], inv_revision='rev1a')
357
        self.add_revision(repo, 'rev2b', inv, ['rev1a'])
358
359
        # rev4 is for testing that when the last modified of a file in
360
        # multiple parent revisions is the same, that it only appears once
361
        # in the generated per file parents list: rev2 and rev2b both
362
        # descend from 1a and do not change the file a-file, so there should
363
        # be no version of a-file 'rev2' or 'rev2b', but rev4 does change
364
        # a-file, and is a merge of rev2 and rev2b, so it should end up with
365
        # a parent of just rev1a - the starting file parents list is simply
366
        # completely wrong.
367
        inv = self.make_one_file_inventory(repo, 'rev4', ['rev2'])
368
        self.add_revision(repo, 'rev4', inv, ['rev2', 'rev2b'])
369
370
        # rev2c changes a-file from rev1a, so the version it of a-file it
371
        # introduces is a head revision when rev5 is checked.
372
        inv = self.make_one_file_inventory(repo, 'rev2c', ['rev1a'])
373
        self.add_revision(repo, 'rev2c', inv, ['rev1a'])
374
375
        # rev5 descends from rev2 and rev2c; as rev2 does not alter a-file,
376
        # but rev2c does, this should use rev2c as the parent for the per
377
        # file history, even though more than one per-file parent is
378
        # available, because we use the heads of the revision parents for
379
        # the inventory modification revisions of the file to determine the
380
        # parents for the per file graph.
381
        inv = self.make_one_file_inventory(repo, 'rev5', ['rev2', 'rev2c'])
382
        self.add_revision(repo, 'rev5', inv, ['rev2', 'rev2c'])
383
384
2927.2.3 by Andrew Bennetts
Add fulltexts to avoid bug 155730.
385
class UnreferencedFileParentsFromNoOpMergeScenario(BrokenRepoScenario):
386
    """
387
    rev1a and rev1b with identical contents
388
    rev2 revision has parents of [rev1a, rev1b]
389
    There is a a-file:rev2 file version, not referenced by the inventory.
390
    """
391
2927.2.14 by Andrew Bennetts
Tweaks suggested by review.
392
    def all_versions_after_reconcile(self):
2927.2.11 by Andrew Bennetts
Merge from bzr.dev.
393
        return ('rev1a', 'rev1b', 'rev2', 'rev4')
2927.2.3 by Andrew Bennetts
Add fulltexts to avoid bug 155730.
394
395
    def populated_parents(self):
2927.2.11 by Andrew Bennetts
Merge from bzr.dev.
396
        return (
397
            ((), 'rev1a'),
398
            ((), 'rev1b'),
399
            (('rev1a', 'rev1b'), 'rev2'),
2927.2.4 by Andrew Bennetts
Don't create a 'rev3' file version in the test.
400
            (None, 'rev3'),
2927.2.11 by Andrew Bennetts
Merge from bzr.dev.
401
            (('rev2',), 'rev4'),
402
            )
2927.2.3 by Andrew Bennetts
Add fulltexts to avoid bug 155730.
403
404
    def corrected_parents(self):
2927.2.11 by Andrew Bennetts
Merge from bzr.dev.
405
        return (
406
            ((), 'rev1a'),
407
            ((), 'rev1b'),
408
            ((), 'rev2'),
2927.2.4 by Andrew Bennetts
Don't create a 'rev3' file version in the test.
409
            (None, 'rev3'),
2927.2.11 by Andrew Bennetts
Merge from bzr.dev.
410
            (('rev2',), 'rev4'),
411
            )
2927.2.3 by Andrew Bennetts
Add fulltexts to avoid bug 155730.
412
413
    def corrected_fulltexts(self):
414
        return ['rev4']
415
416
    def check_regexes(self):
417
        return []
418
419
    def populate_repository(self, repo):
420
        # make rev1a: A well-formed revision, containing 'a-file'
421
        inv1a = self.make_one_file_inventory(
422
            repo, 'rev1a', [], root_revision='rev1a')
423
        self.add_revision(repo, 'rev1a', inv1a, [])
424
425
        # make rev1b: A well-formed revision, containing 'a-file'
426
        # rev1b of a-file has the exact same contents as rev1a.
427
        file_contents = repo.revision_tree('rev1a').get_file_text('a-file-id')
428
        inv = self.make_one_file_inventory(
429
            repo, 'rev1b', [], root_revision='rev1b',
430
            file_contents=file_contents)
431
        self.add_revision(repo, 'rev1b', inv, [])
432
433
        # make rev2, a merge of rev1a and rev1b, with a-file.
434
        # a-file is unmodified from rev1a and rev1b, but a new version is
435
        # wrongly present anyway.
436
        inv = self.make_one_file_inventory(
437
            repo, 'rev2', ['rev1a', 'rev1b'], inv_revision='rev1a',
438
            file_contents=file_contents)
439
        self.add_revision(repo, 'rev2', inv, ['rev1a', 'rev1b'])
440
441
        # rev3: a-file unchanged from rev2, but wrongly referencing rev2 of the
442
        # file in its inventory.
443
        inv = self.make_one_file_inventory(
444
            repo, 'rev3', ['rev2'], inv_revision='rev2',
2927.2.4 by Andrew Bennetts
Don't create a 'rev3' file version in the test.
445
            file_contents=file_contents, make_file_version=False)
2927.2.3 by Andrew Bennetts
Add fulltexts to avoid bug 155730.
446
        self.add_revision(repo, 'rev3', inv, ['rev2'])
447
448
        # 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.
449
        inv = self.make_one_file_inventory(repo, 'rev4', ['rev2'])
2927.2.3 by Andrew Bennetts
Add fulltexts to avoid bug 155730.
450
        self.add_revision(repo, 'rev4', inv, ['rev3'])
451
452
2745.6.43 by Andrew Bennetts
Tidy imports, docstrings, comments and variable names.
453
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.
454
    """A scenario where 'broken-revision' of 'a-file' claims to have parents
455
    ['good-parent', 'bad-parent'].  However 'bad-parent' is in the ancestry of
456
    'good-parent', so the correct parent list for that file version are is just
457
    ['good-parent'].
458
    """
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
459
2927.2.14 by Andrew Bennetts
Tweaks suggested by review.
460
    def all_versions_after_reconcile(self):
2592.3.214 by Robert Collins
Merge bzr.dev.
461
        return ('bad-parent', 'good-parent', 'broken-revision')
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
462
463
    def populated_parents(self):
2592.3.214 by Robert Collins
Merge bzr.dev.
464
        return (
465
            ((), 'bad-parent'),
466
            (('bad-parent',), 'good-parent'),
467
            (('good-parent', 'bad-parent'), 'broken-revision'))
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
468
469
    def corrected_parents(self):
2592.3.214 by Robert Collins
Merge bzr.dev.
470
        return (
471
            ((), 'bad-parent'),
472
            (('bad-parent',), 'good-parent'),
473
            (('good-parent',), 'broken-revision'))
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
474
2745.6.39 by Andrew Bennetts
Use scenario in test_check too, and make check actually report inconsistent parents to the end user.
475
    def check_regexes(self):
2592.3.214 by Robert Collins
Merge bzr.dev.
476
        return (
2745.6.39 by Andrew Bennetts
Use scenario in test_check too, and make check actually report inconsistent parents to the end user.
477
            '     1 inconsistent parents',
478
            (r"      \* a-file-id version broken-revision has parents "
2592.3.214 by Robert Collins
Merge bzr.dev.
479
             r"\('good-parent', 'bad-parent'\) but "
480
             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.
481
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
482
    def populate_repository(self, repo):
483
        inv = self.make_one_file_inventory(
2592.3.214 by Robert Collins
Merge bzr.dev.
484
            repo, 'bad-parent', (), root_revision='bad-parent')
485
        self.add_revision(repo, 'bad-parent', inv, ())
486
        
487
        inv = self.make_one_file_inventory(
488
            repo, 'good-parent', ('bad-parent',))
489
        self.add_revision(repo, 'good-parent', inv, ('bad-parent',))
490
        
491
        inv = self.make_one_file_inventory(
492
            repo, 'broken-revision', ('good-parent', 'bad-parent'))
493
        self.add_revision(repo, 'broken-revision', inv, ('good-parent',))
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
494
495
2745.6.43 by Andrew Bennetts
Tidy imports, docstrings, comments and variable names.
496
class ClaimedFileParentDidNotModifyFileScenario(BrokenRepoScenario):
497
    """A scenario where the file parent is the same as the revision parent, but
498
    should not be because that revision did not modify the file.
499
500
    Specifically, the parent revision of 'current' is
501
    'modified-something-else', which does not modify 'a-file', but the
502
    'current' version of 'a-file' erroneously claims that
503
    'modified-something-else' is the parent file version.
504
    """
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
505
2927.2.14 by Andrew Bennetts
Tweaks suggested by review.
506
    def all_versions_after_reconcile(self):
2927.2.11 by Andrew Bennetts
Merge from bzr.dev.
507
        return ('basis', 'current')
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
508
509
    def populated_parents(self):
2592.3.214 by Robert Collins
Merge bzr.dev.
510
        return (
511
            ((), 'basis'),
512
            (('basis',), 'modified-something-else'),
513
            (('modified-something-else',), 'current'))
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
514
515
    def corrected_parents(self):
2592.3.214 by Robert Collins
Merge bzr.dev.
516
        return (
517
            ((), 'basis'),
2927.2.8 by Andrew Bennetts
Remove totally unreferenced file versions. All reconcile tests passing.
518
            (None, 'modified-something-else'),
2592.3.214 by Robert Collins
Merge bzr.dev.
519
            (('basis',), 'current'))
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
520
2745.6.41 by Andrew Bennetts
Test repo.check against all_scenarios.
521
    def check_regexes(self):
2592.3.214 by Robert Collins
Merge bzr.dev.
522
        return (
2927.2.9 by Andrew Bennetts
Adjust expected 'check' output in test scenarios. All test_check_reconcile now passes.
523
            '2 inconsistent parents',
2745.6.41 by Andrew Bennetts
Test repo.check against all_scenarios.
524
            r"\* a-file-id version current has parents "
2927.2.11 by Andrew Bennetts
Merge from bzr.dev.
525
            r"\('modified-something-else',\) but should have \('basis',\)",
2927.2.9 by Andrew Bennetts
Adjust expected 'check' output in test scenarios. All test_check_reconcile now passes.
526
            r"\* a-file-id version modified-something-else has parents "
2927.2.11 by Andrew Bennetts
Merge from bzr.dev.
527
            r"\('basis',\) but should have \(\)",
528
            )
2745.6.41 by Andrew Bennetts
Test repo.check against all_scenarios.
529
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
530
    def populate_repository(self, repo):
2592.3.214 by Robert Collins
Merge bzr.dev.
531
        inv = self.make_one_file_inventory(repo, 'basis', ())
532
        self.add_revision(repo, 'basis', inv, ())
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
533
2745.6.43 by Andrew Bennetts
Tidy imports, docstrings, comments and variable names.
534
        # 'modified-something-else' is a correctly recorded revision, but it
535
        # does not modify the file we are looking at, so the inventory for that
536
        # file in this revision points to 'basis'.
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
537
        inv = self.make_one_file_inventory(
2592.3.214 by Robert Collins
Merge bzr.dev.
538
            repo, 'modified-something-else', ('basis',), inv_revision='basis')
539
        self.add_revision(repo, 'modified-something-else', inv, ('basis',))
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
540
2745.6.43 by Andrew Bennetts
Tidy imports, docstrings, comments and variable names.
541
        # The 'current' revision has 'modified-something-else' as its parent,
542
        # but the 'current' version of 'a-file' should have 'basis' as its
543
        # parent.
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
544
        inv = self.make_one_file_inventory(
2592.3.214 by Robert Collins
Merge bzr.dev.
545
            repo, 'current', ('modified-something-else',))
546
        self.add_revision(repo, 'current', inv, ('modified-something-else',))
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
547
548
2745.6.43 by Andrew Bennetts
Tidy imports, docstrings, comments and variable names.
549
class IncorrectlyOrderedParentsScenario(BrokenRepoScenario):
550
    """A scenario where the set parents of a version of a file are correct, but
551
    the order of those parents is incorrect.
552
553
    This defines a 'broken-revision-1-2' and a 'broken-revision-2-1' which both
554
    have their file version parents reversed compared to the revision parents,
555
    which is invalid.  (We use two revisions with opposite orderings of the
556
    same parents to make sure that accidentally relying on dictionary/set
557
    ordering cannot make the test pass; the assumption is that while dict/set
558
    iteration order is arbitrary, it is also consistent within a single test).
559
    """
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
560
2927.2.14 by Andrew Bennetts
Tweaks suggested by review.
561
    def all_versions_after_reconcile(self):
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
562
        return ['parent-1', 'parent-2', 'broken-revision-1-2',
563
                'broken-revision-2-1']
564
565
    def populated_parents(self):
2592.3.214 by Robert Collins
Merge bzr.dev.
566
        return (
567
            ((), 'parent-1'),
568
            ((), 'parent-2'),
569
            (('parent-2', 'parent-1'), 'broken-revision-1-2'),
570
            (('parent-1', 'parent-2'), 'broken-revision-2-1'))
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
571
572
    def corrected_parents(self):
2592.3.214 by Robert Collins
Merge bzr.dev.
573
        return (
574
            ((), 'parent-1'),
575
            ((), 'parent-2'),
576
            (('parent-1', 'parent-2'), 'broken-revision-1-2'),
577
            (('parent-2', 'parent-1'), 'broken-revision-2-1'))
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
578
2745.6.41 by Andrew Bennetts
Test repo.check against all_scenarios.
579
    def check_regexes(self):
2592.3.214 by Robert Collins
Merge bzr.dev.
580
        return (
2745.6.41 by Andrew Bennetts
Test repo.check against all_scenarios.
581
            "2 inconsistent parents",
582
            r"\* a-file-id version broken-revision-1-2 has parents "
2592.3.214 by Robert Collins
Merge bzr.dev.
583
            r"\('parent-2', 'parent-1'\) but should have "
584
            r"\('parent-1', 'parent-2'\)",
2745.6.41 by Andrew Bennetts
Test repo.check against all_scenarios.
585
            r"\* a-file-id version broken-revision-2-1 has parents "
2592.3.214 by Robert Collins
Merge bzr.dev.
586
            r"\('parent-1', 'parent-2'\) but should have "
587
            r"\('parent-2', 'parent-1'\)")
2745.6.41 by Andrew Bennetts
Test repo.check against all_scenarios.
588
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
589
    def populate_repository(self, repo):
590
        inv = self.make_one_file_inventory(repo, 'parent-1', [])
591
        self.add_revision(repo, 'parent-1', inv, [])
592
593
        inv = self.make_one_file_inventory(repo, 'parent-2', [])
594
        self.add_revision(repo, 'parent-2', inv, [])
595
596
        inv = self.make_one_file_inventory(
597
            repo, 'broken-revision-1-2', ['parent-2', 'parent-1'])
598
        self.add_revision(
599
            repo, 'broken-revision-1-2', inv, ['parent-1', 'parent-2'])
600
601
        inv = self.make_one_file_inventory(
602
            repo, 'broken-revision-2-1', ['parent-1', 'parent-2'])
603
        self.add_revision(
604
            repo, 'broken-revision-2-1', inv, ['parent-2', 'parent-1'])
2745.6.32 by Andrew Bennetts
Some testing notes, test reorganisation, XXX comments and some failing tests.
605
2485.7.1 by Robert Collins
Relocate TestCaseWithRepository to be more central.
606
2745.6.58 by Andrew Bennetts
Slightly neater test parameterisation in repository_implementations; extract a 'multiply_scenarios' function.
607
all_broken_scenario_classes = [
2745.6.54 by Andrew Bennetts
Tidy test parameterisation in repository_implementations.
608
    UndamagedRepositoryScenario,
609
    FileParentIsNotInRevisionAncestryScenario,
610
    FileParentHasInaccessibleInventoryScenario,
611
    FileParentsNotReferencedByAnyInventoryScenario,
612
    TooManyParentsScenario,
613
    ClaimedFileParentDidNotModifyFileScenario,
614
    IncorrectlyOrderedParentsScenario,
2927.2.3 by Andrew Bennetts
Add fulltexts to avoid bug 155730.
615
    UnreferencedFileParentsFromNoOpMergeScenario,
2745.6.54 by Andrew Bennetts
Tidy test parameterisation in repository_implementations.
616
    ]
617
    
2745.6.42 by Andrew Bennetts
Use TestScenarioApplier to more cleanly parameterise check and reconcile tests.
618
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
619
def test_suite():
2241.1.11 by Martin Pool
Get rid of RepositoryFormat*_instance objects. Instead the format
620
    registry = repository.format_registry
621
    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.
622
    all_formats.extend(weaverepo._legacy_formats)
2745.6.54 by Andrew Bennetts
Tidy test parameterisation in repository_implementations.
623
    disk_format_adapter = RepositoryTestProviderAdapter(
2018.5.30 by Robert Collins
Reenable the stock repository implementations for testing.
624
        default_transport,
625
        # None here will cause a readonly decorator to be created
626
        # by the TestCaseWithTransport.get_readonly_transport method.
627
        None,
2241.1.1 by Martin Pool
Change RepositoryFormat to use a Registry rather than ad-hoc dictionary
628
        [(format, format._matchingbzrdir) for format in all_formats])
2018.5.30 by Robert Collins
Reenable the stock repository implementations for testing.
629
2745.6.54 by Andrew Bennetts
Tidy test parameterisation in repository_implementations.
630
    remote_repo_adapter = RepositoryTestProviderAdapter(
2018.5.30 by Robert Collins
Reenable the stock repository implementations for testing.
631
        SmartTCPServer_for_testing,
632
        ReadonlySmartTCPServer_for_testing,
2018.5.66 by Wouter van Heyst
Fix repository test parameterization for RemoteRepository.
633
        [(RemoteRepositoryFormat(), RemoteBzrDirFormat())],
634
        MemoryServer
635
        )
2745.6.54 by Andrew Bennetts
Tidy test parameterisation in repository_implementations.
636
2745.6.58 by Andrew Bennetts
Slightly neater test parameterisation in repository_implementations; extract a 'multiply_scenarios' function.
637
    # format_scenarios is all the implementations of Repository; i.e. all disk
638
    # formats plus RemoteRepository.
639
    format_scenarios = (disk_format_adapter.scenarios +
640
                        remote_repo_adapter.scenarios)
2745.6.54 by Andrew Bennetts
Tidy test parameterisation in repository_implementations.
641
642
    prefix = 'bzrlib.tests.repository_implementations.'
2745.6.58 by Andrew Bennetts
Slightly neater test parameterisation in repository_implementations; extract a 'multiply_scenarios' function.
643
    test_repository_modules = [
2745.6.57 by Andrew Bennetts
Some improvements suggested by Martin's review.
644
        'test_break_lock',
645
        'test_check',
2745.6.58 by Andrew Bennetts
Slightly neater test parameterisation in repository_implementations; extract a 'multiply_scenarios' function.
646
        # test_check_reconcile is intentionally omitted, see below.
2745.6.57 by Andrew Bennetts
Some improvements suggested by Martin's review.
647
        'test_commit_builder',
648
        'test_fetch',
649
        'test_fileid_involved',
650
        'test_has_same_location',
2904.1.2 by Robert Collins
Merge bzr.dev
651
        'test_is_write_locked',
2745.6.57 by Andrew Bennetts
Some improvements suggested by Martin's review.
652
        'test_iter_reverse_revision_history',
653
        'test_pack',
654
        'test_reconcile',
655
        'test_repository',
656
        'test_revision',
657
        'test_statistics',
658
        'test_write_group',
2745.6.54 by Andrew Bennetts
Tidy test parameterisation in repository_implementations.
659
        ]
2745.6.58 by Andrew Bennetts
Slightly neater test parameterisation in repository_implementations; extract a 'multiply_scenarios' function.
660
    module_name_list = [prefix + module_name
661
                        for module_name in test_repository_modules]
662
663
    # Parameterise repository_implementations test modules by format.
664
    result = multiply_tests_from_modules(module_name_list, format_scenarios)
665
666
    # test_check_reconcile needs to be parameterised by format *and* by broken
667
    # repository scenario.
668
    broken_scenarios = [(s.__name__, {'scenario_class': s})
669
                        for s in all_broken_scenario_classes]
670
    broken_scenarios_for_all_formats = multiply_scenarios(
671
        format_scenarios, broken_scenarios)
672
    broken_scenario_applier = TestScenarioApplier()
673
    broken_scenario_applier.scenarios = broken_scenarios_for_all_formats
2745.6.54 by Andrew Bennetts
Tidy test parameterisation in repository_implementations.
674
    loader = TestLoader()
2745.6.57 by Andrew Bennetts
Some improvements suggested by Martin's review.
675
    adapt_modules(
676
        [prefix + 'test_check_reconcile'],
677
        broken_scenario_applier, loader, result)
2745.6.54 by Andrew Bennetts
Tidy test parameterisation in repository_implementations.
678
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
679
    return result