test3.c 54 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735
  1. /*******************************************************************************
  2. * Copyright (c) 2012, 2022 IBM Corp., Ian Craggs 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. * Allan Stockdill-Mander - initial API and implementation and/or initial documentation
  15. * Ian Craggs - add SSL options NULL test
  16. *******************************************************************************/
  17. /**
  18. * @file
  19. * SSL tests for the Eclipse Paho MQTT C client
  20. */
  21. #include "MQTTClient.h"
  22. #include <string.h>
  23. #include <stdlib.h>
  24. #if defined(_WINDOWS)
  25. #include <windows.h>
  26. #include <openssl/applink.c>
  27. #define MAXHOSTNAMELEN 256
  28. #define snprintf _snprintf
  29. #define setenv(a, b, c) _putenv_s(a, b)
  30. #else
  31. #include <sys/time.h>
  32. #include <sys/socket.h>
  33. #include <unistd.h>
  34. #include <errno.h>
  35. #endif
  36. #if defined(IOS)
  37. char skeytmp[1024];
  38. char ckeytmp[1024];
  39. char persistenceStore[1024];
  40. #else
  41. char* persistenceStore = NULL;
  42. #endif
  43. #define LOGA_DEBUG 0
  44. #define LOGA_INFO 1
  45. #include <stdarg.h>
  46. #include <time.h>
  47. #include <sys/timeb.h>
  48. #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
  49. void usage(void)
  50. {
  51. printf("Options:\n");
  52. printf("\t--test_no <test_no> - Run test number <test_no>\n");
  53. printf("\t--connection <mqtt URL> - Connect to <mqtt URL> for tests\n");
  54. printf("\t--haconnections \"<mqtt URLs>\" - Use \"<mqtt URLs>\" as the list of servers for HA tests (space separated)\n");
  55. printf("\t--client_key <key_file> - Use <key_file> as the client certificate for SSL authentication\n");
  56. printf("\t--client_key_pass <password> - Use <password> to access the private key in the client certificate\n");
  57. printf("\t--client_privatekey <file> - Client private key file if not in certificate file\n");
  58. printf("\t--server_key <key_file> - Use <key_file> as the trusted certificate for server\n");
  59. printf("\t--verbose - Enable verbose output \n");
  60. printf("\tserver connection URLs should be in the form; (tcp|ssl)://hostname:port\n");
  61. printf("\t--help - This help output\n");
  62. exit(EXIT_FAILURE);
  63. }
  64. struct Options
  65. {
  66. char connection[100];
  67. char mutual_auth_connection[100]; /**< connection to system under test. */
  68. char nocert_mutual_auth_connection[100];
  69. char server_auth_connection[100];
  70. char anon_connection[100];
  71. char psk_connection[100];
  72. char** haconnections; /**< connection to system under test. */
  73. int hacount;
  74. char* client_key_file;
  75. char* client_key_pass;
  76. char* server_key_file;
  77. char* client_private_key_file;
  78. int verbose;
  79. int test_no;
  80. int websockets;
  81. } options =
  82. {
  83. "ssl://localhost:18883",
  84. "mqtts://localhost:18884",
  85. "ssl://localhost:18887",
  86. "mqtts://localhost:18885",
  87. "ssl://localhost:18886",
  88. "mqtts://localhost:18888",
  89. NULL,
  90. 0,
  91. "../../../test/ssl/client.pem",
  92. NULL,
  93. "../../../test/ssl/test-root-ca.crt",
  94. NULL,
  95. 0,
  96. 0,
  97. 0,
  98. };
  99. char* test_map[] =
  100. {
  101. "none",
  102. "1", // 1
  103. "2a_s", // 2
  104. "2a_m", // 3
  105. "2b", // 4
  106. "2c", // 5
  107. "3a_s", // 6
  108. "3a_m", // 7
  109. "3b", // 8
  110. "4s", // 9
  111. "4m", // 10
  112. "5a", // 11
  113. "5b", // 12
  114. "5c", // 13
  115. };
  116. void getopts(int argc, char** argv)
  117. {
  118. int count = 1;
  119. while (count < argc)
  120. {
  121. if (strcmp(argv[count], "--help") == 0)
  122. usage();
  123. else if (strcmp(argv[count], "--test_no") == 0)
  124. {
  125. if (++count < argc)
  126. {
  127. int i;
  128. for (i = 1; i < ARRAY_SIZE(test_map); ++i)
  129. {
  130. if (strcmp(argv[count], test_map[i]) == 0)
  131. {
  132. options.test_no = i;
  133. break;
  134. }
  135. }
  136. if (options.test_no == 0)
  137. options.test_no = atoi(argv[count]);
  138. }
  139. else
  140. usage();
  141. }
  142. else if (strcmp(argv[count], "--hostname") == 0)
  143. {
  144. if (++count < argc)
  145. {
  146. char* prefix = (options.websockets) ? "wss" : "ssl";
  147. sprintf(options.connection, "%s://%s:18883", prefix, argv[count]);
  148. printf("Setting connection to %s\n", options.connection);
  149. sprintf(options.mutual_auth_connection, "%s://%s:18884", prefix, argv[count]);
  150. printf("Setting mutual_auth_connection to %s\n", options.mutual_auth_connection);
  151. sprintf(options.nocert_mutual_auth_connection, "%s://%s:18887", prefix, argv[count]);
  152. printf("Setting nocert_mutual_auth_connection to %s\n",
  153. options.nocert_mutual_auth_connection);
  154. sprintf(options.server_auth_connection, "%s://%s:18885", prefix, argv[count]);
  155. printf("Setting server_auth_connection to %s\n", options.server_auth_connection);
  156. sprintf(options.anon_connection, "%s://%s:18886", prefix, argv[count]);
  157. printf("Setting anon_connection to %s\n", options.anon_connection);
  158. sprintf(options.psk_connection, "%s://%s:18888", prefix, argv[count]);
  159. printf("Setting psk_connection to %s\n", options.psk_connection);
  160. }
  161. else
  162. usage();
  163. }
  164. else if (strcmp(argv[count], "--haconnections") == 0)
  165. {
  166. if (++count < argc)
  167. {
  168. char* tok = strtok(argv[count], " ");
  169. options.hacount = 0;
  170. options.haconnections = malloc(sizeof(char*) * 5);
  171. while (tok)
  172. {
  173. options.haconnections[options.hacount] = malloc(strlen(tok) + 1);
  174. strcpy(options.haconnections[options.hacount], tok);
  175. options.hacount++;
  176. tok = strtok(NULL, " ");
  177. }
  178. }
  179. else
  180. usage();
  181. }
  182. else if (strcmp(argv[count], "--client_key") == 0)
  183. {
  184. if (++count < argc)
  185. {
  186. #if defined(IOS)
  187. strcat(ckeytmp, getenv("HOME"));
  188. strcat(ckeytmp, argv[count]);
  189. options.client_key_file = ckeytmp;
  190. #else
  191. options.client_key_file = argv[count];
  192. #endif
  193. }
  194. else
  195. usage();
  196. }
  197. else if (strcmp(argv[count], "--client_privatekey") == 0)
  198. {
  199. if (++count < argc)
  200. {
  201. #if defined(IOS)
  202. strcat(ckeytmp, getenv("HOME"));
  203. strcat(ckeytmp, argv[count]);
  204. options.client_private_key_file = ckeytmp;
  205. #else
  206. options.client_private_key_file = argv[count];
  207. #endif
  208. }
  209. else
  210. usage();
  211. }
  212. else if (strcmp(argv[count], "--client_key_pass") == 0)
  213. {
  214. if (++count < argc)
  215. options.client_key_pass = argv[count];
  216. else
  217. usage();
  218. }
  219. else if (strcmp(argv[count], "--server_key") == 0)
  220. {
  221. if (++count < argc)
  222. {
  223. #if defined(IOS)
  224. strcat(skeytmp, getenv("HOME"));
  225. strcat(skeytmp, argv[count]);
  226. options.server_key_file = skeytmp;
  227. #else
  228. options.server_key_file = argv[count];
  229. #endif
  230. }
  231. else
  232. usage();
  233. }
  234. else if (strcmp(argv[count], "--verbose") == 0)
  235. {
  236. options.verbose = 1;
  237. printf("\nSetting verbose on\n");
  238. }
  239. else if (strcmp(argv[count], "--ws") == 0)
  240. {
  241. options.websockets = 1;
  242. printf("\nSetting websockets on\n");
  243. }
  244. count++;
  245. }
  246. #if defined(IOS)
  247. strcpy(persistenceStore, getenv("HOME"));
  248. strcat(persistenceStore, "/Library/Caches");
  249. #endif
  250. }
  251. void MyLog(int LOGA_level, char* format, ...)
  252. {
  253. static char msg_buf[256];
  254. va_list args;
  255. #if defined(_WIN32) || defined(_WINDOWS)
  256. struct timeb ts;
  257. #else
  258. struct timeval ts;
  259. #endif
  260. struct tm timeinfo;
  261. if (LOGA_level == LOGA_DEBUG && options.verbose == 0)
  262. return;
  263. #if defined(_WIN32) || defined(_WINDOWS)
  264. ftime(&ts);
  265. localtime_s(&timeinfo, &ts.time);
  266. #else
  267. gettimeofday(&ts, NULL);
  268. localtime_r(&ts.tv_sec, &timeinfo);
  269. #endif
  270. strftime(msg_buf, 80, "%Y%m%d %H%M%S", &timeinfo);
  271. #if defined(_WIN32) || defined(_WINDOWS)
  272. sprintf(&msg_buf[strlen(msg_buf)], ".%.3hu ", ts.millitm);
  273. #else
  274. sprintf(&msg_buf[strlen(msg_buf)], ".%.3lu ", ts.tv_usec / 1000L);
  275. #endif
  276. va_start(args, format);
  277. vsnprintf(&msg_buf[strlen(msg_buf)], sizeof(msg_buf) - strlen(msg_buf), format, args);
  278. va_end(args);
  279. printf("%s\n", msg_buf);
  280. fflush(stdout);
  281. }
  282. #if defined(_WIN32) || defined(_WINDOWS)
  283. #define mqsleep(A) Sleep(1000*A)
  284. #define START_TIME_TYPE DWORD
  285. static DWORD start_time = 0;
  286. START_TIME_TYPE start_clock(void)
  287. {
  288. return GetTickCount();
  289. }
  290. #elif defined(AIX)
  291. #define mqsleep sleep
  292. #define START_TIME_TYPE struct timespec
  293. START_TIME_TYPE start_clock(void)
  294. {
  295. static struct timespec start;
  296. clock_gettime(CLOCK_REALTIME, &start);
  297. return start;
  298. }
  299. #else
  300. #define mqsleep sleep
  301. #define START_TIME_TYPE struct timeval
  302. /* TODO - unused - remove? static struct timeval start_time; */
  303. START_TIME_TYPE start_clock(void)
  304. {
  305. struct timeval start_time;
  306. gettimeofday(&start_time, NULL);
  307. return start_time;
  308. }
  309. #endif
  310. #if defined(_WIN32)
  311. long elapsed(START_TIME_TYPE start_time)
  312. {
  313. return GetTickCount() - start_time;
  314. }
  315. #elif defined(AIX)
  316. #define assert(a)
  317. long elapsed(struct timespec start)
  318. {
  319. struct timespec now, res;
  320. clock_gettime(CLOCK_REALTIME, &now);
  321. ntimersub(now, start, res);
  322. return (res.tv_sec)*1000L + (res.tv_nsec)/1000000L;
  323. }
  324. #else
  325. long elapsed(START_TIME_TYPE start_time)
  326. {
  327. struct timeval now, res;
  328. gettimeofday(&now, NULL);
  329. timersub(&now, &start_time, &res);
  330. return (res.tv_sec)*1000 + (res.tv_usec)/1000;
  331. }
  332. #endif
  333. #define assert(a, b, c, d) myassert(__FILE__, __LINE__, a, b, c, d)
  334. #define assert1(a, b, c, d, e) myassert(__FILE__, __LINE__, a, b, c, d, e)
  335. int tests = 0;
  336. int failures = 0;
  337. FILE* xml;
  338. START_TIME_TYPE global_start_time;
  339. char output[3000];
  340. char* cur_output = output;
  341. void write_test_result(void)
  342. {
  343. long duration = elapsed(global_start_time);
  344. fprintf(xml, " time=\"%ld.%.3ld\" >\n", duration / 1000, duration % 1000);
  345. if (cur_output != output)
  346. {
  347. fprintf(xml, "%s", output);
  348. cur_output = output;
  349. }
  350. fprintf(xml, "</testcase>\n");
  351. }
  352. int myassert(char* filename, int lineno, char* description, int value, char* format, ...)
  353. {
  354. ++tests;
  355. if (!value)
  356. {
  357. va_list args;
  358. ++failures;
  359. printf("Assertion failed, file %s, line %d, description: %s\n", filename, lineno, description);
  360. va_start(args, format);
  361. vprintf(format, args);
  362. va_end(args);
  363. cur_output += sprintf(cur_output, "<failure type=\"%s\">file %s, line %d </failure>\n",
  364. description, filename, lineno);
  365. }
  366. else
  367. MyLog(LOGA_DEBUG, "Assertion succeeded, file %s, line %d, description: %s", filename, lineno, description);
  368. return value;
  369. }
  370. /*********************************************************************
  371. Test: single-threaded client
  372. *********************************************************************/
  373. void singleThread_sendAndReceive(MQTTClient* c, int qos, char* test_topic)
  374. {
  375. MQTTClient_deliveryToken dt;
  376. MQTTClient_message pubmsg = MQTTClient_message_initializer;
  377. MQTTClient_message* m = NULL;
  378. char* topicName = NULL;
  379. int topicLen;
  380. int i = 0;
  381. int iterations = 50;
  382. int rc;
  383. MyLog(LOGA_DEBUG, "%d messages at QoS %d", iterations, qos);
  384. pubmsg.payload = "a much longer message that we can shorten to the extent that we need to payload up to 11";
  385. pubmsg.payloadlen = 11;
  386. pubmsg.qos = qos;
  387. pubmsg.retained = 0;
  388. for (i = 0; i< iterations; ++i)
  389. {
  390. if (i % 10 == 0)
  391. rc = MQTTClient_publish(c, test_topic, pubmsg.payloadlen, pubmsg.payload, pubmsg.qos, pubmsg.retained, NULL);
  392. else
  393. rc = MQTTClient_publishMessage(c, test_topic, &pubmsg, &dt);
  394. assert("Good rc from publish", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc);
  395. if (qos > 0)
  396. {
  397. rc = MQTTClient_waitForCompletion(c, dt, 20000L);
  398. assert("Good rc from waitforCompletion", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc);
  399. }
  400. rc = MQTTClient_receive(c, &topicName, &topicLen, &m, 10000);
  401. assert("Good rc from receive", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc);
  402. if (topicName)
  403. {
  404. MyLog(LOGA_DEBUG, "Message received on topic %s is %.*s", topicName, m->payloadlen, (char*)(m->payload));
  405. if (pubmsg.payloadlen != m->payloadlen ||
  406. memcmp(m->payload, pubmsg.payload, m->payloadlen) != 0)
  407. {
  408. failures++;
  409. MyLog(LOGA_INFO, "Error: wrong data - received lengths %d %d", pubmsg.payloadlen, m->payloadlen);
  410. break;
  411. }
  412. MQTTClient_free(topicName);
  413. MQTTClient_freeMessage(&m);
  414. }
  415. else
  416. printf("No message received within timeout period\n");
  417. }
  418. /* receive any outstanding messages */
  419. MQTTClient_receive(c, &topicName, &topicLen, &m, 1000);
  420. while (topicName)
  421. {
  422. printf("Message received on topic %s is %.*s.\n", topicName, m->payloadlen, (char*)(m->payload));
  423. MQTTClient_free(topicName);
  424. MQTTClient_freeMessage(&m);
  425. MQTTClient_receive(c, &topicName, &topicLen, &m, 1000);
  426. }
  427. }
  428. /*********************************************************************
  429. Test: multi-threaded client using callbacks
  430. *********************************************************************/
  431. volatile int multiThread_arrivedcount = 0;
  432. int multiThread_deliveryCompleted = 0;
  433. MQTTClient_message multiThread_pubmsg = MQTTClient_message_initializer;
  434. void multiThread_deliveryComplete(void* context, MQTTClient_deliveryToken dt)
  435. {
  436. ++multiThread_deliveryCompleted;
  437. }
  438. int multiThread_messageArrived(void* context, char* topicName, int topicLen, MQTTClient_message* m)
  439. {
  440. ++multiThread_arrivedcount;
  441. MyLog(LOGA_DEBUG, "Callback: %d message received on topic %s is %.*s.",
  442. multiThread_arrivedcount, topicName, m->payloadlen, (char*)(m->payload));
  443. if (multiThread_pubmsg.payloadlen != m->payloadlen ||
  444. memcmp(m->payload, multiThread_pubmsg.payload, m->payloadlen) != 0)
  445. {
  446. failures++;
  447. MyLog(LOGA_INFO, "Error: wrong data received lengths %d %d\n", multiThread_pubmsg.payloadlen, m->payloadlen);
  448. }
  449. MQTTClient_free(topicName);
  450. MQTTClient_freeMessage(&m);
  451. return 1;
  452. }
  453. void multiThread_sendAndReceive(MQTTClient* c, int qos, char* test_topic)
  454. {
  455. MQTTClient_deliveryToken dt;
  456. int i = 0;
  457. int iterations = 50;
  458. int rc = 0;
  459. int wait_seconds = 0;
  460. multiThread_deliveryCompleted = 0;
  461. multiThread_arrivedcount = 0;
  462. MyLog(LOGA_DEBUG, "%d messages at QoS %d", iterations, qos);
  463. multiThread_pubmsg.payload = "a much longer message that we can shorten to the extent that we need to";
  464. multiThread_pubmsg.payloadlen = 27;
  465. multiThread_pubmsg.qos = qos;
  466. multiThread_pubmsg.retained = 0;
  467. for (i = 1; i <= iterations; ++i)
  468. {
  469. if (i % 10 == 0)
  470. rc = MQTTClient_publish(c, test_topic, multiThread_pubmsg.payloadlen, multiThread_pubmsg.payload,
  471. multiThread_pubmsg.qos, multiThread_pubmsg.retained, NULL);
  472. else
  473. rc = MQTTClient_publishMessage(c, test_topic, &multiThread_pubmsg, &dt);
  474. assert("Good rc from publish", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc);
  475. #if defined(_WIN32)
  476. Sleep(100);
  477. #else
  478. usleep(100000L);
  479. #endif
  480. wait_seconds = 20;
  481. while ((multiThread_arrivedcount < i) && (wait_seconds-- > 0))
  482. {
  483. MyLog(LOGA_DEBUG, "Arrived %d count %d", multiThread_arrivedcount, i);
  484. #if defined(_WIN32)
  485. Sleep(1000);
  486. #else
  487. usleep(1000000L);
  488. #endif
  489. }
  490. assert("Message Arrived", wait_seconds > 0,
  491. "Time out waiting for message %d\n", i );
  492. }
  493. if (qos > 0)
  494. {
  495. /* MQ Telemetry can send a message to a subscriber before the server has
  496. completed the QoS 2 handshake with the publisher. For QoS 1 and 2,
  497. allow time for the final delivery complete callback before checking
  498. that all expected callbacks have been made */
  499. wait_seconds = 10;
  500. while ((multiThread_deliveryCompleted < iterations) && (wait_seconds-- > 0))
  501. {
  502. MyLog(LOGA_DEBUG, "Delivery Completed %d count %d", multiThread_deliveryCompleted, i);
  503. #if defined(_WIN32)
  504. Sleep(1000);
  505. #else
  506. usleep(1000000L);
  507. #endif
  508. }
  509. assert("All Deliveries Complete", wait_seconds > 0,
  510. "Number of deliveryCompleted callbacks was %d\n",
  511. multiThread_deliveryCompleted);
  512. }
  513. }
  514. /*********************************************************************
  515. Test1: SSL connection to non SSL MQTT server
  516. *********************************************************************/
  517. int test1(struct Options options)
  518. {
  519. char* testname = "test1";
  520. char* test_topic = "C client SSL test1";
  521. int subsqos = 2;
  522. MQTTClient c;
  523. MQTTClient_connectOptions opts = MQTTClient_connectOptions_initializer;
  524. MQTTClient_willOptions wopts = MQTTClient_willOptions_initializer;
  525. MQTTClient_SSLOptions sslopts = MQTTClient_SSLOptions_initializer;
  526. int rc = 0;
  527. failures = 0;
  528. MyLog(LOGA_INFO, "Starting SSL test 1 - connection to nonSSL MQTT server");
  529. fprintf(xml, "<testcase classname=\"test3\" name=\"SSL connect fail to nonSSL MQTT server\"");
  530. global_start_time = start_clock();
  531. rc = MQTTClient_create(&c, "a b://wrong protocol", "test1", MQTTCLIENT_PERSISTENCE_DEFAULT, persistenceStore);
  532. assert("bad rc from create", rc == MQTTCLIENT_BAD_PROTOCOL, "rc was %d \n", rc);
  533. rc = MQTTClient_create(&c, options.connection, "test1", MQTTCLIENT_PERSISTENCE_DEFAULT, persistenceStore);
  534. if (!(assert("good rc from create", rc == MQTTCLIENT_SUCCESS, "rc was %d \n", rc)))
  535. goto exit;
  536. opts.keepAliveInterval = 20;
  537. opts.cleansession = 1;
  538. opts.username = "testuser";
  539. opts.password = "testpassword";
  540. if (options.haconnections != NULL)
  541. {
  542. opts.serverURIs = options.haconnections;
  543. opts.serverURIcount = options.hacount;
  544. }
  545. /* Try with ssl opts == NULL - should get error */
  546. rc = MQTTClient_connect(c, &opts);
  547. assert("Connect should fail", rc == MQTTCLIENT_NULL_PARAMETER, "rc was %d ", rc);
  548. opts.ssl = &sslopts;
  549. if (options.server_key_file != NULL)
  550. opts.ssl->trustStore = options.server_key_file; /*file of certificates trusted by client*/
  551. MyLog(LOGA_DEBUG, "Connecting");
  552. rc = MQTTClient_connect(c, &opts);
  553. if (!(assert("Connect should fail", rc == MQTTCLIENT_FAILURE, "rc was %d ", rc)))
  554. goto exit;
  555. exit:
  556. MQTTClient_destroy(&c);
  557. MyLog(LOGA_INFO, "%s: test %s. %d tests run, %d failures.",
  558. (failures == 0) ? "passed" : "failed", testname, tests, failures);
  559. write_test_result();
  560. return failures;
  561. }
  562. /*********************************************************************
  563. Test2a: Mutual SSL Authentication - Certificates in place on client and server - single threaded
  564. *********************************************************************/
  565. int test2a_s(struct Options options)
  566. {
  567. char* testname = "test2a_s";
  568. char* test_topic = "C client test2a_s";
  569. int subsqos = 2;
  570. MQTTClient c;
  571. MQTTClient_connectOptions opts = MQTTClient_connectOptions_initializer;
  572. MQTTClient_willOptions wopts = MQTTClient_willOptions_initializer;
  573. MQTTClient_SSLOptions sslopts = MQTTClient_SSLOptions_initializer;
  574. int rc = 0;
  575. failures = 0;
  576. MyLog(LOGA_INFO, "Starting test 2a_s - Mutual SSL authentication - single threaded client using receive");
  577. fprintf(xml, "<testcase classname=\"test3\" name=\"test 2a_s\"");
  578. global_start_time = start_clock();
  579. rc = MQTTClient_create(&c, options.server_auth_connection, "test2a_s", MQTTCLIENT_PERSISTENCE_DEFAULT, persistenceStore);
  580. if (!(assert("good rc from create", rc == MQTTCLIENT_SUCCESS, "rc was %d\n", rc)))
  581. goto exit;
  582. opts.keepAliveInterval = 20;
  583. opts.cleansession = 1;
  584. opts.username = "testuser";
  585. opts.password = "testpassword";
  586. if (options.haconnections != NULL) {
  587. opts.serverURIs = options.haconnections;
  588. opts.serverURIcount = options.hacount;
  589. }
  590. opts.ssl = &sslopts;
  591. if (options.server_key_file)
  592. opts.ssl->trustStore = options.server_key_file; /*file of certificates trusted by client*/
  593. opts.ssl->keyStore = options.client_key_file; /*file of certificate for client to present to server*/
  594. if (options.client_key_pass)
  595. opts.ssl->privateKeyPassword = options.client_key_pass;
  596. if (options.client_private_key_file)
  597. opts.ssl->privateKey = options.client_private_key_file;
  598. opts.ssl->verify = 1;
  599. MyLog(LOGA_DEBUG, "Connecting");
  600. rc = MQTTClient_connect(c, &opts);
  601. if (!(assert("Good rc from connect", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
  602. goto exit;
  603. rc = MQTTClient_subscribe(c, test_topic, subsqos);
  604. if (!(assert("Good rc from subscribe", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
  605. goto exit;
  606. singleThread_sendAndReceive(c, 0, test_topic);
  607. singleThread_sendAndReceive(c, 1, test_topic);
  608. singleThread_sendAndReceive(c, 2, test_topic);
  609. MyLog(LOGA_DEBUG, "Stopping\n");
  610. rc = MQTTClient_unsubscribe(c, test_topic);
  611. if (!(assert("Unsubscribe successful", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
  612. goto exit;
  613. rc = MQTTClient_disconnect(c, 0);
  614. if (!(assert("Disconnect successful", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
  615. goto exit;
  616. /* Just to make sure we can connect again */
  617. rc = MQTTClient_connect(c, &opts);
  618. if (!(assert("Connect successful", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
  619. goto exit;
  620. rc = MQTTClient_disconnect(c, 0);
  621. if (!(assert("Disconnect successful", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
  622. goto exit;
  623. exit:
  624. MQTTClient_destroy(&c);
  625. MyLog(LOGA_INFO, "%s: test %s. %d tests run, %d failures.",
  626. (failures == 0) ? "passed" : "failed", testname, tests, failures);
  627. write_test_result();
  628. return failures;
  629. }
  630. /*********************************************************************
  631. Test2a: Mutual SSL Authentication - Certificates in place on client and server - multi threaded
  632. *********************************************************************/
  633. int test2a_m(struct Options options)
  634. {
  635. char* testname = "test2a_m";
  636. char* test_topic = "C client test2a_m";
  637. int subsqos = 2;
  638. /* TODO - usused - remove ? MQTTClient_deliveryToken* dt = NULL; */
  639. MQTTClient c;
  640. MQTTClient_connectOptions opts = MQTTClient_connectOptions_initializer;
  641. MQTTClient_willOptions wopts = MQTTClient_willOptions_initializer;
  642. MQTTClient_SSLOptions sslopts = MQTTClient_SSLOptions_initializer;
  643. int rc = 0;
  644. failures = 0;
  645. MyLog(LOGA_INFO, "Starting test 2a_m - Mutual SSL authentication - multi-threaded client using callbacks");
  646. fprintf(xml, "<testcase classname=\"test3\" name=\"test 2a_m\"");
  647. global_start_time = start_clock();
  648. rc = MQTTClient_create(&c, options.mutual_auth_connection, "test2a_m", MQTTCLIENT_PERSISTENCE_DEFAULT, persistenceStore);
  649. if (!(assert("good rc from create", rc == MQTTCLIENT_SUCCESS, "rc was %d\n", rc)))
  650. goto exit;
  651. opts.keepAliveInterval = 20;
  652. opts.cleansession = 1;
  653. opts.username = "testuser";
  654. opts.password = "testpassword";
  655. if (options.haconnections != NULL)
  656. {
  657. opts.serverURIs = options.haconnections;
  658. opts.serverURIcount = options.hacount;
  659. }
  660. opts.ssl = &sslopts;
  661. if (options.server_key_file)
  662. opts.ssl->trustStore = options.server_key_file; /*file of certificates trusted by client*/
  663. opts.ssl->keyStore = options.client_key_file; /*file of certificate for client to present to server*/
  664. if (options.client_key_pass)
  665. opts.ssl->privateKeyPassword = options.client_key_pass;
  666. if (options.client_private_key_file)
  667. opts.ssl->privateKey = options.client_private_key_file;
  668. //opts.ssl->enabledCipherSuites = "DEFAULT";
  669. //opts.ssl->enabledServerCertAuth = 1;
  670. rc = MQTTClient_setCallbacks(c, NULL, NULL, multiThread_messageArrived, multiThread_deliveryComplete);
  671. if (!(assert("Good rc from setCallbacks", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
  672. goto exit;
  673. MyLog(LOGA_DEBUG, "Connecting");
  674. rc = MQTTClient_connect(c, &opts);
  675. if (!(assert("Good rc from connect", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
  676. goto exit;
  677. rc = MQTTClient_subscribe(c, test_topic, subsqos);
  678. if (!(assert("Good rc from subscribe", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
  679. goto exit;
  680. multiThread_sendAndReceive(c, 0, test_topic);
  681. multiThread_sendAndReceive(c, 1, test_topic);
  682. multiThread_sendAndReceive(c, 2, test_topic);
  683. MyLog(LOGA_DEBUG, "Stopping");
  684. rc = MQTTClient_unsubscribe(c, test_topic);
  685. if (!(assert("Unsubscribe successful", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
  686. goto exit;
  687. rc = MQTTClient_disconnect(c, 0);
  688. if (!(assert("Disconnect successful", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
  689. goto exit;
  690. exit:
  691. MQTTClient_destroy(&c);
  692. MyLog(LOGA_INFO, "%s: test %s. %d tests run, %d failures.",
  693. (failures == 0) ? "passed" : "failed", testname, tests, failures);
  694. write_test_result();
  695. return failures;
  696. }
  697. /*********************************************************************
  698. Test2b: Mutual SSL Authentication - Server does not have Client cert, connection fails
  699. *********************************************************************/
  700. int test2b(struct Options options)
  701. {
  702. char* testname = "test2b";
  703. char* test_topic = "C client test2b";
  704. int subsqos = 2;
  705. MQTTClient c;
  706. MQTTClient_connectOptions opts = MQTTClient_connectOptions_initializer;
  707. MQTTClient_willOptions wopts = MQTTClient_willOptions_initializer;
  708. MQTTClient_SSLOptions sslopts = MQTTClient_SSLOptions_initializer;
  709. int rc = 0;
  710. failures = 0;
  711. MyLog(LOGA_INFO, "Starting test 2b - connection to SSL MQTT server with clientauth=req but server does not have client cert");
  712. fprintf(xml, "<testcase classname=\"test3\" name=\"test 2b\"");
  713. global_start_time = start_clock();
  714. rc = MQTTClient_create(&c, options.nocert_mutual_auth_connection, "test2b", MQTTCLIENT_PERSISTENCE_DEFAULT, persistenceStore);
  715. if (!(assert("good rc from create", rc == MQTTCLIENT_SUCCESS, "rc was %d\n", rc)))
  716. goto exit;
  717. opts.keepAliveInterval = 20;
  718. opts.cleansession = 1;
  719. opts.username = "testuser";
  720. opts.password = "testpassword";
  721. if (options.haconnections != NULL)
  722. {
  723. opts.serverURIs = options.haconnections;
  724. opts.serverURIcount = options.hacount;
  725. }
  726. opts.ssl = &sslopts;
  727. if (options.server_key_file)
  728. opts.ssl->trustStore = options.server_key_file; /*file of certificates trusted by client*/
  729. opts.ssl->keyStore = options.client_key_file; /*file of certificate for client to present to server*/
  730. if (options.client_key_pass)
  731. opts.ssl->privateKeyPassword = options.client_key_pass;
  732. if (options.client_private_key_file)
  733. opts.ssl->privateKey = options.client_private_key_file;
  734. //opts.ssl->enabledCipherSuites = "DEFAULT";
  735. //opts.ssl->enabledServerCertAuth = 0;
  736. MyLog(LOGA_DEBUG, "Connecting");
  737. rc = MQTTClient_connect(c, &opts);
  738. if (!(assert("Bad rc from connect", rc == MQTTCLIENT_FAILURE, "rc was %d\n", rc)))
  739. goto exit;
  740. exit:
  741. MQTTClient_destroy(&c);
  742. MyLog(LOGA_INFO, "%s: test %s. %d tests run, %d failures.",
  743. (failures == 0) ? "passed" : "failed", testname, tests, failures);
  744. write_test_result();
  745. return failures;
  746. }
  747. /*********************************************************************
  748. Test2c: Mutual SSL Authentication - Client does not have Server cert
  749. *********************************************************************/
  750. int test2c(struct Options options)
  751. {
  752. char* testname = "test2c";
  753. char* test_topic = "C client test2c";
  754. int subsqos = 2;
  755. MQTTClient c;
  756. MQTTClient_connectOptions opts = MQTTClient_connectOptions_initializer;
  757. MQTTClient_willOptions wopts = MQTTClient_willOptions_initializer;
  758. MQTTClient_SSLOptions sslopts = MQTTClient_SSLOptions_initializer;
  759. int rc = 0;
  760. failures = 0;
  761. MyLog(LOGA_INFO, "Starting test 2c - connection to SSL MQTT server, server auth enabled but unknown cert");
  762. fprintf(xml, "<testcase classname=\"test3\" name=\"test 2c\"");
  763. global_start_time = start_clock();
  764. rc = MQTTClient_create(&c, options.mutual_auth_connection, "test2c", MQTTCLIENT_PERSISTENCE_DEFAULT, persistenceStore);
  765. if (!(assert("good rc from create", rc == MQTTCLIENT_SUCCESS, "rc was %d\n", rc)))
  766. goto exit;
  767. opts.keepAliveInterval = 20;
  768. opts.cleansession = 1;
  769. opts.username = "testuser";
  770. opts.password = "testpassword";
  771. if (options.haconnections != NULL)
  772. {
  773. opts.serverURIs = options.haconnections;
  774. opts.serverURIcount = options.hacount;
  775. }
  776. opts.ssl = &sslopts;
  777. //if (options.server_key_file)
  778. // opts.ssl->trustStore = options.server_key_file; /*file of certificates trusted by client*/
  779. opts.ssl->keyStore = options.client_key_file; /*file of certificate for client to present to server*/
  780. if (options.client_key_pass)
  781. opts.ssl->privateKeyPassword = options.client_key_pass;
  782. if (options.client_private_key_file)
  783. opts.ssl->privateKey = options.client_private_key_file;
  784. //opts.ssl->enabledCipherSuites = "DEFAULT";
  785. //opts.ssl->enabledServerCertAuth = 0;
  786. MyLog(LOGA_DEBUG, "Connecting");
  787. rc = MQTTClient_connect(c, &opts);
  788. if (!(assert("Good rc from connect", rc == MQTTCLIENT_FAILURE, "rc was %d", rc)))
  789. goto exit;
  790. exit:
  791. MQTTClient_destroy(&c);
  792. MyLog(LOGA_INFO, "%s: test %s. %d tests run, %d failures.",
  793. (failures == 0) ? "passed" : "failed", testname, tests, failures);
  794. write_test_result();
  795. return failures;
  796. }
  797. /*********************************************************************
  798. Test2e: Mutual SSL Authentication - high availability
  799. *********************************************************************/
  800. int test2e_s(struct Options options)
  801. {
  802. char* testname = "test2e_s";
  803. char* test_topic = "C client test2e_s";
  804. int subsqos = 2;
  805. MQTTClient c;
  806. MQTTClient_connectOptions opts = MQTTClient_connectOptions_initializer;
  807. MQTTClient_willOptions wopts = MQTTClient_willOptions_initializer;
  808. MQTTClient_SSLOptions sslopts = MQTTClient_SSLOptions_initializer;
  809. char* uris[2] = {"wrong", options.mutual_auth_connection};
  810. int rc = 0;
  811. failures = 0;
  812. MyLog(LOGA_INFO, "Starting test 2e_s - Mutual SSL authentication - HA");
  813. fprintf(xml, "<testcase classname=\"test3\" name=\"test 2e_s\"");
  814. global_start_time = start_clock();
  815. rc = MQTTClient_create(&c, "not used", "test2e_s", MQTTCLIENT_PERSISTENCE_DEFAULT, persistenceStore);
  816. if (!(assert("good rc from create", rc == MQTTCLIENT_SUCCESS, "rc was %d\n", rc)))
  817. goto exit;
  818. opts.keepAliveInterval = 20;
  819. opts.cleansession = 1;
  820. opts.username = "testuser";
  821. opts.password = "testpassword";
  822. opts.serverURIs = uris;
  823. opts.serverURIcount = 2;
  824. opts.ssl = &sslopts;
  825. if (options.server_key_file)
  826. opts.ssl->trustStore = options.server_key_file; /*file of certificates trusted by client*/
  827. opts.ssl->keyStore = options.client_key_file; /*file of certificate for client to present to server*/
  828. if (options.client_key_pass)
  829. opts.ssl->privateKeyPassword = options.client_key_pass;
  830. if (options.client_private_key_file)
  831. opts.ssl->privateKey = options.client_private_key_file;
  832. opts.ssl->verify = 1;
  833. MyLog(LOGA_DEBUG, "Connecting");
  834. rc = MQTTClient_connect(c, &opts);
  835. if (!(assert("Good rc from connect", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
  836. goto exit;
  837. rc = MQTTClient_subscribe(c, test_topic, subsqos);
  838. if (!(assert("Good rc from subscribe", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
  839. goto exit;
  840. singleThread_sendAndReceive(c, 0, test_topic);
  841. singleThread_sendAndReceive(c, 1, test_topic);
  842. singleThread_sendAndReceive(c, 2, test_topic);
  843. MyLog(LOGA_DEBUG, "Stopping\n");
  844. rc = MQTTClient_unsubscribe(c, test_topic);
  845. if (!(assert("Unsubscribe successful", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
  846. goto exit;
  847. rc = MQTTClient_disconnect(c, 0);
  848. if (!(assert("Disconnect successful", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
  849. goto exit;
  850. /* Just to make sure we can connect again */
  851. rc = MQTTClient_connect(c, &opts);
  852. if (!(assert("Connect successful", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
  853. goto exit;
  854. rc = MQTTClient_disconnect(c, 0);
  855. if (!(assert("Disconnect successful", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
  856. goto exit;
  857. exit:
  858. MQTTClient_destroy(&c);
  859. MyLog(LOGA_INFO, "%s: test %s. %d tests run, %d failures.",
  860. (failures == 0) ? "passed" : "failed", testname, tests, failures);
  861. write_test_result();
  862. return failures;
  863. }
  864. /*********************************************************************
  865. Test3a: Server Authentication - server certificate in client trust store - single threaded
  866. *********************************************************************/
  867. int test3a_s(struct Options options)
  868. {
  869. char* testname = "test3a_s";
  870. char* test_topic = "C client test3a_s";
  871. int subsqos = 2;
  872. MQTTClient c;
  873. MQTTClient_connectOptions opts = MQTTClient_connectOptions_initializer;
  874. MQTTClient_willOptions wopts = MQTTClient_willOptions_initializer;
  875. MQTTClient_SSLOptions sslopts = MQTTClient_SSLOptions_initializer;
  876. int rc = 0;
  877. failures = 0;
  878. MyLog(LOGA_INFO, "Starting test 3a_s - Server authentication - single threaded client using receive");
  879. fprintf(xml, "<testcase classname=\"test3\" name=\"test 3a_s\"");
  880. global_start_time = start_clock();
  881. rc = MQTTClient_create(&c, options.server_auth_connection, "test3a_s", MQTTCLIENT_PERSISTENCE_DEFAULT, persistenceStore);
  882. if (!(assert("good rc from create", rc == MQTTCLIENT_SUCCESS, "rc was %d\n", rc)))
  883. goto exit;
  884. opts.keepAliveInterval = 20;
  885. opts.cleansession = 1;
  886. opts.username = "testuser";
  887. opts.password = "testpassword";
  888. if (options.haconnections != NULL)
  889. {
  890. opts.serverURIs = options.haconnections;
  891. opts.serverURIcount = options.hacount;
  892. }
  893. opts.ssl = &sslopts;
  894. if (options.server_key_file != NULL)
  895. opts.ssl->trustStore = options.server_key_file; /*file of certificates trusted by client*/
  896. MyLog(LOGA_DEBUG, "Connecting");
  897. rc = MQTTClient_connect(c, &opts);
  898. if (!(assert("Good rc from connect", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
  899. goto exit;
  900. rc = MQTTClient_subscribe(c, test_topic, subsqos);
  901. if (!(assert("Good rc from subscribe", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
  902. singleThread_sendAndReceive(c, 0, test_topic);
  903. singleThread_sendAndReceive(c, 1, test_topic);
  904. singleThread_sendAndReceive(c, 2, test_topic);
  905. MyLog(LOGA_DEBUG, "Stopping\n");
  906. rc = MQTTClient_unsubscribe(c, test_topic);
  907. if (!(assert("Unsubscribe successful", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
  908. goto exit;
  909. rc = MQTTClient_disconnect(c, 0);
  910. if (!(assert("Disconnect successful", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
  911. goto exit;
  912. /* Just to make sure we can connect again */
  913. rc = MQTTClient_connect(c, &opts);
  914. if (!(assert("Connect successful", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
  915. goto exit;
  916. rc = MQTTClient_disconnect(c, 0);
  917. if (!(assert("Disconnect successful", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
  918. goto exit;
  919. exit:
  920. MQTTClient_destroy(&c);
  921. MyLog(LOGA_INFO, "%s: test %s. %d tests run, %d failures.",
  922. (failures == 0) ? "passed" : "failed", testname, tests, failures);
  923. write_test_result();
  924. return failures;
  925. }
  926. /*********************************************************************
  927. Test3a: Server Authentication - server certificate in client trust store - multi threaded
  928. *********************************************************************/
  929. int test3a_m(struct Options options)
  930. {
  931. char* testname = "test3a_m";
  932. char* test_topic = "C client test3a_m";
  933. int subsqos = 2;
  934. MQTTClient c;
  935. MQTTClient_connectOptions opts = MQTTClient_connectOptions_initializer;
  936. MQTTClient_willOptions wopts = MQTTClient_willOptions_initializer;
  937. MQTTClient_SSLOptions sslopts = MQTTClient_SSLOptions_initializer;
  938. int rc = 0;
  939. failures = 0;
  940. MyLog(LOGA_INFO, "Starting test 3a_m - Server authentication - multi-threaded client using callbacks");
  941. fprintf(xml, "<testcase classname=\"test3\" name=\"test 3a_m\"");
  942. global_start_time = start_clock();
  943. rc = MQTTClient_create(&c, options.server_auth_connection, "test3a_m", MQTTCLIENT_PERSISTENCE_DEFAULT, persistenceStore);
  944. if (!(assert("good rc from create", rc == MQTTCLIENT_SUCCESS, "rc was %d\n", rc)))
  945. goto exit;
  946. opts.keepAliveInterval = 20;
  947. opts.cleansession = 1;
  948. opts.username = "testuser";
  949. opts.password = "testpassword";
  950. if (options.haconnections != NULL)
  951. {
  952. opts.serverURIs = options.haconnections;
  953. opts.serverURIcount = options.hacount;
  954. }
  955. opts.ssl = &sslopts;
  956. if (options.server_key_file != NULL)
  957. opts.ssl->trustStore = options.server_key_file; /*file of certificates trusted by client*/
  958. rc = MQTTClient_setCallbacks(c, NULL, NULL, multiThread_messageArrived, multiThread_deliveryComplete);
  959. if (!(assert("Good rc from setCallbacks", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
  960. goto exit;
  961. MyLog(LOGA_DEBUG, "Connecting");
  962. rc = MQTTClient_connect(c, &opts);
  963. if (!(assert("Good rc from connect", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
  964. goto exit;
  965. rc = MQTTClient_subscribe(c, test_topic, subsqos);
  966. if (!(assert("Good rc from subscribe", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
  967. goto exit;
  968. multiThread_sendAndReceive(c, 0, test_topic);
  969. multiThread_sendAndReceive(c, 1, test_topic);
  970. multiThread_sendAndReceive(c, 2, test_topic);
  971. MyLog(LOGA_DEBUG, "Stopping\n");
  972. rc = MQTTClient_unsubscribe(c, test_topic);
  973. if (!(assert("Unsubscribe successful", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
  974. goto exit;
  975. rc = MQTTClient_disconnect(c, 0);
  976. if (!(assert("Disconnect successful", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
  977. goto exit;
  978. exit:
  979. MQTTClient_destroy(&c);
  980. MyLog(LOGA_INFO, "%s: test %s. %d tests run, %d failures.",
  981. (failures == 0) ? "passed" : "failed", testname, tests, failures);
  982. write_test_result();
  983. return failures;
  984. }
  985. /*********************************************************************
  986. Test3b: Server Authentication - Client does not have server cert
  987. *********************************************************************/
  988. int test3b(struct Options options)
  989. {
  990. char* testname = "test3b";
  991. char* test_topic = "C client test3b";
  992. int subsqos = 2;
  993. MQTTClient c;
  994. MQTTClient_connectOptions opts = MQTTClient_connectOptions_initializer;
  995. MQTTClient_willOptions wopts = MQTTClient_willOptions_initializer;
  996. MQTTClient_SSLOptions sslopts = MQTTClient_SSLOptions_initializer;
  997. int rc = 0;
  998. failures = 0;
  999. MyLog(LOGA_INFO, "Starting test 3b - connection to SSL MQTT server with clientauth=opt but client does not have server cert");
  1000. fprintf(xml, "<testcase classname=\"test3\" name=\"test 3b\"");
  1001. global_start_time = start_clock();
  1002. rc = MQTTClient_create(&c, options.server_auth_connection, "test3b", MQTTCLIENT_PERSISTENCE_DEFAULT, persistenceStore);
  1003. if (!(assert("good rc from create", rc == MQTTCLIENT_SUCCESS, "rc was %d\n", rc)))
  1004. goto exit;
  1005. opts.keepAliveInterval = 20;
  1006. opts.cleansession = 1;
  1007. opts.username = "testuser";
  1008. opts.password = "testpassword";
  1009. if (options.haconnections != NULL)
  1010. {
  1011. opts.serverURIs = options.haconnections;
  1012. opts.serverURIcount = options.hacount;
  1013. }
  1014. opts.ssl = &sslopts;
  1015. MyLog(LOGA_DEBUG, "Connecting");
  1016. rc = MQTTClient_connect(c, &opts);
  1017. if (!(assert("Bad rc from connect", rc == MQTTCLIENT_FAILURE, "rc was %d", rc)))
  1018. goto exit;
  1019. exit:
  1020. MQTTClient_destroy(&c);
  1021. MyLog(LOGA_INFO, "%s: test %s. %d tests run, %d failures.",
  1022. (failures == 0) ? "passed" : "failed", testname, tests, failures);
  1023. write_test_result();
  1024. return failures;
  1025. }
  1026. /*********************************************************************
  1027. Test4_s: Accept invalid server certificates - single threaded
  1028. *********************************************************************/
  1029. int test4_s(struct Options options)
  1030. {
  1031. char* testname = "test4_s";
  1032. char* test_topic = "C client test4_s";
  1033. int subsqos = 2;
  1034. MQTTClient c;
  1035. MQTTClient_connectOptions opts = MQTTClient_connectOptions_initializer;
  1036. MQTTClient_willOptions wopts = MQTTClient_willOptions_initializer;
  1037. MQTTClient_SSLOptions sslopts = MQTTClient_SSLOptions_initializer;
  1038. int rc = 0;
  1039. failures = 0;
  1040. MyLog(LOGA_INFO, "Starting test 4_s - accept invalid server certificates - single threaded");
  1041. fprintf(xml, "<testcase classname=\"test3\" name=\"test 4_s\"");
  1042. global_start_time = start_clock();
  1043. rc = MQTTClient_create(&c, options.server_auth_connection, "test4_s", MQTTCLIENT_PERSISTENCE_DEFAULT, persistenceStore);
  1044. if (!(assert("good rc from create", rc == MQTTCLIENT_SUCCESS, "rc was %d\n", rc)))
  1045. goto exit;
  1046. opts.keepAliveInterval = 20;
  1047. opts.cleansession = 1;
  1048. opts.username = "testuser";
  1049. opts.password = "testpassword";
  1050. if (options.haconnections != NULL)
  1051. {
  1052. opts.serverURIs = options.haconnections;
  1053. opts.serverURIcount = options.hacount;
  1054. }
  1055. opts.ssl = &sslopts;
  1056. opts.ssl->enableServerCertAuth = 0;
  1057. MyLog(LOGA_DEBUG, "Connecting");
  1058. rc = MQTTClient_connect(c, &opts);
  1059. if (!(assert("Good rc from connect", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
  1060. goto exit;
  1061. rc = MQTTClient_subscribe(c, test_topic, subsqos);
  1062. if (!(assert("Good rc from subscribe", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
  1063. goto exit;
  1064. singleThread_sendAndReceive(c, 0, test_topic);
  1065. singleThread_sendAndReceive(c, 1, test_topic);
  1066. singleThread_sendAndReceive(c, 2, test_topic);
  1067. MyLog(LOGA_DEBUG, "Stopping\n");
  1068. rc = MQTTClient_unsubscribe(c, test_topic);
  1069. if (!(assert("Unsubscribe successful", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
  1070. goto exit;
  1071. rc = MQTTClient_disconnect(c, 0);
  1072. if (!(assert("Disconnect successful", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
  1073. goto exit;
  1074. /* Just to make sure we can connect again */
  1075. rc = MQTTClient_connect(c, &opts);
  1076. if (!(assert("Connect successful", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
  1077. goto exit;
  1078. rc = MQTTClient_disconnect(c, 0);
  1079. if (!(assert("Disconnect successful", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
  1080. goto exit;
  1081. exit:
  1082. MQTTClient_destroy(&c);
  1083. MyLog(LOGA_INFO, "%s: test %s. %d tests run, %d failures.",
  1084. (failures == 0) ? "passed" : "failed", testname, tests, failures);
  1085. write_test_result();
  1086. return failures;
  1087. }
  1088. /*********************************************************************
  1089. Test4_m: Accept invalid server certificates - multi threaded
  1090. *********************************************************************/
  1091. int test4_m(struct Options options)
  1092. {
  1093. char* testname = "test4_m";
  1094. char* test_topic = "C client test4_m";
  1095. int subsqos = 2;
  1096. MQTTClient c;
  1097. MQTTClient_connectOptions opts = MQTTClient_connectOptions_initializer;
  1098. MQTTClient_willOptions wopts = MQTTClient_willOptions_initializer;
  1099. MQTTClient_SSLOptions sslopts = MQTTClient_SSLOptions_initializer;
  1100. int rc = 0;
  1101. failures = 0;
  1102. MyLog(LOGA_INFO, "Starting test 4_m - accept invalid server certificates - multi-threaded");
  1103. fprintf(xml, "<testcase classname=\"test3\" name=\"test 4_m\"");
  1104. global_start_time = start_clock();
  1105. rc = MQTTClient_create(&c, options.server_auth_connection, "test4_m", MQTTCLIENT_PERSISTENCE_DEFAULT, persistenceStore);
  1106. if (!(assert("good rc from create", rc == MQTTCLIENT_SUCCESS, "rc was %d\n", rc)))
  1107. goto exit;
  1108. opts.keepAliveInterval = 20;
  1109. opts.cleansession = 1;
  1110. opts.username = "testuser";
  1111. opts.password = "testpassword";
  1112. if (options.haconnections != NULL)
  1113. {
  1114. opts.serverURIs = options.haconnections;
  1115. opts.serverURIcount = options.hacount;
  1116. }
  1117. opts.ssl = &sslopts;
  1118. opts.ssl->enableServerCertAuth = 0;
  1119. rc = MQTTClient_setCallbacks(c, NULL, NULL, multiThread_messageArrived, multiThread_deliveryComplete);
  1120. if (!(assert("Good rc from setCallbacks", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
  1121. goto exit;
  1122. MyLog(LOGA_DEBUG, "Connecting");
  1123. rc = MQTTClient_connect(c, &opts);
  1124. if (!(assert("Good rc from connect", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
  1125. goto exit;
  1126. rc = MQTTClient_subscribe(c, test_topic, subsqos);
  1127. if (!(assert("Good rc from subscribe", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
  1128. goto exit;
  1129. multiThread_sendAndReceive(c, 0, test_topic);
  1130. multiThread_sendAndReceive(c, 1, test_topic);
  1131. multiThread_sendAndReceive(c, 2, test_topic);
  1132. MyLog(LOGA_DEBUG, "Stopping");
  1133. rc = MQTTClient_unsubscribe(c, test_topic);
  1134. if (!(assert("Unsubscribe successful", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
  1135. goto exit;
  1136. rc = MQTTClient_disconnect(c, 0);
  1137. if (!(assert("Disconnect successful", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
  1138. goto exit;
  1139. exit:
  1140. MQTTClient_destroy(&c);
  1141. MyLog(LOGA_INFO, "%s: test %s. %d tests run, %d failures.",
  1142. (failures == 0) ? "passed" : "failed", testname, tests, failures);
  1143. write_test_result();
  1144. return failures;
  1145. }
  1146. /*********************************************************************
  1147. Test5a: Anonymous ciphers - server auth disabled
  1148. *********************************************************************/
  1149. int test5a(struct Options options)
  1150. {
  1151. char* testname = "test5a";
  1152. char* test_topic = "C client SSL test5a";
  1153. int subsqos = 2;
  1154. MQTTClient c;
  1155. MQTTClient_connectOptions opts = MQTTClient_connectOptions_initializer;
  1156. MQTTClient_willOptions wopts = MQTTClient_willOptions_initializer;
  1157. MQTTClient_SSLOptions sslopts = MQTTClient_SSLOptions_initializer;
  1158. int rc = 0;
  1159. failures = 0;
  1160. MyLog(LOGA_INFO, "Starting SSL test 5a - Anonymous ciphers - server authentication disabled");
  1161. fprintf(xml, "<testcase classname=\"test3\" name=\"test 5a\"");
  1162. global_start_time = start_clock();
  1163. rc = MQTTClient_create(&c, options.anon_connection, "test5a", MQTTCLIENT_PERSISTENCE_DEFAULT, persistenceStore);
  1164. if (!(assert("good rc from create", rc == MQTTCLIENT_SUCCESS, "rc was %d\n", rc)))
  1165. goto exit;
  1166. opts.keepAliveInterval = 20;
  1167. opts.cleansession = 1;
  1168. opts.username = "testuser";
  1169. opts.password = "testpassword";
  1170. if (options.haconnections != NULL)
  1171. {
  1172. opts.serverURIs = options.haconnections;
  1173. opts.serverURIcount = options.hacount;
  1174. }
  1175. opts.ssl = &sslopts;
  1176. opts.ssl->enabledCipherSuites = "aNULL";
  1177. opts.ssl->enableServerCertAuth = 0;
  1178. MyLog(LOGA_DEBUG, "Connecting");
  1179. rc = MQTTClient_connect(c, &opts);
  1180. if (!(assert("Good rc from connect", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
  1181. goto exit;
  1182. rc = MQTTClient_subscribe(c, test_topic, subsqos);
  1183. if (!(assert("Good rc from subscribe", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
  1184. goto exit;
  1185. singleThread_sendAndReceive(c, 0, test_topic);
  1186. singleThread_sendAndReceive(c, 1, test_topic);
  1187. singleThread_sendAndReceive(c, 2, test_topic);
  1188. MyLog(LOGA_DEBUG, "Stopping\n");
  1189. rc = MQTTClient_unsubscribe(c, test_topic);
  1190. if (!(assert("Unsubscribe successful", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
  1191. goto exit;
  1192. rc = MQTTClient_disconnect(c, 0);
  1193. if (!(assert("Disconnect successful", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
  1194. goto exit;
  1195. /* Just to make sure we can connect again */
  1196. rc = MQTTClient_connect(c, &opts);
  1197. if (!(assert("Connect successful", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
  1198. goto exit;
  1199. rc = MQTTClient_disconnect(c, 0);
  1200. if (!(assert("Disconnect successful", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
  1201. goto exit;
  1202. exit:
  1203. MQTTClient_destroy(&c);
  1204. MyLog(LOGA_INFO, "%s: test %s. %d tests run, %d failures.",
  1205. (failures == 0) ? "passed" : "failed", testname, tests, failures);
  1206. write_test_result();
  1207. return failures;
  1208. }
  1209. /*********************************************************************
  1210. Test5b: Anonymous ciphers - server auth enabled
  1211. *********************************************************************/
  1212. int test5b(struct Options options)
  1213. {
  1214. char* testname = "test5b";
  1215. char* test_topic = "C client SSL test5b";
  1216. int subsqos = 2;
  1217. MQTTClient c;
  1218. MQTTClient_connectOptions opts = MQTTClient_connectOptions_initializer;
  1219. MQTTClient_willOptions wopts = MQTTClient_willOptions_initializer;
  1220. MQTTClient_SSLOptions sslopts = MQTTClient_SSLOptions_initializer;
  1221. int rc = 0;
  1222. failures = 0;
  1223. MyLog(LOGA_INFO, "Starting SSL test 5b - Anonymous ciphers - server authentication enabled");
  1224. fprintf(xml, "<testcase classname=\"test3\" name=\"test 5b\"");
  1225. global_start_time = start_clock();
  1226. rc = MQTTClient_create(&c, options.anon_connection, "test5b", MQTTCLIENT_PERSISTENCE_DEFAULT, persistenceStore);
  1227. if (!(assert("good rc from create", rc == MQTTCLIENT_SUCCESS, "rc was %d\n", rc)))
  1228. goto exit;
  1229. opts.keepAliveInterval = 20;
  1230. opts.cleansession = 1;
  1231. opts.username = "testuser";
  1232. opts.password = "testpassword";
  1233. if (options.haconnections != NULL)
  1234. {
  1235. opts.serverURIs = options.haconnections;
  1236. opts.serverURIcount = options.hacount;
  1237. }
  1238. opts.ssl = &sslopts;
  1239. //opts.ssl->trustStore = /*file of certificates trusted by client*/
  1240. //opts.ssl->keyStore = options.client_key_file; /*file of certificate for client to present to server*/
  1241. //if (options.client_key_pass != NULL) opts.ssl->privateKeyPassword = options.client_key_pass;
  1242. opts.ssl->enabledCipherSuites = "aNULL";
  1243. opts.ssl->enableServerCertAuth = 1;
  1244. MyLog(LOGA_DEBUG, "Connecting");
  1245. rc = MQTTClient_connect(c, &opts);
  1246. if (!(assert("Good rc from connect", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
  1247. goto exit;
  1248. rc = MQTTClient_subscribe(c, test_topic, subsqos);
  1249. if (!(assert("Good rc from subscribe", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
  1250. goto exit;
  1251. singleThread_sendAndReceive(c, 0, test_topic);
  1252. singleThread_sendAndReceive(c, 1, test_topic);
  1253. singleThread_sendAndReceive(c, 2, test_topic);
  1254. MyLog(LOGA_DEBUG, "Stopping\n");
  1255. rc = MQTTClient_unsubscribe(c, test_topic);
  1256. if (!(assert("Unsubscribe successful", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
  1257. goto exit;
  1258. rc = MQTTClient_disconnect(c, 0);
  1259. if (!(assert("Disconnect successful", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
  1260. goto exit;
  1261. /* Just to make sure we can connect again */
  1262. rc = MQTTClient_connect(c, &opts);
  1263. if (!(assert("Connect successful", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
  1264. goto exit;
  1265. rc = MQTTClient_disconnect(c, 0);
  1266. if (!(assert("Disconnect successful", rc == MQTTCLIENT_SUCCESS, "rc was %d", rc)))
  1267. goto exit;
  1268. exit:
  1269. MQTTClient_destroy(&c);
  1270. MyLog(LOGA_INFO, "%s: test %s. %d tests run, %d failures.",
  1271. (failures == 0) ? "passed" : "failed", testname, tests, failures);
  1272. write_test_result();
  1273. return failures;
  1274. }
  1275. /*********************************************************************
  1276. Test5c: Anonymous ciphers - client not using anonymous ciphers
  1277. *********************************************************************/
  1278. int test5c(struct Options options)
  1279. {
  1280. char* testname = "test5c";
  1281. char* test_topic = "C client SSL test5c";
  1282. int subsqos = 2;
  1283. MQTTClient c;
  1284. MQTTClient_connectOptions opts = MQTTClient_connectOptions_initializer;
  1285. MQTTClient_willOptions wopts = MQTTClient_willOptions_initializer;
  1286. MQTTClient_SSLOptions sslopts = MQTTClient_SSLOptions_initializer;
  1287. int rc = 0;
  1288. failures = 0;
  1289. MyLog(LOGA_INFO, "Starting SSL test 5c - Anonymous ciphers - client not using anonymous cipher");
  1290. fprintf(xml, "<testcase classname=\"test3\" name=\"test 5c\"");
  1291. global_start_time = start_clock();
  1292. rc = MQTTClient_create(&c, options.anon_connection, "test5c", MQTTCLIENT_PERSISTENCE_DEFAULT, persistenceStore);
  1293. if (!(assert("good rc from create", rc == MQTTCLIENT_SUCCESS, "rc was %d\n", rc)))
  1294. goto exit;
  1295. opts.keepAliveInterval = 20;
  1296. opts.cleansession = 1;
  1297. opts.username = "testuser";
  1298. opts.password = "testpassword";
  1299. if (options.haconnections != NULL)
  1300. {
  1301. opts.serverURIs = options.haconnections;
  1302. opts.serverURIcount = options.hacount;
  1303. }
  1304. opts.ssl = &sslopts;
  1305. //opts.ssl->trustStore = /*file of certificates trusted by client*/
  1306. //opts.ssl->keyStore = options.client_key_file; /*file of certificate for client to present to server*/
  1307. //if (options.client_key_pass != NULL) opts.ssl->privateKeyPassword = options.client_key_pass;
  1308. opts.ssl->enabledCipherSuites = "DEFAULT";
  1309. opts.ssl->enableServerCertAuth = 0;
  1310. MyLog(LOGA_DEBUG, "Connecting");
  1311. rc = MQTTClient_connect(c, &opts);
  1312. if (!(assert("Good rc from connect", rc == MQTTCLIENT_FAILURE, "rc was %d", rc)))
  1313. goto exit;
  1314. exit:
  1315. MQTTClient_destroy(&c);
  1316. MyLog(LOGA_INFO, "%s: test %s. %d tests run, %d failures.",
  1317. (failures == 0) ? "passed" : "failed", testname, tests, failures);
  1318. write_test_result();
  1319. return failures;
  1320. }
  1321. /*********************************************************************
  1322. Test6: TLS-PSK - client and server has a common pre-shared key
  1323. *********************************************************************/
  1324. static unsigned int onPSKAuth(const char* hint,
  1325. char* identity,
  1326. unsigned int max_identity_len,
  1327. unsigned char* psk,
  1328. unsigned int max_psk_len,
  1329. void* context)
  1330. {
  1331. unsigned char test_psk[] = {0x50, 0x53, 0x4B, 0x00}; /* {'P', 'S', 'K', '\0' } */
  1332. MyLog(LOGA_DEBUG, "PSK auth callback");
  1333. if (!(assert("Good application context in onPSKAuth", context == (void *) 42, "context was %d\n", context)))
  1334. return 0;
  1335. strncpy(identity, "id", max_identity_len);
  1336. memcpy(psk, test_psk, sizeof(test_psk));
  1337. return sizeof(test_psk);
  1338. }
  1339. int test6(struct Options options)
  1340. {
  1341. char* testname = "test6";
  1342. MQTTClient c;
  1343. MQTTClient_connectOptions opts = MQTTClient_connectOptions_initializer;
  1344. MQTTClient_willOptions wopts = MQTTClient_willOptions_initializer;
  1345. MQTTClient_SSLOptions sslopts = MQTTClient_SSLOptions_initializer;
  1346. int rc = 0;
  1347. failures = 0;
  1348. MyLog(LOGA_INFO, "Starting test 6 - TLS-PSK - client and server has a common pre-shared key");
  1349. fprintf(xml, "<testcase classname=\"test6\" name=\"test 6\"");
  1350. global_start_time = start_clock();
  1351. rc = MQTTClient_create(&c, options.psk_connection, "test6", MQTTCLIENT_PERSISTENCE_DEFAULT, persistenceStore);
  1352. if (!(assert("good rc from create", rc == MQTTCLIENT_SUCCESS, "rc was %d\n", rc)))
  1353. goto exit;
  1354. opts.keepAliveInterval = 20;
  1355. opts.cleansession = 1;
  1356. opts.username = "testuser";
  1357. opts.password = "testpassword";
  1358. if (options.haconnections != NULL)
  1359. {
  1360. opts.serverURIs = options.haconnections;
  1361. opts.serverURIcount = options.hacount;
  1362. }
  1363. opts.ssl = &sslopts;
  1364. opts.ssl->ssl_psk_cb = onPSKAuth;
  1365. opts.ssl->ssl_psk_context = (void *) 42;
  1366. opts.ssl->enabledCipherSuites = "PSK-AES128-CBC-SHA";
  1367. MyLog(LOGA_DEBUG, "Connecting");
  1368. rc = MQTTClient_connect(c, &opts);
  1369. if (!(assert("Good rc from connect", rc == MQTTCLIENT_SUCCESS, "rc was %d\n", rc)))
  1370. goto exit;
  1371. MyLog(LOGA_DEBUG, "Stopping\n");
  1372. rc = MQTTClient_disconnect(c, 0);
  1373. if (!(assert("Disconnect successful", rc == MQTTCLIENT_SUCCESS, "rc was %d\n", rc)))
  1374. goto exit;
  1375. exit:
  1376. MQTTClient_destroy(&c);
  1377. MyLog(LOGA_INFO, "%s: test %s. %d tests run, %d failures.",
  1378. (failures == 0) ? "passed" : "failed", testname, tests, failures);
  1379. write_test_result();
  1380. return failures;
  1381. }
  1382. typedef struct
  1383. {
  1384. char* clientID; /**< the string id of the client */
  1385. char* username; /**< MQTT v3.1 user name */
  1386. char* password; /**< MQTT v3.1 password */
  1387. unsigned int cleansession : 1; /**< MQTT clean session flag */
  1388. unsigned int connected : 1; /**< whether it is currently connected */
  1389. unsigned int good : 1; /**< if we have an error on the socket we turn this off */
  1390. unsigned int ping_outstanding : 1;
  1391. unsigned int connect_state : 2;
  1392. int socket;
  1393. int msgID;
  1394. int keepAliveInterval;
  1395. int retryInterval;
  1396. int maxInflightMessages;
  1397. time_t lastContact;
  1398. void* will;
  1399. void* inboundMsgs;
  1400. void* outboundMsgs; /**< in flight */
  1401. void* messageQueue;
  1402. void* phandle; /* the persistence handle */
  1403. MQTTClient_persistence* persistence; /* a persistence implementation */
  1404. int connectOptionsVersion;
  1405. } Clients;
  1406. typedef struct
  1407. {
  1408. char* serverURI;
  1409. Clients* c;
  1410. MQTTClient_connectionLost* cl;
  1411. MQTTClient_messageArrived* ma;
  1412. MQTTClient_deliveryComplete* dc;
  1413. void* context;
  1414. int connect_sem;
  1415. int rc; /* getsockopt return code in connect */
  1416. int connack_sem;
  1417. int suback_sem;
  1418. int unsuback_sem;
  1419. void* pack;
  1420. } MQTTClients;
  1421. int main(int argc, char** argv)
  1422. {
  1423. int* numtests = &tests;
  1424. int rc = 0;
  1425. int (*tests[])() = {NULL, test1, test2a_s, test2a_m, test2b, test2c, test3a_s, test3a_m, test3b, test4_s, test4_m, test6,
  1426. test2e_s /*test5a, test5b,test5c */};
  1427. //MQTTClient_nameValue* info;
  1428. xml = fopen("TEST-test3.xml", "w");
  1429. fprintf(xml, "<testsuite name=\"test3\" tests=\"%d\">\n", (int)(ARRAY_SIZE(tests) - 1));
  1430. setenv("MQTT_C_CLIENT_TRACE", "ON", 1);
  1431. setenv("MQTT_C_CLIENT_TRACE_LEVEL", "ERROR", 1);
  1432. getopts(argc, argv);
  1433. if (options.test_no == 0)
  1434. { /* run all the tests */
  1435. for (options.test_no = 1; options.test_no < ARRAY_SIZE(tests); ++options.test_no)
  1436. rc += tests[options.test_no](options); /* return number of failures. 0 = test succeeded */
  1437. }
  1438. else
  1439. rc = tests[options.test_no](options); /* run just the selected test */
  1440. MyLog(LOGA_INFO, "Total tests run: %d", *numtests);
  1441. if (rc == 0)
  1442. MyLog(LOGA_INFO, "verdict pass");
  1443. else
  1444. MyLog(LOGA_INFO, "verdict fail");
  1445. fprintf(xml, "</testsuite>\n");
  1446. fclose(xml);
  1447. return rc;
  1448. }