diff --git a/.travis.yml b/.travis.yml index 222d53be..ee470fdf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -43,12 +43,11 @@ matrix: sources: - *base_sources - # GCC 5.0, Release + Valgrind + # GCC 5.0, Valgrind - os: linux compiler: g++-5 env: - - DO_VALGRIND=true - - VARIANT=release + - VARIANT=valgrind - TOOLSET=gcc - COMPILER=g++-5 - CXXSTD=c++11 diff --git a/CHANGELOG.md b/CHANGELOG.md index 2c1b9e52..f37fe12a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ Version 95: * Add test::stream * Tidy up static_buffer braced init * Fix html redirect +* Add valgrind variant, fix false positives -------------------------------------------------------------------------------- diff --git a/Jamfile b/Jamfile index 70f217bd..1320ecad 100644 --- a/Jamfile +++ b/Jamfile @@ -58,6 +58,12 @@ variant coverage : "--coverage" ; +variant valgrind : + release + : + BOOST_USE_VALGRIND=1 + ; + variant ubasan : release diff --git a/build/build-and-test.sh b/build/build-and-test.sh index c06b50d3..de97ecae 100755 --- a/build/build-and-test.sh +++ b/build/build-and-test.sh @@ -119,8 +119,6 @@ function build_bjam () build_bjam -DO_VALGRIND=${DO_VALGRIND:-false} - if [[ $VARIANT == "coverage" ]]; then # for lcov to work effectively, the paths and includes # passed to the compiler should not contain "." or "..". @@ -137,7 +135,7 @@ if [[ $VARIANT == "coverage" ]]; then ~/.local/bin/codecov -X gcov -f lcov.info find "$BOOST_ROOT" -name "*.gcda" | xargs rm -f -elif [[ "$DO_VALGRIND" = true ]]; then +elif [[ $VARIANT == "valgrind" ]]; then run_tests_with_valgrind "$BIN_DIR" fat-tests else diff --git a/test/beast/core/buffered_read_stream.cpp b/test/beast/core/buffered_read_stream.cpp index 5a2571fc..6bcd5b85 100644 --- a/test/beast/core/buffered_read_stream.cpp +++ b/test/beast/core/buffered_read_stream.cpp @@ -15,7 +15,10 @@ #include #include #include -#include +#include +#include +#include +#include namespace boost { namespace beast { @@ -45,6 +48,80 @@ public: } } + struct loop : std::enable_shared_from_this + { + using stream_type = test::fail_stream< + test::string_istream>; + static std::size_t constexpr limit = 100; + std::string s_; + std::size_t n_ = 0; + std::size_t cap_; + unit_test::suite& suite_; + boost::asio::io_service& ios_; + boost::optional fs_; + boost::optional> brs_; + + loop( + unit_test::suite& suite, + boost::asio::io_service& ios, + std::size_t cap) + : cap_(cap) + , suite_(suite) + , ios_(ios) + { + } + + void + run() + { + do_read(); + } + + void + on_read(error_code ec, std::size_t) + { + using boost::asio::buffer; + if(! ec) + { + suite_.expect(s_ == + "Hello, world!", __FILE__, __LINE__); + return; + } + ++n_; + if(! suite_.expect(n_ < limit, __FILE__, __LINE__)) + return; + s_.clear(); + do_read(); + } + + void + do_read() + { + using boost::asio::buffer; + using boost::asio::buffer_copy; + s_.resize(13); + fs_.emplace(n_, ios_, ", world!"); + brs_.emplace(*fs_); + brs_->buffer().commit(buffer_copy( + brs_->buffer().prepare(5), buffer("Hello", 5))); + boost::asio::async_read(*brs_, + buffer(&s_[0], s_.size()), + std::bind( + &loop::on_read, + shared_from_this(), + std::placeholders::_1, + std::placeholders::_2)); + } + }; + + void + testAsyncLoop() + { + std::make_shared(*this, ios_, 0)->run(); + std::make_shared(*this, ios_, 3)->run(); + } + void testRead(yield_context do_yield) { using boost::asio::buffer; @@ -137,6 +214,8 @@ public: yield_to([&](yield_context yield){ testRead(yield);}); + + testAsyncLoop(); } };