2 test_cases_channel_conn.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.
27 #include "execute_tests.h"
28 #include "test_cases_channel_conn.h"
29 #include "../common/containers.h"
30 #include "../common/test_step.h"
31 #include "../common/common_handlers.h"
32 #include "../common/mesh_event_handler.h"
38 static void test_case_channel_conn_01(void **state);
39 static bool test_steps_channel_conn_01(void);
40 static void test_case_channel_conn_02(void **state);
41 static bool test_steps_channel_conn_02(void);
42 static void test_case_channel_conn_03(void **state);
43 static bool test_steps_channel_conn_03(void);
44 static void test_case_channel_conn_04(void **state);
45 static bool test_steps_channel_conn_04(void);
46 static void test_case_channel_conn_05(void **state);
47 static bool test_steps_channel_conn_05(void);
48 static void test_case_channel_conn_06(void **state);
49 static bool test_steps_channel_conn_06(void);
50 static void test_case_channel_conn_07(void **state);
51 static bool test_steps_channel_conn_07(void);
52 static void test_case_channel_conn_08(void **state);
53 static bool test_steps_channel_conn_08(void);
55 static char *test_channel_conn_2_nodes[] = { "peer", "nut" };
56 static char *test_channel_conn_3_nodes[] = { "peer", "nut", "relay" };
58 static black_box_state_t test_case_channel_conn_01_state = {
59 .test_case_name = "test_case_channel_conn_01",
60 .node_names = test_channel_conn_2_nodes,
63 static black_box_state_t test_case_channel_conn_02_state = {
64 .test_case_name = "test_case_channel_conn_02",
65 .node_names = test_channel_conn_2_nodes,
68 static black_box_state_t test_case_channel_conn_03_state = {
69 .test_case_name = "test_case_channel_conn_03",
70 .node_names = test_channel_conn_2_nodes,
73 static black_box_state_t test_case_channel_conn_04_state = {
74 .test_case_name = "test_case_channel_conn_04",
75 .node_names = test_channel_conn_2_nodes,
78 static black_box_state_t test_case_channel_conn_05_state = {
79 .test_case_name = "test_case_channel_conn_05",
80 .node_names = test_channel_conn_3_nodes,
83 static black_box_state_t test_case_channel_conn_06_state = {
84 .test_case_name = "test_case_channel_conn_06",
85 .node_names = test_channel_conn_3_nodes,
88 static black_box_state_t test_case_channel_conn_07_state = {
89 .test_case_name = "test_case_channel_conn_07",
90 .node_names = test_channel_conn_3_nodes,
93 static black_box_state_t test_case_channel_conn_08_state = {
94 .test_case_name = "test_case_channel_conn_08",
95 .node_names = test_channel_conn_3_nodes,
100 static bool channel_opened;
101 static bool node_restarted;
102 static bool received_error;
103 static bool channel_received;
104 static bool node_reachable;
105 static bool node_unreachable;
107 /* Callback function for handling channel connection test cases mesh events */
108 static bool channel_conn_cb(mesh_event_payload_t payload) {
109 switch(payload.mesh_event) {
114 case CHANNEL_OPENED :
115 channel_opened = true;
118 case NODE_RESTARTED :
119 node_restarted = true;
123 received_error = true;
126 case CHANNEL_DATA_RECIEVED :
127 channel_received = true;
130 case NODE_UNREACHABLE :
131 node_unreachable = true;
134 case NODE_REACHABLE :
135 node_reachable = true;
139 PRINT_TEST_CASE_MSG("Undefined event occurred\n");
145 /* Execute channel connections Test Case # 1 - simulate a temporary network
146 failure of about 30 seconds, messages sent while the network was down
147 should be received by the other side after the network comes up again. */
148 static void test_case_channel_conn_01(void **state) {
149 execute_test(test_steps_channel_conn_01, state);
153 /* Test Steps for channel connections Test Case # 1
156 1. Run NUT & peer node instances and open a channel between them
157 2. Simulate a network failure in NUT's container for about 30 secs,
158 meanwhile send data via channel from NUT to peer.
159 3. After restoring network, peer node receive's data via channel.
162 Peer node receives data via channel without any error after restoring network.
164 static bool test_steps_channel_conn_01(void) {
169 channel_opened = false;
170 channel_received = false;
174 install_in_container("nut", "iptables");
175 accept_port_rule("nut", "OUTPUT", "udp", 9000);
176 import = mesh_event_sock_create(eth_if_name);
177 invite_nut = invite_in_container("peer", "nut");
180 // Run node instances in containers & open a channel
182 node_sim_in_container_event("peer", "1", NULL, PEER_ID, import);
183 node_sim_in_container_event("nut", "1", invite_nut, NUT_ID, import);
185 wait_for_event(channel_conn_cb, 30);
186 assert_int_equal(joined, true);
188 wait_for_event(channel_conn_cb, 30);
189 assert_int_equal(channel_opened, true);
191 // Simulate network failure in NUT's LXC container with it's IP address as NAT rule
193 block_node_ip("nut");
196 // Sending SIGUSR1 signal to node-under-test indicating the network failure
198 node_step_in_container("nut", "SIGUSR1");
201 // Restore NUT's network
203 unblock_node_ip("nut");
205 // Wait for peer node to receive data via channel from NUT
207 wait_for_event(channel_conn_cb, 60);
209 mesh_event_destroy();
213 assert_int_equal(channel_received, true);
218 /* Execute channel connections Test Case # 2 - a simulated network failure
219 of more than 1 minute, and sending messages over the channel during the
220 failure. Then after about 1 minute, the channel should receive an error */
221 static void test_case_channel_conn_02(void **state) {
222 execute_test(test_steps_channel_conn_02, state);
226 /* Test Steps for channel connections Test Case # 2
229 1. Run NUT and peer node instances in containers and open a channel between them.
230 2. Create a network failure for about 90 secs in NUT container
231 and signal NUT node about the network failure.
232 3. Meanwhile NUT sends data to peer via channel and restore the network after
236 Peer node should receive error closing the channel after channel timeout(60 secs).
238 static bool test_steps_channel_conn_02(void) {
243 channel_opened = false;
244 received_error = false;
248 install_in_container("nut", "iptables");
249 accept_port_rule("nut", "OUTPUT", "udp", 9000);
250 import = mesh_event_sock_create(eth_if_name);
251 invite_nut = invite_in_container("peer", "nut");
254 // Run NUT and peer node instances in containers & open a channel
256 node_sim_in_container_event("peer", "1", NULL, PEER_ID, import);
257 node_sim_in_container_event("nut", "1", invite_nut, NUT_ID, import);
259 wait_for_event(channel_conn_cb, 30);
260 assert_int_equal(joined, true);
262 wait_for_event(channel_conn_cb, 10);
263 assert_int_equal(channel_opened, true);
265 // Simulate network failure in NUT's LXC container with it's IP address as NAT rule
267 block_node_ip("nut");
269 // Sending SIGUSR1 signal to node-under-test indicating the network failure
271 node_step_in_container("nut", "SIGUSR1");
274 // Restore NUT containers network after 90 secs
276 unblock_node_ip("nut");
278 // Wait for peer node to send the event about the channel error occurred with length = 0
280 wait_for_event(channel_conn_cb, 90);
282 mesh_event_destroy();
286 assert_int_equal(received_error, true);
291 /* Execute channel connections Test Case # 3 - a simulated network failure
292 once node instance is made offline restore the network and send data via
294 static void test_case_channel_conn_03(void **state) {
295 execute_test(test_steps_channel_conn_03, state);
299 /* Test Steps for channel connections Test Case # 3
302 1. Run NUT and peer node instances and open a channel between them.
303 2. Create a network failure in NUT container, bring NUT node offline
304 and receive the status at test driver and restore the network
305 3. After peer node instance is reachable to NUT node send data via channel
308 Peer node should receive data from NUT without any error.
310 static bool test_steps_channel_conn_03(void) {
315 channel_opened = false;
316 node_unreachable = false;
317 node_reachable = false;
318 channel_received = false;
322 install_in_container("nut", "iptables");
323 accept_port_rule("nut", "OUTPUT", "udp", 9000);
324 import = mesh_event_sock_create(eth_if_name);
325 invite_nut = invite_in_container("peer", "nut");
328 // Run NUT and peer node instances in containers & open a channel
330 node_sim_in_container_event("peer", "1", NULL, PEER_ID, import);
331 node_sim_in_container_event("nut", "1", invite_nut, NUT_ID, import);
333 wait_for_event(channel_conn_cb, 30);
334 assert_int_equal(joined, true);
336 wait_for_event(channel_conn_cb, 10);
337 assert_int_equal(channel_opened, true);
339 // Simulate network failure in NUT's LXC container with it's IP address as NAT rule
341 node_reachable = false;
342 block_node_ip("nut");
344 // Sending SIGUSR1 signal to node-under-test indicating the network failure
346 node_step_in_container("nut", "SIGUSR1");
348 // Wait for the node status to become unreachable
350 wait_for_event(channel_conn_cb, 100);
351 assert_int_equal(node_unreachable, true);
353 // Restore NUT container's network
355 unblock_node_ip("nut");
357 // Wait for the node status to become reachable
359 wait_for_event(channel_conn_cb, 100);
360 assert_int_equal(node_reachable, true);
362 // Wait for data to be received at peer via channel from NUT after restoring n/w
364 wait_for_event(channel_conn_cb, 90);
366 mesh_event_destroy();
370 assert_int_equal(channel_received, true);
375 /* Execute channel connections Test Case # 4 - receiving an error when node-under-test
376 tries to send data on channel to peer node after peer node stops and starts the
378 static void test_case_channel_conn_04(void **state) {
379 execute_test(test_steps_channel_conn_04, state);
383 /* Test Steps for Meta-connections Test Case # 4
386 1. Run peer and NUT node instances in containers and open a channel between them.
387 2. Stop and start the NUT node instance and wait for about > 60 secs.
388 3. Send data via channel from Peer node and wait for event in test driver.
391 Peer node should receive error(as length = 0) in receive callback of peer node's instance.
393 static bool test_steps_channel_conn_04(void) {
398 channel_opened = false;
399 node_restarted = false;
400 received_error = false;
401 import = mesh_event_sock_create(eth_if_name);
402 invite_nut = invite_in_container("peer", "nut");
405 // Run NUT and peer node instances in containers and open a channel
407 node_sim_in_container_event("peer", "1", NULL, PEER_ID, import);
408 node_sim_in_container_event("nut", "1", invite_nut, NUT_ID, import);
410 wait_for_event(channel_conn_cb, 10);
411 assert_int_equal(joined, true);
413 wait_for_event(channel_conn_cb, 10);
414 assert_int_equal(channel_opened, true);
416 // Wait for NUT node instance to stop and start
418 wait_for_event(channel_conn_cb, 60);
419 assert_int_equal(node_restarted, true);
423 // After 1 min the channel between NUT and peer should result in error
425 wait_for_event(channel_conn_cb, 10);
428 mesh_event_destroy();
432 assert_int_equal(received_error, true);
437 /* Execute channel connections Test Case # 5 - simulate a temporary network
438 failure of about 30 seconds, messages sent while the network was down
439 should be received by the other side after the network comes up again. */
440 static void test_case_channel_conn_05(void **state) {
441 execute_test(test_steps_channel_conn_05, state);
445 /* Test Steps for channel connections Test Case # 5
448 1. Run NUT, relay & peer node instances with relay inviting NUT and peer
449 and open a channel between them
450 2. Simulate a network failure in NUT's container for about 30 secs,
451 meanwhile send data via channel from NUT to peer.
452 3. After restoring network, peer node receive's data via channel.
455 Peer node receives data via channel without any error after restoring network.
457 static bool test_steps_channel_conn_05(void) {
458 char *invite_nut, *invite_peer;
462 channel_opened = false;
463 channel_received = false;
467 install_in_container("nut", "iptables");
468 accept_port_rule("nut", "OUTPUT", "udp", 9000);
469 import = mesh_event_sock_create(eth_if_name);
470 invite_peer = invite_in_container("relay", "peer");
471 invite_nut = invite_in_container("relay", "nut");
475 // Run node instances and open a channel between NUT and peer nodes
477 node_sim_in_container_event("relay", "1", NULL, RELAY_ID, import);
478 node_sim_in_container_event("peer", "1", invite_peer, PEER_ID, import);
479 node_sim_in_container_event("nut", "1", invite_nut, NUT_ID, import);
481 wait_for_event(channel_conn_cb, 30);
482 assert_int_equal(joined, true);
484 wait_for_event(channel_conn_cb, 30);
485 assert_int_equal(channel_opened, true);
487 // Create a network failure in NUT node's container with it's IP address
489 block_node_ip("nut");
491 // Sending SIGUSR1 signal to node-under-test indicating the network failure
493 node_step_in_container("nut", "SIGUSR1");
496 // Restore the network
498 unblock_node_ip("nut");
500 // Wait for peer to get data from NUT node via channel after restoring network in < 60 secs
502 wait_for_event(channel_conn_cb, 60);
504 mesh_event_destroy();
509 assert_int_equal(channel_received, true);
514 /* Execute channel connections Test Case # 6 - a simulated network failure
515 of more than 1 minute, and sending messages over the channel during the
516 failure. Then after about 1 minute, the channel should receive an error */
517 static void test_case_channel_conn_06(void **state) {
518 execute_test(test_steps_channel_conn_06, state);
522 /* Test Steps for channel connections Test Case # 6
525 1. Run NUT, relay & peer node instances with relay inviting NUT and peer
526 and open a channel between them
527 2. Create a network failure for about 90 secs in NUT container
528 and signal NUT node about the network failure.
529 3. Meanwhile NUT sends data to peer via channel and restore the network after
533 Peer node should receive error closing the channel after channel timeout(60 secs).
535 static bool test_steps_channel_conn_06(void) {
536 char *invite_nut, *invite_peer;
540 channel_opened = false;
541 received_error = false;
545 install_in_container("nut", "iptables");
546 accept_port_rule("nut", "OUTPUT", "udp", 9000);
547 import = mesh_event_sock_create(eth_if_name);
548 invite_peer = invite_in_container("relay", "peer");
550 invite_nut = invite_in_container("relay", "nut");
553 // Run nodes in containers and open a channel between NUt and peer
555 node_sim_in_container_event("relay", "1", NULL, RELAY_ID, import);
556 node_sim_in_container_event("peer", "1", invite_peer, PEER_ID, import);
557 node_sim_in_container_event("nut", "1", invite_nut, NUT_ID, import);
559 wait_for_event(channel_conn_cb, 30);
560 assert_int_equal(joined, true);
562 wait_for_event(channel_conn_cb, 10);
563 assert_int_equal(channel_opened, true);
565 // Simulate a network failure in NUT's container for > 60 secs
567 block_node_ip("nut");
569 // Sending SIGUSR1 signal to node-under-test indicating the network failure
571 node_step_in_container("nut", "SIGUSR1");
574 // Restore the network after 90 secs
576 unblock_node_ip("nut");
578 // Wait for channel to receive error and receive the event
580 wait_for_event(channel_conn_cb, 90);
582 mesh_event_destroy();
587 assert_int_equal(received_error, true);
592 /* Execute channel connections Test Case # 7 - a simulated network failure
593 once node instance is made offline restore the network and send data via
595 static void test_case_channel_conn_07(void **state) {
596 execute_test(test_steps_channel_conn_07, state);
600 /* Test Steps for channel connections Test Case # 7
603 1. Run NUT, relay & peer node instances with relay inviting NUT and peer
604 and open a channel between them
605 2. Create a network failure in NUT container, bring NUT node offline
606 and receive the status at test driver and restore the network
607 3. After peer node instance is reachable to NUT node send data via channel
610 Peer node should receive data from NUT without any error.
612 static bool test_steps_channel_conn_07(void) {
613 char *invite_nut, *invite_peer;
617 channel_opened = false;
618 node_unreachable = false;
619 node_reachable = false;
620 channel_received = false;
624 install_in_container("nut", "iptables");
625 accept_port_rule("nut", "OUTPUT", "udp", 9000);
626 import = mesh_event_sock_create(eth_if_name);
627 invite_peer = invite_in_container("relay", "peer");
628 invite_nut = invite_in_container("relay", "nut");
632 // Run nodes and open a channel
634 node_sim_in_container_event("relay", "1", NULL, RELAY_ID, import);
635 node_sim_in_container_event("peer", "1", invite_peer, PEER_ID, import);
636 node_sim_in_container_event("nut", "1", invite_nut, NUT_ID, import);
638 wait_for_event(channel_conn_cb, 30);
639 assert_int_equal(joined, true);
641 wait_for_event(channel_conn_cb, 15);
642 assert_int_equal(channel_opened, true);
644 // Simulate a network failure
646 node_reachable = false;
647 block_node_ip("nut");
649 // Sending SIGUSR1 signal to node-under-test indicating the network failure
651 node_step_in_container("nut", "SIGUSR1");
653 // Wait for node to become unreachable
655 wait_for_event(channel_conn_cb, 100);
656 assert_int_equal(node_unreachable, true);
658 // Restore the network
660 unblock_node_ip("nut");
662 // Wait for node to become reachable after restoring n/w
664 wait_for_event(channel_conn_cb, 100);
665 assert_int_equal(node_reachable, true);
667 // Wait for peer node to receive data via channel without any error
669 wait_for_event(channel_conn_cb, 90);
671 mesh_event_destroy();
676 assert_int_equal(channel_received, true);
681 /* Execute channel connections Test Case # 8 - receiving an error when node-under-test
682 tries to send data on channel to peer node after peer node stops and starts the
684 static void test_case_channel_conn_08(void **state) {
685 execute_test(test_steps_channel_conn_08, state);
689 /* Test Steps for Meta-connections Test Case # 8
692 1. Run NUT, relay & peer node instances with relay inviting NUT and peer
693 and open a channel between them
694 2. Stop and start the NUT node instance and wait for about > 60 secs.
695 3. Send data via channel from Peer node and wait for event in test driver.
698 Peer node should receive error(as length = 0) in receive callback of peer node's instance.
700 static bool test_steps_channel_conn_08(void) {
701 char *invite_nut, *invite_peer;
705 channel_opened = false;
706 node_restarted = false;
707 received_error = false;
711 import = mesh_event_sock_create(eth_if_name);
712 invite_peer = invite_in_container("relay", "peer");
713 invite_nut = invite_in_container("relay", "nut");
717 // Run nodes and open a channel between NUT and peer
719 node_sim_in_container_event("relay", "1", NULL, RELAY_ID, import);
720 node_sim_in_container_event("peer", "1", invite_peer, PEER_ID, import);
721 node_sim_in_container_event("nut", "1", invite_nut, NUT_ID, import);
723 wait_for_event(channel_conn_cb, 10);
724 assert_int_equal(joined, true);
726 wait_for_event(channel_conn_cb, 10);
727 assert_int_equal(channel_opened, true);
729 // Wait for NUT node to restart it's instance
731 wait_for_event(channel_conn_cb, 60);
732 assert_int_equal(node_restarted, true);
736 // Signal peer to send data to NUT node via channel
738 node_step_in_container("peer", "SIGUSR1");
740 // Wait for peer to receive channel error
742 wait_for_event(channel_conn_cb, 10);
744 mesh_event_destroy();
749 assert_int_equal(received_error, true);
754 static int black_box_group_setup(void **state) {
757 const char *nodes[] = { "peer", "nut", "relay" };
758 int num_nodes = sizeof(nodes) / sizeof(nodes[0]);
760 printf("Creating Containers\n");
761 destroy_containers();
762 create_containers(nodes, num_nodes);
767 static int black_box_group_teardown(void **state) {
770 printf("Destroying Containers\n");
771 destroy_containers();
776 int test_meshlink_channel_conn(void) {
777 const struct CMUnitTest blackbox_group0_tests[] = {
778 cmocka_unit_test_prestate_setup_teardown(test_case_channel_conn_01, setup_test, teardown_test,
779 (void *)&test_case_channel_conn_01_state),
780 cmocka_unit_test_prestate_setup_teardown(test_case_channel_conn_02, setup_test, teardown_test,
781 (void *)&test_case_channel_conn_02_state),
782 cmocka_unit_test_prestate_setup_teardown(test_case_channel_conn_03, setup_test, teardown_test,
783 (void *)&test_case_channel_conn_03_state),
784 cmocka_unit_test_prestate_setup_teardown(test_case_channel_conn_04, setup_test, teardown_test,
785 (void *)&test_case_channel_conn_04_state),
786 cmocka_unit_test_prestate_setup_teardown(test_case_channel_conn_05, setup_test, teardown_test,
787 (void *)&test_case_channel_conn_05_state),
788 cmocka_unit_test_prestate_setup_teardown(test_case_channel_conn_06, setup_test, teardown_test,
789 (void *)&test_case_channel_conn_06_state),
790 cmocka_unit_test_prestate_setup_teardown(test_case_channel_conn_07, setup_test, teardown_test,
791 (void *)&test_case_channel_conn_07_state),
792 cmocka_unit_test_prestate_setup_teardown(test_case_channel_conn_08, setup_test, teardown_test,
793 (void *)&test_case_channel_conn_08_state),
795 total_tests += sizeof(blackbox_group0_tests) / sizeof(blackbox_group0_tests[0]);
797 return cmocka_run_group_tests(blackbox_group0_tests, black_box_group_setup, black_box_group_teardown);