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