Mercurial > public > mercurial-scm > hg
comparison contrib/python-zstandard/tests/test_decompressor_fuzzing.py @ 37495:b1fb341d8a61
zstandard: vendor python-zstandard 0.9.0
This was just released. It features a number of goodies. More info at
https://gregoryszorc.com/blog/2018/04/09/release-of-python-zstandard-0.9/.
The clang-format ignore list was updated to reflect the new source
of files.
The project contains a vendored copy of zstandard 1.3.4. The old
version was 1.1.3. One of the changes between those versions is that
zstandard is now dual licensed BSD + GPLv2 and the patent rights grant
has been removed. Good riddance.
The API should be backwards compatible. So no changes in core
should be needed. However, there were a number of changes in the
library that we'll want to adapt to. Those will be addressed in
subsequent commits.
Differential Revision: https://phab.mercurial-scm.org/D3198
author | Gregory Szorc <gregory.szorc@gmail.com> |
---|---|
date | Mon, 09 Apr 2018 10:13:29 -0700 |
parents | e0dc40530c5a |
children | 675775c33ab6 |
comparison
equal
deleted
inserted
replaced
37494:1ce7a55b09d1 | 37495:b1fb341d8a61 |
---|---|
1 import io | 1 import io |
2 import os | 2 import os |
3 | 3 import unittest |
4 try: | |
5 import unittest2 as unittest | |
6 except ImportError: | |
7 import unittest | |
8 | 4 |
9 try: | 5 try: |
10 import hypothesis | 6 import hypothesis |
11 import hypothesis.strategies as strategies | 7 import hypothesis.strategies as strategies |
12 except ImportError: | 8 except ImportError: |
13 raise unittest.SkipTest('hypothesis not available') | 9 raise unittest.SkipTest('hypothesis not available') |
14 | 10 |
15 import zstd | 11 import zstandard as zstd |
16 | 12 |
17 from . common import ( | 13 from . common import ( |
18 make_cffi, | 14 make_cffi, |
19 random_input_data, | 15 random_input_data, |
20 ) | 16 ) |
21 | 17 |
22 | 18 |
23 @unittest.skipUnless('ZSTD_SLOW_TESTS' in os.environ, 'ZSTD_SLOW_TESTS not set') | 19 @unittest.skipUnless('ZSTD_SLOW_TESTS' in os.environ, 'ZSTD_SLOW_TESTS not set') |
24 @make_cffi | 20 @make_cffi |
25 class TestDecompressor_write_to_fuzzing(unittest.TestCase): | 21 class TestDecompressor_stream_reader_fuzzing(unittest.TestCase): |
22 @hypothesis.settings( | |
23 suppress_health_check=[hypothesis.HealthCheck.large_base_example]) | |
24 @hypothesis.given(original=strategies.sampled_from(random_input_data()), | |
25 level=strategies.integers(min_value=1, max_value=5), | |
26 source_read_size=strategies.integers(1, 16384), | |
27 read_sizes=strategies.data()) | |
28 def test_stream_source_read_variance(self, original, level, source_read_size, | |
29 read_sizes): | |
30 cctx = zstd.ZstdCompressor(level=level) | |
31 frame = cctx.compress(original) | |
32 | |
33 dctx = zstd.ZstdDecompressor() | |
34 source = io.BytesIO(frame) | |
35 | |
36 chunks = [] | |
37 with dctx.stream_reader(source, read_size=source_read_size) as reader: | |
38 while True: | |
39 read_size = read_sizes.draw(strategies.integers(1, 16384)) | |
40 chunk = reader.read(read_size) | |
41 if not chunk: | |
42 break | |
43 | |
44 chunks.append(chunk) | |
45 | |
46 self.assertEqual(b''.join(chunks), original) | |
47 | |
48 @hypothesis.settings( | |
49 suppress_health_check=[hypothesis.HealthCheck.large_base_example]) | |
50 @hypothesis.given(original=strategies.sampled_from(random_input_data()), | |
51 level=strategies.integers(min_value=1, max_value=5), | |
52 source_read_size=strategies.integers(1, 16384), | |
53 read_sizes=strategies.data()) | |
54 def test_buffer_source_read_variance(self, original, level, source_read_size, | |
55 read_sizes): | |
56 cctx = zstd.ZstdCompressor(level=level) | |
57 frame = cctx.compress(original) | |
58 | |
59 dctx = zstd.ZstdDecompressor() | |
60 chunks = [] | |
61 | |
62 with dctx.stream_reader(frame, read_size=source_read_size) as reader: | |
63 while True: | |
64 read_size = read_sizes.draw(strategies.integers(1, 16384)) | |
65 chunk = reader.read(read_size) | |
66 if not chunk: | |
67 break | |
68 | |
69 chunks.append(chunk) | |
70 | |
71 self.assertEqual(b''.join(chunks), original) | |
72 | |
73 @hypothesis.settings( | |
74 suppress_health_check=[hypothesis.HealthCheck.large_base_example]) | |
75 @hypothesis.given( | |
76 original=strategies.sampled_from(random_input_data()), | |
77 level=strategies.integers(min_value=1, max_value=5), | |
78 source_read_size=strategies.integers(1, 16384), | |
79 seek_amounts=strategies.data(), | |
80 read_sizes=strategies.data()) | |
81 def test_relative_seeks(self, original, level, source_read_size, seek_amounts, | |
82 read_sizes): | |
83 cctx = zstd.ZstdCompressor(level=level) | |
84 frame = cctx.compress(original) | |
85 | |
86 dctx = zstd.ZstdDecompressor() | |
87 | |
88 with dctx.stream_reader(frame, read_size=source_read_size) as reader: | |
89 while True: | |
90 amount = seek_amounts.draw(strategies.integers(0, 16384)) | |
91 reader.seek(amount, os.SEEK_CUR) | |
92 | |
93 offset = reader.tell() | |
94 read_amount = read_sizes.draw(strategies.integers(1, 16384)) | |
95 chunk = reader.read(read_amount) | |
96 | |
97 if not chunk: | |
98 break | |
99 | |
100 self.assertEqual(original[offset:offset + len(chunk)], chunk) | |
101 | |
102 | |
103 @unittest.skipUnless('ZSTD_SLOW_TESTS' in os.environ, 'ZSTD_SLOW_TESTS not set') | |
104 @make_cffi | |
105 class TestDecompressor_stream_writer_fuzzing(unittest.TestCase): | |
26 @hypothesis.given(original=strategies.sampled_from(random_input_data()), | 106 @hypothesis.given(original=strategies.sampled_from(random_input_data()), |
27 level=strategies.integers(min_value=1, max_value=5), | 107 level=strategies.integers(min_value=1, max_value=5), |
28 write_size=strategies.integers(min_value=1, max_value=8192), | 108 write_size=strategies.integers(min_value=1, max_value=8192), |
29 input_sizes=strategies.streaming( | 109 input_sizes=strategies.data()) |
30 strategies.integers(min_value=1, max_value=4096))) | |
31 def test_write_size_variance(self, original, level, write_size, input_sizes): | 110 def test_write_size_variance(self, original, level, write_size, input_sizes): |
32 input_sizes = iter(input_sizes) | |
33 | |
34 cctx = zstd.ZstdCompressor(level=level) | 111 cctx = zstd.ZstdCompressor(level=level) |
35 frame = cctx.compress(original) | 112 frame = cctx.compress(original) |
36 | 113 |
37 dctx = zstd.ZstdDecompressor() | 114 dctx = zstd.ZstdDecompressor() |
38 source = io.BytesIO(frame) | 115 source = io.BytesIO(frame) |
39 dest = io.BytesIO() | 116 dest = io.BytesIO() |
40 | 117 |
41 with dctx.write_to(dest, write_size=write_size) as decompressor: | 118 with dctx.stream_writer(dest, write_size=write_size) as decompressor: |
42 while True: | 119 while True: |
43 chunk = source.read(next(input_sizes)) | 120 input_size = input_sizes.draw(strategies.integers(1, 4096)) |
121 chunk = source.read(input_size) | |
44 if not chunk: | 122 if not chunk: |
45 break | 123 break |
46 | 124 |
47 decompressor.write(chunk) | 125 decompressor.write(chunk) |
48 | 126 |
72 @unittest.skipUnless('ZSTD_SLOW_TESTS' in os.environ, 'ZSTD_SLOW_TESTS not set') | 150 @unittest.skipUnless('ZSTD_SLOW_TESTS' in os.environ, 'ZSTD_SLOW_TESTS not set') |
73 @make_cffi | 151 @make_cffi |
74 class TestDecompressor_decompressobj_fuzzing(unittest.TestCase): | 152 class TestDecompressor_decompressobj_fuzzing(unittest.TestCase): |
75 @hypothesis.given(original=strategies.sampled_from(random_input_data()), | 153 @hypothesis.given(original=strategies.sampled_from(random_input_data()), |
76 level=strategies.integers(min_value=1, max_value=5), | 154 level=strategies.integers(min_value=1, max_value=5), |
77 chunk_sizes=strategies.streaming( | 155 chunk_sizes=strategies.data()) |
78 strategies.integers(min_value=1, max_value=4096))) | |
79 def test_random_input_sizes(self, original, level, chunk_sizes): | 156 def test_random_input_sizes(self, original, level, chunk_sizes): |
80 chunk_sizes = iter(chunk_sizes) | |
81 | |
82 cctx = zstd.ZstdCompressor(level=level) | 157 cctx = zstd.ZstdCompressor(level=level) |
83 frame = cctx.compress(original) | 158 frame = cctx.compress(original) |
84 | 159 |
85 source = io.BytesIO(frame) | 160 source = io.BytesIO(frame) |
86 | 161 |
87 dctx = zstd.ZstdDecompressor() | 162 dctx = zstd.ZstdDecompressor() |
88 dobj = dctx.decompressobj() | 163 dobj = dctx.decompressobj() |
89 | 164 |
90 chunks = [] | 165 chunks = [] |
91 while True: | 166 while True: |
92 chunk = source.read(next(chunk_sizes)) | 167 chunk_size = chunk_sizes.draw(strategies.integers(1, 4096)) |
168 chunk = source.read(chunk_size) | |
93 if not chunk: | 169 if not chunk: |
94 break | 170 break |
95 | 171 |
96 chunks.append(dobj.decompress(chunk)) | 172 chunks.append(dobj.decompress(chunk)) |
97 | 173 |
98 self.assertEqual(b''.join(chunks), original) | 174 self.assertEqual(b''.join(chunks), original) |
99 | 175 |
100 | 176 @hypothesis.given(original=strategies.sampled_from(random_input_data()), |
101 @unittest.skipUnless('ZSTD_SLOW_TESTS' in os.environ, 'ZSTD_SLOW_TESTS not set') | 177 level=strategies.integers(min_value=1, max_value=5), |
102 @make_cffi | 178 write_size=strategies.integers(min_value=1, |
103 class TestDecompressor_read_from_fuzzing(unittest.TestCase): | 179 max_value=4 * zstd.DECOMPRESSION_RECOMMENDED_OUTPUT_SIZE), |
180 chunk_sizes=strategies.data()) | |
181 def test_random_output_sizes(self, original, level, write_size, chunk_sizes): | |
182 cctx = zstd.ZstdCompressor(level=level) | |
183 frame = cctx.compress(original) | |
184 | |
185 source = io.BytesIO(frame) | |
186 | |
187 dctx = zstd.ZstdDecompressor() | |
188 dobj = dctx.decompressobj(write_size=write_size) | |
189 | |
190 chunks = [] | |
191 while True: | |
192 chunk_size = chunk_sizes.draw(strategies.integers(1, 4096)) | |
193 chunk = source.read(chunk_size) | |
194 if not chunk: | |
195 break | |
196 | |
197 chunks.append(dobj.decompress(chunk)) | |
198 | |
199 self.assertEqual(b''.join(chunks), original) | |
200 | |
201 | |
202 @unittest.skipUnless('ZSTD_SLOW_TESTS' in os.environ, 'ZSTD_SLOW_TESTS not set') | |
203 @make_cffi | |
204 class TestDecompressor_read_to_iter_fuzzing(unittest.TestCase): | |
104 @hypothesis.given(original=strategies.sampled_from(random_input_data()), | 205 @hypothesis.given(original=strategies.sampled_from(random_input_data()), |
105 level=strategies.integers(min_value=1, max_value=5), | 206 level=strategies.integers(min_value=1, max_value=5), |
106 read_size=strategies.integers(min_value=1, max_value=4096), | 207 read_size=strategies.integers(min_value=1, max_value=4096), |
107 write_size=strategies.integers(min_value=1, max_value=4096)) | 208 write_size=strategies.integers(min_value=1, max_value=4096)) |
108 def test_read_write_size_variance(self, original, level, read_size, write_size): | 209 def test_read_write_size_variance(self, original, level, read_size, write_size): |
110 frame = cctx.compress(original) | 211 frame = cctx.compress(original) |
111 | 212 |
112 source = io.BytesIO(frame) | 213 source = io.BytesIO(frame) |
113 | 214 |
114 dctx = zstd.ZstdDecompressor() | 215 dctx = zstd.ZstdDecompressor() |
115 chunks = list(dctx.read_from(source, read_size=read_size, write_size=write_size)) | 216 chunks = list(dctx.read_to_iter(source, read_size=read_size, write_size=write_size)) |
116 | 217 |
117 self.assertEqual(b''.join(chunks), original) | 218 self.assertEqual(b''.join(chunks), original) |
118 | 219 |
119 | 220 |
120 @unittest.skipUnless('ZSTD_SLOW_TESTS' in os.environ, 'ZSTD_SLOW_TESTS not set') | 221 @unittest.skipUnless('ZSTD_SLOW_TESTS' in os.environ, 'ZSTD_SLOW_TESTS not set') |