5 #include <boost/asio/io_service.hpp> 6 #include <boost/test/unit_test.hpp> 10 void wait_for_connection_close(
11 std::shared_ptr<jb::ehs::request_dispatcher> d,
long last_count) {
12 using namespace std::chrono_literals;
14 for (
int c = 0; c != 100 and last_count == d->get_close_connection(); ++c) {
15 std::this_thread::sleep_for(10ms);
17 BOOST_CHECK_EQUAL(d->get_close_connection(), last_count + 1);
26 boost::asio::ip::tcp::endpoint ep{boost::asio::ip::address_v4(), 0};
29 auto dispatcher = std::make_shared<jb::ehs::request_dispatcher>(
"test");
33 res.insert(
"Content-type",
"text/plain");
38 boost::asio::io_service io_service;
43 std::thread t([&io_service]() { io_service.run(); });
48 boost::asio::io_service io;
50 boost::asio::ip::tcp::socket sock{io};
57 req.set(beast::http::field::host,
"0.0.0.0");
58 req.set(beast::http::field::user_agent,
"acceptor_base");
60 beast::http::write(sock, req);
63 beast::flat_buffer sb{8192};
65 beast::http::read(sock, sb, res);
67 BOOST_CHECK_EQUAL(res.result_int(), 200);
68 BOOST_CHECK_EQUAL(res.version, 11);
69 BOOST_CHECK_EQUAL(res[
"server"],
"test");
70 BOOST_CHECK_EQUAL(res.body,
"OK\n");
74 auto current = dispatcher->get_close_connection();
76 BOOST_TEST_CHECKPOINT(
"closing connection in acceptor_base");
77 wait_for_connection_close(dispatcher, current);
80 io_service.dispatch([&acceptor, &io_service] {
92 using namespace std::chrono_literals;
94 boost::asio::ip::tcp::endpoint ep{boost::asio::ip::address_v4(), 0};
97 auto dispatcher = std::make_shared<jb::ehs::request_dispatcher>(
"test");
101 res.insert(
"Content-type",
"text/plain");
106 boost::asio::io_service io_service;
111 std::thread t([&io_service]() { io_service.run(); });
117 boost::asio::io_service io;
119 boost::asio::ip::tcp::socket sock{io};
120 sock.connect(listen);
125 req.set(
"host",
"0.0.0.0");
126 req.set(
"user-agent",
"acceptor_base");
129 req.set(beast::http::field::content_length,
"1000000");
130 beast::http::write(sock, req);
133 long c = dispatcher->get_close_connection();
140 for (
int i = 0; i != 10 and c == dispatcher->get_close_connection(); ++i) {
141 std::this_thread::sleep_for(10ms);
143 BOOST_CHECK_EQUAL(c, 0);
144 BOOST_CHECK_EQUAL(dispatcher->get_close_connection(), 1);
145 BOOST_CHECK_EQUAL(dispatcher->get_read_error(), 1);
148 io_service.dispatch([&acceptor, &io_service] {
158 void cycle_connection(
159 std::shared_ptr<jb::ehs::request_dispatcher> d, boost::asio::io_service& io,
160 boost::asio::ip::tcp::endpoint
const& ep,
long expected_open_count,
161 long expected_close_count) {
162 using namespace std::chrono_literals;
165 auto open_count = d->get_open_connection();
166 BOOST_CHECK_EQUAL(open_count, expected_open_count);
169 boost::asio::ip::tcp::socket sock{io};
173 for (
int c = 0; c != 10 and open_count == d->get_open_connection(); ++c) {
174 std::this_thread::sleep_for(10ms);
176 BOOST_CHECK_EQUAL(d->get_open_connection(), expected_open_count + 1);
179 auto close_count = d->get_close_connection();
180 BOOST_CHECK_EQUAL(close_count, expected_close_count);
184 BOOST_TEST_CHECKPOINT(
"closing connection in cycle_connection");
185 wait_for_connection_close(d, close_count);
195 boost::asio::ip::tcp::endpoint ep{boost::asio::ip::address_v4(), 0};
198 auto dispatcher = std::make_shared<jb::ehs::request_dispatcher>(
"test");
200 boost::asio::io_service io_service;
204 std::thread t([&io_service]() { io_service.run(); });
210 boost::asio::io_service io;
211 cycle_connection(dispatcher, io, listen, 0, 0);
212 cycle_connection(dispatcher, io, listen, 1, 1);
215 io_service.dispatch([&acceptor, &io_service] {
228 boost::asio::ip::tcp::endpoint ep{boost::asio::ip::address_v4(), 0};
231 auto dispatcher = std::make_shared<jb::ehs::request_dispatcher>(
"test");
233 boost::asio::io_service io_service;
238 std::thread t([&io_service]() { io_service.run(); });
243 boost::asio::io_service io;
245 boost::asio::ip::tcp::socket sock{io};
246 sock.connect(listen);
252 req.set(
"host",
"0.0.0.0");
253 req.set(
"user-agent",
"acceptor_base");
254 beast::http::write(sock, req);
257 beast::flat_buffer sb;
259 beast::http::read(sock, sb, res);
261 BOOST_CHECK_EQUAL(res.result_int(), 404);
262 BOOST_CHECK_EQUAL(res.version, 11);
263 BOOST_CHECK_EQUAL(res[
"server"],
"test");
266 beast::http::write(sock, req);
267 beast::http::read(sock, sb, res);
268 BOOST_CHECK_EQUAL(res.result_int(), 404);
269 BOOST_CHECK_EQUAL(res.version, 11);
270 BOOST_CHECK_EQUAL(res[
"server"],
"test");
274 auto close_count = dispatcher->get_close_connection();
276 BOOST_TEST_CHECKPOINT(
"closing connection in connection_multiple_requests");
277 wait_for_connection_close(dispatcher, close_count);
280 io_service.dispatch([&acceptor, &io_service] {
293 boost::asio::ip::tcp::endpoint ep{boost::asio::ip::address_v4(), 0};
296 auto dispatcher = std::make_shared<jb::ehs::request_dispatcher>(
"test");
298 boost::asio::io_service io_service;
304 BOOST_CHECK_EQUAL(dispatcher->get_accept_error(), 0);
311 using namespace std::chrono_literals;
313 boost::asio::ip::tcp::endpoint ep{boost::asio::ip::address_v4(), 0};
316 auto dispatcher = std::make_shared<jb::ehs::request_dispatcher>(
"test");
318 boost::asio::io_service io_service;
328 std::thread t([&io_service]() { io_service.run(); });
330 for (
int c = 0; c != 100 and 0 == dispatcher->get_accept_closed(); ++c) {
331 std::this_thread::sleep_for(10ms);
333 BOOST_CHECK_EQUAL(dispatcher->get_accept_closed(), 1);
336 io_service.dispatch([&acceptor, &io_service] { io_service.stop(); });
void shutdown()
Gracefully shutdown the acceptor.
beast::http::request< beast::http::string_body > request_type
The request type used for JayBeams Embedded HTTP Servers.
beast::http::response< beast::http::string_body > response_type
The response type used for JayBeams Embedded HTTP Servers.
boost::asio::ip::tcp::endpoint local_endpoint() const
Return the local listening endpoint.
BOOST_AUTO_TEST_CASE(acceptor_base)
Create a control server for the program.