/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.
111
        :all_versions: all the versions in repository.  run_test verifies
112
            that the text of each of these versions of the file is unchanged
113
            by the 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.
122
    """
123
124
    def __init__(self, test_case):
125
        self.test_case = test_case
126
127
    def make_one_file_inventory(self, repo, revision, parents,
128
                                inv_revision=None, root_revision=None):
129
        return self.test_case.make_one_file_inventory(
130
            repo, revision, parents, inv_revision=inv_revision,
131
            root_revision=root_revision)
132
133
    def add_revision(self, repo, revision_id, inv, parent_ids):
134
        return self.test_case.add_revision(repo, revision_id, inv, parent_ids)
135
136
2745.6.50 by Andrew Bennetts
Remove find_bad_ancestors; it's not needed anymore.
137
class UndamagedRepositoryScenario(BrokenRepoScenario):
138
    """A scenario where the repository has no damage.
139
140
    It has a single revision, 'rev1a', with a single file.
141
    """
142
143
    def all_versions(self):
2592.3.214 by Robert Collins
Merge bzr.dev.
144
        return ('rev1a', )
2745.6.50 by Andrew Bennetts
Remove find_bad_ancestors; it's not needed anymore.
145
146
    def populated_parents(self):
2592.3.214 by Robert Collins
Merge bzr.dev.
147
        return (((), 'rev1a'), )
2745.6.50 by Andrew Bennetts
Remove find_bad_ancestors; it's not needed anymore.
148
149
    def corrected_parents(self):
150
        # Same as the populated parents, because there was nothing wrong.
151
        return self.populated_parents()
152
153
    def check_regexes(self):
154
        return ["0 unreferenced text ancestors"]
155
156
    def populate_repository(self, repo):
157
        # make rev1a: A well-formed revision, containing 'a-file'
158
        inv = self.make_one_file_inventory(
159
            repo, 'rev1a', [], root_revision='rev1a')
160
        self.add_revision(repo, 'rev1a', inv, [])
161
162
2745.6.43 by Andrew Bennetts
Tidy imports, docstrings, comments and variable names.
163
class FileParentIsNotInRevisionAncestryScenario(BrokenRepoScenario):
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
164
    """A scenario where a revision 'rev2' has 'a-file' with a
165
    parent 'rev1b' that is not in the revision ancestry.
166
    
167
    Reconcile should remove 'rev1b' from the parents list of 'a-file' in
168
    'rev2', preserving 'rev1a' as a parent.
169
    """
170
171
    def all_versions(self):
2592.3.214 by Robert Collins
Merge bzr.dev.
172
        return ('rev1a', 'rev1b', 'rev2')
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
173
174
    def populated_parents(self):
2592.3.214 by Robert Collins
Merge bzr.dev.
175
        return (
176
            ((), 'rev1a'),
177
            ((), 'rev1b'),
178
            (('rev1a', 'rev1b'), 'rev2'))
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
179
180
    def corrected_parents(self):
2592.3.214 by Robert Collins
Merge bzr.dev.
181
        return (
182
            ((), 'rev1a'),
183
            ((), 'rev1b'),
184
            (('rev1a',), 'rev2'))
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
185
2745.6.41 by Andrew Bennetts
Test repo.check against all_scenarios.
186
    def check_regexes(self):
2592.3.214 by Robert Collins
Merge bzr.dev.
187
        return [r"\* a-file-id version rev2 has parents \('rev1a', 'rev1b'\) "
188
                r"but should have \('rev1a',\)",
2745.6.50 by Andrew Bennetts
Remove find_bad_ancestors; it's not needed anymore.
189
                "1 unreferenced text ancestors",
190
                ]
2745.6.41 by Andrew Bennetts
Test repo.check against all_scenarios.
191
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
192
    def populate_repository(self, repo):
193
        # make rev1a: A well-formed revision, containing 'a-file'
194
        inv = self.make_one_file_inventory(
195
            repo, 'rev1a', [], root_revision='rev1a')
196
        self.add_revision(repo, 'rev1a', inv, [])
197
198
        # make rev1b, which has no Revision, but has an Inventory, and
199
        # a-file
200
        inv = self.make_one_file_inventory(
201
            repo, 'rev1b', [], root_revision='rev1b')
202
        repo.add_inventory('rev1b', inv, [])
203
204
        # make rev2, with a-file.
205
        # a-file has 'rev1b' as an ancestor, even though this is not
206
        # mentioned by 'rev1a', making it an unreferenced ancestor
207
        inv = self.make_one_file_inventory(
208
            repo, 'rev2', ['rev1a', 'rev1b'])
209
        self.add_revision(repo, 'rev2', inv, ['rev1a'])
210
211
2745.6.43 by Andrew Bennetts
Tidy imports, docstrings, comments and variable names.
212
class FileParentHasInaccessibleInventoryScenario(BrokenRepoScenario):
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
213
    """A scenario where a revision 'rev3' containing 'a-file' modified in
214
    'rev3', and with a parent which is in the revision ancestory, but whose
215
    inventory cannot be accessed at all.
216
217
    Reconcile should remove the file version parent whose inventory is
218
    inaccessbile (i.e. remove 'rev1c' from the parents of a-file's rev3).
219
    """
220
221
    def all_versions(self):
2592.3.214 by Robert Collins
Merge bzr.dev.
222
        return ('rev2', 'rev3')
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
223
224
    def populated_parents(self):
2592.3.214 by Robert Collins
Merge bzr.dev.
225
        return (
226
            ((), 'rev2'),
227
            (('rev1c',), 'rev3'))
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
228
229
    def corrected_parents(self):
2592.3.214 by Robert Collins
Merge bzr.dev.
230
        return (
231
            ((), 'rev2'),
232
            ((), 'rev3'))
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
233
2745.6.41 by Andrew Bennetts
Test repo.check against all_scenarios.
234
    def check_regexes(self):
2745.6.43 by Andrew Bennetts
Tidy imports, docstrings, comments and variable names.
235
        return [r"\* a-file-id version rev3 has parents "
2592.3.214 by Robert Collins
Merge bzr.dev.
236
                r"\('rev1c',\) but should have \(\)",
2745.6.50 by Andrew Bennetts
Remove find_bad_ancestors; it's not needed anymore.
237
                # Also check reporting of unreferenced ancestors
238
                r"unreferenced ancestor: {rev1c} in a-file-id",
239
                ]
2745.6.41 by Andrew Bennetts
Test repo.check against all_scenarios.
240
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
241
    def populate_repository(self, repo):
242
        # make rev2, with a-file
243
        # a-file is sane
244
        inv = self.make_one_file_inventory(repo, 'rev2', [])
245
        self.add_revision(repo, 'rev2', inv, [])
246
247
        # make ghost revision rev1c, with a version of a-file present so
248
        # that we generate a knit delta against this version.  In real life
249
        # the ghost might never have been present or rev3 might have been
250
        # generated against a revision that was present at the time.  So
251
        # currently we have the full history of a-file present even though
252
        # the inventory and revision objects are not.
253
        self.make_one_file_inventory(repo, 'rev1c', [])
254
255
        # make rev3 with a-file
256
        # a-file refers to 'rev1c', which is a ghost in this repository, so
257
        # a-file cannot have rev1c as its ancestor.
258
        inv = self.make_one_file_inventory(repo, 'rev3', ['rev1c'])
259
        self.add_revision(repo, 'rev3', inv, ['rev1c', 'rev1a'])
260
261
2745.6.43 by Andrew Bennetts
Tidy imports, docstrings, comments and variable names.
262
class FileParentsNotReferencedByAnyInventoryScenario(BrokenRepoScenario):
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
263
    """A scenario where a repository with file 'a-file' which has extra
264
    per-file versions that are not referenced by any inventory (even though
265
    they have the same ID as actual revisions).  The inventory of 'rev2'
266
    references 'rev1a' of 'a-file', but there is a 'rev2' of 'some-file' stored
267
    and erroneously referenced by later per-file versions (revisions 'rev4' and
268
    'rev5').
269
270
    Reconcile should remove the file parents that are not referenced by any
271
    inventory.
272
    """
273
274
    def all_versions(self):
2592.3.214 by Robert Collins
Merge bzr.dev.
275
        return ('rev1a', 'rev2', 'rev4', 'rev2b', 'rev4', 'rev2c', 'rev5')
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
276
277
    def populated_parents(self):
2592.3.214 by Robert Collins
Merge bzr.dev.
278
        return (
279
            (('rev2',), 'rev3'),
280
            (('rev2',), 'rev4'),
281
            (('rev2', 'rev2c'), 'rev5'))
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
282
283
    def corrected_parents(self):
2592.3.214 by Robert Collins
Merge bzr.dev.
284
        return (
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
285
            # rev3's accessible parent inventories all have rev1a as the last
286
            # modifier.
2592.3.214 by Robert Collins
Merge bzr.dev.
287
            (('rev1a',), 'rev3'),
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
288
            # rev1a features in both rev4's parents but should only appear once
289
            # in the result
2592.3.214 by Robert Collins
Merge bzr.dev.
290
            (('rev1a',), 'rev4'),
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
291
            # rev2c is the head of rev1a and rev2c, the inventory provided
292
            # per-file last-modified revisions.
2592.3.214 by Robert Collins
Merge bzr.dev.
293
            (('rev2c',), 'rev5'))
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
294
2745.6.41 by Andrew Bennetts
Test repo.check against all_scenarios.
295
    def check_regexes(self):
296
        return [
297
            "3 inconsistent parents",
2592.3.214 by Robert Collins
Merge bzr.dev.
298
            r"a-file-id version rev3 has parents \('rev2',\) "
299
            r"but should have \('rev1a',\)",
300
            r"a-file-id version rev5 has parents \('rev2', 'rev2c'\) "
301
            r"but should have \('rev2c',\)",
302
            r"a-file-id version rev4 has parents \('rev2',\) "
303
            r"but should have \('rev1a',\)",
2745.6.41 by Andrew Bennetts
Test repo.check against all_scenarios.
304
            ]
305
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
306
    def populate_repository(self, repo):
307
        # make rev1a: A well-formed revision, containing 'a-file'
308
        inv = self.make_one_file_inventory(
309
            repo, 'rev1a', [], root_revision='rev1a')
310
        self.add_revision(repo, 'rev1a', inv, [])
311
312
        # make rev2, with a-file.
313
        # a-file is unmodified from rev1a.
314
        self.make_one_file_inventory(
315
            repo, 'rev2', ['rev1a'], inv_revision='rev1a')
316
        self.add_revision(repo, 'rev2', inv, ['rev1a'])
317
318
        # make rev3 with a-file
319
        # a-file has 'rev2' as its ancestor, but the revision in 'rev2' was
320
        # rev1a so this is inconsistent with rev2's inventory - it should
321
        # be rev1a, and at the revision level 1c is not present - it is a
322
        # ghost, so only the details from rev1a are available for
323
        # determining whether a delta is acceptable, or a full is needed,
2745.6.43 by Andrew Bennetts
Tidy imports, docstrings, comments and variable names.
324
        # and what the correct parents are.
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
325
        inv = self.make_one_file_inventory(repo, 'rev3', ['rev2'])
2745.6.43 by Andrew Bennetts
Tidy imports, docstrings, comments and variable names.
326
        self.add_revision(repo, 'rev3', inv, ['rev1c', 'rev1a'])
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
327
328
        # In rev2b, the true last-modifying-revision of a-file is rev1a,
329
        # inherited from rev2, but there is a version rev2b of the file, which
330
        # reconcile could remove, leaving no rev2b.  Most importantly,
331
        # revisions descending from rev2b should not have per-file parents of
332
        # a-file-rev2b.
333
        # ??? This is to test deduplication in fixing rev4
334
        inv = self.make_one_file_inventory(
335
            repo, 'rev2b', ['rev1a'], inv_revision='rev1a')
336
        self.add_revision(repo, 'rev2b', inv, ['rev1a'])
337
338
        # rev4 is for testing that when the last modified of a file in
339
        # multiple parent revisions is the same, that it only appears once
340
        # in the generated per file parents list: rev2 and rev2b both
341
        # descend from 1a and do not change the file a-file, so there should
342
        # be no version of a-file 'rev2' or 'rev2b', but rev4 does change
343
        # a-file, and is a merge of rev2 and rev2b, so it should end up with
344
        # a parent of just rev1a - the starting file parents list is simply
345
        # completely wrong.
346
        inv = self.make_one_file_inventory(repo, 'rev4', ['rev2'])
347
        self.add_revision(repo, 'rev4', inv, ['rev2', 'rev2b'])
348
349
        # rev2c changes a-file from rev1a, so the version it of a-file it
350
        # introduces is a head revision when rev5 is checked.
351
        inv = self.make_one_file_inventory(repo, 'rev2c', ['rev1a'])
352
        self.add_revision(repo, 'rev2c', inv, ['rev1a'])
353
354
        # rev5 descends from rev2 and rev2c; as rev2 does not alter a-file,
355
        # but rev2c does, this should use rev2c as the parent for the per
356
        # file history, even though more than one per-file parent is
357
        # available, because we use the heads of the revision parents for
358
        # the inventory modification revisions of the file to determine the
359
        # parents for the per file graph.
360
        inv = self.make_one_file_inventory(repo, 'rev5', ['rev2', 'rev2c'])
361
        self.add_revision(repo, 'rev5', inv, ['rev2', 'rev2c'])
362
363
2745.6.43 by Andrew Bennetts
Tidy imports, docstrings, comments and variable names.
364
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.
365
    """A scenario where 'broken-revision' of 'a-file' claims to have parents
366
    ['good-parent', 'bad-parent'].  However 'bad-parent' is in the ancestry of
367
    'good-parent', so the correct parent list for that file version are is just
368
    ['good-parent'].
369
    """
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
370
371
    def all_versions(self):
2592.3.214 by Robert Collins
Merge bzr.dev.
372
        return ('bad-parent', 'good-parent', 'broken-revision')
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
373
374
    def populated_parents(self):
2592.3.214 by Robert Collins
Merge bzr.dev.
375
        return (
376
            ((), 'bad-parent'),
377
            (('bad-parent',), 'good-parent'),
378
            (('good-parent', 'bad-parent'), 'broken-revision'))
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
379
380
    def corrected_parents(self):
2592.3.214 by Robert Collins
Merge bzr.dev.
381
        return (
382
            ((), 'bad-parent'),
383
            (('bad-parent',), 'good-parent'),
384
            (('good-parent',), 'broken-revision'))
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
385
2745.6.39 by Andrew Bennetts
Use scenario in test_check too, and make check actually report inconsistent parents to the end user.
386
    def check_regexes(self):
2592.3.214 by Robert Collins
Merge bzr.dev.
387
        return (
2745.6.39 by Andrew Bennetts
Use scenario in test_check too, and make check actually report inconsistent parents to the end user.
388
            '     1 inconsistent parents',
389
            (r"      \* a-file-id version broken-revision has parents "
2592.3.214 by Robert Collins
Merge bzr.dev.
390
             r"\('good-parent', 'bad-parent'\) but "
391
             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.
392
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
393
    def populate_repository(self, repo):
394
        inv = self.make_one_file_inventory(
2592.3.214 by Robert Collins
Merge bzr.dev.
395
            repo, 'bad-parent', (), root_revision='bad-parent')
396
        self.add_revision(repo, 'bad-parent', inv, ())
397
        
398
        inv = self.make_one_file_inventory(
399
            repo, 'good-parent', ('bad-parent',))
400
        self.add_revision(repo, 'good-parent', inv, ('bad-parent',))
401
        
402
        inv = self.make_one_file_inventory(
403
            repo, 'broken-revision', ('good-parent', 'bad-parent'))
404
        self.add_revision(repo, 'broken-revision', inv, ('good-parent',))
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
405
406
2745.6.43 by Andrew Bennetts
Tidy imports, docstrings, comments and variable names.
407
class ClaimedFileParentDidNotModifyFileScenario(BrokenRepoScenario):
408
    """A scenario where the file parent is the same as the revision parent, but
409
    should not be because that revision did not modify the file.
410
411
    Specifically, the parent revision of 'current' is
412
    'modified-something-else', which does not modify 'a-file', but the
413
    'current' version of 'a-file' erroneously claims that
414
    'modified-something-else' is the parent file version.
415
    """
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
416
417
    def all_versions(self):
2592.3.214 by Robert Collins
Merge bzr.dev.
418
        return ('basis', 'modified-something-else', 'current')
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
419
420
    def populated_parents(self):
2592.3.214 by Robert Collins
Merge bzr.dev.
421
        return (
422
            ((), 'basis'),
423
            (('basis',), 'modified-something-else'),
424
            (('modified-something-else',), 'current'))
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
425
426
    def corrected_parents(self):
2592.3.214 by Robert Collins
Merge bzr.dev.
427
        return (
428
            ((), 'basis'),
429
            (('basis',), 'modified-something-else'),
430
            (('basis',), 'current'))
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
431
2745.6.41 by Andrew Bennetts
Test repo.check against all_scenarios.
432
    def check_regexes(self):
2592.3.214 by Robert Collins
Merge bzr.dev.
433
        return (
2745.6.41 by Andrew Bennetts
Test repo.check against all_scenarios.
434
            '1 inconsistent parents',
435
            r"\* a-file-id version current has parents "
2592.3.214 by Robert Collins
Merge bzr.dev.
436
            r"\('modified-something-else',\) but should have \('basis',\)")
2745.6.41 by Andrew Bennetts
Test repo.check against all_scenarios.
437
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
438
    def populate_repository(self, repo):
2592.3.214 by Robert Collins
Merge bzr.dev.
439
        inv = self.make_one_file_inventory(repo, 'basis', ())
440
        self.add_revision(repo, 'basis', inv, ())
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
441
2745.6.43 by Andrew Bennetts
Tidy imports, docstrings, comments and variable names.
442
        # 'modified-something-else' is a correctly recorded revision, but it
443
        # does not modify the file we are looking at, so the inventory for that
444
        # file in this revision points to 'basis'.
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
445
        inv = self.make_one_file_inventory(
2592.3.214 by Robert Collins
Merge bzr.dev.
446
            repo, 'modified-something-else', ('basis',), inv_revision='basis')
447
        self.add_revision(repo, 'modified-something-else', inv, ('basis',))
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
448
2745.6.43 by Andrew Bennetts
Tidy imports, docstrings, comments and variable names.
449
        # The 'current' revision has 'modified-something-else' as its parent,
450
        # but the 'current' version of 'a-file' should have 'basis' as its
451
        # parent.
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
452
        inv = self.make_one_file_inventory(
2592.3.214 by Robert Collins
Merge bzr.dev.
453
            repo, 'current', ('modified-something-else',))
454
        self.add_revision(repo, 'current', inv, ('modified-something-else',))
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
455
456
2745.6.43 by Andrew Bennetts
Tidy imports, docstrings, comments and variable names.
457
class IncorrectlyOrderedParentsScenario(BrokenRepoScenario):
458
    """A scenario where the set parents of a version of a file are correct, but
459
    the order of those parents is incorrect.
460
461
    This defines a 'broken-revision-1-2' and a 'broken-revision-2-1' which both
462
    have their file version parents reversed compared to the revision parents,
463
    which is invalid.  (We use two revisions with opposite orderings of the
464
    same parents to make sure that accidentally relying on dictionary/set
465
    ordering cannot make the test pass; the assumption is that while dict/set
466
    iteration order is arbitrary, it is also consistent within a single test).
467
    """
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
468
469
    def all_versions(self):
470
        return ['parent-1', 'parent-2', 'broken-revision-1-2',
471
                'broken-revision-2-1']
472
473
    def populated_parents(self):
2592.3.214 by Robert Collins
Merge bzr.dev.
474
        return (
475
            ((), 'parent-1'),
476
            ((), 'parent-2'),
477
            (('parent-2', 'parent-1'), 'broken-revision-1-2'),
478
            (('parent-1', 'parent-2'), 'broken-revision-2-1'))
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
479
480
    def corrected_parents(self):
2592.3.214 by Robert Collins
Merge bzr.dev.
481
        return (
482
            ((), 'parent-1'),
483
            ((), 'parent-2'),
484
            (('parent-1', 'parent-2'), 'broken-revision-1-2'),
485
            (('parent-2', 'parent-1'), 'broken-revision-2-1'))
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
486
2745.6.41 by Andrew Bennetts
Test repo.check against all_scenarios.
487
    def check_regexes(self):
2592.3.214 by Robert Collins
Merge bzr.dev.
488
        return (
2745.6.41 by Andrew Bennetts
Test repo.check against all_scenarios.
489
            "2 inconsistent parents",
490
            r"\* a-file-id version broken-revision-1-2 has parents "
2592.3.214 by Robert Collins
Merge bzr.dev.
491
            r"\('parent-2', 'parent-1'\) but should have "
492
            r"\('parent-1', 'parent-2'\)",
2745.6.41 by Andrew Bennetts
Test repo.check against all_scenarios.
493
            r"\* a-file-id version broken-revision-2-1 has parents "
2592.3.214 by Robert Collins
Merge bzr.dev.
494
            r"\('parent-1', 'parent-2'\) but should have "
495
            r"\('parent-2', 'parent-1'\)")
2745.6.41 by Andrew Bennetts
Test repo.check against all_scenarios.
496
2745.6.38 by Andrew Bennetts
Create explicit scenario objects for test_reconcile.
497
    def populate_repository(self, repo):
498
        inv = self.make_one_file_inventory(repo, 'parent-1', [])
499
        self.add_revision(repo, 'parent-1', inv, [])
500
501
        inv = self.make_one_file_inventory(repo, 'parent-2', [])
502
        self.add_revision(repo, 'parent-2', inv, [])
503
504
        inv = self.make_one_file_inventory(
505
            repo, 'broken-revision-1-2', ['parent-2', 'parent-1'])
506
        self.add_revision(
507
            repo, 'broken-revision-1-2', inv, ['parent-1', 'parent-2'])
508
509
        inv = self.make_one_file_inventory(
510
            repo, 'broken-revision-2-1', ['parent-1', 'parent-2'])
511
        self.add_revision(
512
            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.
513
2485.7.1 by Robert Collins
Relocate TestCaseWithRepository to be more central.
514
2745.6.58 by Andrew Bennetts
Slightly neater test parameterisation in repository_implementations; extract a 'multiply_scenarios' function.
515
all_broken_scenario_classes = [
2745.6.54 by Andrew Bennetts
Tidy test parameterisation in repository_implementations.
516
    UndamagedRepositoryScenario,
517
    FileParentIsNotInRevisionAncestryScenario,
518
    FileParentHasInaccessibleInventoryScenario,
519
    FileParentsNotReferencedByAnyInventoryScenario,
520
    TooManyParentsScenario,
521
    ClaimedFileParentDidNotModifyFileScenario,
522
    IncorrectlyOrderedParentsScenario,
523
    ]
524
    
2745.6.42 by Andrew Bennetts
Use TestScenarioApplier to more cleanly parameterise check and reconcile tests.
525
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
526
def test_suite():
2241.1.11 by Martin Pool
Get rid of RepositoryFormat*_instance objects. Instead the format
527
    registry = repository.format_registry
528
    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.
529
    all_formats.extend(weaverepo._legacy_formats)
2745.6.54 by Andrew Bennetts
Tidy test parameterisation in repository_implementations.
530
    disk_format_adapter = RepositoryTestProviderAdapter(
2018.5.30 by Robert Collins
Reenable the stock repository implementations for testing.
531
        default_transport,
532
        # None here will cause a readonly decorator to be created
533
        # by the TestCaseWithTransport.get_readonly_transport method.
534
        None,
2241.1.1 by Martin Pool
Change RepositoryFormat to use a Registry rather than ad-hoc dictionary
535
        [(format, format._matchingbzrdir) for format in all_formats])
2018.5.30 by Robert Collins
Reenable the stock repository implementations for testing.
536
2745.6.54 by Andrew Bennetts
Tidy test parameterisation in repository_implementations.
537
    remote_repo_adapter = RepositoryTestProviderAdapter(
2018.5.30 by Robert Collins
Reenable the stock repository implementations for testing.
538
        SmartTCPServer_for_testing,
539
        ReadonlySmartTCPServer_for_testing,
2018.5.66 by Wouter van Heyst
Fix repository test parameterization for RemoteRepository.
540
        [(RemoteRepositoryFormat(), RemoteBzrDirFormat())],
541
        MemoryServer
542
        )
2745.6.54 by Andrew Bennetts
Tidy test parameterisation in repository_implementations.
543
2745.6.58 by Andrew Bennetts
Slightly neater test parameterisation in repository_implementations; extract a 'multiply_scenarios' function.
544
    # format_scenarios is all the implementations of Repository; i.e. all disk
545
    # formats plus RemoteRepository.
546
    format_scenarios = (disk_format_adapter.scenarios +
547
                        remote_repo_adapter.scenarios)
2745.6.54 by Andrew Bennetts
Tidy test parameterisation in repository_implementations.
548
549
    prefix = 'bzrlib.tests.repository_implementations.'
2745.6.58 by Andrew Bennetts
Slightly neater test parameterisation in repository_implementations; extract a 'multiply_scenarios' function.
550
    test_repository_modules = [
2745.6.57 by Andrew Bennetts
Some improvements suggested by Martin's review.
551
        'test_break_lock',
552
        'test_check',
2745.6.58 by Andrew Bennetts
Slightly neater test parameterisation in repository_implementations; extract a 'multiply_scenarios' function.
553
        # test_check_reconcile is intentionally omitted, see below.
2745.6.57 by Andrew Bennetts
Some improvements suggested by Martin's review.
554
        'test_commit_builder',
555
        'test_fetch',
556
        'test_fileid_involved',
557
        'test_has_same_location',
2904.1.2 by Robert Collins
Merge bzr.dev
558
        'test_is_write_locked',
2745.6.57 by Andrew Bennetts
Some improvements suggested by Martin's review.
559
        'test_iter_reverse_revision_history',
560
        'test_pack',
561
        'test_reconcile',
562
        'test_repository',
563
        'test_revision',
564
        'test_statistics',
565
        'test_write_group',
2745.6.54 by Andrew Bennetts
Tidy test parameterisation in repository_implementations.
566
        ]
2745.6.58 by Andrew Bennetts
Slightly neater test parameterisation in repository_implementations; extract a 'multiply_scenarios' function.
567
    module_name_list = [prefix + module_name
568
                        for module_name in test_repository_modules]
569
570
    # Parameterise repository_implementations test modules by format.
571
    result = multiply_tests_from_modules(module_name_list, format_scenarios)
572
573
    # test_check_reconcile needs to be parameterised by format *and* by broken
574
    # repository scenario.
575
    broken_scenarios = [(s.__name__, {'scenario_class': s})
576
                        for s in all_broken_scenario_classes]
577
    broken_scenarios_for_all_formats = multiply_scenarios(
578
        format_scenarios, broken_scenarios)
579
    broken_scenario_applier = TestScenarioApplier()
580
    broken_scenario_applier.scenarios = broken_scenarios_for_all_formats
2745.6.54 by Andrew Bennetts
Tidy test parameterisation in repository_implementations.
581
    loader = TestLoader()
2745.6.57 by Andrew Bennetts
Some improvements suggested by Martin's review.
582
    adapt_modules(
583
        [prefix + 'test_check_reconcile'],
584
        broken_scenario_applier, loader, result)
2745.6.54 by Andrew Bennetts
Tidy test parameterisation in repository_implementations.
585
1534.4.40 by Robert Collins
Add RepositoryFormats and allow bzrdir.open or create _repository to be used.
586
    return result