]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/beast/test/beast/core/multi_buffer.cpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / libs / beast / test / beast / core / multi_buffer.cpp
1 //
2 // Copyright (c) 2016-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 // Official repository: https://github.com/boostorg/beast
8 //
9
10 // Test that header file is self-contained.
11 #include <boost/beast/core/multi_buffer.hpp>
12
13 #include "buffer_test.hpp"
14
15 #include <boost/beast/core/ostream.hpp>
16 #include <boost/beast/core/string.hpp>
17 #include <boost/beast/core/type_traits.hpp>
18 #include <boost/beast/test/test_allocator.hpp>
19 #include <boost/beast/unit_test/suite.hpp>
20 #include <boost/asio/buffer.hpp>
21 #include <algorithm>
22 #include <atomic>
23 #include <memory>
24 #include <string>
25
26 namespace boost {
27 namespace beast {
28
29 BOOST_STATIC_ASSERT(
30 boost::asio::is_dynamic_buffer<multi_buffer>::value);
31
32 class multi_buffer_test : public beast::unit_test::suite
33 {
34 public:
35 template<class Alloc1, class Alloc2>
36 static
37 bool
38 eq(basic_multi_buffer<Alloc1> const& mb1,
39 basic_multi_buffer<Alloc2> const& mb2)
40 {
41 return test::to_string(mb1.data()) ==
42 test::to_string(mb2.data());
43 }
44
45 template<class ConstBufferSequence>
46 void
47 expect_size(std::size_t n, ConstBufferSequence const& buffers)
48 {
49 BEAST_EXPECT(test::size_pre(buffers) == n);
50 BEAST_EXPECT(test::size_post(buffers) == n);
51 BEAST_EXPECT(test::size_rev_pre(buffers) == n);
52 BEAST_EXPECT(test::size_rev_post(buffers) == n);
53 }
54
55 template<class U, class V>
56 static
57 void
58 self_assign(U& u, V&& v)
59 {
60 u = std::forward<V>(v);
61 }
62
63 void
64 testMatrix1()
65 {
66 using namespace test;
67 using boost::asio::buffer;
68 std::string const s = "Hello, world";
69 BEAST_EXPECT(s.size() == 12);
70 for(std::size_t i = 1; i < 12; ++i) {
71 for(std::size_t x = 1; x < 4; ++x) {
72 for(std::size_t y = 1; y < 4; ++y) {
73 std::size_t z = s.size() - (x + y);
74 {
75 multi_buffer b;
76 b.commit(buffer_copy(b.prepare(x), buffer(s.data(), x)));
77 b.commit(buffer_copy(b.prepare(y), buffer(s.data()+x, y)));
78 b.commit(buffer_copy(b.prepare(z), buffer(s.data()+x+y, z)));
79 BEAST_EXPECT(to_string(b.data()) == s);
80 {
81 multi_buffer mb2{b};
82 BEAST_EXPECT(eq(b, mb2));
83 }
84 {
85 multi_buffer mb2;
86 mb2 = b;
87 BEAST_EXPECT(eq(b, mb2));
88 }
89 {
90 multi_buffer mb2{std::move(b)};
91 BEAST_EXPECT(to_string(mb2.data()) == s);
92 expect_size(0, b.data());
93 b = std::move(mb2);
94 BEAST_EXPECT(to_string(b.data()) == s);
95 expect_size(0, mb2.data());
96 }
97 self_assign(b, b);
98 BEAST_EXPECT(to_string(b.data()) == s);
99 self_assign(b, std::move(b));
100 BEAST_EXPECT(to_string(b.data()) == s);
101 }
102 }}}
103 }
104
105 void
106 testMatrix2()
107 {
108 using namespace test;
109 using boost::asio::buffer;
110 using boost::asio::buffer_size;
111 std::string const s = "Hello, world";
112 BEAST_EXPECT(s.size() == 12);
113 for(std::size_t i = 1; i < 12; ++i) {
114 for(std::size_t x = 1; x < 4; ++x) {
115 for(std::size_t y = 1; y < 4; ++y) {
116 for(std::size_t t = 1; t < 4; ++ t) {
117 for(std::size_t u = 1; u < 4; ++ u) {
118 std::size_t z = s.size() - (x + y);
119 std::size_t v = s.size() - (t + u);
120 {
121 multi_buffer b;
122 {
123 auto d = b.prepare(z);
124 BEAST_EXPECT(buffer_size(d) == z);
125 }
126 {
127 auto d = b.prepare(0);
128 BEAST_EXPECT(buffer_size(d) == 0);
129 }
130 {
131 auto d = b.prepare(y);
132 BEAST_EXPECT(buffer_size(d) == y);
133 }
134 {
135 auto d = b.prepare(x);
136 BEAST_EXPECT(buffer_size(d) == x);
137 b.commit(buffer_copy(d, buffer(s.data(), x)));
138 }
139 BEAST_EXPECT(b.size() == x);
140 BEAST_EXPECT(buffer_size(b.data()) == b.size());
141 {
142 auto d = b.prepare(x);
143 BEAST_EXPECT(buffer_size(d) == x);
144 }
145 {
146 auto d = b.prepare(0);
147 BEAST_EXPECT(buffer_size(d) == 0);
148 }
149 {
150 auto d = b.prepare(z);
151 BEAST_EXPECT(buffer_size(d) == z);
152 }
153 {
154 auto d = b.prepare(y);
155 BEAST_EXPECT(buffer_size(d) == y);
156 b.commit(buffer_copy(d, buffer(s.data()+x, y)));
157 }
158 b.commit(1);
159 BEAST_EXPECT(b.size() == x + y);
160 BEAST_EXPECT(buffer_size(b.data()) == b.size());
161 {
162 auto d = b.prepare(x);
163 BEAST_EXPECT(buffer_size(d) == x);
164 }
165 {
166 auto d = b.prepare(y);
167 BEAST_EXPECT(buffer_size(d) == y);
168 }
169 {
170 auto d = b.prepare(0);
171 BEAST_EXPECT(buffer_size(d) == 0);
172 }
173 {
174 auto d = b.prepare(z);
175 BEAST_EXPECT(buffer_size(d) == z);
176 b.commit(buffer_copy(d, buffer(s.data()+x+y, z)));
177 }
178 b.commit(2);
179 BEAST_EXPECT(b.size() == x + y + z);
180 BEAST_EXPECT(buffer_size(b.data()) == b.size());
181 BEAST_EXPECT(to_string(b.data()) == s);
182 b.consume(t);
183 {
184 auto d = b.prepare(0);
185 BEAST_EXPECT(buffer_size(d) == 0);
186 }
187 BEAST_EXPECT(to_string(b.data()) == s.substr(t, std::string::npos));
188 b.consume(u);
189 BEAST_EXPECT(to_string(b.data()) == s.substr(t + u, std::string::npos));
190 b.consume(v);
191 BEAST_EXPECT(to_string(b.data()) == "");
192 b.consume(1);
193 {
194 auto d = b.prepare(0);
195 BEAST_EXPECT(buffer_size(d) == 0);
196 }
197 }
198 }}}}}
199 }
200
201 void
202 testIterators()
203 {
204 using boost::asio::buffer_size;
205 multi_buffer b;
206 b.prepare(1);
207 b.commit(1);
208 b.prepare(2);
209 b.commit(2);
210 expect_size(3, b.data());
211 b.prepare(1);
212 expect_size(3, b.prepare(3));
213 b.commit(2);
214 }
215
216 void
217 testMembers()
218 {
219 using namespace test;
220
221 // compare equal
222 using equal_t = test::test_allocator<char,
223 true, true, true, true, true>;
224
225 // compare not equal
226 using unequal_t = test::test_allocator<char,
227 false, true, true, true, true>;
228
229 // construction
230 {
231 {
232 multi_buffer b;
233 BEAST_EXPECT(b.capacity() == 0);
234 }
235 {
236 multi_buffer b{500};
237 BEAST_EXPECT(b.capacity() == 0);
238 BEAST_EXPECT(b.max_size() == 500);
239 }
240 {
241 unequal_t a1;
242 basic_multi_buffer<unequal_t> b{a1};
243 BEAST_EXPECT(b.get_allocator() == a1);
244 BEAST_EXPECT(b.get_allocator() != unequal_t{});
245 }
246 }
247
248 // move construction
249 {
250 {
251 basic_multi_buffer<equal_t> b1{30};
252 BEAST_EXPECT(b1.get_allocator()->nmove == 0);
253 ostream(b1) << "Hello";
254 basic_multi_buffer<equal_t> b2{std::move(b1)};
255 BEAST_EXPECT(b2.get_allocator()->nmove == 1);
256 BEAST_EXPECT(b1.size() == 0);
257 BEAST_EXPECT(b1.capacity() == 0);
258 BEAST_EXPECT(to_string(b2.data()) == "Hello");
259 BEAST_EXPECT(b1.max_size() == b2.max_size());
260 }
261 // allocators equal
262 {
263 basic_multi_buffer<equal_t> b1{30};
264 ostream(b1) << "Hello";
265 equal_t a;
266 basic_multi_buffer<equal_t> b2{std::move(b1), a};
267 BEAST_EXPECT(b1.size() == 0);
268 BEAST_EXPECT(b1.capacity() == 0);
269 BEAST_EXPECT(to_string(b2.data()) == "Hello");
270 BEAST_EXPECT(b1.max_size() == b2.max_size());
271 }
272 {
273 // allocators unequal
274 basic_multi_buffer<unequal_t> b1{30};
275 ostream(b1) << "Hello";
276 unequal_t a;
277 basic_multi_buffer<unequal_t> b2{std::move(b1), a};
278 BEAST_EXPECT(b1.size() == 0);
279 BEAST_EXPECT(b1.capacity() == 0);
280 BEAST_EXPECT(to_string(b2.data()) == "Hello");
281 BEAST_EXPECT(b1.max_size() == b2.max_size());
282 }
283 }
284
285 // copy construction
286 {
287 {
288 basic_multi_buffer<equal_t> b1;
289 ostream(b1) << "Hello";
290 basic_multi_buffer<equal_t> b2{b1};
291 BEAST_EXPECT(b1.get_allocator() == b2.get_allocator());
292 BEAST_EXPECT(to_string(b1.data()) == "Hello");
293 BEAST_EXPECT(to_string(b2.data()) == "Hello");
294 }
295 {
296 basic_multi_buffer<unequal_t> b1;
297 ostream(b1) << "Hello";
298 unequal_t a;
299 basic_multi_buffer<unequal_t> b2(b1, a);
300 BEAST_EXPECT(b1.get_allocator() != b2.get_allocator());
301 BEAST_EXPECT(to_string(b1.data()) == "Hello");
302 BEAST_EXPECT(to_string(b2.data()) == "Hello");
303 }
304 {
305 basic_multi_buffer<equal_t> b1;
306 ostream(b1) << "Hello";
307 basic_multi_buffer<unequal_t> b2(b1);
308 BEAST_EXPECT(to_string(b1.data()) == "Hello");
309 BEAST_EXPECT(to_string(b2.data()) == "Hello");
310 }
311 {
312 basic_multi_buffer<unequal_t> b1;
313 ostream(b1) << "Hello";
314 equal_t a;
315 basic_multi_buffer<equal_t> b2(b1, a);
316 BEAST_EXPECT(b2.get_allocator() == a);
317 BEAST_EXPECT(to_string(b1.data()) == "Hello");
318 BEAST_EXPECT(to_string(b2.data()) == "Hello");
319 }
320 }
321
322 // move assignment
323 {
324 {
325 multi_buffer b1;
326 ostream(b1) << "Hello";
327 multi_buffer b2;
328 b2 = std::move(b1);
329 BEAST_EXPECT(b1.size() == 0);
330 BEAST_EXPECT(b1.capacity() == 0);
331 BEAST_EXPECT(to_string(b2.data()) == "Hello");
332 }
333 {
334 // propagate_on_container_move_assignment : true
335 using pocma_t = test::test_allocator<char,
336 true, true, true, true, true>;
337 basic_multi_buffer<pocma_t> b1;
338 ostream(b1) << "Hello";
339 basic_multi_buffer<pocma_t> b2;
340 b2 = std::move(b1);
341 BEAST_EXPECT(b1.size() == 0);
342 BEAST_EXPECT(to_string(b2.data()) == "Hello");
343 }
344 {
345 // propagate_on_container_move_assignment : false
346 using pocma_t = test::test_allocator<char,
347 true, true, false, true, true>;
348 basic_multi_buffer<pocma_t> b1;
349 ostream(b1) << "Hello";
350 basic_multi_buffer<pocma_t> b2;
351 b2 = std::move(b1);
352 BEAST_EXPECT(b1.size() == 0);
353 BEAST_EXPECT(to_string(b2.data()) == "Hello");
354 }
355 }
356
357 // copy assignment
358 {
359 {
360 multi_buffer b1;
361 ostream(b1) << "Hello";
362 multi_buffer b2;
363 b2 = b1;
364 BEAST_EXPECT(to_string(b1.data()) == "Hello");
365 BEAST_EXPECT(to_string(b2.data()) == "Hello");
366 basic_multi_buffer<equal_t> b3;
367 b3 = b2;
368 BEAST_EXPECT(to_string(b3.data()) == "Hello");
369 }
370 {
371 // propagate_on_container_copy_assignment : true
372 using pocca_t = test::test_allocator<char,
373 true, true, true, true, true>;
374 basic_multi_buffer<pocca_t> b1;
375 ostream(b1) << "Hello";
376 basic_multi_buffer<pocca_t> b2;
377 b2 = b1;
378 BEAST_EXPECT(to_string(b2.data()) == "Hello");
379 }
380 {
381 // propagate_on_container_copy_assignment : false
382 using pocca_t = test::test_allocator<char,
383 true, false, true, true, true>;
384 basic_multi_buffer<pocca_t> b1;
385 ostream(b1) << "Hello";
386 basic_multi_buffer<pocca_t> b2;
387 b2 = b1;
388 BEAST_EXPECT(to_string(b2.data()) == "Hello");
389 }
390 }
391
392 // prepare
393 {
394 {
395 multi_buffer b{100};
396 try
397 {
398 b.prepare(b.max_size() + 1);
399 fail("", __FILE__, __LINE__);
400 }
401 catch(std::length_error const&)
402 {
403 pass();
404 }
405 }
406 {
407 string_view const s = "Hello, world!";
408 multi_buffer b1{64};
409 BEAST_EXPECT(b1.size() == 0);
410 BEAST_EXPECT(b1.max_size() == 64);
411 BEAST_EXPECT(b1.capacity() == 0);
412 ostream(b1) << s;
413 BEAST_EXPECT(to_string(b1.data()) == s);
414 {
415 multi_buffer b2{b1};
416 BEAST_EXPECT(to_string(b2.data()) == s);
417 b2.consume(7);
418 BEAST_EXPECT(to_string(b2.data()) == s.substr(7));
419 }
420 {
421 multi_buffer b2{64};
422 b2 = b1;
423 BEAST_EXPECT(to_string(b2.data()) == s);
424 b2.consume(7);
425 BEAST_EXPECT(to_string(b2.data()) == s.substr(7));
426 }
427 }
428 {
429 multi_buffer b;
430 b.prepare(1000);
431 BEAST_EXPECT(b.capacity() >= 1000);
432 b.commit(1);
433 BEAST_EXPECT(b.size() == 1);
434 BEAST_EXPECT(b.capacity() >= 1000);
435 b.prepare(1000);
436 BEAST_EXPECT(b.size() == 1);
437 BEAST_EXPECT(b.capacity() >= 1000);
438 b.prepare(1500);
439 BEAST_EXPECT(b.capacity() >= 1000);
440 }
441 {
442 multi_buffer b;
443 b.prepare(1000);
444 BEAST_EXPECT(b.capacity() >= 1000);
445 b.commit(1);
446 BEAST_EXPECT(b.capacity() >= 1000);
447 b.prepare(1000);
448 BEAST_EXPECT(b.capacity() >= 1000);
449 b.prepare(2000);
450 BEAST_EXPECT(b.capacity() >= 2000);
451 b.commit(2);
452 }
453 {
454 multi_buffer b;
455 b.prepare(1000);
456 BEAST_EXPECT(b.capacity() >= 1000);
457 b.prepare(2000);
458 BEAST_EXPECT(b.capacity() >= 2000);
459 b.prepare(4000);
460 BEAST_EXPECT(b.capacity() >= 4000);
461 b.prepare(50);
462 BEAST_EXPECT(b.capacity() >= 50);
463 }
464 }
465
466 // commit
467 {
468 multi_buffer b;
469 b.prepare(1000);
470 BEAST_EXPECT(b.capacity() >= 1000);
471 b.commit(1000);
472 BEAST_EXPECT(b.size() == 1000);
473 BEAST_EXPECT(b.capacity() >= 1000);
474 b.consume(1000);
475 BEAST_EXPECT(b.size() == 0);
476 BEAST_EXPECT(b.capacity() == 0);
477 b.prepare(1000);
478 b.commit(650);
479 BEAST_EXPECT(b.size() == 650);
480 BEAST_EXPECT(b.capacity() >= 1000);
481 b.prepare(1000);
482 BEAST_EXPECT(b.capacity() >= 1650);
483 b.commit(100);
484 BEAST_EXPECT(b.size() == 750);
485 BEAST_EXPECT(b.capacity() >= 1000);
486 b.prepare(1000);
487 BEAST_EXPECT(b.capacity() >= 2000);
488 b.commit(500);
489 }
490
491 // consume
492 {
493 multi_buffer b;
494 b.prepare(1000);
495 BEAST_EXPECT(b.capacity() >= 1000);
496 b.commit(1000);
497 BEAST_EXPECT(b.size() == 1000);
498 BEAST_EXPECT(b.capacity() >= 1000);
499 b.prepare(1000);
500 BEAST_EXPECT(b.capacity() >= 2000);
501 b.commit(750);
502 BEAST_EXPECT(b.size() == 1750);
503 b.consume(500);
504 BEAST_EXPECT(b.size() == 1250);
505 b.consume(500);
506 BEAST_EXPECT(b.size() == 750);
507 b.prepare(250);
508 b.consume(750);
509 BEAST_EXPECT(b.size() == 0);
510 b.prepare(1000);
511 b.commit(800);
512 BEAST_EXPECT(b.size() == 800);
513 b.prepare(1000);
514 b.commit(600);
515 BEAST_EXPECT(b.size() == 1400);
516 b.consume(1400);
517 BEAST_EXPECT(b.size() == 0);
518 }
519
520 // swap
521 {
522 {
523 // propagate_on_container_swap : true
524 using pocs_t = test::test_allocator<char,
525 false, true, true, true, true>;
526 pocs_t a1, a2;
527 BEAST_EXPECT(a1 != a2);
528 basic_multi_buffer<pocs_t> b1{a1};
529 ostream(b1) << "Hello";
530 basic_multi_buffer<pocs_t> b2{a2};
531 BEAST_EXPECT(b1.get_allocator() == a1);
532 BEAST_EXPECT(b2.get_allocator() == a2);
533 swap(b1, b2);
534 BEAST_EXPECT(b1.get_allocator() == a2);
535 BEAST_EXPECT(b2.get_allocator() == a1);
536 BEAST_EXPECT(b1.size() == 0);
537 BEAST_EXPECT(to_string(b2.data()) == "Hello");
538 swap(b1, b2);
539 BEAST_EXPECT(b1.get_allocator() == a1);
540 BEAST_EXPECT(b2.get_allocator() == a2);
541 BEAST_EXPECT(to_string(b1.data()) == "Hello");
542 BEAST_EXPECT(b2.size() == 0);
543 }
544 {
545 // propagate_on_container_swap : false
546 using pocs_t = test::test_allocator<char,
547 true, true, true, false, true>;
548 pocs_t a1, a2;
549 BEAST_EXPECT(a1 == a2);
550 BEAST_EXPECT(a1.id() != a2.id());
551 basic_multi_buffer<pocs_t> b1{a1};
552 ostream(b1) << "Hello";
553 basic_multi_buffer<pocs_t> b2{a2};
554 BEAST_EXPECT(b1.get_allocator() == a1);
555 BEAST_EXPECT(b2.get_allocator() == a2);
556 swap(b1, b2);
557 BEAST_EXPECT(b1.get_allocator().id() == a1.id());
558 BEAST_EXPECT(b2.get_allocator().id() == a2.id());
559 BEAST_EXPECT(b1.size() == 0);
560 BEAST_EXPECT(to_string(b2.data()) == "Hello");
561 swap(b1, b2);
562 BEAST_EXPECT(b1.get_allocator().id() == a1.id());
563 BEAST_EXPECT(b2.get_allocator().id() == a2.id());
564 BEAST_EXPECT(to_string(b1.data()) == "Hello");
565 BEAST_EXPECT(b2.size() == 0);
566 }
567 }
568
569 // read_size
570 {
571 multi_buffer b{10};
572 BEAST_EXPECT(read_size(b, 512) == 10);
573 b.prepare(4);
574 b.commit(4);
575 BEAST_EXPECT(read_size(b, 512) == 6);
576 b.consume(2);
577 BEAST_EXPECT(read_size(b, 512) == 8);
578 b.prepare(8);
579 b.commit(8);
580 BEAST_EXPECT(read_size(b, 512) == 0);
581 }
582 }
583
584 void
585 run() override
586 {
587 testMatrix1();
588 testMatrix2();
589 testIterators();
590 testMembers();
591 }
592 };
593
594 BEAST_DEFINE_TESTSUITE(beast,core,multi_buffer);
595
596 } // beast
597 } // boost