/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
4454.3.1 by John Arbash Meinel
Initial api for Annotator.
1
# Copyright (C) 2009 Canonical Ltd
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
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
17
"""Tests for Annotators."""
18
19
from bzrlib import (
20
    errors,
4454.3.27 by John Arbash Meinel
Simplify the test__annotator tests by avoiding having a real repository.
21
    knit,
4454.3.1 by John Arbash Meinel
Initial api for Annotator.
22
    _annotator_py,
23
    tests,
24
    )
25
26
27
def load_tests(standard_tests, module, loader):
28
    """Parameterize tests for all versions of groupcompress."""
29
    scenarios = [
30
        ('python', {'module': _annotator_py}),
31
    ]
32
    suite = loader.suiteClass()
33
    if CompiledAnnotator.available():
34
        from bzrlib import _annotator_pyx
35
        scenarios.append(('C', {'module': _annotator_pyx}))
36
    else:
37
        # the compiled module isn't available, so we add a failing test
38
        class FailWithoutFeature(tests.TestCase):
39
            def test_fail(self):
40
                self.requireFeature(CompiledAnnotator)
41
        suite.addTest(loader.loadTestsFromTestCase(FailWithoutFeature))
42
    result = tests.multiply_tests(standard_tests, scenarios, suite)
43
    return result
44
45
46
class _CompiledAnnotator(tests.Feature):
47
48
    def _probe(self):
49
        try:
50
            import bzrlib._annotator_pyx
51
        except ImportError:
52
            return False
53
        return True
54
55
    def feature_name(self):
56
        return 'bzrlib._annotator_pyx'
57
58
CompiledAnnotator = _CompiledAnnotator()
59
60
61
class TestAnnotator(tests.TestCaseWithMemoryTransport):
62
63
    module = None # Set by load_tests
64
4454.3.4 by John Arbash Meinel
New work on how to resolve conflict lines.
65
    fa_key = ('f-id', 'a-id')
66
    fb_key = ('f-id', 'b-id')
67
    fc_key = ('f-id', 'c-id')
68
    fd_key = ('f-id', 'd-id')
4454.3.12 by John Arbash Meinel
Finish fleshing out the ability to determine a revision after conflicts.
69
    fe_key = ('f-id', 'e-id')
70
    ff_key = ('f-id', 'f-id')
4454.3.4 by John Arbash Meinel
New work on how to resolve conflict lines.
71
4454.3.2 by John Arbash Meinel
Start moving bits into helper functions. Add tests for multiple revs.
72
    def make_simple_text(self):
4454.3.27 by John Arbash Meinel
Simplify the test__annotator tests by avoiding having a real repository.
73
        # TODO: all we really need is a VersionedFile instance, we'd like to
74
        #       avoid creating all the intermediate stuff
75
        factory = knit.make_pack_factory(True, True, 2)
76
        self.vf = factory(self.get_transport())
4454.3.18 by John Arbash Meinel
Start tracking the number of children that need a given text.
77
        # This assumes nothing special happens during __init__, which may be
78
        # valid
79
        self.ann = self.module.Annotator(self.vf)
4454.3.27 by John Arbash Meinel
Simplify the test__annotator tests by avoiding having a real repository.
80
        self.vf.add_lines(self.fa_key, [], ['simple\n', 'content\n'])
81
        self.vf.add_lines(self.fb_key, [self.fa_key],
82
                          ['simple\n', 'new content\n'])
4454.3.4 by John Arbash Meinel
New work on how to resolve conflict lines.
83
84
    def make_merge_text(self):
85
        self.make_simple_text()
4454.3.27 by John Arbash Meinel
Simplify the test__annotator tests by avoiding having a real repository.
86
        self.vf.add_lines(self.fc_key, [self.fa_key],
87
                          ['simple\n', 'from c\n', 'content\n'])
88
        self.vf.add_lines(self.fd_key, [self.fb_key, self.fc_key],
89
                          ['simple\n', 'from c\n', 'new content\n',
90
                           'introduced in merge\n'])
4454.3.4 by John Arbash Meinel
New work on how to resolve conflict lines.
91
92
    def make_common_merge_text(self):
93
        """Both sides of the merge will have introduced a line."""
94
        self.make_simple_text()
4454.3.27 by John Arbash Meinel
Simplify the test__annotator tests by avoiding having a real repository.
95
        self.vf.add_lines(self.fc_key, [self.fa_key],
96
                          ['simple\n', 'new content\n'])
97
        self.vf.add_lines(self.fd_key, [self.fb_key, self.fc_key],
98
                          ['simple\n', 'new content\n'])
4454.3.4 by John Arbash Meinel
New work on how to resolve conflict lines.
99
4454.3.12 by John Arbash Meinel
Finish fleshing out the ability to determine a revision after conflicts.
100
    def make_many_way_common_merge_text(self):
101
        self.make_simple_text()
4454.3.27 by John Arbash Meinel
Simplify the test__annotator tests by avoiding having a real repository.
102
        self.vf.add_lines(self.fc_key, [self.fa_key],
103
                          ['simple\n', 'new content\n'])
104
        self.vf.add_lines(self.fd_key, [self.fb_key, self.fc_key],
105
                          ['simple\n', 'new content\n'])
106
        self.vf.add_lines(self.fe_key, [self.fa_key],
107
                          ['simple\n', 'new content\n'])
108
        self.vf.add_lines(self.ff_key, [self.fd_key, self.fe_key],
109
                          ['simple\n', 'new content\n'])
4454.3.12 by John Arbash Meinel
Finish fleshing out the ability to determine a revision after conflicts.
110
4454.3.4 by John Arbash Meinel
New work on how to resolve conflict lines.
111
    def make_merge_and_restored_text(self):
112
        self.make_simple_text()
4454.3.27 by John Arbash Meinel
Simplify the test__annotator tests by avoiding having a real repository.
113
        # c reverts back to 'a' for the new content line
114
        self.vf.add_lines(self.fc_key, [self.fb_key],
115
                          ['simple\n', 'content\n'])
116
        # d merges 'a' and 'c', to find both claim last modified
117
        self.vf.add_lines(self.fd_key, [self.fa_key, self.fc_key],
118
                          ['simple\n', 'content\n'])
4454.3.4 by John Arbash Meinel
New work on how to resolve conflict lines.
119
120
    def assertAnnotateEqual(self, expected_annotation, annotator, key):
121
        annotation, lines = annotator.annotate(key)
122
        self.assertEqual(expected_annotation, annotation)
123
        record = self.vf.get_record_stream([key], 'unordered', True).next()
124
        exp_text = record.get_bytes_as('fulltext')
125
        self.assertEqualDiff(exp_text, ''.join(lines))
4454.3.1 by John Arbash Meinel
Initial api for Annotator.
126
127
    def test_annotate_missing(self):
4454.3.4 by John Arbash Meinel
New work on how to resolve conflict lines.
128
        self.make_simple_text()
4454.3.1 by John Arbash Meinel
Initial api for Annotator.
129
        self.assertRaises(errors.RevisionNotPresent,
4454.3.18 by John Arbash Meinel
Start tracking the number of children that need a given text.
130
                          self.ann.annotate, ('not', 'present'))
4454.3.1 by John Arbash Meinel
Initial api for Annotator.
131
132
    def test_annotate_simple(self):
4454.3.4 by John Arbash Meinel
New work on how to resolve conflict lines.
133
        self.make_simple_text()
4454.3.18 by John Arbash Meinel
Start tracking the number of children that need a given text.
134
        self.assertAnnotateEqual([(self.fa_key,)]*2, self.ann, self.fa_key)
4454.3.4 by John Arbash Meinel
New work on how to resolve conflict lines.
135
        self.assertAnnotateEqual([(self.fa_key,), (self.fb_key,)],
4454.3.18 by John Arbash Meinel
Start tracking the number of children that need a given text.
136
                                 self.ann, self.fb_key)
4454.3.4 by John Arbash Meinel
New work on how to resolve conflict lines.
137
138
    def test_annotate_merge_text(self):
139
        self.make_merge_text()
140
        self.assertAnnotateEqual([(self.fa_key,), (self.fc_key,),
141
                                  (self.fb_key,), (self.fd_key,)],
4454.3.18 by John Arbash Meinel
Start tracking the number of children that need a given text.
142
                                 self.ann, self.fd_key)
4454.3.4 by John Arbash Meinel
New work on how to resolve conflict lines.
143
144
    def test_annotate_common_merge_text(self):
145
        self.make_common_merge_text()
146
        self.assertAnnotateEqual([(self.fa_key,), (self.fb_key, self.fc_key)],
4454.3.18 by John Arbash Meinel
Start tracking the number of children that need a given text.
147
                                 self.ann, self.fd_key)
4454.3.4 by John Arbash Meinel
New work on how to resolve conflict lines.
148
4454.3.12 by John Arbash Meinel
Finish fleshing out the ability to determine a revision after conflicts.
149
    def test_annotate_many_way_common_merge_text(self):
150
        self.make_many_way_common_merge_text()
151
        self.assertAnnotateEqual([(self.fa_key,),
152
                                  (self.fb_key, self.fc_key, self.fe_key)],
4454.3.18 by John Arbash Meinel
Start tracking the number of children that need a given text.
153
                                 self.ann, self.ff_key)
4454.3.12 by John Arbash Meinel
Finish fleshing out the ability to determine a revision after conflicts.
154
4454.3.4 by John Arbash Meinel
New work on how to resolve conflict lines.
155
    def test_annotate_merge_and_restored(self):
156
        self.make_merge_and_restored_text()
157
        self.assertAnnotateEqual([(self.fa_key,), (self.fa_key, self.fc_key)],
4454.3.18 by John Arbash Meinel
Start tracking the number of children that need a given text.
158
                                 self.ann, self.fd_key)
4454.3.10 by John Arbash Meinel
Start working on 'annotate_flat' which conforms to the original spec.
159
160
    def test_annotate_flat_simple(self):
161
        self.make_simple_text()
162
        self.assertEqual([(self.fa_key, 'simple\n'),
163
                          (self.fa_key, 'content\n'),
4454.3.18 by John Arbash Meinel
Start tracking the number of children that need a given text.
164
                         ], self.ann.annotate_flat(self.fa_key))
4454.3.10 by John Arbash Meinel
Start working on 'annotate_flat' which conforms to the original spec.
165
        self.assertEqual([(self.fa_key, 'simple\n'),
166
                          (self.fb_key, 'new content\n'),
4454.3.18 by John Arbash Meinel
Start tracking the number of children that need a given text.
167
                         ], self.ann.annotate_flat(self.fb_key))
4454.3.12 by John Arbash Meinel
Finish fleshing out the ability to determine a revision after conflicts.
168
169
    def test_annotate_flat_merge_and_restored_text(self):
170
        self.make_merge_and_restored_text()
171
        # fc is a simple dominator of fa
172
        self.assertEqual([(self.fa_key, 'simple\n'),
173
                          (self.fc_key, 'content\n'),
4454.3.18 by John Arbash Meinel
Start tracking the number of children that need a given text.
174
                         ], self.ann.annotate_flat(self.fd_key))
4454.3.12 by John Arbash Meinel
Finish fleshing out the ability to determine a revision after conflicts.
175
176
    def test_annotate_common_merge_text(self):
177
        self.make_common_merge_text()
178
        # there is no common point, so we just pick the lexicographical lowest
179
        # and 'b-id' comes before 'c-id'
180
        self.assertEqual([(self.fa_key, 'simple\n'),
181
                          (self.fb_key, 'new content\n'),
4454.3.18 by John Arbash Meinel
Start tracking the number of children that need a given text.
182
                         ], self.ann.annotate_flat(self.fd_key))
4454.3.12 by John Arbash Meinel
Finish fleshing out the ability to determine a revision after conflicts.
183
184
    def test_annotate_many_way_common_merge_text(self):
185
        self.make_many_way_common_merge_text()
4454.3.14 by John Arbash Meinel
Had a slightly bogus test.
186
        self.assertEqual([(self.fa_key, 'simple\n'),
187
                         (self.fb_key, 'new content\n')],
4454.3.18 by John Arbash Meinel
Start tracking the number of children that need a given text.
188
                         self.ann.annotate_flat(self.ff_key))
189
190
4454.3.19 by John Arbash Meinel
Have _record_annotation start to remove texts when they are no longer needed.
191
    def test_needed_keys_simple(self):
4454.3.18 by John Arbash Meinel
Start tracking the number of children that need a given text.
192
        self.make_simple_text()
193
        keys = self.ann._get_needed_keys(self.fb_key)
194
        self.assertEqual([self.fa_key, self.fb_key], sorted(keys))
195
        self.assertEqual({self.fa_key: 1, self.fb_key: 1},
196
                         self.ann._num_needed_children)
4454.3.19 by John Arbash Meinel
Have _record_annotation start to remove texts when they are no longer needed.
197
198
    def test_needed_keys_many(self):
199
        self.make_many_way_common_merge_text()
200
        keys = self.ann._get_needed_keys(self.ff_key)
201
        self.assertEqual([self.fa_key, self.fb_key, self.fc_key,
202
                          self.fd_key, self.fe_key, self.ff_key,
203
                         ], sorted(keys))
204
        self.assertEqual({self.fa_key: 3,
205
                          self.fb_key: 1,
206
                          self.fc_key: 1,
207
                          self.fd_key: 1,
208
                          self.fe_key: 1,
209
                          self.ff_key: 1,
210
                         }, self.ann._num_needed_children)
211
212
    def test_record_annotation_removes_texts(self):
213
        self.make_many_way_common_merge_text()
214
        # Populate the caches
215
        for x in self.ann._get_needed_texts(self.ff_key):
216
            continue
217
        self.assertEqual({self.fa_key: 3,
218
                          self.fb_key: 1,
219
                          self.fc_key: 1,
220
                          self.fd_key: 1,
221
                          self.fe_key: 1,
222
                          self.ff_key: 1,
223
                         }, self.ann._num_needed_children)
224
        self.assertEqual([self.fa_key, self.fb_key, self.fc_key,
225
                          self.fd_key, self.fe_key, self.ff_key,
226
                         ], sorted(self.ann._text_cache.keys()))
4454.3.22 by John Arbash Meinel
Need to record the other annotations before we can record this,
227
        self.ann._record_annotation(self.fa_key, [], [])
4454.3.19 by John Arbash Meinel
Have _record_annotation start to remove texts when they are no longer needed.
228
        self.ann._record_annotation(self.fb_key, [self.fa_key], [])
229
        self.assertEqual({self.fa_key: 2,
230
                          self.fb_key: 1,
231
                          self.fc_key: 1,
232
                          self.fd_key: 1,
233
                          self.fe_key: 1,
234
                          self.ff_key: 1,
235
                         }, self.ann._num_needed_children)
236
        self.assertTrue(self.fa_key in self.ann._text_cache)
4454.3.21 by John Arbash Meinel
Assert that entries in the annotation cache also get cleaned up.
237
        self.assertTrue(self.fa_key in self.ann._annotations_cache)
4454.3.22 by John Arbash Meinel
Need to record the other annotations before we can record this,
238
        self.ann._record_annotation(self.fc_key, [self.fa_key], [])
4454.3.19 by John Arbash Meinel
Have _record_annotation start to remove texts when they are no longer needed.
239
        self.ann._record_annotation(self.fd_key, [self.fb_key, self.fc_key], [])
4454.3.22 by John Arbash Meinel
Need to record the other annotations before we can record this,
240
        self.assertEqual({self.fa_key: 1,
4454.3.19 by John Arbash Meinel
Have _record_annotation start to remove texts when they are no longer needed.
241
                          self.fb_key: 0,
242
                          self.fc_key: 0,
243
                          self.fd_key: 1,
244
                          self.fe_key: 1,
245
                          self.ff_key: 1,
246
                         }, self.ann._num_needed_children)
247
        self.assertTrue(self.fa_key in self.ann._text_cache)
4454.3.21 by John Arbash Meinel
Assert that entries in the annotation cache also get cleaned up.
248
        self.assertTrue(self.fa_key in self.ann._annotations_cache)
4454.3.19 by John Arbash Meinel
Have _record_annotation start to remove texts when they are no longer needed.
249
        self.assertFalse(self.fb_key in self.ann._text_cache)
4454.3.22 by John Arbash Meinel
Need to record the other annotations before we can record this,
250
        self.assertFalse(self.fb_key in self.ann._annotations_cache)
4454.3.19 by John Arbash Meinel
Have _record_annotation start to remove texts when they are no longer needed.
251
        self.assertFalse(self.fc_key in self.ann._text_cache)
4454.3.22 by John Arbash Meinel
Need to record the other annotations before we can record this,
252
        self.assertFalse(self.fc_key in self.ann._annotations_cache)