]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/beast/test/beast/core/buffered_read_stream.cpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / libs / beast / test / beast / core / buffered_read_stream.cpp
1 //
2 // Copyright (c) 2016-2019 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/buffered_read_stream.hpp>
12
13 #include <boost/beast/core/multi_buffer.hpp>
14 #include <boost/beast/_experimental/test/stream.hpp>
15 #include <boost/beast/_experimental/unit_test/suite.hpp>
16 #include <boost/beast/core/bind_handler.hpp>
17 #include <boost/beast/test/yield_to.hpp>
18 #include <boost/asio/buffer.hpp>
19 #include <boost/asio/io_context.hpp>
20 #include <boost/asio/read.hpp>
21 #include <boost/asio/strand.hpp>
22 #include <boost/optional.hpp>
23 #if BOOST_ASIO_HAS_CO_AWAIT
24 #include <boost/asio/use_awaitable.hpp>
25 #endif
26
27 namespace boost {
28 namespace beast {
29
30 class buffered_read_stream_test
31 : public unit_test::suite
32 , public test::enable_yield_to
33 {
34 using self = buffered_read_stream_test;
35
36 public:
37 void testSpecialMembers()
38 {
39 net::io_context ioc;
40 {
41 buffered_read_stream<test::stream, multi_buffer> srs(ioc);
42 buffered_read_stream<test::stream, multi_buffer> srs2(std::move(srs));
43 srs = std::move(srs2);
44 BEAST_EXPECT(&net::query(srs.get_executor(), net::execution::context) == &ioc);
45 BEAST_EXPECT(
46 &net::query(srs.get_executor(), net::execution::context) ==
47 &net::query(srs2.get_executor(), net::execution::context));
48 }
49 {
50 test::stream ts{ioc};
51 buffered_read_stream<test::stream&, multi_buffer> srs(ts);
52 }
53 }
54
55 struct loop : std::enable_shared_from_this<loop>
56 {
57 static std::size_t constexpr limit = 100;
58 std::string s_;
59 std::size_t n_ = 0;
60 std::size_t cap_;
61 unit_test::suite& suite_;
62 net::io_context& ioc_;
63 boost::optional<test::stream> ts_;
64 boost::optional<test::fail_count> fc_;
65 boost::optional<buffered_read_stream<
66 test::stream&, multi_buffer>> brs_;
67
68 loop(
69 unit_test::suite& suite,
70 net::io_context& ioc,
71 std::size_t cap)
72 : cap_(cap)
73 , suite_(suite)
74 , ioc_(ioc)
75 {
76 }
77
78 void
79 run()
80 {
81 do_read();
82 }
83
84 void
85 on_read(error_code ec, std::size_t)
86 {
87 if(! ec)
88 {
89 suite_.expect(s_ ==
90 "Hello, world!", __FILE__, __LINE__);
91 return;
92 }
93 ++n_;
94 if(! suite_.expect(n_ < limit, __FILE__, __LINE__))
95 return;
96 s_.clear();
97 do_read();
98 }
99
100 void
101 do_read()
102 {
103 s_.resize(13);
104 fc_.emplace(n_);
105 ts_.emplace(ioc_, *fc_, ", world!");
106 brs_.emplace(*ts_);
107 brs_->buffer().commit(net::buffer_copy(
108 brs_->buffer().prepare(5), net::buffer("Hello", 5)));
109 net::async_read(*brs_,
110 net::buffer(&s_[0], s_.size()),
111 bind_front_handler(
112 &loop::on_read,
113 shared_from_this()));
114 }
115 };
116
117 void
118 testAsyncLoop()
119 {
120 std::make_shared<loop>(*this, ioc_, 0)->run();
121 std::make_shared<loop>(*this, ioc_, 3)->run();
122 }
123
124 void testRead(yield_context do_yield)
125 {
126 static std::size_t constexpr limit = 100;
127 std::size_t n;
128 std::string s;
129 s.resize(13);
130
131 for(n = 0; n < limit; ++n)
132 {
133 test::fail_count fc{n};
134 test::stream ts(ioc_, fc, ", world!");
135 buffered_read_stream<
136 test::stream&, multi_buffer> srs(ts);
137 srs.buffer().commit(net::buffer_copy(
138 srs.buffer().prepare(5), net::buffer("Hello", 5)));
139 error_code ec = test::error::test_failure;
140 net::read(srs, net::buffer(&s[0], s.size()), ec);
141 if(! ec)
142 {
143 BEAST_EXPECT(s == "Hello, world!");
144 break;
145 }
146 }
147 BEAST_EXPECT(n < limit);
148
149 for(n = 0; n < limit; ++n)
150 {
151 test::fail_count fc{n};
152 test::stream ts(ioc_, fc, ", world!");
153 buffered_read_stream<
154 test::stream&, multi_buffer> srs(ts);
155 srs.capacity(3);
156 srs.buffer().commit(net::buffer_copy(
157 srs.buffer().prepare(5), net::buffer("Hello", 5)));
158 error_code ec = test::error::test_failure;
159 net::read(srs, net::buffer(&s[0], s.size()), ec);
160 if(! ec)
161 {
162 BEAST_EXPECT(s == "Hello, world!");
163 break;
164 }
165 }
166 BEAST_EXPECT(n < limit);
167
168 for(n = 0; n < limit; ++n)
169 {
170 test::fail_count fc{n};
171 test::stream ts(ioc_, fc, ", world!");
172 buffered_read_stream<
173 test::stream&, multi_buffer> srs(ts);
174 srs.buffer().commit(net::buffer_copy(
175 srs.buffer().prepare(5), net::buffer("Hello", 5)));
176 error_code ec = test::error::test_failure;
177 net::async_read(
178 srs, net::buffer(&s[0], s.size()), do_yield[ec]);
179 if(! ec)
180 {
181 BEAST_EXPECT(s == "Hello, world!");
182 break;
183 }
184 }
185 BEAST_EXPECT(n < limit);
186
187 for(n = 0; n < limit; ++n)
188 {
189 test::fail_count fc{n};
190 test::stream ts(ioc_, fc, ", world!");
191 buffered_read_stream<
192 test::stream&, multi_buffer> srs(ts);
193 srs.capacity(3);
194 srs.buffer().commit(net::buffer_copy(
195 srs.buffer().prepare(5), net::buffer("Hello", 5)));
196 error_code ec = test::error::test_failure;
197 net::async_read(
198 srs, net::buffer(&s[0], s.size()), do_yield[ec]);
199 if(! ec)
200 {
201 BEAST_EXPECT(s == "Hello, world!");
202 break;
203 }
204 }
205 BEAST_EXPECT(n < limit);
206 }
207
208 struct copyable_handler
209 {
210 template<class... Args>
211 void
212 operator()(Args&&...) const
213 {
214 }
215 };
216
217 #if BOOST_ASIO_HAS_CO_AWAIT
218 void testAwaitableCompiles(
219 buffered_read_stream<test::stream, flat_buffer>& stream,
220 net::mutable_buffer rxbuf,
221 net::const_buffer txbuf)
222 {
223 static_assert(std::is_same_v<
224 net::awaitable<std::size_t>, decltype(
225 stream.async_read_some(rxbuf, net::use_awaitable))>);
226
227 static_assert(std::is_same_v<
228 net::awaitable<std::size_t>, decltype(
229 stream.async_write_some(txbuf, net::use_awaitable))>);
230 }
231 #endif
232
233 void run() override
234 {
235 testSpecialMembers();
236
237 yield_to([&](yield_context yield)
238 {
239 testRead(yield);
240 });
241 testAsyncLoop();
242
243 #if BOOST_ASIO_HAS_CO_AWAIT
244 boost::ignore_unused(&buffered_read_stream_test::testAwaitableCompiles);
245 #endif
246 }
247 };
248
249 BEAST_DEFINE_TESTSUITE(beast,core,buffered_read_stream);
250
251 } // beast
252 } // boost