Commit b7b0db4b14f3719c3cac8a46f040991e6d55fa6f

Authored by Peter M. Groen
1 parent 5cd80369

Added tests

test/CMakeLists.txt
... ... @@ -7,25 +7,26 @@
7 7 #
8 8 # Build rules for the MQTT Library
9 9  
10   -add_executable(topictest
  10 +add_executable(mqtt_test
  11 + helperclasses/PublisherClass.h
11 12 TopicLengthTest.cpp
12 13 SledgeHammerTest.cpp
13 14 )
14 15  
15   -target_include_directories(topictest PRIVATE
  16 +target_include_directories(mqtt_test PRIVATE
16 17 ${CMAKE_CIRRENT_SOURECE_DIR}
17 18 ../include
18 19 )
19 20  
20   -target_link_libraries(topictest PRIVATE
  21 +target_link_libraries(mqtt_test PRIVATE
21 22 gmock_main
22 23 gmock
23 24 gtest
24 25 mqtt-cpp
25 26 )
26 27  
27   -add_test(NAME topictest COMMAND topictest)
  28 +add_test(NAME mqtt_test COMMAND mqtt_test)
28 29  
29   -set_tests_properties(topictest PROPERTIES
  30 +set_tests_properties(mqtt_test PROPERTIES
30 31 WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
31 32 )
... ...
test/SledgeHammerTest.cpp
... ... @@ -6,9 +6,179 @@
6 6 #include <gtest/gtest.h>
7 7 #include <string>
8 8 #include <memory>
  9 +#include <chrono>
  10 +#include <unistd.h>
9 11  
10   -#include "mqttclient.h"
  12 +#include <iostream>
11 13  
12   -using namespace osdev::components::mqtt;
13   -using namespace osdev::components::log;
  14 +#include "helperclasses/PublisherClass.h"
14 15  
  16 +/// Every test does basically the same.
  17 +/// 1. Create a Publisher object
  18 +/// 2. Connect to the MQTT broker
  19 +/// 3. Publish 10 message(s)
  20 +/// 4. Disconnect from the MQTT broker
  21 +/// 5. Destroy the Publisher object
  22 +/// 6. Repeat 10 times.
  23 +
  24 +const std::string sledge_maintopic = "SledgeHammerTest/";
  25 +
  26 +enum TIME_RES
  27 +{
  28 + T_MICRO,
  29 + T_MILLI,
  30 + T_SECONDS
  31 +};
  32 +
  33 +std::uint64_t getEpochUSecs()
  34 +{
  35 + auto tsUSec =std::chrono::time_point_cast<std::chrono::microseconds>(std::chrono::system_clock::now());
  36 + return static_cast<std::uint64_t>(tsUSec.time_since_epoch().count());
  37 +}
  38 +
  39 +
  40 +void sleepcp( int number, TIME_RES resolution = T_MILLI ) // Cross-platform sleep function
  41 +{
  42 + int factor = 0; // Should not happen..
  43 +
  44 + switch( resolution )
  45 + {
  46 + case T_MICRO:
  47 + factor = 1;
  48 + break;
  49 +
  50 + case T_MILLI:
  51 + factor = 1000;
  52 + break;
  53 +
  54 + case T_SECONDS:
  55 + factor = 1000000;
  56 + break;
  57 + }
  58 +
  59 + usleep( number * factor );
  60 +}
  61 +
  62 +/// Test a single connection, 1 time
  63 +TEST(SledgeHammerTest, SingleConnectionCleanExit)
  64 +{
  65 + Publisher *publisher = nullptr;
  66 + for (int test_counter = 0; test_counter < 10; test_counter++)
  67 + {
  68 + publisher = new Publisher(std::to_string(getEpochUSecs()));
  69 + if(publisher)
  70 + {
  71 + publisher->connect("localhost");
  72 + publisher->publish(sledge_maintopic + "Single Connection Clean Exit Test/" + std::to_string(test_counter), "Hello World. I'm alive..");
  73 + publisher->disconnect();
  74 + delete publisher;
  75 + publisher = nullptr;
  76 + }
  77 + }
  78 +}
  79 +
  80 +TEST(SledgeHammerTest, SingleConnectionForcedExit)
  81 +{
  82 + Publisher *publisher = nullptr;
  83 + for (int test_counter = 0; test_counter < 10; test_counter++)
  84 + {
  85 + publisher = new Publisher(std::to_string(getEpochUSecs()));
  86 + if(publisher)
  87 + {
  88 + publisher->connect("localhost");
  89 + publisher->publish(sledge_maintopic + "Single Connection Forced Exit/Test/" + std::to_string(test_counter), "Hello World. I'm alive..");
  90 + delete publisher;
  91 + publisher = nullptr;
  92 + }
  93 + }
  94 +}
  95 +
  96 +TEST(SledgeHammerTest, MultipleConnections_10_CleanExit)
  97 +{
  98 + std::unordered_map<std::string, Publisher *> publishers;
  99 +
  100 + for (int test_counter = 0; test_counter < 10; test_counter++)
  101 + {
  102 + publishers["Publisher" + std::to_string(test_counter)] = new Publisher(std::to_string(getEpochUSecs()));
  103 + if(publishers["Publisher" + std::to_string(test_counter)])
  104 + {
  105 + publishers["Publisher" + std::to_string(test_counter)]->connect("localhost");
  106 + }
  107 + }
  108 +
  109 + for (int test_counter = 0; test_counter < 10; test_counter++)
  110 + {
  111 + for (int nCount = 0; nCount < 10; nCount++)
  112 + {
  113 + publishers["Publisher" + std::to_string(test_counter)]->publish(sledge_maintopic + "Multiple Connections [10]/Clean Exit/Test " + std::to_string(test_counter), "Hello World. I'm alive..");
  114 + }
  115 + publishers["Publisher" + std::to_string(test_counter)]->disconnect();
  116 + delete publishers["Publisher" + std::to_string(test_counter)];
  117 + publishers.erase("Publisher" + std::to_string(test_counter));
  118 + }
  119 +}
  120 +
  121 +TEST(SledgeHammerTest, MultipleConnections_BurnTest)
  122 +{
  123 + std::unordered_map<std::string, Publisher *> publishers;
  124 +
  125 + const int max_run = 100;
  126 + const int max_connections = 10;
  127 + const int max_messages = 10;
  128 +
  129 + for (int test_run = 0; test_run < max_run; test_run++)
  130 + {
  131 + std::cout << "Creating " << max_connections << " connections for test run " << test_run << " " << std::endl;
  132 + for (int test_counter = 0; test_counter < max_connections; test_counter++)
  133 + {
  134 + publishers["Publisher" + std::to_string(test_counter)] = new Publisher(std::to_string(getEpochUSecs()));
  135 + if(publishers["Publisher" + std::to_string(test_counter)])
  136 + {
  137 + publishers["Publisher" + std::to_string(test_counter)]->connect("localhost");
  138 + std::cout << ".";
  139 + }
  140 + }
  141 + std::cout << std::endl;
  142 +
  143 + // Wait a second for the connections to be established.
  144 + sleepcp(1, T_SECONDS);
  145 +
  146 + std::cout << "Publishing " << max_messages << " messages for test run " << test_run << std::endl;
  147 + for (int test_counter = 0; test_counter < max_connections; test_counter++)
  148 + {
  149 + std::cout << "\tConnection : " << test_counter << " ";
  150 + for (int nCount = 0; nCount < max_messages; nCount++)
  151 + {
  152 + if(publishers["Publisher" + std::to_string(test_counter)])
  153 + {
  154 + std::cout << ".";
  155 + publishers["Publisher" + std::to_string(test_counter)]->publish(sledge_maintopic +
  156 + "Multiple Connections [" + std::to_string(max_connections) + "]/Multi Messages [" + std::to_string(max_messages) + "]/Test Run " +
  157 + std::to_string(test_run) + "/" + "[" + std::to_string(test_counter) + "]" +
  158 + "[" + std::to_string(nCount) + "]", "Hello World. I'm alive..");
  159 + }
  160 + }
  161 + std::cout << std::endl;
  162 + }
  163 +
  164 + // Wait another second to update the broker.
  165 + sleepcp(1, T_SECONDS);
  166 +
  167 + std::cout << "Disconnecting " << max_connections << " connections for test run " << test_run << " ";
  168 + for (int test_counter = 0; test_counter < max_connections; test_counter++)
  169 + {
  170 + if(publishers["Publisher" + std::to_string(test_counter)])
  171 + {
  172 + std::cout << ".";
  173 + publishers["Publisher" + std::to_string(test_counter)]->disconnect();
  174 + delete publishers["Publisher" + std::to_string(test_counter)];
  175 + }
  176 + }
  177 + std::cout << std::endl;
  178 + publishers.clear();
  179 + std::cout << std::string(200,'=') << std::endl;
  180 +
  181 + // Wait for another second before re-running another 100 times.
  182 + sleepcp(1, T_SECONDS);
  183 + }
  184 +}
15 185 \ No newline at end of file
... ...
test/TopicLengthTest.cpp
... ... @@ -12,7 +12,7 @@
12 12 using namespace osdev::components::mqtt;
13 13 using namespace osdev::components::log;
14 14  
15   -static const std::string main_topic = "test/";
  15 +static const std::string main_topic = "Topic Length Test/";
16 16  
17 17 /****************************************************************************
18 18 * H E L P E R C L A S S E S
... ...
test/helperclasses/PublisherClass.h
... ... @@ -5,17 +5,46 @@
5 5 #include "mqttclient.h"
6 6  
7 7 #include <string>
8   -#include <memory>
9 8  
10 9 using namespace osdev::components::mqtt;
11 10 using namespace osdev::components::log;
12 11  
13   -static const std::string main_topic = "test/";
14   -
15 12 class Publisher
16 13 {
17 14 public:
18   - Publisher() : m_mqtt_client("TopicTester"){}
  15 + Publisher(const std::string &unique_id) : m_mqtt_client("SledgeHammerTest" + unique_id){}
19 16 virtual ~Publisher() {}
20 17  
  18 + void connect( const std::string &hostname,
  19 + int portnumber = 1883,
  20 + const std::string &username = std::string(),
  21 + const std::string &password = std::string(),
  22 + const std::string &lwt_topic = std::string(),
  23 + const std::string &lwt_message = std::string()
  24 + )
  25 + {
  26 + m_mqtt_client.connect(hostname, portnumber,
  27 + Credentials(username, password),
  28 + mqtt_LWT(lwt_topic, lwt_message),
  29 + true,
  30 + LogSettings
  31 + {
  32 + LogLevel::Debug,
  33 + LogMask::None
  34 + });
  35 + }
  36 +
  37 + void disconnect()
  38 + {
  39 + m_mqtt_client.disconnect();
  40 + }
  41 +
  42 + void publish(const std::string &message_topic, const std::string &message_payload)
  43 + {
  44 + MqttMessage message(message_topic, true, false, message_payload);
  45 + Token t_result = m_mqtt_client.publish(message, 0);
  46 + }
  47 +
  48 +private:
  49 + osdev::components::mqtt::MqttClient m_mqtt_client;
21 50 };
22 51 \ No newline at end of file
... ...