test_sync_session_present.c
Go to the documentation of this file.
1 /*******************************************************************************
2  * Copyright (c) 2009, 2020 IBM Corp. and others
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 - Test program utilities
15  * Milan Tucic - Session present test1
16  *******************************************************************************/
17 
18 
24 #include "MQTTClient.h"
25 #include <string.h>
26 #include <stdlib.h>
27 
28 #if !defined(_WINDOWS)
29  #include <sys/time.h>
30  #include <sys/socket.h>
31  #include <unistd.h>
32  #include <errno.h>
33 #else
34  #include <windows.h>
35  #define setenv(a, b, c) _putenv_s(a, b)
36 #endif
37 
38 #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
39 
40 void usage(void)
41 {
42  printf("help!!\n");
43  exit(EXIT_FAILURE);
44 }
45 
46 struct Options
47 {
48  char* connection;
49  char** haconnections;
50  char* proxy_connection;
51  char* client_id;
52  char* username;
53  char* password;
54  char* log;
55  int hacount;
56  int verbose;
57  int test_no;
58  int MQTTVersion;
59  int iterations;
61 } options =
62 {
63  "tcp://mqtt.eclipse.org:1883",
64  NULL,
65  "tcp://localhost:1883",
66  "cli/test",
67  NULL,
68  NULL,
69  NULL,
70  0,
71  0,
72  0,
74  1,
75  3
76 };
77 
78 void getopts(int argc, char** argv)
79 {
80  int count = 1;
81 
82  while (count < argc)
83  {
84  if (strcmp(argv[count], "--test_no") == 0)
85  {
86  if (++count < argc)
87  options.test_no = atoi(argv[count]);
88  else
89  usage();
90  }
91  else if (strcmp(argv[count], "--connection") == 0)
92  {
93  if (++count < argc)
94  {
95  options.connection = argv[count];
96  printf("\nSetting connection to %s\n", options.connection);
97  }
98  else
99  usage();
100  }
101  else if (strcmp(argv[count], "--haconnections") == 0)
102  {
103  if (++count < argc)
104  {
105  char* tok = strtok(argv[count], " ");
106  options.hacount = 0;
107  options.haconnections = malloc(sizeof(char*) * 5);
108  while (tok)
109  {
110  options.haconnections[options.hacount] = malloc(strlen(tok) + 1);
111  strcpy(options.haconnections[options.hacount], tok);
112  options.hacount++;
113  tok = strtok(NULL, " ");
114  }
115  }
116  else
117  usage();
118  }
119  else if (strcmp(argv[count], "--proxy_connection") == 0)
120  {
121  if (++count < argc)
123  else
124  usage();
125  }
126  else if (strcmp(argv[count], "--client_id") == 0)
127  {
128  if (++count < argc)
129  options.client_id = argv[count];
130  else
131  usage();
132  }
133  else if (strcmp(argv[count], "--username") == 0)
134  {
135  if (++count < argc)
136  options.username = argv[count];
137  else
138  usage();
139  }
140  else if (strcmp(argv[count], "--password") == 0)
141  {
142  if (++count < argc)
143  options.password = argv[count];
144  else
145  usage();
146  }
147  else if (strcmp(argv[count], "--log") == 0)
148  {
149  if (++count < argc)
150  options.log = argv[count];
151  else
152  usage();
153  }
154  else if (strcmp(argv[count], "--MQTTversion") == 0)
155  {
156  if (++count < argc)
157  {
158  options.MQTTVersion = atoi(argv[count]);
159  printf("setting MQTT version to %d\n", options.MQTTVersion);
160  }
161  else
162  usage();
163  }
164  else if (strcmp(argv[count], "--iterations") == 0)
165  {
166  if (++count < argc)
167  options.iterations = atoi(argv[count]);
168  else
169  usage();
170  }
171  else if (strcmp(argv[count], "--reconnection_period") == 0)
172  {
173  if (++count < argc)
174  options.reconnect_period = atoi(argv[count]);
175  else
176  usage();
177  }
178  else if (strcmp(argv[count], "--verbose") == 0)
179  {
180  options.verbose = 1;
181  printf("\nSetting verbose on\n");
182  }
183  count++;
184  }
185 }
186 
187 
188 #define LOGA_DEBUG 0
189 #define LOGA_INFO 1
190 #include <stdarg.h>
191 #include <time.h>
192 #include <sys/timeb.h>
193 void MyLog(int LOGA_level, char* format, ...)
194 {
195  static char msg_buf[256];
196  va_list args;
197 #if defined(_WIN32) || defined(_WINDOWS)
198  struct timeb ts;
199 #else
200  struct timeval ts;
201 #endif
202  struct tm timeinfo;
203 
204  if (LOGA_level == LOGA_DEBUG && options.verbose == 0)
205  return;
206 
207 #if defined(_WIN32) || defined(_WINDOWS)
208  ftime(&ts);
209  localtime_s(&timeinfo, &ts.time);
210 #else
211  gettimeofday(&ts, NULL);
212  localtime_r(&ts.tv_sec, &timeinfo);
213 #endif
214  strftime(msg_buf, 80, "%Y%m%d %H%M%S", &timeinfo);
215 
216 #if defined(_WIN32) || defined(_WINDOWS)
217  sprintf(&msg_buf[strlen(msg_buf)], ".%.3hu ", ts.millitm);
218 #else
219  sprintf(&msg_buf[strlen(msg_buf)], ".%.3lu ", ts.tv_usec / 1000);
220 #endif
221 
222  va_start(args, format);
223  vsnprintf(&msg_buf[strlen(msg_buf)], sizeof(msg_buf) - strlen(msg_buf), format, args);
224  va_end(args);
225 
226  printf("%s\n", msg_buf);
227  fflush(stdout);
228 }
229 
230 
231 #if defined(_WIN32) || defined(_WINDOWS)
232 #define mqsleep(A) Sleep(1000*A)
233 #define START_TIME_TYPE DWORD
234 static DWORD start_time = 0;
236 {
237  return GetTickCount();
238 }
239 #elif defined(AIX)
240 #define mqsleep sleep
241 #define START_TIME_TYPE struct timespec
243 {
244  static struct timespec start;
245  clock_gettime(CLOCK_REALTIME, &start);
246  return start;
247 }
248 #else
249 #define mqsleep sleep
250 #define START_TIME_TYPE struct timeval
251 /* TODO - unused - remove? static struct timeval start_time; */
253 {
254  struct timeval start_time;
255  gettimeofday(&start_time, NULL);
256  return start_time;
257 }
258 #endif
259 
260 
261 #if defined(_WIN32)
262 long elapsed(START_TIME_TYPE start_time)
263 {
264  return GetTickCount() - start_time;
265 }
266 #elif defined(AIX)
267 #define assert(a)
268 long elapsed(struct timespec start)
269 {
270  struct timespec now, res;
271 
272  clock_gettime(CLOCK_REALTIME, &now);
273  ntimersub(now, start, res);
274  return (res.tv_sec)*1000L + (res.tv_nsec)/1000000L;
275 }
276 #else
277 long elapsed(START_TIME_TYPE start_time)
278 {
279  struct timeval now, res;
280 
281  gettimeofday(&now, NULL);
282  timersub(&now, &start_time, &res);
283  return (res.tv_sec)*1000 + (res.tv_usec)/1000;
284 }
285 #endif
286 
287 
288 #define assert(a, b, c, d) myassert(__FILE__, __LINE__, a, b, c, d)
289 #define assert1(a, b, c, d, e) myassert(__FILE__, __LINE__, a, b, c, d, e)
290 
291 int tests = 0;
292 int failures = 0;
293 FILE* xml;
295 char output[3000];
297 
298 
300 {
301  long duration = elapsed(global_start_time);
302 
303  fprintf(xml, " time=\"%ld.%.3ld\" >\n", duration / 1000, duration % 1000);
304  if (cur_output != output)
305  {
306  fprintf(xml, "%s", output);
307  cur_output = output;
308  }
309  fprintf(xml, "</testcase>\n");
310 }
311 
312 
313 void myassert(char* filename, int lineno, char* description, int value, char* format, ...)
314 {
315  ++tests;
316  if (!value)
317  {
318  va_list args;
319 
320  ++failures;
321  MyLog(LOGA_INFO, "Assertion failed, file %s, line %d, description: %s\n", filename, lineno, description);
322 
323  va_start(args, format);
324  vprintf(format, args);
325  va_end(args);
326 
327  cur_output += sprintf(cur_output, "<failure type=\"%s\">file %s, line %d </failure>\n",
328  description, filename, lineno);
329  }
330  else
331  MyLog(LOGA_DEBUG, "Assertion succeeded, file %s, line %d, description: %s", filename, lineno, description);
332 }
333 
334 void mysleep(int seconds)
335 {
336 #if defined(_WIN32)
337  Sleep(1000L*seconds);
338 #else
339  sleep(seconds);
340 #endif
341 }
342 
343 /*********************************************************************
344 
345 Test 1: clean session and reconnect with session present
346 
347 *********************************************************************/
349 
350 void test1_connectionLost(void* context, char* cause)
351 {
352  printf("Callback: connection lost\n");
353 }
354 
356 {
357  printf("Callback: publish complete for token %d\n", token);
358 }
359 
360 int test1_messageArrived(void* context, char* topicName, int topicLen, MQTTClient_message* m)
361 {
362  MQTTClient c = (MQTTClient)context;
363  printf("Callback: message received on topic '%s' is '%.*s'.\n", topicName, m->payloadlen, (char*)(m->payload));
364  MQTTClient_free(topicName);
366  return 1;
367 }
368 
369 int test1(struct Options options)
370 {
371  char* testname = "test1";
373  int rc;
374 
375  failures = 0;
376  MyLog(LOGA_INFO, "Starting test 1 - clean session and reconnect with session present");
377  fprintf(xml, "<testcase classname=\"test1\" name=\"connectionLost and will messages\"");
379 
380  opts.keepAliveInterval = 60;
381  opts.cleansession = 1;
383  if (options.haconnections != NULL)
384  {
385  opts.serverURIs = options.haconnections;
386  opts.serverURIcount = options.hacount;
387  }
388  if (options.username)
389  {
390  opts.username = options.username;
391  }
392  if (options.password)
393  {
394  opts.password = options.password;
395  }
396 
398  assert("good rc from create", rc == MQTTCLIENT_SUCCESS, "rc was %d\n", rc);
399  if (rc != MQTTCLIENT_SUCCESS)
400  goto exit;
401 
403  assert("good rc from setCallbacks", rc == MQTTCLIENT_SUCCESS, "rc was %d\n", rc);
404  if (rc != MQTTCLIENT_SUCCESS)
405  goto exit;
406 
407  /* Connect to the broker with clean session = true */
408  rc = MQTTClient_connect(test1_c1, &opts);
409  assert("good rc from connect with clean session = true", rc == MQTTCLIENT_SUCCESS, "rc was %d\n", rc);
410  if (rc != MQTTCLIENT_SUCCESS)
411  goto exit;
412 
413  assert("connected, session cleaned", opts.returned.sessionPresent == 0,
414  "opts.returned.sessionPresent = %d\n", opts.returned.sessionPresent);
415 
416  /* Disconnect */
417  rc = MQTTClient_disconnect(test1_c1, 1000);
418  assert("good rc from disconnect", rc == MQTTCLIENT_SUCCESS, "rc was %d\n", rc);
419  if (rc != MQTTCLIENT_SUCCESS)
420  goto exit;
421 
422  MyLog(LOGA_INFO, "Sleeping after session cleaned %d s ...", options.reconnect_period);
423  mysleep(options.reconnect_period);
424 
425  /* Connect to the broker with clean session = false */
426  opts.cleansession = 0;
427  rc = MQTTClient_connect(test1_c1, &opts);
428  assert("good rc from connect with clean session = false", rc == MQTTCLIENT_SUCCESS, "rc was %d\n", rc);
429  if (rc != MQTTCLIENT_SUCCESS)
430  goto exit;
431 
432  assert("connected, session clean", opts.returned.sessionPresent == 0,
433  "opts.returned.sessionPresent = %d\n", opts.returned.sessionPresent);
434 
435  /* Disconnect */
436  rc = MQTTClient_disconnect(test1_c1, 1000);
437  assert("good rc from disconnect", rc == MQTTCLIENT_SUCCESS, "rc was %d\n", rc);
438  if (rc != MQTTCLIENT_SUCCESS)
439  goto exit;
440 
441  MyLog(LOGA_INFO, "Sleeping after session persist %d s ...", options.reconnect_period);
442  mysleep(options.reconnect_period);
443 
444  /* Connect to the broker with clean session = false, expected to have session */
445  opts.cleansession = 0;
446  rc = MQTTClient_connect(test1_c1, &opts);
447  assert("good rc from second connect with clean session = false", rc == MQTTCLIENT_SUCCESS, "rc was %d\n", rc);
448  if (rc != MQTTCLIENT_SUCCESS)
449  goto exit;
450 
451  assert("connected, session present", opts.returned.sessionPresent == 1,
452  "opts.returned.sessionPresent = %d\n", opts.returned.sessionPresent);
453 
455 
456 exit:
457  MyLog(LOGA_INFO, "%s: test %s. %d tests run, %d failures.\n",
458  (failures == 0) ? "passed" : "failed", testname, tests, failures);
460  return failures;
461 }
462 
463 int main(int argc, char** argv)
464 {
465  int rc = 0;
466  int (*tests[])() = {NULL, test1};
467  int i;
468  unsigned test_i;
469 
470  xml = fopen("TEST-test1.xml", "w");
471  fprintf(xml, "<testsuite name=\"test1\" tests=\"%d\">\n", (int)(ARRAY_SIZE(tests) - 1));
472 
473  getopts(argc, argv);
474 
475  if (options.log)
476  {
477  setenv("MQTT_C_CLIENT_TRACE", "ON", 1);
478  setenv("MQTT_C_CLIENT_TRACE_LEVEL", options.log, 1);
479  }
480 
481 
482  MyLog(LOGA_INFO, "Running %d iteration(s)", options.iterations);
483 
484  for (i = 0; i < options.iterations; ++i)
485  {
486  if (options.test_no == 0)
487  { /* run all the tests */
488  for (test_i = 1; test_i < ARRAY_SIZE(tests); ++test_i)
489  rc += tests[test_i](options); /* return number of failures. 0 = test succeeded */
490  }
491  else
492  rc = tests[options.test_no](options); /* run just the selected test */
493  }
494 
495  if (rc == 0)
496  MyLog(LOGA_INFO, "verdict pass");
497  else
498  MyLog(LOGA_INFO, "verdict fail");
499 
500  fprintf(xml, "</testsuite>\n");
501  fclose(xml);
502  return rc;
503 }
void mysleep(int seconds)
enum MQTTPropertyCodes value
char ** haconnections
Definition: test1.c:50
int test1_messageArrived(void *context, char *topicName, int topicLen, MQTTClient_message *m)
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 * proxy_connection
Definition: test1.c:51
char * connection
int MQTTClient_disconnect(MQTTClient handle, int timeout)
Definition: MQTTClient.c:1908
char * password
struct pubsub_opts opts
Definition: paho_c_pub.c:42
START_TIME_TYPE start_clock(void)
size_t strftime(char *str, size_t count, const char *format, const std::tm *time)
Definition: chrono.h:375
struct Options options
#define malloc(x)
Definition: Heap.h:41
static char msg_buf[512]
Definition: Log.c:122
void write_test_result(void)
START_TIME_TYPE global_start_time
char output[3000]
int MQTTClient_setCallbacks(MQTTClient handle, void *context, MQTTClient_connectionLost *cl, MQTTClient_messageArrived *ma, MQTTClient_deliveryComplete *dc)
Definition: MQTTClient.c:1032
constexpr size_t count()
Definition: core.h:960
int hacount
Definition: test1.c:52
#define assert(a, b, c, d)
description
Definition: setup.py:19
#define MQTTVERSION_3_1_1
Definition: MQTTAsync.h:203
void MyLog(int LOGA_level, char *format,...)
void test1_connectionLost(void *context, char *cause)
#define LOGA_DEBUG
void MQTTClient_freeMessage(MQTTClient_message **message)
Definition: MQTTClient.c:601
void * MQTTClient
Definition: MQTTClient.h:246
void MQTTClient_destroy(MQTTClient *handle)
Definition: MQTTClient.c:556
int test1(struct Options options)
#define MQTTCLIENT_PERSISTENCE_DEFAULT
MQTTClient test1_c1
void usage(void)
char * cur_output
MQTTClient c
Definition: test10.c:1656
void myassert(char *filename, int lineno, char *description, int value, char *format,...)
dictionary context
Definition: test2.py:57
void MQTTClient_free(void *memory)
Definition: MQTTClient.c:612
null localtime_s(...)
Definition: chrono.h:286
#define MQTTClient_connectOptions_initializer
Definition: MQTTClient.h:953
int MQTTClient_deliveryToken
Definition: MQTTClient.h:257
char * username
long elapsed(START_TIME_TYPE start_time)
char *const * serverURIs
Definition: MQTTClient.h:913
enum MQTTReasonCodes rc
Definition: test10.c:1112
int main(int argc, char **argv)
#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
void getopts(int argc, char **argv)
#define MQTTVERSION_DEFAULT
Definition: MQTTAsync.h:195
void test1_deliveryComplete(void *context, MQTTClient_deliveryToken token)
#define ARRAY_SIZE(a)
int test_no
Definition: test1.c:54
#define LOGA_INFO
Definition: test1.py:1


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