2 test_cases_get_node_reachability.c -- Execution of specific meshlink black box test cases
3 Copyright (C) 2019 Guus Sliepen <guus@meshlink.io>
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.
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.
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.
32 #include <sys/types.h>
39 #include "execute_tests.h"
40 #include "test_cases_get_node_reachability.h"
41 #include "../common/test_step.h"
42 #include "../common/common_handlers.h"
43 #include "../../utils.h"
48 #define GET_NODE_REACHABILITY "test_get_node_reachability"
49 #define create_path(confbase, node_name, test_case_no) assert(snprintf(confbase, sizeof(confbase), GET_NODE_REACHABILITY "_%ld_%s_%02d", (long) getpid(), node_name, test_case_no) > 0)
51 static struct sync_flag peer_reachable_status_cond = {.mutex = PTHREAD_MUTEX_INITIALIZER, .cond = PTHREAD_COND_INITIALIZER};
52 static bool peer_reachable_status;
53 static struct sync_flag nut_reachable_status_cond = {.mutex = PTHREAD_MUTEX_INITIALIZER, .cond = PTHREAD_COND_INITIALIZER};
54 static bool nut_reachable_status;
55 static struct sync_flag nut_started_status_cond = {.mutex = PTHREAD_MUTEX_INITIALIZER, .cond = PTHREAD_COND_INITIALIZER};
56 static bool peer_node_callback_test_status;
58 static void test_case_get_node_reachability_01(void **state);
59 static bool test_get_node_reachability_01(void);
60 static void test_case_get_node_reachability_02(void **state);
61 static bool test_get_node_reachability_02(void);
62 static void test_case_get_node_reachability_03(void **state);
63 static bool test_get_node_reachability_03(void);
64 static void test_case_get_node_reachability_04(void **state);
65 static bool test_get_node_reachability_04(void);
66 static void test_case_get_node_reachability_05(void **state);
67 static bool test_get_node_reachability_05(void);
68 static void test_case_get_node_reachability_06(void **state);
69 static bool test_get_node_reachability_06(void);
70 static void test_case_get_node_reachability_07(void **state);
71 static bool test_get_node_reachability_07(void);
73 /* Node reachable status callback which signals the respective conditional varibale */
74 static void meshlink_node_reachable_status_cb(meshlink_handle_t *mesh, meshlink_node_t *node, bool reachable_status) {
75 if(meshlink_get_self(mesh) == node) {
79 if(!strcasecmp(mesh->name, NUT)) {
80 if(!strcasecmp(node->name, PEER)) {
81 peer_reachable_status = reachable_status;
82 set_sync_flag(&peer_reachable_status_cond, true);
84 } else if(!strcasecmp(mesh->name, PEER)) {
85 if(!strcasecmp(node->name, NUT)) {
86 nut_reachable_status = reachable_status;
87 set_sync_flag(&nut_reachable_status_cond, true);
91 // Reset the node reachability status callback, as the two nodes making a simultaneous connection to each other, and then one connection will win and cause the other one to be disconnected.
92 meshlink_set_node_status_cb(mesh, NULL);
95 static void meshlink_node_reachable_status_cb_2(meshlink_handle_t *mesh, meshlink_node_t *node, bool reachable_status) {
96 meshlink_node_t *peer_handle;
97 char *peer_name = NULL;
98 time_t last_unreachable, last_reachable;
101 if(meshlink_get_self(mesh) == node) {
105 /* Of the 2 node reachable callbacks, the latest callback calls meshlink_get_node_reachability API
106 for the 1st node joined */
107 if(count && reachable_status && !strcasecmp(mesh->name, NUT)) {
111 if(!strcasecmp(node->name, PEER)) {
113 } else if(!strcasecmp(node->name, PEER2)) {
117 peer_handle = meshlink_get_node(mesh, peer_name);
118 assert_non_null(peer_handle);
120 bool status = meshlink_get_node_reachability(mesh, peer_handle, &last_reachable, &last_unreachable);
122 peer_node_callback_test_status = status && last_reachable && !last_unreachable;
123 set_sync_flag(&peer_reachable_status_cond, true);
128 /* SIGUSR2 signal handler that signals the NUT started and PEER node can join */
129 void nut_started_user_signal_handler(int signum) {
130 if(signum == SIGUSR2) {
131 set_sync_flag(&nut_started_status_cond, true);
137 Execute meshlink get last node reachability times feature Test Case # 1 -
140 static void test_case_get_node_reachability_01(void **state) {
141 execute_test(test_get_node_reachability_01, state);
144 /* Test Steps for meshlink_get_node_reachability Test Case # 1
146 Test steps and scenarios:
147 1. Open Node-Under-Test (NUT) instance, Call meshlink_get_node_reachability API
148 with valid mesh handle, self node handle, last_reachable pointer and
149 last_unreachable pointer.
151 API returns self node unreachable, last_reachable and last_unreachable values
154 2. Call meshlink_get_node_reachability API with valid mesh handle, self node handle.
155 But pass NULL pointers for last_reachable and last_unreachable arguments
157 API returns self node unreachable
159 3. Call meshlink_get_node_reachability API with NULL as mesh handle,
160 valid self node handle, last_reachable pointer and last_unreachable pointer.
162 API fails and sets MESHLINK_EINVAL as meshlink errno value
164 4. Call meshlink_get_node_reachability API with NULL as mesh handle,
165 valid self node handle, NULL pointers for last_reachable and last_unreachable
168 API fails and sets MESHLINK_EINVAL as meshlink errno value
170 5. Call meshlink_get_node_reachability API with valid mesh handle,
171 NULL as self node handle, last_reachable pointer and last_unreachable pointer.
173 API fails and sets MESHLINK_EINVAL as meshlink errno value
175 6. Call meshlink_get_node_reachability API with valid mesh handle,
176 NULL as self node handle, NULL pointers for last_reachable and last_unreachable
179 API fails and sets MESHLINK_EINVAL as meshlink errno value
182 static bool test_get_node_reachability_01(void) {
184 time_t last_unreachable, last_reachable;
185 char nut_confbase[PATH_MAX];
186 create_path(nut_confbase, NUT, 1);
188 meshlink_set_log_cb(NULL, MESHLINK_DEBUG, log_cb);
190 // Open Node-Under-Test node instance
192 meshlink_handle_t *mesh = meshlink_open(nut_confbase, NUT, GET_NODE_REACHABILITY, DEV_CLASS_STATIONARY);
193 assert_int_not_equal(mesh, NULL);
195 // Call meshlink_get_node_reachability API with all valid arguments
197 status = meshlink_get_node_reachability(mesh, meshlink_get_self(mesh), &last_reachable, &last_unreachable);
198 assert_int_equal(status, false);
199 assert_int_equal(last_reachable, 0);
200 assert_int_equal(last_unreachable, 0);
202 // Call meshlink_get_node_reachability API with all valid arguments
204 status = meshlink_get_node_reachability(mesh, meshlink_get_self(mesh), NULL, NULL);
205 assert_int_equal(status, false);
207 // Call meshlink_get_node_reachability API with invalid parameters
209 meshlink_errno = MESHLINK_OK;
210 meshlink_get_node_reachability(NULL, meshlink_get_self(mesh), NULL, NULL);
211 assert_int_equal(meshlink_errno, MESHLINK_EINVAL);
212 meshlink_errno = MESHLINK_OK;
213 meshlink_get_node_reachability(NULL, meshlink_get_self(mesh), &last_reachable, &last_unreachable);
214 assert_int_equal(meshlink_errno, MESHLINK_EINVAL);
215 meshlink_errno = MESHLINK_OK;
216 meshlink_get_node_reachability(mesh, NULL, NULL, NULL);
217 assert_int_equal(meshlink_errno, MESHLINK_EINVAL);
218 meshlink_errno = MESHLINK_OK;
219 meshlink_get_node_reachability(mesh, NULL, &last_reachable, &last_unreachable);
220 assert_int_equal(meshlink_errno, MESHLINK_EINVAL);
224 meshlink_close(mesh);
225 assert_true(meshlink_destroy(nut_confbase));
230 Execute meshlink get last node reachability times feature Test Case # 2 -
231 API testing with stand-alone node
233 static void test_case_get_node_reachability_02(void **state) {
234 execute_test(test_get_node_reachability_02, state);
237 /* Test Steps for meshlink_get_node_reachability Test Case # 2
239 Test steps and scenarios:
240 1. Open and start Node-Under-Test (NUT) instance, Call meshlink_get_node_reachability API.
242 API returns self node reachable status, last_reachable as some positive non-zero integer
243 and last_unreachable value as 0 seconds
245 2. Stop the NUT instance, Call meshlink_get_node_reachability API.
247 API returns self node unreachable, both last_reachable and last_unreachable values
248 as some positive non-zero time in seconds
250 3. Close and reopen NUT instance, Call meshlink_get_node_reachability API.
252 API returns self node unreachable, both last_reachable and last_unreachable values
253 as some positive non-zero time in seconds
256 static bool test_get_node_reachability_02(void) {
258 time_t last_unreachable, last_reachable, last_peer_unreachable, last_peer_reachable;
259 char nut_confbase[PATH_MAX];
260 create_path(nut_confbase, NUT, 2);
261 meshlink_set_log_cb(NULL, MESHLINK_DEBUG, log_cb);
263 // Open and start Node-Under-Test node instance
265 meshlink_handle_t *mesh = meshlink_open(nut_confbase, NUT, GET_NODE_REACHABILITY, DEV_CLASS_STATIONARY);
266 assert_non_null(mesh);
267 assert_true(meshlink_start(mesh));
269 // Call meshlink_get_node_reachability API with all valid arguments
271 status = meshlink_get_node_reachability(mesh, meshlink_get_self(mesh), &last_reachable, &last_unreachable);
273 assert_int_not_equal(last_reachable, 0);
274 assert_int_equal(last_unreachable, 0);
275 last_peer_reachable = last_reachable;
277 // Stop NUT node instance
281 // Call meshlink_get_node_reachability API with all valid arguments
283 status = meshlink_get_node_reachability(mesh, meshlink_get_self(mesh), &last_reachable, &last_unreachable);
284 assert_false(status);
285 assert_int_not_equal(last_unreachable, 0);
286 assert_int_equal(last_reachable, last_peer_reachable);
287 last_peer_unreachable = last_unreachable;
289 // Reinitialize NUT node instance
291 meshlink_close(mesh);
292 mesh = meshlink_open(nut_confbase, NUT, GET_NODE_REACHABILITY, DEV_CLASS_STATIONARY);
293 assert_non_null(mesh);
295 // Call meshlink_get_node_reachability API with all valid arguments
297 status = meshlink_get_node_reachability(mesh, meshlink_get_self(mesh), &last_reachable, &last_unreachable);
298 assert_false(status);
299 assert_int_equal(last_reachable, last_peer_reachable);
300 assert_int_equal(last_unreachable, last_peer_unreachable);
304 meshlink_close(mesh);
305 assert_true(meshlink_destroy(nut_confbase));
310 Execute meshlink get last node reachability times feature Test Case # 3 -
311 API testing with host node which already joined with a peer node which later
312 goes offline, test host node with an offline peer node case.
314 static void test_case_get_node_reachability_03(void **state) {
315 execute_test(test_get_node_reachability_03, state);
318 /* Test Steps for meshlink_get_node_reachability Test Case # 3
320 Test steps and scenarios:
321 1. Open Node-Under-Test (NUT) and peer node instance, start peer node instance
322 and invite NUT. NUT joins peer and destroy peer node instance.
323 Call meshlink_get_node_reachability API.
325 API returns peer node unreachable status, last_reachable and last_unreachable
328 2. Start the NUT instance, Call meshlink_get_node_reachability API.
330 API returns peer node unreachable status, last_reachable and last_unreachable
333 3. Stop the NUT instance, Call meshlink_get_node_reachability API.
335 API returns peer node unreachable status, last_reachable and last_unreachable
338 4. Close and reopen NUT instance, Call meshlink_get_node_reachability API.
340 API returns peer node unreachable status, last_reachable and last_unreachable
344 static bool test_get_node_reachability_03(void) {
346 time_t last_unreachable, last_reachable;
347 char nut_confbase[PATH_MAX];
348 char peer_confbase[PATH_MAX];
349 create_path(nut_confbase, NUT, 3);
350 create_path(peer_confbase, PEER, 3);
352 meshlink_set_log_cb(NULL, MESHLINK_DEBUG, log_cb);
354 // Open and start peer node instance, invite NUT.
356 meshlink_handle_t *mesh_peer = meshlink_open(peer_confbase, PEER, GET_NODE_REACHABILITY,
357 DEV_CLASS_STATIONARY);
358 assert_non_null(mesh_peer);
359 assert_true(meshlink_start(mesh_peer));
360 char *invitation = meshlink_invite(mesh_peer, NULL, NUT);
361 assert_non_null(invitation);
363 // Open NUT node instance and join with the peer node
365 meshlink_handle_t *mesh = meshlink_open(nut_confbase, NUT, GET_NODE_REACHABILITY, DEV_CLASS_STATIONARY);
366 assert_non_null(mesh);
367 assert_true(meshlink_join(mesh, invitation));
369 meshlink_node_t *peer_handle = meshlink_get_node(mesh, PEER);
370 assert_non_null(peer_handle);
372 // Cleanup peer node instance
374 meshlink_close(mesh_peer);
375 assert_true(meshlink_destroy(peer_confbase));
377 // Call meshlink_get_node_reachability API with valid arguments
379 status = meshlink_get_node_reachability(mesh, peer_handle, &last_reachable, &last_unreachable);
380 assert_false(status);
381 assert_int_equal(last_reachable, 0);
382 assert_int_equal(last_unreachable, 0);
384 // Start NUT node instance
386 assert_true(meshlink_start(mesh));
388 // Call meshlink_get_node_reachability API with valid arguments
390 status = meshlink_get_node_reachability(mesh, peer_handle, &last_reachable, &last_unreachable);
391 assert_false(status);
392 assert_int_equal(last_reachable, 0);
393 assert_int_equal(last_unreachable, 0);
395 // Stop NUT node instance
399 // Call meshlink_get_node_reachability API with valid arguments
401 status = meshlink_get_node_reachability(mesh, peer_handle, &last_reachable, &last_unreachable);
402 assert_false(status);
403 assert_int_equal(last_reachable, 0);
404 assert_int_equal(last_unreachable, 0);
406 // Reinitialize NUT node instance
408 meshlink_close(mesh);
409 mesh = meshlink_open(nut_confbase, NUT, GET_NODE_REACHABILITY, DEV_CLASS_STATIONARY);
410 assert_non_null(mesh);
411 peer_handle = meshlink_get_node(mesh, PEER);
412 assert_non_null(peer_handle);
414 // Call meshlink_get_node_reachability API with valid arguments
416 status = meshlink_get_node_reachability(mesh, peer_handle, &last_reachable, &last_unreachable);
417 assert_false(status);
418 assert_int_equal(last_reachable, 0);
419 assert_int_equal(last_unreachable, 0);
423 meshlink_close(mesh);
424 assert_true(meshlink_destroy(nut_confbase));
429 Execute meshlink get last node reachability times feature Test Case # 4 -
430 API testing around invited and invitee node.
432 static void test_case_get_node_reachability_04(void **state) {
433 execute_test(test_get_node_reachability_04, state);
436 /* Test Steps for meshlink_get_node_reachability Test Case # 4
438 Test steps and scenarios:
439 1. Open Node-Under-Test (NUT) and peer node instance, join both the node and
440 bring them online. Call meshlink_get_node_reachability API from both the nodes.
442 API for both the nodes returns reachable status, last_reachable should be
443 some non-zero positive seconds and last_unreachable should be 0 seconds.
445 2. Stop both the node instances, Call meshlink_get_node_reachability API from both the nodes.
447 API for both the nodes returns unreachable status. last_reachable should match with
448 the old value and last_unreachable should be non-zero positive value.
450 3. Restart both the node instances, Call meshlink_get_node_reachability APIs.
452 API for both the nodes should return reachable status. last_reachable should not match with
453 the old value, but last_unreachable should remain same
455 4. Close and reopen both the node instances, Call meshlink_get_node_reachability APIs.
457 API returns self node unreachable status, last_reachable should remain same
458 but last_unreachable should vary.
460 4. Start both the node instances, Call meshlink_get_node_reachability APIs.
462 API returns self node reachable status, last_reachable should vary and
463 last_unreachable remains same.
466 static bool test_get_node_reachability_04(void) {
468 time_t last_nut_unreachable, last_nut_reachable;
469 time_t last_peer_unreachable, last_peer_reachable;
470 time_t last_reachable, last_unreachable;
471 char nut_confbase[PATH_MAX];
472 char peer_confbase[PATH_MAX];
473 create_path(nut_confbase, NUT, 4);
474 create_path(peer_confbase, PEER, 4);
475 meshlink_set_log_cb(NULL, MESHLINK_DEBUG, log_cb);
477 // Open both NUT and peer node instance, invite and join NUT with peer node.
479 meshlink_handle_t *mesh_peer = meshlink_open(peer_confbase, PEER, GET_NODE_REACHABILITY,
480 DEV_CLASS_STATIONARY);
481 assert_non_null(mesh_peer);
482 meshlink_set_node_status_cb(mesh_peer, meshlink_node_reachable_status_cb);
483 char *invitation = meshlink_invite(mesh_peer, NULL, NUT);
484 assert_non_null(invitation);
485 assert_true(meshlink_start(mesh_peer));
487 meshlink_handle_t *mesh = meshlink_open(nut_confbase, NUT, GET_NODE_REACHABILITY,
488 DEV_CLASS_STATIONARY);
489 assert_non_null(mesh);
490 meshlink_set_node_status_cb(mesh, meshlink_node_reachable_status_cb);
491 assert_true(meshlink_join(mesh, invitation));
494 meshlink_node_t *peer_handle = meshlink_get_node(mesh, PEER);
495 assert_non_null(peer_handle);
496 meshlink_node_t *nut_handle = meshlink_get_node(mesh_peer, NUT);
497 assert_non_null(nut_handle);
499 // Bring nodes online.
501 set_sync_flag(&peer_reachable_status_cond, false);
502 set_sync_flag(&nut_reachable_status_cond, false);
503 assert_true(meshlink_start(mesh));
504 assert_true(wait_sync_flag(&peer_reachable_status_cond, 60));
505 assert_true(peer_reachable_status);
506 assert_true(wait_sync_flag(&nut_reachable_status_cond, 60));
507 assert_true(nut_reachable_status);
509 // Call meshlink_get_node_reachability API from joined node and also from joining node.
511 status = meshlink_get_node_reachability(mesh, peer_handle, &last_reachable, &last_unreachable);
513 assert_int_not_equal(last_reachable, 0);
514 assert_int_equal(last_unreachable, 0);
515 last_peer_reachable = last_reachable;
517 status = meshlink_get_node_reachability(mesh_peer, nut_handle, &last_reachable, &last_unreachable);
519 assert_int_not_equal(last_reachable, 0);
520 assert_int_equal(last_unreachable, 0);
521 last_nut_reachable = last_reachable;
523 // Stop the node instances of both peer and NUT.
526 meshlink_stop(mesh_peer);
528 // Call meshlink_get_node_reachability API from joined node and also from joining node.
530 status = meshlink_get_node_reachability(mesh, peer_handle, &last_reachable, &last_unreachable);
531 assert_false(status);
532 assert_int_not_equal(last_unreachable, 0);
533 assert_int_equal(last_reachable, last_peer_reachable);
534 last_peer_unreachable = last_unreachable;
536 status = meshlink_get_node_reachability(mesh_peer, nut_handle, &last_reachable, &last_unreachable);
537 assert_false(status);
538 assert_int_not_equal(last_unreachable, 0);
539 assert_int_equal(last_reachable, last_nut_reachable);
540 last_nut_unreachable = last_unreachable;
542 // Restart the node instances of both peer and NUT and wait for nodes to come online
545 set_sync_flag(&peer_reachable_status_cond, false);
546 set_sync_flag(&nut_reachable_status_cond, false);
547 meshlink_set_node_status_cb(mesh, meshlink_node_reachable_status_cb);
548 meshlink_set_node_status_cb(mesh_peer, meshlink_node_reachable_status_cb);
549 assert_true(meshlink_start(mesh));
550 assert_true(meshlink_start(mesh_peer));
552 assert_true(wait_sync_flag(&peer_reachable_status_cond, 60));
553 assert_true(peer_reachable_status);
554 assert_true(wait_sync_flag(&nut_reachable_status_cond, 60));
555 assert_true(nut_reachable_status);
557 // Call meshlink_get_node_reachability API from joined node and also from joining node.
559 status = meshlink_get_node_reachability(mesh, peer_handle, &last_reachable, &last_unreachable);
561 assert_int_not_equal(last_reachable, last_peer_reachable);
562 assert_true(last_unreachable >= last_peer_unreachable);
563 last_peer_reachable = last_reachable;
565 status = meshlink_get_node_reachability(mesh_peer, nut_handle, &last_reachable, &last_unreachable);
567 assert_int_not_equal(last_reachable, last_nut_reachable);
568 assert_true(last_unreachable >= last_nut_unreachable);
569 last_nut_reachable = last_reachable;
571 // Reinitialize the node instances of both peer and NUT
573 meshlink_close(mesh);
574 meshlink_close(mesh_peer);
578 mesh = meshlink_open(nut_confbase, NUT, GET_NODE_REACHABILITY, DEV_CLASS_STATIONARY);
579 assert_non_null(mesh);
580 meshlink_set_node_status_cb(mesh, meshlink_node_reachable_status_cb);
581 mesh_peer = meshlink_open(peer_confbase, PEER, GET_NODE_REACHABILITY,
582 DEV_CLASS_STATIONARY);
583 assert_non_null(mesh_peer);
584 meshlink_set_node_status_cb(mesh_peer, meshlink_node_reachable_status_cb);
586 peer_handle = meshlink_get_node(mesh, PEER);
587 assert_non_null(peer_handle);
588 nut_handle = meshlink_get_node(mesh_peer, NUT);
589 assert_non_null(nut_handle);
591 // Call meshlink_get_node_reachability API from joined node and also from joining node.
593 status = meshlink_get_node_reachability(mesh, peer_handle, &last_reachable, &last_unreachable);
594 assert_false(status);
595 assert_int_equal(last_reachable, last_peer_reachable);
596 assert_int_not_equal(last_unreachable, last_peer_unreachable);
597 last_peer_unreachable = last_unreachable;
599 status = meshlink_get_node_reachability(mesh_peer, nut_handle, &last_reachable, &last_unreachable);
600 assert_false(status);
601 assert_int_equal(last_reachable, last_nut_reachable);
602 assert_int_not_equal(last_unreachable, last_nut_unreachable);
603 last_nut_unreachable = last_unreachable;
605 // Restart the node instances of both peer and NUT
607 set_sync_flag(&peer_reachable_status_cond, false);
608 set_sync_flag(&nut_reachable_status_cond, false);
610 assert_true(meshlink_start(mesh));
611 assert_true(meshlink_start(mesh_peer));
613 assert_true(wait_sync_flag(&peer_reachable_status_cond, 60));
614 assert_true(peer_reachable_status);
615 assert_true(wait_sync_flag(&nut_reachable_status_cond, 60));
616 assert_true(nut_reachable_status);
618 // Call meshlink_get_node_reachability API from joined node and also from joining node.
620 status = meshlink_get_node_reachability(mesh, peer_handle, &last_reachable, &last_unreachable);
622 assert_int_not_equal(last_reachable, last_peer_reachable);
623 assert_true(last_unreachable >= last_peer_unreachable);
625 status = meshlink_get_node_reachability(mesh_peer, nut_handle, &last_reachable, &last_unreachable);
627 assert_int_not_equal(last_reachable, last_nut_reachable);
628 assert_true(last_unreachable >= last_nut_unreachable);
632 meshlink_close(mesh);
633 meshlink_close(mesh_peer);
634 assert_true(meshlink_destroy(nut_confbase));
635 assert_true(meshlink_destroy(peer_confbase));
640 Execute meshlink get last node reachability times feature Test Case # 5 -
641 API testing by calling it in the meshlink callback(s) and also isolation property.
643 static void test_case_get_node_reachability_05(void **state) {
644 execute_test(test_get_node_reachability_05, state);
647 /* Test Steps for meshlink_get_node_reachability Test Case # 5
649 Test steps and scenarios:
650 1. Open Node-Under-Test (NUT), peer and peer2 node instances. Join both the peer nodes
651 with NUT and bring them online.
653 API called from the node reachable callback of the latest peer node from NUT
654 about other peer node which joined 1st should return reachable status,
655 last_reachable status as some positive non-zero value and last unreachable value as 0.
658 static bool test_get_node_reachability_05(void) {
661 time_t last_reachable, last_unreachable;
662 char nut_confbase[PATH_MAX];
663 char peer_confbase[PATH_MAX];
664 char peer2_confbase[PATH_MAX];
665 create_path(nut_confbase, NUT, 5);
666 create_path(peer_confbase, PEER, 5);
667 create_path(peer2_confbase, PEER2, 5);
668 meshlink_set_log_cb(NULL, MESHLINK_DEBUG, log_cb);
670 // Open NUT, peer and peer2 and join peer nodes with NUT.
672 meshlink_handle_t *mesh = meshlink_open(nut_confbase, NUT, GET_NODE_REACHABILITY,
673 DEV_CLASS_STATIONARY);
674 assert_non_null(mesh);
675 meshlink_set_node_status_cb(mesh, meshlink_node_reachable_status_cb_2);
676 meshlink_handle_t *mesh_peer = meshlink_open(peer_confbase, PEER, GET_NODE_REACHABILITY,
677 DEV_CLASS_STATIONARY);
678 assert_non_null(mesh_peer);
679 meshlink_handle_t *mesh_peer2 = meshlink_open(peer2_confbase, PEER2, GET_NODE_REACHABILITY,
680 DEV_CLASS_STATIONARY);
681 assert_non_null(mesh_peer2);
683 assert_true(meshlink_start(mesh));
685 invitation = meshlink_invite(mesh, NULL, PEER);
686 assert_non_null(invitation);
687 assert_true(meshlink_join(mesh_peer, invitation));
688 invitation = meshlink_invite(mesh, NULL, PEER2);
689 assert_non_null(invitation);
690 assert_true(meshlink_join(mesh_peer2, invitation));
692 // Call meshlink_get_node_reachability API from NUT and check they remained 0 and unreachable
694 status = meshlink_get_node_reachability(mesh, meshlink_get_node(mesh, PEER), &last_reachable, &last_unreachable);
695 assert_int_equal(status, false);
696 assert_int_equal(last_reachable, 0);
697 assert_int_equal(last_unreachable, 0);
698 status = meshlink_get_node_reachability(mesh, meshlink_get_node(mesh, PEER2), &last_reachable, &last_unreachable);
699 assert_int_equal(status, false);
700 assert_int_equal(last_reachable, 0);
701 assert_int_equal(last_unreachable, 0);
703 // Start and wait for the signal from the node reachable callback which is raised when
704 // NUT is able to call meshlink_get_node_reachability API from callback of other peer node.
706 set_sync_flag(&peer_reachable_status_cond, false);
707 assert_true(meshlink_start(mesh_peer));
708 assert_true(meshlink_start(mesh_peer2));
709 assert_true(wait_sync_flag(&peer_reachable_status_cond, 60));
710 assert_true(peer_node_callback_test_status);
714 meshlink_close(mesh);
715 meshlink_close(mesh_peer);
716 meshlink_close(mesh_peer2);
717 assert_true(meshlink_destroy(nut_confbase));
718 assert_true(meshlink_destroy(peer_confbase));
719 assert_true(meshlink_destroy(peer2_confbase));
724 Execute meshlink get last node reachability times feature Test Case # 6 -
725 Persistence testing on the joining node.
727 static void test_case_get_node_reachability_06(void **state) {
728 execute_test(test_get_node_reachability_06, state);
731 /* Test Steps for meshlink_get_node_reachability Test Case # 6
733 Test steps and scenarios:
734 1. Open Node-Under-Test (NUT) and invite peer node and close it's instance.
735 Spawn a process which waits for the peer node to join and raises SIGINT if the
736 appropriate callback is received (on the other hand the test suite opens and joins
737 the peer node with NUT in the forked process).
738 Reopen NUT instance in the test suite process and call meshlink_get_node_reachability.
740 API returns peer node unreachable, last_reachable and last_unreachable values
741 as 0 seconds. It is expected that this feature synchronize it at least for the first time
742 when the NUT receives that a new peer node joined.
745 static bool test_get_node_reachability_06(void) {
747 time_t last_reachable, last_unreachable;
750 char nut_confbase[PATH_MAX];
751 char peer_confbase[PATH_MAX];
752 create_path(nut_confbase, NUT, 6);
753 create_path(peer_confbase, PEER, 6);
754 meshlink_set_log_cb(NULL, MESHLINK_DEBUG, log_cb);
756 // Open NUT node instance and invite peer node. Close NUT node instance.
758 meshlink_handle_t *mesh = meshlink_open(nut_confbase, NUT, GET_NODE_REACHABILITY, DEV_CLASS_STATIONARY);
759 assert_non_null(mesh);
760 char *invitation = meshlink_invite(mesh, NULL, PEER);
761 meshlink_close(mesh);
763 // Set the SIGUSR2 signal handler with handler that signal the condition to the test suite
765 sighandler_t usr2sighandler = signal(SIGUSR2, nut_started_user_signal_handler);
766 assert_int_not_equal(usr2sighandler, SIG_ERR);
768 // Fork a new process and run NUT in it which just waits for the peer node reachable status callback
769 // and terminates the process immediately.
772 assert_int_not_equal(pid, -1);
775 assert(signal(SIGUSR2, SIG_DFL) != SIG_ERR);
777 mesh = meshlink_open(nut_confbase, NUT, GET_NODE_REACHABILITY, DEV_CLASS_STATIONARY);
779 meshlink_set_log_cb(mesh, MESHLINK_DEBUG, log_cb);
780 meshlink_set_node_status_cb(mesh, meshlink_node_reachable_status_cb);
782 set_sync_flag(&peer_reachable_status_cond, false);
783 assert(meshlink_start(mesh));
785 assert(kill(getppid(), SIGUSR2) != -1);
787 assert(wait_sync_flag(&peer_reachable_status_cond, 60));
788 assert(peer_reachable_status);
793 // Open peer node instance and join with the invitation obtained.
795 meshlink_handle_t *mesh_peer = meshlink_open(peer_confbase, PEER, GET_NODE_REACHABILITY,
796 DEV_CLASS_STATIONARY);
797 assert_non_null(mesh_peer);
799 // Wait for the started signal from NUT and reset the previous SIGUSR2 signal handler
801 assert_true(wait_sync_flag(&nut_started_status_cond, 60));
802 assert_int_not_equal(signal(SIGUSR2, usr2sighandler), SIG_ERR);
804 assert_true(meshlink_join(mesh_peer, invitation));
805 assert_true(meshlink_start(mesh_peer));
807 // Wait for child exit and verify which signal terminated it
809 assert_int_not_equal(waitpid(pid, &pid_status, 0), -1);
810 assert_int_equal(WIFSIGNALED(pid_status), true);
811 assert_int_equal(WTERMSIG(pid_status), SIGINT);
813 // Reopen the NUT instance in the same test suite
815 mesh = meshlink_open(nut_confbase, NUT, GET_NODE_REACHABILITY, DEV_CLASS_STATIONARY);
816 assert_non_null(mesh);
818 // Call meshlink_get_node_reachability API and verify that the time stamps has persisted.
820 status = meshlink_get_node_reachability(mesh, meshlink_get_node(mesh, PEER), &last_reachable, &last_unreachable);
821 assert_int_equal(status, false);
822 assert_int_not_equal(last_reachable, 0);
823 assert_int_equal(last_unreachable, 0);
827 meshlink_close(mesh);
828 meshlink_close(mesh_peer);
829 assert_true(meshlink_destroy(nut_confbase));
830 assert_true(meshlink_destroy(peer_confbase));
835 Execute meshlink get last node reachability times feature Test Case # 7 -
836 Persistence testing on the invited node.
838 static void test_case_get_node_reachability_07(void **state) {
839 execute_test(test_get_node_reachability_07, state);
842 /* Test Steps for meshlink_get_node_reachability Test Case # 7
844 Test steps and scenarios:
845 1. Open peer node instance, invite NUT and start peer node. Spawn a new process in
846 which it opens and joins the NUT with peer node.
847 Reopen NUT instance in the test suite process and call meshlink_get_node_reachability API.
849 API returns peer node unreachable, last_reachable and last_unreachable values
850 as 0 seconds. It is expected that this feature synchronize it at least for the first time
851 when the Node-Under-Test joined with the peer node.
854 static bool test_get_node_reachability_07(void) {
856 time_t last_reachable, last_unreachable;
859 char nut_confbase[PATH_MAX];
860 char peer_confbase[PATH_MAX];
861 create_path(nut_confbase, NUT, 7);
862 create_path(peer_confbase, PEER, 7);
863 meshlink_set_log_cb(NULL, MESHLINK_DEBUG, log_cb);
865 // Open peer node instance and invite NUT.
867 meshlink_handle_t *mesh_peer = meshlink_open(peer_confbase, PEER, GET_NODE_REACHABILITY,
868 DEV_CLASS_STATIONARY);
869 assert_int_not_equal(mesh_peer, NULL);
870 char *invitation = meshlink_invite(mesh_peer, NULL, NUT);
871 assert_non_null(invitation);
873 assert_true(meshlink_start(mesh_peer));
875 // Fork a new process in which NUT is joins with the peer node and raises SIGINT to terminate.
878 assert_int_not_equal(pid, -1);
881 meshlink_handle_t *mesh = meshlink_open(nut_confbase, NUT, GET_NODE_REACHABILITY, DEV_CLASS_STATIONARY);
883 meshlink_set_log_cb(mesh, MESHLINK_DEBUG, log_cb);
885 assert(meshlink_join(mesh, invitation));
890 // Wait for child exit and verify which signal terminated it
892 assert_int_not_equal(waitpid(pid, &pid_status, 0), -1);
893 assert_int_equal(WIFSIGNALED(pid_status), true);
894 assert_int_equal(WTERMSIG(pid_status), SIGINT);
896 // Reopen the NUT instance in the same test suite
898 meshlink_handle_t *mesh = meshlink_open(nut_confbase, NUT, GET_NODE_REACHABILITY, DEV_CLASS_STATIONARY);
899 assert_non_null(mesh);
901 // Call meshlink_get_node_reachability API and verify that the time stamps has persisted.
903 status = meshlink_get_node_reachability(mesh, meshlink_get_node(mesh, PEER), &last_reachable, &last_unreachable);
904 assert_int_equal(status, false);
905 assert_int_equal(last_reachable, 0);
906 assert_int_equal(last_unreachable, 0);
910 meshlink_close(mesh);
911 meshlink_close(mesh_peer);
912 assert_true(meshlink_destroy(nut_confbase));
913 assert_true(meshlink_destroy(peer_confbase));
917 int test_get_node_reachability(void) {
918 /* State structures for get node reachability Test Cases */
919 black_box_state_t test_case_get_node_reachability_01_state = {
920 .test_case_name = "test_case_get_node_reachability_01",
922 black_box_state_t test_case_get_node_reachability_02_state = {
923 .test_case_name = "test_case_get_node_reachability_02",
925 black_box_state_t test_case_get_node_reachability_03_state = {
926 .test_case_name = "test_case_get_node_reachability_03",
928 black_box_state_t test_case_get_node_reachability_04_state = {
929 .test_case_name = "test_case_get_node_reachability_04",
931 black_box_state_t test_case_get_node_reachability_05_state = {
932 .test_case_name = "test_case_get_node_reachability_05",
934 black_box_state_t test_case_get_node_reachability_06_state = {
935 .test_case_name = "test_case_get_node_reachability_06",
937 black_box_state_t test_case_get_node_reachability_07_state = {
938 .test_case_name = "test_case_get_node_reachability_07",
941 const struct CMUnitTest blackbox_status_tests[] = {
942 cmocka_unit_test_prestate_setup_teardown(test_case_get_node_reachability_01, NULL, NULL,
943 (void *)&test_case_get_node_reachability_01_state),
944 cmocka_unit_test_prestate_setup_teardown(test_case_get_node_reachability_02, NULL, NULL,
945 (void *)&test_case_get_node_reachability_02_state),
946 cmocka_unit_test_prestate_setup_teardown(test_case_get_node_reachability_03, NULL, NULL,
947 (void *)&test_case_get_node_reachability_03_state),
948 cmocka_unit_test_prestate_setup_teardown(test_case_get_node_reachability_04, NULL, NULL,
949 (void *)&test_case_get_node_reachability_04_state),
950 cmocka_unit_test_prestate_setup_teardown(test_case_get_node_reachability_05, NULL, NULL,
951 (void *)&test_case_get_node_reachability_05_state),
952 cmocka_unit_test_prestate_setup_teardown(test_case_get_node_reachability_06, NULL, NULL,
953 (void *)&test_case_get_node_reachability_06_state),
954 cmocka_unit_test_prestate_setup_teardown(test_case_get_node_reachability_07, NULL, NULL,
955 (void *)&test_case_get_node_reachability_07_state),
957 total_tests += sizeof(blackbox_status_tests) / sizeof(blackbox_status_tests[0]);
959 return cmocka_run_group_tests(blackbox_status_tests, NULL, NULL);