diff --git a/test/cppunit/client_test.h b/test/cppunit/client_test.h deleted file mode 100644 index e573ec6..0000000 --- a/test/cppunit/client_test.h +++ /dev/null @@ -1,523 +0,0 @@ -// client_test.h -// Unit tests for the client class in the Paho MQTT C++ library. - -/******************************************************************************* - * Copyright (c) 2017 Guilherme M. Ferreira - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Guilherme M. Ferreira - initial implementation and documentation - * Frank Pagliughi - updated tests for modified v1.0 client API - *******************************************************************************/ - -#ifndef __mqtt_client_test_h -#define __mqtt_client_test_h - -#include -#include - -#include -#include - -#include "mqtt/client.h" - -#include "dummy_client_persistence.h" -#include "dummy_callback.h" - -namespace mqtt { - -///////////////////////////////////////////////////////////////////////////// - -class client_test : public CppUnit::TestFixture -{ - CPPUNIT_TEST_SUITE( client_test ); - - CPPUNIT_TEST( test_user_constructor_2_string_args ); - CPPUNIT_TEST( test_user_constructor_3_string_args ); - CPPUNIT_TEST( test_user_constructor_3_args ); - - CPPUNIT_TEST( test_connect_0_arg ); - CPPUNIT_TEST( test_connect_1_arg ); - CPPUNIT_TEST( test_connect_1_arg_failure ); - - CPPUNIT_TEST( test_disconnect_0_arg ); - CPPUNIT_TEST( test_disconnect_1_arg ); - CPPUNIT_TEST( test_disconnect_1_arg_failure ); - - CPPUNIT_TEST( test_timeout_int ); - CPPUNIT_TEST( test_timeout_duration ); - - CPPUNIT_TEST( test_get_topic ); - - CPPUNIT_TEST( test_publish_pointer_2_args ); - CPPUNIT_TEST( test_publish_pointer_2_args_failure ); - CPPUNIT_TEST( test_publish_reference_2_args ); - CPPUNIT_TEST( test_publish_5_args ); - - CPPUNIT_TEST( test_set_callback ); - - CPPUNIT_TEST( test_subscribe_single_topic_1_arg ); - CPPUNIT_TEST( test_subscribe_single_topic_1_arg_failure ); - CPPUNIT_TEST( test_subscribe_single_topic_2_args ); - CPPUNIT_TEST( test_subscribe_single_topic_2_args_failure ); - CPPUNIT_TEST( test_subscribe_many_topics_1_arg ); - CPPUNIT_TEST( test_subscribe_many_topics_1_arg_failure ); - CPPUNIT_TEST( test_subscribe_many_topics_2_args ); - CPPUNIT_TEST( test_subscribe_many_topics_2_args_failure ); - - CPPUNIT_TEST( test_unsubscribe_single_topic_1_arg ); - CPPUNIT_TEST( test_unsubscribe_single_topic_1_arg_failure ); - CPPUNIT_TEST( test_unsubscribe_many_topics_1_arg ); - CPPUNIT_TEST( test_unsubscribe_many_topics_1_arg_failure ); - - CPPUNIT_TEST_SUITE_END(); - - // NOTE: This test case requires network access. It uses one of - // the public available MQTT brokers - #if defined(TEST_EXTERNAL_SERVER) - const std::string GOOD_SERVER_URI { "tcp://mqtt.eclipse.org:1883" }; - #else - const std::string GOOD_SERVER_URI { "tcp://localhost:1883" }; - #endif - const std::string BAD_SERVER_URI { "one://invalid.address" }; - const std::string CLIENT_ID { "client_test" }; - const std::string PERSISTENCE_DIR { "/tmp" }; - const std::string TOPIC { "TOPIC" }; - const int GOOD_QOS { 0 }; - const int BAD_QOS { 3 }; - mqtt::string_collection TOPIC_COLL { "TOPIC0", "TOPIC1", "TOPIC2" }; - mqtt::client::qos_collection GOOD_QOS_COLL { 0, 1, 2 }; - mqtt::client::qos_collection BAD_QOS_COLL { BAD_QOS }; - const std::string PAYLOAD { "PAYLOAD" }; - //const int TIMEOUT { 1000 }; - //int CONTEXT { 4 }; - mqtt::test::dummy_action_listener listener; - const bool RETAINED { false }; - -public: - void setUp() {} - void tearDown() {} - -//---------------------------------------------------------------------- -// Test constructors client::client() -//---------------------------------------------------------------------- - - void test_user_constructor_2_string_args() { - mqtt::client cli { GOOD_SERVER_URI, CLIENT_ID }; - - CPPUNIT_ASSERT_EQUAL(GOOD_SERVER_URI, cli.get_server_uri()); - CPPUNIT_ASSERT_EQUAL(CLIENT_ID, cli.get_client_id()); - } - - void test_user_constructor_2_string_args_failure() { - int return_code = MQTTASYNC_SUCCESS; - try { - mqtt::client cli { BAD_SERVER_URI, CLIENT_ID }; - } catch (mqtt::exception& ex) { - return_code = ex.get_return_code(); - } - CPPUNIT_ASSERT_EQUAL(MQTTASYNC_BAD_PROTOCOL, return_code); - } - - void test_user_constructor_3_string_args() { - mqtt::client cli { GOOD_SERVER_URI, CLIENT_ID, PERSISTENCE_DIR }; - - CPPUNIT_ASSERT_EQUAL(GOOD_SERVER_URI, cli.get_server_uri()); - CPPUNIT_ASSERT_EQUAL(CLIENT_ID, cli.get_client_id()); - } - - void test_user_constructor_3_args() { - mqtt::test::dummy_client_persistence cp; - mqtt::client cli { GOOD_SERVER_URI, CLIENT_ID, &cp }; - - CPPUNIT_ASSERT_EQUAL(GOOD_SERVER_URI, cli.get_server_uri()); - CPPUNIT_ASSERT_EQUAL(CLIENT_ID, cli.get_client_id()); - - mqtt::client cli_no_persistence { GOOD_SERVER_URI, CLIENT_ID, nullptr }; - - CPPUNIT_ASSERT_EQUAL(GOOD_SERVER_URI, cli_no_persistence.get_server_uri()); - CPPUNIT_ASSERT_EQUAL(CLIENT_ID, cli_no_persistence.get_client_id()); - } - -//---------------------------------------------------------------------- -// Test client::connect() -//---------------------------------------------------------------------- - - void test_connect_0_arg() { - mqtt::client cli { GOOD_SERVER_URI, CLIENT_ID }; - CPPUNIT_ASSERT_EQUAL(false, cli.is_connected()); - - cli.connect(); - CPPUNIT_ASSERT(cli.is_connected()); - } - - void test_connect_1_arg() { - mqtt::client cli { GOOD_SERVER_URI, CLIENT_ID }; - CPPUNIT_ASSERT_EQUAL(false, cli.is_connected()); - - mqtt::connect_options co; - cli.connect(co); - CPPUNIT_ASSERT(cli.is_connected()); - } - - void test_connect_1_arg_failure() { - mqtt::client cli { GOOD_SERVER_URI, CLIENT_ID }; - CPPUNIT_ASSERT_EQUAL(false, cli.is_connected()); - - mqtt::connect_options co; - mqtt::will_options wo; - wo.set_qos(BAD_QOS); // Invalid QoS causes connection failure - co.set_will(wo); - int return_code = MQTTASYNC_SUCCESS; - try { - cli.connect(co); - } catch (mqtt::exception& ex) { - return_code = ex.get_return_code(); - } - CPPUNIT_ASSERT_EQUAL(false, cli.is_connected()); - CPPUNIT_ASSERT_EQUAL(MQTTASYNC_BAD_QOS, return_code); - } - -//---------------------------------------------------------------------- -// Test client::disconnect() -//---------------------------------------------------------------------- - - void test_disconnect_0_arg() { - mqtt::client cli { GOOD_SERVER_URI, CLIENT_ID }; - CPPUNIT_ASSERT_EQUAL(false, cli.is_connected()); - - cli.connect(); - CPPUNIT_ASSERT(cli.is_connected()); - - cli.disconnect(); - CPPUNIT_ASSERT_EQUAL(false, cli.is_connected()); - } - - void test_disconnect_1_arg() { - mqtt::client cli { GOOD_SERVER_URI, CLIENT_ID }; - CPPUNIT_ASSERT_EQUAL(false, cli.is_connected()); - - cli.connect(); - CPPUNIT_ASSERT(cli.is_connected()); - - cli.disconnect(0); - CPPUNIT_ASSERT_EQUAL(false, cli.is_connected()); - } - - void test_disconnect_1_arg_failure() { - mqtt::client cli { GOOD_SERVER_URI, CLIENT_ID }; - CPPUNIT_ASSERT_EQUAL(false, cli.is_connected()); - - int return_code = MQTTASYNC_SUCCESS; - try { - cli.disconnect(0); - } catch (mqtt::exception& ex) { - return_code = ex.get_return_code(); - } - CPPUNIT_ASSERT_EQUAL(false, cli.is_connected()); - CPPUNIT_ASSERT_EQUAL(MQTTASYNC_DISCONNECTED, return_code); - } - -//---------------------------------------------------------------------- -// Test client::get_timeout() and client::set_timeout() using ints -//---------------------------------------------------------------------- - - void test_timeout_int() { - mqtt::client cli { GOOD_SERVER_URI, CLIENT_ID }; - CPPUNIT_ASSERT_EQUAL(false, cli.is_connected()); - - int timeout { std::numeric_limits::min() }; - cli.set_timeout(timeout); - CPPUNIT_ASSERT_EQUAL(timeout, (int) cli.get_timeout().count()); - - timeout = 0; - cli.set_timeout(timeout); - CPPUNIT_ASSERT_EQUAL(timeout, (int) cli.get_timeout().count()); - - timeout = std::numeric_limits::max(); - cli.set_timeout(timeout); - CPPUNIT_ASSERT_EQUAL(timeout, (int) cli.get_timeout().count()); - } - -//---------------------------------------------------------------------- -// Test client::get_timeout() and client::set_timeout() using durations -//---------------------------------------------------------------------- - - void test_timeout_duration() { - const int TIMEOUT_SEC = 120; - mqtt::client cli { GOOD_SERVER_URI, CLIENT_ID }; - - std::chrono::seconds timeout{ TIMEOUT_SEC }; - cli.set_timeout(timeout); - CPPUNIT_ASSERT(timeout == cli.get_timeout()); - CPPUNIT_ASSERT_EQUAL(TIMEOUT_SEC*1000, (int) cli.get_timeout().count()); - } - -//---------------------------------------------------------------------- -// Test client::get_topic() -//---------------------------------------------------------------------- - - void test_get_topic() { - mqtt::client cli { GOOD_SERVER_URI, CLIENT_ID }; - CPPUNIT_ASSERT_EQUAL(false, cli.is_connected()); - - mqtt::topic t { cli.get_topic(TOPIC) }; - CPPUNIT_ASSERT_EQUAL(TOPIC, t.get_name()); - } - -//---------------------------------------------------------------------- -// Test client::publish() -//---------------------------------------------------------------------- - - void test_publish_pointer_2_args() { - mqtt::client cli { GOOD_SERVER_URI, CLIENT_ID }; - CPPUNIT_ASSERT_EQUAL(false, cli.is_connected()); - - cli.connect(); - CPPUNIT_ASSERT(cli.is_connected()); - - mqtt::message_ptr msg { mqtt::message::create(TOPIC, PAYLOAD) }; - cli.publish(msg); - - cli.disconnect(); - CPPUNIT_ASSERT_EQUAL(false, cli.is_connected()); - } - - void test_publish_pointer_2_args_failure() { - mqtt::client cli { GOOD_SERVER_URI, CLIENT_ID }; - CPPUNIT_ASSERT_EQUAL(false, cli.is_connected()); - - int return_code = MQTTASYNC_SUCCESS; - try { - mqtt::message_ptr msg { mqtt::message::create(TOPIC, PAYLOAD) }; - cli.publish(msg); - } catch (mqtt::exception& ex) { - return_code = ex.get_return_code(); - } - CPPUNIT_ASSERT_EQUAL(MQTTASYNC_DISCONNECTED, return_code); - } - - void test_publish_reference_2_args() { - mqtt::client cli { GOOD_SERVER_URI, CLIENT_ID }; - CPPUNIT_ASSERT_EQUAL(false, cli.is_connected()); - - cli.connect(); - CPPUNIT_ASSERT(cli.is_connected()); - - mqtt::message msg { TOPIC, PAYLOAD }; - cli.publish(msg); - - cli.disconnect(); - CPPUNIT_ASSERT_EQUAL(false, cli.is_connected()); - } - - void test_publish_5_args() { - mqtt::client cli { GOOD_SERVER_URI, CLIENT_ID }; - CPPUNIT_ASSERT_EQUAL(false, cli.is_connected()); - - cli.connect(); - CPPUNIT_ASSERT(cli.is_connected()); - - const void* payload { PAYLOAD.c_str() }; - const size_t payload_size { PAYLOAD.size() }; - cli.publish(TOPIC, payload, payload_size, GOOD_QOS, RETAINED); - - cli.disconnect(); - CPPUNIT_ASSERT_EQUAL(false, cli.is_connected()); - } - -//---------------------------------------------------------------------- -// Test client::set_callback() -//---------------------------------------------------------------------- - - void test_set_callback() { - mqtt::client cli { GOOD_SERVER_URI, CLIENT_ID }; - CPPUNIT_ASSERT_EQUAL(false, cli.is_connected()); - - mqtt::test::dummy_callback cb; - cli.set_callback(cb); - } - -//---------------------------------------------------------------------- -// Test client::subscribe() -//---------------------------------------------------------------------- - - void test_subscribe_single_topic_1_arg() { - mqtt::client cli { GOOD_SERVER_URI, CLIENT_ID }; - CPPUNIT_ASSERT_EQUAL(false, cli.is_connected()); - - cli.connect(); - CPPUNIT_ASSERT(cli.is_connected()); - - cli.subscribe(TOPIC); - - cli.disconnect(); - CPPUNIT_ASSERT_EQUAL(false, cli.is_connected()); - } - - void test_subscribe_single_topic_1_arg_failure() { - mqtt::client cli { GOOD_SERVER_URI, CLIENT_ID }; - CPPUNIT_ASSERT_EQUAL(false, cli.is_connected()); - - int return_code = MQTTASYNC_SUCCESS; - try { - cli.subscribe(TOPIC); - } catch (mqtt::exception& ex) { - return_code = ex.get_return_code(); - } - CPPUNIT_ASSERT_EQUAL(MQTTASYNC_DISCONNECTED, return_code); - } - - void test_subscribe_single_topic_2_args() { - mqtt::client cli { GOOD_SERVER_URI, CLIENT_ID }; - CPPUNIT_ASSERT_EQUAL(false, cli.is_connected()); - - cli.connect(); - CPPUNIT_ASSERT(cli.is_connected()); - - cli.subscribe(TOPIC, GOOD_QOS); - - cli.disconnect(); - CPPUNIT_ASSERT_EQUAL(false, cli.is_connected()); - } - - void test_subscribe_single_topic_2_args_failure() { - mqtt::client cli { GOOD_SERVER_URI, CLIENT_ID }; - CPPUNIT_ASSERT_EQUAL(false, cli.is_connected()); - - int return_code = MQTTASYNC_SUCCESS; - try { - cli.subscribe(TOPIC, BAD_QOS); - } catch (mqtt::exception& ex) { - return_code = ex.get_return_code(); - } - CPPUNIT_ASSERT_EQUAL(MQTTASYNC_DISCONNECTED, return_code); - } - - void test_subscribe_many_topics_1_arg() { - mqtt::client cli { GOOD_SERVER_URI, CLIENT_ID }; - CPPUNIT_ASSERT_EQUAL(false, cli.is_connected()); - - cli.connect(); - CPPUNIT_ASSERT(cli.is_connected()); - - cli.subscribe(TOPIC_COLL); - - cli.disconnect(); - CPPUNIT_ASSERT_EQUAL(false, cli.is_connected()); - } - - void test_subscribe_many_topics_1_arg_failure() { - mqtt::client cli { GOOD_SERVER_URI, CLIENT_ID }; - CPPUNIT_ASSERT_EQUAL(false, cli.is_connected()); - - int return_code = MQTTASYNC_SUCCESS; - try { - cli.subscribe(TOPIC_COLL); - } catch (mqtt::exception& ex) { - return_code = ex.get_return_code(); - } - CPPUNIT_ASSERT_EQUAL(MQTTASYNC_DISCONNECTED, return_code); - } - - void test_subscribe_many_topics_2_args() { - mqtt::client cli { GOOD_SERVER_URI, CLIENT_ID }; - CPPUNIT_ASSERT_EQUAL(false, cli.is_connected()); - - cli.connect(); - CPPUNIT_ASSERT(cli.is_connected()); - - cli.subscribe(TOPIC_COLL, GOOD_QOS_COLL); - - cli.disconnect(); - CPPUNIT_ASSERT_EQUAL(false, cli.is_connected()); - } - - void test_subscribe_many_topics_2_args_failure() { - mqtt::client cli { GOOD_SERVER_URI, CLIENT_ID }; - CPPUNIT_ASSERT_EQUAL(false, cli.is_connected()); - - try { - cli.subscribe(TOPIC_COLL, BAD_QOS_COLL); - } catch (std::invalid_argument& ex) {} - - int return_code = MQTTASYNC_SUCCESS; - try { - cli.subscribe(TOPIC_COLL, GOOD_QOS_COLL); - } catch (mqtt::exception& ex) { - return_code = ex.get_return_code(); - } - CPPUNIT_ASSERT_EQUAL(MQTTASYNC_DISCONNECTED, return_code); - } - -//---------------------------------------------------------------------- -// Test client::unsubscribe() -//---------------------------------------------------------------------- - - void test_unsubscribe_single_topic_1_arg() { - mqtt::client cli { GOOD_SERVER_URI, CLIENT_ID }; - CPPUNIT_ASSERT_EQUAL(false, cli.is_connected()); - - cli.connect(); - CPPUNIT_ASSERT(cli.is_connected()); - - cli.unsubscribe(TOPIC); - - cli.disconnect(); - CPPUNIT_ASSERT_EQUAL(false, cli.is_connected()); - } - - void test_unsubscribe_single_topic_1_arg_failure() { - mqtt::client cli { GOOD_SERVER_URI, CLIENT_ID }; - CPPUNIT_ASSERT_EQUAL(false, cli.is_connected()); - - int return_code = MQTTASYNC_SUCCESS; - try { - cli.unsubscribe(TOPIC); - } catch (mqtt::exception& ex) { - return_code = ex.get_return_code(); - } - CPPUNIT_ASSERT_EQUAL(MQTTASYNC_DISCONNECTED, return_code); - } - - void test_unsubscribe_many_topics_1_arg() { - mqtt::client cli { GOOD_SERVER_URI, CLIENT_ID }; - CPPUNIT_ASSERT_EQUAL(false, cli.is_connected()); - - cli.connect(); - CPPUNIT_ASSERT(cli.is_connected()); - - cli.unsubscribe(TOPIC_COLL); - - cli.disconnect(); - CPPUNIT_ASSERT_EQUAL(false, cli.is_connected()); - } - - void test_unsubscribe_many_topics_1_arg_failure() { - mqtt::client cli { GOOD_SERVER_URI, CLIENT_ID }; - CPPUNIT_ASSERT_EQUAL(false, cli.is_connected()); - - int return_code = MQTTASYNC_SUCCESS; - try { - cli.unsubscribe(TOPIC_COLL); - } catch (mqtt::exception& ex) { - return_code = ex.get_return_code(); - } - CPPUNIT_ASSERT_EQUAL(MQTTASYNC_DISCONNECTED, return_code); - } - -}; - -///////////////////////////////////////////////////////////////////////////// -// end namespace mqtt -} - -#endif // __mqtt_client_test_h diff --git a/test/cppunit/test.cpp b/test/cppunit/test.cpp index a5badce..9f0d74f 100644 --- a/test/cppunit/test.cpp +++ b/test/cppunit/test.cpp @@ -19,7 +19,6 @@ #include "async_client_test.h" #include "async_client_v3_test.h" -#include "client_test.h" using namespace CppUnit; @@ -29,7 +28,6 @@ int main(int argc, char* argv[]) { CPPUNIT_TEST_SUITE_REGISTRATION( mqtt::async_client_test ); CPPUNIT_TEST_SUITE_REGISTRATION( mqtt::async_client_v3_test ); - CPPUNIT_TEST_SUITE_REGISTRATION( mqtt::client_test ); TextUi::TestRunner runner; TestFactoryRegistry ®istry = TestFactoryRegistry::getRegistry(); diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt index 3429d6c..a45688e 100644 --- a/test/unit/CMakeLists.txt +++ b/test/unit/CMakeLists.txt @@ -30,6 +30,7 @@ find_package(Catch2 REQUIRED) add_executable(unit_tests unit_tests.cpp test_buffer_ref.cpp + test_client.cpp test_connect_options.cpp test_create_options.cpp test_disconnect_options.cpp diff --git a/test/unit/test_client.cpp b/test/unit/test_client.cpp new file mode 100644 index 0000000..a5c670b --- /dev/null +++ b/test/unit/test_client.cpp @@ -0,0 +1,514 @@ +// client_test.h +// +// Unit tests for the client class in the Paho MQTT C++ library. +// + +/******************************************************************************* + * Copyright (c) 2017 Guilherme M. Ferreira + * Copyright (c) 2020 Frank Pagliughi + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * http://www.eclipse.org/legal/epl-v10.html + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Guilherme M. Ferreira + * - initial implementation and documentation + * Frank Pagliughi + * - updated tests for modified v1.0 client API + * - Converted to use Catch2 + *******************************************************************************/ + +#define UNIT_TESTS + +#include "catch2/catch.hpp" +#include "mqtt/client.h" +#include "mock_persistence.h" +#include "mock_callback.h" +#include "mock_action_listener.h" + +using namespace std::chrono; +using namespace mqtt; + +///////////////////////////////////////////////////////////////////////////// + +// NOTE: This test case requires network access. It uses one of +// the public available MQTT brokers +#if defined(TEST_EXTERNAL_SERVER) + static const std::string GOOD_SERVER_URI { "tcp://mqtt.eclipse.org:1883" }; +#else + static const std::string GOOD_SERVER_URI { "tcp://localhost:1883" }; +#endif +static const std::string BAD_SERVER_URI { "one://invalid.address" }; +static const std::string CLIENT_ID { "client_test" }; +static const std::string PERSISTENCE_DIR { "/tmp" }; +static const std::string TOPIC { "TOPIC" }; +static const int GOOD_QOS { 0 }; +static const int BAD_QOS { 3 }; + +static mqtt::string_collection TOPIC_COLL { "TOPIC0", "TOPIC1", "TOPIC2" }; +static mqtt::client::qos_collection GOOD_QOS_COLL { 0, 1, 2 }; +static mqtt::client::qos_collection BAD_QOS_COLL { BAD_QOS }; + +static const std::string PAYLOAD { "PAYLOAD" }; +//const int TIMEOUT { 1000 }; +//int CONTEXT { 4 }; +static mock_action_listener listener; +static const bool RETAINED { false }; + +//---------------------------------------------------------------------- +// Test constructors client::client() +//---------------------------------------------------------------------- + +TEST_CASE("client user constructor 2 string args", "[client]") +{ + mqtt::client cli{GOOD_SERVER_URI, CLIENT_ID}; + + REQUIRE(GOOD_SERVER_URI == cli.get_server_uri()); + REQUIRE(CLIENT_ID == cli.get_client_id()); +} + +TEST_CASE("client user constructor 2 string args failure", "[client]") +{ + int return_code = MQTTASYNC_SUCCESS; + try { + mqtt::client cli{BAD_SERVER_URI, CLIENT_ID}; + } + catch (mqtt::exception& ex) { + return_code = ex.get_return_code(); + } + REQUIRE(MQTTASYNC_BAD_PROTOCOL == return_code); +} + +TEST_CASE("client user constructor 3 string args", "[client]") +{ + mqtt::client cli{GOOD_SERVER_URI, CLIENT_ID, PERSISTENCE_DIR}; + + REQUIRE(GOOD_SERVER_URI == cli.get_server_uri()); + REQUIRE(CLIENT_ID == cli.get_client_id()); +} + +#if 0 +TEST_CASE("client user constructor 3 args", "[client]") +{ + mock_persistence cp; + mqtt::client cli{GOOD_SERVER_URI, CLIENT_ID, &cp}; + + REQUIRE(GOOD_SERVER_URI == cli.get_server_uri()); + REQUIRE(CLIENT_ID == cli.get_client_id()); + + mqtt::client cli_no_persistence{GOOD_SERVER_URI, CLIENT_ID, nullptr}; + + REQUIRE(GOOD_SERVER_URI == cli_no_persistence.get_server_uri()); + REQUIRE(CLIENT_ID == cli_no_persistence.get_client_id()); +} +#endif + +//---------------------------------------------------------------------- +// Test client::connect() +//---------------------------------------------------------------------- + +TEST_CASE("client connect 0 arg", "[client]") +{ + mqtt::client cli{GOOD_SERVER_URI, CLIENT_ID}; + REQUIRE(!cli.is_connected()); + + cli.connect(); + REQUIRE(cli.is_connected()); +} + +TEST_CASE("client connect 1 arg", "[client]") +{ + mqtt::client cli{GOOD_SERVER_URI, CLIENT_ID}; + REQUIRE(!cli.is_connected()); + + mqtt::connect_options co; + cli.connect(co); + REQUIRE(cli.is_connected()); +} + +TEST_CASE("client connect 1 arg failure", "[client]") +{ + mqtt::client cli{GOOD_SERVER_URI, CLIENT_ID}; + REQUIRE(!cli.is_connected()); + + mqtt::connect_options co; + mqtt::will_options wo; + wo.set_qos(BAD_QOS); // Invalid QoS causes connection failure + co.set_will(wo); + int return_code = MQTTASYNC_SUCCESS; + try { + cli.connect(co); + } + catch (mqtt::exception& ex) { + return_code = ex.get_return_code(); + } + REQUIRE(!cli.is_connected()); + REQUIRE(MQTTASYNC_BAD_QOS == return_code); +} + +//---------------------------------------------------------------------- +// Test client::disconnect() +//---------------------------------------------------------------------- + +TEST_CASE("client disconnect 0 arg", "[client]") +{ + mqtt::client cli{GOOD_SERVER_URI, CLIENT_ID}; + REQUIRE(!cli.is_connected()); + + cli.connect(); + REQUIRE(cli.is_connected()); + + cli.disconnect(); + REQUIRE(!cli.is_connected()); +} + +TEST_CASE("client disconnect 1 arg", "[client]") +{ + mqtt::client cli{GOOD_SERVER_URI, CLIENT_ID}; + REQUIRE(!cli.is_connected()); + + cli.connect(); + REQUIRE(cli.is_connected()); + + cli.disconnect(0); + REQUIRE(!cli.is_connected()); +} + +TEST_CASE("client disconnect 1 arg failure", "[client]") +{ + mqtt::client cli{GOOD_SERVER_URI, CLIENT_ID}; + REQUIRE(!cli.is_connected()); + + int return_code = MQTTASYNC_SUCCESS; + try { + cli.disconnect(0); + } + catch (mqtt::exception& ex) { + return_code = ex.get_return_code(); + } + REQUIRE(!cli.is_connected()); + REQUIRE(MQTTASYNC_DISCONNECTED == return_code); +} + +//---------------------------------------------------------------------- +// Test client::get_timeout() and client::set_timeout() using ints +//---------------------------------------------------------------------- + +TEST_CASE("client timeout int", "[client]") +{ + mqtt::client cli{GOOD_SERVER_URI, CLIENT_ID}; + REQUIRE(!cli.is_connected()); + + int timeout{std::numeric_limits::min()}; + cli.set_timeout(timeout); + REQUIRE(timeout == (int) cli.get_timeout().count()); + + timeout = 0; + cli.set_timeout(timeout); + REQUIRE(timeout == (int) cli.get_timeout().count()); + + timeout = std::numeric_limits::max(); + cli.set_timeout(timeout); + REQUIRE(timeout == (int) cli.get_timeout().count()); +} + +//---------------------------------------------------------------------- +// Test client::get_timeout() and client::set_timeout() using durations +//---------------------------------------------------------------------- + +TEST_CASE("client timeout duration", "[client]") +{ + const int TIMEOUT_SEC = 120; + mqtt::client cli{GOOD_SERVER_URI, CLIENT_ID}; + + std::chrono::seconds timeout{TIMEOUT_SEC}; + cli.set_timeout(timeout); + REQUIRE(timeout == cli.get_timeout()); + REQUIRE(TIMEOUT_SEC * 1000 == (int) cli.get_timeout().count()); +} + +//---------------------------------------------------------------------- +// Test client::get_topic() +//---------------------------------------------------------------------- + +TEST_CASE("client get topic", "[client]") +{ + mqtt::client cli {GOOD_SERVER_URI, CLIENT_ID}; + REQUIRE(!cli.is_connected()); + + mqtt::topic t {cli.get_topic(TOPIC)}; + REQUIRE(TOPIC == t.get_name()); +} + +//---------------------------------------------------------------------- +// Test client::publish() +//---------------------------------------------------------------------- + +TEST_CASE("client publish pointer 2 args", "[client]") +{ + mqtt::client cli{GOOD_SERVER_URI, CLIENT_ID}; + REQUIRE(!cli.is_connected()); + + cli.connect(); + REQUIRE(cli.is_connected()); + + mqtt::message_ptr msg{mqtt::message::create(TOPIC, PAYLOAD)}; + cli.publish(msg); + + cli.disconnect(); + REQUIRE(!cli.is_connected()); +} + +TEST_CASE("client publish pointer 2 args failure", "[client]") +{ + mqtt::client cli{GOOD_SERVER_URI, CLIENT_ID}; + REQUIRE(!cli.is_connected()); + + int return_code = MQTTASYNC_SUCCESS; + try { + mqtt::message_ptr msg{mqtt::message::create(TOPIC, PAYLOAD)}; + cli.publish(msg); + } + catch (mqtt::exception& ex) { + return_code = ex.get_return_code(); + } + REQUIRE(MQTTASYNC_DISCONNECTED == return_code); +} + +TEST_CASE("client publish reference 2 args", "[client]") +{ + mqtt::client cli{GOOD_SERVER_URI, CLIENT_ID}; + REQUIRE(!cli.is_connected()); + + cli.connect(); + REQUIRE(cli.is_connected()); + + mqtt::message msg{TOPIC, PAYLOAD}; + cli.publish(msg); + + cli.disconnect(); + REQUIRE(!cli.is_connected()); +} + +TEST_CASE("client publish 5 args", "[client]") +{ + mqtt::client cli{GOOD_SERVER_URI, CLIENT_ID}; + REQUIRE(!cli.is_connected()); + + cli.connect(); + REQUIRE(cli.is_connected()); + + const void* payload{PAYLOAD.c_str()}; + const size_t payload_size{PAYLOAD.size()}; + cli.publish(TOPIC, payload, payload_size, GOOD_QOS, RETAINED); + + cli.disconnect(); + REQUIRE(!cli.is_connected()); +} + +//---------------------------------------------------------------------- +// Test client::set_callback() +//---------------------------------------------------------------------- + +TEST_CASE("client set callback", "[client]") +{ + mqtt::client cli{GOOD_SERVER_URI, CLIENT_ID}; + REQUIRE(!cli.is_connected()); + + mock_callback cb; + cli.set_callback(cb); +} + +//---------------------------------------------------------------------- +// Test client::subscribe() +//---------------------------------------------------------------------- + +TEST_CASE("client subscribe single topic 1 arg", "[client]") +{ + mqtt::client cli{GOOD_SERVER_URI, CLIENT_ID}; + REQUIRE(!cli.is_connected()); + + cli.connect(); + REQUIRE(cli.is_connected()); + + cli.subscribe(TOPIC); + + cli.disconnect(); + REQUIRE(!cli.is_connected()); +} + +TEST_CASE("client subscribe single topic 1 arg failure", "[client]") +{ + mqtt::client cli{GOOD_SERVER_URI, CLIENT_ID}; + REQUIRE(!cli.is_connected()); + + int return_code = MQTTASYNC_SUCCESS; + try { + cli.subscribe(TOPIC); + } + catch (mqtt::exception& ex) { + return_code = ex.get_return_code(); + } + REQUIRE(MQTTASYNC_DISCONNECTED == return_code); +} + +TEST_CASE("client subscribe single topic 2 args", "[client]") +{ + mqtt::client cli{GOOD_SERVER_URI, CLIENT_ID}; + REQUIRE(!cli.is_connected()); + + cli.connect(); + REQUIRE(cli.is_connected()); + + cli.subscribe(TOPIC, GOOD_QOS); + + cli.disconnect(); + REQUIRE(!cli.is_connected()); +} + +TEST_CASE("client subscribe single topic 2 args failure", "[client]") +{ + mqtt::client cli{GOOD_SERVER_URI, CLIENT_ID}; + REQUIRE(!cli.is_connected()); + + int return_code = MQTTASYNC_SUCCESS; + try { + cli.subscribe(TOPIC, BAD_QOS); + } + catch (mqtt::exception& ex) { + return_code = ex.get_return_code(); + } + REQUIRE(MQTTASYNC_DISCONNECTED == return_code); +} + +TEST_CASE("client subscribe many topics 1 arg", "[client]") +{ + mqtt::client cli{GOOD_SERVER_URI, CLIENT_ID}; + REQUIRE(!cli.is_connected()); + + cli.connect(); + REQUIRE(cli.is_connected()); + + cli.subscribe(TOPIC_COLL); + + cli.disconnect(); + REQUIRE(!cli.is_connected()); +} + +TEST_CASE("client subscribe many topics 1 arg failure", "[client]") +{ + mqtt::client cli{GOOD_SERVER_URI, CLIENT_ID}; + REQUIRE(!cli.is_connected()); + + int return_code = MQTTASYNC_SUCCESS; + try { + cli.subscribe(TOPIC_COLL); + } + catch (mqtt::exception& ex) { + return_code = ex.get_return_code(); + } + REQUIRE(MQTTASYNC_DISCONNECTED == return_code); +} + +TEST_CASE("client subscribe many topics 2 args", "[client]") +{ + mqtt::client cli{GOOD_SERVER_URI, CLIENT_ID}; + REQUIRE(!cli.is_connected()); + + cli.connect(); + REQUIRE(cli.is_connected()); + + cli.subscribe(TOPIC_COLL, GOOD_QOS_COLL); + + cli.disconnect(); + REQUIRE(!cli.is_connected()); +} + +TEST_CASE("client subscribe many topics 2 args failure", "[client]") +{ + mqtt::client cli{GOOD_SERVER_URI, CLIENT_ID}; + REQUIRE(!cli.is_connected()); + + try { + cli.subscribe(TOPIC_COLL, BAD_QOS_COLL); + } + catch (std::invalid_argument& ex) {} + + int return_code = MQTTASYNC_SUCCESS; + try { + cli.subscribe(TOPIC_COLL, GOOD_QOS_COLL); + } + catch (mqtt::exception& ex) { + return_code = ex.get_return_code(); + } + REQUIRE(MQTTASYNC_DISCONNECTED == return_code); +} + +//---------------------------------------------------------------------- +// Test client::unsubscribe() +//---------------------------------------------------------------------- + +TEST_CASE("client unsubscribe single topic 1 arg", "[client]") +{ + mqtt::client cli{GOOD_SERVER_URI, CLIENT_ID}; + REQUIRE(!cli.is_connected()); + + cli.connect(); + REQUIRE(cli.is_connected()); + + cli.unsubscribe(TOPIC); + + cli.disconnect(); + REQUIRE(!cli.is_connected()); +} + +TEST_CASE("client unsubscribe single topic 1 arg failure", "[client]") +{ + mqtt::client cli{GOOD_SERVER_URI, CLIENT_ID}; + REQUIRE(!cli.is_connected()); + + int return_code = MQTTASYNC_SUCCESS; + try { + cli.unsubscribe(TOPIC); + } + catch (mqtt::exception& ex) { + return_code = ex.get_return_code(); + } + REQUIRE(MQTTASYNC_DISCONNECTED == return_code); +} + +TEST_CASE("client unsubscribe many topics 1 arg", "[client]") +{ + mqtt::client cli{GOOD_SERVER_URI, CLIENT_ID}; + REQUIRE(!cli.is_connected()); + + cli.connect(); + REQUIRE(cli.is_connected()); + + cli.unsubscribe(TOPIC_COLL); + + cli.disconnect(); + REQUIRE(!cli.is_connected()); +} + +TEST_CASE("client unsubscribe many topics 1 arg failure", "[client]") +{ + mqtt::client cli{GOOD_SERVER_URI, CLIENT_ID}; + REQUIRE(!cli.is_connected()); + + int return_code = MQTTASYNC_SUCCESS; + try { + cli.unsubscribe(TOPIC_COLL); + } + catch (mqtt::exception& ex) { + return_code = ex.get_return_code(); + } + REQUIRE(MQTTASYNC_DISCONNECTED == return_code); +} +