1
0
mirror of https://github.com/eclipse/paho.mqtt.cpp.git synced 2025-05-10 12:02:32 +08:00

Rewrote topic unit tests for Catch2

This commit is contained in:
fpagliughi 2020-08-23 17:51:10 -04:00
parent e337b3e173
commit 75e4701a10
5 changed files with 376 additions and 222 deletions

View File

@ -30,7 +30,6 @@
#include "delivery_response_options_test.h" #include "delivery_response_options_test.h"
#include "iclient_persistence_test.h" #include "iclient_persistence_test.h"
#include "token_test.h" #include "token_test.h"
#include "topic_test.h"
#include "exception_test.h" #include "exception_test.h"
using namespace CppUnit; using namespace CppUnit;
@ -54,7 +53,6 @@ int main(int argc, char* argv[])
CPPUNIT_TEST_SUITE_REGISTRATION( mqtt::delivery_response_options_test ); CPPUNIT_TEST_SUITE_REGISTRATION( mqtt::delivery_response_options_test );
CPPUNIT_TEST_SUITE_REGISTRATION( mqtt::iclient_persistence_test ); CPPUNIT_TEST_SUITE_REGISTRATION( mqtt::iclient_persistence_test );
CPPUNIT_TEST_SUITE_REGISTRATION( mqtt::token_test ); CPPUNIT_TEST_SUITE_REGISTRATION( mqtt::token_test );
CPPUNIT_TEST_SUITE_REGISTRATION( mqtt::topic_test );
CPPUNIT_TEST_SUITE_REGISTRATION( mqtt::exception_test ); CPPUNIT_TEST_SUITE_REGISTRATION( mqtt::exception_test );
CPPUNIT_TEST_SUITE_REGISTRATION( mqtt::async_client_test ); CPPUNIT_TEST_SUITE_REGISTRATION( mqtt::async_client_test );

View File

@ -1,220 +0,0 @@
// topic_test.h
// Unit tests for the topic class in the Paho MQTT C++ library.
/*******************************************************************************
* Copyright (c) 2016 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
*******************************************************************************/
#ifndef __mqtt_topic_test_h
#define __mqtt_topic_test_h
#include <algorithm>
#include <memory>
#include <stdexcept>
#include <cppunit/ui/text/TestRunner.h>
#include <cppunit/extensions/HelperMacros.h>
#include "mqtt/topic.h"
namespace mqtt {
/////////////////////////////////////////////////////////////////////////////
class topic_test : public CppUnit::TestFixture
{
CPPUNIT_TEST_SUITE( topic_test );
CPPUNIT_TEST( test_basic_ctor );
CPPUNIT_TEST( test_full_ctor );
CPPUNIT_TEST( test_set_qos );
CPPUNIT_TEST( test_set_retained );
CPPUNIT_TEST( test_publish_basic_c_arr );
CPPUNIT_TEST( test_publish_full_c_arr );
CPPUNIT_TEST( test_publish_basic_binary );
CPPUNIT_TEST( test_publish_basic_binary );
CPPUNIT_TEST_SUITE_END();
const int DFLT_QOS = message::DFLT_QOS;
const bool DFLT_RETAINED = message::DFLT_RETAINED;
const std::string TOPIC { "topic_name" };
const int QOS = 1;
const bool RETAINED = true;
const int BAD_LOW_QOS = -1;
const int BAD_HIGH_QOS = 3;
const char* BUF = "Hello there";
const size_t N = std::strlen(BUF);
const binary PAYLOAD { BUF };
mqtt::test::dummy_async_client cli;
public:
void setUp() {}
void tearDown() {}
// ----------------------------------------------------------------------
// Test basic constructor
// ----------------------------------------------------------------------
void test_basic_ctor() {
mqtt::topic topic{ cli, TOPIC };
CPPUNIT_ASSERT_EQUAL(static_cast<iasync_client*>(&cli),
&(topic.get_client()));
CPPUNIT_ASSERT_EQUAL(TOPIC, topic.get_name());
CPPUNIT_ASSERT_EQUAL(DFLT_QOS, topic.get_qos());
CPPUNIT_ASSERT_EQUAL(DFLT_RETAINED, topic.get_retained());
}
// ----------------------------------------------------------------------
// Test full constructor
// ----------------------------------------------------------------------
void test_full_ctor() {
mqtt::topic topic{ cli, TOPIC, QOS, RETAINED };
CPPUNIT_ASSERT_EQUAL(TOPIC, topic.get_name());
CPPUNIT_ASSERT_EQUAL(QOS, topic.get_qos());
CPPUNIT_ASSERT_EQUAL(RETAINED, topic.get_retained());
}
// ----------------------------------------------------------------------
// Test set qos
// ----------------------------------------------------------------------
void test_set_qos() {
mqtt::topic topic{ cli, TOPIC };
CPPUNIT_ASSERT_EQUAL(DFLT_QOS, topic.get_qos());
topic.set_qos(QOS);
CPPUNIT_ASSERT_EQUAL(QOS, topic.get_qos());
try {
topic.set_qos(BAD_LOW_QOS);
CPPUNIT_FAIL("topic should not accept bad (low) QOS");
}
catch (...) {}
try {
topic.set_qos(BAD_HIGH_QOS);
CPPUNIT_FAIL("topic should not accept bad (low) QOS");
}
catch (...) {}
}
// ----------------------------------------------------------------------
// Test set retained
// ----------------------------------------------------------------------
void test_set_retained() {
mqtt::topic topic{ cli, TOPIC };
CPPUNIT_ASSERT_EQUAL(DFLT_RETAINED, topic.get_retained());
topic.set_retained(RETAINED);
CPPUNIT_ASSERT_EQUAL(RETAINED, topic.get_retained());
}
// ----------------------------------------------------------------------
// Test publish with the basic C array form
// ----------------------------------------------------------------------
void test_publish_basic_c_arr() {
mqtt::topic topic{ cli, TOPIC, QOS, RETAINED };
auto tok = topic.publish(BUF, N);
CPPUNIT_ASSERT(tok);
auto msg = tok->get_message();
CPPUNIT_ASSERT(msg);
CPPUNIT_ASSERT_EQUAL(TOPIC, msg->get_topic());
CPPUNIT_ASSERT(msg->get_payload().data());
CPPUNIT_ASSERT(!memcmp(BUF, msg->get_payload().data(), N));
CPPUNIT_ASSERT_EQUAL(QOS, msg->get_qos());
CPPUNIT_ASSERT_EQUAL(RETAINED, msg->is_retained());
}
// ----------------------------------------------------------------------
// Test publish with the full C array form
// ----------------------------------------------------------------------
void test_publish_full_c_arr() {
mqtt::topic topic{ cli, TOPIC };
auto tok = topic.publish(BUF, N, QOS, RETAINED);
CPPUNIT_ASSERT(tok);
auto msg = tok->get_message();
CPPUNIT_ASSERT(msg);
CPPUNIT_ASSERT_EQUAL(TOPIC, msg->get_topic());
CPPUNIT_ASSERT(msg->get_payload().data());
CPPUNIT_ASSERT(!memcmp(BUF, msg->get_payload().data(), N));
CPPUNIT_ASSERT_EQUAL(QOS, msg->get_qos());
CPPUNIT_ASSERT_EQUAL(RETAINED, msg->is_retained());
}
// ----------------------------------------------------------------------
// Test publish with the basic C array form
// ----------------------------------------------------------------------
void test_publish_basic_binary() {
mqtt::topic topic{ cli, TOPIC, QOS, RETAINED };
auto tok = topic.publish(PAYLOAD);
CPPUNIT_ASSERT(tok);
auto msg = tok->get_message();
CPPUNIT_ASSERT(msg);
CPPUNIT_ASSERT_EQUAL(TOPIC, msg->get_topic());
CPPUNIT_ASSERT_EQUAL(PAYLOAD, msg->get_payload());
CPPUNIT_ASSERT_EQUAL(QOS, msg->get_qos());
CPPUNIT_ASSERT_EQUAL(RETAINED, msg->is_retained());
}
// ----------------------------------------------------------------------
// Test publish with the full C array form
// ----------------------------------------------------------------------
void test_publish_full_binary() {
mqtt::topic topic{ cli, TOPIC };
auto tok = topic.publish(PAYLOAD, QOS, RETAINED);
CPPUNIT_ASSERT(tok);
auto msg = tok->get_message();
CPPUNIT_ASSERT(msg);
CPPUNIT_ASSERT_EQUAL(TOPIC, msg->get_topic());
CPPUNIT_ASSERT_EQUAL(PAYLOAD, msg->get_payload());
CPPUNIT_ASSERT_EQUAL(QOS, msg->get_qos());
CPPUNIT_ASSERT_EQUAL(RETAINED, msg->is_retained());
}
};
/////////////////////////////////////////////////////////////////////////////
// end namespace mqtt
}
#endif // __mqtt_topic_test_h

View File

@ -31,6 +31,7 @@ find_package(Catch2 REQUIRED)
add_executable(unit_tests unit_tests.cpp add_executable(unit_tests unit_tests.cpp
test_properties.cpp test_properties.cpp
test_string_collection.cpp test_string_collection.cpp
test_topic.cpp
) )
# --- Link for executables --- # --- Link for executables ---

View File

@ -0,0 +1,197 @@
// mock_async_client.h
//
// Dummy/mock implementation of mqtt::iasync_client for unit tests.
//
/*******************************************************************************
* Copyright (c) 2016 Guilherme M. Ferreira <guilherme.maciel.ferreira@gmail.com>
* Copyright (c) 2020 Frank Pagliughi <fpagliughi@mindspring.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
* Frank Pagliughi - updated and renamed
*******************************************************************************/
#ifndef __mqtt_test_mock_async_client_h
#define __mqtt_test_mock_async_client_h
#include <vector>
#include "mqtt/iasync_client.h"
#include "mqtt/token.h"
#include "mqtt/connect_options.h"
namespace mqtt {
namespace test {
/////////////////////////////////////////////////////////////////////////////
class mock_async_client : public mqtt::iasync_client
{
public:
void remove_token(mqtt::token* tok) override {}
mqtt::token_ptr connect() override {
return mqtt::token_ptr{};
}
mqtt::token_ptr connect(mqtt::connect_options options) override {
return mqtt::token_ptr{};
}
mqtt::token_ptr connect(mqtt::connect_options options, void* userContext, mqtt::iaction_listener& cb) override {
return mqtt::token_ptr{};
}
mqtt::token_ptr connect(void* userContext, mqtt::iaction_listener& cb) override {
return mqtt::token_ptr{};
}
mqtt::token_ptr reconnect() override {
return mqtt::token_ptr{};
}
mqtt::token_ptr disconnect() override {
return mqtt::token_ptr{};
}
mqtt::token_ptr disconnect(disconnect_options) override {
return mqtt::token_ptr{};
}
mqtt::token_ptr disconnect(int timeout) override {
return mqtt::token_ptr{};
}
mqtt::token_ptr disconnect(int timeout, void* userContext, mqtt::iaction_listener& cb) override {
return mqtt::token_ptr{};
}
mqtt::token_ptr disconnect(void* userContext, mqtt::iaction_listener& cb) override {
return mqtt::token_ptr{};
}
mqtt::delivery_token_ptr get_pending_delivery_token(int msgID) const override {
return mqtt::delivery_token_ptr{};
}
std::vector<mqtt::delivery_token_ptr> get_pending_delivery_tokens() const override {
return std::vector<mqtt::delivery_token_ptr>{};
};
std::string get_client_id() const override {
return std::string{};
};
std::string get_server_uri() const override {
return std::string{};
};
bool is_connected() const override {
return true;
};
mqtt::delivery_token_ptr publish(string_ref topic,
const void* payload, size_t n,
int qos, bool retained) override {
auto msg = mqtt::message::create(topic, payload, n, qos, retained);
return publish(msg);
};
mqtt::delivery_token_ptr publish(string_ref topic,
const void* payload, size_t n) override {
auto msg = mqtt::message::create(topic, payload, n);
return publish(msg);
};
mqtt::delivery_token_ptr publish(string_ref topic, binary_ref payload,
int qos, bool retained) override {
auto msg = mqtt::message::create(topic, payload, qos, retained);
return publish(msg);
};
mqtt::delivery_token_ptr publish(string_ref topic, binary_ref payload) override {
auto msg = mqtt::message::create(topic, payload);
return publish(msg);
};
mqtt::delivery_token_ptr publish(string_ref topic,
const void* payload, size_t n,
int qos, bool retained, void* userContext,
mqtt::iaction_listener& cb) override {
return mqtt::delivery_token_ptr{};
}
mqtt::delivery_token_ptr publish(mqtt::const_message_ptr msg) override {
return mqtt::delivery_token::create(*this, msg);
}
mqtt::delivery_token_ptr publish(mqtt::const_message_ptr msg,
void* userContext, mqtt::iaction_listener& cb) override {
return mqtt::delivery_token_ptr{};
}
void set_callback(mqtt::callback& cb) override {}
void disable_callbacks() override {}
mqtt::token_ptr subscribe(const string& topicFilter, int qos,
const subscribe_options& opts=subscribe_options()) override {
return mqtt::token_ptr{};
}
mqtt::token_ptr subscribe(const string& topicFilter, int qos,
void* userContext, iaction_listener& callback,
const subscribe_options& opts=subscribe_options()) override {
return mqtt::token_ptr{};
}
mqtt::token_ptr subscribe(const_string_collection_ptr topicFilters,
const qos_collection& qos,
const std::vector<subscribe_options>& opts=std::vector<subscribe_options>()) override {
return mqtt::token_ptr{};
}
mqtt::token_ptr subscribe(const_string_collection_ptr topicFilters,
const qos_collection& qos,
void* userContext, iaction_listener& callback,
const std::vector<subscribe_options>& opts=std::vector<subscribe_options>()) override {
return mqtt::token_ptr{};
}
mqtt::token_ptr unsubscribe(const string& topicFilter) override {
return mqtt::token_ptr{};
}
mqtt::token_ptr unsubscribe(const_string_collection_ptr topicFilters) override {
return mqtt::token_ptr{};
}
mqtt::token_ptr unsubscribe(const_string_collection_ptr topicFilters,
void* userContext, mqtt::iaction_listener& cb) override {
return mqtt::token_ptr{};
}
mqtt::token_ptr unsubscribe(const string& topicFilter,
void* userContext, mqtt::iaction_listener& cb) override {
return mqtt::token_ptr{};
}
};
/////////////////////////////////////////////////////////////////////////////
// end namespace test
}
/////////////////////////////////////////////////////////////////////////////
// end namespace mqtt
}
#endif // __mqtt_test_mock_async_client_h

178
test/unit/test_topic.cpp Normal file
View File

@ -0,0 +1,178 @@
// topic_test.h
//
// Unit tests for the topic class in the Paho MQTT C++ library.
//
/*******************************************************************************
* Copyright (c) 2020 Frank Pagliughi <fpagliughi@mindspring.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.
*
*******************************************************************************/
#include <algorithm>
#include <memory>
#include <stdexcept>
#include "catch2/catch.hpp"
#include "mqtt/topic.h"
#include "mock_async_client.h"
using namespace mqtt;
/////////////////////////////////////////////////////////////////////////////
const int DFLT_QOS = message::DFLT_QOS;
const bool DFLT_RETAINED = message::DFLT_RETAINED;
const std::string TOPIC { "my/topic/name" };
const int QOS = 1;
const bool RETAINED = true;
const int BAD_LOW_QOS = -1;
const int BAD_HIGH_QOS = 3;
const char* BUF = "Hello there";
const size_t N = std::strlen(BUF);
const binary PAYLOAD { BUF };
mqtt::test::mock_async_client cli;
// ----------------------------------------------------------------------
// Constructors
// ----------------------------------------------------------------------
TEST_CASE("basic ctor", "[topic]")
{
mqtt::topic topic { cli, TOPIC };
REQUIRE(static_cast<iasync_client*>(&cli) == &topic.get_client());
REQUIRE(TOPIC == topic.get_name());
REQUIRE(TOPIC == topic.to_string());
REQUIRE(DFLT_QOS == topic.get_qos());
REQUIRE(DFLT_RETAINED == topic.get_retained());
}
// ----------------------------------------------------------------------
TEST_CASE("full ctor", "[topic]")
{
mqtt::topic topic { cli, TOPIC, QOS, RETAINED };
REQUIRE(static_cast<iasync_client*>(&cli) == &topic.get_client());
REQUIRE(TOPIC == topic.get_name());
REQUIRE(TOPIC == topic.to_string());
REQUIRE(QOS == topic.get_qos());
REQUIRE(RETAINED == topic.get_retained());
}
// ----------------------------------------------------------------------
// get/set
// ----------------------------------------------------------------------
TEST_CASE("get/set", "[topic]")
{
mqtt::topic topic { cli, TOPIC };
REQUIRE(DFLT_QOS == topic.get_qos());
REQUIRE(DFLT_RETAINED == topic.get_retained());
SECTION("qos") {
topic.set_qos(QOS);
REQUIRE(QOS == topic.get_qos());
REQUIRE_THROWS(topic.set_qos(BAD_LOW_QOS));
REQUIRE_THROWS(topic.set_qos(BAD_HIGH_QOS));
}
SECTION("retained") {
topic.set_retained(RETAINED);
REQUIRE(RETAINED == topic.get_retained());
topic.set_retained(!RETAINED);
REQUIRE(!RETAINED == topic.get_retained());
}
}
// ----------------------------------------------------------------------
// Publish
// ----------------------------------------------------------------------
TEST_CASE("publish C str", "[topic]")
{
mqtt::topic topic{ cli, TOPIC, QOS, RETAINED };
auto tok = topic.publish(BUF, N);
REQUIRE(tok);
auto msg = tok->get_message();
REQUIRE(msg);
REQUIRE(TOPIC == msg->get_topic());
REQUIRE(msg->get_payload().data());
REQUIRE(0 == memcmp(BUF, msg->get_payload().data(), N));
REQUIRE(QOS == msg->get_qos());
REQUIRE(RETAINED == msg->is_retained());
}
// ----------------------------------------------------------------------
TEST_CASE("publish full C str", "[topic]")
{
mqtt::topic topic { cli, TOPIC };
auto tok = topic.publish(BUF, N, QOS, RETAINED);
REQUIRE(tok);
auto msg = tok->get_message();
REQUIRE(msg);
REQUIRE(TOPIC == msg->get_topic());
REQUIRE(msg->get_payload().data());
REQUIRE(0 == memcmp(BUF, msg->get_payload().data(), N));
REQUIRE(QOS == msg->get_qos());
REQUIRE(RETAINED == msg->is_retained());
}
// ----------------------------------------------------------------------
TEST_CASE("publish binary", "[topic]")
{
mqtt::topic topic { cli, TOPIC, QOS, RETAINED };
auto tok = topic.publish(PAYLOAD);
REQUIRE(tok);
auto msg = tok->get_message();
REQUIRE(msg);
REQUIRE(TOPIC == msg->get_topic());
REQUIRE(PAYLOAD == msg->get_payload());
REQUIRE(QOS == msg->get_qos());
REQUIRE(RETAINED == msg->is_retained());
}
// ----------------------------------------------------------------------
TEST_CASE("publish full binary", "[topic]")
{
mqtt::topic topic { cli, TOPIC };
auto tok = topic.publish(PAYLOAD, QOS, RETAINED);
REQUIRE(tok);
auto msg = tok->get_message();
REQUIRE(msg);
REQUIRE(TOPIC == msg->get_topic());
REQUIRE(PAYLOAD == msg->get_payload());
REQUIRE(QOS == msg->get_qos());
REQUIRE(RETAINED == msg->is_retained());
}