From 85ef3e70e4b8888576707da9c9036fea80e669a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Korina=20=C5=A0imi=C4=8Devi=C4=87?= Date: Tue, 23 Jan 2024 08:04:37 +0100 Subject: [PATCH] Simplify and shorten unit test code - part 2 Summary: related to T12015 Reviewers: ivica Reviewed By: ivica Subscribers: miljen, iljazovic Differential Revision: https://repo.mireo.local/D27502 --- include/async_mqtt5/impl/subscribe_op.hpp | 2 +- test/unit/subscribe_op.cpp | 310 +++++++--------------- test/unit/unsubscribe_op.cpp | 176 ++++++------ 3 files changed, 180 insertions(+), 308 deletions(-) diff --git a/include/async_mqtt5/impl/subscribe_op.hpp b/include/async_mqtt5/impl/subscribe_op.hpp index 5103bc2..4d1d369 100644 --- a/include/async_mqtt5/impl/subscribe_op.hpp +++ b/include/async_mqtt5/impl/subscribe_op.hpp @@ -229,7 +229,7 @@ private: return (min_subscription_identifier <= *sub_id && *sub_id <= max_subscription_identifier) ? error_code {} : - client::error::subscription_identifier_not_available; + client::error::malformed_packet; } static std::vector to_reason_codes( diff --git a/test/unit/subscribe_op.cpp b/test/unit/subscribe_op.cpp index 7c5058a..9978143 100644 --- a/test/unit/subscribe_op.cpp +++ b/test/unit/subscribe_op.cpp @@ -10,7 +10,7 @@ using namespace async_mqtt5; BOOST_AUTO_TEST_SUITE(subscribe_op/*, *boost::unit_test::disabled()*/) -BOOST_AUTO_TEST_CASE(test_pid_overrun) { +BOOST_AUTO_TEST_CASE(pid_overrun) { constexpr int expected_handlers_called = 1; int handlers_called = 0; @@ -18,7 +18,7 @@ BOOST_AUTO_TEST_CASE(test_pid_overrun) { using client_service_type = test::overrun_client; auto svc_ptr = std::make_shared(ioc.get_executor(), ""); - auto handler = [&handlers_called](error_code ec, std::vector rcs, auto) { + auto handler = [&handlers_called](error_code ec, std::vector rcs, suback_props) { ++handlers_called; BOOST_CHECK(ec == client::error::pid_overrun); BOOST_ASSERT(rcs.size() == 1); @@ -36,246 +36,136 @@ BOOST_AUTO_TEST_CASE(test_pid_overrun) { BOOST_CHECK_EQUAL(handlers_called, expected_handlers_called); } -BOOST_AUTO_TEST_CASE(test_invalid_topic_filters) { - std::vector invalid_topics = { - "", "+topic", "#topic", "some/#/topic", "topic+", - "$share//topic" - }; - const int expected_handlers_called = static_cast(invalid_topics.size()); +void run_test( + error_code expected_ec, const std::string& topic_filter, + const subscribe_props& sprops = {}, const connack_props& cprops = {} +) { + constexpr int expected_handlers_called = 1; int handlers_called = 0; asio::io_context ioc; using client_service_type = test::test_service; - auto svc_ptr = std::make_shared(ioc.get_executor()); + auto svc_ptr = std::make_shared(ioc.get_executor(), cprops); - for (const auto& topic: invalid_topics) { - auto handler = [&handlers_called](error_code ec, std::vector rcs, auto) { + auto handler = [&handlers_called, expected_ec] + (error_code ec, std::vector rcs, suback_props) { ++handlers_called; - BOOST_CHECK(ec == client::error::invalid_topic); + + BOOST_CHECK(ec == expected_ec); BOOST_ASSERT(rcs.size() == 1); BOOST_CHECK_EQUAL(rcs[0], reason_codes::empty); }; - detail::subscribe_op< - client_service_type, decltype(handler) - > { svc_ptr, std::move(handler) } - .perform({{ topic, { qos_e::exactly_once } }}, subscribe_props {}); - } - - ioc.run_for(std::chrono::milliseconds(500)); - BOOST_CHECK_EQUAL(handlers_called, expected_handlers_called); -} - - -BOOST_AUTO_TEST_CASE(test_malformed_packet) { - std::vector test_properties = { - std::string(75000, 'a'), std::string(10, char(0x01)) - }; - - const int expected_handlers_called = static_cast(test_properties.size()); - int handlers_called = 0; - - asio::io_context ioc; - using client_service_type = test::test_service; - auto svc_ptr = std::make_shared(ioc.get_executor()); - - for (const auto& test_prop: test_properties) { - auto handler = [&handlers_called](error_code ec, std::vector rcs, auto) { - ++handlers_called; - BOOST_CHECK(ec == client::error::malformed_packet); - BOOST_ASSERT(rcs.size() == 1); - BOOST_CHECK_EQUAL(rcs[0], reason_codes::empty); - }; - - subscribe_props props; - props[prop::user_property].push_back(test_prop); - - detail::subscribe_op< - client_service_type, decltype(handler) - > { svc_ptr, std::move(handler) } - .perform({ { "topic", { qos_e::exactly_once } } }, props - ); - } - - ioc.run_for(std::chrono::milliseconds(500)); - BOOST_CHECK_EQUAL(handlers_called, expected_handlers_called); -} - -BOOST_AUTO_TEST_CASE(test_wildcard_subscriptions_not_supported) { - std::vector wildcard_topics = { - "topic/#", "$share/grp/topic/#" - }; - connack_props props; - props[prop::wildcard_subscription_available] = uint8_t(0); - - int expected_handlers_called = static_cast(wildcard_topics.size()); - int handlers_called = 0; - - asio::io_context ioc; - using client_service_type = test::test_service; - auto svc_ptr = std::make_shared( - ioc.get_executor(), std::move(props) - ); - BOOST_ASSERT(svc_ptr->connack_property(prop::wildcard_subscription_available) == 0); - - for (const auto& topic: wildcard_topics) { - auto handler = [&handlers_called](error_code ec, std::vector rcs, auto) { - ++handlers_called; - BOOST_CHECK(ec == client::error::wildcard_subscription_not_available); - BOOST_ASSERT(rcs.size() == 1); - BOOST_CHECK_EQUAL(rcs[0], reason_codes::empty); - }; - - detail::subscribe_op< - client_service_type, decltype(handler) - > { svc_ptr, std::move(handler) } - .perform( - {{ topic, { qos_e::exactly_once } }}, subscribe_props {} - ); - } - - ioc.run_for(std::chrono::milliseconds(500)); - BOOST_CHECK_EQUAL(handlers_called, expected_handlers_called); -} - -BOOST_AUTO_TEST_CASE(test_shared_subscriptions_not_supported) { - connack_props props; - props[prop::shared_subscription_available] = uint8_t(0); - - constexpr int expected_handlers_called = 1; - int handlers_called = 0; - - asio::io_context ioc; - using client_service_type = test::test_service; - auto svc_ptr = std::make_shared( - ioc.get_executor(), std::move(props) - ); - BOOST_ASSERT(svc_ptr->connack_property(prop::shared_subscription_available) == 0); - - auto handler = [&handlers_called](error_code ec, std::vector rcs, auto) { - ++handlers_called; - BOOST_CHECK(ec == client::error::shared_subscription_not_available); - BOOST_ASSERT(rcs.size() == 1); - BOOST_CHECK_EQUAL(rcs[0], reason_codes::empty); - }; - detail::subscribe_op< client_service_type, decltype(handler) > { svc_ptr, std::move(handler) } .perform( - {{ "$share/group/topic", { qos_e::exactly_once } }}, subscribe_props {} + { { topic_filter, { qos_e::exactly_once } } }, sprops ); ioc.run_for(std::chrono::milliseconds(500)); BOOST_CHECK_EQUAL(handlers_called, expected_handlers_called); } -BOOST_AUTO_TEST_CASE(test_large_subscription_id) { - uint8_t sub_id_available = 1; - - connack_props props; - props[prop::subscription_identifier_available] = sub_id_available; - - constexpr int expected_handlers_called = 1; - int handlers_called = 0; - - asio::io_context ioc; - using client_service_type = test::test_service; - auto svc_ptr = std::make_shared( - ioc.get_executor(), std::move(props) - ); - BOOST_ASSERT(svc_ptr->connack_property(prop::subscription_identifier_available) == sub_id_available); - - auto handler = [&handlers_called](error_code ec, std::vector rcs, auto) { - ++handlers_called; - BOOST_CHECK(ec == client::error::subscription_identifier_not_available); - BOOST_ASSERT(rcs.size() == 1); - BOOST_CHECK_EQUAL(rcs[0], reason_codes::empty); - }; - - subscribe_props sub_props_big_id {}; - sub_props_big_id[prop::subscription_identifier] = std::numeric_limits::max(); - - detail::subscribe_op< - client_service_type, decltype(handler) - > { svc_ptr, std::move(handler) } - .perform( - {{ "topic", { qos_e::exactly_once } }}, sub_props_big_id - ); - - ioc.run_for(std::chrono::milliseconds(500)); - BOOST_CHECK_EQUAL(handlers_called, expected_handlers_called); +BOOST_AUTO_TEST_CASE(invalid_topic_filter_1) { + run_test(client::error::invalid_topic, ""); } -BOOST_AUTO_TEST_CASE(test_subscription_ids_not_supported) { - uint8_t sub_id_available = 0; - - connack_props props; - props[prop::subscription_identifier_available] = sub_id_available; - - constexpr int expected_handlers_called = 1; - int handlers_called = 0; - - asio::io_context ioc; - using client_service_type = test::test_service; - auto svc_ptr = std::make_shared( - ioc.get_executor(), std::move(props) - ); - BOOST_ASSERT(svc_ptr->connack_property(prop::subscription_identifier_available) == sub_id_available); - - auto handler = [&handlers_called](error_code ec, std::vector rcs, auto) { - ++handlers_called; - BOOST_CHECK(ec == client::error::subscription_identifier_not_available); - BOOST_ASSERT(rcs.size() == 1); - BOOST_CHECK_EQUAL(rcs[0], reason_codes::empty); - }; - - subscribe_props sub_props {}; - sub_props[prop::subscription_identifier] = 23; - - detail::subscribe_op< - client_service_type, decltype(handler) - > { svc_ptr, std::move(handler) } - .perform( - {{ "topic", { qos_e::exactly_once } }}, sub_props - ); - - ioc.run_for(std::chrono::milliseconds(500)); - BOOST_CHECK_EQUAL(handlers_called, expected_handlers_called); +BOOST_AUTO_TEST_CASE(invalid_topic_filter_2) { + run_test(client::error::invalid_topic, "+topic"); } -BOOST_AUTO_TEST_CASE(test_packet_too_large) { - int max_packet_sz = 10; +BOOST_AUTO_TEST_CASE(invalid_topic_filter_3) { + run_test(client::error::invalid_topic, "topic+"); +} - connack_props props; - props[prop::maximum_packet_size] = max_packet_sz; +BOOST_AUTO_TEST_CASE(invalid_topic_filter_4) { + run_test(client::error::invalid_topic, "#topic"); +} - constexpr int expected_handlers_called = 1; - int handlers_called = 0; +BOOST_AUTO_TEST_CASE(invalid_topic_filter_5) { + run_test(client::error::invalid_topic, "some/#/topic"); +} - asio::io_context ioc; - using client_service_type = test::test_service; - auto svc_ptr = std::make_shared( - ioc.get_executor(), std::move(props) +BOOST_AUTO_TEST_CASE(invalid_topic_filter_6) { + run_test(client::error::invalid_topic, "$share//topic#"); +} + +BOOST_AUTO_TEST_CASE(malformed_user_property_1) { + subscribe_props sprops; + sprops[prop::user_property].push_back(std::string(10, char(0x01))); + + run_test(client::error::malformed_packet, "topic", sprops); +} + +BOOST_AUTO_TEST_CASE(malformed_user_property_2) { + subscribe_props sprops; + sprops[prop::user_property].push_back(std::string(75000, 'a')); + + run_test(client::error::malformed_packet, "topic", sprops); +} + +BOOST_AUTO_TEST_CASE(wildcard_subscriptions_not_available_1) { + connack_props cprops; + cprops[prop::wildcard_subscription_available] = uint8_t(0); + + run_test( + client::error::wildcard_subscription_not_available, "topic/#", + subscribe_props {}, cprops ); - BOOST_ASSERT(svc_ptr->connack_property(prop::maximum_packet_size) == max_packet_sz); +} - auto handler = [&handlers_called](error_code ec, std::vector rcs, auto) { - ++handlers_called; - BOOST_CHECK(ec == client::error::packet_too_large); - BOOST_ASSERT(rcs.size() == 1); - BOOST_CHECK_EQUAL(rcs[0], reason_codes::empty); - }; +BOOST_AUTO_TEST_CASE(wildcard_subscriptions_not_available_2) { + connack_props cprops; + cprops[prop::wildcard_subscription_available] = uint8_t(0); - detail::subscribe_op< - client_service_type, decltype(handler) - > { svc_ptr, std::move(handler) } - .perform( - { { "topic", { qos_e::exactly_once } } }, subscribe_props {} + run_test( + client::error::wildcard_subscription_not_available, "$share/grp/topic/#", + subscribe_props {}, cprops ); +} - ioc.run_for(std::chrono::milliseconds(500)); - BOOST_CHECK_EQUAL(handlers_called, expected_handlers_called); +BOOST_AUTO_TEST_CASE(shared_subscriptions_not_available) { + connack_props cprops; + cprops[prop::shared_subscription_available] = uint8_t(0); + + run_test( + client::error::shared_subscription_not_available, "$share/group/topic", + subscribe_props {}, cprops + ); +} + +BOOST_AUTO_TEST_CASE(subscription_id_not_available) { + connack_props cprops; + cprops[prop::subscription_identifier_available] = uint8_t(0); + + subscribe_props sprops; + sprops[prop::subscription_identifier] = 23; + + run_test( + client::error::subscription_identifier_not_available, "topic", sprops, cprops + ); +} + +BOOST_AUTO_TEST_CASE(large_subscription_id) { + connack_props cprops; + cprops[prop::subscription_identifier_available] = uint8_t(1); + + subscribe_props sprops; + sprops[prop::subscription_identifier] = std::numeric_limits::max(); + + run_test( + client::error::malformed_packet, "topic", sprops, cprops + ); +} + +BOOST_AUTO_TEST_CASE(packet_too_large) { + connack_props cprops; + cprops[prop::maximum_packet_size] = 10; + + run_test( + client::error::packet_too_large, "very large topic", subscribe_props {}, cprops + ); } BOOST_AUTO_TEST_SUITE_END() diff --git a/test/unit/unsubscribe_op.cpp b/test/unit/unsubscribe_op.cpp index d1b18d9..626c562 100644 --- a/test/unit/unsubscribe_op.cpp +++ b/test/unit/unsubscribe_op.cpp @@ -10,7 +10,7 @@ using namespace async_mqtt5; BOOST_AUTO_TEST_SUITE(unsubscribe_op/*, *boost::unit_test::disabled()*/) -BOOST_AUTO_TEST_CASE(test_pid_overrun) { +BOOST_AUTO_TEST_CASE(pid_overrun) { constexpr int expected_handlers_called = 1; int handlers_called = 0; @@ -18,108 +18,13 @@ BOOST_AUTO_TEST_CASE(test_pid_overrun) { using client_service_type = test::overrun_client; auto svc_ptr = std::make_shared(ioc.get_executor(), ""); - auto handler = [&handlers_called](error_code ec, std::vector rcs, auto) { + auto handler = [&handlers_called](error_code ec, std::vector rcs, unsuback_props) { ++handlers_called; BOOST_CHECK(ec == client::error::pid_overrun); BOOST_ASSERT(rcs.size() == 1); BOOST_CHECK_EQUAL(rcs[0], reason_codes::empty); }; - detail::unsubscribe_op< - client_service_type, decltype(handler) - > { svc_ptr, std::move(handler) } - .perform({ "topic" }, unsubscribe_props{}); - - ioc.run_for(std::chrono::milliseconds(500)); - BOOST_CHECK_EQUAL(handlers_called, expected_handlers_called); -} - -BOOST_AUTO_TEST_CASE(test_invalid_topic_filters) { - std::vector invalid_topics = { - "", "+topic", "#topic", "some/#/topic", "topic+" - }; - const int expected_handlers_called = static_cast(invalid_topics.size()); - int handlers_called = 0; - - asio::io_context ioc; - using client_service_type = test::test_service; - auto svc_ptr = std::make_shared(ioc.get_executor()); - - for (const auto& topic: invalid_topics) { - auto handler = [&handlers_called](error_code ec, std::vector rcs, auto) { - ++handlers_called; - BOOST_CHECK(ec == client::error::invalid_topic); - BOOST_ASSERT(rcs.size() == 1); - BOOST_CHECK_EQUAL(rcs[0], reason_codes::empty); - }; - - detail::unsubscribe_op< - client_service_type, decltype(handler) - > { svc_ptr, std::move(handler) } - .perform({ topic }, unsubscribe_props{}); - } - - ioc.run_for(std::chrono::milliseconds(500)); - BOOST_CHECK_EQUAL(handlers_called, expected_handlers_called); -} - - -BOOST_AUTO_TEST_CASE(test_malformed_packet) { - std::vector test_properties = { - std::string(75000, 'a'), std::string(10, char(0x01)) - }; - - const int expected_handlers_called = static_cast(test_properties.size()); - int handlers_called = 0; - - asio::io_context ioc; - using client_service_type = test::test_service; - auto svc_ptr = std::make_shared(ioc.get_executor()); - - for (const auto& test_prop: test_properties) { - auto handler = [&handlers_called](error_code ec, std::vector rcs, auto) { - ++handlers_called; - BOOST_CHECK(ec == client::error::malformed_packet); - BOOST_ASSERT(rcs.size() == 1); - BOOST_CHECK_EQUAL(rcs[0], reason_codes::empty); - }; - - unsubscribe_props props; - props[prop::user_property].push_back(test_prop); - - detail::unsubscribe_op< - client_service_type, decltype(handler) - > { svc_ptr, std::move(handler) } - .perform({ "topic" }, props); - } - - ioc.run_for(std::chrono::milliseconds(500)); - BOOST_CHECK_EQUAL(handlers_called, expected_handlers_called); -} - -BOOST_AUTO_TEST_CASE(test_packet_too_large) { - int max_packet_sz = 10; - - connack_props props; - props[prop::maximum_packet_size] = max_packet_sz; - - constexpr int expected_handlers_called = 1; - int handlers_called = 0; - - asio::io_context ioc; - using client_service_type = test::test_service; - auto svc_ptr = std::make_shared( - ioc.get_executor(), std::move(props) - ); - BOOST_ASSERT(svc_ptr->connack_property(prop::maximum_packet_size) == max_packet_sz); - - auto handler = [&handlers_called](error_code ec, std::vector rcs, auto) { - ++handlers_called; - BOOST_CHECK(ec == client::error::packet_too_large); - BOOST_ASSERT(rcs.size() == 1); - BOOST_CHECK_EQUAL(rcs[0], reason_codes::empty); - }; - detail::unsubscribe_op< client_service_type, decltype(handler) > { svc_ptr, std::move(handler) } @@ -129,4 +34,81 @@ BOOST_AUTO_TEST_CASE(test_packet_too_large) { BOOST_CHECK_EQUAL(handlers_called, expected_handlers_called); } +void run_test( + error_code expected_ec, const std::string& topic_filter, + const unsubscribe_props& uprops = {}, const connack_props& cprops = {} +) { + constexpr int expected_handlers_called = 1; + int handlers_called = 0; + + asio::io_context ioc; + using client_service_type = test::test_service; + auto svc_ptr = std::make_shared(ioc.get_executor(), cprops); + + auto handler = [&handlers_called, expected_ec] + (error_code ec, std::vector rcs, unsuback_props) { + ++handlers_called; + + BOOST_CHECK(ec == expected_ec); + BOOST_ASSERT(rcs.size() == 1); + BOOST_CHECK_EQUAL(rcs[0], reason_codes::empty); + }; + + detail::unsubscribe_op< + client_service_type, decltype(handler) + > { svc_ptr, std::move(handler) } + .perform({ topic_filter }, uprops); + + ioc.run_for(std::chrono::milliseconds(500)); + BOOST_CHECK_EQUAL(handlers_called, expected_handlers_called); +} + +BOOST_AUTO_TEST_CASE(invalid_topic_filter_1) { + run_test(client::error::invalid_topic, ""); +} + +BOOST_AUTO_TEST_CASE(invalid_topic_filter_2) { + run_test(client::error::invalid_topic, "+topic"); +} + +BOOST_AUTO_TEST_CASE(invalid_topic_filter_3) { + run_test(client::error::invalid_topic, "topic+"); +} + +BOOST_AUTO_TEST_CASE(invalid_topic_filter_4) { + run_test(client::error::invalid_topic, "#topic"); +} + +BOOST_AUTO_TEST_CASE(invalid_topic_filter_5) { + run_test(client::error::invalid_topic, "some/#/topic"); +} + +BOOST_AUTO_TEST_CASE(invalid_topic_filter_6) { + run_test(client::error::invalid_topic, "some/topic#"); +} + +BOOST_AUTO_TEST_CASE(malformed_user_property_1) { + unsubscribe_props uprops; + uprops[prop::user_property].push_back(std::string(10, char(0x01))); + + run_test(client::error::malformed_packet, "topic", uprops); +} + +BOOST_AUTO_TEST_CASE(malformed_user_property_2) { + unsubscribe_props uprops; + uprops[prop::user_property].push_back(std::string(75000, 'a')); + + run_test(client::error::malformed_packet, "topic", uprops); +} + +BOOST_AUTO_TEST_CASE(packet_too_large) { + connack_props cprops; + cprops[prop::maximum_packet_size] = 10; + + run_test( + client::error::packet_too_large, "very large topic", + unsubscribe_props {}, cprops + ); +} + BOOST_AUTO_TEST_SUITE_END()