diff --git a/CHANGELOG.md b/CHANGELOG.md index d661f80d..24b73d1f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 -------------------------------------------------------------------------------- diff --git a/doc/qbk/quickref.xml b/doc/qbk/quickref.xml index 66694d44..7acdb932 100644 --- a/doc/qbk/quickref.xml +++ b/doc/qbk/quickref.xml @@ -284,8 +284,10 @@ - + + + @@ -300,6 +302,18 @@ flat_stream ssl_stream + test::fail_count + + + + Functions + + + + + Constants + + test::error diff --git a/doc/source.dox b/doc/source.dox index a543f8be..52ddb673 100644 --- a/doc/source.dox +++ b/doc/source.dox @@ -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 diff --git a/include/boost/beast/experimental/core/ssl_stream.hpp b/include/boost/beast/experimental/core/ssl_stream.hpp index bc234c42..ca05ba02 100644 --- a/include/boost/beast/experimental/core/ssl_stream.hpp +++ b/include/boost/beast/experimental/core/ssl_stream.hpp @@ -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. diff --git a/include/boost/beast/experimental/test/fail_count.hpp b/include/boost/beast/experimental/test/fail_count.hpp new file mode 100644 index 00000000..98317ad5 --- /dev/null +++ b/include/boost/beast/experimental/test/fail_count.hpp @@ -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 +#include +#include + +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 + +#endif diff --git a/include/boost/beast/experimental/test/impl/fail_count.ipp b/include/boost/beast/experimental/test/impl/fail_count.ipp new file mode 100644 index 00000000..34e4cfa6 --- /dev/null +++ b/include/boost/beast/experimental/test/impl/fail_count.ipp @@ -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 +#include +#include + +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 diff --git a/test/beast/core/buffered_read_stream.cpp b/test/beast/core/buffered_read_stream.cpp index 055ed29c..3d45c45b 100644 --- a/test/beast/core/buffered_read_stream.cpp +++ b/test/beast/core/buffered_read_stream.cpp @@ -57,7 +57,7 @@ public: unit_test::suite& suite_; boost::asio::io_context& ioc_; boost::optional ts_; - boost::optional fc_; + boost::optional fc_; boost::optional> 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); diff --git a/test/beast/http/read.cpp b/test/beast/http/read.cpp index 04e9e504..aea30169 100644 --- a/test/beast/http/read.cpp +++ b/test/beast/http/read.cpp @@ -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 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 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 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 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 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" diff --git a/test/beast/http/test_parser.hpp b/test/beast/http/test_parser.hpp index 76174819..b3e7367a 100644 --- a/test/beast/http/test_parser.hpp +++ b/test/beast/http/test_parser.hpp @@ -11,7 +11,7 @@ #define BOOST_BEAST_HTTP_TEST_PARSER_HPP #include -#include +#include #include #include @@ -23,7 +23,7 @@ template class test_parser : public basic_parser> { - 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) { } diff --git a/test/beast/http/write.cpp b/test/beast/http/write.cpp index d981cac1..e3a07ffc 100644 --- a/test/beast/http/write.cpp +++ b/test/beast/http/write.cpp @@ -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 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 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 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 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 m{verb::get, "/", 10, fc}; diff --git a/test/beast/websocket/close.cpp b/test/beast/websocket/close.cpp index 91d7fa6e..1a8625dc 100644 --- a/test/beast/websocket/close.cpp +++ b/test/beast/websocket/close.cpp @@ -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; diff --git a/test/beast/websocket/ping.cpp b/test/beast/websocket/ping.cpp index 3ba7d15c..9bca3cdc 100644 --- a/test/beast/websocket/ping.cpp +++ b/test/beast/websocket/ping.cpp @@ -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; diff --git a/test/beast/websocket/read1.cpp b/test/beast/websocket/read1.cpp index befdcfd7..97ae9191 100644 --- a/test/beast/websocket/read1.cpp +++ b/test/beast/websocket/read1.cpp @@ -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; diff --git a/test/beast/websocket/read2.cpp b/test/beast/websocket/read2.cpp index 24d5387e..4870033a 100644 --- a/test/beast/websocket/read2.cpp +++ b/test/beast/websocket/read2.cpp @@ -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; diff --git a/test/beast/websocket/test.hpp b/test/beast/websocket/test.hpp index 79dca2ce..ecdb88a0 100644 --- a/test/beast/websocket/test.hpp +++ b/test/beast/websocket/test.hpp @@ -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 ws{ts}; ws.set_option(pmd); diff --git a/test/beast/websocket/write.cpp b/test/beast/websocket/write.cpp index f2ad5071..1a54bfee 100644 --- a/test/beast/websocket/write.cpp +++ b/test/beast/websocket/write.cpp @@ -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; diff --git a/test/extras/include/boost/beast/test/fail_counter.hpp b/test/extras/include/boost/beast/test/fail_counter.hpp deleted file mode 100644 index a783d61c..00000000 --- a/test/extras/include/boost/beast/test/fail_counter.hpp +++ /dev/null @@ -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 -#include -#include - -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 diff --git a/test/extras/include/boost/beast/test/stream.hpp b/test/extras/include/boost/beast/test/stream.hpp index ba2c4b3d..975a3069 100644 --- a/test/extras/include/boost/beast/test/stream.hpp +++ b/test/extras/include/boost/beast/test/stream.hpp @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include #include #include @@ -73,7 +73,7 @@ class stream std::unique_ptr 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(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(ioc, &fc)) {