2 test_cases_join.c -- Execution of specific meshlink black box test cases
3 Copyright (C) 2018 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"
44 #include "../../../src/devtools.h"
49 #define TEST_MESHLINK_JOIN "test_meshlink_join"
50 #define create_path(confbase, node_name, test_case_no) assert(snprintf(confbase, sizeof(confbase), TEST_MESHLINK_JOIN "_%ld_%s_%02d", (long) getpid(), node_name, test_case_no) > 0)
52 static struct sync_flag peer_reachable_status_cond = {.mutex = PTHREAD_MUTEX_INITIALIZER, .cond = PTHREAD_COND_INITIALIZER};
53 static bool peer_reachable_status;
54 static struct sync_flag nut_reachable_status_cond = {.mutex = PTHREAD_MUTEX_INITIALIZER, .cond = PTHREAD_COND_INITIALIZER};
55 static bool nut_reachable_status;
56 static struct sync_flag nut_started_status_cond = {.mutex = PTHREAD_MUTEX_INITIALIZER, .cond = PTHREAD_COND_INITIALIZER};
58 /* Node reachable status callback which signals the respective conditional varibale */
59 static void meshlink_node_reachable_status_cb(meshlink_handle_t *mesh, meshlink_node_t *node, bool reachable_status) {
60 if(!strcasecmp(mesh->name, NUT)) {
61 if(!strcasecmp(node->name, PEER)) {
62 peer_reachable_status = reachable_status;
63 set_sync_flag(&peer_reachable_status_cond, true);
65 } else if(!strcasecmp(mesh->name, PEER)) {
66 if(!strcasecmp(node->name, NUT)) {
67 nut_reachable_status = reachable_status;
68 set_sync_flag(&nut_reachable_status_cond, true);
73 /* SIGUSR2 signal handler that signals the NUT started and PEER node can join */
74 static void nut_started_user_signal_handler(int signum) {
75 if(signum == SIGUSR2) {
76 set_sync_flag(&nut_started_status_cond, true);
81 /* Test Steps for meshlink_join Test Case # 1 - Valid case
84 1. Open instances for NUT and peer, peer invites NUT and starts instance.
85 2. NUT consumes the invitation generated by peer
88 NUT joins peer using the invitation generated.
90 static void test_case_meshlink_join_01(void **state) {
92 char nut_confbase[PATH_MAX];
93 char peer_confbase[PATH_MAX];
94 create_path(nut_confbase, NUT, 1);
95 create_path(peer_confbase, PEER, 1);
96 meshlink_set_log_cb(NULL, MESHLINK_DEBUG, log_cb);
98 // Open both NUT and peer node instance, invite and join NUT with peer node.
100 meshlink_handle_t *mesh_peer = meshlink_open(peer_confbase, PEER, TEST_MESHLINK_JOIN,
101 DEV_CLASS_STATIONARY);
102 assert_non_null(mesh_peer);
103 meshlink_set_inviter_commits_first(mesh_peer, true);
104 meshlink_set_node_status_cb(mesh_peer, meshlink_node_reachable_status_cb);
105 char *invitation = meshlink_invite(mesh_peer, NULL, NUT);
106 assert_non_null(invitation);
107 assert_true(meshlink_start(mesh_peer));
109 meshlink_handle_t *mesh = meshlink_open(nut_confbase, NUT, TEST_MESHLINK_JOIN,
110 DEV_CLASS_STATIONARY);
111 assert_non_null(mesh);
112 meshlink_set_inviter_commits_first(mesh, true);
113 meshlink_set_node_status_cb(mesh, meshlink_node_reachable_status_cb);
114 assert_true(meshlink_join(mesh, invitation));
117 meshlink_node_t *peer_handle = meshlink_get_node(mesh, PEER);
118 assert_non_null(peer_handle);
119 meshlink_node_t *nut_handle = meshlink_get_node(mesh_peer, NUT);
120 assert_non_null(nut_handle);
122 // Bring nodes online.
124 set_sync_flag(&peer_reachable_status_cond, false);
125 set_sync_flag(&nut_reachable_status_cond, false);
126 assert_true(meshlink_start(mesh));
127 assert_true(wait_sync_flag(&peer_reachable_status_cond, 60));
128 assert_true(peer_reachable_status);
129 assert_true(wait_sync_flag(&nut_reachable_status_cond, 60));
130 assert_true(nut_reachable_status);
134 meshlink_close(mesh);
135 meshlink_close(mesh_peer);
136 assert_true(meshlink_destroy(nut_confbase));
137 assert_true(meshlink_destroy(peer_confbase));
141 /* Test Steps for meshlink_join Test Case # 2 - Invalid case
144 1. Call meshlink_join with NULL as mesh handler or node name argument.
147 NUT joining fails when NULL is passed as mesh handle or node name argument
149 static void test_case_meshlink_join_02(void **state) {
151 char nut_confbase[PATH_MAX];
152 char peer_confbase[PATH_MAX];
153 create_path(nut_confbase, NUT, 2);
154 create_path(peer_confbase, PEER, 2);
155 meshlink_set_log_cb(NULL, MESHLINK_DEBUG, log_cb);
157 // Open both NUT and peer node instance, invite and join NUT with peer node.
159 meshlink_handle_t *mesh_peer = meshlink_open(peer_confbase, PEER, TEST_MESHLINK_JOIN,
160 DEV_CLASS_STATIONARY);
161 assert_non_null(mesh_peer);
162 meshlink_set_node_status_cb(mesh_peer, meshlink_node_reachable_status_cb);
163 char *invitation = meshlink_invite(mesh_peer, NULL, NUT);
164 assert_non_null(invitation);
165 assert_true(meshlink_start(mesh_peer));
167 meshlink_handle_t *mesh = meshlink_open(nut_confbase, NUT, TEST_MESHLINK_JOIN,
168 DEV_CLASS_STATIONARY);
169 assert_non_null(mesh);
170 meshlink_set_node_status_cb(mesh, meshlink_node_reachable_status_cb);
172 // meshlink_join called with NULL as mesh handle and with valid invitation
174 assert_int_equal(meshlink_join(NULL, invitation), false);
175 assert_int_equal(meshlink_join(mesh, NULL), false);
180 meshlink_close(mesh);
181 meshlink_close(mesh_peer);
182 assert_true(meshlink_destroy(nut_confbase));
183 assert_true(meshlink_destroy(peer_confbase));
187 /* Test Steps for meshlink_join Test Case # 3 - Persistence testing around inviter
189 Test steps and scenarios:
190 1. Open Node-Under-Test (NUT) and invite peer node and close it's instance.
191 Spawn a process which waits for the peer node to join and raises SIGINT if the
192 appropriate callback is received (on the other hand the test suite opens and joins
193 the peer node with NUT in the forked process).
195 NUT joins peer successfully
199 static void test_case_meshlink_join_03(void **state) {
203 char nut_confbase[PATH_MAX];
204 char peer_confbase[PATH_MAX];
205 create_path(nut_confbase, NUT, 3);
206 create_path(peer_confbase, PEER, 3);
207 meshlink_set_log_cb(NULL, MESHLINK_DEBUG, log_cb);
209 // Open NUT node instance and invite peer node. Close NUT node instance.
211 meshlink_handle_t *mesh = meshlink_open(nut_confbase, NUT, TEST_MESHLINK_JOIN, DEV_CLASS_STATIONARY);
212 assert_non_null(mesh);
213 char *invitation = meshlink_invite(mesh, NULL, PEER);
214 meshlink_close(mesh);
216 // Set the SIGUSR2 signal handler with handler that signal the condition to the test suite
218 sighandler_t usr2sighandler = signal(SIGUSR2, nut_started_user_signal_handler);
219 assert_int_not_equal(usr2sighandler, SIG_ERR);
221 // Fork a new process and run NUT in it which just waits for the peer node reachable status callback
222 // and terminates the process immediately.
225 assert_int_not_equal(pid, -1);
228 assert(signal(SIGUSR2, SIG_DFL) != SIG_ERR);
230 mesh = meshlink_open(nut_confbase, NUT, TEST_MESHLINK_JOIN, DEV_CLASS_STATIONARY);
232 meshlink_set_log_cb(mesh, MESHLINK_DEBUG, log_cb);
233 meshlink_set_node_status_cb(mesh, meshlink_node_reachable_status_cb);
235 set_sync_flag(&peer_reachable_status_cond, false);
236 assert(meshlink_start(mesh));
238 assert(kill(getppid(), SIGUSR2) != -1);
240 assert(wait_sync_flag(&peer_reachable_status_cond, 60));
241 assert(peer_reachable_status);
246 // Open peer node instance and join with the invitation obtained.
248 meshlink_handle_t *mesh_peer = meshlink_open(peer_confbase, PEER, TEST_MESHLINK_JOIN,
249 DEV_CLASS_STATIONARY);
250 assert_non_null(mesh_peer);
252 // Wait for the started signal from NUT and reset the previous SIGUSR2 signal handler
254 assert_true(wait_sync_flag(&nut_started_status_cond, 60));
255 assert_int_not_equal(signal(SIGUSR2, usr2sighandler), SIG_ERR);
257 assert_true(meshlink_join(mesh_peer, invitation));
258 assert_true(meshlink_start(mesh_peer));
260 // Wait for child exit and verify which signal terminated it
262 assert_int_not_equal(waitpid(pid, &pid_status, 0), -1);
263 assert_int_equal(WIFSIGNALED(pid_status), true);
264 assert_int_equal(WTERMSIG(pid_status), SIGINT);
266 // Reopen the NUT instance in the same test suite
268 mesh = meshlink_open(nut_confbase, NUT, TEST_MESHLINK_JOIN, DEV_CLASS_STATIONARY);
269 assert_non_null(mesh);
271 assert_non_null(meshlink_get_node(mesh, PEER));
275 meshlink_close(mesh);
276 meshlink_close(mesh_peer);
277 assert_true(meshlink_destroy(nut_confbase));
278 assert_true(meshlink_destroy(peer_confbase));
282 /* Test Steps for meshlink_get_node_reachability Test Case # 4 - Persistence testing around invitee
284 Test steps and scenarios:
285 1. Open peer node instance, invite NUT and start peer node. Spawn a new process in
286 which it opens and joins the NUT with peer node.
287 Reopen NUT instance in the test suite process and verify peer is joined.
289 NUT joins peer successfully
292 static void test_case_meshlink_join_04(void **state) {
296 char nut_confbase[PATH_MAX];
297 char peer_confbase[PATH_MAX];
298 create_path(nut_confbase, NUT, 4);
299 create_path(peer_confbase, PEER, 4);
300 meshlink_set_log_cb(NULL, MESHLINK_DEBUG, log_cb);
302 // Open peer node instance and invite NUT.
304 meshlink_handle_t *mesh_peer = meshlink_open(peer_confbase, PEER, TEST_MESHLINK_JOIN,
305 DEV_CLASS_STATIONARY);
306 assert_int_not_equal(mesh_peer, NULL);
307 char *invitation = meshlink_invite(mesh_peer, NULL, NUT);
308 assert_non_null(invitation);
310 assert_true(meshlink_start(mesh_peer));
312 // Fork a new process in which NUT is joins with the peer node and raises SIGINT to terminate.
315 assert_int_not_equal(pid, -1);
318 meshlink_handle_t *mesh = meshlink_open(nut_confbase, NUT, TEST_MESHLINK_JOIN, DEV_CLASS_STATIONARY);
320 meshlink_set_log_cb(mesh, MESHLINK_DEBUG, log_cb);
322 assert(meshlink_join(mesh, invitation));
327 // Wait for child exit and verify which signal terminated it
329 assert_int_not_equal(waitpid(pid, &pid_status, 0), -1);
330 assert_int_equal(WIFSIGNALED(pid_status), true);
331 assert_int_equal(WTERMSIG(pid_status), SIGINT);
333 // Reopen the NUT instance in the same test suite
335 meshlink_handle_t *mesh = meshlink_open(nut_confbase, NUT, TEST_MESHLINK_JOIN, DEV_CLASS_STATIONARY);
336 assert_non_null(mesh);
338 assert_non_null(meshlink_get_node(mesh, PEER));
342 meshlink_close(mesh);
343 meshlink_close(mesh_peer);
344 assert_true(meshlink_destroy(nut_confbase));
345 assert_true(meshlink_destroy(peer_confbase));
349 static void nop_stage(bool stage) {
354 static void debug_probe(bool stage) {
360 /* Test Steps for meshlink_get_node_reachability Test Case # 5 - Test the invitee committing first scenario
362 Test steps and scenarios:
363 1. Open peer node instance, invite NUT and start peer node. Enable the debug probe, Spawn a new process in
364 which it opens and joins the NUT with peer node which terminates the NUT while joining.
365 Reopen NUT instance in the test suite process and verify peer is joined.
367 NUT(invitee) commits the config file(s) first but peer is unaware of NUT.
370 static void test_case_meshlink_join_05(void **state) {
374 char nut_confbase[PATH_MAX];
375 char peer_confbase[PATH_MAX];
376 create_path(nut_confbase, NUT, 5);
377 create_path(peer_confbase, PEER, 5);
378 meshlink_set_log_cb(NULL, MESHLINK_DEBUG, log_cb);
380 assert(signal(SIGINT, SIG_DFL) != SIG_ERR);
381 assert(signal(SIGABRT, SIG_DFL) != SIG_ERR);
383 // Set debug_probe callback
385 devtool_set_inviter_commits_first = debug_probe;
387 // Open peer node instance and invite NUT.
389 meshlink_handle_t *mesh_peer = meshlink_open(peer_confbase, PEER, TEST_MESHLINK_JOIN,
390 DEV_CLASS_STATIONARY);
391 assert_int_not_equal(mesh_peer, NULL);
392 meshlink_set_inviter_commits_first(mesh_peer, false);
393 char *invitation = meshlink_invite(mesh_peer, NULL, NUT);
394 assert_non_null(invitation);
396 assert_true(meshlink_start(mesh_peer));
398 // Fork a new process in which NUT is joins with the peer node and raises SIGINT to terminate.
401 assert_int_not_equal(pid, -1);
404 meshlink_handle_t *mesh = meshlink_open(nut_confbase, NUT, TEST_MESHLINK_JOIN, DEV_CLASS_STATIONARY);
406 meshlink_set_inviter_commits_first(mesh_peer, false);
407 meshlink_set_log_cb(mesh, MESHLINK_DEBUG, log_cb);
409 assert_true(meshlink_join(mesh, invitation));
414 // Wait for child exit and verify which signal terminated it
416 assert_int_not_equal(waitpid(pid, &pid_status, 0), -1);
417 assert_int_equal(WIFSIGNALED(pid_status), true);
418 assert_int_equal(WTERMSIG(pid_status), SIGINT);
420 // Reopen the NUT instance in the same test suite
422 meshlink_handle_t *mesh = meshlink_open(nut_confbase, NUT, TEST_MESHLINK_JOIN, DEV_CLASS_STATIONARY);
423 assert_non_null(mesh);
425 // Invitee committed host config file but invitee should not
427 assert_non_null(meshlink_get_node(mesh, PEER));
428 assert_null(meshlink_get_node(mesh_peer, NUT));
433 meshlink_close(mesh);
434 meshlink_close(mesh_peer);
435 assert_true(meshlink_destroy(nut_confbase));
436 assert_true(meshlink_destroy(peer_confbase));
438 devtool_set_inviter_commits_first = nop_stage;
442 /* Test Steps for meshlink_get_node_reachability Test Case # 6 - Test the inviter committing first scenario
444 Test steps and scenarios:
445 1. Open NUT node instance, invite peer and close the instance. Enable the debug probe, Spawn a new process in
446 which it starts the NUT instance. At the parents/test vector thread wait for the signal that NUT raises after starting
447 and join peer with NUT. NUT terminates in debug probe after committing into the disk
448 Reopen NUT instance in the test suite process and verify peer is joined.
450 NUT(inviter) commits the config file(s) first but peer is unaware of NUT.
453 static void test_case_meshlink_join_06(void **state) {
457 char nut_confbase[PATH_MAX];
458 char peer_confbase[PATH_MAX];
459 create_path(nut_confbase, NUT, 6);
460 create_path(peer_confbase, PEER, 6);
461 meshlink_set_log_cb(NULL, MESHLINK_DEBUG, log_cb);
463 assert(signal(SIGINT, SIG_DFL) != SIG_ERR);
464 assert(signal(SIGABRT, SIG_DFL) != SIG_ERR);
466 // Set debug_probe callback
468 devtool_set_inviter_commits_first = debug_probe;
470 // Open NUT node instance and invite peer node. Close NUT node instance.
472 meshlink_handle_t *mesh = meshlink_open(nut_confbase, NUT, TEST_MESHLINK_JOIN, DEV_CLASS_STATIONARY);
473 assert_non_null(mesh);
474 meshlink_set_inviter_commits_first(mesh, true);
475 char *invitation = meshlink_invite(mesh, NULL, PEER);
476 meshlink_close(mesh);
478 // Set the SIGUSR2 signal handler with handler that signal the condition to the test suite
480 sighandler_t usr2sighandler = signal(SIGUSR2, nut_started_user_signal_handler);
481 assert_int_not_equal(usr2sighandler, SIG_ERR);
482 set_sync_flag(&peer_reachable_status_cond, false);
484 // Fork a new process and run NUT in it which just waits for the peer node reachable status callback
485 // and terminates the process immediately.
488 assert_int_not_equal(pid, -1);
491 assert(signal(SIGUSR2, SIG_DFL) != SIG_ERR);
493 mesh = meshlink_open(nut_confbase, NUT, TEST_MESHLINK_JOIN, DEV_CLASS_STATIONARY);
495 meshlink_set_inviter_commits_first(mesh, true);
496 meshlink_set_log_cb(mesh, MESHLINK_DEBUG, log_cb);
497 meshlink_set_node_status_cb(mesh, meshlink_node_reachable_status_cb);
499 assert(meshlink_start(mesh));
501 assert(kill(getppid(), SIGUSR2) != -1);
508 // Open peer node instance and join with the invitation obtained.
510 meshlink_handle_t *mesh_peer = meshlink_open(peer_confbase, PEER, TEST_MESHLINK_JOIN,
511 DEV_CLASS_STATIONARY);
512 assert_non_null(mesh_peer);
513 meshlink_set_inviter_commits_first(mesh_peer, true);
515 // Wait for the started signal from NUT and reset the previous SIGUSR2 signal handler
517 assert_true(wait_sync_flag(&nut_started_status_cond, 60));
518 assert_int_not_equal(signal(SIGUSR2, usr2sighandler), SIG_ERR);
520 assert_false(meshlink_join(mesh_peer, invitation));
522 // Wait for child exit and verify which signal terminated it
524 assert_int_not_equal(waitpid(pid, &pid_status, 0), -1);
525 assert_int_equal(WIFSIGNALED(pid_status), true);
526 assert_int_equal(WTERMSIG(pid_status), SIGINT);
528 // Reopen the NUT instance in the same test suite
530 mesh = meshlink_open(nut_confbase, NUT, TEST_MESHLINK_JOIN, DEV_CLASS_STATIONARY);
531 assert_non_null(mesh);
533 // Inviter should first commit config file(s) into the disk
535 assert_null(meshlink_get_node(mesh_peer, NUT));
536 assert_non_null(meshlink_get_node(mesh, PEER));
541 meshlink_close(mesh);
542 meshlink_close(mesh_peer);
543 assert_true(meshlink_destroy(nut_confbase));
544 assert_true(meshlink_destroy(peer_confbase));
545 devtool_set_inviter_commits_first = nop_stage;
549 /* Test Steps for meshlink_join Test Case # 7 - Inviter sets that invitee should commit first,
550 even invitee sets that inviter should commit first.
553 1. Open instances for NUT and peer, peer invites NUT and starts instance.
554 Both the instances sets meshlink_set_inviter_commits_first API mutually exclusively
555 NUT tries to consume the invitation generated by peer
558 NUT fails to join peer using the invitation generated.
560 static void test_case_meshlink_join_07(void **state) {
562 char nut_confbase[PATH_MAX];
563 char peer_confbase[PATH_MAX];
564 create_path(nut_confbase, NUT, 7);
565 create_path(peer_confbase, PEER, 7);
566 meshlink_set_log_cb(NULL, MESHLINK_DEBUG, log_cb);
568 // Open both NUT and peer node instance, invite and join NUT with peer node.
570 meshlink_handle_t *mesh_peer = meshlink_open(peer_confbase, PEER, TEST_MESHLINK_JOIN,
571 DEV_CLASS_STATIONARY);
572 assert_non_null(mesh_peer);
573 meshlink_set_inviter_commits_first(mesh_peer, false);
574 meshlink_set_node_status_cb(mesh_peer, meshlink_node_reachable_status_cb);
575 char *invitation = meshlink_invite(mesh_peer, NULL, NUT);
576 assert_non_null(invitation);
577 assert_true(meshlink_start(mesh_peer));
579 meshlink_handle_t *mesh = meshlink_open(nut_confbase, NUT, TEST_MESHLINK_JOIN,
580 DEV_CLASS_STATIONARY);
581 assert_non_null(mesh);
582 meshlink_set_inviter_commits_first(mesh, true);
583 meshlink_set_node_status_cb(mesh, meshlink_node_reachable_status_cb);
584 assert_false(meshlink_join(mesh, invitation));
587 meshlink_node_t *peer_handle = meshlink_get_node(mesh, PEER);
588 assert_null(peer_handle);
589 meshlink_node_t *nut_handle = meshlink_get_node(mesh_peer, NUT);
590 assert_null(nut_handle);
594 meshlink_close(mesh);
595 meshlink_close(mesh_peer);
596 assert_true(meshlink_destroy(nut_confbase));
597 assert_true(meshlink_destroy(peer_confbase));
601 /* Test Steps for meshlink_join Test Case # 8 - Inviter sets that it should commit first,
602 even invitee sets that it should commit first
605 1. Open instances for NUT and peer, peer invites NUT and starts instance.
606 Both the instances sets meshlink_set_inviter_commits_first API mutually exclusively
607 NUT tries to consume the invitation generated by peer
610 NUT fails to join peer using the invitation generated.
612 static void test_case_meshlink_join_08(void **state) {
614 char nut_confbase[PATH_MAX];
615 char peer_confbase[PATH_MAX];
616 create_path(nut_confbase, NUT, 8);
617 create_path(peer_confbase, PEER, 8);
618 meshlink_set_log_cb(NULL, MESHLINK_DEBUG, log_cb);
620 // Open both NUT and peer node instance, invite and join NUT with peer node.
622 meshlink_handle_t *mesh_peer = meshlink_open(peer_confbase, PEER, TEST_MESHLINK_JOIN,
623 DEV_CLASS_STATIONARY);
624 assert_non_null(mesh_peer);
625 meshlink_set_inviter_commits_first(mesh_peer, true);
626 meshlink_set_node_status_cb(mesh_peer, meshlink_node_reachable_status_cb);
627 char *invitation = meshlink_invite(mesh_peer, NULL, NUT);
628 assert_non_null(invitation);
629 assert_true(meshlink_start(mesh_peer));
631 meshlink_handle_t *mesh = meshlink_open(nut_confbase, NUT, TEST_MESHLINK_JOIN,
632 DEV_CLASS_STATIONARY);
633 assert_non_null(mesh);
634 meshlink_set_inviter_commits_first(mesh, false);
635 meshlink_set_node_status_cb(mesh, meshlink_node_reachable_status_cb);
636 assert_false(meshlink_join(mesh, invitation));
639 meshlink_node_t *peer_handle = meshlink_get_node(mesh, PEER);
640 assert_null(peer_handle);
641 meshlink_node_t *nut_handle = meshlink_get_node(mesh_peer, NUT);
642 assert_null(nut_handle);
646 meshlink_close(mesh);
647 meshlink_close(mesh_peer);
648 assert_true(meshlink_destroy(nut_confbase));
649 assert_true(meshlink_destroy(peer_confbase));
653 /* Test Steps for meshlink_join Test Case # 9 - Invitee already started its instance
656 1. Open instances for NUT and peer, peer invites NUT and both the instances starts their instances.
657 NUT tries to join the peer with the generated invitation.
660 NUT fails to join peer using the invitation generated.
662 static void test_case_meshlink_join_09(void **state) {
664 char nut_confbase[PATH_MAX];
665 char peer_confbase[PATH_MAX];
666 create_path(nut_confbase, NUT, 9);
667 create_path(peer_confbase, PEER, 9);
668 meshlink_set_log_cb(NULL, MESHLINK_DEBUG, log_cb);
670 // Open both NUT and peer node instance, invite and join NUT with peer node.
672 meshlink_handle_t *mesh_peer = meshlink_open(peer_confbase, PEER, TEST_MESHLINK_JOIN,
673 DEV_CLASS_STATIONARY);
674 assert_non_null(mesh_peer);
675 meshlink_set_node_status_cb(mesh_peer, meshlink_node_reachable_status_cb);
676 char *invitation = meshlink_invite(mesh_peer, NULL, NUT);
677 assert_non_null(invitation);
678 assert_true(meshlink_start(mesh_peer));
680 meshlink_handle_t *mesh = meshlink_open(nut_confbase, NUT, TEST_MESHLINK_JOIN,
681 DEV_CLASS_STATIONARY);
682 assert_non_null(mesh);
683 meshlink_set_node_status_cb(mesh, meshlink_node_reachable_status_cb);
685 assert_true(meshlink_start(mesh));
687 assert_false(meshlink_join(mesh, invitation));
690 meshlink_node_t *peer_handle = meshlink_get_node(mesh, PEER);
691 assert_null(peer_handle);
692 meshlink_node_t *nut_handle = meshlink_get_node(mesh_peer, NUT);
693 assert_null(nut_handle);
697 meshlink_close(mesh);
698 meshlink_close(mesh_peer);
699 assert_true(meshlink_destroy(nut_confbase));
700 assert_true(meshlink_destroy(peer_confbase));
704 /* Test Steps for meshlink_join Test Case # 10 - Invitee already joined in a mesh
707 1. Open instances for NUT, peer2 and peer, peer invites NUT. Peer2 and NUT both mutually imports data
708 i.e, both formed or joined the mesh.
709 NUT tries to join the peer with the generated invitation.
712 NUT fails to join peer using the invitation generated.
714 static void test_case_meshlink_join_10(void **state) {
716 char nut_confbase[PATH_MAX];
717 char peer_confbase[PATH_MAX];
718 char peer_confbase2[PATH_MAX];
719 create_path(nut_confbase, NUT, 10);
720 create_path(peer_confbase, PEER, 10);
721 create_path(peer_confbase2, PEER2, 10);
722 meshlink_set_log_cb(NULL, MESHLINK_DEBUG, log_cb);
724 // Open both NUT and peer node instance, invite and join NUT with peer node.
726 meshlink_handle_t *mesh_peer = meshlink_open(peer_confbase, PEER, TEST_MESHLINK_JOIN,
727 DEV_CLASS_STATIONARY);
728 assert_non_null(mesh_peer);
729 meshlink_set_node_status_cb(mesh_peer, meshlink_node_reachable_status_cb);
730 char *invitation = meshlink_invite(mesh_peer, NULL, NUT);
731 assert_non_null(invitation);
732 assert_true(meshlink_start(mesh_peer));
734 meshlink_handle_t *mesh_peer2 = meshlink_open(peer_confbase2, PEER2, TEST_MESHLINK_JOIN,
735 DEV_CLASS_STATIONARY);
736 assert_non_null(mesh_peer2);
737 meshlink_handle_t *mesh = meshlink_open(nut_confbase, NUT, TEST_MESHLINK_JOIN,
738 DEV_CLASS_STATIONARY);
739 assert_non_null(mesh);
740 meshlink_set_node_status_cb(mesh, meshlink_node_reachable_status_cb);
742 char *data = meshlink_export(mesh);
743 assert_non_null(data);
744 assert_true(meshlink_import(mesh_peer2, data));
746 data = meshlink_export(mesh_peer2);
747 assert_non_null(data);
748 assert_true(meshlink_import(mesh, data));
751 assert_true(meshlink_start(mesh));
753 assert_false(meshlink_join(mesh, invitation));
756 meshlink_node_t *peer_handle = meshlink_get_node(mesh, PEER);
757 assert_null(peer_handle);
758 meshlink_node_t *nut_handle = meshlink_get_node(mesh_peer, NUT);
759 assert_null(nut_handle);
763 meshlink_close(mesh);
764 meshlink_close(mesh_peer);
765 assert_true(meshlink_destroy(nut_confbase));
766 assert_true(meshlink_destroy(peer_confbase));
770 int test_meshlink_join(void) {
771 const struct CMUnitTest blackbox_join_tests[] = {
772 cmocka_unit_test(test_case_meshlink_join_01),
773 cmocka_unit_test(test_case_meshlink_join_02),
774 cmocka_unit_test(test_case_meshlink_join_03),
775 cmocka_unit_test(test_case_meshlink_join_04),
776 cmocka_unit_test(test_case_meshlink_join_05),
777 cmocka_unit_test(test_case_meshlink_join_06),
778 cmocka_unit_test(test_case_meshlink_join_07),
779 cmocka_unit_test(test_case_meshlink_join_08),
780 cmocka_unit_test(test_case_meshlink_join_09),
781 cmocka_unit_test(test_case_meshlink_join_10)
783 total_tests += sizeof(blackbox_join_tests) / sizeof(blackbox_join_tests[0]);
785 int failed = cmocka_run_group_tests(blackbox_join_tests, NULL, NULL);