1
0
mirror of https://github.com/eclipse/paho.mqtt.cpp.git synced 2025-05-10 03:39:07 +08:00
paho.mqtt.cpp/test/cppunit/client_test.h

524 lines
16 KiB
C++

// client_test.h
// Unit tests for the client class in the Paho MQTT C++ library.
/*******************************************************************************
* Copyright (c) 2017 Guilherme M. Ferreira <guilherme.maciel.ferreira@gmail.com>
*
* 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 <stdexcept>
#include <vector>
#include <cppunit/ui/text/TestRunner.h>
#include <cppunit/extensions/HelperMacros.h>
#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<int>::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<int>::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