Files
boost_beast/include/boost/beast/_experimental/test/tcp.hpp
T

111 lines
2.8 KiB
C++

//
// Copyright (c) 2019 Vinnie Falco (vinnie dot falco at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Official repository: https://github.com/boostorg/beast
//
#ifndef BOOST_BEAST_TEST_TCP_HPP
#define BOOST_BEAST_TEST_TCP_HPP
#include <boost/beast/core/detail/config.hpp>
#include <boost/beast/_experimental/unit_test/suite.hpp>
#include <boost/beast/_experimental/test/handler.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <chrono>
namespace boost {
namespace beast {
namespace test {
/** Run an I/O context.
This function runs and dispatches handlers on the specified
I/O context, until one of the following conditions is true:
@li The I/O context runs out of work.
*/
inline
void
run(net::io_context& ioc)
{
ioc.run();
ioc.restart();
}
/** Run an I/O context for a certain amount of time.
This function runs and dispatches handlers on the specified
I/O context, until one of the following conditions is true:
@li The I/O context runs out of work.
@li No completions occur and the specified amount of time has elapsed.
@param elapsed The maximum amount of time to run for.
*/
template<class Rep, class Period>
void
run_for(
net::io_context& ioc,
std::chrono::duration<Rep, Period> elapsed)
{
ioc.run_for(elapsed);
ioc.restart();
}
/** Connect two TCP/IP sockets together.
*/
inline
bool
connect(
net::ip::tcp::socket& s1,
net::ip::tcp::socket& s2)
{
// Sockets must use the same I/O context
BOOST_ASSERT(
std::addressof(s1.get_executor().context()) ==
std::addressof(s2.get_executor().context()));
auto& ioc = s1.get_executor().context();
s1 = net::ip::tcp::socket(ioc);
s2 = net::ip::tcp::socket(ioc);
try
{
net::ip::tcp::acceptor a(
s1.get_executor().context());
auto ep = net::ip::tcp::endpoint(
net::ip::make_address_v4("127.0.0.1"), 0);
a.open(ep.protocol());
a.set_option(
net::socket_base::reuse_address(true));
a.bind(ep);
a.listen(0);
ep = a.local_endpoint();
a.async_accept(s2, test::success_handler());
s1.async_connect(ep, test::success_handler());
run(ioc);
if(! BEAST_EXPECT(
s1.remote_endpoint() == s2.local_endpoint()))
return false;
if(! BEAST_EXPECT(
s2.remote_endpoint() == s1.local_endpoint()))
return false;
}
catch(std::exception const& e)
{
beast::unit_test::suite::this_suite()->fail(
e.what(), __FILE__, __LINE__);
return false;
}
return true;
}
} // test
} // beast
} // boost
#endif