Commit b7b0db4b14f3719c3cac8a46f040991e6d55fa6f

Authored by Peter M. Groen
1 parent 5cd80369

Added tests

test/CMakeLists.txt
@@ -7,25 +7,26 @@ @@ -7,25 +7,26 @@
7 # 7 #
8 # Build rules for the MQTT Library 8 # Build rules for the MQTT Library
9 9
10 -add_executable(topictest 10 +add_executable(mqtt_test
  11 + helperclasses/PublisherClass.h
11 TopicLengthTest.cpp 12 TopicLengthTest.cpp
12 SledgeHammerTest.cpp 13 SledgeHammerTest.cpp
13 ) 14 )
14 15
15 -target_include_directories(topictest PRIVATE 16 +target_include_directories(mqtt_test PRIVATE
16 ${CMAKE_CIRRENT_SOURECE_DIR} 17 ${CMAKE_CIRRENT_SOURECE_DIR}
17 ../include 18 ../include
18 ) 19 )
19 20
20 -target_link_libraries(topictest PRIVATE 21 +target_link_libraries(mqtt_test PRIVATE
21 gmock_main 22 gmock_main
22 gmock 23 gmock
23 gtest 24 gtest
24 mqtt-cpp 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 WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" 31 WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
31 ) 32 )
test/SledgeHammerTest.cpp
@@ -6,9 +6,179 @@ @@ -6,9 +6,179 @@
6 #include <gtest/gtest.h> 6 #include <gtest/gtest.h>
7 #include <string> 7 #include <string>
8 #include <memory> 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 \ No newline at end of file 185 \ No newline at end of file
test/TopicLengthTest.cpp
@@ -12,7 +12,7 @@ @@ -12,7 +12,7 @@
12 using namespace osdev::components::mqtt; 12 using namespace osdev::components::mqtt;
13 using namespace osdev::components::log; 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 * H E L P E R C L A S S E S 18 * H E L P E R C L A S S E S
test/helperclasses/PublisherClass.h
@@ -5,17 +5,46 @@ @@ -5,17 +5,46 @@
5 #include "mqttclient.h" 5 #include "mqttclient.h"
6 6
7 #include <string> 7 #include <string>
8 -#include <memory>  
9 8
10 using namespace osdev::components::mqtt; 9 using namespace osdev::components::mqtt;
11 using namespace osdev::components::log; 10 using namespace osdev::components::log;
12 11
13 -static const std::string main_topic = "test/";  
14 -  
15 class Publisher 12 class Publisher
16 { 13 {
17 public: 14 public:
18 - Publisher() : m_mqtt_client("TopicTester"){} 15 + Publisher(const std::string &unique_id) : m_mqtt_client("SledgeHammerTest" + unique_id){}
19 virtual ~Publisher() {} 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 \ No newline at end of file 51 \ No newline at end of file