forked from boostorg/beast
Add trait:
is_completion_token_for
Fixes for
buffered_read_stream
Add tests for
basic_stream
buffered_read_stream
flat_stream
http (all)
websocket (all)
resolves #1920
245 lines
6.9 KiB
C++
245 lines
6.9 KiB
C++
//
|
|
// Copyright (c) 2016-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
|
|
//
|
|
|
|
// Test that header file is self-contained.
|
|
#include <boost/beast/core/flat_stream.hpp>
|
|
|
|
#include "stream_tests.hpp"
|
|
|
|
#include <boost/beast/_experimental/unit_test/suite.hpp>
|
|
#include <boost/beast/_experimental/test/stream.hpp>
|
|
#include <boost/beast/core/role.hpp>
|
|
#include <initializer_list>
|
|
#include <vector>
|
|
#if BOOST_ASIO_HAS_CO_AWAIT
|
|
#include <boost/asio/use_awaitable.hpp>
|
|
#endif
|
|
|
|
namespace boost {
|
|
namespace beast {
|
|
|
|
class flat_stream_test : public unit_test::suite
|
|
{
|
|
public:
|
|
void
|
|
testMembers()
|
|
{
|
|
net::io_context ioc;
|
|
|
|
test_sync_stream<flat_stream<test::stream>>();
|
|
|
|
test_async_stream<flat_stream<test::stream>>();
|
|
|
|
// read/write
|
|
|
|
{
|
|
error_code ec;
|
|
flat_stream<test::stream> s(ioc);
|
|
{
|
|
// VFALCO Hack to make test stream code = eof
|
|
test::stream ts(ioc);
|
|
s.next_layer().connect(ts);
|
|
}
|
|
char buf[1];
|
|
net::mutable_buffer m1 = net::buffer(buf);
|
|
|
|
BEAST_EXPECT(s.read_some(net::mutable_buffer{}) == 0);
|
|
BEAST_EXPECT(s.read_some(net::mutable_buffer{}, ec) == 0);
|
|
BEAST_EXPECTS(! ec, ec.message());
|
|
|
|
try
|
|
{
|
|
s.read_some(m1);
|
|
BEAST_FAIL();
|
|
}
|
|
catch(std::exception const&)
|
|
{
|
|
BEAST_PASS();
|
|
}
|
|
catch(...)
|
|
{
|
|
BEAST_FAIL();
|
|
}
|
|
|
|
BEAST_EXPECT(s.write_some(net::const_buffer{}) == 0);
|
|
BEAST_EXPECT(s.write_some(net::const_buffer{}, ec) == 0);
|
|
BEAST_EXPECTS(! ec, ec.message());
|
|
|
|
try
|
|
{
|
|
s.write_some(m1);
|
|
BEAST_FAIL();
|
|
}
|
|
catch(std::exception const&)
|
|
{
|
|
BEAST_PASS();
|
|
}
|
|
catch(...)
|
|
{
|
|
BEAST_FAIL();
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
// stack_write_some
|
|
|
|
{
|
|
char b[detail::flat_stream_base::max_size];
|
|
std::array<net::const_buffer, 3> bs;
|
|
bs[0] = net::const_buffer(b, 100);
|
|
bs[1] = net::const_buffer(b + 100, 200);
|
|
bs[2] = net::const_buffer(b + 100 + 200, 300);
|
|
BEAST_EXPECT(buffer_bytes(bs) <=
|
|
detail::flat_stream_base::max_stack);
|
|
flat_stream<test::stream> s(ioc);
|
|
error_code ec;
|
|
s.write_some(bs, ec);
|
|
}
|
|
|
|
// write_some
|
|
|
|
{
|
|
char b[detail::flat_stream_base::max_size];
|
|
std::array<net::const_buffer, 2> bs;
|
|
bs[0] = net::const_buffer(b,
|
|
detail::flat_stream_base::max_stack);
|
|
bs[1] = net::const_buffer(b + bs[0].size(), 1024);
|
|
BEAST_EXPECT(buffer_bytes(bs) <=
|
|
detail::flat_stream_base::max_size);
|
|
flat_stream<test::stream> s(ioc);
|
|
error_code ec;
|
|
s.write_some(bs, ec);
|
|
}
|
|
|
|
// async_write_some
|
|
|
|
{
|
|
char b[detail::flat_stream_base::max_size];
|
|
std::array<net::const_buffer, 2> bs;
|
|
bs[0] = net::const_buffer(b,
|
|
detail::flat_stream_base::max_stack);
|
|
bs[1] = net::const_buffer(b + bs[0].size(), 1024);
|
|
BEAST_EXPECT(buffer_bytes(bs) <=
|
|
detail::flat_stream_base::max_size);
|
|
flat_stream<test::stream> s(ioc);
|
|
s.async_write_some(bs,
|
|
[](error_code, std::size_t)
|
|
{
|
|
});
|
|
}
|
|
|
|
// teardown
|
|
|
|
{
|
|
test::stream ts(ioc);
|
|
flat_stream<test::stream> s(ioc);
|
|
ts.connect(s.next_layer());
|
|
error_code ec;
|
|
teardown(role_type::client, s, ec);
|
|
}
|
|
|
|
{
|
|
test::stream ts(ioc);
|
|
flat_stream<test::stream> s(ioc);
|
|
ts.connect(s.next_layer());
|
|
async_teardown(role_type::client, s,
|
|
[](error_code)
|
|
{
|
|
});
|
|
}
|
|
}
|
|
|
|
void
|
|
testSplit()
|
|
{
|
|
auto const check =
|
|
[&](
|
|
std::initializer_list<int> v0,
|
|
std::size_t limit,
|
|
unsigned long count,
|
|
bool copy)
|
|
{
|
|
std::vector<net::const_buffer> v;
|
|
v.reserve(v0.size());
|
|
for(auto const n : v0)
|
|
v.emplace_back("", n);
|
|
auto const result =
|
|
boost::beast::detail::flat_stream_base::flatten(v, limit);
|
|
BEAST_EXPECT(result.size == count);
|
|
BEAST_EXPECT(result.flatten == copy);
|
|
return result;
|
|
};
|
|
check({}, 1, 0, false);
|
|
check({1,2}, 1, 1, false);
|
|
check({1,2}, 2, 1, false);
|
|
check({1,2}, 3, 3, true);
|
|
check({1,2}, 4, 3, true);
|
|
check({1,2,3}, 1, 1, false);
|
|
check({1,2,3}, 2, 1, false);
|
|
check({1,2,3}, 3, 3, true);
|
|
check({1,2,3}, 4, 3, true);
|
|
check({1,2,3}, 7, 6, true);
|
|
check({1,2,3,4}, 3, 3, true);
|
|
}
|
|
|
|
#if BOOST_ASIO_HAS_CO_AWAIT
|
|
void testAwaitableCompiles(
|
|
flat_stream<test::stream>& stream,
|
|
net::mutable_buffer rxbuf,
|
|
net::const_buffer txbuf)
|
|
{
|
|
static_assert(std::is_same_v<
|
|
net::awaitable<std::size_t>, decltype(
|
|
stream.async_read_some(rxbuf, net::use_awaitable))>);
|
|
|
|
static_assert(std::is_same_v<
|
|
net::awaitable<std::size_t>, decltype(
|
|
stream.async_write_some(txbuf, net::use_awaitable))>);
|
|
}
|
|
#endif
|
|
|
|
void
|
|
run() override
|
|
{
|
|
testMembers();
|
|
testSplit();
|
|
#if BOOST_ASIO_HAS_CO_AWAIT
|
|
boost::ignore_unused(&flat_stream_test::testAwaitableCompiles);
|
|
#endif
|
|
}
|
|
};
|
|
|
|
BEAST_DEFINE_TESTSUITE(beast,core,flat_stream);
|
|
|
|
} // beast
|
|
} // boost
|