aboutsummaryrefslogtreecommitdiff
path: root/test/interop
diff options
context:
space:
mode:
Diffstat (limited to 'test/interop')
-rw-r--r--test/interop/CMakeLists.txt10
-rw-r--r--test/interop/basic_test.c34
-rw-r--r--test/interop/testclient.c210
-rw-r--r--test/interop/testclient.h63
4 files changed, 317 insertions, 0 deletions
diff --git a/test/interop/CMakeLists.txt b/test/interop/CMakeLists.txt
new file mode 100644
index 0000000..f4d71e8
--- /dev/null
+++ b/test/interop/CMakeLists.txt
@@ -0,0 +1,10 @@
+ADD_LIBRARY(testclient STATIC testclient.c testclient.h)
+TARGET_LINK_LIBRARIES(testclient PUBLIC mqtt)
+
+FUNCTION(ADD_INTEROP_TEST NAME)
+ ADD_EXECUTABLE(${NAME} ${NAME}.c)
+ TARGET_LINK_LIBRARIES(${NAME} PRIVATE testclient)
+ ADD_TEST(NAME ${NAME} COMMAND ${NAME})
+ENDFUNCTION()
+
+ADD_INTEROP_TEST(basic_test)
diff --git a/test/interop/basic_test.c b/test/interop/basic_test.c
new file mode 100644
index 0000000..76ddaec
--- /dev/null
+++ b/test/interop/basic_test.c
@@ -0,0 +1,34 @@
+#include "greatest.h"
+#include "testclient.h"
+
+TEST basic_test()
+{
+ TestClient *client;
+
+ client = TestClientNew("basic_test");
+ ASSERT(TestClientConnect(client, "localhost", 1883, 60, 1));
+ TestClientDisconnect(client);
+ TestClientFree(client);
+
+ client = TestClientNew("basic_test");
+ ASSERT(TestClientConnect(client, "localhost", 1883, 60, 1));
+ ASSERT(TestClientSubscribe(client, "basic_test/basic_test", 2));
+ ASSERT(TestClientPublish(client, 0, 0, "basic_test/basic_test", "msg0"));
+ ASSERT(TestClientPublish(client, 1, 0, "basic_test/basic_test", "msg1"));
+ ASSERT(TestClientPublish(client, 2, 0, "basic_test/basic_test", "msg2"));
+ ASSERT(TestClientWait(client, 2000));
+ ASSERT_EQ(3, TestClientMessageCount(client));
+ TestClientDisconnect(client);
+ TestClientFree(client);
+
+ PASS();
+}
+
+GREATEST_MAIN_DEFS();
+
+int main(int argc, char **argv)
+{
+ GREATEST_MAIN_BEGIN();
+ RUN_TEST(basic_test);
+ GREATEST_MAIN_END();
+}
diff --git a/test/interop/testclient.c b/test/interop/testclient.c
new file mode 100644
index 0000000..c27945d
--- /dev/null
+++ b/test/interop/testclient.c
@@ -0,0 +1,210 @@
+#include "testclient.h"
+#include "misc.h"
+
+#include <stdio.h>
+#include <string.h>
+
+static void TestClientOnConnect(MqttClient *client,
+ MqttConnectionStatus status,
+ int sessionPresent)
+{
+ TestClient *testClient = (TestClient *) MqttClientGetUserData(client);
+ testClient->connectionStatus = status;
+ testClient->sessionPresent = sessionPresent;
+}
+
+static void TestClientOnSubscribe(MqttClient *client, int id,
+ MqttSubscriptionStatus status)
+{
+ TestClient *testClient = (TestClient *) MqttClientGetUserData(client);
+ testClient->subId = id;
+ testClient->subStatus = status;
+}
+
+static void TestClientOnPublish(MqttClient *client, int id)
+{
+ TestClient *testClient = (TestClient *) MqttClientGetUserData(client);
+ testClient->pubId = id;
+}
+
+static void TestClientOnMessage(MqttClient *client, const char *topic,
+ const void *data, size_t size, int qos,
+ int retain)
+{
+ Message *msg = MessageNew(topic, data, size, qos, retain);
+ TestClient *testClient = (TestClient *) MqttClientGetUserData(client);
+ SIMPLEQ_INSERT_TAIL(&testClient->messages, msg, chain);
+}
+
+Message *MessageNew(const char *topic, const void *data, size_t size,
+ int qos, int retain)
+{
+ Message *msg = calloc(1, sizeof(*msg));
+ int topicLen;
+
+ topicLen = strlen(topic);
+ msg->topic = (char *) malloc(topicLen+1);
+ memcpy(msg->topic, topic, topicLen);
+ msg->topic[topicLen] = '\0';
+
+ msg->data = malloc(size);
+ memcpy(msg->data, data, size);
+ msg->size = size;
+
+ msg->qos = qos;
+ msg->retain = retain;
+
+ return msg;
+}
+
+void MessageFree(Message *msg)
+{
+ free(msg->topic);
+ free(msg->data);
+ free(msg);
+}
+
+TestClient *TestClientNew(const char *clientId)
+{
+ TestClient *client = calloc(1, sizeof(*client));
+
+ client->client = MqttClientNew(clientId);
+
+ MqttClientSetUserData(client->client, client);
+
+ client->connectionStatus = (MqttConnectionStatus) -1;
+
+ MqttClientSetOnConnect(client->client, TestClientOnConnect);
+ MqttClientSetOnSubscribe(client->client, TestClientOnSubscribe);
+ MqttClientSetOnPublish(client->client, TestClientOnPublish);
+ MqttClientSetOnMessage(client->client, TestClientOnMessage);
+
+ SIMPLEQ_INIT(&client->messages);
+
+ return client;
+}
+
+void TestClientFree(TestClient *client)
+{
+ MqttClientFree(client->client);
+
+ while (!SIMPLEQ_EMPTY(&client->messages))
+ {
+ Message *msg = SIMPLEQ_FIRST(&client->messages);
+ SIMPLEQ_REMOVE_HEAD(&client->messages, chain);
+ MessageFree(msg);
+ }
+
+ free(client);
+}
+
+int TestClientConnect(TestClient *client, const char *host, int port,
+ int keepAlive, int cleanSession)
+{
+ MqttClientConnect(client->client, host, port, keepAlive, cleanSession);
+
+ while (MqttClientRunOnce(client->client, -1) != -1)
+ {
+ if (client->connectionStatus != (MqttConnectionStatus) -1)
+ {
+ break;
+ }
+ }
+
+ return client->connectionStatus == MqttConnectionAccepted;
+}
+
+void TestClientDisconnect(TestClient *client)
+{
+ MqttClientDisconnect(client->client);
+
+ while (MqttClientRunOnce(client->client, -1) != -1)
+ {
+ if (!MqttClientIsConnected(client->client))
+ {
+ break;
+ }
+ }
+}
+
+int TestClientSubscribe(TestClient *client, const char *topicFilter, int qos)
+{
+ int id = MqttClientSubscribe(client->client, topicFilter, qos);
+
+ client->subId = -1;
+
+ while (MqttClientRunOnce(client->client, -1) != -1)
+ {
+ if (client->subId != -1)
+ {
+ if (client->subId != id)
+ {
+ printf(
+ "WARNING: subscription id mismatch: expected %d, got %d\n",
+ id, client->subId);
+ }
+ break;
+ }
+ }
+
+ return client->subStatus != MqttSubscriptionFailure;
+}
+
+int TestClientPublish(TestClient *client, int qos, int retain,
+ const char *topic, const char *message)
+{
+ int id = MqttClientPublishCString(client->client, qos, retain, topic,
+ message);
+
+ client->pubId = -1;
+
+ while (MqttClientRunOnce(client->client, -1) != -1)
+ {
+ if (qos == 0)
+ return 1;
+
+ if (client->pubId != -1)
+ {
+ if (client->pubId != id)
+ {
+ printf("WARNING: publish id mismatch: expected %d, got %d",
+ id, client->pubId);
+ }
+ break;
+ }
+ }
+
+ return client->pubId == id;
+}
+
+int TestClientMessageCount(TestClient *client)
+{
+ int count = 0;
+ Message *msg;
+ SIMPLEQ_FOREACH(msg, &client->messages, chain)
+ {
+ ++count;
+ }
+ return count;
+}
+
+int TestClientWait(TestClient *client, int timeout)
+{
+ int64_t start = MqttGetCurrentTime();
+ int rc;
+
+ while ((rc = MqttClientRunOnce(client->client, timeout)) != -1)
+ {
+ printf("TestClientWait timeout:%d rc:%d\n", timeout, rc);
+ int64_t now = MqttGetCurrentTime();
+ int64_t elapsed = now - start;
+ timeout -= elapsed;
+ printf("TestClientWait elapsed:%d\n", (int) elapsed);
+ if (timeout <= 0)
+ {
+ break;
+ }
+ }
+
+ return rc != -1;
+}
diff --git a/test/interop/testclient.h b/test/interop/testclient.h
new file mode 100644
index 0000000..6f9bdb9
--- /dev/null
+++ b/test/interop/testclient.h
@@ -0,0 +1,63 @@
+#ifndef TESTCLIENT_H
+#define TESTCLIENT_H
+
+#include "mqtt.h"
+#include "queue.h"
+
+typedef struct Message Message;
+
+struct Message
+{
+ SIMPLEQ_ENTRY(Message) chain;
+ char *topic;
+ void *data;
+ size_t size;
+ int qos;
+ int retain;
+};
+
+typedef struct TestClient TestClient;
+
+struct TestClient
+{
+ MqttClient *client;
+
+ /* OnConnect */
+ MqttConnectionStatus connectionStatus;
+ int sessionPresent;
+
+ /* OnSubscribe */
+ int subId;
+ MqttSubscriptionStatus subStatus;
+
+ /* OnPublish */
+ int pubId;
+
+ /* OnMessage */
+ SIMPLEQ_HEAD(messages, Message) messages;
+};
+
+Message *MessageNew(const char *topic, const void *data, size_t size,
+ int qos, int retain);
+
+void MessageFree(Message *msg);
+
+TestClient *TestClientNew(const char *clientId);
+
+void TestClientFree(TestClient *client);
+
+int TestClientConnect(TestClient *client, const char *host, int port,
+ int keepAlive, int cleanSession);
+
+void TestClientDisconnect(TestClient *client);
+
+int TestClientSubscribe(TestClient *client, const char *topicFilter, int qos);
+
+int TestClientPublish(TestClient *client, int qos, int retain,
+ const char *topic, const char *message);
+
+int TestClientMessageCount(TestClient *client);
+
+int TestClientWait(TestClient *client, int timeout);
+
+#endif