forked from boostorg/beast
basic_stream subsumes stranded_stream:
* All functionality of stranded_stream is folded into basic_stream * tcp_stream is an alias for basic_stream with tcp * The tests are expanded to produce full coverage * Timeout implementation is simplified
This commit is contained in:
@@ -30,7 +30,7 @@ add_executable (tests-beast-core
|
||||
_detail_variant.cpp
|
||||
_detail_varint.cpp
|
||||
async_op_base.cpp
|
||||
basic_timeout_stream.cpp
|
||||
basic_stream.cpp
|
||||
bind_handler.cpp
|
||||
buffer_size.cpp
|
||||
buffer_traits.cpp
|
||||
@@ -61,11 +61,10 @@ add_executable (tests-beast-core
|
||||
span.cpp
|
||||
static_buffer.cpp
|
||||
static_string.cpp
|
||||
stranded_socket.cpp
|
||||
stream_traits.cpp
|
||||
string.cpp
|
||||
string_param.cpp
|
||||
timeout_stream.cpp
|
||||
tcp_stream.cpp
|
||||
)
|
||||
|
||||
set_property(TARGET tests-beast-core PROPERTY FOLDER "tests")
|
||||
|
||||
@@ -18,7 +18,7 @@ local SOURCES =
|
||||
_detail_variant.cpp
|
||||
_detail_varint.cpp
|
||||
async_op_base.cpp
|
||||
basic_timeout_stream.cpp
|
||||
basic_stream.cpp
|
||||
bind_handler.cpp
|
||||
buffer_size.cpp
|
||||
buffer_traits.cpp
|
||||
@@ -49,11 +49,10 @@ local SOURCES =
|
||||
span.cpp
|
||||
static_buffer.cpp
|
||||
static_string.cpp
|
||||
stranded_socket.cpp
|
||||
stream_traits.cpp
|
||||
string.cpp
|
||||
string_param.cpp
|
||||
timeout_stream.cpp
|
||||
tcp_stream.cpp
|
||||
;
|
||||
|
||||
local RUN_TESTS ;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,519 +0,0 @@
|
||||
//
|
||||
// Copyright (c) 2018 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
|
||||
//
|
||||
|
||||
// Test that header file is self-contained.
|
||||
#include <boost/beast/core/stranded_socket.hpp>
|
||||
|
||||
#include "stream_tests.hpp"
|
||||
|
||||
#include <boost/beast/_experimental/unit_test/suite.hpp>
|
||||
#include <boost/asio/ip/tcp.hpp>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace boost {
|
||||
namespace beast {
|
||||
|
||||
namespace {
|
||||
|
||||
template<class Executor = net::io_context::executor_type>
|
||||
class test_executor
|
||||
{
|
||||
public:
|
||||
// VFALCO These need to be atomic or something
|
||||
struct info
|
||||
{
|
||||
int dispatch = 0;
|
||||
int post = 0;
|
||||
int defer = 0;
|
||||
int work = 0;
|
||||
int total = 0;
|
||||
};
|
||||
|
||||
private:
|
||||
struct state
|
||||
{
|
||||
Executor ex;
|
||||
info info_;
|
||||
|
||||
state(Executor const& ex_)
|
||||
: ex(ex_)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
std::shared_ptr<state> sp_;
|
||||
|
||||
public:
|
||||
test_executor(test_executor const&) = default;
|
||||
test_executor& operator=(test_executor const&) = default;
|
||||
|
||||
explicit
|
||||
test_executor(Executor const& ex)
|
||||
: sp_(std::make_shared<state>(ex))
|
||||
{
|
||||
}
|
||||
|
||||
decltype(sp_->ex.context())
|
||||
context() const noexcept
|
||||
{
|
||||
return sp_->ex.context();
|
||||
}
|
||||
|
||||
info&
|
||||
operator*() noexcept
|
||||
{
|
||||
return sp_->info_;
|
||||
}
|
||||
|
||||
info*
|
||||
operator->() noexcept
|
||||
{
|
||||
return &sp_->info_;
|
||||
}
|
||||
|
||||
void
|
||||
on_work_started() const noexcept
|
||||
{
|
||||
++sp_->info_.work;
|
||||
}
|
||||
|
||||
void
|
||||
on_work_finished() const noexcept
|
||||
{
|
||||
}
|
||||
|
||||
template<class F, class A>
|
||||
void
|
||||
dispatch(F&& f, A const& a)
|
||||
{
|
||||
++sp_->info_.dispatch;
|
||||
++sp_->info_.total;
|
||||
sp_->ex.dispatch(
|
||||
std::forward<F>(f), a);
|
||||
}
|
||||
|
||||
template<class F, class A>
|
||||
void
|
||||
post(F&& f, A const& a)
|
||||
{
|
||||
++sp_->info_.post;
|
||||
++sp_->info_.total;
|
||||
sp_->ex.post(
|
||||
std::forward<F>(f), a);
|
||||
}
|
||||
|
||||
template<class F, class A>
|
||||
void
|
||||
defer(F&& f, A const& a)
|
||||
{
|
||||
++sp_->info_.defer;
|
||||
++sp_->info_.total;
|
||||
sp_->ex.defer(
|
||||
std::forward<F>(f), a);
|
||||
}
|
||||
};
|
||||
|
||||
struct test_handler
|
||||
{
|
||||
int& flags;
|
||||
|
||||
void
|
||||
operator()()
|
||||
{
|
||||
flags |= 1;
|
||||
}
|
||||
|
||||
template<class F>
|
||||
friend
|
||||
void
|
||||
asio_handler_invoke(F&& f, test_handler* p)
|
||||
{
|
||||
p->flags |= 2;
|
||||
std::move(f)();
|
||||
}
|
||||
};
|
||||
|
||||
struct test_acceptor
|
||||
{
|
||||
net::io_context ioc;
|
||||
net::ip::tcp::acceptor a;
|
||||
net::ip::tcp::endpoint ep;
|
||||
|
||||
test_acceptor()
|
||||
: a(ioc)
|
||||
, ep(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(1);
|
||||
ep = a.local_endpoint();
|
||||
a.async_accept(
|
||||
[](error_code, net::ip::tcp::socket)
|
||||
{
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
} // (anon)
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
class stranded_socket_test
|
||||
: public beast::unit_test::suite
|
||||
{
|
||||
public:
|
||||
using tcp = net::ip::tcp;
|
||||
using strand = net::io_context::strand;
|
||||
using executor = net::io_context::executor_type;
|
||||
|
||||
void
|
||||
testStream()
|
||||
{
|
||||
net::io_context ioc;
|
||||
|
||||
// default Executor
|
||||
|
||||
{
|
||||
stranded_socket<tcp> s1{strand(ioc)};
|
||||
stranded_socket<tcp> s2{strand{ioc}};
|
||||
//stranded_socket<tcp> s3{strand{ioc}}; // ambiguous parse
|
||||
}
|
||||
|
||||
// explicit Executor
|
||||
|
||||
{
|
||||
auto ex = ioc.get_executor();
|
||||
stranded_socket<tcp, executor> s1(ioc);
|
||||
stranded_socket<tcp, executor> s2(ex);
|
||||
stranded_socket<tcp, executor> s3(ioc, tcp::v4());
|
||||
stranded_socket<tcp, executor> s4(std::move(s1));
|
||||
s2.socket() = tcp::socket(ioc);
|
||||
BEAST_EXPECT(s1.get_executor() == ex);
|
||||
BEAST_EXPECT(s2.get_executor() == ex);
|
||||
BEAST_EXPECT(s3.get_executor() == ex);
|
||||
BEAST_EXPECT(s4.get_executor() == ex);
|
||||
|
||||
BEAST_EXPECT((! static_cast<
|
||||
stranded_socket<tcp, executor> const&>(
|
||||
s2).socket().is_open()));
|
||||
}
|
||||
|
||||
{
|
||||
auto ex = strand{ioc};
|
||||
stranded_socket<tcp, strand> s1(ex);
|
||||
stranded_socket<tcp, strand> s2(ex, tcp::v4());
|
||||
stranded_socket<tcp, strand> s3(std::move(s1));
|
||||
s2.socket() = tcp::socket(ioc);
|
||||
BEAST_EXPECT(s1.get_executor() == ex);
|
||||
BEAST_EXPECT(s2.get_executor() == ex);
|
||||
BEAST_EXPECT(s3.get_executor() == ex);
|
||||
|
||||
BEAST_EXPECT((! static_cast<
|
||||
stranded_socket<tcp, strand> const&>(
|
||||
s2).socket().is_open()));
|
||||
}
|
||||
|
||||
{
|
||||
test_sync_stream<stranded_socket<tcp, executor>>();
|
||||
test_async_stream<stranded_socket<tcp, executor>>();
|
||||
test_sync_stream<stranded_socket<tcp, strand>>();
|
||||
test_async_stream<stranded_socket<tcp, strand>>();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
testMembers()
|
||||
{
|
||||
net::io_context ioc;
|
||||
|
||||
// connect (member)
|
||||
|
||||
auto const cond =
|
||||
[](error_code, tcp::endpoint)
|
||||
{
|
||||
return true;
|
||||
};
|
||||
|
||||
{
|
||||
stranded_socket<tcp, executor> s(ioc);
|
||||
error_code ec;
|
||||
test_acceptor a;
|
||||
try
|
||||
{
|
||||
s.connect(a.ep);
|
||||
BEAST_PASS();
|
||||
}
|
||||
catch(std::exception const&)
|
||||
{
|
||||
BEAST_FAIL();
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
stranded_socket<tcp, executor> s(ioc);
|
||||
error_code ec;
|
||||
test_acceptor a;
|
||||
s.connect(a.ep, ec);
|
||||
BEAST_EXPECT(! ec);
|
||||
}
|
||||
|
||||
// connect
|
||||
|
||||
{
|
||||
test_acceptor a;
|
||||
std::array<tcp::endpoint, 1> epa;
|
||||
epa[0] = a.ep;
|
||||
stranded_socket<tcp, executor> s(ioc);
|
||||
error_code ec;
|
||||
connect(s, epa);
|
||||
connect(s, epa, ec);
|
||||
}
|
||||
|
||||
{
|
||||
test_acceptor a;
|
||||
std::array<tcp::endpoint, 1> epa;
|
||||
epa[0] = a.ep;
|
||||
stranded_socket<tcp, executor> s(ioc);
|
||||
error_code ec;
|
||||
connect(s, epa, cond);
|
||||
connect(s, epa, cond, ec);
|
||||
}
|
||||
|
||||
{
|
||||
test_acceptor a;
|
||||
std::array<tcp::endpoint, 1> epa;
|
||||
epa[0] = a.ep;
|
||||
stranded_socket<tcp, executor> s(ioc);
|
||||
error_code ec;
|
||||
connect(s, epa.begin(), epa.end());
|
||||
connect(s, epa.begin(), epa.end(), ec);
|
||||
}
|
||||
|
||||
{
|
||||
test_acceptor a;
|
||||
std::array<tcp::endpoint, 1> epa;
|
||||
epa[0] = a.ep;
|
||||
stranded_socket<tcp, executor> s(ioc);
|
||||
error_code ec;
|
||||
connect(s, epa.begin(), epa.end(), cond);
|
||||
connect(s, epa.begin(), epa.end(), cond, ec);
|
||||
}
|
||||
|
||||
// async_connect
|
||||
|
||||
{
|
||||
stranded_socket<tcp, executor> s(ioc);
|
||||
test_acceptor a;
|
||||
error_code ec;
|
||||
s.async_connect(a. ep,
|
||||
[](error_code ec)
|
||||
{
|
||||
BEAST_EXPECT(! ec);
|
||||
});
|
||||
ioc.run();
|
||||
ioc.restart();
|
||||
}
|
||||
|
||||
{
|
||||
std::array<tcp::endpoint, 1> epa;
|
||||
epa[0] = tcp::endpoint(
|
||||
net::ip::make_address_v4("127.0.0.1"), 0);
|
||||
stranded_socket<tcp, executor> s(ioc);
|
||||
async_connect(s, epa,
|
||||
[](error_code, tcp::endpoint)
|
||||
{
|
||||
});
|
||||
}
|
||||
|
||||
{
|
||||
std::array<tcp::endpoint, 1> epa;
|
||||
epa[0] = tcp::endpoint(
|
||||
net::ip::make_address_v4("127.0.0.1"), 0);
|
||||
stranded_socket<tcp, executor> s(ioc);
|
||||
async_connect(s, epa, cond,
|
||||
[](error_code, tcp::endpoint)
|
||||
{
|
||||
});
|
||||
}
|
||||
|
||||
{
|
||||
std::array<tcp::endpoint, 1> epa;
|
||||
epa[0] = tcp::endpoint(
|
||||
net::ip::make_address_v4("127.0.0.1"), 0);
|
||||
using iter_type = decltype(epa)::const_iterator;
|
||||
stranded_socket<tcp, executor> s(ioc);
|
||||
async_connect(s, epa.begin(), epa.end(),
|
||||
[](error_code, iter_type)
|
||||
{
|
||||
});
|
||||
}
|
||||
|
||||
{
|
||||
std::array<tcp::endpoint, 1> epa;
|
||||
epa[0] = tcp::endpoint(
|
||||
net::ip::make_address_v4("127.0.0.1"), 0);
|
||||
using iter_type = decltype(epa)::const_iterator;
|
||||
stranded_socket<tcp, executor> s(ioc);
|
||||
async_connect(s, epa.begin(), epa.end(), cond,
|
||||
[](error_code, iter_type)
|
||||
{
|
||||
});
|
||||
}
|
||||
|
||||
// read/write
|
||||
|
||||
{
|
||||
error_code ec;
|
||||
stranded_socket<tcp, executor> s(ioc, tcp::v4());
|
||||
|
||||
BEAST_EXPECT(s.read_some(net::mutable_buffer{}) == 0);
|
||||
BEAST_EXPECT(s.read_some(net::mutable_buffer{}, ec) == 0);
|
||||
BEAST_EXPECTS(! ec, ec.message());
|
||||
|
||||
BEAST_EXPECT(s.write_some(net::const_buffer{}) == 0);
|
||||
BEAST_EXPECT(s.write_some(net::const_buffer{}, ec) == 0);
|
||||
BEAST_EXPECTS(! ec, ec.message());
|
||||
|
||||
bool invoked;
|
||||
|
||||
invoked = false;
|
||||
s.async_read_some(net::mutable_buffer{},
|
||||
[&](error_code ec, std::size_t)
|
||||
{
|
||||
invoked = true;
|
||||
BEAST_EXPECTS(! ec, ec.message());
|
||||
});
|
||||
ioc.run();
|
||||
ioc.restart();
|
||||
BEAST_EXPECT(invoked);
|
||||
|
||||
invoked = false;
|
||||
s.async_write_some(net::const_buffer{},
|
||||
[&](error_code ec, std::size_t)
|
||||
{
|
||||
invoked = true;
|
||||
BEAST_EXPECTS(! ec, ec.message());
|
||||
});
|
||||
ioc.run();
|
||||
ioc.restart();
|
||||
BEAST_EXPECT(invoked);
|
||||
}
|
||||
|
||||
// stranded
|
||||
|
||||
{
|
||||
error_code ec;
|
||||
stranded_socket<tcp, strand> s(strand(ioc), tcp::v4());
|
||||
|
||||
bool invoked;
|
||||
|
||||
invoked = false;
|
||||
s.async_read_some(net::mutable_buffer{},
|
||||
[&](error_code ec, std::size_t)
|
||||
{
|
||||
invoked = true;
|
||||
BEAST_EXPECTS(! ec, ec.message());
|
||||
});
|
||||
ioc.run();
|
||||
ioc.restart();
|
||||
BEAST_EXPECT(invoked);
|
||||
|
||||
invoked = false;
|
||||
s.async_write_some(net::const_buffer{},
|
||||
[&](error_code ec, std::size_t)
|
||||
{
|
||||
invoked = true;
|
||||
BEAST_EXPECTS(! ec, ec.message());
|
||||
});
|
||||
ioc.run();
|
||||
ioc.restart();
|
||||
BEAST_EXPECT(invoked);
|
||||
}
|
||||
|
||||
// test_executor
|
||||
|
||||
{
|
||||
error_code ec;
|
||||
stranded_socket<tcp, test_executor<>> s(
|
||||
test_executor<>(ioc.get_executor()), tcp::v4());
|
||||
|
||||
bool invoked;
|
||||
|
||||
invoked = false;
|
||||
s.async_read_some(net::mutable_buffer{},
|
||||
[&](error_code ec, std::size_t)
|
||||
{
|
||||
invoked = true;
|
||||
BEAST_EXPECTS(! ec, ec.message());
|
||||
});
|
||||
ioc.run();
|
||||
ioc.restart();
|
||||
BEAST_EXPECT(invoked);
|
||||
BEAST_EXPECT(s.get_executor()->total > 0);
|
||||
s.get_executor()->total = 0;
|
||||
|
||||
invoked = false;
|
||||
s.async_write_some(net::const_buffer{},
|
||||
[&](error_code ec, std::size_t)
|
||||
{
|
||||
invoked = true;
|
||||
BEAST_EXPECTS(! ec, ec.message());
|
||||
});
|
||||
ioc.run();
|
||||
ioc.restart();
|
||||
BEAST_EXPECT(invoked);
|
||||
BEAST_EXPECT(s.get_executor()->total > 0);
|
||||
s.get_executor()->total = 0;
|
||||
}
|
||||
|
||||
// bind_default_executor::asio_handler_invoke
|
||||
|
||||
#if 0
|
||||
// VFALCO This test fails, because it is unclear how
|
||||
// asio_handler_invoke interacts with the wrapper.
|
||||
// Need to ask Chris Kohlhoff about this one.
|
||||
{
|
||||
int flags = 0;
|
||||
net::post(
|
||||
ioc,
|
||||
detail::bind_default_executor(
|
||||
strand(ioc),
|
||||
test_handler{flags}));
|
||||
ioc.run();
|
||||
ioc.restart();
|
||||
BEAST_EXPECT(flags == 3);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void
|
||||
testJavadocs()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void
|
||||
run()
|
||||
{
|
||||
testStream();
|
||||
testJavadocs();
|
||||
testMembers();
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE(beast,core,stranded_socket);
|
||||
|
||||
} // beast
|
||||
} // boost
|
||||
@@ -8,4 +8,4 @@
|
||||
//
|
||||
|
||||
// Test that header file is self-contained.
|
||||
#include <boost/beast/core/timeout_stream.hpp>
|
||||
#include <boost/beast/core/tcp_stream.hpp>
|
||||
Reference in New Issue
Block a user