test_mqtt4sync.c
Go to the documentation of this file.
1 /*******************************************************************************
2  * Copyright (c) 2009, 2014 IBM Corp.
3  *
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v2.0
6  * and Eclipse Distribution License v1.0 which accompany this distribution.
7  *
8  * The Eclipse Public License is available at
9  * https://www.eclipse.org/legal/epl-2.0/
10  * and the Eclipse Distribution License is available at
11  * http://www.eclipse.org/org/documents/edl-v10.php.
12  *
13  * Contributors:
14  * Ian Craggs - initial API and implementation and/or initial documentation
15  * Ian Craggs - MQTT 3.1.1 support
16  *******************************************************************************/
17 
18 
25 /*
26 #if !defined(_RTSHEADER)
27  #include <rts.h>
28 #endif
29 */
30 
31 #include "MQTTClient.h"
32 #include <string.h>
33 #include <stdlib.h>
34 
35 #if !defined(_WINDOWS)
36  #include <sys/time.h>
37  #include <sys/socket.h>
38  #include <unistd.h>
39  #include <errno.h>
40 #else
41 #include <winsock2.h>
42 #include <ws2tcpip.h>
43 #define MAXHOSTNAMELEN 256
44 #define EAGAIN WSAEWOULDBLOCK
45 #define EINTR WSAEINTR
46 #define EINPROGRESS WSAEINPROGRESS
47 #define EWOULDBLOCK WSAEWOULDBLOCK
48 #define ENOTCONN WSAENOTCONN
49 #define ECONNRESET WSAECONNRESET
50 #define setenv(a, b, c) _putenv_s(a, b)
51 #endif
52 
53 #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
54 
55 void usage(void)
56 {
57  printf("help!!\n");
58  exit(EXIT_FAILURE);
59 }
60 
61 struct Options
62 {
63  char* connection;
64  char** haconnections;
65  int hacount;
66  int verbose;
67  int test_no;
68  int iterations;
69 } options =
70 {
71  "tcp://m2m.eclipse.org:1883",
72  NULL,
73  0,
74  0,
75  0,
76  1,
77 };
78 
79 void getopts(int argc, char** argv)
80 {
81  int count = 1;
82 
83  while (count < argc)
84  {
85  if (strcmp(argv[count], "--test_no") == 0)
86  {
87  if (++count < argc)
88  options.test_no = atoi(argv[count]);
89  else
90  usage();
91  }
92  else if (strcmp(argv[count], "--connection") == 0)
93  {
94  if (++count < argc)
95  {
96  options.connection = argv[count];
97  printf("\nSetting connection to %s\n", options.connection);
98  }
99  else
100  usage();
101  }
102  else if (strcmp(argv[count], "--haconnections") == 0)
103  {
104  if (++count < argc)
105  {
106  char* tok = strtok(argv[count], " ");
107  options.hacount = 0;
108  options.haconnections = malloc(sizeof(char*) * 5);
109  while (tok)
110  {
111  options.haconnections[options.hacount] = malloc(strlen(tok) + 1);
112  strcpy(options.haconnections[options.hacount], tok);
113  options.hacount++;
114  tok = strtok(NULL, " ");
115  }
116  }
117  else
118  usage();
119  }
120  else if (strcmp(argv[count], "--iterations") == 0)
121  {
122  if (++count < argc)
123  options.iterations = atoi(argv[count]);
124  else
125  usage();
126  }
127  else if (strcmp(argv[count], "--verbose") == 0)
128  {
129  options.verbose = 1;
130  printf("\nSetting verbose on\n");
131  }
132  count++;
133  }
134 }
135 
136 
137 #define LOGA_DEBUG 0
138 #define LOGA_INFO 1
139 #include <stdarg.h>
140 #include <time.h>
141 #include <sys/timeb.h>
142 void MyLog(int LOGA_level, char* format, ...)
143 {
144  static char msg_buf[256];
145  va_list args;
146  struct timeb ts;
147 
148  struct tm *timeinfo;
149 
150  if (LOGA_level == LOGA_DEBUG && options.verbose == 0)
151  return;
152 
153  ftime(&ts);
154  timeinfo = localtime(&ts.time);
155  strftime(msg_buf, 80, "%Y%m%d %H%M%S", timeinfo);
156 
157  sprintf(&msg_buf[strlen(msg_buf)], ".%.3hu ", ts.millitm);
158 
159  va_start(args, format);
160  vsnprintf(&msg_buf[strlen(msg_buf)], sizeof(msg_buf) - strlen(msg_buf), format, args);
161  va_end(args);
162 
163  printf("%s\n", msg_buf);
164  fflush(stdout);
165 }
166 
167 
168 #if defined(_WIN32) || defined(_WINDOWS)
169 #define mqsleep(A) Sleep(1000*A)
170 #define START_TIME_TYPE DWORD
171 static DWORD start_time = 0;
173 {
174  return GetTickCount();
175 }
176 #elif defined(AIX)
177 #define mqsleep sleep
178 #define START_TIME_TYPE struct timespec
180 {
181  static struct timespec start;
182  clock_gettime(CLOCK_REALTIME, &start);
183  return start;
184 }
185 #else
186 #define mqsleep sleep
187 #define START_TIME_TYPE struct timeval
188 /* TODO - unused - remove? static struct timeval start_time; */
190 {
191  struct timeval start_time;
192  gettimeofday(&start_time, NULL);
193  return start_time;
194 }
195 #endif
196 
197 
198 #if defined(_WIN32)
199 long elapsed(START_TIME_TYPE start_time)
200 {
201  return GetTickCount() - start_time;
202 }
203 #elif defined(AIX)
204 #define assert(a)
205 long elapsed(struct timespec start)
206 {
207  struct timespec now, res;
208 
209  clock_gettime(CLOCK_REALTIME, &now);
210  ntimersub(now, start, res);
211  return (res.tv_sec)*1000L + (res.tv_nsec)/1000000L;
212 }
213 #else
214 long elapsed(START_TIME_TYPE start_time)
215 {
216  struct timeval now, res;
217 
218  gettimeofday(&now, NULL);
219  timersub(&now, &start_time, &res);
220  return (res.tv_sec)*1000 + (res.tv_usec)/1000;
221 }
222 #endif
223 
224 
225 #define assert(a, b, c, d) myassert(__FILE__, __LINE__, a, b, c, d)
226 #define assert1(a, b, c, d, e) myassert(__FILE__, __LINE__, a, b, c, d, e)
227 
228 int tests = 0;
229 int failures = 0;
230 FILE* xml;
232 char output[3000];
234 
235 
237 {
238  long duration = elapsed(global_start_time);
239 
240  fprintf(xml, " time=\"%ld.%.3ld\" >\n", duration / 1000, duration % 1000);
241  if (cur_output != output)
242  {
243  fprintf(xml, "%s", output);
244  cur_output = output;
245  }
246  fprintf(xml, "</testcase>\n");
247 }
248 
249 
250 void myassert(char* filename, int lineno, char* description, int value, char* format, ...)
251 {
252  ++tests;
253  if (!value)
254  {
255  va_list args;
256 
257  ++failures;
258  MyLog(LOGA_INFO, "Assertion failed, file %s, line %d, description: %s\n", filename, lineno, description);
259 
260  va_start(args, format);
261  vprintf(format, args);
262  va_end(args);
263 
264  cur_output += sprintf(cur_output, "<failure type=\"%s\">file %s, line %d </failure>\n",
265  description, filename, lineno);
266  }
267  else
268  MyLog(LOGA_DEBUG, "Assertion succeeded, file %s, line %d, description: %s", filename, lineno, description);
269 }
270 
271 
272 /*********************************************************************
273 
274 Test1: sessionPresent
275 
276 *********************************************************************/
277 int test1(struct Options options)
278 {
279  MQTTClient c;
282  int rc = 0;
283  char* test_topic = "C client test1";
284 
285  fprintf(xml, "<testcase classname=\"test1\" name=\"sessionPresent\"");
287  failures = 0;
288  MyLog(LOGA_INFO, "Starting test 1 - sessionPresent");
289 
290  rc = MQTTClient_create(&c, options.connection, "sesssionPresent",
292  assert("good rc from create", rc == MQTTCLIENT_SUCCESS, "rc was %d\n", rc);
293  if (rc != MQTTCLIENT_SUCCESS)
294  {
295  MQTTClient_destroy(&c);
296  goto exit;
297  }
298 
299  opts.keepAliveInterval = 20;
300  opts.username = "testuser";
301  opts.password = "testpassword";
302  opts.MQTTVersion = 4;
303  if (options.haconnections != NULL)
304  {
305  opts.serverURIs = options.haconnections;
306  opts.serverURIcount = options.hacount;
307  }
308 
309  opts.will = &wopts;
310  opts.will->message = "will message";
311  opts.will->qos = 1;
312  opts.will->retained = 0;
313  opts.will->topicName = "will topic";
314  opts.will = NULL;
315 
316  /* Connect cleansession */
317  opts.cleansession = 1;
318  MyLog(LOGA_DEBUG, "Connecting");
319  rc = MQTTClient_connect(c, &opts);
320  assert("Good rc from connect", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc);
321  if (rc != MQTTCLIENT_SUCCESS)
322  goto exit;
323 
324  assert("Correct serverURI returned", strcmp(opts.returned.serverURI, options.connection) == 0, "serverURI was %s",
325  opts.returned.serverURI);
326  assert("Correct MQTTVersion returned", opts.returned.MQTTVersion == 4, "MQTTVersion was %d",
327  opts.returned.MQTTVersion);
328  assert("Correct sessionPresent returned", opts.returned.sessionPresent == 0, "sessionPresent was %d",
329  opts.returned.sessionPresent);
330 
331  rc = MQTTClient_disconnect(c, 0);
332  assert("Disconnect successful", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc);
333 
334  /* Connect again, non-cleansession */
335  opts.cleansession = 0;
336  rc = MQTTClient_connect(c, &opts);
337  assert("Connect successful", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc);
338 
339  assert("Correct serverURI returned", strcmp(opts.returned.serverURI, options.connection) == 0, "serverURI was %s",
340  opts.returned.serverURI);
341  assert("Correct MQTTVersion returned", opts.returned.MQTTVersion == 4, "MQTTVersion was %d",
342  opts.returned.MQTTVersion);
343  assert("Correct sessionPresent returned", opts.returned.sessionPresent == 0, "sessionPresent was %d",
344  opts.returned.sessionPresent);
345 
346  rc = MQTTClient_disconnect(c, 0);
347  assert("Disconnect successful", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc);
348 
349  /* Connect again, non-cleansession */
350  opts.cleansession = 0;
351  rc = MQTTClient_connect(c, &opts);
352  assert("Connect successful", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc);
353  assert("Correct serverURI returned", strcmp(opts.returned.serverURI, options.connection) == 0, "serverURI was %s",
354  opts.returned.serverURI);
355  assert("Correct MQTTVersion returned", opts.returned.MQTTVersion == 4, "MQTTVersion was %d",
356  opts.returned.MQTTVersion);
357  assert("Correct sessionPresent returned", opts.returned.sessionPresent == 1, "sessionPresent was %d",
358  opts.returned.sessionPresent);
359  rc = MQTTClient_disconnect(c, 0);
360  assert("Disconnect successful", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc);
361 
362  MQTTClient_destroy(&c);
363 
364 exit:
365  MyLog(LOGA_INFO, "TEST1: test %s. %d tests run, %d failures.",
366  (failures == 0) ? "passed" : "failed", tests, failures);
368  return failures;
369 }
370 
371 
372 /*********************************************************************
373 
374 Test2: 0x80 return code from subscribe
375 
376 *********************************************************************/
377 volatile int test2_arrivedcount = 0;
380 
382 {
384 }
385 
386 int test2_messageArrived(void* context, char* topicName, int topicLen, MQTTClient_message* m)
387 {
389  MyLog(LOGA_DEBUG, "Callback: %d message received on topic %s is %.*s.",
390  test2_arrivedcount, topicName, m->payloadlen, (char*)(m->payload));
391  MQTTClient_free(topicName);
393  return 1;
394 }
395 
396 int test2(struct Options options)
397 {
398  char* testname = "test2";
399  int subsqos = 2;
400  MQTTClient c;
402  int rc = 0;
403  char* test_topic = "C client test2";
404  char* topics[2] = {"test_topic", "nosubscribe"};
405  int qoss[2] = {2, 2};
406 
407  fprintf(xml, "<testcase classname=\"test1\" name=\"bad return code from subscribe\"");
408  MyLog(LOGA_INFO, "Starting test 2 - bad return code from subscribe");
410  failures = 0;
411 
412  MQTTClient_create(&c, options.connection, "multi_threaded_sample", MQTTCLIENT_PERSISTENCE_DEFAULT, NULL);
413 
414  opts.keepAliveInterval = 20;
415  opts.cleansession = 1;
416  opts.MQTTVersion = 4;
417  if (options.haconnections != NULL)
418  {
419  opts.serverURIs = options.haconnections;
420  opts.serverURIcount = options.hacount;
421  }
422 
424  assert("Good rc from setCallbacks", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc);
425 
426  MyLog(LOGA_DEBUG, "Connecting");
427  rc = MQTTClient_connect(c, &opts);
428  assert("Good rc from connect", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc);
429  if (rc != MQTTCLIENT_SUCCESS)
430  goto exit;
431 
432  assert("Correct serverURI returned", strcmp(opts.returned.serverURI, options.connection) == 0, "serverURI was %s",
433  opts.returned.serverURI);
434  assert("Correct MQTTVersion returned", opts.returned.MQTTVersion == 4, "MQTTVersion was %d",
435  opts.returned.MQTTVersion);
436  assert("Correct sessionPresent returned", opts.returned.sessionPresent == 0, "sessionPresent was %d",
437  opts.returned.sessionPresent);
438 
439  rc = MQTTClient_subscribe(c, test_topic, subsqos);
440  assert("Good rc from subscribe", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc);
441 
442  rc = MQTTClient_subscribe(c, "nosubscribe", 2);
443  assert("0x80 from subscribe", rc == 0x80, "rc was %d", rc);
444 
445  rc = MQTTClient_subscribeMany(c, 2, topics, qoss);
446  assert("Good rc from subscribe", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc);
447  assert("Correct returned qos from subscribe", qoss[0] == 2, "qos 0 was %d", qoss[0]);
448  assert("Correct returned qos from subscribe", qoss[1] == 0x80, "qos 0 was %d", qoss[0]);
449 
450  rc = MQTTClient_unsubscribe(c, test_topic);
451  assert("Unsubscribe successful", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc);
452  rc = MQTTClient_disconnect(c, 0);
453  assert("Disconnect successful", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc);
454 
455  MQTTClient_destroy(&c);
456 
457 exit:
458  MyLog(LOGA_INFO, "%s: test %s. %d tests run, %d failures.",
459  (failures == 0) ? "passed" : "failed", testname, tests, failures);
461  return failures;
462 }
463 
464 
465 int main(int argc, char** argv)
466 {
467  int rc = 0;
468  int (*tests[])() = {NULL, test1, test2};
469  int i;
470 
471  xml = fopen("TEST-MQTT4sync.xml", "w");
472  fprintf(xml, "<testsuite name=\"test-mqtt4sync\" tests=\"%d\">\n", (int)(ARRAY_SIZE(tests) - 1));
473 
474  setenv("MQTT_C_CLIENT_TRACE", "ON", 1);
475  setenv("MQTT_C_CLIENT_TRACE_LEVEL", "ERROR", 1);
476 
477  getopts(argc, argv);
478 
479  for (i = 0; i < options.iterations; ++i)
480  {
481  if (options.test_no == 0)
482  { /* run all the tests */
484  rc += tests[options.test_no](options); /* return number of failures. 0 = test succeeded */
485  }
486  else
487  rc = tests[options.test_no](options); /* run just the selected test */
488  }
489 
490  if (rc == 0)
491  MyLog(LOGA_INFO, "verdict pass");
492  else
493  MyLog(LOGA_INFO, "verdict fail");
494 
495  fprintf(xml, "</testsuite>\n");
496  fclose(xml);
497  return rc;
498 }
void MyLog(int LOGA_level, char *format,...)
MQTTClient_message test2_pubmsg
START_TIME_TYPE global_start_time
enum MQTTPropertyCodes value
char ** haconnections
Definition: test1.c:50
void getopts(int argc, char **argv)
void write_test_result(void)
FMT_INLINE std::basic_string< Char > format(const S &format_str, Args &&...args)
Definition: core.h:2081
#define MQTTCLIENT_SUCCESS
Definition: MQTTClient.h:131
struct MQTTClient_connectOptions::@57 returned
int MQTTClient_connect(MQTTClient handle, MQTTClient_connectOptions *options)
Definition: MQTTClient.c:1644
char * connection
int MQTTClient_disconnect(MQTTClient handle, int timeout)
Definition: MQTTClient.c:1908
int test2(struct Options options)
Definition: test2.py:1
struct pubsub_opts opts
Definition: paho_c_pub.c:42
size_t strftime(char *str, size_t count, const char *format, const std::tm *time)
Definition: chrono.h:375
#define malloc(x)
Definition: Heap.h:41
#define LOGA_DEBUG
std::tm localtime(std::time_t time)
Definition: chrono.h:292
void test2_deliveryComplete(void *context, MQTTClient_deliveryToken dt)
#define MQTTClient_message_initializer
Definition: MQTTClient.h:327
static char msg_buf[512]
Definition: Log.c:122
#define MQTTClient_willOptions_initializer
Definition: MQTTClient.h:639
int test2_deliveryCompleted
int MQTTClient_setCallbacks(MQTTClient handle, void *context, MQTTClient_connectionLost *cl, MQTTClient_messageArrived *ma, MQTTClient_deliveryComplete *dc)
Definition: MQTTClient.c:1032
#define assert(a, b, c, d)
constexpr size_t count()
Definition: core.h:960
int hacount
Definition: test1.c:52
description
Definition: setup.py:19
int MQTTClient_unsubscribe(MQTTClient handle, const char *topic)
Definition: MQTTClient.c:2239
const char * topicName
Definition: MQTTClient.h:619
char * cur_output
void MQTTClient_freeMessage(MQTTClient_message **message)
Definition: MQTTClient.c:601
START_TIME_TYPE start_clock(void)
int main(int argc, char **argv)
void * MQTTClient
Definition: MQTTClient.h:246
void MQTTClient_destroy(MQTTClient *handle)
Definition: MQTTClient.c:556
int test2_messageArrived(void *context, char *topicName, int topicLen, MQTTClient_message *m)
#define MQTTCLIENT_PERSISTENCE_DEFAULT
#define ARRAY_SIZE(a)
int MQTTClient_subscribe(MQTTClient handle, const char *topic, int qos)
Definition: MQTTClient.c:2104
FILE * xml
char * test_topic
Definition: test11.c:307
long elapsed(START_TIME_TYPE start_time)
MQTTClient c
Definition: test10.c:1656
dictionary context
Definition: test2.py:57
void MQTTClient_free(void *memory)
Definition: MQTTClient.c:612
#define MQTTClient_connectOptions_initializer
Definition: MQTTClient.h:953
int MQTTClient_subscribeMany(MQTTClient handle, int count, char *const *topic, int *qos)
Definition: MQTTClient.c:2075
int MQTTClient_deliveryToken
Definition: MQTTClient.h:257
int tests
char output[3000]
int test1(struct Options options)
void myassert(char *filename, int lineno, char *description, int value, char *format,...)
int failures
void usage(void)
char *const * serverURIs
Definition: MQTTClient.h:913
volatile int test2_arrivedcount
char * topics[]
const char * message
Definition: MQTTClient.h:621
enum MQTTReasonCodes rc
Definition: test10.c:1112
#define START_TIME_TYPE
int MQTTClient_create(MQTTClient *handle, const char *serverURI, const char *clientId, int persistence_type, void *persistence_context)
Definition: MQTTClient.c:507
MQTTClient_willOptions * will
Definition: MQTTClient.h:866
int test_no
Definition: test1.c:54
struct Options options
#define LOGA_INFO


plotjuggler
Author(s): Davide Faconti
autogenerated on Sun Dec 6 2020 04:02:48