]> git.meshlink.io Git - meshlink/blob - test/blackbox/run_blackbox_tests/test_cases_channel_ex.c
Add UTCP UDP channel corner cases and test cases on channel get MSS length API
[meshlink] / test / blackbox / run_blackbox_tests / test_cases_channel_ex.c
1 /*
2     test_cases_channel_ex.c -- Execution of specific meshlink black box test cases
3     Copyright (C) 2018  Guus Sliepen <guus@meshlink.io>
4
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2 of the License, or
8     (at your option) any later version.
9
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14
15     You should have received a copy of the GNU General Public License along
16     with this program; if not, write to the Free Software Foundation, Inc.,
17     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #ifdef NDEBUG
21 #undef NDEBUG
22 #endif
23
24 #include "execute_tests.h"
25 #include "test_cases_channel_ex.h"
26 #include "../common/containers.h"
27 #include "../common/test_step.h"
28 #include "../common/common_handlers.h"
29 #include "../../utils.h"
30 #include <assert.h>
31 #include <strings.h>
32 #include <string.h>
33 #include <stdlib.h>
34 #include <stdarg.h>
35 #include <setjmp.h>
36 #include <pthread.h>
37 #include <cmocka.h>
38 #include <limits.h>
39 #include <linux/limits.h>
40
41 /* Modify this to change the logging level of Meshlink */
42 #define TEST_MESHLINK_LOG_LEVEL MESHLINK_DEBUG
43 /* Modify this to change the port number */
44 #define PORT 8000
45
46 #define NUT                         "nut"
47 #define PEER                        "peer"
48 #define TEST_CHANNEL_OPEN           "test_channel_open"
49 #define create_path(confbase, node_name, test_case_no)   assert(snprintf(confbase, sizeof(confbase), TEST_CHANNEL_OPEN "_%ld_%s_%02d", (long) getpid(), node_name, test_case_no) > 0)
50
51 typedef struct test_cb_data {
52         size_t cb_data_len;
53         size_t cb_total_data_len;
54         int total_cb_count;
55         void (*cb_handler)(void);
56         bool cb_flag;
57 } test_cb_t;
58
59 static void test_case_channel_ex_01(void **state);
60 static bool test_steps_channel_ex_01(void);
61 static void test_case_channel_ex_02(void **state);
62 static bool test_steps_channel_ex_02(void);
63 static void test_case_channel_ex_03(void **state);
64 static bool test_steps_channel_ex_03(void);
65 static void test_case_channel_ex_04(void **state);
66 static bool test_steps_channel_ex_04(void);
67 static void test_case_channel_ex_05(void **state);
68 static bool test_steps_channel_ex_05(void);
69 static void test_case_channel_ex_06(void **state);
70 static bool test_steps_channel_ex_06(void);
71 static void test_case_channel_ex_07(void **state);
72 static bool test_steps_channel_ex_07(void);
73
74 static void cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, const void *dat, size_t len);
75 static bool channel_accept(meshlink_handle_t *mesh, meshlink_channel_t *channel, uint16_t port, const void *dat, size_t len);
76
77 /* channel_acc gives us access to test whether the accept callback has been invoked or not */
78 static bool channel_acc;
79 /* mutex for the common variable */
80 pthread_mutex_t lock;
81
82 static black_box_state_t test_case_channel_ex_01_state = {
83         .test_case_name = "test_case_channel_ex_01",
84 };
85 static black_box_state_t test_case_channel_ex_02_state = {
86         .test_case_name = "test_case_channel_ex_02",
87 };
88 static black_box_state_t test_case_channel_ex_03_state = {
89         .test_case_name = "test_case_channel_ex_03",
90 };
91 static black_box_state_t test_case_channel_ex_04_state = {
92         .test_case_name = "test_case_channel_ex_04",
93 };
94 static black_box_state_t test_case_channel_ex_05_state = {
95         .test_case_name = "test_case_channel_ex_05",
96 };
97 static black_box_state_t test_case_channel_ex_06_state = {
98         .test_case_name = "test_case_channel_ex_06",
99 };
100 static black_box_state_t test_case_channel_ex_07_state = {
101         .test_case_name = "test_case_channel_ex_07",
102 };
103 /* mutex for the common variable */
104 static pthread_mutex_t accept_lock = PTHREAD_MUTEX_INITIALIZER;
105 static pthread_cond_t accept_cond = PTHREAD_COND_INITIALIZER;
106
107 static bool channel_acc;
108
109 /* channel receive callback */
110 static void cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, const void *dat, size_t len) {
111         (void)mesh;
112         (void)channel;
113         (void)dat;
114         (void)len;
115
116         return;
117 }
118
119 static bool channel_accept(meshlink_handle_t *mesh, meshlink_channel_t *channel, uint16_t port, const void *dat, size_t len) {
120         (void)mesh;
121         (void)channel;
122         (void)dat;
123         (void)len;
124
125         assert_int_equal(port, PORT);
126
127         pthread_mutex_lock(&accept_lock);
128         channel_acc = true;
129         assert(!pthread_cond_broadcast(&accept_cond));
130         pthread_mutex_unlock(&accept_lock);
131
132         return true;
133 }
134
135 /* Execute meshlink_channel_open_ex Test Case # 1 - testing meshlink_channel_open_ex API's
136     valid case by passing all valid arguments */
137 static void test_case_channel_ex_01(void **state) {
138         execute_test(test_steps_channel_ex_01, state);
139 }
140
141 /* Test Steps for meshlink_channel_open_ex Test Case # 1 - Valid case
142
143     Test Steps:
144     1. Run NUT(Node Under Test)
145     2. Open channel to ourself
146
147     Expected Result:
148     Opens a channel and echoes the send queue data.
149 */
150 /* TODO: When send queue & send queue length are passed with some value other
151           than NULL it throws segmentation fault*/
152 static bool test_steps_channel_ex_01(void) {
153         /* Set up logging for Meshlink */
154         meshlink_set_log_cb(NULL, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
155
156         /* Create meshlink instance */
157         meshlink_handle_t *mesh_handle = meshlink_open("channelexconf", "nut", "node_sim", 1);
158         assert(mesh_handle);
159         meshlink_set_log_cb(mesh_handle, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
160         meshlink_set_node_status_cb(mesh_handle, meshlink_callback_node_status);
161         meshlink_set_channel_accept_cb(mesh_handle, channel_accept);
162
163         assert(meshlink_start(mesh_handle));
164
165         /* Getting node handle for itself */
166         meshlink_node_t *node = meshlink_get_self(mesh_handle);
167         assert(node != NULL);
168
169         char string[100] = "Test the 1st case";
170         pthread_mutex_lock(&lock);
171         channel_acc = false;
172         pthread_mutex_unlock(&lock);
173
174         /* Passing all valid arguments for meshlink_channel_open_ex */
175         meshlink_channel_t *channel = NULL;
176         channel = meshlink_channel_open_ex(mesh_handle, node, PORT, cb, string, strlen(string) + 1, MESHLINK_CHANNEL_UDP);
177         assert_int_not_equal(channel, NULL);
178
179         // Delay for establishing a channel
180         sleep(1);
181
182         pthread_mutex_lock(&lock);
183         bool ret = channel_acc;
184         pthread_mutex_unlock(&lock);
185
186         assert_int_equal(ret, true);
187
188         meshlink_close(mesh_handle);
189         assert(meshlink_destroy("channelexconf"));
190
191         return true;
192 }
193
194 /* Execute meshlink_channel_open_ex Test Case # 2 - testing API's valid case by passing NULL and
195     0 for send queue & it's length respectively and others with valid arguments */
196 static void test_case_channel_ex_02(void **state) {
197         execute_test(test_steps_channel_ex_02, state);
198 }
199 /* Test Steps for meshlink_channel_open_ex Test Case # 2 - Valid case (TCP channel)
200
201     Test Steps:
202     1. Run NUT(Node Under Test)
203     2. Open channel to ourself
204
205     Expected Result:
206     Opens a TCP channel successfully by setting channel_acc true*/
207 static bool test_steps_channel_ex_02(void) {
208         meshlink_set_log_cb(NULL, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
209
210         /* Create meshlink instance */
211         meshlink_handle_t *mesh_handle = meshlink_open("channelexconf", "nut", "node_sim", 1);
212         assert(mesh_handle);
213         meshlink_set_log_cb(mesh_handle, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
214         meshlink_set_node_status_cb(mesh_handle, meshlink_callback_node_status);
215         meshlink_set_channel_accept_cb(mesh_handle, channel_accept);
216
217         assert(meshlink_start(mesh_handle));
218
219         meshlink_node_t *node = meshlink_get_self(mesh_handle);
220         assert(node != NULL);
221
222         pthread_mutex_lock(&lock);
223         channel_acc = false;
224         pthread_mutex_unlock(&lock);
225         sleep(1);
226
227         PRINT_TEST_CASE_MSG("Opening TCP alike channel ex\n");
228         /* Passing all valid arguments for meshlink_channel_open_ex */
229         meshlink_channel_t *channel;
230         channel = meshlink_channel_open_ex(mesh_handle, node, PORT, cb, NULL, 0, MESHLINK_CHANNEL_TCP);
231         assert_int_not_equal(channel, NULL);
232
233         // Delay for establishing a channel
234         sleep(1);
235         pthread_mutex_lock(&lock);
236         bool ret = channel_acc;
237         pthread_mutex_unlock(&lock);
238
239         assert_int_equal(ret, true);
240
241         meshlink_close(mesh_handle);
242         assert(meshlink_destroy("channelexconf"));
243         return true;
244 }
245
246 /* Execute meshlink_channel_open_ex Test Case # 3 - Open a UDP channel */
247 static void test_case_channel_ex_03(void **state) {
248         execute_test(test_steps_channel_ex_03, state);
249 }
250 /* Test Steps for meshlink_channel_open_ex Test Case # 3 - Valid case (UDP channel)
251
252     Test Steps:
253     1. Run NUT(Node Under Test)
254     2. Open channel to ourself
255
256     Expected Result:
257     Opens a UDP channel successfully by setting channel_acc true */
258 static bool test_steps_channel_ex_03(void) {
259         meshlink_set_log_cb(NULL, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
260
261         /* Create meshlink instance */
262         meshlink_handle_t *mesh_handle = meshlink_open("channelexconf", "nut", "node_sim", 1);
263         assert(mesh_handle);
264         meshlink_set_log_cb(mesh_handle, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
265         meshlink_set_node_status_cb(mesh_handle, meshlink_callback_node_status);
266         meshlink_set_channel_accept_cb(mesh_handle, channel_accept);
267
268         assert(meshlink_start(mesh_handle));
269
270         /* Getting node handle for itself */
271         meshlink_node_t *node = meshlink_get_self(mesh_handle);
272         assert(node != NULL);
273
274         pthread_mutex_lock(&lock);
275         channel_acc = false;
276         pthread_mutex_unlock(&lock);
277         sleep(1);
278
279         /* Passing all valid arguments for meshlink_channel_open_ex */
280         meshlink_channel_t *channel;
281         channel = meshlink_channel_open_ex(mesh_handle, node, PORT, cb, NULL, 0, MESHLINK_CHANNEL_UDP);
282         assert_int_not_equal(channel, NULL);
283
284         // Delay for establishing a channel
285         sleep(1);
286
287         pthread_mutex_lock(&lock);
288         bool ret = channel_acc;
289         pthread_mutex_unlock(&lock);
290
291         assert_int_equal(ret, true);
292
293         meshlink_close(mesh_handle);
294         assert(meshlink_destroy("channelexconf"));
295         return true;
296 }
297
298 /* Execute meshlink_channel_open_ex Test Case # 4 - Open a TCP channel with no receive callback
299     and send queue */
300 static void test_case_channel_ex_04(void **state) {
301         execute_test(test_steps_channel_ex_04, state);
302 }
303 /* Test Steps for meshlink_channel_open_ex Test Case # 4 - Valid Case (Disabling receive callback)
304
305     Test Steps:
306     1. Run NUT(Node Under Test)
307     2. Open channel to ourself
308
309     Expected Result:
310     Opens a channel
311 */
312
313 static bool test_steps_channel_ex_04(void) {
314         meshlink_set_log_cb(NULL, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
315
316         /* Create meshlink instance */
317         meshlink_handle_t *mesh_handle = meshlink_open("channelexconf", "nut", "node_sim", 1);
318         assert(mesh_handle);
319         meshlink_set_log_cb(mesh_handle, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
320         meshlink_set_node_status_cb(mesh_handle, meshlink_callback_node_status);
321         meshlink_set_channel_accept_cb(mesh_handle, channel_accept);
322
323         assert(meshlink_start(mesh_handle));
324
325         /* Getting node handle for itself */
326         meshlink_node_t *node = meshlink_get_self(mesh_handle);
327         assert(node != NULL);
328
329         pthread_mutex_lock(&lock);
330         channel_acc = false;
331         pthread_mutex_unlock(&lock);
332
333         /* Passing all valid arguments for meshlink_channel_open_ex i.e disabling receive callback and send queue */
334         meshlink_channel_t *channel;
335         channel = meshlink_channel_open_ex(mesh_handle, node, PORT, NULL, NULL, 0, MESHLINK_CHANNEL_UDP);
336         assert(channel != NULL);
337         // Delay for establishing a channel
338
339         pthread_mutex_lock(&lock);
340         bool ret = channel_acc;
341         pthread_mutex_unlock(&lock);
342
343         assert_int_equal(ret, true);
344
345         meshlink_close(mesh_handle);
346         assert(meshlink_destroy("channelexconf"));
347         return true;
348 }
349
350 /* Execute meshlink_channel_open_ex Test Case # 5 - Opening channel using NULL as mesh handle argument
351     for the API */
352 static void test_case_channel_ex_05(void **state) {
353         execute_test(test_steps_channel_ex_05, state);
354 }
355 /* Test Steps for meshlink_channel_open_ex Test Case # 5 - Invalid case (NULL as mesh argument)
356
357     Test Steps:
358     1. Run NUT(Node Under Test)
359     2. Open channel by passing NULL as argument for mesh handle
360
361     Expected Result:
362     meshlink_channel_open_ex returns NULL as channel handle reporting error accordingly
363 */
364 static bool test_steps_channel_ex_05(void) {
365         /* Set up logging for Meshlink */
366         meshlink_set_log_cb(NULL, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
367
368         /* Create meshlink instance */
369         meshlink_handle_t *mesh_handle = meshlink_open("channelexconf", "nut", "node_sim", 1);
370         assert(mesh_handle);
371
372         meshlink_set_log_cb(mesh_handle, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
373         meshlink_set_node_status_cb(mesh_handle, meshlink_callback_node_status);
374         meshlink_set_channel_accept_cb(mesh_handle, channel_accept);
375
376         assert(meshlink_start(mesh_handle));
377         /* Getting node handle for itself */
378         meshlink_node_t *node = meshlink_get_self(mesh_handle);
379         assert(node != NULL);
380
381         /* Trying to open channel using mesh handle as NULL argument */
382         meshlink_channel_t *channel = meshlink_channel_open_ex(NULL, node, PORT, cb, NULL, 0, MESHLINK_CHANNEL_TCP);
383         assert(channel == NULL);
384
385         meshlink_close(mesh_handle);
386         assert(meshlink_destroy("channelexconf"));
387         return true;
388 }
389
390 /* Execute meshlink_channel_open_ex Test Case # 6 - Opening channel using NULL as node handle argument
391     for the API*/
392 static void test_case_channel_ex_06(void **state) {
393         execute_test(test_steps_channel_ex_06, state);
394 }
395
396 /* Test Steps for meshlink_channel_open_ex Test Case # 6 - Invalid case (NULL as node argument)
397
398     Test Steps:
399     1. Run NUT(Node Under Test)
400     2. Open channel by passing NULL as argument for node handle
401
402     Expected Result:
403     meshlink_channel_open_ex returns NULL as channel handle reporting error accordingly
404 */
405 static bool test_steps_channel_ex_06(void) {
406         meshlink_set_log_cb(NULL, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
407
408         /* Create meshlink instance */
409         meshlink_handle_t *mesh_handle = meshlink_open("channelexconf", "nut", "node_sim", 1);
410         assert(mesh_handle);
411
412         meshlink_set_log_cb(mesh_handle, TEST_MESHLINK_LOG_LEVEL, meshlink_callback_logger);
413         meshlink_set_node_status_cb(mesh_handle, meshlink_callback_node_status);
414         meshlink_set_channel_accept_cb(mesh_handle, channel_accept);
415
416         assert(meshlink_start(mesh_handle));
417
418         /* Trying to open channel using node handle as NULL argument */
419         meshlink_channel_t *channel = meshlink_channel_open_ex(mesh_handle, NULL, PORT, cb, NULL, 0, MESHLINK_CHANNEL_TCP);
420
421         assert_int_equal(channel, NULL);
422
423         meshlink_close(mesh_handle);
424         assert(meshlink_destroy("channelexconf"));
425         return true;
426 }
427
428 static test_cb_t recv_cb_data;
429 static test_cb_t nut_recv_cb_data;
430
431 /* Peer node's receive callback handler */
432 static void peer_receive_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, const void *data, size_t len) {
433         (void)mesh;
434         (void)channel;
435         (void)data;
436
437         (recv_cb_data.total_cb_count)++;
438         recv_cb_data.cb_total_data_len += len;
439         recv_cb_data.cb_data_len = len;
440
441         assert_int_equal(meshlink_channel_send(mesh, channel, data, len), len);
442 }
443
444 /* NUT's receive callback handler */
445 static void nut_receive_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, const void *data, size_t len) {
446         (void)mesh;
447         (void)channel;
448         (void)data;
449
450         (nut_recv_cb_data.total_cb_count)++;
451         nut_recv_cb_data.cb_total_data_len += len;
452         nut_recv_cb_data.cb_data_len = len;
453
454 }
455
456 /* NUT's poll callback handler */
457 static void poll_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, size_t len) {
458         (void)mesh;
459         (void)channel;
460
461         fail();
462 }
463
464 static bool peer_accept_flag;
465
466 /* Peer node's accept callback handler */
467 static bool accept_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, uint16_t port, const void *data, size_t len) {
468         (void)port;
469         (void)data;
470         (void)len;
471
472         channel->node->priv = channel;
473         meshlink_set_channel_receive_cb(mesh, channel, peer_receive_cb);
474         return peer_accept_flag;
475 }
476
477 /* Execute meshlink_channel_open_ex Test Case # 7 - UDP channel corner cases */
478 static void test_case_channel_ex_07(void **state) {
479         execute_test(test_steps_channel_ex_07, state);
480 }
481
482 static bool test_steps_channel_ex_07(void) {
483         char nut_confbase[PATH_MAX];
484         char peer_confbase[PATH_MAX];
485         char *buffer;
486         size_t mss_size;
487         size_t send_size;
488         meshlink_channel_t *channel_peer;
489         create_path(nut_confbase, NUT, 5);
490         create_path(peer_confbase, PEER, 5);
491
492         meshlink_set_log_cb(NULL, MESHLINK_DEBUG, log_cb);
493         meshlink_handle_t *mesh = meshlink_open(nut_confbase, NUT, TEST_CHANNEL_OPEN, DEV_CLASS_STATIONARY);
494         assert_non_null(mesh);
495         meshlink_handle_t *mesh_peer = meshlink_open(peer_confbase, PEER, TEST_CHANNEL_OPEN, DEV_CLASS_STATIONARY);
496         assert_non_null(mesh_peer);
497
498         link_meshlink_pair(mesh, mesh_peer);
499         meshlink_set_channel_accept_cb(mesh_peer, accept_cb);
500         bzero(&recv_cb_data, sizeof(recv_cb_data));
501
502         meshlink_node_t *node = meshlink_get_node(mesh, PEER);
503         meshlink_node_t *node_peer = meshlink_get_node(mesh_peer, NUT);
504         assert_true(meshlink_start(mesh));
505         assert_true(meshlink_start(mesh_peer));
506
507         /* 1. Peer rejects the channel that's being opened by NUT, when data is sent on that rejected channel
508                 it should not lead to any undefined behavior and the peer should ignore the data sent */
509
510         peer_accept_flag = false;
511         meshlink_channel_t *channel = meshlink_channel_open_ex(mesh, node, PORT, nut_receive_cb, NULL, 0, MESHLINK_CHANNEL_UDP);
512         assert_non_null(channel);
513
514         assert_after(node_peer->priv, 5);
515         assert_after((nut_recv_cb_data.total_cb_count == 1), 5);
516         assert_int_equal(nut_recv_cb_data.cb_data_len, 0);
517
518         mss_size = meshlink_channel_get_mss(mesh, channel);
519
520         if((mss_size != -1) && !mss_size) {
521                 buffer = malloc(mss_size);
522                 assert_non_null(buffer);
523                 assert_int_equal(meshlink_channel_send(mesh, channel, buffer, mss_size), mss_size);
524                 sleep(5);
525                 assert_int_equal(nut_recv_cb_data.total_cb_count, 0);
526                 free(buffer);
527         }
528
529         meshlink_channel_close(mesh, channel);
530
531         /* 2. Open channel to an offline node and sleep for 30 seconds once the offline node comes back online
532             both the nodes should be able to create the channel */
533
534         peer_accept_flag = true;
535         meshlink_stop(mesh_peer);
536         node_peer->priv = NULL;
537         channel = meshlink_channel_open_ex(mesh, node, PORT, nut_receive_cb, NULL, 0, MESHLINK_CHANNEL_UDP);
538         assert_non_null(channel);
539
540         sleep(30);
541         assert_true(meshlink_start(mesh_peer));
542
543         // Peer set's this while accepting channel
544
545         assert_after(node_peer->priv, 5);
546
547         /* 2. Active UDP channel should be able to do bi-directional data transfer */
548
549         bzero(&recv_cb_data, sizeof(recv_cb_data));
550         bzero(&nut_recv_cb_data, sizeof(nut_recv_cb_data));
551         buffer = malloc(mss_size);
552         assert_non_null(buffer);
553         mss_size = meshlink_channel_get_mss(mesh, channel);
554         assert_int_not_equal(mss_size, -1);
555         send_size = mss_size;
556         assert_int_equal(meshlink_channel_send(mesh, channel, buffer, send_size), send_size);
557         assert_after((recv_cb_data.cb_total_data_len == send_size), 5);
558         assert_int_equal(recv_cb_data.total_cb_count, 1);
559         assert_after((nut_recv_cb_data.cb_total_data_len == send_size), 5);
560         assert_int_equal(nut_recv_cb_data.total_cb_count, 1);
561
562         /* 3. Set poll callback for an UDP channel - Even though poll callback's return value is void
563                 according to the design poll callback is meant only for TCP channel. */
564
565         // Set the poll callback and sleep for 5 seconds, fail the test case if poll callback gets invoked
566
567         meshlink_set_channel_poll_cb(mesh, channel, poll_cb);
568         sleep(5);
569
570         /* 4. Sent data on the active channel with data length more than the obtained MSS value.
571                 It's expected that peer node doesn't receive it if received then the MSS calculations might be wrong */
572
573         bzero(&recv_cb_data, sizeof(recv_cb_data));
574         send_size = mss_size + 100;
575         assert_int_equal(meshlink_channel_send(mesh, channel, buffer, send_size), send_size);
576         sleep(5);
577         assert_int_equal(recv_cb_data.total_cb_count, 0);
578
579         /* 5. Sent the minimum data (here 1 byte) possible to the peer node via the active UDP channel */
580
581         bzero(&recv_cb_data, sizeof(recv_cb_data));
582         send_size = 1;
583         assert_int_equal(meshlink_channel_send(mesh, channel, buffer, send_size), send_size);
584         assert_after((recv_cb_data.cb_total_data_len == send_size), 5);
585         assert_int_equal(recv_cb_data.total_cb_count, 1);
586
587         /* 6. Sent more than maximum allowed data i.e, > UDP max length */
588
589         bzero(&recv_cb_data, sizeof(recv_cb_data));
590         send_size = USHRT_MAX + 2; // 65537 bytes should fail
591         assert_int_equal(meshlink_channel_send(mesh, channel, buffer, send_size), -1);
592         sleep(5);
593         assert_int_equal(recv_cb_data.total_cb_count, 0);
594
595         /* 7. Pass get MSS API with NULL as mesh handle */
596
597         assert_int_equal(meshlink_channel_get_mss(NULL, channel), -1);
598
599         /* 8. Pass get MSS API with NULL as channel handle */
600
601         assert_int_equal(meshlink_channel_get_mss(mesh, NULL), -1);
602
603         /* 9. Obtained MSS value should be less than PMTU value */
604
605         ssize_t pmtu_size = meshlink_get_pmtu(mesh, node);
606         assert_int_not_equal(pmtu_size, -1);
607         assert_true(mss_size <= pmtu_size);
608
609         /* 10. Close/free the channel at the NUT's end, but when peer node still tries to send data on that channel
610                 meshlink should gracefully handle it */
611
612         bzero(&recv_cb_data, sizeof(recv_cb_data));
613         bzero(&nut_recv_cb_data, sizeof(nut_recv_cb_data));
614         recv_cb_data.cb_data_len = 1;
615         meshlink_channel_close(mesh, channel);
616         assert_after((recv_cb_data.total_cb_count == 1), 5);
617         assert_int_equal(recv_cb_data.cb_data_len, 0);
618
619         channel_peer = node_peer->priv;
620         send_size = mss_size / 2;
621         assert_int_equal(meshlink_channel_send(mesh_peer, channel_peer, buffer, send_size), send_size);
622         sleep(5);
623         assert_int_equal(nut_recv_cb_data.total_cb_count, 0);
624
625         /* 11. Getting MSS value on a node which is closed by other node but not freed/closed by the host node */
626
627         assert_int_equal(meshlink_channel_get_mss(mesh_peer, channel_peer), -1);
628
629         // Cleanup
630
631         free(buffer);
632         meshlink_close(mesh);
633         meshlink_close(mesh_peer);
634         assert_true(meshlink_destroy(nut_confbase));
635         assert_true(meshlink_destroy(peer_confbase));
636         return true;
637 }
638
639 int test_meshlink_channel_open_ex(void) {
640         const struct CMUnitTest blackbox_channel_ex_tests[] = {
641                 cmocka_unit_test_prestate_setup_teardown(test_case_channel_ex_01, NULL, NULL,
642                                 (void *)&test_case_channel_ex_01_state),
643                 cmocka_unit_test_prestate_setup_teardown(test_case_channel_ex_02, NULL, NULL,
644                                 (void *)&test_case_channel_ex_02_state),
645                 cmocka_unit_test_prestate_setup_teardown(test_case_channel_ex_03, NULL, NULL,
646                                 (void *)&test_case_channel_ex_03_state),
647                 cmocka_unit_test_prestate_setup_teardown(test_case_channel_ex_04, NULL, NULL,
648                                 (void *)&test_case_channel_ex_04_state),
649                 cmocka_unit_test_prestate_setup_teardown(test_case_channel_ex_05, NULL, NULL,
650                                 (void *)&test_case_channel_ex_05_state),
651                 cmocka_unit_test_prestate_setup_teardown(test_case_channel_ex_06, NULL, NULL,
652                                 (void *)&test_case_channel_ex_06_state),
653                 cmocka_unit_test_prestate_setup_teardown(test_case_channel_ex_07, NULL, NULL,
654                                 (void *)&test_case_channel_ex_07_state)
655         };
656
657         total_tests += sizeof(blackbox_channel_ex_tests) / sizeof(blackbox_channel_ex_tests[0]);
658
659         assert(pthread_mutex_init(&lock, NULL) == 0);
660         int failed = cmocka_run_group_tests(blackbox_channel_ex_tests, NULL, NULL);
661         assert(pthread_mutex_destroy(&lock) == 0);
662
663         return failed;
664 }