Add test::fail_count to experimental

This commit is contained in:
Vinnie Falco
2018-05-01 14:19:35 -07:00
parent 59f01a158b
commit e4c2ae6384
18 changed files with 208 additions and 149 deletions

View File

@ -3,6 +3,7 @@ Version 170:
* Add flat_stream to experimental
* Add ssl_stream to experimental
* Add test::error to experimental
* Add test::fail_count to experimental
--------------------------------------------------------------------------------

View File

@ -284,8 +284,10 @@
</row>
</tbody>
</tgroup>
<tgroup cols="1">
<tgroup cols="2">
<colspec colname="a"/>
<colspec colname="b"/>
<colspec colname="c"/>
<thead>
<row>
<entry valign="center" namest="a" nameend="c">
@ -300,6 +302,18 @@
<simplelist type="vert" columns="1">
<member><link linkend="beast.ref.boost__beast__flat_stream">flat_stream</link></member>
<member><link linkend="beast.ref.boost__beast__ssl_stream">ssl_stream</link></member>
<member><link linkend="beast.ref.boost__beast__test__fail_count">test::fail_count</link></member>
</simplelist>
</entry>
<entry valign="top">
<bridgehead renderas="sect3">Functions</bridgehead>
<simplelist type="vert" columns="1">
</simplelist>
</entry>
<entry valign="top">
<bridgehead renderas="sect3">Constants</bridgehead>
<simplelist type="vert" columns="1">
<member><link linkend="beast.ref.boost__beast__test__error">test::error</link></member>
</simplelist>
</entry>
</row>

View File

@ -106,6 +106,7 @@ INPUT = \
$(LIB_DIR)/include/boost/beast/ \
$(LIB_DIR)/include/boost/beast/core \
$(LIB_DIR)/include/boost/beast/experimental/core \
$(LIB_DIR)/include/boost/beast/experimental/test \
$(LIB_DIR)/include/boost/beast/http \
$(LIB_DIR)/include/boost/beast/websocket \
$(LIB_DIR)/include/boost/beast/zlib

View File

@ -250,7 +250,7 @@ public:
This function may be used to configure the peer verification mode used by
the stream. The new mode will override the mode inherited from the context.
@param v A bitmask of peer verification modes. See @ref verify_mode for
@param v A bitmask of peer verification modes. See `verify_mode` for
available values.
@param ec Set to indicate what error occurred, if any.

View File

@ -0,0 +1,65 @@
//
// Copyright (c) 2016-2017 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_FAIL_COUNT_HPP
#define BOOST_BEAST_TEST_FAIL_COUNT_HPP
#include <boost/beast/core/error.hpp>
#include <boost/beast/experimental/test/error.hpp>
#include <boost/throw_exception.hpp>
namespace boost {
namespace beast {
namespace test {
/** A countdown to simulated failure
On the Nth operation, the class will fail with the specified
error code, or the default error code of @ref error::test_failure.
Instances of this class may be used to build objects which
are specifically designed to aid in writing unit tests, for
interfaces which can throw exceptions or return `error_code`
values representing failure.
*/
class fail_count
{
std::size_t n_;
std::size_t i_ = 0;
error_code ec_;
public:
fail_count(fail_count&&) = default;
/** Construct a counter
@param n The 0-based index of the operation to fail on or after
@param ev An optional error code to use when generating a simulated failure
*/
explicit
fail_count(
std::size_t n,
error_code ev = make_error_code(error::test_failure));
/// Throw an exception on the Nth failure
void
fail();
/// Set an error code on the Nth failure
bool
fail(error_code& ec);
};
} // test
} // beast
} // boost
#include <boost/beast/experimental/test/impl/fail_count.ipp>
#endif

View File

@ -0,0 +1,62 @@
//
// Copyright (c) 2016-2017 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_IMPL_FAIL_COUNT_IPP
#define BOOST_BEAST_TEST_IMPL_FAIL_COUNT_IPP
#include <boost/beast/core/error.hpp>
#include <boost/beast/experimental/test/error.hpp>
#include <boost/throw_exception.hpp>
namespace boost {
namespace beast {
namespace test {
inline
fail_count::
fail_count(
std::size_t n,
error_code ev)
: n_(n)
, ec_(ev)
{
}
inline
void
fail_count::
fail()
{
if(i_ < n_)
++i_;
if(i_ == n_)
BOOST_THROW_EXCEPTION(system_error{ec_});
}
inline
bool
fail_count::
fail(error_code& ec)
{
if(i_ < n_)
++i_;
if(i_ == n_)
{
ec = ec_;
return true;
}
ec.assign(0, ec.category());
return false;
}
} // test
} // beast
} // boost
#endif

View File

@ -57,7 +57,7 @@ public:
unit_test::suite& suite_;
boost::asio::io_context& ioc_;
boost::optional<test::stream> ts_;
boost::optional<test::fail_counter> fc_;
boost::optional<test::fail_count> fc_;
boost::optional<buffered_read_stream<
test::stream&, multi_buffer>> brs_;
@ -133,7 +133,7 @@ public:
for(n = 0; n < limit; ++n)
{
test::fail_counter fc{n};
test::fail_count fc{n};
test::stream ts(ioc_, fc, ", world!");
buffered_read_stream<
test::stream&, multi_buffer> srs(ts);
@ -151,7 +151,7 @@ public:
for(n = 0; n < limit; ++n)
{
test::fail_counter fc{n};
test::fail_count fc{n};
test::stream ts(ioc_, fc, ", world!");
buffered_read_stream<
test::stream&, multi_buffer> srs(ts);
@ -170,7 +170,7 @@ public:
for(n = 0; n < limit; ++n)
{
test::fail_counter fc{n};
test::fail_count fc{n};
test::stream ts(ioc_, fc, ", world!");
buffered_read_stream<
test::stream&, multi_buffer> srs(ts);
@ -189,7 +189,7 @@ public:
for(n = 0; n < limit; ++n)
{
test::fail_counter fc{n};
test::fail_count fc{n};
test::stream ts(ioc_, fc, ", world!");
buffered_read_stream<
test::stream&, multi_buffer> srs(ts);

View File

@ -48,7 +48,7 @@ public:
multi_buffer b;
b.commit(buffer_copy(
b.prepare(len), buffer(s, len)));
test::fail_counter fc(n);
test::fail_count fc(n);
test::stream ts{ioc_, fc};
test_parser<isRequest> p(fc);
error_code ec = test::error::test_failure;
@ -64,7 +64,7 @@ public:
multi_buffer b;
b.commit(buffer_copy(
b.prepare(pre), buffer(s, pre)));
test::fail_counter fc(n);
test::fail_count fc(n);
test::stream ts{ioc_, fc,
std::string(s + pre, len - pre)};
test_parser<isRequest> p(fc);
@ -80,7 +80,7 @@ public:
multi_buffer b;
b.commit(buffer_copy(
b.prepare(len), buffer(s, len)));
test::fail_counter fc(n);
test::fail_count fc(n);
test::stream ts{ioc_, fc};
test_parser<isRequest> p(fc);
error_code ec = test::error::test_failure;
@ -95,7 +95,7 @@ public:
multi_buffer b;
b.commit(buffer_copy(
b.prepare(len), buffer(s, len)));
test::fail_counter fc(n);
test::fail_count fc(n);
test::stream ts{ioc_, fc};
test_parser<isRequest> p(fc);
error_code ec = test::error::test_failure;
@ -111,7 +111,7 @@ public:
multi_buffer b;
b.commit(buffer_copy(
b.prepare(pre), buffer(s, pre)));
test::fail_counter fc(n);
test::fail_count fc(n);
test::stream ts(ioc_, fc,
std::string{s + pre, len - pre});
test_parser<isRequest> p(fc);
@ -254,7 +254,7 @@ public:
for(n = 0; n < limit; ++n)
{
test::fail_counter fc{n};
test::fail_count fc{n};
test::stream c{ioc_, fc,
"GET / HTTP/1.1\r\n"
"Host: localhost\r\n"
@ -277,7 +277,7 @@ public:
for(n = 0; n < limit; ++n)
{
test::fail_counter fc{n};
test::fail_count fc{n};
test::stream ts{ioc_, fc,
"GET / HTTP/1.1\r\n"
"Host: localhost\r\n"
@ -296,7 +296,7 @@ public:
for(n = 0; n < limit; ++n)
{
test::fail_counter fc{n};
test::fail_count fc{n};
test::stream c{ioc_, fc,
"GET / HTTP/1.1\r\n"
"Host: localhost\r\n"
@ -315,7 +315,7 @@ public:
for(n = 0; n < limit; ++n)
{
test::fail_counter fc{n};
test::fail_count fc{n};
test::stream c{ioc_, fc,
"GET / HTTP/1.1\r\n"
"Host: localhost\r\n"

View File

@ -11,7 +11,7 @@
#define BOOST_BEAST_HTTP_TEST_PARSER_HPP
#include <boost/beast/http/basic_parser.hpp>
#include <boost/beast/test/fail_counter.hpp>
#include <boost/beast/experimental/test/fail_count.hpp>
#include <string>
#include <unordered_map>
@ -23,7 +23,7 @@ template<bool isRequest>
class test_parser
: public basic_parser<isRequest, test_parser<isRequest>>
{
test::fail_counter* fc_ = nullptr;
test::fail_count* fc_ = nullptr;
public:
using mutable_buffers_type =
@ -48,7 +48,7 @@ public:
test_parser() = default;
explicit
test_parser(test::fail_counter& fc)
test_parser(test::fail_count& fc)
: fc_(&fc)
{
}

View File

@ -203,11 +203,11 @@ public:
friend class writer;
std::string s_;
test::fail_counter& fc_;
test::fail_count& fc_;
public:
explicit
value_type(test::fail_counter& fc)
value_type(test::fail_count& fc)
: fc_(fc)
{
}
@ -353,7 +353,7 @@ public:
for(n = 0; n < limit; ++n)
{
test::fail_counter fc(n);
test::fail_count fc(n);
test::stream ts{ioc_, fc}, tr{ioc_};
ts.connect(tr);
request<fail_body> m(verb::get, "/", 10, fc);
@ -383,7 +383,7 @@ public:
for(n = 0; n < limit; ++n)
{
test::fail_counter fc(n);
test::fail_count fc(n);
test::stream ts{ioc_, fc}, tr{ioc_};
ts.connect(tr);
request<fail_body> m{verb::get, "/", 10, fc};
@ -414,7 +414,7 @@ public:
for(n = 0; n < limit; ++n)
{
test::fail_counter fc(n);
test::fail_count fc(n);
test::stream ts{ioc_, fc}, tr{ioc_};
ts.connect(tr);
request<fail_body> m{verb::get, "/", 10, fc};
@ -445,7 +445,7 @@ public:
for(n = 0; n < limit; ++n)
{
test::fail_counter fc(n);
test::fail_count fc(n);
test::stream ts{ioc_, fc}, tr{ioc_};
ts.connect(tr);
request<fail_body> m{verb::get, "/", 10, fc};
@ -472,7 +472,7 @@ public:
for(n = 0; n < limit; ++n)
{
test::fail_counter fc(n);
test::fail_count fc(n);
test::stream ts{ioc_, fc}, tr{ioc_};
ts.connect(tr);
request<fail_body> m{verb::get, "/", 10, fc};

View File

@ -174,7 +174,7 @@ public:
using boost::asio::buffer;
// suspend on ping
doFailLoop([&](test::fail_counter& fc)
doFailLoop([&](test::fail_count& fc)
{
echo_server es{log};
boost::asio::io_context ioc;
@ -206,7 +206,7 @@ public:
});
// suspend on write
doFailLoop([&](test::fail_counter& fc)
doFailLoop([&](test::fail_count& fc)
{
echo_server es{log};
boost::asio::io_context ioc;
@ -239,7 +239,7 @@ public:
});
// suspend on read ping + message
doFailLoop([&](test::fail_counter& fc)
doFailLoop([&](test::fail_count& fc)
{
echo_server es{log};
boost::asio::io_context ioc;
@ -280,7 +280,7 @@ public:
});
// suspend on read bad message
doFailLoop([&](test::fail_counter& fc)
doFailLoop([&](test::fail_count& fc)
{
echo_server es{log};
boost::asio::io_context ioc;
@ -321,7 +321,7 @@ public:
});
// suspend on read close #1
doFailLoop([&](test::fail_counter& fc)
doFailLoop([&](test::fail_count& fc)
{
echo_server es{log};
boost::asio::io_context ioc;
@ -362,7 +362,7 @@ public:
});
// teardown on received close
doFailLoop([&](test::fail_counter& fc)
doFailLoop([&](test::fail_count& fc)
{
echo_server es{log};
boost::asio::io_context ioc;
@ -406,7 +406,7 @@ public:
});
// check for deadlock
doFailLoop([&](test::fail_counter& fc)
doFailLoop([&](test::fail_count& fc)
{
echo_server es{log};
boost::asio::io_context ioc;
@ -453,7 +453,7 @@ public:
});
// Four-way: close, read, write, ping
doFailLoop([&](test::fail_counter& fc)
doFailLoop([&](test::fail_count& fc)
{
echo_server es{log};
boost::asio::io_context ioc;
@ -501,7 +501,7 @@ public:
});
// Four-way: read, write, ping, close
doFailLoop([&](test::fail_counter& fc)
doFailLoop([&](test::fail_count& fc)
{
echo_server es{log};
boost::asio::io_context ioc;
@ -562,7 +562,7 @@ public:
});
// Four-way: ping, read, write, close
doFailLoop([&](test::fail_counter& fc)
doFailLoop([&](test::fail_count& fc)
{
echo_server es{log};
boost::asio::io_context ioc;

View File

@ -98,7 +98,7 @@ public:
testSuspend()
{
// suspend on write
doFailLoop([&](test::fail_counter& fc)
doFailLoop([&](test::fail_count& fc)
{
echo_server es{log};
boost::asio::io_context ioc;
@ -131,7 +131,7 @@ public:
});
// suspend on close
doFailLoop([&](test::fail_counter& fc)
doFailLoop([&](test::fail_count& fc)
{
echo_server es{log};
boost::asio::io_context ioc;
@ -163,7 +163,7 @@ public:
});
// suspend on read ping + message
doFailLoop([&](test::fail_counter& fc)
doFailLoop([&](test::fail_count& fc)
{
echo_server es{log};
boost::asio::io_context ioc;
@ -204,7 +204,7 @@ public:
});
// suspend on read bad message
doFailLoop([&](test::fail_counter& fc)
doFailLoop([&](test::fail_count& fc)
{
echo_server es{log};
boost::asio::io_context ioc;
@ -246,7 +246,7 @@ public:
});
// suspend on read close #1
doFailLoop([&](test::fail_counter& fc)
doFailLoop([&](test::fail_count& fc)
{
echo_server es{log};
boost::asio::io_context ioc;
@ -287,7 +287,7 @@ public:
});
// suspend on read close #2
doFailLoop([&](test::fail_counter& fc)
doFailLoop([&](test::fail_count& fc)
{
echo_server es{log, kind::async};
boost::asio::io_context ioc;
@ -327,7 +327,7 @@ public:
});
// don't ping on close
doFailLoop([&](test::fail_counter& fc)
doFailLoop([&](test::fail_count& fc)
{
echo_server es{log};
error_code ec;

View File

@ -237,7 +237,7 @@ public:
});
// close
doFailLoop([&](test::fail_counter& fc)
doFailLoop([&](test::fail_count& fc)
{
echo_server es{log, kind::async};
boost::asio::io_context ioc;

View File

@ -29,7 +29,7 @@ public:
using boost::asio::buffer;
#if 1
// suspend on read block
doFailLoop([&](test::fail_counter& fc)
doFailLoop([&](test::fail_count& fc)
{
echo_server es{log};
boost::asio::io_context ioc;
@ -62,7 +62,7 @@ public:
#endif
// suspend on release read block
doFailLoop([&](test::fail_counter& fc)
doFailLoop([&](test::fail_count& fc)
{
//log << "fc.count()==" << fc.count() << std::endl;
echo_server es{log};
@ -95,7 +95,7 @@ public:
#if 1
// suspend on write pong
doFailLoop([&](test::fail_counter& fc)
doFailLoop([&](test::fail_count& fc)
{
echo_server es{log};
boost::asio::io_context ioc;
@ -133,7 +133,7 @@ public:
});
// Ignore ping when closing
doFailLoop([&](test::fail_counter& fc)
doFailLoop([&](test::fail_count& fc)
{
echo_server es{log};
boost::asio::io_context ioc;
@ -181,7 +181,7 @@ public:
});
// See if we are already closing
doFailLoop([&](test::fail_counter& fc)
doFailLoop([&](test::fail_count& fc)
{
echo_server es{log};
boost::asio::io_context ioc;

View File

@ -287,7 +287,7 @@ public:
std::size_t n;
for(n = 0; n < limit; ++n)
{
test::fail_counter fc{n};
test::fail_count fc{n};
try
{
f(fc);
@ -312,7 +312,7 @@ public:
static std::size_t constexpr limit = 200;
doFailLoop(
[&](test::fail_counter& fc)
[&](test::fail_count& fc)
{
test::stream ts{ioc_, fc};
f(ts);
@ -336,7 +336,7 @@ public:
std::size_t n;
for(n = 0; n < limit; ++n)
{
test::fail_counter fc{n};
test::fail_count fc{n};
test::stream ts{ioc_, fc};
ws_type_t<deflateSupported> ws{ts};
ws.set_option(pmd);

View File

@ -274,7 +274,7 @@ public:
using boost::asio::buffer;
// suspend on ping
doFailLoop([&](test::fail_counter& fc)
doFailLoop([&](test::fail_count& fc)
{
echo_server es{log};
boost::asio::io_context ioc;
@ -307,7 +307,7 @@ public:
});
// suspend on close
doFailLoop([&](test::fail_counter& fc)
doFailLoop([&](test::fail_count& fc)
{
echo_server es{log};
boost::asio::io_context ioc;
@ -339,7 +339,7 @@ public:
});
// suspend on read ping + message
doFailLoop([&](test::fail_counter& fc)
doFailLoop([&](test::fail_count& fc)
{
echo_server es{log};
boost::asio::io_context ioc;
@ -381,7 +381,7 @@ public:
});
// suspend on ping: nomask, nofrag
doFailLoop([&](test::fail_counter& fc)
doFailLoop([&](test::fail_count& fc)
{
echo_server es{log, kind::async_client};
boost::asio::io_context ioc;
@ -415,7 +415,7 @@ public:
});
// suspend on ping: nomask, frag
doFailLoop([&](test::fail_counter& fc)
doFailLoop([&](test::fail_count& fc)
{
echo_server es{log, kind::async_client};
boost::asio::io_context ioc;
@ -449,7 +449,7 @@ public:
});
// suspend on ping: mask, nofrag
doFailLoop([&](test::fail_counter& fc)
doFailLoop([&](test::fail_count& fc)
{
echo_server es{log};
error_code ec;
@ -482,7 +482,7 @@ public:
});
// suspend on ping: mask, frag
doFailLoop([&](test::fail_counter& fc)
doFailLoop([&](test::fail_count& fc)
{
echo_server es{log};
error_code ec;
@ -515,7 +515,7 @@ public:
});
// suspend on ping: deflate
doFailLoop([&](test::fail_counter& fc)
doFailLoop([&](test::fail_count& fc)
{
echo_server es{log, kind::async};
boost::asio::io_context ioc;

View File

@ -1,84 +0,0 @@
//
// Copyright (c) 2016-2017 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_FAIL_COUNTER_HPP
#define BOOST_BEAST_TEST_FAIL_COUNTER_HPP
#include <boost/beast/core/error.hpp>
#include <boost/beast/experimental/test/error.hpp>
#include <boost/throw_exception.hpp>
namespace boost {
namespace beast {
namespace test {
/** A countdown to simulated failure.
On the Nth operation, the class will fail with the specified
error code, or the default error code of @ref error::test_failure.
*/
class fail_counter
{
std::size_t n_;
std::size_t i_ = 0;
error_code ec_;
public:
fail_counter(fail_counter&&) = default;
/** Construct a counter.
@param The 0-based index of the operation to fail on or after.
*/
explicit
fail_counter(std::size_t n,
error_code ev = make_error_code(error::test_failure))
: n_(n)
, ec_(ev)
{
}
/// Returns the fail index
std::size_t
count() const
{
return n_;
}
/// Throw an exception on the Nth failure
void
fail()
{
if(i_ < n_)
++i_;
if(i_ == n_)
BOOST_THROW_EXCEPTION(system_error{ec_});
}
/// Set an error code on the Nth failure
bool
fail(error_code& ec)
{
if(i_ < n_)
++i_;
if(i_ == n_)
{
ec = ec_;
return true;
}
ec.assign(0, ec.category());
return false;
}
};
} // test
} // beast
} // boost
#endif

View File

@ -16,7 +16,7 @@
#include <boost/beast/core/string.hpp>
#include <boost/beast/core/type_traits.hpp>
#include <boost/beast/websocket/teardown.hpp>
#include <boost/beast/test/fail_counter.hpp>
#include <boost/beast/experimental/test/fail_count.hpp>
#include <boost/asio/async_result.hpp>
#include <boost/asio/buffer.hpp>
#include <boost/asio/executor_work_guard.hpp>
@ -73,7 +73,7 @@ class stream
std::unique_ptr<read_op> op;
boost::asio::io_context& ioc;
status code = status::ok;
fail_counter* fc = nullptr;
fail_count* fc = nullptr;
std::size_t nread = 0;
std::size_t nwrite = 0;
std::size_t read_max =
@ -89,7 +89,7 @@ class stream
explicit
state(
boost::asio::io_context& ioc_,
fail_counter* fc_)
fail_count* fc_)
: ioc(ioc_)
, fc(fc_)
{
@ -170,7 +170,7 @@ public:
/// Constructor
stream(
boost::asio::io_context& ioc,
fail_counter& fc)
fail_count& fc)
: in_(std::make_shared<state>(ioc, &fc))
{
}
@ -191,7 +191,7 @@ public:
/// Constructor
stream(
boost::asio::io_context& ioc,
fail_counter& fc,
fail_count& fc,
string_view s)
: in_(std::make_shared<state>(ioc, &fc))
{