]> git.proxmox.com Git - ceph.git/blob - ceph/src/Beast/test/zlib/inflate_stream.cpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / Beast / test / zlib / inflate_stream.cpp
1 //
2 // Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7
8 // Test that header file is self-contained.
9 #include <beast/zlib/inflate_stream.hpp>
10
11 #include "ztest.hpp"
12 #include <beast/unit_test/suite.hpp>
13 #include <chrono>
14 #include <random>
15
16 namespace beast {
17 namespace zlib {
18
19 class inflate_stream_test : public beast::unit_test::suite
20 {
21 public:
22 //--------------------------------------------------------------------------
23
24 enum Split
25 {
26 once,
27 half,
28 full
29 };
30
31 class Beast
32 {
33 Split in_;
34 Split check_;
35 Flush flush_;
36
37 public:
38 Beast(Split in, Split check, Flush flush = Flush::sync)
39 : in_(in)
40 , check_(check)
41 , flush_(flush)
42 {
43 }
44
45 void
46 operator()(
47 int window,
48 std::string const& in,
49 std::string const& check,
50 unit_test::suite& suite) const
51 {
52 auto const f =
53 [&](std::size_t i, std::size_t j)
54 {
55 std::string out(check.size(), 0);
56 z_params zs;
57 zs.next_in = in.data();
58 zs.next_out = &out[0];
59 zs.avail_in = i;
60 zs.avail_out = j;
61 inflate_stream is;
62 is.reset(window);
63 bool bi = ! (i < in.size());
64 bool bo = ! (j < check.size());
65 for(;;)
66 {
67 error_code ec;
68 is.write(zs, flush_, ec);
69 if( ec == error::need_buffers ||
70 ec == error::end_of_stream)
71 {
72 out.resize(zs.total_out);
73 suite.expect(out == check, __FILE__, __LINE__);
74 break;
75 }
76 if(ec)
77 {
78 suite.fail(ec.message(), __FILE__, __LINE__);
79 break;
80 }
81 if(zs.avail_in == 0 && ! bi)
82 {
83 bi = true;
84 zs.avail_in = in.size() - i;
85 }
86 if(zs.avail_out == 0 && ! bo)
87 {
88 bo = true;
89 zs.avail_out = check.size() - j;
90 }
91 }
92 };
93
94 std::size_t i0, i1;
95 std::size_t j0, j1;
96
97 switch(in_)
98 {
99 default:
100 case once: i0 = in.size(); i1 = i0; break;
101 case half: i0 = in.size() / 2; i1 = i0; break;
102 case full: i0 = 1; i1 = in.size(); break;
103 }
104
105 switch(check_)
106 {
107 default:
108 case once: j0 = check.size(); j1 = j0; break;
109 case half: j0 = check.size() / 2; j1 = j0; break;
110 case full: j0 = 1; j1 = check.size(); break;
111 }
112
113 for(std::size_t i = i0; i <= i1; ++i)
114 for(std::size_t j = j0; j <= j1; ++j)
115 f(i, j);
116 }
117 };
118
119 class ZLib
120 {
121 Split in_;
122 Split check_;
123 int flush_;
124
125 public:
126 ZLib(Split in, Split check, int flush = Z_SYNC_FLUSH)
127 : in_(in)
128 , check_(check)
129 , flush_(flush)
130 {
131 }
132
133 void
134 operator()(
135 int window,
136 std::string const& in,
137 std::string const& check,
138 unit_test::suite& suite) const
139 {
140 auto const f =
141 [&](std::size_t i, std::size_t j)
142 {
143 int result;
144 std::string out(check.size(), 0);
145 ::z_stream zs;
146 memset(&zs, 0, sizeof(zs));
147 result = inflateInit2(&zs, -window);
148 if(result != Z_OK)
149 {
150 suite.fail("! Z_OK", __FILE__, __LINE__);
151 return;
152 }
153 zs.next_in = (Bytef*)in.data();
154 zs.next_out = (Bytef*)out.data();
155 zs.avail_in = static_cast<uInt>(i);
156 zs.avail_out = static_cast<uInt>(j);
157 bool bi = ! (i < in.size());
158 bool bo = ! (j < check.size());
159 for(;;)
160 {
161 result = inflate(&zs, flush_);
162 if( result == Z_BUF_ERROR ||
163 result == Z_STREAM_END) // per zlib FAQ
164 {
165 out.resize(zs.total_out);
166 suite.expect(out == check, __FILE__, __LINE__);
167 break;
168 }
169 if(result != Z_OK)
170 {
171 suite.fail("! Z_OK", __FILE__, __LINE__);
172 break;
173 }
174 if(zs.avail_in == 0 && ! bi)
175 {
176 bi = true;
177 zs.avail_in = static_cast<uInt>(in.size() - i);
178 }
179 if(zs.avail_out == 0 && ! bo)
180 {
181 bo = true;
182 zs.avail_out = static_cast<uInt>(check.size() - j);
183 }
184 }
185 inflateEnd(&zs);
186 };
187
188 std::size_t i0, i1;
189 std::size_t j0, j1;
190
191 switch(in_)
192 {
193 default:
194 case once: i0 = in.size(); i1 = i0; break;
195 case half: i0 = in.size() / 2; i1 = i0; break;
196 case full: i0 = 1; i1 = in.size(); break;
197 }
198
199 switch(check_)
200 {
201 default:
202 case once: j0 = check.size(); j1 = j0; break;
203 case half: j0 = check.size() / 2; j1 = j0; break;
204 case full: j0 = 1; j1 = check.size(); break;
205 }
206
207 for(std::size_t i = i0; i <= i1; ++i)
208 for(std::size_t j = j0; j <= j1; ++j)
209 f(i, j);
210 }
211 };
212
213 class Matrix
214 {
215 unit_test::suite& suite_;
216
217 int level_[2];
218 int window_[2];
219 int strategy_[2];
220
221 public:
222 explicit
223 Matrix(unit_test::suite& suite)
224 : suite_(suite)
225 {
226 level_[0] = 0;
227 level_[1] = 9;
228 window_[0] = 8;
229 window_[1] = 15;
230 strategy_[0] = 0;
231 strategy_[1] = 4;
232 }
233
234 void
235 level(int from, int to)
236 {
237 level_[0] = from;
238 level_[1] = to;
239 }
240
241 void
242 level(int what)
243 {
244 level(what, what);
245 }
246
247 void
248 window(int from, int to)
249 {
250 window_[0] = from;
251 window_[1] = to;
252 }
253
254 void
255 window(int what)
256 {
257 window(what, what);
258 }
259
260 void
261 strategy(int from, int to)
262 {
263 strategy_[0] = from;
264 strategy_[1] = to;
265 }
266
267 void
268 strategy(int what)
269 {
270 strategy(what, what);
271 }
272
273 template<class F>
274 void
275 operator()(
276 std::string label,
277 F const& f,
278 std::string const& check) const
279 {
280 using namespace std::chrono;
281 using clock_type = steady_clock;
282 auto const when = clock_type::now();
283
284 for(auto level = level_[0];
285 level <= level_[1]; ++level)
286 {
287 for(auto window = window_[0];
288 window <= window_[1]; ++window)
289 {
290 for(auto strategy = strategy_[0];
291 strategy <= strategy_[1]; ++strategy)
292 {
293 z_deflator zd;
294 zd.level(level);
295 zd.windowBits(window);
296 zd.strategy(strategy);
297 auto const in = zd(check);
298 f(window, in, check, suite_);
299 }
300 }
301 }
302 auto const elapsed = clock_type::now() - when;
303 suite_.log <<
304 label << ": " <<
305 duration_cast<
306 milliseconds>(elapsed).count() << "ms\n";
307 suite_.log.flush();
308 }
309 };
310
311 void
312 testInflate()
313 {
314 {
315 Matrix m{*this};
316 std::string check =
317 "{\n \"AutobahnPython/0.6.0\": {\n"
318 " \"1.1.1\": {\n"
319 " \"behavior\": \"OK\",\n"
320 " \"behaviorClose\": \"OK\",\n"
321 " \"duration\": 2,\n"
322 " \"remoteCloseCode\": 1000,\n"
323 " \"reportfile\": \"autobahnpython_0_6_0_case_1_1_1.json\"\n"
324 ;
325 m("1. beast", Beast{half, half}, check);
326 m("1. zlib ", ZLib {half, half}, check);
327 }
328 {
329 Matrix m{*this};
330 auto const check = corpus1(50000);
331 m("2. beast", Beast{half, half}, check);
332 m("2. zlib ", ZLib {half, half}, check);
333 }
334 {
335 Matrix m{*this};
336 auto const check = corpus2(50000);
337 m("3. beast", Beast{half, half}, check);
338 m("3. zlib ", ZLib {half, half}, check);
339 }
340 {
341 Matrix m{*this};
342 auto const check = corpus1(10000);
343 m.level(6);
344 m.window(9);
345 m.strategy(Z_DEFAULT_STRATEGY);
346 m("4. beast", Beast{once, full}, check);
347 m("4. zlib ", ZLib {once, full}, check);
348 }
349 {
350 Matrix m{*this};
351 auto const check = corpus2(10000);
352 m.level(6);
353 m.window(9);
354 m.strategy(Z_DEFAULT_STRATEGY);
355 m("5. beast", Beast{once, full}, check);
356 m("5. zlib ", ZLib {once, full}, check);
357 }
358 {
359 Matrix m{*this};
360 m.level(6);
361 m.window(9);
362 auto const check = corpus1(200);
363 m("6. beast", Beast{full, full}, check);
364 m("6. zlib ", ZLib {full, full}, check);
365 }
366 {
367 Matrix m{*this};
368 m.level(6);
369 m.window(9);
370 auto const check = corpus2(500);
371 m("7. beast", Beast{full, full}, check);
372 m("7. zlib ", ZLib {full, full}, check);
373 }
374 {
375 Matrix m{*this};
376 auto const check = corpus2(10000);
377 m.level(6);
378 m.window(9);
379 m.strategy(Z_DEFAULT_STRATEGY);
380 m("8. beast", Beast{full, once, Flush::block}, check);
381 m("8. zlib ", ZLib {full, once, Z_BLOCK}, check);
382 }
383
384 // VFALCO Fails, but I'm unsure of what the correct
385 // behavior of Z_TREES/Flush::trees is.
386 #if 0
387 {
388 Matrix m{*this};
389 auto const check = corpus2(10000);
390 m.level(6);
391 m.window(9);
392 m.strategy(Z_DEFAULT_STRATEGY);
393 m("9. beast", Beast{full, once, Flush::trees}, check);
394 m("9. zlib ", ZLib {full, once, Z_TREES}, check);
395 }
396 #endif
397 }
398
399 void
400 run() override
401 {
402 log <<
403 "sizeof(inflate_stream) == " <<
404 sizeof(inflate_stream) << std::endl;
405 testInflate();
406 }
407 };
408
409 BEAST_DEFINE_TESTSUITE(inflate_stream,core,beast);
410
411 } // zlib
412 } // beast