~bzr-pqm/bzr/bzr.dev

4763.2.4 by John Arbash Meinel
merge bzr.2.1 in preparation for NEWS entry.
1
# Copyright (C) 2007-2010 Canonical Ltd
2745.6.7 by Aaron Bentley
Clean-up
2
#
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
2745.6.7 by Aaron Bentley
Clean-up
16
17
18
"""Test operations that check the repository for corruption"""
19
4657.1.1 by Robert Collins
Do not add the root directory entry to the list of expected keys during check in non rich-root repositories. (#416732)
20
import os
2745.6.7 by Aaron Bentley
Clean-up
21
2745.6.1 by Aaron Bentley
Initial checking of knit graphs
22
from bzrlib import (
4657.1.1 by Robert Collins
Do not add the root directory entry to the list of expected keys during check in non rich-root repositories. (#416732)
23
    check,
24
    config as _mod_config,
2745.6.48 by Andrew Bennetts
Merge find-inconsistent-parents.
25
    errors,
4657.1.1 by Robert Collins
Do not add the root directory entry to the list of expected keys during check in non rich-root repositories. (#416732)
26
    inventory,
2745.6.1 by Aaron Bentley
Initial checking of knit graphs
27
    revision as _mod_revision,
28
    )
2745.6.48 by Andrew Bennetts
Merge find-inconsistent-parents.
29
from bzrlib.tests import TestNotApplicable
3689.1.1 by John Arbash Meinel
Rename repository_implementations tests into per_repository tests
30
from bzrlib.tests.per_repository import TestCaseWithRepository
31
from bzrlib.tests.per_repository.helpers import (
2819.2.5 by Andrew Bennetts
Make reconcile abort gracefully if the revision index has bad parents.
32
    TestCaseWithBrokenRevisionIndex,
2819.2.1 by Andrew Bennetts
Implement KnitRepository._find_inconsistent_revision_parents.
33
    )
34
35
3036.1.1 by Robert Collins
* ``check`` no longer reports spurious unreferenced text versions.
36
class TestNoSpuriousInconsistentAncestors(TestCaseWithRepository):
37
38
    def test_two_files_different_versions_no_inconsistencies_bug_165071(self):
39
        """Two files, with different versions can be clean."""
40
        tree = self.make_branch_and_tree('.')
41
        self.build_tree(['foo'])
42
        tree.smart_add(['.'])
4332.3.11 by Robert Collins
Move tree and back callbacks into the repository check core.
43
        revid1 = tree.commit('1')
3036.1.1 by Robert Collins
* ``check`` no longer reports spurious unreferenced text versions.
44
        self.build_tree(['bar'])
45
        tree.smart_add(['.'])
4332.3.11 by Robert Collins
Move tree and back callbacks into the repository check core.
46
        revid2 = tree.commit('2')
47
        check_object = tree.branch.repository.check([revid1, revid2])
4245.1.1 by Ian Clatworthy
minor test clean-ups & _reconcile_pack API
48
        check_object.report_results(verbose=True)
4794.1.15 by Robert Collins
Review feedback.
49
        self.assertContainsRe(self.get_log(), "0 unreferenced text versions")
3036.1.1 by Robert Collins
* ``check`` no longer reports spurious unreferenced text versions.
50
51
2819.2.5 by Andrew Bennetts
Make reconcile abort gracefully if the revision index has bad parents.
52
class TestFindInconsistentRevisionParents(TestCaseWithBrokenRevisionIndex):
2819.2.1 by Andrew Bennetts
Implement KnitRepository._find_inconsistent_revision_parents.
53
2819.2.2 by Andrew Bennetts
Implement _check_for_inconsistent_revision_parents.
54
    def test__find_inconsistent_revision_parents(self):
55
        """_find_inconsistent_revision_parents finds revisions with broken
56
        parents.
57
        """
58
        repo = self.make_repo_with_extra_ghost_index()
2819.2.1 by Andrew Bennetts
Implement KnitRepository._find_inconsistent_revision_parents.
59
        self.assertEqual(
2592.3.214 by Robert Collins
Merge bzr.dev.
60
            [('revision-id', ('incorrect-parent',), ())],
2819.2.1 by Andrew Bennetts
Implement KnitRepository._find_inconsistent_revision_parents.
61
            list(repo._find_inconsistent_revision_parents()))
62
2819.2.2 by Andrew Bennetts
Implement _check_for_inconsistent_revision_parents.
63
    def test__check_for_inconsistent_revision_parents(self):
64
        """_check_for_inconsistent_revision_parents raises BzrCheckError if
65
        there are any revisions with inconsistent parents.
66
        """
67
        repo = self.make_repo_with_extra_ghost_index()
68
        self.assertRaises(
69
            errors.BzrCheckError,
70
            repo._check_for_inconsistent_revision_parents)
71
72
    def test__check_for_inconsistent_revision_parents_on_clean_repo(self):
73
        """_check_for_inconsistent_revision_parents does nothing if there are
74
        no broken revisions.
75
        """
76
        repo = self.make_repository('empty-repo')
2819.2.5 by Andrew Bennetts
Make reconcile abort gracefully if the revision index has bad parents.
77
        if not repo.revision_graph_can_have_wrong_parents():
78
            raise TestNotApplicable(
79
                '%r cannot have corrupt revision index.' % repo)
2592.3.214 by Robert Collins
Merge bzr.dev.
80
        repo.lock_read()
81
        try:
82
            repo._check_for_inconsistent_revision_parents()  # nothing happens
83
        finally:
84
            repo.unlock()
2819.2.2 by Andrew Bennetts
Implement _check_for_inconsistent_revision_parents.
85
2819.2.3 by Andrew Bennetts
Add test that repo.check will report on wrong parents in the revision graph.
86
    def test_check_reports_bad_ancestor(self):
87
        repo = self.make_repo_with_extra_ghost_index()
88
        # XXX: check requires a non-empty revision IDs list, but it ignores the
89
        # contents of it!
90
        check_object = repo.check(['ignored'])
91
        check_object.report_results(verbose=False)
4794.1.15 by Robert Collins
Review feedback.
92
        self.assertContainsRe(self.get_log(),
93
            '1 revisions have incorrect parents in the revision index')
2819.2.3 by Andrew Bennetts
Add test that repo.check will report on wrong parents in the revision graph.
94
        check_object.report_results(verbose=True)
95
        self.assertContainsRe(
4794.1.15 by Robert Collins
Review feedback.
96
            self.get_log(),
2819.2.3 by Andrew Bennetts
Add test that repo.check will report on wrong parents in the revision graph.
97
            "revision-id has wrong parents in index: "
2592.3.214 by Robert Collins
Merge bzr.dev.
98
            r"\('incorrect-parent',\) should be \(\)")
2819.2.3 by Andrew Bennetts
Add test that repo.check will report on wrong parents in the revision graph.
99
4332.3.11 by Robert Collins
Move tree and back callbacks into the repository check core.
100
101
class TestCallbacks(TestCaseWithRepository):
102
103
    def test_callback_tree_and_branch(self):
104
        # use a real tree to get actual refs that will work
105
        tree = self.make_branch_and_tree('foo')
106
        revid = tree.commit('foo')
107
        tree.lock_read()
108
        self.addCleanup(tree.unlock)
109
        needed_refs = {}
110
        for ref in tree._get_check_refs():
111
            needed_refs.setdefault(ref, []).append(tree)
112
        for ref in tree.branch._get_check_refs():
113
            needed_refs.setdefault(ref, []).append(tree.branch)
114
        self.tree_check = tree._check
115
        self.branch_check = tree.branch.check
116
        tree._check = self.tree_callback
117
        tree.branch.check = self.branch_callback
118
        self.callbacks = []
119
        tree.branch.repository.check([revid], callback_refs=needed_refs)
120
        self.assertNotEqual([], self.callbacks)
121
122
    def tree_callback(self, refs):
123
        self.callbacks.append(('tree', refs))
124
        return self.tree_check(refs)
125
126
    def branch_callback(self, refs):
127
        self.callbacks.append(('branch', refs))
128
        return self.branch_check(refs)
4657.1.1 by Robert Collins
Do not add the root directory entry to the list of expected keys during check in non rich-root repositories. (#416732)
129
130
131
class TestCleanRepository(TestCaseWithRepository):
132
133
    def test_new_repo(self):
134
        repo = self.make_repository('foo')
135
        repo.lock_write()
136
        self.addCleanup(repo.unlock)
137
        config = _mod_config.Config()
138
        os.environ['BZR_EMAIL'] = 'foo@sample.com'
139
        builder = repo.get_commit_builder(None, [], config)
140
        list(builder.record_iter_changes(None, _mod_revision.NULL_REVISION, [
141
            ('TREE_ROOT', (None, ''), True, (False, True), (None, None),
142
            (None, ''), (None, 'directory'), (None, False))]))
143
        builder.finish_inventory()
144
        rev_id = builder.commit('first post')
145
        result = repo.check(None, check_repo=True)
146
        result.report_results(True)
4794.1.15 by Robert Collins
Review feedback.
147
        log = self.get_log()
4657.1.1 by Robert Collins
Do not add the root directory entry to the list of expected keys during check in non rich-root repositories. (#416732)
148
        self.assertFalse('Missing' in log, "Something was missing in %r" % log)