31 #if !defined(_WINDOWS) 33 #include <sys/socket.h> 38 #define setenv(a, b, c) _putenv_s(a, b) 41 #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) 61 "tcp://localhost:1883",
63 "tcp://localhost:1884",
77 if (strcmp(argv[count],
"--test_no") == 0)
84 else if (strcmp(argv[count],
"--connection") == 0)
94 else if (strcmp(argv[count],
"--haconnections") == 0)
98 char* tok = strtok(argv[count],
" ");
106 tok = strtok(NULL,
" ");
112 else if (strcmp(argv[count],
"--proxy_connection") == 0)
119 else if (strcmp(argv[count],
"--MQTTversion") == 0)
129 else if (strcmp(argv[count],
"--iterations") == 0)
136 else if (strcmp(argv[count],
"--verbose") == 0)
139 printf(
"\nSetting verbose on\n");
150 #include <sys/timeb.h> 155 #if defined(_WIN32) || defined(_WINDOWS) 165 #if defined(_WIN32) || defined(_WINDOWS) 169 gettimeofday(&ts, NULL);
170 localtime_r(&ts.tv_sec, &timeinfo);
172 strftime(msg_buf, 80,
"%Y%m%d %H%M%S", &timeinfo);
174 #if defined(_WIN32) || defined(_WINDOWS) 175 sprintf(&msg_buf[strlen(msg_buf)],
".%.3hu ", ts.millitm);
177 sprintf(&msg_buf[strlen(msg_buf)],
".%.3lu ", ts.tv_usec / 1000);
180 va_start(args, format);
181 vsnprintf(&msg_buf[strlen(msg_buf)],
sizeof(msg_buf) - strlen(msg_buf), format, args);
184 printf(
"%s\n", msg_buf);
189 #if defined(_WIN32) || defined(_WINDOWS) 190 #define mqsleep(A) Sleep(1000*A) 191 #define START_TIME_TYPE DWORD 192 static DWORD start_time = 0;
195 return GetTickCount();
198 #define mqsleep sleep 199 #define START_TIME_TYPE struct timespec 202 static struct timespec start;
203 clock_gettime(CLOCK_REALTIME, &start);
207 #define mqsleep sleep 208 #define START_TIME_TYPE struct timeval 212 struct timeval start_time;
213 gettimeofday(&start_time, NULL);
222 return GetTickCount() - start_time;
226 long elapsed(
struct timespec start)
228 struct timespec now, res;
230 clock_gettime(CLOCK_REALTIME, &now);
231 ntimersub(now, start, res);
232 return (res.tv_sec)*1000L + (res.tv_nsec)/1000000L;
237 struct timeval now, res;
239 gettimeofday(&now, NULL);
240 timersub(&now, &start_time, &res);
241 return (res.tv_sec)*1000 + (res.tv_usec)/1000;
246 #define assert(a, b, c, d) myassert(__FILE__, __LINE__, a, b, c, d) 247 #define assert1(a, b, c, d, e) myassert(__FILE__, __LINE__, a, b, c, d, e) 261 fprintf(
xml,
" time=\"%ld.%.3ld\" >\n", duration / 1000, duration % 1000);
267 fprintf(
xml,
"</testcase>\n");
279 MyLog(
LOGA_INFO,
"Assertion failed, file %s, line %d, description: %s\n", filename, lineno, description);
281 va_start(args, format);
282 vprintf(format, args);
286 description, filename, lineno);
289 MyLog(
LOGA_DEBUG,
"Assertion succeeded, file %s, line %d, description: %s", filename, lineno, description);
303 char* topicName = NULL;
312 pubmsg.
payload =
"a much longer message that we can shorten to the extent that we need to payload up to 11";
318 property.value.data.data =
"test user property";
319 property.value.data.len = (int)strlen(property.
value.
data.data);
320 property.value.value.data =
"test user property value";
321 property.value.value.len = (int)strlen(property.
value.value.
data);
375 for (i = 0; i < props->
count; ++i)
379 char* intformat =
"Property name %s value %d";
424 fprintf(
xml,
"<testcase classname=\"test1\" name=\"single threaded client using receive\"");
427 MyLog(
LOGA_INFO,
"Starting test 1 - single threaded client using receive");
444 printf(
"test MQTT version %d\n", options.
MQTTVersion);
459 property.value.integer4 = 30;
463 property.value.data.data =
"test user property";
464 property.value.data.len = (int)strlen(property.
value.
data.data);
465 property.value.value.data =
"test user property value";
466 property.value.value.len = (int)strlen(property.
value.value.
data);
485 property.value.integer4 = 33;
505 property.value.data.data =
"User property name";
506 property.value.data.len = (int)strlen(property.
value.
data.data);
507 property.value.value.data =
"User property value";
508 property.value.value.len = (int)strlen(property.
value.value.
data);
517 property.value.integer4 = 0;
558 MyLog(
LOGA_DEBUG,
"Callback: %d message received on topic %s is %.*s.",
565 const int props_count = 0;
590 int wait_seconds = 0;
595 test2_pubmsg.
payload =
"a much longer message that we can shorten to the extent that we need to";
604 test2_pubmsg.
qos, test2_pubmsg.
retained, NULL, NULL);
625 assert(
"Message Arrived", wait_seconds > 0,
626 "Time out waiting for message %d\n", i );
644 assert(
"All Deliveries Complete", wait_seconds > 0,
645 "Number of deliveryCompleted callbacks was %d\n",
653 char* testname =
"test2";
666 fprintf(
xml,
"<testcase classname=\"test1\" name=\"multi-threaded client using callbacks\"");
667 MyLog(
LOGA_INFO,
"Starting test 2 - multi-threaded client using callbacks");
699 assert(
"Good rc from subscribe", response.
reasonCode == subsqos,
"rc was %d", rc);
738 char* testname =
"test3";
746 fprintf(
xml,
"<testcase classname=\"test1\" name=\"connack return codes\"");
759 assert(
"identifier rejected", rc == 2,
"rc was %d\n", rc);
768 assert(
"broker unavailable", rc == 3,
"rc was %d\n", rc);
774 assert(
"Bad user name or password", rc == 4,
"rc was %d\n", rc);
814 int test4_run(
int qos,
int start_mqtt_version,
int restore_mqtt_version)
816 char* testname =
"test 4";
817 char*
topic =
"Persistence test 1";
822 char* topicName = NULL;
836 MyLog(
LOGA_INFO,
"Starting test 4 - persistence, qos %d, MQTT versions: %s then %s", qos,
864 MyLog(
LOGA_DEBUG,
"Cleanup by connecting clean start, add session expiry > 0\n");
867 property.value.integer4 = 30;
878 MyLog(
LOGA_DEBUG,
"Cleanup by connecting clean session, then reconnecting non-cleansession\n");
908 property.value.data.data =
"test user property";
909 property.value.data.len = (int)strlen(property.
value.
data.data);
910 property.value.value.data =
"test user property value";
911 property.value.value.len = (int)strlen(property.
value.value.
data);
915 for (i = 0; i <
count; ++i)
917 sprintf(buffer,
"Message sequence no %d", i);
940 assert(
"should get some tokens back", tokens != NULL,
"tokens was %p", tokens);
945 while (tokens[i] != -1)
947 assert1(
"no of tokens should be count", i == count,
"no of tokens %d count %d", i, count);
969 assert(
"should get some tokens back", tokens != NULL,
"tokens was %p", tokens);
973 while (tokens[i] != -1)
976 assert1(
"no of tokens should be count", i == count,
"no of tokens %d count %d", i, count);
987 for (i = 0; i <
count; ++i)
996 assert(
"No duplicates should be received for qos 2", qos == 1,
"qos is %d", qos);
1006 assert(
"should get a message", m != NULL,
"m was %p", m);
1010 assert(
"topicName is correct", strcmp(topicName, topic) == 0,
"topicName is %s", topicName);
1027 assert(
"should get no tokens back", tokens == NULL,
"tokens was %p", tokens);
1044 fprintf(
xml,
"<testcase classname=\"test4\" name=\"persistence\"");
1056 fprintf(
xml,
"</testcase>\n");
1068 char* testname =
"test 5";
1069 char*
topic =
"Persistence test 2";
1082 fprintf(
xml,
"<testcase classname=\"test1\" name=\"disconnect with quiesce timeout should allow exchanges to complete\"");
1085 MyLog(
LOGA_INFO,
"Starting test 5 - disconnect with quiesce timeout should allow exchanges to complete");
1101 property.value.integer4 = 30;
1117 for (i = 0; i <
count; ++i)
1119 sprintf(buffer,
"Message sequence no %d", i);
1130 assert(
"should get no tokens back", tokens == NULL,
"tokens was %p", tokens);
1161 MyLog(
LOGA_DEBUG,
"Client-2 -> Callback: publish complete for token %d", token);
1170 MyLog(
LOGA_INFO,
"%s -> Callback: message received on topic '%s' is '%.*s'",
1182 char* testname =
"test6";
1188 char* mqttsas_topic =
"MQTTSAS topic";
1192 MyLog(
LOGA_INFO,
"Starting test 6 - connectionLost and will messages");
1193 fprintf(
xml,
"<testcase classname=\"test1\" name=\"connectionLost and will messages\"");
1256 while (++count < 40)
1275 assert(
"Client-2 still connected", rc == 1,
"isconnected is %d", rc);
1278 assert(
"Client-1 not connected", rc == 0,
"isconnected is %d", rc);
1296 char* testname =
"test6a";
1302 char* mqttsas_topic =
"MQTTSAS topic";
1306 MyLog(
LOGA_INFO,
"Starting test 6 - connectionLost and binary will messages");
1307 fprintf(
xml,
"<testcase classname=\"test1\" name=\"connectionLost and binary will messages\"");
1372 while (++count < 40)
1391 assert(
"Client-2 still connected", rc == 1,
"isconnected is %d", rc);
1394 assert(
"Client-1 not connected", rc == 0,
"isconnected is %d", rc);
1415 xml = fopen(
"TEST-test1.xml",
"w");
1416 fprintf(
xml,
"<testsuite name=\"test1\" tests=\"%d\">\n", (
int)(
ARRAY_SIZE(
tests) - 1));
1418 setenv(
"MQTT_C_CLIENT_TRACE",
"ON", 1);
1419 setenv(
"MQTT_C_CLIENT_TRACE_LEVEL",
"ERROR", 1);
1439 fprintf(
xml,
"</testsuite>\n");
int MQTTClient_disconnect5(MQTTClient handle, int timeout, enum MQTTReasonCodes reason, MQTTProperties *props)
#define assert(a, b, c, d)
int test6_messageArrived(void *context, char *topicName, int topicLen, MQTTClient_message *m)
int MQTTClient_waitForCompletion(MQTTClient handle, MQTTClient_deliveryToken mdt, unsigned long timeout)
int test6(struct Options options)
enum MQTTPropertyCodes value
int MQTTClient_receive(MQTTClient handle, char **topicName, int *topicLen, MQTTClient_message **message, unsigned long timeout)
void logProperties(MQTTProperties *props)
MQTTResponse MQTTClient_publish5(MQTTClient handle, const char *topicName, int payloadlen, const void *payload, int qos, int retained, MQTTProperties *properties, MQTTClient_deliveryToken *deliveryToken)
FMT_INLINE std::basic_string< Char > format(const S &format_str, Args &&...args)
#define MQTTCLIENT_SUCCESS
int MQTTClient_isConnected(MQTTClient handle)
int MQTTClient_connect(MQTTClient handle, MQTTClient_connectOptions *options)
void test6_connectionLost(void *context, char *cause)
int MQTTClient_publish(MQTTClient handle, const char *topicName, int payloadlen, const void *payload, int qos, int retained, MQTTClient_deliveryToken *deliveryToken)
#define MQTTCLIENT_PERSISTENCE_ERROR
int MQTTClient_disconnect(MQTTClient handle, int timeout)
void test2_sendAndReceive(MQTTClient *c, int qos, char *test_topic)
void MQTTProperties_free(MQTTProperties *props)
int main(int argc, char **argv)
int MQTTProperties_add(MQTTProperties *props, const MQTTProperty *prop)
size_t strftime(char *str, size_t count, const char *format, const std::tm *time)
int MQTTProperty_getType(enum MQTTPropertyCodes value)
#define MQTTClient_connectOptions_initializer5
char * test6_will_message
int MQTTClient_createWithOptions(MQTTClient *handle, const char *serverURI, const char *clientId, int persistence_type, void *persistence_context, MQTTClient_createOptions *options)
unsigned char retainAsPublished
MQTTResponse MQTTClient_unsubscribe5(MQTTClient handle, const char *topic, MQTTProperties *props)
void myassert(char *filename, int lineno, char *description, int value, char *format,...)
int test4(struct Options options)
#define MQTTClient_message_initializer
enum MQTTReasonCodes reasonCode
void MQTTResponse_free(MQTTResponse response)
MQTTClient_message test2_pubmsg
int test4_run(int qos, int start_mqtt_version, int restore_mqtt_version)
#define MQTTClient_willOptions_initializer
int test2_messageArrived(void *context, char *topicName, int topicLen, MQTTClient_message *message)
int MQTTClient_setCallbacks(MQTTClient handle, void *context, MQTTClient_connectionLost *cl, MQTTClient_messageArrived *ma, MQTTClient_deliveryComplete *dc)
#define assert1(a, b, c, d, e)
const char * MQTTPropertyName(enum MQTTPropertyCodes value)
MQTTResponse MQTTClient_publishMessage5(MQTTClient handle, const char *topicName, MQTTClient_message *message, MQTTClient_deliveryToken *deliveryToken)
struct MQTTClient_willOptions::@56 payload
#define MQTTVERSION_3_1_1
enum MQTTPropertyCodes identifier
int test3(struct Options options)
long elapsed(START_TIME_TYPE start_time)
void MQTTClient_freeMessage(MQTTClient_message **message)
int test6a(struct Options options)
void MQTTClient_yield(void)
void MQTTClient_destroy(MQTTClient *handle)
MQTTResponse MQTTClient_connect5(MQTTClient handle, MQTTClient_connectOptions *options, MQTTProperties *connectProperties, MQTTProperties *willProperties)
#define MQTTCLIENT_PERSISTENCE_DEFAULT
MQTTProperties properties
int test5(struct Options options)
volatile int test2_arrivedcount
START_TIME_TYPE global_start_time
int MQTTClient_subscribe(MQTTClient handle, const char *topic, int qos)
volatile int test6_connection_lost_called
MQTTResponse MQTTClient_subscribe5(MQTTClient handle, const char *topic, int qos, MQTTSubscribe_options *opts, MQTTProperties *props)
START_TIME_TYPE start_clock(void)
void MQTTClient_free(void *memory)
void MyLog(int LOGA_level, char *format,...)
#define MQTTCLIENT_PERSISTENCE_NONE
#define MQTTResponse_initializer
int test2_deliveryCompleted
int MQTTClient_deliveryToken
#define MQTTClient_createOptions_initializer
int MQTTClient_getPendingDeliveryTokens(MQTTClient handle, MQTTClient_deliveryToken **tokens)
void test6_deliveryComplete(void *context, MQTTClient_deliveryToken token)
volatile int test6_will_message_arrived
void test1_sendAndReceive(MQTTClient *c, int qos, char *test_topic)
void write_test_result(void)
#define MQTTSubscribe_options_initializer
int test1(struct Options options)
void getopts(int argc, char **argv)
void test2_deliveryComplete(void *context, MQTTClient_deliveryToken dt)
int MQTTClient_create(MQTTClient *handle, const char *serverURI, const char *clientId, int persistence_type, void *persistence_context)
MQTTClient_willOptions * will
MQTTProperties * properties
int test2(struct Options options)
struct MQTTClient_connectOptions::@58 binarypwd
#define MQTTProperties_initializer