mirror of
https://github.com/boostorg/mqtt5.git
synced 2026-01-19 04:22:11 +00:00
Mock timer and resolver in unit tests.
Summary: * Removed all usage of real timers and resolvers in unit tests * Moved most of the tests to test/unit folder * cmake: split boost_mqtt5_tests into boost_mqtt5_unittests and boost_mqtt5_integrationtests Reviewers: ivica Reviewed By: ivica Subscribers: miljen Differential Revision: https://repo.mireo.local/D38186
This commit is contained in:
2
.github/workflows/ci-posix.yml
vendored
2
.github/workflows/ci-posix.yml
vendored
@@ -142,6 +142,7 @@ jobs:
|
||||
CXXFLAGS: ${{ matrix.cxxflags }} -Wall -Wextra
|
||||
LDFLAGS: ${{ matrix.ldflags }}
|
||||
CMAKE_BUILD_PARALLEL_LEVEL: 4
|
||||
DEBIAN_FRONTEND: noninteractive
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
@@ -257,6 +258,7 @@ jobs:
|
||||
env:
|
||||
CXXFLAGS: ${{ matrix.cxxflags }} -Wall -Wextra
|
||||
LDFLAGS: ${{ matrix.ldflags }}
|
||||
DEBIAN_FRONTEND: noninteractive
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
|
||||
1
.github/workflows/coverage.yml
vendored
1
.github/workflows/coverage.yml
vendored
@@ -35,6 +35,7 @@ jobs:
|
||||
CXXFLAGS: ${{ matrix.cxxflags }}
|
||||
LDFLAGS: ${{ matrix.ldflags }}
|
||||
CMAKE_BUILD_PARALLEL_LEVEL: 4
|
||||
DEBIAN_FRONTEND: noninteractive
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
|
||||
@@ -91,7 +91,7 @@ private:
|
||||
if (*_ihandler) {
|
||||
auto h = std::move(*_ihandler);
|
||||
auto ex = asio::get_associated_executor(h);
|
||||
asio::require(ex, asio::execution::blocking.possibly)
|
||||
(asio::require)(ex, asio::execution::blocking.possibly)
|
||||
.execute([h = std::move(h)]() mutable {
|
||||
std::move(h)(asio::error::operation_aborted);
|
||||
});
|
||||
@@ -160,7 +160,7 @@ public:
|
||||
_waiting.pop_front();
|
||||
if (!op) continue;
|
||||
op.get_cancellation_slot().clear();
|
||||
asio::require(_ex, asio::execution::blocking.never)
|
||||
(asio::require)(_ex, asio::execution::blocking.never)
|
||||
.execute([ex = _ex, op = std::move(op)]() mutable {
|
||||
auto opex = asio::get_associated_executor(op, ex);
|
||||
opex.execute(
|
||||
@@ -178,7 +178,7 @@ private:
|
||||
// The operation is equivalent to asio::post(_ex, op) but
|
||||
// for some reason this form of execution is much faster.
|
||||
void execute_op(queued_op_t op) {
|
||||
asio::require(_ex, asio::execution::blocking.never)
|
||||
(asio::require)(_ex, asio::execution::blocking.never)
|
||||
.execute([ex = _ex, op = std::move(op)]() mutable {
|
||||
auto opex = asio::get_associated_executor(op, ex);
|
||||
opex.execute(
|
||||
|
||||
@@ -13,7 +13,9 @@
|
||||
|
||||
#include <boost/mqtt5/detail/any_authenticator.hpp>
|
||||
|
||||
#include <chrono>
|
||||
#include <boost/asio/steady_timer.hpp>
|
||||
#include <boost/asio/ip/tcp.hpp>
|
||||
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
@@ -22,9 +24,6 @@ namespace boost::mqtt5::detail {
|
||||
|
||||
using byte_citer = std::string::const_iterator;
|
||||
|
||||
using time_stamp = std::chrono::time_point<std::chrono::steady_clock>;
|
||||
using duration = time_stamp::duration;
|
||||
|
||||
struct credentials {
|
||||
std::string client_id;
|
||||
std::optional<std::string> username;
|
||||
@@ -112,6 +111,16 @@ constexpr unsigned terminal = 0b100;
|
||||
|
||||
};
|
||||
|
||||
#ifdef BOOST_MQTT5_UNIT_TESTS
|
||||
using timer_type = asio::basic_waitable_timer<BOOST_MQTT5_DETAIL_CLOCK_TYPE>;
|
||||
using resolver_type = BOOST_MQTT5_DETAIL_RESOLVER_TYPE;
|
||||
#else
|
||||
using timer_type = asio::steady_timer;
|
||||
using resolver_type = asio::ip::tcp::resolver;
|
||||
#endif
|
||||
|
||||
using duration = timer_type::duration;
|
||||
|
||||
} // end namespace boost::mqtt5::detail
|
||||
|
||||
#endif // !BOOST_MQTT5_INTERNAL_TYPES_HPP
|
||||
|
||||
@@ -204,8 +204,8 @@ private:
|
||||
duration compute_read_timeout() const {
|
||||
auto negotiated_ka = _svc.negotiated_keep_alive();
|
||||
return negotiated_ka ?
|
||||
std::chrono::milliseconds(3 * negotiated_ka * 1000 / 2) :
|
||||
duration((std::numeric_limits<duration::rep>::max)());
|
||||
duration(std::chrono::milliseconds(3 * negotiated_ka * 1000 / 2)) :
|
||||
(duration::max)();
|
||||
}
|
||||
|
||||
static bool valid_header(uint8_t control_byte) {
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
|
||||
#include <boost/asio/async_result.hpp>
|
||||
#include <boost/asio/ip/tcp.hpp>
|
||||
#include <boost/asio/steady_timer.hpp>
|
||||
#include <boost/system/error_code.hpp>
|
||||
|
||||
#include <cstdint>
|
||||
@@ -40,7 +39,7 @@ template <
|
||||
>
|
||||
class autoconnect_stream {
|
||||
public:
|
||||
using self_type = autoconnect_stream<StreamType, StreamContext, LoggerType>;
|
||||
using self_type = autoconnect_stream;
|
||||
using stream_type = StreamType;
|
||||
using stream_context_type = StreamContext;
|
||||
using logger_type = LoggerType;
|
||||
@@ -50,7 +49,7 @@ private:
|
||||
|
||||
executor_type _stream_executor;
|
||||
async_mutex _conn_mtx;
|
||||
asio::steady_timer _read_timer, _connect_timer;
|
||||
timer_type _read_timer, _connect_timer;
|
||||
endpoints<logger_type> _endpoints;
|
||||
|
||||
stream_ptr _stream_ptr;
|
||||
|
||||
@@ -266,8 +266,8 @@ private:
|
||||
|
||||
receive_channel _rec_channel;
|
||||
|
||||
asio::steady_timer _ping_timer;
|
||||
asio::steady_timer _sentry_timer;
|
||||
timer_type _ping_timer;
|
||||
timer_type _sentry_timer;
|
||||
|
||||
client_service(const client_service& other) :
|
||||
_executor(other._executor),
|
||||
|
||||
@@ -10,8 +10,6 @@
|
||||
|
||||
#include <boost/mqtt5/types.hpp>
|
||||
|
||||
#include <boost/mqtt5/detail/internal_types.hpp>
|
||||
|
||||
#include <boost/mqtt5/impl/codecs/base_decoders.hpp>
|
||||
|
||||
#include <cstdint>
|
||||
@@ -22,7 +20,7 @@
|
||||
|
||||
namespace boost::mqtt5::decoders {
|
||||
|
||||
using byte_citer = detail::byte_citer;
|
||||
using byte_citer = std::string::const_iterator;
|
||||
|
||||
using fixed_header = std::tuple<
|
||||
uint8_t, // control byte
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
#include <boost/asio/error.hpp>
|
||||
#include <boost/asio/experimental/parallel_group.hpp>
|
||||
#include <boost/asio/prepend.hpp>
|
||||
#include <boost/asio/steady_timer.hpp>
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
@@ -185,7 +184,7 @@ class terminal_disconnect_op {
|
||||
static constexpr uint8_t seconds = 5;
|
||||
|
||||
std::shared_ptr<client_service> _svc_ptr;
|
||||
std::unique_ptr<asio::steady_timer> _timer;
|
||||
std::unique_ptr<timer_type> _timer;
|
||||
|
||||
using handler_type = Handler;
|
||||
handler_type _handler;
|
||||
@@ -196,7 +195,7 @@ public:
|
||||
Handler&& handler
|
||||
) :
|
||||
_svc_ptr(std::move(svc_ptr)),
|
||||
_timer(new asio::steady_timer(_svc_ptr->get_executor())),
|
||||
_timer(new timer_type(_svc_ptr->get_executor())),
|
||||
_handler(std::move(handler))
|
||||
{}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#ifndef BOOST_MQTT5_ENDPOINTS_HPP
|
||||
#define BOOST_MQTT5_ENDPOINTS_HPP
|
||||
|
||||
#include <boost/mqtt5/detail/internal_types.hpp>
|
||||
#include <boost/mqtt5/detail/log_invoke.hpp>
|
||||
#include <boost/mqtt5/detail/internal_types.hpp>
|
||||
|
||||
@@ -141,8 +142,8 @@ template <typename LoggerType>
|
||||
class endpoints {
|
||||
using logger_type = LoggerType;
|
||||
|
||||
asio::ip::tcp::resolver _resolver;
|
||||
asio::steady_timer& _connect_timer;
|
||||
resolver_type _resolver;
|
||||
timer_type& _connect_timer;
|
||||
|
||||
std::vector<authority_path> _servers;
|
||||
|
||||
@@ -156,7 +157,7 @@ class endpoints {
|
||||
public:
|
||||
template <typename Executor>
|
||||
endpoints(
|
||||
Executor ex, asio::steady_timer& timer,
|
||||
Executor ex, timer_type& timer,
|
||||
log_invoke<logger_type>& log
|
||||
) :
|
||||
_resolver(std::move(ex)), _connect_timer(timer),
|
||||
|
||||
@@ -96,7 +96,7 @@ private:
|
||||
auto negotiated_ka = _svc_ptr->negotiated_keep_alive();
|
||||
return negotiated_ka ?
|
||||
std::chrono::seconds(negotiated_ka) :
|
||||
duration((std::numeric_limits<duration::rep>::max)());
|
||||
(duration::max)();
|
||||
}
|
||||
|
||||
void complete() {
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <boost/mqtt5/types.hpp>
|
||||
|
||||
#include <boost/mqtt5/detail/async_traits.hpp>
|
||||
#include <boost/mqtt5/detail/internal_types.hpp>
|
||||
|
||||
#include <boost/mqtt5/impl/connect_op.hpp>
|
||||
|
||||
|
||||
@@ -10,36 +10,48 @@ project(boost_mqtt5_tests CXX)
|
||||
file(GLOB integration_tests "integration/*.cpp")
|
||||
file(GLOB unit_tests "unit/*.cpp")
|
||||
|
||||
add_executable(boost_mqtt5-tests src/run_tests.cpp ${integration_tests} ${unit_tests})
|
||||
|
||||
target_include_directories(boost_mqtt5-tests PRIVATE include)
|
||||
target_compile_definitions(boost_mqtt5-tests PRIVATE BOOST_TEST_NO_MAIN=1)
|
||||
add_executable(boost_mqtt5_unittests src/run_tests.cpp ${unit_tests})
|
||||
add_executable(boost_mqtt5_integrationtests src/run_tests.cpp ${integration_tests})
|
||||
|
||||
if(BOOST_MQTT5_MAIN_PROJECT)
|
||||
find_package(OpenSSL REQUIRED)
|
||||
target_compile_definitions(boost_mqtt5-tests PRIVATE BOOST_MQTT5_EXTRA_DEPS=1)
|
||||
|
||||
target_link_libraries(
|
||||
boost_mqtt5-tests PRIVATE
|
||||
Boost::mqtt5
|
||||
OpenSSL::SSL
|
||||
)
|
||||
else()
|
||||
target_link_libraries(
|
||||
boost_mqtt5-tests PRIVATE
|
||||
Boost::mqtt5
|
||||
Boost::included_unit_test_framework
|
||||
)
|
||||
|
||||
# Follow the Boost convention: don't build test targets by default,
|
||||
# and only when explicitly requested by building target tests
|
||||
set_target_properties(boost_mqtt5-tests PROPERTIES EXCLUDE_FROM_ALL ON)
|
||||
add_dependencies(tests boost_mqtt5-tests)
|
||||
endif()
|
||||
|
||||
target_compile_definitions(boost_mqtt5_unittests PRIVATE BOOST_MQTT5_UNIT_TESTS=1)
|
||||
|
||||
foreach(BOOST_MQTT5_TEST boost_mqtt5_unittests boost_mqtt5_integrationtests)
|
||||
target_include_directories(${BOOST_MQTT5_TEST} PRIVATE include)
|
||||
target_compile_definitions(${BOOST_MQTT5_TEST} PRIVATE BOOST_TEST_NO_MAIN=1)
|
||||
|
||||
if(BOOST_MQTT5_MAIN_PROJECT)
|
||||
target_compile_definitions(${BOOST_MQTT5_TEST} PRIVATE BOOST_MQTT5_EXTRA_DEPS=1)
|
||||
|
||||
target_link_libraries(
|
||||
${BOOST_MQTT5_TEST} PRIVATE
|
||||
Boost::mqtt5
|
||||
OpenSSL::SSL
|
||||
)
|
||||
else()
|
||||
target_link_libraries(
|
||||
${BOOST_MQTT5_TEST} PRIVATE
|
||||
Boost::mqtt5
|
||||
Boost::included_unit_test_framework
|
||||
)
|
||||
|
||||
# Follow the Boost convention: don't build test targets by default,
|
||||
# and only when explicitly requested by building target tests
|
||||
set_target_properties(${BOOST_MQTT5_TEST} PROPERTIES EXCLUDE_FROM_ALL ON)
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
include(CTest)
|
||||
add_test(NAME boost_mqtt5-tests COMMAND boost_mqtt5-tests)
|
||||
add_test(NAME boost_mqtt5_unittests COMMAND boost_mqtt5_unittests)
|
||||
|
||||
if (BOOST_MQTT5_PUBLIC_BROKER_TESTS)
|
||||
set_property(TEST boost_mqtt5-tests PROPERTY ENVIRONMENT "BOOST_MQTT5_PUBLIC_BROKER_TESTS=1")
|
||||
add_dependencies(tests boost_mqtt5_unittests)
|
||||
|
||||
if (BOOST_MQTT5_MAIN_PROJECT)
|
||||
add_test(NAME boost_mqtt5_integrationtests COMMAND boost_mqtt5_integrationtests)
|
||||
if (BOOST_MQTT5_PUBLIC_BROKER_TESTS)
|
||||
set_property(TEST boost_mqtt5_integrationtests PROPERTY ENVIRONMENT "BOOST_MQTT5_PUBLIC_BROKER_TESTS=1")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -15,6 +15,7 @@ local requirements =
|
||||
<define>BOOST_ALL_NO_LIB=1
|
||||
<define>BOOST_ASIO_NO_DEPRECATED=1
|
||||
<define>BOOST_TEST_NO_MAIN=1
|
||||
<define>BOOST_MQTT5_UNIT_TESTS=1
|
||||
<toolset>msvc:<cxxflags>"/bigobj"
|
||||
<target-os>windows:<define>_WIN32_WINNT=0x0601
|
||||
<library>/boost/test//included
|
||||
@@ -25,5 +26,5 @@ run
|
||||
[ glob "unit/*.cpp" ]
|
||||
: requirements $(requirements)
|
||||
<include>include
|
||||
: target-name boost_mqtt5_tests
|
||||
: target-name boost_mqtt5_unittests
|
||||
;
|
||||
|
||||
@@ -9,116 +9,64 @@
|
||||
#define BOOST_MQTT5_TEST_DELAYED_OP_HPP
|
||||
|
||||
#include <boost/asio/append.hpp>
|
||||
#include <boost/asio/bind_cancellation_slot.hpp>
|
||||
#include <boost/asio/cancellation_signal.hpp>
|
||||
#include <boost/asio/consign.hpp>
|
||||
#include <boost/asio/dispatch.hpp>
|
||||
#include <boost/asio/prepend.hpp>
|
||||
#include <boost/asio/recycling_allocator.hpp>
|
||||
#include <boost/asio/steady_timer.hpp>
|
||||
#include <boost/type_traits/remove_cv_ref.hpp>
|
||||
|
||||
#include <chrono>
|
||||
|
||||
#include "test_timer.hpp"
|
||||
|
||||
namespace boost::mqtt5::test {
|
||||
|
||||
namespace asio = boost::asio;
|
||||
|
||||
using error_code = boost::system::error_code;
|
||||
using time_stamp = std::chrono::time_point<std::chrono::steady_clock>;
|
||||
using time_stamp = clock::time_point;
|
||||
using duration = time_stamp::duration;
|
||||
using rep = duration::rep;
|
||||
|
||||
template <typename ...BoundArgs>
|
||||
class delayed_op {
|
||||
struct on_timer {};
|
||||
template <typename... BoundArgs>
|
||||
struct delayed_op {
|
||||
duration delay;
|
||||
std::tuple<BoundArgs...> args;
|
||||
|
||||
std::unique_ptr<asio::steady_timer> _timer;
|
||||
time_stamp::duration _delay;
|
||||
asio::cancellation_slot _cancel_slot;
|
||||
|
||||
std::tuple<BoundArgs...> _args;
|
||||
|
||||
public:
|
||||
template <typename Executor, typename ...Args>
|
||||
delayed_op(
|
||||
const Executor& ex, time_stamp::duration delay, Args&& ...args
|
||||
) :
|
||||
_timer(new asio::steady_timer(ex)), _delay(delay),
|
||||
_args(std::move(args)...)
|
||||
delayed_op(duration delay, BoundArgs... args)
|
||||
: delay(delay), args(std::move(args)...)
|
||||
{}
|
||||
|
||||
delayed_op(delayed_op&&) = default;
|
||||
delayed_op(const delayed_op&) = delete;
|
||||
|
||||
delayed_op& operator=(delayed_op&&) = default;
|
||||
delayed_op& operator=(const delayed_op&) = delete;
|
||||
|
||||
using allocator_type = asio::recycling_allocator<void>;
|
||||
allocator_type get_allocator() const noexcept {
|
||||
return allocator_type {};
|
||||
}
|
||||
|
||||
using cancellation_slot_type = asio::cancellation_slot;
|
||||
asio::cancellation_slot get_cancellation_slot() const noexcept {
|
||||
return _cancel_slot;
|
||||
}
|
||||
|
||||
using executor_type = asio::steady_timer::executor_type;
|
||||
executor_type get_executor() const noexcept {
|
||||
return _timer->get_executor();
|
||||
}
|
||||
|
||||
template <typename CompletionHandler>
|
||||
void perform(CompletionHandler&& handler) {
|
||||
_cancel_slot = asio::get_associated_cancellation_slot(handler);
|
||||
|
||||
_timer->expires_after(_delay);
|
||||
_timer->async_wait(
|
||||
asio::prepend(std::move(*this), on_timer {}, std::move(handler))
|
||||
);
|
||||
}
|
||||
|
||||
template <typename CompletionHandler>
|
||||
void operator()(on_timer, CompletionHandler&& h, error_code ec) {
|
||||
// The timer places a handler into the cancellation slot
|
||||
// and does not clear it. Therefore, we need to clear it explicitly
|
||||
// to properly remove the corresponding cancellation signal
|
||||
// in the test_broker.
|
||||
get_cancellation_slot().clear();
|
||||
|
||||
auto bh = std::apply(
|
||||
[h = std::move(h)](auto&&... args) mutable {
|
||||
return asio::append(std::move(h), std::move(args)...);
|
||||
},
|
||||
_args
|
||||
);
|
||||
|
||||
asio::dispatch(asio::prepend(std::move(bh), ec));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename CompletionToken, typename ...BoundArgs>
|
||||
template <typename CompletionToken, typename Executor, typename... BoundArgs>
|
||||
decltype(auto) async_delay(
|
||||
asio::cancellation_slot cancel_slot,
|
||||
delayed_op<BoundArgs...>&& op,
|
||||
const Executor& ex,
|
||||
delayed_op<BoundArgs...> op,
|
||||
CompletionToken&& token
|
||||
) {
|
||||
using Signature = void (error_code, boost::remove_cv_ref_t<BoundArgs>...);
|
||||
|
||||
auto initiation = [](
|
||||
auto handler, asio::cancellation_slot cancel_slot,
|
||||
delayed_op<BoundArgs...> op
|
||||
) {
|
||||
op.perform(
|
||||
asio::bind_cancellation_slot(cancel_slot, std::move(handler))
|
||||
auto initiation = [](auto handler, const Executor& ex, auto op) {
|
||||
auto timer = std::make_unique<asio::basic_waitable_timer<clock>>(ex);
|
||||
timer->expires_after(op.delay);
|
||||
auto bound_handler = std::apply(
|
||||
[h = std::move(handler)](auto&&... args) mutable {
|
||||
return asio::append(std::move(h), std::move(args)...);
|
||||
},
|
||||
std::move(op.args)
|
||||
);
|
||||
timer->async_wait(
|
||||
asio::consign(
|
||||
[bh = std::move(bound_handler)](error_code ec) mutable {
|
||||
asio::dispatch(asio::prepend(std::move(bh), ec));
|
||||
}, std::move(timer)
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
return asio::async_initiate<CompletionToken, Signature>(
|
||||
std::move(initiation), token, cancel_slot, std::move(op)
|
||||
std::move(initiation), token, ex, std::move(op)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
} // end namespace boost::mqtt5::test
|
||||
|
||||
#endif // BOOST_MQTT5_TEST_DELAYED_OP_HPP
|
||||
|
||||
@@ -20,13 +20,13 @@
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
#include "test_common/delayed_op.hpp"
|
||||
#include "delayed_op.hpp"
|
||||
|
||||
namespace boost::mqtt5::test {
|
||||
|
||||
using error_code = boost::system::error_code;
|
||||
using time_stamp = std::chrono::time_point<std::chrono::steady_clock>;
|
||||
using duration = time_stamp::duration;
|
||||
using time_point = clock::time_point;
|
||||
using duration = clock::duration;
|
||||
|
||||
class msg_exchange;
|
||||
class broker_message;
|
||||
@@ -57,10 +57,9 @@ public:
|
||||
stream_message& operator=(stream_message&&) = default;
|
||||
stream_message& operator=(const stream_message&) = delete;
|
||||
|
||||
template <typename Executor>
|
||||
auto to_operation(const Executor& ex) {
|
||||
auto to_operation() {
|
||||
return delayed_op<error_code, std::vector<uint8_t>> {
|
||||
ex, _after, _ec, std::move(_content)
|
||||
_after, _ec, std::move(_content)
|
||||
};
|
||||
}
|
||||
};
|
||||
@@ -107,17 +106,15 @@ public:
|
||||
template <typename ...Args>
|
||||
broker_message& send(Args&& ...args);
|
||||
|
||||
template <typename Executor>
|
||||
decltype(auto) write_completion(const Executor& ex) const {
|
||||
return delayed_op<error_code>(ex, _complete_after, _write_ec);
|
||||
decltype(auto) write_completion() const {
|
||||
return delayed_op<error_code>(_complete_after, _write_ec);
|
||||
}
|
||||
|
||||
template <typename Executor>
|
||||
decltype(auto) pop_reply_ops(const Executor& ex) {
|
||||
decltype(auto) pop_reply_ops() {
|
||||
std::vector<delayed_op<error_code, std::vector<uint8_t>>> ret;
|
||||
std::transform(
|
||||
_replies.begin(), _replies.end(), std::back_inserter(ret),
|
||||
[&ex](auto& r) { return r.to_operation(ex); }
|
||||
[](auto& r) { return r.to_operation(); }
|
||||
);
|
||||
_replies.clear();
|
||||
return ret;
|
||||
@@ -187,9 +184,8 @@ public:
|
||||
template <typename ...Args>
|
||||
broker_message& send(Args&& ...args);
|
||||
|
||||
template <typename Executor>
|
||||
decltype(auto) pop_send_op(const Executor& ex) {
|
||||
return _message.to_operation(ex);
|
||||
decltype(auto) pop_send_op() {
|
||||
return _message.to_operation();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -233,12 +229,11 @@ public:
|
||||
return rv;
|
||||
}
|
||||
|
||||
template <typename Executor>
|
||||
auto pop_broker_ops(const Executor& ex) {
|
||||
auto pop_broker_ops() {
|
||||
std::vector<delayed_op<error_code, std::vector<uint8_t>>> ret;
|
||||
std::transform(
|
||||
_from_broker.begin(), _from_broker.end(), std::back_inserter(ret),
|
||||
[&ex](auto& s) { return s.pop_send_op(ex); }
|
||||
[](auto& s) { return s.pop_send_op(); }
|
||||
);
|
||||
_from_broker.clear();
|
||||
return ret;
|
||||
|
||||
@@ -8,11 +8,14 @@
|
||||
#ifndef BOOST_MQTT5_TEST_AUTOCONNECT_STREAM_HPP
|
||||
#define BOOST_MQTT5_TEST_AUTOCONNECT_STREAM_HPP
|
||||
|
||||
#include "test_broker.hpp"
|
||||
|
||||
#include <boost/mqtt5/detail/async_mutex.hpp>
|
||||
#include <boost/mqtt5/detail/async_traits.hpp>
|
||||
#include <boost/mqtt5/detail/log_invoke.hpp>
|
||||
|
||||
#include <boost/mqtt5/impl/endpoints.hpp>
|
||||
#include <boost/mqtt5/impl/reconnect_op.hpp>
|
||||
|
||||
#include <boost/asio/ip/tcp.hpp>
|
||||
#include <boost/asio/steady_timer.hpp>
|
||||
@@ -22,6 +25,7 @@
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <variant>
|
||||
|
||||
namespace boost::mqtt5::test {
|
||||
|
||||
@@ -47,7 +51,7 @@ private:
|
||||
|
||||
executor_type _stream_executor;
|
||||
async_mutex _conn_mtx;
|
||||
asio::steady_timer _connect_timer;
|
||||
test_timer _connect_timer;
|
||||
endpoints _endpoints;
|
||||
|
||||
stream_ptr _stream_ptr;
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
#include <boost/asio/any_io_executor.hpp>
|
||||
#include <boost/asio/async_result.hpp>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <boost/asio/cancellation_signal.hpp>
|
||||
#include <boost/asio/dispatch.hpp>
|
||||
#include <boost/asio/execution_context.hpp>
|
||||
#include <boost/asio/ip/tcp.hpp>
|
||||
@@ -35,8 +34,13 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "test_common/message_exchange.hpp"
|
||||
#include "test_common/packet_util.hpp"
|
||||
#include "message_exchange.hpp"
|
||||
#include "packet_util.hpp"
|
||||
#include "test_timer.hpp"
|
||||
#include "test_resolver.hpp"
|
||||
|
||||
#define BOOST_MQTT5_DETAIL_RESOLVER_TYPE boost::mqtt5::test::test_resolver
|
||||
#define BOOST_MQTT5_DETAIL_CLOCK_TYPE boost::mqtt5::test::clock
|
||||
|
||||
namespace boost::mqtt5::test {
|
||||
|
||||
@@ -109,7 +113,6 @@ private:
|
||||
pending_read _pending_read;
|
||||
|
||||
msg_exchange _broker_side;
|
||||
std::vector<std::unique_ptr<asio::cancellation_signal>> _cancel_signals;
|
||||
|
||||
public:
|
||||
explicit test_broker(
|
||||
@@ -133,9 +136,6 @@ public:
|
||||
get_executor(), asio::error::operation_aborted, 0
|
||||
);
|
||||
|
||||
for (auto& cs : _cancel_signals)
|
||||
cs->emit(asio::cancellation_type::terminal);
|
||||
|
||||
_broker_data.clear();
|
||||
}
|
||||
|
||||
@@ -161,53 +161,48 @@ public:
|
||||
|
||||
executor_type ex = get_executor();
|
||||
|
||||
if (reply_action) {
|
||||
const auto& expected = reply_action->expected_packets();
|
||||
|
||||
size_t buffers_size = std::distance(
|
||||
asio::buffer_sequence_begin(buffers), asio::buffer_sequence_end(buffers)
|
||||
);
|
||||
BOOST_TEST(buffers_size == expected.size());
|
||||
|
||||
size_t num_packets = (std::min)(buffers_size, expected.size());
|
||||
auto it = asio::buffer_sequence_begin(buffers);
|
||||
for (size_t i = 0; i < num_packets; ++i, ++it) {
|
||||
BOOST_TEST(it->size() == expected[i].size());
|
||||
size_t len = (std::min)(it->size(), expected[i].size());
|
||||
if (memcmp(it->data(), expected[i].data(), len))
|
||||
BOOST_ERROR(
|
||||
concat_strings(
|
||||
"Packet mismatch!\nExpected: ",
|
||||
to_readable_packet(expected[i]),
|
||||
"\nReceived: ",
|
||||
to_readable_packet(std::string((const char*)it->data(), it->size()))
|
||||
)
|
||||
);
|
||||
}
|
||||
} else
|
||||
if (!reply_action.has_value()) {
|
||||
BOOST_ERROR(
|
||||
"Broker side did not expect: " <<
|
||||
boost::algorithm::join(to_readable_packets(buffers), ",")
|
||||
);
|
||||
return asio::post(asio::prepend(std::move(handler), error_code{}, 0));
|
||||
}
|
||||
|
||||
auto complete_op = reply_action ?
|
||||
reply_action->write_completion(ex) :
|
||||
delayed_op<error_code>(ex, 0ms, error_code {});
|
||||
const auto& expected = reply_action->expected_packets();
|
||||
|
||||
size_t buffers_size = std::distance(
|
||||
asio::buffer_sequence_begin(buffers), asio::buffer_sequence_end(buffers)
|
||||
);
|
||||
BOOST_TEST(buffers_size == expected.size());
|
||||
|
||||
size_t num_packets = (std::min)(buffers_size, expected.size());
|
||||
auto it = asio::buffer_sequence_begin(buffers);
|
||||
for (size_t i = 0; i < num_packets; ++i, ++it) {
|
||||
BOOST_TEST(it->size() == expected[i].size());
|
||||
size_t len = (std::min)(it->size(), expected[i].size());
|
||||
if (memcmp(it->data(), expected[i].data(), len))
|
||||
BOOST_ERROR(
|
||||
concat_strings(
|
||||
"Packet mismatch!\nExpected: ",
|
||||
to_readable_packet(expected[i]),
|
||||
"\nReceived: ",
|
||||
to_readable_packet(std::string((const char*)it->data(), it->size()))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
async_delay(
|
||||
make_cancel_slot(), std::move(complete_op),
|
||||
_ex, reply_action->write_completion(),
|
||||
asio::prepend(
|
||||
std::ref(*this), on_delayed_complete {},
|
||||
std::move(handler), bytes_written
|
||||
)
|
||||
);
|
||||
|
||||
if (!reply_action.has_value())
|
||||
return;
|
||||
|
||||
for (auto& op : reply_action->pop_reply_ops(ex))
|
||||
for (auto& op : reply_action->pop_reply_ops())
|
||||
async_delay(
|
||||
make_cancel_slot(), std::move(op),
|
||||
_ex, std::move(op),
|
||||
asio::prepend(std::ref(*this), on_receive {})
|
||||
);
|
||||
};
|
||||
@@ -239,8 +234,6 @@ public:
|
||||
on_receive, error_code delay_ec,
|
||||
error_code ec, std::vector<uint8_t> bytes
|
||||
) {
|
||||
remove_cancel_signal();
|
||||
|
||||
if (delay_ec) // asio::operation_aborted
|
||||
return;
|
||||
|
||||
@@ -253,8 +246,6 @@ public:
|
||||
on_delayed_complete, Handler handler, size_t bytes,
|
||||
error_code delay_ec, error_code ec
|
||||
) {
|
||||
remove_cancel_signal();
|
||||
|
||||
if (delay_ec) { // asio::operation_aborted
|
||||
ec = delay_ec;
|
||||
bytes = 0;
|
||||
@@ -267,6 +258,13 @@ public:
|
||||
_pending_read.complete(get_executor(), asio::error::operation_aborted, 0);
|
||||
}
|
||||
|
||||
static void run(asio::io_context& ioc) {
|
||||
while (!ioc.stopped()) {
|
||||
ioc.poll();
|
||||
asio::use_service<timer_service<clock>>(ioc).advance();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void shutdown() override {
|
||||
@@ -274,9 +272,9 @@ private:
|
||||
}
|
||||
|
||||
void launch_broker_ops() {
|
||||
for (auto& op: _broker_side.pop_broker_ops(get_executor())) {
|
||||
for (auto& op: _broker_side.pop_broker_ops()) {
|
||||
async_delay(
|
||||
asio::cancellation_slot {},
|
||||
_ex,
|
||||
std::move(op),
|
||||
asio::prepend(std::ref(*this), on_receive {})
|
||||
);
|
||||
@@ -304,22 +302,6 @@ private:
|
||||
_pending_read.complete(get_executor(), ec, bytes_read);
|
||||
}
|
||||
|
||||
asio::cancellation_slot make_cancel_slot() {
|
||||
_cancel_signals.push_back(
|
||||
std::make_unique<asio::cancellation_signal>()
|
||||
);
|
||||
return _cancel_signals.back()->slot();
|
||||
}
|
||||
|
||||
void remove_cancel_signal() {
|
||||
_cancel_signals.erase(
|
||||
std::remove_if(
|
||||
_cancel_signals.begin(), _cancel_signals.end(),
|
||||
[](auto& sig_ptr) { return !sig_ptr->slot().has_handler(); }
|
||||
),
|
||||
_cancel_signals.end()
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace boost::mqtt5::test
|
||||
|
||||
59
test/include/test_common/test_resolver.hpp
Normal file
59
test/include/test_common/test_resolver.hpp
Normal file
@@ -0,0 +1,59 @@
|
||||
//
|
||||
// Copyright (c) 2025 Ivica Siladic, Bruno Iljazovic, Korina Simicevic
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef BOOST_MQTT5_TEST_RESOLVER_HPP
|
||||
#define BOOST_MQTT5_TEST_RESOLVER_HPP
|
||||
|
||||
#include <boost/asio/any_io_executor.hpp>
|
||||
#include <boost/asio/ip/tcp.hpp>
|
||||
#include <boost/asio/prepend.hpp>
|
||||
|
||||
namespace boost::mqtt5::test {
|
||||
|
||||
class test_resolver {
|
||||
public:
|
||||
using executor_type = asio::any_io_executor;
|
||||
using results_type = asio::ip::tcp::resolver::results_type;
|
||||
|
||||
private:
|
||||
executor_type _ex;
|
||||
|
||||
public:
|
||||
static constexpr std::string_view invalid_host = "example.invalid";
|
||||
|
||||
explicit test_resolver(executor_type ex) : _ex(std::move(ex)) {}
|
||||
|
||||
executor_type get_executor() const noexcept { return _ex; }
|
||||
|
||||
template <typename CompletionToken>
|
||||
decltype(auto) async_resolve(
|
||||
std::string_view host, std::string_view port, CompletionToken&& token
|
||||
) {
|
||||
results_type results;
|
||||
boost::system::error_code ec;
|
||||
|
||||
if (host == invalid_host)
|
||||
ec = asio::error::host_not_found;
|
||||
else
|
||||
results = results_type::create(
|
||||
asio::ip::tcp::endpoint(asio::ip::make_address_v4("127.0.0.1"), 1883),
|
||||
std::string(host), std::string(port)
|
||||
);
|
||||
|
||||
return asio::post(
|
||||
get_executor(),
|
||||
asio::prepend(
|
||||
std::forward<CompletionToken>(token),
|
||||
ec, results
|
||||
)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace boost::mqtt5::test
|
||||
|
||||
#endif // !BOOST_MQTT5_TEST_RESOLVER_HPP
|
||||
@@ -8,6 +8,8 @@
|
||||
#ifndef BOOST_MQTT5_TEST_TEST_SERVICE_HPP
|
||||
#define BOOST_MQTT5_TEST_TEST_SERVICE_HPP
|
||||
|
||||
#include "test_broker.hpp"
|
||||
|
||||
#include <boost/mqtt5/types.hpp>
|
||||
|
||||
#include <boost/mqtt5/impl/client_service.hpp>
|
||||
|
||||
@@ -18,21 +18,18 @@
|
||||
#include <boost/asio/post.hpp>
|
||||
#include <boost/asio/prepend.hpp>
|
||||
#include <boost/asio/recycling_allocator.hpp>
|
||||
#include <boost/asio/steady_timer.hpp>
|
||||
#include <boost/system/error_code.hpp>
|
||||
|
||||
#include <chrono>
|
||||
#include <memory>
|
||||
|
||||
#include "test_common/test_broker.hpp"
|
||||
#include "test_broker.hpp"
|
||||
|
||||
namespace boost::mqtt5::test {
|
||||
|
||||
namespace asio = boost::asio;
|
||||
|
||||
using error_code = boost::system::error_code;
|
||||
using time_stamp = std::chrono::time_point<std::chrono::steady_clock>;
|
||||
using duration = time_stamp::duration;
|
||||
|
||||
namespace detail {
|
||||
|
||||
|
||||
207
test/include/test_common/test_timer.hpp
Normal file
207
test/include/test_common/test_timer.hpp
Normal file
@@ -0,0 +1,207 @@
|
||||
//
|
||||
// Copyright (c) 2025 Ivica Siladic, Bruno Iljazovic, Korina Simicevic
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef BOOST_MQTT5_TEST_TIMER_HPP
|
||||
#define BOOST_MQTT5_TEST_TIMER_HPP
|
||||
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
|
||||
#include <boost/asio/any_completion_handler.hpp>
|
||||
#include <boost/asio/any_io_executor.hpp>
|
||||
#include <boost/asio/basic_waitable_timer.hpp>
|
||||
#include <boost/asio/execution_context.hpp>
|
||||
#include <boost/asio/post.hpp>
|
||||
#include <boost/asio/prepend.hpp>
|
||||
|
||||
#include <boost/system/error_code.hpp>
|
||||
|
||||
namespace boost::mqtt5::test {
|
||||
|
||||
namespace asio = boost::asio;
|
||||
|
||||
class clock {
|
||||
public:
|
||||
using duration = std::chrono::duration<int64_t, std::milli>;
|
||||
using time_point = std::chrono::time_point<clock, duration>;
|
||||
using rep = duration::rep;
|
||||
using period = duration::period;
|
||||
|
||||
static constexpr bool is_steady = false;
|
||||
|
||||
static time_point now() noexcept {
|
||||
std::terminate();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Clock>
|
||||
class timer_service : public boost::asio::execution_context::service {
|
||||
public:
|
||||
static inline boost::asio::execution_context::id id;
|
||||
|
||||
private:
|
||||
using base = boost::asio::execution_context::service;
|
||||
using error_code = boost::system::error_code;
|
||||
using test_timer = boost::asio::basic_waitable_timer<Clock>;
|
||||
|
||||
std::vector<test_timer*> _timers;
|
||||
typename Clock::time_point _simulation_time;
|
||||
|
||||
public:
|
||||
explicit timer_service(boost::asio::execution_context& context)
|
||||
: base(context) {}
|
||||
|
||||
void add_timer(test_timer* timer) {
|
||||
_timers.push_back(timer);
|
||||
}
|
||||
|
||||
void remove_timer(test_timer* timer) {
|
||||
auto it = std::remove(_timers.begin(), _timers.end(), timer);
|
||||
_timers.erase(it);
|
||||
}
|
||||
|
||||
void advance() {
|
||||
if (_timers.empty()) return;
|
||||
auto it = std::min_element(
|
||||
_timers.begin(), _timers.end(),
|
||||
[](const test_timer* fst, const test_timer* snd) {
|
||||
return fst->expiry() < snd->expiry();
|
||||
}
|
||||
);
|
||||
_simulation_time = (*it)->expiry();
|
||||
for (auto it = _timers.begin(); it != _timers.end();) {
|
||||
auto* timer = *it;
|
||||
if (timer->expiry() <= now()) {
|
||||
timer->complete_post(error_code {});
|
||||
it = _timers.erase(it);
|
||||
}
|
||||
else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto now() const { return _simulation_time; }
|
||||
|
||||
private:
|
||||
void shutdown() noexcept override {
|
||||
for (auto* timer : _timers)
|
||||
timer->complete_post(asio::error::operation_aborted);
|
||||
_timers.clear();
|
||||
}
|
||||
};
|
||||
|
||||
using test_timer = asio::basic_waitable_timer<clock>;
|
||||
|
||||
} // namespace boost::mqtt5::test
|
||||
|
||||
|
||||
namespace boost::asio {
|
||||
|
||||
template <>
|
||||
class basic_waitable_timer<boost::mqtt5::test::clock> {
|
||||
public:
|
||||
using executor_type = asio::any_io_executor;
|
||||
using clock_type = boost::mqtt5::test::clock;
|
||||
using duration = clock_type::duration;
|
||||
using time_point = clock_type::time_point;
|
||||
|
||||
private:
|
||||
using error_code = boost::system::error_code;
|
||||
using service = boost::mqtt5::test::timer_service<clock_type>;
|
||||
using signature = void (error_code);
|
||||
|
||||
friend class boost::mqtt5::test::timer_service<clock_type>;
|
||||
|
||||
executor_type _ex;
|
||||
time_point _expires_at;
|
||||
asio::any_completion_handler<signature> _handler;
|
||||
asio::prefer_result_t<
|
||||
executor_type, execution::outstanding_work_t::tracked_t> _handler_ex;
|
||||
|
||||
public:
|
||||
explicit basic_waitable_timer(executor_type ex) : _ex(std::move(ex)) {}
|
||||
basic_waitable_timer(executor_type ex, time_point expiry_time)
|
||||
: _ex(std::move(ex)) { expires_at(expiry_time); }
|
||||
basic_waitable_timer(executor_type ex, duration dur)
|
||||
: _ex(std::move(ex)) { expires_after(dur); }
|
||||
|
||||
~basic_waitable_timer() {
|
||||
if (_handler) {
|
||||
get_service().remove_timer(this);
|
||||
complete_post(asio::error::operation_aborted);
|
||||
}
|
||||
}
|
||||
|
||||
executor_type get_executor() const noexcept { return _ex; }
|
||||
|
||||
size_t expires_at(time_point expiry_time) {
|
||||
_expires_at = expiry_time;
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t expires_after(duration dur) {
|
||||
auto now = get_service().now();
|
||||
if ((time_point::max)() - now < dur)
|
||||
_expires_at = (time_point::max)();
|
||||
else
|
||||
_expires_at = now + dur;
|
||||
return 0;
|
||||
}
|
||||
|
||||
time_point expiry() const { return _expires_at; }
|
||||
size_t cancel() {
|
||||
if (_handler) {
|
||||
get_service().remove_timer(this);
|
||||
complete_post(asio::error::operation_aborted);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename CompletionToken>
|
||||
decltype(auto) async_wait(CompletionToken&& token) {
|
||||
auto initiation = [this](auto handler) {
|
||||
if (_expires_at <= get_service().now())
|
||||
return asio::post(
|
||||
get_executor(),
|
||||
asio::prepend(std::move(handler), error_code {})
|
||||
);
|
||||
|
||||
_handler = std::move(handler);
|
||||
_handler_ex = asio::prefer(_ex, asio::execution::outstanding_work.tracked);
|
||||
|
||||
auto slot = asio::get_associated_cancellation_slot(_handler);
|
||||
if (slot.is_connected())
|
||||
slot.assign([this](asio::cancellation_type_t type) {
|
||||
if (type != asio::cancellation_type_t::none)
|
||||
cancel();
|
||||
});
|
||||
|
||||
get_service().add_timer(this);
|
||||
};
|
||||
|
||||
return asio::async_initiate<CompletionToken, signature>(
|
||||
initiation, token
|
||||
);
|
||||
}
|
||||
|
||||
private:
|
||||
service& get_service() const {
|
||||
return use_service<service>(_ex.context());
|
||||
}
|
||||
|
||||
void complete_post(error_code ec) {
|
||||
asio::get_associated_cancellation_slot(_handler).clear();
|
||||
asio::post(get_executor(), asio::prepend(std::move(_handler), ec));
|
||||
_handler_ex = {};
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace boost::asio
|
||||
|
||||
#endif // !BOOST_MQTT5_TEST_TIMER_HPP
|
||||
133
test/integration/logger.cpp
Normal file
133
test/integration/logger.cpp
Normal file
@@ -0,0 +1,133 @@
|
||||
//
|
||||
// Copyright (c) 2023-2025 Ivica Siladic, Bruno Iljazovic, Korina Simicevic
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include "test_common/extra_deps.hpp"
|
||||
#include "test_common/preconditions.hpp"
|
||||
|
||||
#include <boost/mqtt5/logger.hpp>
|
||||
#include <boost/mqtt5/logger_traits.hpp>
|
||||
#include <boost/mqtt5/mqtt_client.hpp>
|
||||
|
||||
#include <boost/mqtt5/detail/log_invoke.hpp>
|
||||
|
||||
#include <boost/asio/detached.hpp>
|
||||
#include <boost/asio/io_context.hpp>
|
||||
#include <boost/asio/ip/tcp.hpp>
|
||||
#include <boost/system/error_code.hpp>
|
||||
#include <boost/test/tools/output_test_stream.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <chrono>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
|
||||
using namespace boost::mqtt5;
|
||||
namespace asio = boost::asio;
|
||||
|
||||
void logger_test() {
|
||||
BOOST_STATIC_ASSERT(has_at_resolve<logger>);
|
||||
BOOST_STATIC_ASSERT(has_at_tcp_connect<logger>);
|
||||
BOOST_STATIC_ASSERT(has_at_tls_handshake<logger>);
|
||||
BOOST_STATIC_ASSERT(has_at_ws_handshake<logger>);
|
||||
BOOST_STATIC_ASSERT(has_at_connack<logger>);
|
||||
BOOST_STATIC_ASSERT(has_at_disconnect<logger>);
|
||||
BOOST_STATIC_ASSERT(has_at_transport_error<logger>);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(logger_tests)
|
||||
|
||||
using error_code = boost::system::error_code;
|
||||
|
||||
class clog_redirect {
|
||||
std::streambuf* _old_buffer;
|
||||
|
||||
public:
|
||||
clog_redirect(std::streambuf* new_buffer) :
|
||||
_old_buffer(std::clog.rdbuf(new_buffer))
|
||||
{}
|
||||
|
||||
~clog_redirect() {
|
||||
std::clog.rdbuf(_old_buffer);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
bool contains(const std::string& str, const std::string& substr) {
|
||||
return str.find(substr) != std::string::npos;
|
||||
}
|
||||
|
||||
#ifdef BOOST_MQTT5_EXTRA_DEPS
|
||||
using stream_type = boost::beast::websocket::stream<
|
||||
asio::ssl::stream<asio::ip::tcp::socket>
|
||||
>;
|
||||
using context_type = asio::ssl::context;
|
||||
using logger_type = logger;
|
||||
using client_type = mqtt_client<stream_type, context_type, logger_type>;
|
||||
|
||||
BOOST_AUTO_TEST_CASE(client_successful_connect_debug,
|
||||
* boost::unit_test::precondition(test::public_broker_cond))
|
||||
{
|
||||
boost::test_tools::output_test_stream output;
|
||||
|
||||
{
|
||||
clog_redirect guard(output.rdbuf());
|
||||
asio::io_context ioc;
|
||||
|
||||
asio::ssl::context tls_context(asio::ssl::context::tls_client);
|
||||
client_type c(
|
||||
ioc, std::move(tls_context), logger(log_level::debug)
|
||||
);
|
||||
|
||||
c.brokers("broker.hivemq.com/mqtt", 8884)
|
||||
.async_run(asio::detached);
|
||||
|
||||
c.async_disconnect([](error_code) {});
|
||||
|
||||
ioc.run();
|
||||
}
|
||||
|
||||
std::string log = output.rdbuf()->str();
|
||||
BOOST_TEST_MESSAGE(log);
|
||||
BOOST_TEST_WARN(contains(log, "resolve"));
|
||||
BOOST_TEST_WARN(contains(log, "TCP connect"));
|
||||
BOOST_TEST_WARN(contains(log, "TLS handshake"));
|
||||
BOOST_TEST_WARN(contains(log, "WebSocket handshake"));
|
||||
BOOST_TEST_WARN(contains(log, "connack"));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(client_successful_connect_warning,
|
||||
* boost::unit_test::precondition(test::public_broker_cond))
|
||||
{
|
||||
boost::test_tools::output_test_stream output;
|
||||
|
||||
{
|
||||
clog_redirect guard(output.rdbuf());
|
||||
|
||||
asio::io_context ioc;
|
||||
asio::ssl::context tls_context(asio::ssl::context::tls_client);
|
||||
client_type c(
|
||||
ioc, std::move(tls_context), logger(log_level::warning)
|
||||
);
|
||||
|
||||
c.brokers("broker.hivemq.com/mqtt", 8884)
|
||||
.async_run(asio::detached);
|
||||
|
||||
c.async_disconnect([](error_code) {});
|
||||
|
||||
ioc.run();
|
||||
}
|
||||
|
||||
// If connection is successful, nothing should be printed.
|
||||
// However if the Broker is down or overloaded, this will cause logs to be printed.
|
||||
// We should not fail the test because of it.
|
||||
BOOST_TEST_WARN(output.is_empty());
|
||||
}
|
||||
#endif // BOOST_MQTT5_EXTRA_DEPS
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END();
|
||||
@@ -13,7 +13,6 @@
|
||||
#include <boost/asio/error.hpp>
|
||||
#include <boost/asio/io_context.hpp>
|
||||
#include <boost/asio/strand.hpp>
|
||||
#include <boost/asio/thread_pool.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <chrono>
|
||||
@@ -30,8 +29,8 @@ BOOST_AUTO_TEST_CASE(lock_mutex) {
|
||||
constexpr int expected_handlers_called = 1;
|
||||
int handlers_called = 0;
|
||||
|
||||
asio::thread_pool tp(1);
|
||||
async_mutex mutex(tp.executor());
|
||||
asio::io_context ioc;
|
||||
async_mutex mutex(ioc.get_executor());
|
||||
|
||||
mutex.lock([&mutex, &handlers_called](error_code ec) {
|
||||
++handlers_called;
|
||||
@@ -41,13 +40,13 @@ BOOST_AUTO_TEST_CASE(lock_mutex) {
|
||||
BOOST_TEST(!mutex.is_locked());
|
||||
});
|
||||
|
||||
tp.wait();
|
||||
ioc.poll();
|
||||
BOOST_TEST(handlers_called == expected_handlers_called);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(get_executor) {
|
||||
asio::thread_pool tp(1);
|
||||
auto ex = tp.get_executor();
|
||||
asio::io_context ioc;
|
||||
auto ex = ioc.get_executor();
|
||||
async_mutex mutex(ex);
|
||||
BOOST_CHECK(mutex.get_executor() == ex);
|
||||
}
|
||||
@@ -56,11 +55,11 @@ BOOST_AUTO_TEST_CASE(bind_executor) {
|
||||
constexpr int expected_handlers_called = 2;
|
||||
int handlers_called = 0;
|
||||
|
||||
asio::thread_pool tp(1);
|
||||
asio::io_context ioc;
|
||||
|
||||
async_mutex mutex(tp.get_executor());
|
||||
auto s1 = asio::make_strand(tp.get_executor());
|
||||
auto s2 = asio::make_strand(tp.get_executor());
|
||||
async_mutex mutex(ioc.get_executor());
|
||||
auto s1 = asio::make_strand(ioc.get_executor());
|
||||
auto s2 = asio::make_strand(ioc.get_executor());
|
||||
|
||||
mutex.lock(
|
||||
asio::bind_executor(
|
||||
@@ -88,7 +87,7 @@ BOOST_AUTO_TEST_CASE(bind_executor) {
|
||||
)
|
||||
);
|
||||
|
||||
tp.wait();
|
||||
ioc.poll();
|
||||
BOOST_TEST(handlers_called == expected_handlers_called);
|
||||
BOOST_TEST(!mutex.is_locked());
|
||||
}
|
||||
@@ -123,7 +122,7 @@ BOOST_AUTO_TEST_CASE(per_op_cancellation) {
|
||||
cs.emit(asio::cancellation_type_t::terminal);
|
||||
cs.slot().clear();
|
||||
|
||||
ioc.run();
|
||||
ioc.poll();
|
||||
BOOST_TEST(handlers_called == expected_handlers_called);
|
||||
BOOST_TEST(!mutex.is_locked());
|
||||
}
|
||||
@@ -151,7 +150,7 @@ BOOST_AUTO_TEST_CASE(cancel_ops_by_destructor) {
|
||||
mutex.lock(std::move(cancelled_op));
|
||||
}
|
||||
|
||||
ioc.run();
|
||||
ioc.poll();
|
||||
BOOST_TEST(handlers_called == expected_handlers_called);
|
||||
}
|
||||
|
||||
@@ -180,7 +179,7 @@ BOOST_AUTO_TEST_CASE(cancel_ops) {
|
||||
mutex.lock(cancelled_op);
|
||||
|
||||
mutex.cancel();
|
||||
ioc.run();
|
||||
ioc.poll();
|
||||
BOOST_TEST(handlers_called == expected_handlers_called);
|
||||
BOOST_TEST(!mutex.is_locked());
|
||||
}
|
||||
|
||||
@@ -5,12 +5,14 @@
|
||||
// (See accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include "test_common/message_exchange.hpp"
|
||||
#include "test_common/test_stream.hpp"
|
||||
|
||||
#include <boost/mqtt5/mqtt_client.hpp>
|
||||
#include <boost/mqtt5/types.hpp>
|
||||
|
||||
#include <boost/asio/detached.hpp>
|
||||
#include <boost/asio/io_context.hpp>
|
||||
#include <boost/asio/steady_timer.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <chrono>
|
||||
@@ -19,9 +21,6 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "test_common/message_exchange.hpp"
|
||||
#include "test_common/test_stream.hpp"
|
||||
|
||||
using namespace boost::mqtt5;
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(async_sender/*, *boost::unit_test::disabled()*/)
|
||||
@@ -130,7 +129,7 @@ BOOST_FIXTURE_TEST_CASE(publish_ordering_after_reconnect, shared_test_data) {
|
||||
}
|
||||
);
|
||||
|
||||
ioc.run_for(1s);
|
||||
broker.run(ioc);
|
||||
BOOST_TEST(handlers_called == expected_handlers_called);
|
||||
BOOST_TEST(broker.received_all_expected());
|
||||
}
|
||||
@@ -209,7 +208,7 @@ BOOST_FIXTURE_TEST_CASE(sub_unsub_ordering_after_reconnect, shared_test_data) {
|
||||
}
|
||||
);
|
||||
|
||||
ioc.run_for(1s);
|
||||
broker.run(ioc);
|
||||
BOOST_TEST(handlers_called == expected_handlers_called);
|
||||
BOOST_TEST(broker.received_all_expected());
|
||||
}
|
||||
@@ -274,7 +273,7 @@ BOOST_FIXTURE_TEST_CASE(throttling, shared_test_data) {
|
||||
}
|
||||
);
|
||||
|
||||
ioc.run_for(1s);
|
||||
broker.run(ioc);
|
||||
BOOST_TEST(handlers_called == expected_handlers_called);
|
||||
BOOST_TEST(broker.received_all_expected());
|
||||
}
|
||||
@@ -333,7 +332,7 @@ BOOST_FIXTURE_TEST_CASE(throttling_ordering, shared_test_data) {
|
||||
}
|
||||
);
|
||||
|
||||
ioc.run_for(1s);
|
||||
broker.run(ioc);
|
||||
BOOST_TEST(handlers_called == expected_handlers_called);
|
||||
BOOST_TEST(broker.received_all_expected());
|
||||
}
|
||||
@@ -377,7 +376,7 @@ BOOST_FIXTURE_TEST_CASE(prioritize_disconnect, shared_test_data) {
|
||||
.async_run(asio::detached);
|
||||
|
||||
// give time to establish a connection
|
||||
asio::steady_timer timer(executor);
|
||||
test::test_timer timer(executor);
|
||||
timer.expires_after(100ms);
|
||||
timer.async_wait([&](error_code) {
|
||||
c.async_publish<qos_e::at_least_once>(
|
||||
@@ -407,7 +406,7 @@ BOOST_FIXTURE_TEST_CASE(prioritize_disconnect, shared_test_data) {
|
||||
});
|
||||
});
|
||||
|
||||
ioc.run_for(2s);
|
||||
broker.run(ioc);
|
||||
BOOST_TEST(handlers_called == expected_handlers_called);
|
||||
BOOST_TEST(broker.received_all_expected());
|
||||
}
|
||||
@@ -5,6 +5,9 @@
|
||||
// (See accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include "test_common/message_exchange.hpp"
|
||||
#include "test_common/test_stream.hpp"
|
||||
|
||||
#include <boost/asio/as_tuple.hpp>
|
||||
#include <boost/asio/bind_cancellation_slot.hpp>
|
||||
#include <boost/asio/cancellation_signal.hpp>
|
||||
@@ -12,16 +15,12 @@
|
||||
#include <boost/asio/detached.hpp>
|
||||
#include <boost/asio/io_context.hpp>
|
||||
#include <boost/asio/ip/tcp.hpp>
|
||||
#include <boost/asio/steady_timer.hpp>
|
||||
#include <boost/asio/use_awaitable.hpp>
|
||||
#include <boost/mqtt5.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#include "test_common/message_exchange.hpp"
|
||||
#include "test_common/test_stream.hpp"
|
||||
|
||||
using namespace boost::mqtt5;
|
||||
|
||||
namespace boost::mqtt5::test {
|
||||
@@ -190,7 +189,7 @@ void run_cancel_op_test() {
|
||||
|
||||
setup_cancel_op_test_case<op_type>(c, signal, handlers_called);
|
||||
|
||||
asio::steady_timer timer(c.get_executor());
|
||||
test::test_timer timer(c.get_executor());
|
||||
timer.expires_after(std::chrono::milliseconds(100));
|
||||
timer.async_wait([&](error_code) {
|
||||
if constexpr (c_type == client_cancel)
|
||||
@@ -199,7 +198,7 @@ void run_cancel_op_test() {
|
||||
signal.emit(asio::cancellation_type_t::terminal);
|
||||
});
|
||||
|
||||
ioc.run();
|
||||
test::test_broker::run(ioc);
|
||||
BOOST_TEST(handlers_called == expected_handlers_called);
|
||||
}
|
||||
|
||||
@@ -341,7 +340,7 @@ BOOST_FIXTURE_TEST_CASE(rerunning_the_client, shared_test_data) {
|
||||
asio::detached
|
||||
);
|
||||
|
||||
ioc.run();
|
||||
broker.run(ioc);
|
||||
BOOST_TEST(broker.received_all_expected());
|
||||
}
|
||||
|
||||
@@ -5,6 +5,12 @@
|
||||
// (See accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include "test_common/extra_deps.hpp"
|
||||
#include "test_common/message_exchange.hpp"
|
||||
#include "test_common/packet_util.hpp"
|
||||
#include "test_common/test_authenticators.hpp"
|
||||
#include "test_common/test_stream.hpp"
|
||||
|
||||
#include <boost/mqtt5/mqtt_client.hpp>
|
||||
#include <boost/mqtt5/types.hpp>
|
||||
|
||||
@@ -13,7 +19,6 @@
|
||||
#include <boost/asio/detached.hpp>
|
||||
#include <boost/asio/io_context.hpp>
|
||||
#include <boost/asio/ip/tcp.hpp>
|
||||
#include <boost/asio/steady_timer.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/type_traits/remove_cv_ref.hpp>
|
||||
|
||||
@@ -22,12 +27,6 @@
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
#include "test_common/extra_deps.hpp"
|
||||
#include "test_common/message_exchange.hpp"
|
||||
#include "test_common/packet_util.hpp"
|
||||
#include "test_common/test_authenticators.hpp"
|
||||
#include "test_common/test_stream.hpp"
|
||||
|
||||
using namespace boost::mqtt5;
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
@@ -58,13 +57,13 @@ void run_test(
|
||||
c.brokers("127.0.0.1")
|
||||
.async_run(asio::detached);
|
||||
|
||||
asio::steady_timer timer(executor);
|
||||
test::test_timer timer(executor);
|
||||
timer.expires_after(700ms);
|
||||
timer.async_wait(
|
||||
[&c](error_code) { c.cancel(); }
|
||||
);
|
||||
|
||||
ioc.run();
|
||||
broker.run(ioc);
|
||||
BOOST_TEST(broker.received_all_expected());
|
||||
}
|
||||
|
||||
@@ -302,7 +301,7 @@ void run_test_with_post_fun(
|
||||
c.brokers("127.0.0.1")
|
||||
.async_run(asio::detached);
|
||||
|
||||
asio::steady_timer timer(executor);
|
||||
test::test_timer timer(executor);
|
||||
timer.expires_after(700ms);
|
||||
timer.async_wait(
|
||||
[&c, fun = std::forward<TestingClientFun>(client_fun)](error_code) {
|
||||
@@ -311,7 +310,7 @@ void run_test_with_post_fun(
|
||||
}
|
||||
);
|
||||
|
||||
ioc.run();
|
||||
broker.run(ioc);
|
||||
|
||||
BOOST_TEST(broker.received_all_expected());
|
||||
}
|
||||
@@ -5,6 +5,9 @@
|
||||
// (See accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include "test_common/test_authenticators.hpp"
|
||||
#include "test_common/test_stream.hpp"
|
||||
|
||||
#include <boost/mqtt5/logger_traits.hpp>
|
||||
#include <boost/mqtt5/types.hpp>
|
||||
|
||||
@@ -15,7 +18,6 @@
|
||||
|
||||
#include <boost/asio/io_context.hpp>
|
||||
#include <boost/asio/ip/tcp.hpp>
|
||||
#include <boost/asio/steady_timer.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <chrono>
|
||||
@@ -23,9 +25,6 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "test_common/test_authenticators.hpp"
|
||||
#include "test_common/test_stream.hpp"
|
||||
|
||||
using namespace boost::mqtt5;
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(connect_op/*, *boost::unit_test::disabled()*/)
|
||||
@@ -72,7 +71,7 @@ void run_unit_test(
|
||||
stream, mqtt_ctx, d, std::move(handler)
|
||||
).perform(*std::begin(eps), std::move(ap));
|
||||
|
||||
ioc.run_for(1s);
|
||||
broker.run(ioc);
|
||||
BOOST_TEST(handlers_called == expected_handlers_called);
|
||||
BOOST_TEST(broker.received_all_expected());
|
||||
}
|
||||
|
||||
@@ -9,6 +9,9 @@
|
||||
|
||||
#ifdef BOOST_ASIO_HAS_CO_AWAIT
|
||||
|
||||
#include "test_common/test_broker.hpp"
|
||||
#include "test_common/extra_deps.hpp"
|
||||
|
||||
#include <boost/mqtt5.hpp>
|
||||
|
||||
#include <boost/asio/io_context.hpp>
|
||||
@@ -19,8 +22,6 @@
|
||||
#include <variant> // std::monostate
|
||||
#include <vector>
|
||||
|
||||
#include "test_common/extra_deps.hpp"
|
||||
|
||||
namespace boost::mqtt5::test {
|
||||
|
||||
// the following code needs to compile
|
||||
|
||||
@@ -5,22 +5,21 @@
|
||||
// (See accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include "test_common/message_exchange.hpp"
|
||||
#include "test_common/test_broker.hpp"
|
||||
#include "test_common/test_stream.hpp"
|
||||
|
||||
#include <boost/mqtt5/mqtt_client.hpp>
|
||||
#include <boost/mqtt5/types.hpp>
|
||||
|
||||
#include <boost/asio/detached.hpp>
|
||||
#include <boost/asio/io_context.hpp>
|
||||
#include <boost/asio/steady_timer.hpp>
|
||||
#include <boost/test/data/test_case.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <chrono>
|
||||
#include <string>
|
||||
|
||||
#include "test_common/message_exchange.hpp"
|
||||
#include "test_common/test_broker.hpp"
|
||||
#include "test_common/test_stream.hpp"
|
||||
|
||||
using namespace boost::mqtt5;
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(disconnect/*, *boost::unit_test::disabled()*/)
|
||||
@@ -52,14 +51,14 @@ void run_test(test::msg_exchange broker_side, TestCase&& test_case) {
|
||||
ioc, executor, std::move(broker_side)
|
||||
);
|
||||
|
||||
asio::steady_timer timer(executor);
|
||||
test::test_timer timer(executor);
|
||||
client_type c(executor);
|
||||
c.brokers("127.0.0.1,127.0.0.1") // to avoid reconnect backoff
|
||||
.async_run(asio::detached);
|
||||
|
||||
test_case(c, timer);
|
||||
|
||||
ioc.run();
|
||||
broker.run(ioc);
|
||||
BOOST_TEST(broker.received_all_expected());
|
||||
}
|
||||
|
||||
@@ -77,7 +76,7 @@ BOOST_FIXTURE_TEST_CASE(successful_disconnect, shared_test_data) {
|
||||
|
||||
run_test(
|
||||
std::move(broker_side),
|
||||
[&](client_type& c, asio::steady_timer& timer) {
|
||||
[&](client_type& c, test::test_timer& timer) {
|
||||
timer.expires_after(100ms);
|
||||
timer.async_wait([&](error_code) {
|
||||
c.async_disconnect(
|
||||
@@ -114,7 +113,7 @@ BOOST_FIXTURE_TEST_CASE(successful_disconnect_in_queue, shared_test_data) {
|
||||
|
||||
run_test(
|
||||
std::move(broker_side),
|
||||
[&](client_type& c, asio::steady_timer& timer) {
|
||||
[&](client_type& c, test::test_timer& timer) {
|
||||
timer.expires_after(50ms);
|
||||
timer.async_wait([&](error_code) {
|
||||
c.async_publish<qos_e::at_most_once>(
|
||||
@@ -150,7 +149,7 @@ BOOST_FIXTURE_TEST_CASE(disconnect_on_disconnected_client, shared_test_data) {
|
||||
|
||||
run_test(
|
||||
std::move(broker_side),
|
||||
[&](client_type& c, asio::steady_timer& timer) {
|
||||
[&](client_type& c, test::test_timer& timer) {
|
||||
timer.expires_after(50ms);
|
||||
timer.async_wait([&](error_code) {
|
||||
c.async_disconnect(
|
||||
@@ -177,7 +176,7 @@ BOOST_FIXTURE_TEST_CASE(disconnect_in_queue_on_disconnected_client, shared_test_
|
||||
|
||||
run_test(
|
||||
std::move(broker_side),
|
||||
[&](client_type& c, asio::steady_timer& timer) {
|
||||
[&](client_type& c, test::test_timer& timer) {
|
||||
timer.expires_after(50ms);
|
||||
timer.async_wait([&](error_code) {
|
||||
c.async_publish<qos_e::at_most_once>(
|
||||
@@ -216,7 +215,7 @@ BOOST_FIXTURE_TEST_CASE(resend_terminal_disconnect, shared_test_data) {
|
||||
|
||||
run_test(
|
||||
std::move(broker_side),
|
||||
[&](client_type& c, asio::steady_timer&) {
|
||||
[&](client_type& c, test::test_timer&) {
|
||||
c.async_disconnect(
|
||||
[&](error_code ec) {
|
||||
handlers_called++;
|
||||
@@ -258,7 +257,7 @@ BOOST_FIXTURE_TEST_CASE(dont_resend_non_terminal_disconnect, shared_test_data) {
|
||||
|
||||
run_test(
|
||||
std::move(broker_side),
|
||||
[&](client_type& c, asio::steady_timer& timer) {
|
||||
[&](client_type& c, test::test_timer& timer) {
|
||||
timer.expires_after(50ms);
|
||||
timer.async_wait([&](error_code) {
|
||||
c.cancel();
|
||||
@@ -292,7 +291,7 @@ BOOST_FIXTURE_TEST_CASE(omit_props, shared_test_data) {
|
||||
|
||||
run_test(
|
||||
std::move(broker_side),
|
||||
[&](client_type& c, asio::steady_timer&) {
|
||||
[&](client_type& c, test::test_timer&) {
|
||||
c.async_disconnect(
|
||||
disconnect_rc_e::normal_disconnection, props,
|
||||
[&](error_code ec) {
|
||||
@@ -313,7 +312,7 @@ struct long_shutdown_stream : public test::test_stream {
|
||||
|
||||
template <typename ShutdownHandler>
|
||||
void async_shutdown(long_shutdown_stream& stream, ShutdownHandler&& handler) {
|
||||
auto timer = std::make_shared<asio::steady_timer>(stream.get_executor());
|
||||
auto timer = std::make_shared<test::test_timer>(stream.get_executor());
|
||||
timer->expires_after(std::chrono::seconds(10));
|
||||
timer->async_wait(asio::consign(std::move(handler), std::move(timer)));
|
||||
}
|
||||
@@ -340,7 +339,7 @@ BOOST_DATA_TEST_CASE_F(
|
||||
ioc, executor, std::move(broker_side)
|
||||
);
|
||||
|
||||
asio::steady_timer timer(executor);
|
||||
test::test_timer timer(executor);
|
||||
mqtt_client<long_shutdown_stream> c(executor);
|
||||
c.brokers("127.0.0.1")
|
||||
.async_run(asio::detached);
|
||||
@@ -363,7 +362,7 @@ BOOST_DATA_TEST_CASE_F(
|
||||
signal.emit(asio::cancellation_type::all);
|
||||
});
|
||||
|
||||
ioc.run_for(6s);
|
||||
broker.run(ioc);
|
||||
|
||||
BOOST_TEST(broker.received_all_expected());
|
||||
BOOST_TEST(handlers_called == expected_handlers_called);
|
||||
@@ -5,6 +5,8 @@
|
||||
// (See accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include "test_common/test_service.hpp"
|
||||
|
||||
#include <boost/mqtt5/types.hpp>
|
||||
|
||||
#include <boost/mqtt5/impl/disconnect_op.hpp>
|
||||
@@ -18,8 +20,6 @@
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "test_common/test_service.hpp"
|
||||
|
||||
using namespace boost::mqtt5;
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(disconnect_op/*, *boost::unit_test::disabled()*/)
|
||||
@@ -45,7 +45,7 @@ void run_malformed_props_test(const disconnect_props& dprops) {
|
||||
> { svc_ptr, std::move(ctx), std::move(handler) }
|
||||
.perform();
|
||||
|
||||
ioc.run_for(std::chrono::milliseconds(500));
|
||||
ioc.poll();
|
||||
BOOST_TEST(handlers_called == expected_handlers_called);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
// (See accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include "test_common/test_broker.hpp"
|
||||
|
||||
#include <boost/mqtt5/impl/endpoints.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
@@ -27,7 +29,7 @@ struct shared_test_data {
|
||||
error_code success {};
|
||||
|
||||
asio::io_context ioc;
|
||||
asio::steady_timer timer;
|
||||
test::test_timer timer;
|
||||
detail::log_invoke<noop_logger> logger;
|
||||
detail::endpoints<noop_logger> ep;
|
||||
|
||||
@@ -47,7 +49,7 @@ BOOST_FIXTURE_TEST_CASE(empty_path, shared_test_data) {
|
||||
BOOST_TEST(ec == asio::error::host_not_found);
|
||||
}, [&finished](auto eptr) { finished = !eptr; });
|
||||
|
||||
ioc.run_for(1s);
|
||||
test::test_broker::run(ioc);
|
||||
BOOST_TEST(finished);
|
||||
}
|
||||
|
||||
@@ -67,7 +69,7 @@ BOOST_FIXTURE_TEST_CASE(single_host, shared_test_data) {
|
||||
BOOST_TEST(ec == asio::error::try_again);
|
||||
}, [&finished](auto eptr) { finished = !eptr; });
|
||||
|
||||
ioc.run_for(1s);
|
||||
test::test_broker::run(ioc);
|
||||
BOOST_TEST(finished);
|
||||
}
|
||||
|
||||
@@ -104,7 +106,7 @@ BOOST_FIXTURE_TEST_CASE(multiple_hosts, shared_test_data) {
|
||||
}
|
||||
}, [&finished](auto eptr) { finished = !eptr; });
|
||||
|
||||
ioc.run_for(1s);
|
||||
test::test_broker::run(ioc);
|
||||
BOOST_TEST(finished);
|
||||
}
|
||||
|
||||
@@ -124,7 +126,7 @@ BOOST_FIXTURE_TEST_CASE(parse_failure, shared_test_data) {
|
||||
BOOST_TEST(ec == asio::error::try_again);
|
||||
}, [&finished](auto eptr) { finished = !eptr; });
|
||||
|
||||
ioc.run_for(1s);
|
||||
test::test_broker::run(ioc);
|
||||
BOOST_TEST(finished);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
// (See accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include "test_common/message_exchange.hpp"
|
||||
#include "test_common/test_stream.hpp"
|
||||
|
||||
#include <boost/mqtt5/impl/codecs/message_encoders.hpp>
|
||||
|
||||
#include <boost/asio/bind_executor.hpp>
|
||||
@@ -12,7 +15,6 @@
|
||||
#include <boost/asio/detached.hpp>
|
||||
#include <boost/asio/io_context.hpp>
|
||||
#include <boost/asio/ip/tcp.hpp>
|
||||
#include <boost/asio/steady_timer.hpp>
|
||||
#include <boost/asio/strand.hpp>
|
||||
#include <boost/mqtt5.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
@@ -22,9 +24,6 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "test_common/message_exchange.hpp"
|
||||
#include "test_common/test_stream.hpp"
|
||||
|
||||
using namespace boost::mqtt5;
|
||||
|
||||
using strand_type = asio::strand<asio::any_io_executor>;
|
||||
@@ -205,7 +204,7 @@ void run_test(
|
||||
)
|
||||
);
|
||||
|
||||
ioc.run_for(500ms);
|
||||
test::test_broker::run(ioc);
|
||||
BOOST_TEST(handlers_called == expected_handlers_called);
|
||||
BOOST_TEST(broker.received_all_expected());
|
||||
}
|
||||
@@ -261,7 +260,7 @@ BOOST_AUTO_TEST_CASE(immediate_executor_async_publish) {
|
||||
"invalid/#", "", retain_e::no, publish_props {}, std::move(handler)
|
||||
);
|
||||
|
||||
ioc.run();
|
||||
test::test_broker::run(ioc);
|
||||
BOOST_TEST(handlers_called == expected_handlers_called);
|
||||
}
|
||||
|
||||
@@ -290,7 +289,7 @@ BOOST_AUTO_TEST_CASE(immediate_executor_async_subscribe) {
|
||||
{ "+topic", subscribe_options {} }, subscribe_props{}, std::move(handler)
|
||||
);
|
||||
|
||||
ioc.run();
|
||||
test::test_broker::run(ioc);
|
||||
BOOST_TEST(handlers_called == expected_handlers_called);
|
||||
}
|
||||
|
||||
@@ -319,7 +318,7 @@ BOOST_AUTO_TEST_CASE(immediate_executor_async_unsubscribe) {
|
||||
"some/topic#", unsubscribe_props {}, std::move(handler)
|
||||
);
|
||||
|
||||
ioc.run();
|
||||
test::test_broker::run(ioc);
|
||||
BOOST_TEST(handlers_called == expected_handlers_called);
|
||||
}
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
// (See accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include "test_common/message_exchange.hpp"
|
||||
#include "test_common/test_stream.hpp"
|
||||
|
||||
#include <boost/mqtt5/logger.hpp>
|
||||
#include <boost/mqtt5/logger_traits.hpp>
|
||||
#include <boost/mqtt5/mqtt_client.hpp>
|
||||
@@ -14,7 +17,6 @@
|
||||
#include <boost/asio/detached.hpp>
|
||||
#include <boost/asio/io_context.hpp>
|
||||
#include <boost/asio/ip/tcp.hpp>
|
||||
#include <boost/asio/system_executor.hpp>
|
||||
#include <boost/system/error_code.hpp>
|
||||
#include <boost/test/tools/output_test_stream.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
@@ -25,11 +27,6 @@
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
|
||||
#include "test_common/extra_deps.hpp"
|
||||
#include "test_common/message_exchange.hpp"
|
||||
#include "test_common/preconditions.hpp"
|
||||
#include "test_common/test_stream.hpp"
|
||||
|
||||
using namespace boost::mqtt5;
|
||||
namespace asio = boost::asio;
|
||||
|
||||
@@ -102,27 +99,11 @@ struct resolve_test_data {
|
||||
std::string_view host = "localhost";
|
||||
std::string_view port = "1883";
|
||||
|
||||
asio::ip::tcp::resolver::results_type endpoints() {
|
||||
auto ex = asio::system_executor {};
|
||||
asio::ip::tcp::resolver resolver(ex);
|
||||
error_code ec;
|
||||
auto eps = resolver.resolve(host, port, ec);
|
||||
BOOST_TEST_REQUIRE(!ec);
|
||||
return eps;
|
||||
}
|
||||
|
||||
std::string endpoints_output() {
|
||||
// Endpoints resolved depend on the platform.
|
||||
auto eps = endpoints();
|
||||
std::stringstream ss;
|
||||
ss << "[";
|
||||
for (auto it = eps.begin(); it != eps.end();) {
|
||||
ss << it->endpoint().address().to_string();
|
||||
if (++it != eps.end())
|
||||
ss << ",";
|
||||
}
|
||||
ss << "]";
|
||||
return ss.str();
|
||||
auto endpoints() {
|
||||
return asio::ip::tcp::resolver::results_type::create(
|
||||
{ asio::ip::make_address("127.0.0.1"), 1883 },
|
||||
std::string(host), std::string(port)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -165,7 +146,7 @@ BOOST_FIXTURE_TEST_CASE(at_resolve_info, resolve_test_data) {
|
||||
|
||||
BOOST_FIXTURE_TEST_CASE(at_resolve_success_debug, resolve_test_data) {
|
||||
const auto expected_output =
|
||||
"[Boost.MQTT5] resolve: localhost:1883 - " + success_msg() + ". " + endpoints_output() + "\n"
|
||||
"[Boost.MQTT5] resolve: localhost:1883 - " + success_msg() + ". [127.0.0.1]\n"
|
||||
;
|
||||
|
||||
auto test_fun = [this] {
|
||||
@@ -479,11 +460,11 @@ BOOST_AUTO_TEST_CASE(client_disconnect) {
|
||||
c.brokers("127.0.0.1,127.0.0.1") // to avoid reconnect backoff
|
||||
.async_run(asio::detached);
|
||||
|
||||
asio::steady_timer timer(c.get_executor());
|
||||
test::test_timer timer(c.get_executor());
|
||||
timer.expires_after(100ms);
|
||||
timer.async_wait([&c](error_code) { c.cancel(); });
|
||||
|
||||
ioc.run();
|
||||
broker.run(ioc);
|
||||
BOOST_TEST(broker.received_all_expected());
|
||||
}
|
||||
|
||||
@@ -538,11 +519,11 @@ BOOST_AUTO_TEST_CASE(client_transport_error) {
|
||||
c.brokers("127.0.0.1,127.0.0.1") // to avoid reconnect backoff
|
||||
.async_run(asio::detached);
|
||||
|
||||
asio::steady_timer timer(c.get_executor());
|
||||
test::test_timer timer(c.get_executor());
|
||||
timer.expires_after(100ms);
|
||||
timer.async_wait([&c](error_code) { c.cancel(); });
|
||||
|
||||
ioc.run();
|
||||
broker.run(ioc);
|
||||
BOOST_TEST(broker.received_all_expected());
|
||||
}
|
||||
|
||||
@@ -550,72 +531,4 @@ BOOST_AUTO_TEST_CASE(client_transport_error) {
|
||||
BOOST_TEST(log == expected_msg);
|
||||
}
|
||||
|
||||
#ifdef BOOST_MQTT5_EXTRA_DEPS
|
||||
using stream_type = boost::beast::websocket::stream<
|
||||
asio::ssl::stream<asio::ip::tcp::socket>
|
||||
>;
|
||||
using context_type = asio::ssl::context;
|
||||
using logger_type = logger;
|
||||
using client_type = mqtt_client<stream_type, context_type, logger_type>;
|
||||
|
||||
BOOST_AUTO_TEST_CASE(client_successful_connect_debug,
|
||||
* boost::unit_test::precondition(test::public_broker_cond))
|
||||
{
|
||||
boost::test_tools::output_test_stream output;
|
||||
|
||||
{
|
||||
clog_redirect guard(output.rdbuf());
|
||||
asio::io_context ioc;
|
||||
|
||||
asio::ssl::context tls_context(asio::ssl::context::tls_client);
|
||||
client_type c(
|
||||
ioc, std::move(tls_context), logger(log_level::debug)
|
||||
);
|
||||
|
||||
c.brokers("broker.hivemq.com/mqtt", 8884)
|
||||
.async_run(asio::detached);
|
||||
|
||||
c.async_disconnect([](error_code) {});
|
||||
|
||||
ioc.run();
|
||||
}
|
||||
|
||||
std::string log = output.rdbuf()->str();
|
||||
BOOST_TEST_MESSAGE(log);
|
||||
BOOST_TEST_WARN(contains(log, "resolve"));
|
||||
BOOST_TEST_WARN(contains(log, "TCP connect"));
|
||||
BOOST_TEST_WARN(contains(log, "TLS handshake"));
|
||||
BOOST_TEST_WARN(contains(log, "WebSocket handshake"));
|
||||
BOOST_TEST_WARN(contains(log, "connack"));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(client_successful_connect_warning,
|
||||
* boost::unit_test::precondition(test::public_broker_cond))
|
||||
{
|
||||
boost::test_tools::output_test_stream output;
|
||||
|
||||
{
|
||||
clog_redirect guard(output.rdbuf());
|
||||
|
||||
asio::io_context ioc;
|
||||
asio::ssl::context tls_context(asio::ssl::context::tls_client);
|
||||
client_type c(
|
||||
ioc, std::move(tls_context), logger(log_level::warning)
|
||||
);
|
||||
|
||||
c.brokers("broker.hivemq.com/mqtt", 8884)
|
||||
.async_run(asio::detached);
|
||||
|
||||
c.async_disconnect([](error_code) {});
|
||||
|
||||
ioc.run();
|
||||
}
|
||||
|
||||
// If connection is successful, nothing should be printed.
|
||||
// However if the Broker is down or overloaded, this will cause logs to be printed.
|
||||
// We should not fail the test because of it.
|
||||
BOOST_TEST_WARN(output.is_empty());
|
||||
}
|
||||
#endif // BOOST_MQTT5_EXTRA_DEPS
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END();
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
// (See accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include "test_common/message_exchange.hpp"
|
||||
#include "test_common/test_stream.hpp"
|
||||
|
||||
#include <boost/mqtt5/mqtt_client.hpp>
|
||||
#include <boost/mqtt5/types.hpp>
|
||||
|
||||
@@ -18,9 +21,6 @@
|
||||
#include <limits>
|
||||
#include <string>
|
||||
|
||||
#include "test_common/message_exchange.hpp"
|
||||
#include "test_common/test_stream.hpp"
|
||||
|
||||
using namespace boost::mqtt5;
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(ping/*, *boost::unit_test::disabled()*/)
|
||||
@@ -72,13 +72,13 @@ void run_test(
|
||||
.keep_alive(keep_alive)
|
||||
.async_run(asio::detached);
|
||||
|
||||
asio::steady_timer timer(c.get_executor());
|
||||
test::test_timer timer(c.get_executor());
|
||||
timer.expires_after(cancel_timeout);
|
||||
timer.async_wait([&c](error_code) {
|
||||
c.cancel();
|
||||
});
|
||||
|
||||
ioc.run();
|
||||
broker.run(ioc);
|
||||
BOOST_TEST(broker.received_all_expected());
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
// (See accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include "test_common/test_service.hpp"
|
||||
|
||||
#include <boost/mqtt5/types.hpp>
|
||||
|
||||
#include <boost/mqtt5/impl/client_service.hpp>
|
||||
@@ -14,7 +16,6 @@
|
||||
#include <boost/asio/cancellation_signal.hpp>
|
||||
#include <boost/asio/io_context.hpp>
|
||||
#include <boost/asio/ip/tcp.hpp>
|
||||
#include <boost/asio/steady_timer.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <chrono>
|
||||
@@ -23,8 +24,6 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "test_common/test_service.hpp"
|
||||
|
||||
using namespace boost::mqtt5;
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(publish_send_op/*, *boost::unit_test::disabled()*/)
|
||||
@@ -50,7 +49,7 @@ BOOST_AUTO_TEST_CASE(pid_overrun) {
|
||||
"test", "payload", retain_e::no, {}
|
||||
);
|
||||
|
||||
ioc.run_for(std::chrono::milliseconds(500));
|
||||
ioc.poll();
|
||||
BOOST_TEST(handlers_called == expected_handlers_called);
|
||||
}
|
||||
|
||||
@@ -78,7 +77,7 @@ void run_test(
|
||||
> { svc_ptr, std::move(handler) }
|
||||
.perform(topic_name, payload, retain_e::yes, pprops);
|
||||
|
||||
ioc.run_for(std::chrono::milliseconds(500));
|
||||
ioc.poll();
|
||||
BOOST_TEST(handlers_called == expected_handlers_called);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,12 +5,16 @@
|
||||
// (See accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include "test_common/message_exchange.hpp"
|
||||
#include "test_common/packet_util.hpp"
|
||||
#include "test_common/test_authenticators.hpp"
|
||||
#include "test_common/test_stream.hpp"
|
||||
|
||||
#include <boost/mqtt5/mqtt_client.hpp>
|
||||
#include <boost/mqtt5/types.hpp>
|
||||
|
||||
#include <boost/asio/detached.hpp>
|
||||
#include <boost/asio/io_context.hpp>
|
||||
#include <boost/asio/steady_timer.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <chrono>
|
||||
@@ -19,12 +23,6 @@
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
|
||||
#include "test_common/message_exchange.hpp"
|
||||
#include "test_common/packet_util.hpp"
|
||||
#include "test_common/test_authenticators.hpp"
|
||||
#include "test_common/test_broker.hpp"
|
||||
#include "test_common/test_stream.hpp"
|
||||
|
||||
using namespace boost::mqtt5;
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(re_authentication/*, *boost::unit_test::disabled()*/)
|
||||
@@ -87,7 +85,7 @@ void run_test(
|
||||
|
||||
c.async_run(asio::detached);
|
||||
|
||||
asio::steady_timer timer(c.get_executor());
|
||||
test::test_timer timer(c.get_executor());
|
||||
// wait until the connection is established
|
||||
timer.expires_after(20ms);
|
||||
timer.async_wait([&](error_code) {
|
||||
@@ -97,7 +95,7 @@ void run_test(
|
||||
timer.async_wait([&c](error_code) { c.cancel(); });
|
||||
});
|
||||
|
||||
ioc.run();
|
||||
broker.run(ioc);
|
||||
BOOST_TEST(broker.received_all_expected());
|
||||
}
|
||||
|
||||
@@ -5,13 +5,15 @@
|
||||
// (See accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include "test_common/message_exchange.hpp"
|
||||
#include "test_common/test_stream.hpp"
|
||||
|
||||
#include <boost/mqtt5/mqtt_client.hpp>
|
||||
#include <boost/mqtt5/types.hpp>
|
||||
|
||||
#include <boost/asio/any_completion_handler.hpp>
|
||||
#include <boost/asio/detached.hpp>
|
||||
#include <boost/asio/io_context.hpp>
|
||||
#include <boost/asio/steady_timer.hpp>
|
||||
#include <boost/test/data/test_case.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
@@ -19,9 +21,6 @@
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
#include "test_common/message_exchange.hpp"
|
||||
#include "test_common/test_stream.hpp"
|
||||
|
||||
using namespace boost::mqtt5;
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(read_message/*, *boost::unit_test::disabled()*/)
|
||||
@@ -69,11 +68,11 @@ void test_receive_malformed_packet(
|
||||
c.brokers("127.0.0.1,127.0.0.1") // to avoid reconnect backoff
|
||||
.async_run(asio::detached);
|
||||
|
||||
asio::steady_timer timer(c.get_executor());
|
||||
test::test_timer timer(c.get_executor());
|
||||
timer.expires_after(100ms);
|
||||
timer.async_wait([&c](error_code) { c.cancel(); });
|
||||
|
||||
ioc.run();
|
||||
broker.run(ioc);
|
||||
BOOST_TEST(broker.received_all_expected());
|
||||
}
|
||||
|
||||
@@ -167,11 +166,11 @@ BOOST_FIXTURE_TEST_CASE(receive_disconnect, shared_test_data) {
|
||||
c.brokers("127.0.0.1,127.0.0.1") // to avoid reconnect backoff
|
||||
.async_run(asio::detached);
|
||||
|
||||
asio::steady_timer timer(c.get_executor());
|
||||
test::test_timer timer(c.get_executor());
|
||||
timer.expires_after(100ms);
|
||||
timer.async_wait([&c](error_code) { c.cancel(); });
|
||||
|
||||
ioc.run();
|
||||
broker.run(ioc);
|
||||
BOOST_TEST(broker.received_all_expected());
|
||||
}
|
||||
|
||||
@@ -216,7 +215,7 @@ BOOST_FIXTURE_TEST_CASE(receive_disconnect_while_reconnecting, shared_test_data)
|
||||
}
|
||||
);
|
||||
|
||||
ioc.run_for(1s);
|
||||
broker.run(ioc);
|
||||
BOOST_TEST(handlers_called == expected_handlers_called);
|
||||
BOOST_TEST(broker.received_all_expected());
|
||||
}
|
||||
@@ -253,7 +252,7 @@ void run_receive_test(
|
||||
c.cancel();
|
||||
});
|
||||
|
||||
ioc.run();
|
||||
broker.run(ioc);
|
||||
BOOST_TEST(handlers_called == expected_handlers_called);
|
||||
BOOST_TEST(broker.received_all_expected());
|
||||
}
|
||||
@@ -5,24 +5,23 @@
|
||||
// (See accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include "test_common/message_exchange.hpp"
|
||||
#include "test_common/packet_util.hpp"
|
||||
#include "test_common/test_broker.hpp"
|
||||
#include "test_common/test_stream.hpp"
|
||||
|
||||
#include <boost/mqtt5/mqtt_client.hpp>
|
||||
#include <boost/mqtt5/types.hpp>
|
||||
|
||||
#include <boost/algorithm/string/join.hpp>
|
||||
#include <boost/asio/detached.hpp>
|
||||
#include <boost/asio/io_context.hpp>
|
||||
#include <boost/asio/steady_timer.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "test_common/message_exchange.hpp"
|
||||
#include "test_common/packet_util.hpp"
|
||||
#include "test_common/test_broker.hpp"
|
||||
#include "test_common/test_stream.hpp"
|
||||
|
||||
using namespace boost::mqtt5;
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(receive_publish/*, *boost::unit_test::disabled()*/)
|
||||
@@ -91,7 +90,7 @@ void run_test(
|
||||
}
|
||||
);
|
||||
|
||||
ioc.run_for(3s);
|
||||
broker.run(ioc);
|
||||
BOOST_TEST(handlers_called == expected_handlers_called);
|
||||
BOOST_TEST(broker.received_all_expected());
|
||||
}
|
||||
@@ -206,7 +205,7 @@ BOOST_FIXTURE_TEST_CASE(receive_publish_properties, shared_test_data) {
|
||||
}
|
||||
);
|
||||
|
||||
ioc.run();
|
||||
broker.run(ioc);
|
||||
BOOST_TEST(handlers_called == expected_handlers_called);
|
||||
BOOST_TEST(broker.received_all_expected());
|
||||
}
|
||||
@@ -469,7 +468,7 @@ BOOST_FIXTURE_TEST_CASE(receive_buffer_overflow, shared_test_data) {
|
||||
c.brokers("127.0.0.1")
|
||||
.async_run(asio::detached);
|
||||
|
||||
asio::steady_timer timer(executor);
|
||||
test::test_timer timer(executor);
|
||||
timer.expires_after(10s);
|
||||
timer.async_wait(
|
||||
[&](error_code) {
|
||||
@@ -487,7 +486,7 @@ BOOST_FIXTURE_TEST_CASE(receive_buffer_overflow, shared_test_data) {
|
||||
}
|
||||
);
|
||||
|
||||
ioc.run();
|
||||
broker.run(ioc);
|
||||
BOOST_TEST(handlers_called == expected_handlers_called);
|
||||
BOOST_TEST(broker.received_all_expected());
|
||||
}
|
||||
@@ -5,7 +5,12 @@
|
||||
// (See accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include "test_common/test_autoconnect_stream.hpp"
|
||||
#include "test_common/test_broker.hpp"
|
||||
#include "test_common/test_stream.hpp"
|
||||
|
||||
#include <boost/mqtt5/logger_traits.hpp>
|
||||
#include <boost/mqtt5/logger.hpp>
|
||||
|
||||
#include <boost/mqtt5/detail/log_invoke.hpp>
|
||||
|
||||
@@ -20,10 +25,6 @@
|
||||
#include <chrono>
|
||||
#include <memory>
|
||||
|
||||
#include "test_common/test_autoconnect_stream.hpp"
|
||||
#include "test_common/test_broker.hpp"
|
||||
#include "test_common/test_stream.hpp"
|
||||
|
||||
using namespace boost::mqtt5;
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
@@ -132,7 +133,7 @@ void run_connect_to_localhost_test(int succeed_after) {
|
||||
detail::reconnect_op(auto_stream, std::move(handler))
|
||||
.perform(auto_stream.stream_pointer());
|
||||
|
||||
ioc.run();
|
||||
broker.run(ioc);
|
||||
BOOST_TEST(expected_handlers_called == handlers_called);
|
||||
BOOST_TEST(broker.received_all_expected());
|
||||
}
|
||||
@@ -165,7 +166,7 @@ BOOST_AUTO_TEST_CASE(no_servers) {
|
||||
detail::reconnect_op(auto_stream, std::move(handler))
|
||||
.perform(auto_stream.stream_pointer());
|
||||
|
||||
ioc.run();
|
||||
ioc.poll();
|
||||
BOOST_TEST(expected_handlers_called == handlers_called);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,10 @@
|
||||
// (See accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include "test_common/message_exchange.hpp"
|
||||
#include "test_common/packet_util.hpp"
|
||||
#include "test_common/test_stream.hpp"
|
||||
|
||||
#include <boost/mqtt5/mqtt_client.hpp>
|
||||
#include <boost/mqtt5/types.hpp>
|
||||
|
||||
@@ -19,10 +23,6 @@
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
#include "test_common/message_exchange.hpp"
|
||||
#include "test_common/packet_util.hpp"
|
||||
#include "test_common/test_stream.hpp"
|
||||
|
||||
using namespace boost::mqtt5;
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(send_publish/*, *boost::unit_test::disabled()*/)
|
||||
@@ -101,7 +101,7 @@ void run_test(
|
||||
}
|
||||
);
|
||||
|
||||
ioc.run_for(2s);
|
||||
broker.run(ioc);
|
||||
BOOST_TEST(handlers_called == expected_handlers_called);
|
||||
BOOST_TEST(broker.received_all_expected());
|
||||
}
|
||||
@@ -551,7 +551,7 @@ void run_validation_test(
|
||||
}
|
||||
);
|
||||
|
||||
ioc.run_for(2s);
|
||||
broker.run(ioc);
|
||||
BOOST_TEST(handlers_called == expected_handlers_called);
|
||||
BOOST_TEST(broker.received_all_expected());
|
||||
}
|
||||
@@ -619,7 +619,7 @@ BOOST_FIXTURE_TEST_CASE(cancel_resending_publish, shared_test_data) {
|
||||
);
|
||||
cancel_signal.emit(asio::cancellation_type::total);
|
||||
|
||||
ioc.run_for(1s);
|
||||
broker.run(ioc);
|
||||
BOOST_TEST(handlers_called == expected_handlers_called);
|
||||
BOOST_TEST(broker.received_all_expected());
|
||||
}
|
||||
@@ -689,7 +689,7 @@ BOOST_FIXTURE_TEST_CASE(send_big_publish, shared_test_data) {
|
||||
}
|
||||
);
|
||||
|
||||
ioc.run_for(2s);
|
||||
broker.run(ioc);
|
||||
BOOST_TEST(handlers_called == expected_handlers_called);
|
||||
BOOST_TEST(broker.received_all_expected());
|
||||
}
|
||||
@@ -20,7 +20,7 @@
|
||||
#include <vector>
|
||||
|
||||
using namespace boost::mqtt5;
|
||||
using byte_citer = detail::byte_citer;
|
||||
using byte_citer = decoders::byte_citer;
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(serialization/*, *boost::unit_test::disabled()*/)
|
||||
|
||||
|
||||
@@ -5,9 +5,10 @@
|
||||
// (See accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include "test_common/test_service.hpp"
|
||||
|
||||
#include <boost/asio/io_context.hpp>
|
||||
#include <boost/asio/ip/tcp.hpp>
|
||||
#include <boost/asio/steady_timer.hpp>
|
||||
#include <boost/mqtt5.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
@@ -15,8 +16,6 @@
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
#include "test_common/test_service.hpp"
|
||||
|
||||
using namespace boost::mqtt5;
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(session/*, *boost::unit_test::disabled()*/)
|
||||
@@ -50,8 +49,8 @@ BOOST_AUTO_TEST_CASE(clear_waiting_on_pubrel) {
|
||||
detail::publish_rec_op<client_service_type> { svc_ptr }.perform(pub_msg);
|
||||
|
||||
// let publish_rec_op reach wait_on_pubrel stage
|
||||
asio::steady_timer timer(ioc.get_executor());
|
||||
timer.expires_after(std::chrono::milliseconds(50));
|
||||
test::test_timer timer(ioc.get_executor());
|
||||
timer.expires_after(std::chrono::milliseconds(1));
|
||||
timer.async_wait([&svc_ptr](error_code) {
|
||||
BOOST_TEST(svc_ptr.use_count() == 2);
|
||||
svc_ptr->update_session_state(); // session_present = false
|
||||
@@ -59,7 +58,7 @@ BOOST_AUTO_TEST_CASE(clear_waiting_on_pubrel) {
|
||||
BOOST_TEST(svc_ptr.use_count() == 1);
|
||||
});
|
||||
|
||||
ioc.run();
|
||||
test::test_broker::run(ioc);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -5,6 +5,10 @@
|
||||
// (See accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include "test_common/message_exchange.hpp"
|
||||
#include "test_common/packet_util.hpp"
|
||||
#include "test_common/test_stream.hpp"
|
||||
|
||||
#include <boost/mqtt5/mqtt_client.hpp>
|
||||
#include <boost/mqtt5/types.hpp>
|
||||
|
||||
@@ -20,10 +24,6 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "test_common/message_exchange.hpp"
|
||||
#include "test_common/packet_util.hpp"
|
||||
#include "test_common/test_stream.hpp"
|
||||
|
||||
using namespace boost::mqtt5;
|
||||
|
||||
namespace boost::mqtt5::test {
|
||||
@@ -89,7 +89,7 @@ void run_test(
|
||||
|
||||
test_body(c, handlers_called);
|
||||
|
||||
ioc.run_for(5s);
|
||||
broker.run(ioc);
|
||||
BOOST_TEST(handlers_called == expected_handlers_called);
|
||||
BOOST_TEST(broker.received_all_expected());
|
||||
}
|
||||
@@ -5,6 +5,8 @@
|
||||
// (See accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include "test_common/test_service.hpp"
|
||||
|
||||
#include <boost/mqtt5/types.hpp>
|
||||
|
||||
#include <boost/mqtt5/impl/subscribe_op.hpp>
|
||||
@@ -19,8 +21,6 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "test_common/test_service.hpp"
|
||||
|
||||
using namespace boost::mqtt5;
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(subscribe_op/*, *boost::unit_test::disabled()*/)
|
||||
@@ -47,7 +47,7 @@ BOOST_AUTO_TEST_CASE(pid_overrun) {
|
||||
{ { "topic", { qos_e::exactly_once } } }, subscribe_props {}
|
||||
);
|
||||
|
||||
ioc.run_for(std::chrono::milliseconds(500));
|
||||
ioc.poll();
|
||||
BOOST_TEST(handlers_called == expected_handlers_called);
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ void run_test(
|
||||
> { svc_ptr, std::move(handler) }
|
||||
.perform(topics, sprops);
|
||||
|
||||
ioc.run_for(std::chrono::milliseconds(500));
|
||||
ioc.poll();
|
||||
BOOST_TEST(handlers_called == expected_handlers_called);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
// (See accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include "test_common/test_broker.hpp"
|
||||
#include "test_common/extra_deps.hpp"
|
||||
|
||||
#include <boost/mqtt5/mqtt_client.hpp>
|
||||
|
||||
#include <boost/mqtt5/detail/any_authenticator.hpp>
|
||||
@@ -20,8 +23,6 @@
|
||||
#include <string_view>
|
||||
#include <type_traits>
|
||||
|
||||
#include "test_common/extra_deps.hpp"
|
||||
|
||||
using namespace boost::mqtt5;
|
||||
|
||||
struct good_authenticator {
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
// (See accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include "test_common/test_service.hpp"
|
||||
|
||||
#include <boost/mqtt5/types.hpp>
|
||||
|
||||
#include <boost/mqtt5/impl/unsubscribe_op.hpp>
|
||||
@@ -19,8 +21,6 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "test_common/test_service.hpp"
|
||||
|
||||
using namespace boost::mqtt5;
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(unsubscribe_op/*, *boost::unit_test::disabled()*/)
|
||||
@@ -45,7 +45,7 @@ BOOST_AUTO_TEST_CASE(pid_overrun) {
|
||||
> { svc_ptr, std::move(handler) }
|
||||
.perform({ "topic" }, unsubscribe_props {});
|
||||
|
||||
ioc.run_for(std::chrono::milliseconds(500));
|
||||
ioc.poll();
|
||||
BOOST_TEST(handlers_called == expected_handlers_called);
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ void run_test(
|
||||
> { svc_ptr, std::move(handler) }
|
||||
.perform(topics, uprops);
|
||||
|
||||
ioc.run_for(std::chrono::milliseconds(500));
|
||||
ioc.poll();
|
||||
BOOST_TEST(handlers_called == expected_handlers_called);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user