129
122
'different\nmoredifferent\nand then some more\n'),
131
124
expected_lines.extend([
134
'sha1:%s\n' % sha1_3,
136
'\xfa\x01\x5f' # source and target length
125
'\x63\x5f' # source and target length
139
128
# Copy of first parent 'common' range
140
'\x91\x51\x31' # copy, offset 0x51, 0x31 bytes
129
'\x91\x07\x31' # copy, offset 0x07, 0x31 bytes
141
130
# Copy of second parent 'different' range
142
'\x91\xcf\x2b' # copy, offset 0xcf, 0x2b bytes
131
'\x91\x38\x2b' # copy, offset 0x38, 0x2b bytes
144
133
self.assertEqualDiffEncoded(expected_lines, compressor.lines)
145
134
self.assertEqual(sum(map(len, expected_lines)), end_point)
147
136
def test_stats(self):
148
137
compressor = groupcompress.GroupCompressor(True)
149
compressor.compress(('label',), 'strange\ncommon\n', None)
138
compressor.compress(('label',), 'strange\ncommon long line\n'
139
'plus more text\n', None)
150
140
compressor.compress(('newlabel',),
151
'common\ndifferent\nmoredifferent\n', None)
141
'common long line\nplus more text\n'
142
'different\nmoredifferent\n', None)
152
143
compressor.compress(('label3',),
153
'new\ncommon\ndifferent\nmoredifferent\n', None)
154
self.assertAlmostEqual(0.3, compressor.ratio(), 1)
144
'new\ncommon long line\nplus more text\n'
145
'\ndifferent\nmoredifferent\n', None)
146
self.assertAlmostEqual(1.4, compressor.ratio(), 1)
156
148
def test_extract_from_compressor(self):
157
149
# Knit fetching will try to reconstruct texts locally which results in
158
150
# reading something that is in the compressor stream already.
159
151
compressor = groupcompress.GroupCompressor(True)
160
sha_1, _ = compressor.compress(('label',), 'strange\ncommon\n', None)
161
sha_2, _ = compressor.compress(('newlabel',),
162
'common\ndifferent\nmoredifferent\n', None)
152
sha1_1, _, _, _ = compressor.compress(('label',),
153
'strange\ncommon long line\nthat needs a 16 byte match\n', None)
154
expected_lines = list(compressor.lines)
155
sha1_2, end_point, _, _ = compressor.compress(('newlabel',),
156
'common long line\nthat needs a 16 byte match\ndifferent\n', None)
163
157
# get the first out
164
self.assertEqual((['strange\ncommon\n'], sha_1),
158
self.assertEqual(('strange\ncommon long line\n'
159
'that needs a 16 byte match\n', sha1_1),
165
160
compressor.extract(('label',)))
167
self.assertEqual((['common\ndifferent\nmoredifferent\n'],
168
sha_2), compressor.extract(('newlabel',)))
162
self.assertEqual(('common long line\nthat needs a 16 byte match\n'
163
'different\n', sha1_2),
164
compressor.extract(('newlabel',)))
167
class TestBase128Int(tests.TestCase):
169
def assertEqualEncode(self, bytes, val):
170
self.assertEqual(bytes, groupcompress.encode_base128_int(val))
172
def assertEqualDecode(self, val, num_decode, bytes):
173
self.assertEqual((val, num_decode),
174
groupcompress.decode_base128_int(bytes))
176
def test_encode(self):
177
self.assertEqualEncode('\x01', 1)
178
self.assertEqualEncode('\x02', 2)
179
self.assertEqualEncode('\x7f', 127)
180
self.assertEqualEncode('\x80\x01', 128)
181
self.assertEqualEncode('\xff\x01', 255)
182
self.assertEqualEncode('\x80\x02', 256)
183
self.assertEqualEncode('\xff\xff\xff\xff\x0f', 0xFFFFFFFF)
185
def test_decode(self):
186
self.assertEqualDecode(1, 1, '\x01')
187
self.assertEqualDecode(2, 1, '\x02')
188
self.assertEqualDecode(127, 1, '\x7f')
189
self.assertEqualDecode(128, 2, '\x80\x01')
190
self.assertEqualDecode(255, 2, '\xff\x01')
191
self.assertEqualDecode(256, 2, '\x80\x02')
192
self.assertEqualDecode(0xFFFFFFFF, 5, '\xff\xff\xff\xff\x0f')
194
def test_decode_with_trailing_bytes(self):
195
self.assertEqualDecode(1, 1, '\x01abcdef')
196
self.assertEqualDecode(127, 1, '\x7f\x01')
197
self.assertEqualDecode(128, 2, '\x80\x01abcdef')
198
self.assertEqualDecode(255, 2, '\xff\x01\xff')
201
class TestGroupCompressBlock(tests.TestCase):
203
def test_from_empty_bytes(self):
204
self.assertRaises(errors.InvalidGroupCompressBlock,
205
groupcompress.GroupCompressBlock.from_bytes, '')
207
def test_from_minimal_bytes(self):
208
block = groupcompress.GroupCompressBlock.from_bytes('gcb1z\n0\n0\n')
209
self.assertIsInstance(block, groupcompress.GroupCompressBlock)
210
self.assertEqual({}, block._entries)
212
def test_from_bytes(self):
214
'gcb1z\n' # group compress block v1 plain
215
'76\n' # Length of zlib bytes
216
'183\n' # Length of all meta-info
219
'sha1:abcdabcdabcdabcdabcdabcdabcdabcdabcdabcd\n'
225
'sha1:abcdabcdabcdabcdabcdabcdabcdabcdabcdabcd\n'
230
block = groupcompress.GroupCompressBlock.from_bytes(
232
self.assertIs(None, block._content)
233
self.assertIsInstance(block, groupcompress.GroupCompressBlock)
234
self.assertEqual([('bing',), ('foo', 'bar')], sorted(block._entries))
235
bing = block._entries[('bing',)]
236
self.assertEqual(('bing',), bing.key)
237
self.assertEqual('fulltext', bing.type)
238
self.assertEqual('abcd'*10, bing.sha1)
239
self.assertEqual(100, bing.start)
240
self.assertEqual(100, bing.length)
241
foobar = block._entries[('foo', 'bar')]
242
self.assertEqual(('foo', 'bar'), foobar.key)
243
self.assertEqual('fulltext', foobar.type)
244
self.assertEqual('abcd'*10, foobar.sha1)
245
self.assertEqual(0, foobar.start)
246
self.assertEqual(100, foobar.length)
248
def test_add_entry(self):
249
gcb = groupcompress.GroupCompressBlock()
250
e = gcb.add_entry(('foo', 'bar'), 'fulltext', 'abcd'*10, 0, 100)
251
self.assertIsInstance(e, groupcompress.GroupCompressBlockEntry)
252
self.assertEqual(('foo', 'bar'), e.key)
253
self.assertEqual('fulltext', e.type)
254
self.assertEqual('abcd'*10, e.sha1)
255
self.assertEqual(0, e.start)
256
self.assertEqual(100, e.length)
258
def test_to_bytes(self):
259
gcb = groupcompress.GroupCompressBlock()
260
gcb.add_entry(('foo', 'bar'), 'fulltext', 'abcd'*10, 0, 100)
261
gcb.add_entry(('bing',), 'fulltext', 'abcd'*10, 100, 100)
262
bytes = gcb.to_bytes()
263
self.assertStartsWith(bytes,
264
'gcb1z\n' # group compress block v1 zlib
265
'77\n' # Length of compressed bytes
266
'183\n' # Length of all meta-info
268
remaining_bytes = bytes[13:]
269
raw_bytes = zlib.decompress(remaining_bytes)
270
self.assertEqualDiff('key:bing\n'
271
'sha1:abcdabcdabcdabcdabcdabcdabcdabcdabcdabcd\n'
277
'sha1:abcdabcdabcdabcdabcdabcdabcdabcdabcdabcd\n'