]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/beast/test/beast/zlib/inflate_stream.cpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / libs / beast / test / beast / zlib / inflate_stream.cpp
CommitLineData
7c673cae 1//
b32b8144 2// Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
7c673cae
FG
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//
b32b8144
FG
7// Official repository: https://github.com/boostorg/beast
8//
7c673cae
FG
9
10// Test that header file is self-contained.
b32b8144 11#include <boost/beast/zlib/inflate_stream.hpp>
7c673cae 12
b32b8144
FG
13#include <boost/beast/core/string.hpp>
14#include <boost/beast/unit_test/suite.hpp>
7c673cae
FG
15#include <chrono>
16#include <random>
17
b32b8144
FG
18#include "zlib-1.2.11/zlib.h"
19
20namespace boost {
7c673cae
FG
21namespace beast {
22namespace zlib {
23
24class inflate_stream_test : public beast::unit_test::suite
25{
26public:
b32b8144
FG
27 // Lots of repeats, limited char range
28 static
29 std::string
30 corpus1(std::size_t n)
31 {
32 static std::string const alphabet{
33 "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
34 };
35 std::string s;
36 s.reserve(n + 5);
37 std::mt19937 g;
38 std::uniform_int_distribution<std::size_t> d0{
39 0, alphabet.size() - 1};
40 std::uniform_int_distribution<std::size_t> d1{
41 1, 5};
42 while(s.size() < n)
43 {
44 auto const rep = d1(g);
45 auto const ch = alphabet[d0(g)];
46 s.insert(s.end(), rep, ch);
47 }
48 s.resize(n);
49 return s;
50 }
51
52 // Random data
53 static
54 std::string
55 corpus2(std::size_t n)
56 {
57 std::string s;
58 s.reserve(n);
59 std::mt19937 g;
60 std::uniform_int_distribution<std::uint32_t> d0{0, 255};
61 while(n--)
62 s.push_back(static_cast<char>(d0(g)));
63 return s;
64 }
65
66 static
67 std::string
68 compress(
69 string_view const& in,
70 int level, // 0=none, 1..9, -1=default
71 int windowBits, // 9..15
72 int memLevel, // 1..9 (8=default)
73 int strategy) // e.g. Z_DEFAULT_STRATEGY
74 {
75 int result;
76 z_stream zs;
77 memset(&zs, 0, sizeof(zs));
78 result = deflateInit2(
79 &zs,
80 level,
81 Z_DEFLATED,
82 -windowBits,
83 memLevel,
84 strategy);
85 if(result != Z_OK)
86 throw std::logic_error{"deflateInit2 failed"};
87 zs.next_in = (Bytef*)in.data();
88 zs.avail_in = static_cast<uInt>(in.size());
89 std::string out;
90 out.resize(deflateBound(&zs,
91 static_cast<uLong>(in.size())));
92 zs.next_in = (Bytef*)in.data();
93 zs.avail_in = static_cast<uInt>(in.size());
94 zs.next_out = (Bytef*)&out[0];
95 zs.avail_out = static_cast<uInt>(out.size());
96 result = deflate(&zs, Z_FULL_FLUSH);
97 if(result != Z_OK)
98 throw std::logic_error("deflate failed");
99 out.resize(zs.total_out);
100 deflateEnd(&zs);
101 return out;
102 }
103
7c673cae
FG
104 //--------------------------------------------------------------------------
105
106 enum Split
107 {
108 once,
109 half,
110 full
111 };
112
113 class Beast
114 {
115 Split in_;
116 Split check_;
117 Flush flush_;
118
119 public:
120 Beast(Split in, Split check, Flush flush = Flush::sync)
121 : in_(in)
122 , check_(check)
123 , flush_(flush)
124 {
125 }
126
127 void
128 operator()(
129 int window,
130 std::string const& in,
131 std::string const& check,
132 unit_test::suite& suite) const
133 {
134 auto const f =
135 [&](std::size_t i, std::size_t j)
136 {
137 std::string out(check.size(), 0);
138 z_params zs;
139 zs.next_in = in.data();
140 zs.next_out = &out[0];
141 zs.avail_in = i;
142 zs.avail_out = j;
143 inflate_stream is;
144 is.reset(window);
145 bool bi = ! (i < in.size());
146 bool bo = ! (j < check.size());
147 for(;;)
148 {
149 error_code ec;
150 is.write(zs, flush_, ec);
151 if( ec == error::need_buffers ||
152 ec == error::end_of_stream)
153 {
154 out.resize(zs.total_out);
155 suite.expect(out == check, __FILE__, __LINE__);
156 break;
157 }
158 if(ec)
159 {
160 suite.fail(ec.message(), __FILE__, __LINE__);
161 break;
162 }
163 if(zs.avail_in == 0 && ! bi)
164 {
165 bi = true;
166 zs.avail_in = in.size() - i;
167 }
168 if(zs.avail_out == 0 && ! bo)
169 {
170 bo = true;
171 zs.avail_out = check.size() - j;
172 }
173 }
174 };
175
176 std::size_t i0, i1;
177 std::size_t j0, j1;
178
179 switch(in_)
180 {
181 default:
182 case once: i0 = in.size(); i1 = i0; break;
183 case half: i0 = in.size() / 2; i1 = i0; break;
184 case full: i0 = 1; i1 = in.size(); break;
185 }
186
187 switch(check_)
188 {
189 default:
190 case once: j0 = check.size(); j1 = j0; break;
191 case half: j0 = check.size() / 2; j1 = j0; break;
192 case full: j0 = 1; j1 = check.size(); break;
193 }
194
195 for(std::size_t i = i0; i <= i1; ++i)
196 for(std::size_t j = j0; j <= j1; ++j)
197 f(i, j);
198 }
199 };
200
7c673cae
FG
201 class Matrix
202 {
203 unit_test::suite& suite_;
204
205 int level_[2];
206 int window_[2];
207 int strategy_[2];
208
209 public:
210 explicit
211 Matrix(unit_test::suite& suite)
212 : suite_(suite)
213 {
214 level_[0] = 0;
215 level_[1] = 9;
b32b8144 216 window_[0] = 9;
7c673cae
FG
217 window_[1] = 15;
218 strategy_[0] = 0;
219 strategy_[1] = 4;
220 }
221
222 void
223 level(int from, int to)
224 {
225 level_[0] = from;
226 level_[1] = to;
227 }
228
229 void
230 level(int what)
231 {
232 level(what, what);
233 }
234
235 void
236 window(int from, int to)
237 {
238 window_[0] = from;
239 window_[1] = to;
240 }
241
242 void
243 window(int what)
244 {
245 window(what, what);
246 }
247
248 void
249 strategy(int from, int to)
250 {
251 strategy_[0] = from;
252 strategy_[1] = to;
253 }
254
255 void
256 strategy(int what)
257 {
258 strategy(what, what);
259 }
260
261 template<class F>
262 void
263 operator()(
7c673cae
FG
264 F const& f,
265 std::string const& check) const
266 {
7c673cae
FG
267 for(auto level = level_[0];
268 level <= level_[1]; ++level)
269 {
270 for(auto window = window_[0];
271 window <= window_[1]; ++window)
272 {
273 for(auto strategy = strategy_[0];
274 strategy <= strategy_[1]; ++strategy)
b32b8144
FG
275 f(
276 window,
277 compress(check, level, window, 4, strategy),
278 check,
279 suite_);
7c673cae
FG
280 }
281 }
7c673cae
FG
282 }
283 };
284
285 void
286 testInflate()
287 {
288 {
289 Matrix m{*this};
290 std::string check =
291 "{\n \"AutobahnPython/0.6.0\": {\n"
292 " \"1.1.1\": {\n"
293 " \"behavior\": \"OK\",\n"
294 " \"behaviorClose\": \"OK\",\n"
295 " \"duration\": 2,\n"
296 " \"remoteCloseCode\": 1000,\n"
297 " \"reportfile\": \"autobahnpython_0_6_0_case_1_1_1.json\"\n"
298 ;
b32b8144 299 m(Beast{half, half}, check);
7c673cae 300 }
b32b8144 301
7c673cae
FG
302 {
303 Matrix m{*this};
b32b8144
FG
304 auto const check = corpus1(5000);
305 m(Beast{half, half}, check);
7c673cae
FG
306 }
307 {
308 Matrix m{*this};
b32b8144
FG
309 auto const check = corpus2(5000);
310 m(Beast{half, half}, check);
7c673cae
FG
311 }
312 {
313 Matrix m{*this};
b32b8144 314 auto const check = corpus1(1000);
7c673cae
FG
315 m.level(6);
316 m.window(9);
317 m.strategy(Z_DEFAULT_STRATEGY);
b32b8144 318 m(Beast{once, full}, check);
7c673cae
FG
319 }
320 {
321 Matrix m{*this};
b32b8144 322 auto const check = corpus2(1000);
7c673cae
FG
323 m.level(6);
324 m.window(9);
325 m.strategy(Z_DEFAULT_STRATEGY);
b32b8144 326 m(Beast{once, full}, check);
7c673cae
FG
327 }
328 {
329 Matrix m{*this};
330 m.level(6);
331 m.window(9);
332 auto const check = corpus1(200);
b32b8144 333 m(Beast{full, full}, check);
7c673cae
FG
334 }
335 {
336 Matrix m{*this};
337 m.level(6);
338 m.window(9);
339 auto const check = corpus2(500);
b32b8144 340 m(Beast{full, full}, check);
7c673cae
FG
341 }
342 {
343 Matrix m{*this};
b32b8144 344 auto const check = corpus2(1000);
7c673cae
FG
345 m.level(6);
346 m.window(9);
347 m.strategy(Z_DEFAULT_STRATEGY);
b32b8144 348 m(Beast{full, once, Flush::block}, check);
7c673cae
FG
349 }
350
351 // VFALCO Fails, but I'm unsure of what the correct
352 // behavior of Z_TREES/Flush::trees is.
353#if 0
354 {
355 Matrix m{*this};
356 auto const check = corpus2(10000);
357 m.level(6);
358 m.window(9);
359 m.strategy(Z_DEFAULT_STRATEGY);
b32b8144 360 m(Beast{full, once, Flush::trees}, check);
7c673cae
FG
361 }
362#endif
363 }
364
365 void
366 run() override
367 {
368 log <<
369 "sizeof(inflate_stream) == " <<
370 sizeof(inflate_stream) << std::endl;
371 testInflate();
372 }
373};
374
b32b8144 375BEAST_DEFINE_TESTSUITE(beast,zlib,inflate_stream);
7c673cae
FG
376
377} // zlib
378} // beast
b32b8144 379} // boost