Rewrite comments and added hudge payload test

This commit is contained in:
hsaturn
2021-09-20 01:57:40 +02:00
parent 4dcc6a6cf4
commit dfd5983715
5 changed files with 131 additions and 58 deletions

View File

@@ -1,14 +1,6 @@
#include "TinyMqtt.h"
#include <sstream>
void outstring(const char* prefix, const char*p, uint16_t len)
{
return;
Serial << prefix << "='";
while(len--) Serial << (char)*p++;
Serial << '\'' << endl;
}
MqttBroker::MqttBroker(uint16_t port)
{
server = new TcpServer(port);
@@ -447,11 +439,9 @@ if (mesg->type() != MqttMessage::Type::PingReq && mesg->type() != MqttMessage::T
if (mqtt_flags & FlagWill) // Will topic
{
mesg->getString(payload, len); // Will Topic
outstring("WillTopic", payload, len);
payload += len;
mesg->getString(payload, len); // Will Message
outstring("WillMessage", payload, len);
payload += len;
}
// FIXME forgetting credential is allowed (security hole)
@@ -468,7 +458,9 @@ if (mesg->type() != MqttMessage::Type::PingReq && mesg->type() != MqttMessage::T
payload += len;
}
#ifdef TINY_MQTT_DEBUG
Serial << "Connected client:" << clientId.c_str() << ", keep alive=" << keep_alive << '.' << endl;
#endif
bclose = false;
mqtt_connected=true;
{
@@ -522,7 +514,6 @@ if (mesg->type() != MqttMessage::Type::PingReq && mesg->type() != MqttMessage::T
{
mesg->getString(payload, len); // Topic
debug( " topic (" << std::string(payload, len) << ')');
outstring(" un/subscribes", payload, len);
// subscribe(Topic(payload, len));
Topic topic(payload, len);
payload += len;
@@ -602,10 +593,12 @@ if (mesg->type() != MqttMessage::Type::PingReq && mesg->type() != MqttMessage::T
};
if (bclose)
{
#ifdef TINY_MQTT_DEBUG
Serial << "*************** Error msg 0x" << _HEX(mesg->type());
mesg->hexdump("-------ERROR ------");
dump();
Serial << endl;
#endif
close();
}
else
@@ -722,8 +715,10 @@ void MqttMessage::incoming(char in_byte)
break;
case Complete:
default:
#ifdef TINY_MQTT_DEBUG
Serial << "Spurious " << _HEX(in_byte) << endl;
hexdump("spurious");
#endif
reset();
break;
}
@@ -778,6 +773,8 @@ MqttError MqttMessage::sendTo(MqttClient* client)
void MqttMessage::hexdump(const char* prefix) const
{
(void)prefix;
#ifdef TINY_MQTT_DEBUG
uint16_t addr=0;
const int bytes_per_row = 8;
const char* hex_to_str = " | ";
@@ -813,4 +810,5 @@ void MqttMessage::hexdump(const char* prefix) const
}
Serial << endl;
#endif
}

View File

@@ -29,7 +29,7 @@
// #define TINY_MQTT_DEBUG
#ifdef TINY_MQTT_DEBUG
#define debug(what) { Serial << __LINE__ << ' ' << what << endl; delay(100); }
#define debug(what) { Serial << (int)__LINE__ << ' ' << what << endl; delay(100); }
#else
#define debug(what) {}
#endif
@@ -160,6 +160,8 @@ class MqttClient
void connect(MqttBroker* parent);
void connect(std::string broker, uint16_t port, uint16_t keep_alive = 10);
// TODO it seems that connected returns true in tcp mode even if
// no negociation occured (only if tcp link is established)
bool connected() { return
(parent!=nullptr and client==nullptr) or
(client and client->connected()); }
@@ -198,6 +200,8 @@ class MqttClient
void dump(std::string indent="")
{
(void)indent;
#ifdef TINY_MQTT_DEBUG
uint32_t ms=millis();
Serial << indent << "+-- " << '\'' << clientId.c_str() << "' " << (connected() ? " ON " : " OFF");
Serial << ", alive=" << alive << '/' << ms << ", ka=" << keep_alive << ' ';
@@ -207,6 +211,7 @@ class MqttClient
bool c = false;
Serial << " [";
for(auto s: subscriptions)
(void)indent;
{
if (c) Serial << ", ";
Serial << s.str().c_str();
@@ -215,6 +220,7 @@ class MqttClient
Serial << ']';
}
Serial << endl;
#endif
}
static long counter; // Number of processed messages
@@ -235,7 +241,7 @@ class MqttClient
MqttError publishIfSubscribed(const Topic& topic, MqttMessage& msg);
void clientAlive(uint32_t more_seconds);
void processMessage(const MqttMessage* message);
void processMessage(MqttMessage* message);
bool mqtt_connected = false;
char mqtt_flags;

View File

@@ -1,6 +1,11 @@
# See https://github.com/bxparks/EpoxyDuino for documentation about this
# Makefile to compile and run Arduino programs natively on Linux or MacOS.
EXTRA_CXXFLAGS=-g3 -O0
# Remove flto flag from EpoxyDuino (too many <optimized out>)
CXXFLAGS = -Wextra -Wall -std=gnu++11 -fno-exceptions -fno-threadsafe-statics
APP_NAME := local-tests
ARDUINO_LIBS := AUnit AceCommon AceTime TinyMqtt EspMock ESP8266WiFi ESPAsyncTCP
ARDUINO_LIB_DIRS := ../../../EspMock/libraries

View File

@@ -68,8 +68,8 @@ test(local_publish_should_be_dispatched)
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);
assertEqual(published[""]["a/b"], 1);
assertEqual(published[""]["a/c"], 2);
}
test(local_publish_should_be_dispatched_to_local_clients)
@@ -91,10 +91,10 @@ test(local_publish_should_be_dispatched_to_local_clients)
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);
assertEqual(published["A"]["a/b"], 1);
assertEqual(published["A"]["a/c"], 1);
assertEqual(published["B"]["a/b"], 1);
assertEqual(published["B"]["a/c"], 0);
}
test(local_unsubscribe)
@@ -114,7 +114,7 @@ test(local_unsubscribe)
publisher.publish("a/b");
publisher.publish("a/b");
assertTrue(published[""]["a/b"] == 1); // Only one publish has been received
assertEqual(published[""]["a/b"], 1); // Only one publish has been received
}
test(local_nocallback_when_destroyed)

View File

@@ -19,6 +19,18 @@ std::map<std::string, std::map<Topic, int>> published; // map[client_id] => map
char* lastPayload = nullptr;
size_t lastLength;
void start_servers(int n, bool early_accept = true)
{
ESP8266WiFiClass::resetInstances();
ESP8266WiFiClass::earlyAccept = early_accept;
while(n)
{
ESP8266WiFiClass::selectInstance(n--);
WiFi.mode(WIFI_STA);
WiFi.begin("fake_ssid", "fake_pwd");
}
}
void onPublish(const MqttClient* srce, const Topic& topic, const char* payload, size_t length)
{
if (srce)
@@ -41,43 +53,90 @@ test(network_single_broker_begin)
test(network_client_to_broker_connexion)
{
start_servers(2, true);
assertEqual(WiFi.status(), WL_CONNECTED);
MqttBroker broker(1883);
broker.begin();
IPAddress broker_ip = WiFi.localIP();
Serial << "TODO IP = " << WiFi.localIP() << endl;
ESP8266WiFiClass::selectInstance(2);
MqttClient client;
client.connect(WiFi.localIP().toString().c_str(), 1883);
client.connect(broker_ip.toString().c_str(), 1883);
broker.loop();
assertEqual(broker.clientsCount(), (size_t)1);
assertTrue(broker.clientsCount() == 1);
assertTrue(client.connected());
}
/*
test(network_one_broker_one_client)
test(network_one_client_one_broker_publish_and_subscribe_through_network)
{
start_servers(2, true);
published.clear();
assertEqual(WiFi.status(), WL_CONNECTED);
MqttBroker broker(1883);
broker.begin();
IPAddress ip_broker = WiFi.localIP();
Serial << "TODO IP = " << WiFi.localIP() << endl;
// We have a 2nd ESP in order to test through wifi (opposed to local)
ESP8266WiFiClass::selectInstance(2);
MqttClient client;
client.connect(WiFi.localIP().toString().c_str(), 1883);
client.connect(ip_broker.toString().c_str(), 1883);
broker.loop();
assertTrue(client.connected());
client.setCallback(onPublish);
client.subscribe("a/b");
client.publish("a/b", "ab");
// client.loop();
for (int i =0; i<2; i++)
{
client.loop();
broker.loop();
}
assertEqual(published.size(), (size_t)1);
assertEqual((int)lastLength, (int)2); // sizeof(ab)
}
test(network_one_client_one_broker_hudge_publish_and_subscribe_through_network)
{
start_servers(2, true);
published.clear();
assertEqual(WiFi.status(), WL_CONNECTED);
MqttBroker broker(1883);
broker.begin();
IPAddress ip_broker = WiFi.localIP();
// We have a 2nd ESP in order to test through wifi (opposed to local)
ESP8266WiFiClass::selectInstance(2);
MqttClient client;
client.connect(ip_broker.toString().c_str(), 1883);
broker.loop();
assertTrue(client.connected());
std::string sent;
for(int i=0; i<200; i++)
sent += char('0'+i%10);
client.setCallback(onPublish);
client.subscribe("a/b");
client.publish("a/b", sent.c_str());
for (int i =0; i<2; i++)
{
client.loop();
broker.loop();
}
assertEqual(published.size(), (size_t)1);
assertEqual((unsigned int)lastLength, (unsigned int)sent.size());
}
*/
#if 0
test(network_client_should_unregister_when_destroyed)
{
assertEqual(broker.clientsCount(), (size_t)0);
@@ -88,6 +147,11 @@ test(network_client_should_unregister_when_destroyed)
assertEqual(broker.clientsCount(), (size_t)0);
}
#if 0
// THESE TESTS ARE IN LOCAL MODE
// WE HAVE TO CONVERT THEM TO WIFI MODE (pass through virtual TCP link)
test(network_connect)
{
assertEqual(broker.clientsCount(), (size_t)0);
@@ -219,12 +283,12 @@ test(network_hudge_payload)
//----------------------------------------------------------------------------
// setup() and loop()
void setup() {
delay(1000);
/* delay(1000);
Serial.begin(115200);
while(!Serial);
Serial.println("=============[ FAKE NETWORK TinyMqtt TESTS ]========================");
*/
WiFi.mode(WIFI_STA);
WiFi.begin("network", "password");
}