/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
2951.1.6 by Robert Collins
All check/reconcile tests passing now.
163
    def check_regexes(self, repo):
2745.6.50 by Andrew Bennetts
Remove find_bad_ancestors; it's not needed anymore.
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
2951.1.6 by Robert Collins
All check/reconcile tests passing now.
196
    def check_regexes(self, repo):
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
2951.1.6 by Robert Collins
All check/reconcile tests passing now.
244
    def check_regexes(self, repo):
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
2951.1.6 by Robert Collins
All check/reconcile tests passing now.
310
    def check_regexes(self, repo):
311
        if repo.supports_rich_root():
312
            # TREE_ROOT will be wrong; but we're not testing it. so just adjust
313
            # the expected count of errors.
314
            count = 11
315
        else:
316
            count = 5
2745.6.41 by Andrew Bennetts
Test repo.check against all_scenarios.
317
        return [
2951.1.6 by Robert Collins
All check/reconcile tests passing now.
318
            "%d inconsistent parents" % count,
2927.2.11 by Andrew Bennetts
Merge from bzr.dev.
319
            r"a-file-id version rev2 has parents \('rev1a',\) "
320
            r"but should have \(\)",
321
            r"a-file-id version rev2b has parents \('rev1a',\) "
322
            r"but should have \(\)",
2592.3.214 by Robert Collins
Merge bzr.dev.
323
            r"a-file-id version rev3 has parents \('rev2',\) "
324
            r"but should have \('rev1a',\)",
325
            r"a-file-id version rev5 has parents \('rev2', 'rev2c'\) "
326
            r"but should have \('rev2c',\)",
327
            r"a-file-id version rev4 has parents \('rev2',\) "
328
            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.
329
            "2 file versions are not referenced by their inventory",
2745.6.41 by Andrew Bennetts
Test repo.check against all_scenarios.
330
            ]
331
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
332
    def populate_repository(self, repo):
333
        # make rev1a: A well-formed revision, containing 'a-file'
334
        inv = self.make_one_file_inventory(
335
            repo, 'rev1a', [], root_revision='rev1a')
336
        self.add_revision(repo, 'rev1a', inv, [])
337
338
        # make rev2, with a-file.
2927.2.3 by Andrew Bennetts
Add fulltexts to avoid bug 155730.
339
        # a-file is unmodified from rev1a, and an unreferenced rev2 file
340
        # version is present in the repository.
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
341
        self.make_one_file_inventory(
342
            repo, 'rev2', ['rev1a'], inv_revision='rev1a')
343
        self.add_revision(repo, 'rev2', inv, ['rev1a'])
344
345
        # make rev3 with a-file
346
        # a-file has 'rev2' as its ancestor, but the revision in 'rev2' was
347
        # rev1a so this is inconsistent with rev2's inventory - it should
348
        # be rev1a, and at the revision level 1c is not present - it is a
349
        # ghost, so only the details from rev1a are available for
350
        # determining whether a delta is acceptable, or a full is needed,
2745.6.43 by Andrew Bennetts
Tidy imports, docstrings, comments and variable names.
351
        # and what the correct parents are.
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
352
        inv = self.make_one_file_inventory(repo, 'rev3', ['rev2'])
2745.6.43 by Andrew Bennetts
Tidy imports, docstrings, comments and variable names.
353
        self.add_revision(repo, 'rev3', inv, ['rev1c', 'rev1a'])
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
354
355
        # In rev2b, the true last-modifying-revision of a-file is rev1a,
356
        # inherited from rev2, but there is a version rev2b of the file, which
357
        # reconcile could remove, leaving no rev2b.  Most importantly,
358
        # revisions descending from rev2b should not have per-file parents of
359
        # a-file-rev2b.
360
        # ??? This is to test deduplication in fixing rev4
361
        inv = self.make_one_file_inventory(
362
            repo, 'rev2b', ['rev1a'], inv_revision='rev1a')
363
        self.add_revision(repo, 'rev2b', inv, ['rev1a'])
364
365
        # rev4 is for testing that when the last modified of a file in
366
        # multiple parent revisions is the same, that it only appears once
367
        # in the generated per file parents list: rev2 and rev2b both
368
        # descend from 1a and do not change the file a-file, so there should
369
        # be no version of a-file 'rev2' or 'rev2b', but rev4 does change
370
        # a-file, and is a merge of rev2 and rev2b, so it should end up with
371
        # a parent of just rev1a - the starting file parents list is simply
372
        # completely wrong.
373
        inv = self.make_one_file_inventory(repo, 'rev4', ['rev2'])
374
        self.add_revision(repo, 'rev4', inv, ['rev2', 'rev2b'])
375
376
        # rev2c changes a-file from rev1a, so the version it of a-file it
377
        # introduces is a head revision when rev5 is checked.
378
        inv = self.make_one_file_inventory(repo, 'rev2c', ['rev1a'])
379
        self.add_revision(repo, 'rev2c', inv, ['rev1a'])
380
381
        # rev5 descends from rev2 and rev2c; as rev2 does not alter a-file,
382
        # but rev2c does, this should use rev2c as the parent for the per
383
        # file history, even though more than one per-file parent is
384
        # available, because we use the heads of the revision parents for
385
        # the inventory modification revisions of the file to determine the
386
        # parents for the per file graph.
387
        inv = self.make_one_file_inventory(repo, 'rev5', ['rev2', 'rev2c'])
388
        self.add_revision(repo, 'rev5', inv, ['rev2', 'rev2c'])
389
390
2927.2.3 by Andrew Bennetts
Add fulltexts to avoid bug 155730.
391
class UnreferencedFileParentsFromNoOpMergeScenario(BrokenRepoScenario):
392
    """
393
    rev1a and rev1b with identical contents
394
    rev2 revision has parents of [rev1a, rev1b]
395
    There is a a-file:rev2 file version, not referenced by the inventory.
396
    """
397
2927.2.14 by Andrew Bennetts
Tweaks suggested by review.
398
    def all_versions_after_reconcile(self):
2927.2.11 by Andrew Bennetts
Merge from bzr.dev.
399
        return ('rev1a', 'rev1b', 'rev2', 'rev4')
2927.2.3 by Andrew Bennetts
Add fulltexts to avoid bug 155730.
400
401
    def populated_parents(self):
2927.2.11 by Andrew Bennetts
Merge from bzr.dev.
402
        return (
403
            ((), 'rev1a'),
404
            ((), 'rev1b'),
405
            (('rev1a', 'rev1b'), 'rev2'),
2927.2.4 by Andrew Bennetts
Don't create a 'rev3' file version in the test.
406
            (None, 'rev3'),
2927.2.11 by Andrew Bennetts
Merge from bzr.dev.
407
            (('rev2',), 'rev4'),
408
            )
2927.2.3 by Andrew Bennetts
Add fulltexts to avoid bug 155730.
409
410
    def corrected_parents(self):
2927.2.11 by Andrew Bennetts
Merge from bzr.dev.
411
        return (
412
            ((), 'rev1a'),
413
            ((), 'rev1b'),
414
            ((), 'rev2'),
2927.2.4 by Andrew Bennetts
Don't create a 'rev3' file version in the test.
415
            (None, 'rev3'),
2927.2.11 by Andrew Bennetts
Merge from bzr.dev.
416
            (('rev2',), 'rev4'),
417
            )
2927.2.3 by Andrew Bennetts
Add fulltexts to avoid bug 155730.
418
419
    def corrected_fulltexts(self):
420
        return ['rev4']
421
2951.1.6 by Robert Collins
All check/reconcile tests passing now.
422
    def check_regexes(self, repo):
2927.2.3 by Andrew Bennetts
Add fulltexts to avoid bug 155730.
423
        return []
424
425
    def populate_repository(self, repo):
426
        # make rev1a: A well-formed revision, containing 'a-file'
427
        inv1a = self.make_one_file_inventory(
428
            repo, 'rev1a', [], root_revision='rev1a')
429
        self.add_revision(repo, 'rev1a', inv1a, [])
430
431
        # make rev1b: A well-formed revision, containing 'a-file'
432
        # rev1b of a-file has the exact same contents as rev1a.
433
        file_contents = repo.revision_tree('rev1a').get_file_text('a-file-id')
434
        inv = self.make_one_file_inventory(
435
            repo, 'rev1b', [], root_revision='rev1b',
436
            file_contents=file_contents)
437
        self.add_revision(repo, 'rev1b', inv, [])
438
439
        # make rev2, a merge of rev1a and rev1b, with a-file.
440
        # a-file is unmodified from rev1a and rev1b, but a new version is
441
        # wrongly present anyway.
442
        inv = self.make_one_file_inventory(
443
            repo, 'rev2', ['rev1a', 'rev1b'], inv_revision='rev1a',
444
            file_contents=file_contents)
445
        self.add_revision(repo, 'rev2', inv, ['rev1a', 'rev1b'])
446
447
        # rev3: a-file unchanged from rev2, but wrongly referencing rev2 of the
448
        # file in its inventory.
449
        inv = self.make_one_file_inventory(
450
            repo, 'rev3', ['rev2'], inv_revision='rev2',
2927.2.4 by Andrew Bennetts
Don't create a 'rev3' file version in the test.
451
            file_contents=file_contents, make_file_version=False)
2927.2.3 by Andrew Bennetts
Add fulltexts to avoid bug 155730.
452
        self.add_revision(repo, 'rev3', inv, ['rev2'])
453
454
        # 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.
455
        inv = self.make_one_file_inventory(repo, 'rev4', ['rev2'])
2927.2.3 by Andrew Bennetts
Add fulltexts to avoid bug 155730.
456
        self.add_revision(repo, 'rev4', inv, ['rev3'])
457
458
2745.6.43 by Andrew Bennetts
Tidy imports, docstrings, comments and variable names.
459
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.
460
    """A scenario where 'broken-revision' of 'a-file' claims to have parents
461
    ['good-parent', 'bad-parent'].  However 'bad-parent' is in the ancestry of
462
    'good-parent', so the correct parent list for that file version are is just
463
    ['good-parent'].
464
    """
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
465
2927.2.14 by Andrew Bennetts
Tweaks suggested by review.
466
    def all_versions_after_reconcile(self):
2592.3.214 by Robert Collins
Merge bzr.dev.
467
        return ('bad-parent', 'good-parent', 'broken-revision')
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
468
469
    def populated_parents(self):
2592.3.214 by Robert Collins
Merge bzr.dev.
470
        return (
471
            ((), 'bad-parent'),
472
            (('bad-parent',), 'good-parent'),
473
            (('good-parent', 'bad-parent'), 'broken-revision'))
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
474
475
    def corrected_parents(self):
2592.3.214 by Robert Collins
Merge bzr.dev.
476
        return (
477
            ((), 'bad-parent'),
478
            (('bad-parent',), 'good-parent'),
479
            (('good-parent',), 'broken-revision'))
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
480
2951.1.6 by Robert Collins
All check/reconcile tests passing now.
481
    def check_regexes(self, repo):
482
        if repo.supports_rich_root():
483
            # TREE_ROOT will be wrong; but we're not testing it. so just adjust
484
            # the expected count of errors.
485
            count = 3
486
        else:
487
            count = 1
2592.3.214 by Robert Collins
Merge bzr.dev.
488
        return (
2951.1.6 by Robert Collins
All check/reconcile tests passing now.
489
            '     %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.
490
            (r"      \* a-file-id version broken-revision has parents "
2592.3.214 by Robert Collins
Merge bzr.dev.
491
             r"\('good-parent', 'bad-parent'\) but "
492
             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.
493
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
494
    def populate_repository(self, repo):
495
        inv = self.make_one_file_inventory(
2592.3.214 by Robert Collins
Merge bzr.dev.
496
            repo, 'bad-parent', (), root_revision='bad-parent')
497
        self.add_revision(repo, 'bad-parent', inv, ())
498
        
499
        inv = self.make_one_file_inventory(
500
            repo, 'good-parent', ('bad-parent',))
501
        self.add_revision(repo, 'good-parent', inv, ('bad-parent',))
502
        
503
        inv = self.make_one_file_inventory(
504
            repo, 'broken-revision', ('good-parent', 'bad-parent'))
505
        self.add_revision(repo, 'broken-revision', inv, ('good-parent',))
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
506
507
2745.6.43 by Andrew Bennetts
Tidy imports, docstrings, comments and variable names.
508
class ClaimedFileParentDidNotModifyFileScenario(BrokenRepoScenario):
509
    """A scenario where the file parent is the same as the revision parent, but
510
    should not be because that revision did not modify the file.
511
512
    Specifically, the parent revision of 'current' is
513
    'modified-something-else', which does not modify 'a-file', but the
514
    'current' version of 'a-file' erroneously claims that
515
    'modified-something-else' is the parent file version.
516
    """
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
517
2927.2.14 by Andrew Bennetts
Tweaks suggested by review.
518
    def all_versions_after_reconcile(self):
2927.2.11 by Andrew Bennetts
Merge from bzr.dev.
519
        return ('basis', 'current')
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
520
521
    def populated_parents(self):
2592.3.214 by Robert Collins
Merge bzr.dev.
522
        return (
523
            ((), 'basis'),
524
            (('basis',), 'modified-something-else'),
525
            (('modified-something-else',), 'current'))
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
526
527
    def corrected_parents(self):
2592.3.214 by Robert Collins
Merge bzr.dev.
528
        return (
529
            ((), 'basis'),
2927.2.8 by Andrew Bennetts
Remove totally unreferenced file versions. All reconcile tests passing.
530
            (None, 'modified-something-else'),
2592.3.214 by Robert Collins
Merge bzr.dev.
531
            (('basis',), 'current'))
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
532
2951.1.6 by Robert Collins
All check/reconcile tests passing now.
533
    def check_regexes(self, repo):
534
        if repo.supports_rich_root():
535
            # TREE_ROOT will be wrong; but we're not testing it. so just adjust
536
            # the expected count of errors.
537
            count = 4
538
        else:
539
            count = 2
2592.3.214 by Robert Collins
Merge bzr.dev.
540
        return (
2951.1.6 by Robert Collins
All check/reconcile tests passing now.
541
            "%d inconsistent parents" % count,
2745.6.41 by Andrew Bennetts
Test repo.check against all_scenarios.
542
            r"\* a-file-id version current has parents "
2927.2.11 by Andrew Bennetts
Merge from bzr.dev.
543
            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.
544
            r"\* a-file-id version modified-something-else has parents "
2927.2.11 by Andrew Bennetts
Merge from bzr.dev.
545
            r"\('basis',\) but should have \(\)",
546
            )
2745.6.41 by Andrew Bennetts
Test repo.check against all_scenarios.
547
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
548
    def populate_repository(self, repo):
2592.3.214 by Robert Collins
Merge bzr.dev.
549
        inv = self.make_one_file_inventory(repo, 'basis', ())
550
        self.add_revision(repo, 'basis', inv, ())
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
551
2745.6.43 by Andrew Bennetts
Tidy imports, docstrings, comments and variable names.
552
        # 'modified-something-else' is a correctly recorded revision, but it
553
        # does not modify the file we are looking at, so the inventory for that
554
        # file in this revision points to 'basis'.
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
555
        inv = self.make_one_file_inventory(
2592.3.214 by Robert Collins
Merge bzr.dev.
556
            repo, 'modified-something-else', ('basis',), inv_revision='basis')
557
        self.add_revision(repo, 'modified-something-else', inv, ('basis',))
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
558
2745.6.43 by Andrew Bennetts
Tidy imports, docstrings, comments and variable names.
559
        # The 'current' revision has 'modified-something-else' as its parent,
560
        # but the 'current' version of 'a-file' should have 'basis' as its
561
        # parent.
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
562
        inv = self.make_one_file_inventory(
2592.3.214 by Robert Collins
Merge bzr.dev.
563
            repo, 'current', ('modified-something-else',))
564
        self.add_revision(repo, 'current', inv, ('modified-something-else',))
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
565
566
2745.6.43 by Andrew Bennetts
Tidy imports, docstrings, comments and variable names.
567
class IncorrectlyOrderedParentsScenario(BrokenRepoScenario):
568
    """A scenario where the set parents of a version of a file are correct, but
569
    the order of those parents is incorrect.
570
571
    This defines a 'broken-revision-1-2' and a 'broken-revision-2-1' which both
572
    have their file version parents reversed compared to the revision parents,
573
    which is invalid.  (We use two revisions with opposite orderings of the
574
    same parents to make sure that accidentally relying on dictionary/set
575
    ordering cannot make the test pass; the assumption is that while dict/set
576
    iteration order is arbitrary, it is also consistent within a single test).
577
    """
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
578
2927.2.14 by Andrew Bennetts
Tweaks suggested by review.
579
    def all_versions_after_reconcile(self):
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
580
        return ['parent-1', 'parent-2', 'broken-revision-1-2',
581
                'broken-revision-2-1']
582
583
    def populated_parents(self):
2592.3.214 by Robert Collins
Merge bzr.dev.
584
        return (
585
            ((), 'parent-1'),
586
            ((), 'parent-2'),
587
            (('parent-2', 'parent-1'), 'broken-revision-1-2'),
588
            (('parent-1', 'parent-2'), 'broken-revision-2-1'))
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
589
590
    def corrected_parents(self):
2592.3.214 by Robert Collins
Merge bzr.dev.
591
        return (
592
            ((), 'parent-1'),
593
            ((), 'parent-2'),
594
            (('parent-1', 'parent-2'), 'broken-revision-1-2'),
595
            (('parent-2', 'parent-1'), 'broken-revision-2-1'))
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
596
2951.1.6 by Robert Collins
All check/reconcile tests passing now.
597
    def check_regexes(self, repo):
598
        if repo.supports_rich_root():
599
            # TREE_ROOT will be wrong; but we're not testing it. so just adjust
600
            # the expected count of errors.
601
            count = 4
602
        else:
603
            count = 2
2592.3.214 by Robert Collins
Merge bzr.dev.
604
        return (
2951.1.6 by Robert Collins
All check/reconcile tests passing now.
605
            "%d inconsistent parents" % count,
2745.6.41 by Andrew Bennetts
Test repo.check against all_scenarios.
606
            r"\* a-file-id version broken-revision-1-2 has parents "
2592.3.214 by Robert Collins
Merge bzr.dev.
607
            r"\('parent-2', 'parent-1'\) but should have "
608
            r"\('parent-1', 'parent-2'\)",
2745.6.41 by Andrew Bennetts
Test repo.check against all_scenarios.
609
            r"\* a-file-id version broken-revision-2-1 has parents "
2592.3.214 by Robert Collins
Merge bzr.dev.
610
            r"\('parent-1', 'parent-2'\) but should have "
611
            r"\('parent-2', 'parent-1'\)")
2745.6.41 by Andrew Bennetts
Test repo.check against all_scenarios.
612
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
613
    def populate_repository(self, repo):
614
        inv = self.make_one_file_inventory(repo, 'parent-1', [])
615
        self.add_revision(repo, 'parent-1', inv, [])
616
617
        inv = self.make_one_file_inventory(repo, 'parent-2', [])
618
        self.add_revision(repo, 'parent-2', inv, [])
619
620
        inv = self.make_one_file_inventory(
621
            repo, 'broken-revision-1-2', ['parent-2', 'parent-1'])
622
        self.add_revision(
623
            repo, 'broken-revision-1-2', inv, ['parent-1', 'parent-2'])
624
625
        inv = self.make_one_file_inventory(
626
            repo, 'broken-revision-2-1', ['parent-1', 'parent-2'])
627
        self.add_revision(
628
            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.
629
2485.7.1 by Robert Collins
Relocate TestCaseWithRepository to be more central.
630
2745.6.58 by Andrew Bennetts
Slightly neater test parameterisation in repository_implementations; extract a 'multiply_scenarios' function.
631
all_broken_scenario_classes = [
2745.6.54 by Andrew Bennetts
Tidy test parameterisation in repository_implementations.
632
    UndamagedRepositoryScenario,
633
    FileParentIsNotInRevisionAncestryScenario,
634
    FileParentHasInaccessibleInventoryScenario,
635
    FileParentsNotReferencedByAnyInventoryScenario,
636
    TooManyParentsScenario,
637
    ClaimedFileParentDidNotModifyFileScenario,
638
    IncorrectlyOrderedParentsScenario,
2927.2.3 by Andrew Bennetts
Add fulltexts to avoid bug 155730.
639
    UnreferencedFileParentsFromNoOpMergeScenario,
2745.6.54 by Andrew Bennetts
Tidy test parameterisation in repository_implementations.
640
    ]
641
    
2745.6.42 by Andrew Bennetts
Use TestScenarioApplier to more cleanly parameterise check and reconcile tests.
642
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
643
def test_suite():
2241.1.11 by Martin Pool
Get rid of RepositoryFormat*_instance objects. Instead the format
644
    registry = repository.format_registry
645
    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.
646
    all_formats.extend(weaverepo._legacy_formats)
2745.6.54 by Andrew Bennetts
Tidy test parameterisation in repository_implementations.
647
    disk_format_adapter = RepositoryTestProviderAdapter(
2018.5.30 by Robert Collins
Reenable the stock repository implementations for testing.
648
        default_transport,
649
        # None here will cause a readonly decorator to be created
650
        # by the TestCaseWithTransport.get_readonly_transport method.
651
        None,
2241.1.1 by Martin Pool
Change RepositoryFormat to use a Registry rather than ad-hoc dictionary
652
        [(format, format._matchingbzrdir) for format in all_formats])
2018.5.30 by Robert Collins
Reenable the stock repository implementations for testing.
653
2745.6.54 by Andrew Bennetts
Tidy test parameterisation in repository_implementations.
654
    remote_repo_adapter = RepositoryTestProviderAdapter(
2018.5.30 by Robert Collins
Reenable the stock repository implementations for testing.
655
        SmartTCPServer_for_testing,
656
        ReadonlySmartTCPServer_for_testing,
2018.5.66 by Wouter van Heyst
Fix repository test parameterization for RemoteRepository.
657
        [(RemoteRepositoryFormat(), RemoteBzrDirFormat())],
658
        MemoryServer
659
        )
2745.6.54 by Andrew Bennetts
Tidy test parameterisation in repository_implementations.
660
2745.6.58 by Andrew Bennetts
Slightly neater test parameterisation in repository_implementations; extract a 'multiply_scenarios' function.
661
    # format_scenarios is all the implementations of Repository; i.e. all disk
662
    # formats plus RemoteRepository.
663
    format_scenarios = (disk_format_adapter.scenarios +
664
                        remote_repo_adapter.scenarios)
2745.6.54 by Andrew Bennetts
Tidy test parameterisation in repository_implementations.
665
666
    prefix = 'bzrlib.tests.repository_implementations.'
2745.6.58 by Andrew Bennetts
Slightly neater test parameterisation in repository_implementations; extract a 'multiply_scenarios' function.
667
    test_repository_modules = [
2745.6.57 by Andrew Bennetts
Some improvements suggested by Martin's review.
668
        'test_break_lock',
669
        'test_check',
2745.6.58 by Andrew Bennetts
Slightly neater test parameterisation in repository_implementations; extract a 'multiply_scenarios' function.
670
        # test_check_reconcile is intentionally omitted, see below.
2745.6.57 by Andrew Bennetts
Some improvements suggested by Martin's review.
671
        'test_commit_builder',
672
        'test_fetch',
673
        'test_fileid_involved',
674
        'test_has_same_location',
2904.1.2 by Robert Collins
Merge bzr.dev
675
        'test_is_write_locked',
2745.6.57 by Andrew Bennetts
Some improvements suggested by Martin's review.
676
        'test_iter_reverse_revision_history',
677
        'test_pack',
678
        'test_reconcile',
679
        'test_repository',
680
        'test_revision',
681
        'test_statistics',
682
        'test_write_group',
2745.6.54 by Andrew Bennetts
Tidy test parameterisation in repository_implementations.
683
        ]
2745.6.58 by Andrew Bennetts
Slightly neater test parameterisation in repository_implementations; extract a 'multiply_scenarios' function.
684
    module_name_list = [prefix + module_name
685
                        for module_name in test_repository_modules]
686
687
    # Parameterise repository_implementations test modules by format.
688
    result = multiply_tests_from_modules(module_name_list, format_scenarios)
689
690
    # test_check_reconcile needs to be parameterised by format *and* by broken
691
    # repository scenario.
692
    broken_scenarios = [(s.__name__, {'scenario_class': s})
693
                        for s in all_broken_scenario_classes]
694
    broken_scenarios_for_all_formats = multiply_scenarios(
695
        format_scenarios, broken_scenarios)
696
    broken_scenario_applier = TestScenarioApplier()
697
    broken_scenario_applier.scenarios = broken_scenarios_for_all_formats
2745.6.54 by Andrew Bennetts
Tidy test parameterisation in repository_implementations.
698
    loader = TestLoader()
2745.6.57 by Andrew Bennetts
Some improvements suggested by Martin's review.
699
    adapt_modules(
700
        [prefix + 'test_check_reconcile'],
701
        broken_scenario_applier, loader, result)
2745.6.54 by Andrew Bennetts
Tidy test parameterisation in repository_implementations.
702
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
703
    return result