From 1eaa5145795937ec1c3f13034398e777ad43a2a7 Mon Sep 17 00:00:00 2001 From: hsaturn Date: Tue, 30 Mar 2021 08:35:33 +0200 Subject: [PATCH 1/9] result.yaml --- tests/result.yaml | 1 + 1 file changed, 1 insertion(+) create mode 100644 tests/result.yaml diff --git a/tests/result.yaml b/tests/result.yaml new file mode 100644 index 0000000..0c20405 --- /dev/null +++ b/tests/result.yaml @@ -0,0 +1 @@ +result: 1 From 6fc6794dc3f9a8ac8a1b8d3cfefa21242ff66ddf Mon Sep 17 00:00:00 2001 From: hsaturn Date: Tue, 30 Mar 2021 08:37:25 +0200 Subject: [PATCH 2/9] result0.yaml --- tests/result0.yaml | 1 + 1 file changed, 1 insertion(+) create mode 100644 tests/result0.yaml diff --git a/tests/result0.yaml b/tests/result0.yaml new file mode 100644 index 0000000..2db2755 --- /dev/null +++ b/tests/result0.yaml @@ -0,0 +1 @@ +result: 0 From 6a9e1584282dff018085896dd6d862093b1a323d Mon Sep 17 00:00:00 2001 From: hsaturn Date: Tue, 30 Mar 2021 08:39:02 +0200 Subject: [PATCH 3/9] results --- tests/result.yaml | 1 + tests/result0.yaml | 1 + 2 files changed, 2 insertions(+) diff --git a/tests/result.yaml b/tests/result.yaml index 0c20405..448244c 100644 --- a/tests/result.yaml +++ b/tests/result.yaml @@ -1 +1,2 @@ result: 1 +insert: passed diff --git a/tests/result0.yaml b/tests/result0.yaml index 2db2755..0668d78 100644 --- a/tests/result0.yaml +++ b/tests/result0.yaml @@ -1 +1,2 @@ result: 0 +insert: failed From 27bdbb9a0b6f620d415042ab3cd079a5a643aa6e Mon Sep 17 00:00:00 2001 From: hsaturn Date: Tue, 30 Mar 2021 08:41:30 +0200 Subject: [PATCH 4/9] str --- tests/result.yaml | 2 +- tests/result0.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/result.yaml b/tests/result.yaml index 448244c..3d352b4 100644 --- a/tests/result.yaml +++ b/tests/result.yaml @@ -1,2 +1,2 @@ result: 1 -insert: passed +insert: "passed" diff --git a/tests/result0.yaml b/tests/result0.yaml index 0668d78..9937cfc 100644 --- a/tests/result0.yaml +++ b/tests/result0.yaml @@ -1,2 +1,2 @@ result: 0 -insert: failed +insert: "failed" From babc3916325ed7c831aad4a1af59befa77783d0e Mon Sep 17 00:00:00 2001 From: hsaturn Date: Tue, 30 Mar 2021 08:52:10 +0200 Subject: [PATCH 5/9] Added json --- tests/{result0.yaml => result.json} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename tests/{result0.yaml => result.json} (100%) diff --git a/tests/result0.yaml b/tests/result.json similarity index 100% rename from tests/result0.yaml rename to tests/result.json From b6a0dde2b15fb42a607d9b9c9471f73722245ae0 Mon Sep 17 00:00:00 2001 From: hsaturn Date: Tue, 30 Mar 2021 08:52:46 +0200 Subject: [PATCH 6/9] json --- tests/result.json | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/result.json b/tests/result.json index 9937cfc..fda2614 100644 --- a/tests/result.json +++ b/tests/result.json @@ -1,2 +1,6 @@ -result: 0 -insert: "failed" +{ + "schemaVersion" : 1, + "label" : "tests", + "message" : "Message content", + "color": "red" +} From e71ffefc5a0499de373ef83283c9622171af9a7b Mon Sep 17 00:00:00 2001 From: hsaturn Date: Wed, 31 Mar 2021 00:22:31 +0200 Subject: [PATCH 7/9] Fixed a useless test and modified MqttClient constructors --- .gitignore | 1 + src/TinyMqtt.cpp | 4 ++-- src/TinyMqtt.h | 5 ++--- tests/nowifi-tests/nowifi-tests.ino | 21 ++++++++++++--------- 4 files changed, 17 insertions(+), 14 deletions(-) diff --git a/.gitignore b/.gitignore index 9465b8b..55bb629 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ *~ src/my_credentials.h *.o +*.swp *.out diff --git a/src/TinyMqtt.cpp b/src/TinyMqtt.cpp index 3a95f39..4c3745a 100644 --- a/src/TinyMqtt.cpp +++ b/src/TinyMqtt.cpp @@ -29,8 +29,8 @@ MqttClient::MqttClient(MqttBroker* parent, WiFiClient& new_client) alive = millis()+5000; // client expires after 5s if no CONNECT msg } -MqttClient::MqttClient(MqttBroker* parent) - : parent(parent) +MqttClient::MqttClient(MqttBroker* parent, const std::string& id) + : parent(parent), clientId(id) { client = nullptr; diff --git a/src/TinyMqtt.h b/src/TinyMqtt.h index 1eb23ec..23bb3ac 100644 --- a/src/TinyMqtt.h +++ b/src/TinyMqtt.h @@ -120,9 +120,8 @@ class MqttClient FlagReserved = 1 }; public: - MqttClient(MqttBroker*); - MqttClient(MqttBroker* brk, const std::string& id) : MqttClient(brk) { clientId=id; } - MqttClient() : MqttClient(nullptr) {}; + MqttClient(MqttBroker* brk = nullptr, const std::string& id=""); + MqttClient(const std::string& id) : MqttClient(nullptr, id){} ~MqttClient(); diff --git a/tests/nowifi-tests/nowifi-tests.ino b/tests/nowifi-tests/nowifi-tests.ino index 3bce9c4..b4d1cc7 100644 --- a/tests/nowifi-tests/nowifi-tests.ino +++ b/tests/nowifi-tests/nowifi-tests.ino @@ -3,9 +3,10 @@ #include /** - * TinyMqtt local unit tests. + * TinyMqtt nowifi unit tests. * * No wifi connection unit tests. + * Checks with a local broker. Clients must connect to the local client **/ using namespace std; @@ -20,7 +21,7 @@ void onPublish(const MqttClient* srce, const Topic& topic, const char* payload, published[srce->id()][topic]++; } -test(local_client_should_unregister_when_destroyed) +test(nowifi_client_should_unregister_when_destroyed) { assertEqual(broker.clientsCount(), (size_t)0); { @@ -30,7 +31,7 @@ test(local_client_should_unregister_when_destroyed) assertEqual(broker.clientsCount(), (size_t)0); } -test(local_connect) +test(nowifi_connect) { assertEqual(broker.clientsCount(), (size_t)0); @@ -39,7 +40,7 @@ test(local_connect) assertEqual(broker.clientsCount(), (size_t)1); } -test(local_publish_should_be_dispatched) +test(nowifi_publish_should_be_dispatched) { published.clear(); assertEqual(broker.clientsCount(), (size_t)0); @@ -59,7 +60,7 @@ test(local_publish_should_be_dispatched) assertTrue(published[""]["a/c"] == 2); } -test(local_publish_should_be_dispatched_to_local_clients) +test(nowifi_publish_should_be_dispatched_to_nowifi_clients) { published.clear(); assertEqual(broker.clientsCount(), (size_t)0); @@ -84,7 +85,7 @@ test(local_publish_should_be_dispatched_to_local_clients) assertTrue(published["B"]["a/c"] == 0); } -test(local_unsubscribe) +test(nowifi_unsubscribe) { published.clear(); assertEqual(broker.clientsCount(), (size_t)0); @@ -104,21 +105,23 @@ test(local_unsubscribe) assertTrue(published[""]["a/b"] == 1); // Only one publish has been received } -test(local_nocallback_when_destroyed) +test(nowifi_nocallback_when_destroyed) { published.clear(); assertEqual(broker.clientsCount(), (size_t)0); + MqttClient publisher(&broker); + { MqttClient subscriber(&broker); subscriber.setCallback(onPublish); subscriber.subscribe("a/b"); + publisher.publish("a/b"); } - MqttClient publisher(&broker); publisher.publish("a/b"); - assertEqual(published.size(), (size_t)0); // Only one publish has been received + assertEqual(published.size(), (size_t)1); // Only one publish has been received } //---------------------------------------------------------------------------- From 5211360b91f71c48dc720102325e7310bba09439 Mon Sep 17 00:00:00 2001 From: hsaturn Date: Wed, 31 Mar 2021 19:09:05 +0200 Subject: [PATCH 8/9] 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(); +} From 87a78c549ff606535491a68c227761109fcbe032 Mon Sep 17 00:00:00 2001 From: hsaturn Date: Wed, 31 Mar 2021 19:09:43 +0200 Subject: [PATCH 9/9] Fix crash at end of unit tests --- src/StringIndexer.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/StringIndexer.h b/src/StringIndexer.h index 0c45f2a..dc3777c 100644 --- a/src/StringIndexer.h +++ b/src/StringIndexer.h @@ -15,6 +15,16 @@ class StringIndexer std::string str; uint8_t used=0; friend class StringIndexer; + + #if EPOXY_DUINO + public: + // Workaround to avoid coredump in Indexer::release + // when destroying a Topic after the deletion of + // StringIndexer::strings map (which can occurs only with AUnit, + // never in the ESP itself, because ESP never ends) + // (I hate static vars) + ~StringCounter() { used=255; } + #endif }; public: using index_t=uint8_t;