Files
boost_beast/test/beast/core/flat_stream.cpp
Richard Hodges d016ff52af Fix all async initiating functions with use_awaitable:
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
2020-04-28 20:48:00 +02:00

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