/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_groupcompress.py

Factor out tests that rely on the exact bytecode.
The Pyrex compressor gives slightly different encoding than the
Python compressor, because it has a better diff engine.

Show diffs side-by-side

added added

removed removed

Lines of Context:
32
32
    )
33
33
 
34
34
 
 
35
def load_tests(standard_tests, module, loader):
 
36
    """Parameterize tests for view-aware vs not."""
 
37
    to_adapt, result = tests.split_suite_by_condition(
 
38
        standard_tests, tests.condition_isinstance(TestAllGroupCompressors))
 
39
    scenarios = [
 
40
        ('python', {'compressor': groupcompress.PythonGroupCompressor}),
 
41
        ]
 
42
    if CompiledGroupcompressFeature.available():
 
43
        scenarios.append(('C',
 
44
            {'compressor': groupcompress.PyrexGroupCompressor}))
 
45
    return multiply_tests(to_adapt, scenarios, result)
 
46
 
 
47
 
 
48
class _CompiledGroupcompressFeature(tests.Feature):
 
49
 
 
50
    def _probe(self):
 
51
        try:
 
52
            import bzrlib._groupcompress_pyx
 
53
        except ImportError:
 
54
            return False
 
55
        return True
 
56
 
 
57
    def feature_name(self):
 
58
        return "bzrlib._groupcompress_pyx"
 
59
 
 
60
CompiledGroupcompressFeature = _CompiledGroupcompressFeature()
 
61
 
 
62
 
35
63
class TestGroupCompressor(tests.TestCase):
 
64
 
 
65
    def _chunks_to_repr_lines(self, chunks):
 
66
        return '\n'.join(map(repr, ''.join(chunks).split('\n')))
 
67
 
 
68
    def assertEqualDiffEncoded(self, expected, actual):
 
69
        """Compare the actual content to the expected content.
 
70
 
 
71
        :param expected: A group of chunks that we expect to see
 
72
        :param actual: The measured 'chunks'
 
73
 
 
74
        We will transform the chunks back into lines, and then run 'repr()'
 
75
        over them to handle non-ascii characters.
 
76
        """
 
77
        self.assertEqualDiff(self._chunks_to_repr_lines(expected),
 
78
                             self._chunks_to_repr_lines(actual))
 
79
 
 
80
 
 
81
class TestAllGroupCompressors(TestGroupCompressor):
36
82
    """Tests for GroupCompressor"""
37
83
 
 
84
    compressor = None # Set by multiply_tests
 
85
 
38
86
    def test_empty_delta(self):
39
 
        compressor = groupcompress.GroupCompressor()
 
87
        compressor = self.compressor()
40
88
        self.assertEqual([], compressor.lines)
41
89
 
42
90
    def test_one_nosha_delta(self):
43
91
        # diff against NUKK
44
 
        compressor = groupcompress.GroupCompressor()
 
92
        compressor = self.compressor()
45
93
        sha1, start_point, end_point, _, _ = compressor.compress(('label',),
46
94
            'strange\ncommon\n', None)
47
95
        self.assertEqual(sha_string('strange\ncommon\n'), sha1)
48
 
        expected_lines = [
49
 
            'f', '\x0f', 'strange\ncommon\n',
50
 
            ]
51
 
        self.assertEqual(expected_lines, compressor.lines)
 
96
        expected_lines = 'f' '\x0f' 'strange\ncommon\n'
 
97
        self.assertEqual(expected_lines, ''.join(compressor.lines))
52
98
        self.assertEqual(0, start_point)
53
99
        self.assertEqual(sum(map(len, expected_lines)), end_point)
54
100
 
55
101
    def test_empty_content(self):
56
 
        compressor = groupcompress.GroupCompressor()
 
102
        compressor = self.compressor()
57
103
        # Adding empty bytes should return the 'null' record
58
104
        sha1, start_point, end_point, kind, _ = compressor.compress(('empty',),
59
105
            '', None)
73
119
        self.assertEqual('fulltext', kind)
74
120
        self.assertEqual(groupcompress._null_sha1, sha1)
75
121
 
76
 
    def _chunks_to_repr_lines(self, chunks):
77
 
        return '\n'.join(map(repr, ''.join(chunks).split('\n')))
78
 
 
79
 
    def assertEqualDiffEncoded(self, expected, actual):
80
 
        """Compare the actual content to the expected content.
81
 
 
82
 
        :param expected: A group of chunks that we expect to see
83
 
        :param actual: The measured 'chunks'
84
 
 
85
 
        We will transform the chunks back into lines, and then run 'repr()'
86
 
        over them to handle non-ascii characters.
87
 
        """
88
 
        self.assertEqualDiff(self._chunks_to_repr_lines(expected),
89
 
                             self._chunks_to_repr_lines(actual))
90
 
 
91
 
    def test_two_nosha_delta(self):
92
 
        compressor = groupcompress.GroupCompressor()
93
 
        sha1_1, _, _, _, _ = compressor.compress(('label',),
94
 
            'strange\ncommon long line\nthat needs a 16 byte match\n', None)
95
 
        expected_lines = list(compressor.lines)
96
 
        sha1_2, start_point, end_point, _, _ = compressor.compress(('newlabel',),
97
 
            'common long line\nthat needs a 16 byte match\ndifferent\n', None)
98
 
        self.assertEqual(sha_string('common long line\n'
99
 
                                    'that needs a 16 byte match\n'
100
 
                                    'different\n'), sha1_2)
101
 
        expected_lines.extend([
102
 
            # 'delta', delta length
103
 
            'd\x10',
104
 
            # source and target length
105
 
            '\x36\x36',
106
 
            # copy the line common
107
 
            '\x91\x0a\x2c', #copy, offset 0x0a, len 0x2c
108
 
            # add the line different, and the trailing newline
109
 
            '\x0adifferent\n', # insert 10 bytes
110
 
            ])
111
 
        self.assertEqualDiffEncoded(expected_lines, compressor.lines)
112
 
        self.assertEqual(sum(map(len, expected_lines)), end_point)
113
 
 
114
 
    def test_three_nosha_delta(self):
115
 
        # The first interesting test: make a change that should use lines from
116
 
        # both parents.
117
 
        compressor = groupcompress.GroupCompressor()
118
 
        sha1_1, _, _, _, _ = compressor.compress(('label',),
119
 
            'strange\ncommon very very long line\nwith some extra text\n', None)
120
 
        sha1_2, _, _, _, _ = compressor.compress(('newlabel',),
121
 
            'different\nmoredifferent\nand then some more\n', None)
122
 
        expected_lines = list(compressor.lines)
123
 
        sha1_3, start_point, end_point, _, _ = compressor.compress(('label3',),
124
 
            'new\ncommon very very long line\nwith some extra text\n'
125
 
            'different\nmoredifferent\nand then some more\n',
126
 
            None)
127
 
        self.assertEqual(
128
 
            sha_string('new\ncommon very very long line\nwith some extra text\n'
129
 
                       'different\nmoredifferent\nand then some more\n'),
130
 
            sha1_3)
131
 
        expected_lines.extend([
132
 
            # 'delta', delta length
133
 
            'd\x0c',
134
 
            # source and target length
135
 
            '\x67\x5f'
136
 
            # insert new
137
 
            '\x03new',
138
 
            # Copy of first parent 'common' range
139
 
            '\x91\x09\x31' # copy, offset 0x09, 0x31 bytes
140
 
            # Copy of second parent 'different' range
141
 
            '\x91\x3c\x2b' # copy, offset 0x3c, 0x2b bytes
142
 
            ])
143
 
        self.assertEqualDiffEncoded(expected_lines, compressor.lines)
144
 
        self.assertEqual(sum(map(len, expected_lines)), end_point)
145
 
 
146
 
    def test_stats(self):
147
 
        compressor = groupcompress.GroupCompressor()
148
 
        compressor.compress(('label',), 'strange\ncommon long line\n'
149
 
                                        'plus more text\n', None)
150
 
        compressor.compress(('newlabel',),
151
 
                            'common long line\nplus more text\n'
152
 
                            'different\nmoredifferent\n', None)
153
 
        compressor.compress(('label3',),
154
 
                            'new\ncommon long line\nplus more text\n'
155
 
                            '\ndifferent\nmoredifferent\n', None)
156
 
        self.assertAlmostEqual(1.4, compressor.ratio(), 1)
157
 
 
158
122
    def test_extract_from_compressor(self):
159
123
        # Knit fetching will try to reconstruct texts locally which results in
160
124
        # reading something that is in the compressor stream already.
161
 
        compressor = groupcompress.GroupCompressor()
 
125
        compressor = self.compressor()
162
126
        sha1_1, _, _, _, _ = compressor.compress(('label',),
163
127
            'strange\ncommon long line\nthat needs a 16 byte match\n', None)
164
128
        expected_lines = list(compressor.lines)
174
138
                         compressor.extract(('newlabel',)))
175
139
 
176
140
 
 
141
class TestPyrexGroupCompressor(TestGroupCompressor):
 
142
 
 
143
    _test_needs_features = [CompiledGroupcompressFeature]
 
144
    compressor = groupcompress.PyrexGroupCompressor
 
145
 
 
146
    def test_stats(self):
 
147
        compressor = self.compressor()
 
148
        compressor.compress(('label',), 'strange\ncommon long line\n'
 
149
                                        'plus more text\n', None)
 
150
        compressor.compress(('newlabel',),
 
151
                            'common long line\nplus more text\n'
 
152
                            'different\nmoredifferent\n', None)
 
153
        compressor.compress(('label3',),
 
154
                            'new\ncommon long line\nplus more text\n'
 
155
                            '\ndifferent\nmoredifferent\n', None)
 
156
        self.assertAlmostEqual(1.4, compressor.ratio(), 1)
 
157
 
 
158
    def test_two_nosha_delta(self):
 
159
        compressor = self.compressor()
 
160
        sha1_1, _, _, _, _ = compressor.compress(('label',),
 
161
            'strange\ncommon long line\nthat needs a 16 byte match\n', None)
 
162
        expected_lines = list(compressor.lines)
 
163
        sha1_2, start_point, end_point, _, _ = compressor.compress(('newlabel',),
 
164
            'common long line\nthat needs a 16 byte match\ndifferent\n', None)
 
165
        self.assertEqual(sha_string('common long line\n'
 
166
                                    'that needs a 16 byte match\n'
 
167
                                    'different\n'), sha1_2)
 
168
        expected_lines.extend([
 
169
            # 'delta', delta length
 
170
            'd\x10',
 
171
            # source and target length
 
172
            '\x36\x36',
 
173
            # copy the line common
 
174
            '\x91\x0a\x2c', #copy, offset 0x0a, len 0x2c
 
175
            # add the line different, and the trailing newline
 
176
            '\x0adifferent\n', # insert 10 bytes
 
177
            ])
 
178
        self.assertEqualDiffEncoded(expected_lines, compressor.lines)
 
179
        self.assertEqual(sum(map(len, expected_lines)), end_point)
 
180
 
 
181
    def test_three_nosha_delta(self):
 
182
        # The first interesting test: make a change that should use lines from
 
183
        # both parents.
 
184
        compressor = self.compressor()
 
185
        sha1_1, _, _, _, _ = compressor.compress(('label',),
 
186
            'strange\ncommon very very long line\nwith some extra text\n', None)
 
187
        sha1_2, _, _, _, _ = compressor.compress(('newlabel',),
 
188
            'different\nmoredifferent\nand then some more\n', None)
 
189
        expected_lines = list(compressor.lines)
 
190
        sha1_3, start_point, end_point, _, _ = compressor.compress(('label3',),
 
191
            'new\ncommon very very long line\nwith some extra text\n'
 
192
            'different\nmoredifferent\nand then some more\n',
 
193
            None)
 
194
        self.assertEqual(
 
195
            sha_string('new\ncommon very very long line\nwith some extra text\n'
 
196
                       'different\nmoredifferent\nand then some more\n'),
 
197
            sha1_3)
 
198
        expected_lines.extend([
 
199
            # 'delta', delta length
 
200
            'd\x0c',
 
201
            # source and target length
 
202
            '\x67\x5f'
 
203
            # insert new
 
204
            '\x03new',
 
205
            # Copy of first parent 'common' range
 
206
            '\x91\x09\x31' # copy, offset 0x09, 0x31 bytes
 
207
            # Copy of second parent 'different' range
 
208
            '\x91\x3c\x2b' # copy, offset 0x3c, 0x2b bytes
 
209
            ])
 
210
        self.assertEqualDiffEncoded(expected_lines, compressor.lines)
 
211
        self.assertEqual(sum(map(len, expected_lines)), end_point)
 
212
 
 
213
 
 
214
class TestPythonGroupCompressor(TestGroupCompressor):
 
215
 
 
216
    compressor = groupcompress.PythonGroupCompressor
 
217
 
 
218
    def test_stats(self):
 
219
        compressor = self.compressor()
 
220
        compressor.compress(('label',), 'strange\ncommon long line\n'
 
221
                                        'plus more text\n', None)
 
222
        compressor.compress(('newlabel',),
 
223
                            'common long line\nplus more text\n'
 
224
                            'different\nmoredifferent\n', None)
 
225
        compressor.compress(('label3',),
 
226
                            'new\ncommon long line\nplus more text\n'
 
227
                            '\ndifferent\nmoredifferent\n', None)
 
228
        self.assertAlmostEqual(1.1, compressor.ratio(), 1)
 
229
 
 
230
    def test_two_nosha_delta(self):
 
231
        compressor = self.compressor()
 
232
        sha1_1, _, _, _, _ = compressor.compress(('label',),
 
233
            'strange\ncommon long line\nthat needs a 16 byte match\n', None)
 
234
        expected_lines = list(compressor.lines)
 
235
        sha1_2, start_point, end_point, _, _ = compressor.compress(('newlabel',),
 
236
            'common long line\nthat needs a 16 byte match\ndifferent\n', None)
 
237
        self.assertEqual(sha_string('common long line\n'
 
238
                                    'that needs a 16 byte match\n'
 
239
                                    'different\n'), sha1_2)
 
240
        expected_lines.extend([
 
241
            # 'delta', delta length
 
242
            'd\x10',
 
243
            # source and target length
 
244
            '\x36\x36',
 
245
            # copy the line common
 
246
            '\x91\x0a\x2c', #copy, offset 0x0a, len 0x2c
 
247
            # add the line different, and the trailing newline
 
248
            '\x0adifferent\n', # insert 10 bytes
 
249
            ])
 
250
        self.assertEqualDiffEncoded(expected_lines, compressor.lines)
 
251
        self.assertEqual(sum(map(len, expected_lines)), end_point)
 
252
 
 
253
    def test_three_nosha_delta(self):
 
254
        # The first interesting test: make a change that should use lines from
 
255
        # both parents.
 
256
        compressor = self.compressor()
 
257
        sha1_1, _, _, _, _ = compressor.compress(('label',),
 
258
            'strange\ncommon very very long line\nwith some extra text\n', None)
 
259
        sha1_2, _, _, _, _ = compressor.compress(('newlabel',),
 
260
            'different\nmoredifferent\nand then some more\n', None)
 
261
        expected_lines = list(compressor.lines)
 
262
        sha1_3, start_point, end_point, _, _ = compressor.compress(('label3',),
 
263
            'new\ncommon very very long line\nwith some extra text\n'
 
264
            'different\nmoredifferent\nand then some more\n',
 
265
            None)
 
266
        self.assertEqual(
 
267
            sha_string('new\ncommon very very long line\nwith some extra text\n'
 
268
                       'different\nmoredifferent\nand then some more\n'),
 
269
            sha1_3)
 
270
        expected_lines.extend([
 
271
            # 'delta', delta length
 
272
            'd\x0d',
 
273
            # source and target length
 
274
            '\x67\x5f'
 
275
            # insert new
 
276
            '\x04new\n',
 
277
            # Copy of first parent 'common' range
 
278
            '\x91\x0a\x30' # copy, offset 0x0a, 0x30 bytes
 
279
            # Copy of second parent 'different' range
 
280
            '\x91\x3c\x2b' # copy, offset 0x3c, 0x2b bytes
 
281
            ])
 
282
        self.assertEqualDiffEncoded(expected_lines, compressor.lines)
 
283
        self.assertEqual(sum(map(len, expected_lines)), end_point)
 
284
 
 
285
 
177
286
class TestEncodeCopyInstruction(tests.TestCase):
178
287
 
179
288
    def assertCopyInstruction(self, expected, offset, length):