From 5211360b91f71c48dc720102325e7310bba09439 Mon Sep 17 00:00:00 2001 From: hsaturn Date: Wed, 31 Mar 2021 19:09:05 +0200 Subject: [PATCH] Local tests added --- src/TinyMqtt.h | 5 +- tests/local-tests/Makefile | 6 ++ tests/local-tests/local-tests.ino | 146 ++++++++++++++++++++++++++++++ 3 files changed, 154 insertions(+), 3 deletions(-) create mode 100644 tests/local-tests/Makefile create mode 100644 tests/local-tests/local-tests.ino diff --git a/src/TinyMqtt.h b/src/TinyMqtt.h index 23bb3ac..26c5766 100644 --- a/src/TinyMqtt.h +++ b/src/TinyMqtt.h @@ -157,9 +157,8 @@ class MqttClient void dump() { uint32_t ms=millis(); - Serial << "MqttClient (" << clientId.c_str() << ") p=" << (uint64_t) parent - << " c=" << (uint64_t)client << (connected() ? " ON " : " OFF"); - Serial << ", alive=" << (uint32_t)alive << '/' << ms << ", ka=" << keep_alive; + Serial << "MqttClient (" << clientId.c_str() << ") " << (connected() ? " ON " : " OFF"); + Serial << ", alive=" << alive << '/' << ms << ", ka=" << keep_alive; Serial << (client && client->connected() ? "" : "dis") << "connected"; message.hexdump("entrant msg"); bool c=false; diff --git a/tests/local-tests/Makefile b/tests/local-tests/Makefile new file mode 100644 index 0000000..d6ab7a3 --- /dev/null +++ b/tests/local-tests/Makefile @@ -0,0 +1,6 @@ +# See https://github.com/bxparks/EpoxyDuino for documentation about this +# Makefile to compile and run Arduino programs natively on Linux or MacOS. + +APP_NAME := local-tests +ARDUINO_LIBS := AUnit AceCommon AceTime TinyMqtt EspMock +include ../../../EpoxyDuino/EpoxyDuino.mk diff --git a/tests/local-tests/local-tests.ino b/tests/local-tests/local-tests.ino new file mode 100644 index 0000000..7415f58 --- /dev/null +++ b/tests/local-tests/local-tests.ino @@ -0,0 +1,146 @@ +#include +#include +#include + +/** + * TinyMqtt local unit tests. + * + * Clients are connected to pseudo remote broker + * The remote will be 127.0.0.1:1883 + * We are using 127.0.0.1 because this is simpler to test with a single ESP + * Also, this will allow to mock and thus run Action on github + **/ + +using namespace std; + +MqttBroker broker(1883); + +std::map> published; // map[client_id] => map[topic] = count + +void onPublish(const MqttClient* srce, const Topic& topic, const char* payload, size_t length) +{ + if (srce) + published[srce->id()][topic]++; +} + +test(local_client_should_unregister_when_destroyed) +{ + assertEqual(broker.clientsCount(), (size_t)0); + { + MqttClient client; + assertEqual(broker.clientsCount(), (size_t)0); // Ensure client is not yet connected + client.connect("127.0.0.1", 1883); + assertEqual(broker.clientsCount(), (size_t)1); // Ensure client is now connected + } + assertEqual(broker.clientsCount(), (size_t)0); +} + +#if 0 +test(local_connect) +{ + assertEqual(broker.clientsCount(), (size_t)0); + + MqttClient client; + assertTrue(client.connected()); + assertEqual(broker.clientsCount(), (size_t)1); +} + +test(local_publish_should_be_dispatched) +{ + published.clear(); + assertEqual(broker.clientsCount(), (size_t)0); + + MqttClient subscriber; + subscriber.subscribe("a/b"); + subscriber.subscribe("a/c"); + subscriber.setCallback(onPublish); + + MqttClient publisher; + publisher.publish("a/b"); + publisher.publish("a/c"); + publisher.publish("a/c"); + + assertEqual(published.size(), (size_t)1); // 1 client has received something + assertTrue(published[""]["a/b"] == 1); + assertTrue(published[""]["a/c"] == 2); +} + +test(local_publish_should_be_dispatched_to_local_clients) +{ + published.clear(); + assertEqual(broker.clientsCount(), (size_t)0); + + MqttClient subscriber_a("A"); + subscriber_a.setCallback(onPublish); + subscriber_a.subscribe("a/b"); + subscriber_a.subscribe("a/c"); + + MqttClient subscriber_b("B"); + subscriber_b.setCallback(onPublish); + subscriber_b.subscribe("a/b"); + + MqttClient publisher; + publisher.publish("a/b"); + publisher.publish("a/c"); + + assertEqual(published.size(), (size_t)2); // 2 clients have received something + assertTrue(published["A"]["a/b"] == 1); + assertTrue(published["A"]["a/c"] == 1); + assertTrue(published["B"]["a/b"] == 1); + assertTrue(published["B"]["a/c"] == 0); +} + +test(local_unsubscribe) +{ + published.clear(); + assertEqual(broker.clientsCount(), (size_t)0); + + MqttClient subscriber; + subscriber.setCallback(onPublish); + subscriber.subscribe("a/b"); + + MqttClient publisher; + publisher.publish("a/b"); + + subscriber.unsubscribe("a/b"); + + publisher.publish("a/b"); + publisher.publish("a/b"); + + assertTrue(published[""]["a/b"] == 1); // Only one publish has been received +} + +test(local_nocallback_when_destroyed) +{ + published.clear(); + assertEqual(broker.clientsCount(), (size_t)0); + + MqttClient publisher; + { + MqttClient subscriber; + subscriber.setCallback(onPublish); + subscriber.subscribe("a/b"); + publisher.publish("a/b"); + } + + publisher.publish("a/b"); + + assertEqual(published.size(), (size_t)1); // Only one publish has been received +} +#endif + +//---------------------------------------------------------------------------- +// setup() and loop() +void setup() { + delay(1000); + Serial.begin(115200); + while(!Serial); + + Serial.println("=============[ NO WIFI CONNECTION TinyMqtt TESTS ]========================"); +} + +void loop() { + aunit::TestRunner::run(); + + if (Serial.available()) ESP.reset(); +}