diff options
Diffstat (limited to 'test/interop')
| -rw-r--r-- | test/interop/CMakeLists.txt | 10 | ||||
| -rw-r--r-- | test/interop/basic_test.c | 34 | ||||
| -rw-r--r-- | test/interop/testclient.c | 210 | ||||
| -rw-r--r-- | test/interop/testclient.h | 63 |
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 |
