diff --git a/test/unit/async_mutex.cpp b/test/unit/async_mutex.cpp index b6c0082..6554220 100644 --- a/test/unit/async_mutex.cpp +++ b/test/unit/async_mutex.cpp @@ -127,6 +127,34 @@ BOOST_AUTO_TEST_CASE(per_op_cancellation) { BOOST_TEST(!mutex.is_locked()); } +BOOST_AUTO_TEST_CASE(cancel_ops_by_none_type) { + constexpr int expected_handlers_called = 4; + int handlers_called = 0; + + asio::io_context ioc; + asio::cancellation_signal cs; + + async_mutex mutex(asio::make_strand(ioc.get_executor())); + + for (int i = 0; i < expected_handlers_called; ++i) { + mutex.lock( + [&mutex, &handlers_called](error_code ec) { + ++handlers_called; + BOOST_TEST(!ec); + mutex.unlock(); + } + ); + } + + // Canceling with cancellation_type_t::none shouldn't cause cancellation + cs.emit(asio::cancellation_type_t::none); + cs.slot().clear(); + + ioc.poll(); + BOOST_TEST(handlers_called == expected_handlers_called); + BOOST_TEST(!mutex.is_locked()); +} + BOOST_AUTO_TEST_CASE(cancel_ops_by_destructor) { constexpr int expected_handlers_called = 2; int handlers_called = 0; diff --git a/test/unit/async_sender.cpp b/test/unit/async_sender.cpp index 35161f8..b6781e3 100644 --- a/test/unit/async_sender.cpp +++ b/test/unit/async_sender.cpp @@ -279,22 +279,34 @@ BOOST_FIXTURE_TEST_CASE(throttling, shared_test_data) { } BOOST_FIXTURE_TEST_CASE(throttling_ordering, shared_test_data) { - constexpr int expected_handlers_called = 2; + constexpr int expected_handlers_called = 4; int handlers_called = 0; // packets auto publish_qos0 = encoders::encode_publish( 0, topic, payload, qos_e::at_most_once, retain_e::no, dup_e::no, {} ); + auto publish_1_qos1 = encoders::encode_publish( + 1, topic, payload, qos_e::at_least_once, retain_e::no, dup_e::no, {} + ); + auto publish_2_qos1 = encoders::encode_publish( + 2, topic, payload, qos_e::at_least_once, retain_e::no, dup_e::no, {} + ); + + auto puback_1 = encoders::encode_puback(1, uint8_t(0x00), {}); + auto puback_2 = encoders::encode_puback(2, uint8_t(0x00), {}); test::msg_exchange broker_side; broker_side .expect(connect) .complete_with(success, after(1ms)) - .reply_with(connack, after(2ms)) - .expect(publish_qos1, publish_qos0) + .reply_with(connack_rm, after(2ms)) + .expect(publish_qos0, publish_1_qos1, publish_qos0) + .complete_with(success, after(1ms)) + .reply_with(puback_1, after(2ms)) + .expect(publish_2_qos1) .complete_with(success, after(1ms)) - .reply_with(puback, after(2ms)); + .reply_with(puback_2, after(2ms)); asio::io_context ioc; auto executor = ioc.get_executor(); @@ -307,30 +319,39 @@ BOOST_FIXTURE_TEST_CASE(throttling_ordering, shared_test_data) { c.brokers("127.0.0.1,127.0.0.1") // to avoid reconnect backoff .async_run(asio::detached); - c.async_publish( - topic, payload, retain_e::no, publish_props {}, - [&](error_code ec, reason_code rc, puback_props) { - ++handlers_called; + auto send_qos0 = [&] { + c.async_publish( + topic, payload, retain_e::no, publish_props{}, + [&](error_code ec) { + ++handlers_called; - BOOST_TEST(!ec); - BOOST_TEST(rc == reason_codes::success); + BOOST_TEST(!ec); - if (handlers_called == expected_handlers_called) - c.cancel(); - } - ); + if (handlers_called == expected_handlers_called) + c.cancel(); + } + ); + }; - c.async_publish( - topic, payload, retain_e::no, publish_props{}, - [&](error_code ec) { - ++handlers_called; + auto send_qos1 = [&] { + c.async_publish( + topic, payload, retain_e::no, publish_props {}, + [&](error_code ec, reason_code rc, puback_props) { + ++handlers_called; - BOOST_TEST(!ec); + BOOST_TEST(!ec); + BOOST_TEST(rc == reason_codes::success); - if (handlers_called == expected_handlers_called) - c.cancel(); - } - ); + if (handlers_called == expected_handlers_called) + c.cancel(); + } + ); + }; + + send_qos0(); + send_qos1(); + send_qos1(); + send_qos0(); broker.run(ioc); BOOST_TEST(handlers_called == expected_handlers_called); diff --git a/test/unit/connect_op.cpp b/test/unit/connect_op.cpp index 76d1c5b..6d6b6b0 100644 --- a/test/unit/connect_op.cpp +++ b/test/unit/connect_op.cpp @@ -204,6 +204,22 @@ BOOST_FIXTURE_TEST_CASE(fail_reading_connack_payload, shared_test_data) { run_unit_test(std::move(broker_side), std::move(handler)); } +BOOST_FIXTURE_TEST_CASE(fail_reading_connack_fixed_header, shared_test_data) { + test::msg_exchange broker_side; + broker_side + .expect(connect) + .complete_with(success, after(2ms)) + // Send only 3 bytes (min packet size is 5) + .send(std::string({0x20, 0x02, 0x00}), after(30ms)) + .send(fail, after(60ms)); + + auto handler = [&](error_code ec) { + BOOST_TEST(ec == fail); + }; + + run_unit_test(std::move(broker_side), std::move(handler)); +} + BOOST_FIXTURE_TEST_CASE(receive_unexpected_auth, shared_test_data) { auth_props aprops; aprops[prop::authentication_method] = "method"; diff --git a/test/unit/logger.cpp b/test/unit/logger.cpp index 82fecfa..e8d4860 100644 --- a/test/unit/logger.cpp +++ b/test/unit/logger.cpp @@ -105,6 +105,18 @@ struct resolve_test_data { std::string(host), std::string(port) ); } + + auto few_endpoints() { + std::vector eps; + eps.emplace_back(asio::ip::make_address("127.0.0.1"), 1883); + eps.emplace_back(asio::ip::make_address("127.0.0.2"), 1883); + eps.emplace_back(asio::ip::make_address("127.0.0.3"), 1883); + + return asio::ip::tcp::resolver::results_type::create( + eps.begin(), eps.end(), + std::string(host), std::string(port) + ); + } }; BOOST_FIXTURE_TEST_CASE(at_resolve_success_warning, resolve_test_data) { @@ -157,6 +169,20 @@ BOOST_FIXTURE_TEST_CASE(at_resolve_success_debug, resolve_test_data) { test_logger_output(std::move(test_fun), expected_output); } +BOOST_FIXTURE_TEST_CASE(at_resolve_success_debug_few_eps, resolve_test_data) { + const auto expected_output = + "[Boost.MQTT5] resolve: localhost:1883 - " + + success_msg() + ". [127.0.0.1,127.0.0.2,127.0.0.3]\n" + ; + + auto test_fun = [this] { + logger l(log_level::debug); + l.at_resolve(error_code {}, host, port, few_endpoints()); + }; + + test_logger_output(std::move(test_fun), expected_output); +} + BOOST_FIXTURE_TEST_CASE(at_resolve_fail_debug, resolve_test_data) { const auto expected_output = "[Boost.MQTT5] resolve: localhost:1883 - " + host_not_found_msg() + ". []\n" @@ -412,6 +438,17 @@ BOOST_AUTO_TEST_CASE(at_transport_error_info) { test_logger_output(std::move(test_fun), expected_output); } +BOOST_AUTO_TEST_CASE(at_transport_error_warning) { + const auto expected_output = ""; + + auto test_fun = [] { + logger l(log_level::warning); + l.at_transport_error(asio::error::eof); + }; + + test_logger_output(std::move(test_fun), expected_output); +} + // Test that the mqtt_client calls logger functions as expected. BOOST_AUTO_TEST_CASE(client_disconnect) { diff --git a/test/unit/subscribe_op.cpp b/test/unit/subscribe_op.cpp index a8001d5..9d61f88 100644 --- a/test/unit/subscribe_op.cpp +++ b/test/unit/subscribe_op.cpp @@ -73,10 +73,12 @@ void run_test( BOOST_TEST(rcs[i] == reason_codes::empty); }; - detail::subscribe_op< + auto sub_op = detail::subscribe_op< client_service_type, decltype(handler) - > { svc_ptr, std::move(handler) } - .perform(topics, sprops); + > { svc_ptr, std::move(handler) }; + + BOOST_TEST(static_cast(sub_op.get_executor() == asio::any_io_executor(ioc.get_executor()))); + sub_op.perform(topics, sprops); ioc.poll(); BOOST_TEST(handlers_called == expected_handlers_called); diff --git a/test/unit/unsubscribe_op.cpp b/test/unit/unsubscribe_op.cpp index f9e2c43..8172678 100644 --- a/test/unit/unsubscribe_op.cpp +++ b/test/unit/unsubscribe_op.cpp @@ -40,10 +40,12 @@ BOOST_AUTO_TEST_CASE(pid_overrun) { BOOST_TEST(rcs[0] == reason_codes::empty); }; - detail::unsubscribe_op< + auto unsub_op = detail::unsubscribe_op< client_service_type, decltype(handler) - > { svc_ptr, std::move(handler) } - .perform({ "topic" }, unsubscribe_props {}); + > { svc_ptr, std::move(handler) }; + + BOOST_TEST(static_cast(unsub_op.get_executor() == asio::any_io_executor(ioc.get_executor()))); + unsub_op.perform({ "topic" }, unsubscribe_props {}); ioc.poll(); BOOST_TEST(handlers_called == expected_handlers_called);