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.
31 #include "execute_tests.h"
32 #include "test_cases_channel_conn.h"
33 #include "../common/containers.h"
34 #include "../common/test_step.h"
35 #include "../common/common_handlers.h"
36 #include "../common/mesh_event_handler.h"
42 static void test_case_channel_conn_01(void **state);
43 static bool test_steps_channel_conn_01(void);
44 static void test_case_channel_conn_02(void **state);
45 static bool test_steps_channel_conn_02(void);
46 static void test_case_channel_conn_03(void **state);
47 static bool test_steps_channel_conn_03(void);
48 static void test_case_channel_conn_04(void **state);
49 static bool test_steps_channel_conn_04(void);
50 static void test_case_channel_conn_05(void **state);
51 static bool test_steps_channel_conn_05(void);
52 static void test_case_channel_conn_06(void **state);
53 static bool test_steps_channel_conn_06(void);
54 static void test_case_channel_conn_07(void **state);
55 static bool test_steps_channel_conn_07(void);
56 static void test_case_channel_conn_08(void **state);
57 static bool test_steps_channel_conn_08(void);
59 static char *test_channel_conn_2_nodes[] = { "peer", "nut" };
60 static char *test_channel_conn_3_nodes[] = { "peer", "nut", "relay" };
62 static black_box_state_t test_case_channel_conn_01_state = {
63 .test_case_name = "test_case_channel_conn_01",
64 .node_names = test_channel_conn_2_nodes,
67 static black_box_state_t test_case_channel_conn_02_state = {
68 .test_case_name = "test_case_channel_conn_02",
69 .node_names = test_channel_conn_2_nodes,
72 static black_box_state_t test_case_channel_conn_03_state = {
73 .test_case_name = "test_case_channel_conn_03",
74 .node_names = test_channel_conn_2_nodes,
77 static black_box_state_t test_case_channel_conn_04_state = {
78 .test_case_name = "test_case_channel_conn_04",
79 .node_names = test_channel_conn_2_nodes,
82 static black_box_state_t test_case_channel_conn_05_state = {
83 .test_case_name = "test_case_channel_conn_05",
84 .node_names = test_channel_conn_3_nodes,
87 static black_box_state_t test_case_channel_conn_06_state = {
88 .test_case_name = "test_case_channel_conn_06",
89 .node_names = test_channel_conn_3_nodes,
92 static black_box_state_t test_case_channel_conn_07_state = {
93 .test_case_name = "test_case_channel_conn_07",
94 .node_names = test_channel_conn_3_nodes,
97 static black_box_state_t test_case_channel_conn_08_state = {
98 .test_case_name = "test_case_channel_conn_08",
99 .node_names = test_channel_conn_3_nodes,
104 static bool channel_opened;
105 static bool node_restarted;
106 static bool received_error;
107 static bool channel_received;
108 static bool node_reachable;
109 static bool node_unreachable;
111 /* Callback function for handling channel connection test cases mesh events */
112 static bool channel_conn_cb(mesh_event_payload_t payload) {
113 switch(payload.mesh_event) {
118 case CHANNEL_OPENED :
119 channel_opened = true;
122 case NODE_RESTARTED :
123 node_restarted = true;
127 received_error = true;
130 case CHANNEL_DATA_RECIEVED :
131 channel_received = true;
134 case NODE_UNREACHABLE :
135 node_unreachable = true;
138 case NODE_REACHABLE :
139 node_reachable = true;
143 PRINT_TEST_CASE_MSG("Undefined event occurred\n");
149 /* Execute channel connections Test Case # 1 - simulate a temporary network
150 failure of about 30 seconds, messages sent while the network was down
151 should be received by the other side after the network comes up again. */
152 static void test_case_channel_conn_01(void **state) {
153 execute_test(test_steps_channel_conn_01, state);
157 /* Test Steps for channel connections Test Case # 1
160 1. Run NUT & peer node instances and open a channel between them
161 2. Simulate a network failure in NUT's container for about 30 secs,
162 meanwhile send data via channel from NUT to peer.
163 3. After restoring network, peer node receive's data via channel.
166 Peer node receives data via channel without any error after restoring network.
168 static bool test_steps_channel_conn_01(void) {
173 channel_opened = false;
174 channel_received = false;
178 install_in_container("nut", "iptables");
179 accept_port_rule("nut", "OUTPUT", "udp", 9000);
180 import = mesh_event_sock_create(eth_if_name);
181 invite_nut = invite_in_container("peer", "nut");
184 // Run node instances in containers & open a channel
186 node_sim_in_container_event("peer", "1", NULL, PEER_ID, import);
187 node_sim_in_container_event("nut", "1", invite_nut, NUT_ID, import);
189 wait_for_event(channel_conn_cb, 30);
190 assert_int_equal(joined, true);
192 wait_for_event(channel_conn_cb, 30);
193 assert_int_equal(channel_opened, true);
195 // Simulate network failure in NUT's LXC container with it's IP address as NAT rule
197 block_node_ip("nut");
200 // Sending SIGUSR1 signal to node-under-test indicating the network failure
202 node_step_in_container("nut", "SIGUSR1");
205 // Restore NUT's network
207 unblock_node_ip("nut");
209 // Wait for peer node to receive data via channel from NUT
211 wait_for_event(channel_conn_cb, 60);
213 mesh_event_destroy();
217 assert_int_equal(channel_received, true);
222 /* Execute channel connections Test Case # 2 - a simulated network failure
223 of more than 1 minute, and sending messages over the channel during the
224 failure. Then after about 1 minute, the channel should receive an error */
225 static void test_case_channel_conn_02(void **state) {
226 execute_test(test_steps_channel_conn_02, state);
230 /* Test Steps for channel connections Test Case # 2
233 1. Run NUT and peer node instances in containers and open a channel between them.
234 2. Create a network failure for about 90 secs in NUT container
235 and signal NUT node about the network failure.
236 3. Meanwhile NUT sends data to peer via channel and restore the network after
240 Peer node should receive error closing the channel after channel timeout(60 secs).
242 static bool test_steps_channel_conn_02(void) {
247 channel_opened = false;
248 received_error = false;
252 install_in_container("nut", "iptables");
253 accept_port_rule("nut", "OUTPUT", "udp", 9000);
254 import = mesh_event_sock_create(eth_if_name);
255 invite_nut = invite_in_container("peer", "nut");
258 // Run NUT and peer node instances in containers & open a channel
260 node_sim_in_container_event("peer", "1", NULL, PEER_ID, import);
261 node_sim_in_container_event("nut", "1", invite_nut, NUT_ID, import);
263 wait_for_event(channel_conn_cb, 30);
264 assert_int_equal(joined, true);
266 wait_for_event(channel_conn_cb, 10);
267 assert_int_equal(channel_opened, true);
269 // Simulate network failure in NUT's LXC container with it's IP address as NAT rule
271 block_node_ip("nut");
273 // Sending SIGUSR1 signal to node-under-test indicating the network failure
275 node_step_in_container("nut", "SIGUSR1");
278 // Restore NUT containers network after 90 secs
280 unblock_node_ip("nut");
282 // Wait for peer node to send the event about the channel error occurred with length = 0
284 wait_for_event(channel_conn_cb, 90);
286 mesh_event_destroy();
290 assert_int_equal(received_error, true);
295 /* Execute channel connections Test Case # 3 - a simulated network failure
296 once node instance is made offline restore the network and send data via
298 static void test_case_channel_conn_03(void **state) {
299 execute_test(test_steps_channel_conn_03, state);
303 /* Test Steps for channel connections Test Case # 3
306 1. Run NUT and peer node instances and open a channel between them.
307 2. Create a network failure in NUT container, bring NUT node offline
308 and receive the status at test driver and restore the network
309 3. After peer node instance is reachable to NUT node send data via channel
312 Peer node should receive data from NUT without any error.
314 static bool test_steps_channel_conn_03(void) {
319 channel_opened = false;
320 node_unreachable = false;
321 node_reachable = false;
322 channel_received = false;
326 install_in_container("nut", "iptables");
327 accept_port_rule("nut", "OUTPUT", "udp", 9000);
328 import = mesh_event_sock_create(eth_if_name);
329 invite_nut = invite_in_container("peer", "nut");
332 // Run NUT and peer node instances in containers & open a channel
334 node_sim_in_container_event("peer", "1", NULL, PEER_ID, import);
335 node_sim_in_container_event("nut", "1", invite_nut, NUT_ID, import);
337 wait_for_event(channel_conn_cb, 30);
338 assert_int_equal(joined, true);
340 wait_for_event(channel_conn_cb, 10);
341 assert_int_equal(channel_opened, true);
343 // Simulate network failure in NUT's LXC container with it's IP address as NAT rule
345 node_reachable = false;
346 block_node_ip("nut");
348 // Sending SIGUSR1 signal to node-under-test indicating the network failure
350 node_step_in_container("nut", "SIGUSR1");
352 // Wait for the node status to become unreachable
354 wait_for_event(channel_conn_cb, 100);
355 assert_int_equal(node_unreachable, true);
357 // Restore NUT container's network
359 unblock_node_ip("nut");
361 // Wait for the node status to become reachable
363 wait_for_event(channel_conn_cb, 100);
364 assert_int_equal(node_reachable, true);
366 // Wait for data to be received at peer via channel from NUT after restoring n/w
368 wait_for_event(channel_conn_cb, 90);
370 mesh_event_destroy();
374 assert_int_equal(channel_received, true);
379 /* Execute channel connections Test Case # 4 - receiving an error when node-under-test
380 tries to send data on channel to peer node after peer node stops and starts the
382 static void test_case_channel_conn_04(void **state) {
383 execute_test(test_steps_channel_conn_04, state);
387 /* Test Steps for Meta-connections Test Case # 4
390 1. Run peer and NUT node instances in containers and open a channel between them.
391 2. Stop and start the NUT node instance and wait for about > 60 secs.
392 3. Send data via channel from Peer node and wait for event in test driver.
395 Peer node should receive error(as length = 0) in receive callback of peer node's instance.
397 static bool test_steps_channel_conn_04(void) {
402 channel_opened = false;
403 node_restarted = false;
404 received_error = false;
405 import = mesh_event_sock_create(eth_if_name);
406 invite_nut = invite_in_container("peer", "nut");
409 // Run NUT and peer node instances in containers and open a channel
411 node_sim_in_container_event("peer", "1", NULL, PEER_ID, import);
412 node_sim_in_container_event("nut", "1", invite_nut, NUT_ID, import);
414 wait_for_event(channel_conn_cb, 10);
415 assert_int_equal(joined, true);
417 wait_for_event(channel_conn_cb, 10);
418 assert_int_equal(channel_opened, true);
420 // Wait for NUT node instance to stop and start
422 wait_for_event(channel_conn_cb, 60);
423 assert_int_equal(node_restarted, true);
427 // After 1 min the channel between NUT and peer should result in error
429 wait_for_event(channel_conn_cb, 10);
432 mesh_event_destroy();
436 assert_int_equal(received_error, true);
441 /* Execute channel connections Test Case # 5 - simulate a temporary network
442 failure of about 30 seconds, messages sent while the network was down
443 should be received by the other side after the network comes up again. */
444 static void test_case_channel_conn_05(void **state) {
445 execute_test(test_steps_channel_conn_05, state);
449 /* Test Steps for channel connections Test Case # 5
452 1. Run NUT, relay & peer node instances with relay inviting NUT and peer
453 and open a channel between them
454 2. Simulate a network failure in NUT's container for about 30 secs,
455 meanwhile send data via channel from NUT to peer.
456 3. After restoring network, peer node receive's data via channel.
459 Peer node receives data via channel without any error after restoring network.
461 static bool test_steps_channel_conn_05(void) {
462 char *invite_nut, *invite_peer;
466 channel_opened = false;
467 channel_received = false;
471 install_in_container("nut", "iptables");
472 accept_port_rule("nut", "OUTPUT", "udp", 9000);
473 import = mesh_event_sock_create(eth_if_name);
474 invite_peer = invite_in_container("relay", "peer");
475 invite_nut = invite_in_container("relay", "nut");
479 // Run node instances and open a channel between NUT and peer nodes
481 node_sim_in_container_event("relay", "1", NULL, RELAY_ID, import);
482 node_sim_in_container_event("peer", "1", invite_peer, PEER_ID, import);
483 node_sim_in_container_event("nut", "1", invite_nut, NUT_ID, import);
485 wait_for_event(channel_conn_cb, 30);
486 assert_int_equal(joined, true);
488 wait_for_event(channel_conn_cb, 30);
489 assert_int_equal(channel_opened, true);
491 // Create a network failure in NUT node's container with it's IP address
493 block_node_ip("nut");
495 // Sending SIGUSR1 signal to node-under-test indicating the network failure
497 node_step_in_container("nut", "SIGUSR1");
500 // Restore the network
502 unblock_node_ip("nut");
504 // Wait for peer to get data from NUT node via channel after restoring network in < 60 secs
506 wait_for_event(channel_conn_cb, 60);
508 mesh_event_destroy();
513 assert_int_equal(channel_received, true);
518 /* Execute channel connections Test Case # 6 - a simulated network failure
519 of more than 1 minute, and sending messages over the channel during the
520 failure. Then after about 1 minute, the channel should receive an error */
521 static void test_case_channel_conn_06(void **state) {
522 execute_test(test_steps_channel_conn_06, state);
526 /* Test Steps for channel connections Test Case # 6
529 1. Run NUT, relay & peer node instances with relay inviting NUT and peer
530 and open a channel between them
531 2. Create a network failure for about 90 secs in NUT container
532 and signal NUT node about the network failure.
533 3. Meanwhile NUT sends data to peer via channel and restore the network after
537 Peer node should receive error closing the channel after channel timeout(60 secs).
539 static bool test_steps_channel_conn_06(void) {
540 char *invite_nut, *invite_peer;
544 channel_opened = false;
545 received_error = false;
549 install_in_container("nut", "iptables");
550 accept_port_rule("nut", "OUTPUT", "udp", 9000);
551 import = mesh_event_sock_create(eth_if_name);
552 invite_peer = invite_in_container("relay", "peer");
554 invite_nut = invite_in_container("relay", "nut");
557 // Run nodes in containers and open a channel between NUt and peer
559 node_sim_in_container_event("relay", "1", NULL, RELAY_ID, import);
560 node_sim_in_container_event("peer", "1", invite_peer, PEER_ID, import);
561 node_sim_in_container_event("nut", "1", invite_nut, NUT_ID, import);
563 wait_for_event(channel_conn_cb, 30);
564 assert_int_equal(joined, true);
566 wait_for_event(channel_conn_cb, 10);
567 assert_int_equal(channel_opened, true);
569 // Simulate a network failure in NUT's container for > 60 secs
571 block_node_ip("nut");
573 // Sending SIGUSR1 signal to node-under-test indicating the network failure
575 node_step_in_container("nut", "SIGUSR1");
578 // Restore the network after 90 secs
580 unblock_node_ip("nut");
582 // Wait for channel to receive error and receive the event
584 wait_for_event(channel_conn_cb, 90);
586 mesh_event_destroy();
591 assert_int_equal(received_error, true);
596 /* Execute channel connections Test Case # 7 - a simulated network failure
597 once node instance is made offline restore the network and send data via
599 static void test_case_channel_conn_07(void **state) {
600 execute_test(test_steps_channel_conn_07, state);
604 /* Test Steps for channel connections Test Case # 7
607 1. Run NUT, relay & peer node instances with relay inviting NUT and peer
608 and open a channel between them
609 2. Create a network failure in NUT container, bring NUT node offline
610 and receive the status at test driver and restore the network
611 3. After peer node instance is reachable to NUT node send data via channel
614 Peer node should receive data from NUT without any error.
616 static bool test_steps_channel_conn_07(void) {
617 char *invite_nut, *invite_peer;
621 channel_opened = false;
622 node_unreachable = false;
623 node_reachable = false;
624 channel_received = false;
628 install_in_container("nut", "iptables");
629 accept_port_rule("nut", "OUTPUT", "udp", 9000);
630 import = mesh_event_sock_create(eth_if_name);
631 invite_peer = invite_in_container("relay", "peer");
632 invite_nut = invite_in_container("relay", "nut");
636 // Run nodes and open a channel
638 node_sim_in_container_event("relay", "1", NULL, RELAY_ID, import);
639 node_sim_in_container_event("peer", "1", invite_peer, PEER_ID, import);
640 node_sim_in_container_event("nut", "1", invite_nut, NUT_ID, import);
642 wait_for_event(channel_conn_cb, 30);
643 assert_int_equal(joined, true);
645 wait_for_event(channel_conn_cb, 15);
646 assert_int_equal(channel_opened, true);
648 // Simulate a network failure
650 node_reachable = false;
651 block_node_ip("nut");
653 // Sending SIGUSR1 signal to node-under-test indicating the network failure
655 node_step_in_container("nut", "SIGUSR1");
657 // Wait for node to become unreachable
659 wait_for_event(channel_conn_cb, 100);
660 assert_int_equal(node_unreachable, true);
662 // Restore the network
664 unblock_node_ip("nut");
666 // Wait for node to become reachable after restoring n/w
668 wait_for_event(channel_conn_cb, 100);
669 assert_int_equal(node_reachable, true);
671 // Wait for peer node to receive data via channel without any error
673 wait_for_event(channel_conn_cb, 90);
675 mesh_event_destroy();
680 assert_int_equal(channel_received, true);
685 /* Execute channel connections Test Case # 8 - receiving an error when node-under-test
686 tries to send data on channel to peer node after peer node stops and starts the
688 static void test_case_channel_conn_08(void **state) {
689 execute_test(test_steps_channel_conn_08, state);
693 /* Test Steps for Meta-connections Test Case # 8
696 1. Run NUT, relay & peer node instances with relay inviting NUT and peer
697 and open a channel between them
698 2. Stop and start the NUT node instance and wait for about > 60 secs.
699 3. Send data via channel from Peer node and wait for event in test driver.
702 Peer node should receive error(as length = 0) in receive callback of peer node's instance.
704 static bool test_steps_channel_conn_08(void) {
705 char *invite_nut, *invite_peer;
709 channel_opened = false;
710 node_restarted = false;
711 received_error = false;
715 import = mesh_event_sock_create(eth_if_name);
716 invite_peer = invite_in_container("relay", "peer");
717 invite_nut = invite_in_container("relay", "nut");
721 // Run nodes and open a channel between NUT and peer
723 node_sim_in_container_event("relay", "1", NULL, RELAY_ID, import);
724 node_sim_in_container_event("peer", "1", invite_peer, PEER_ID, import);
725 node_sim_in_container_event("nut", "1", invite_nut, NUT_ID, import);
727 wait_for_event(channel_conn_cb, 10);
728 assert_int_equal(joined, true);
730 wait_for_event(channel_conn_cb, 10);
731 assert_int_equal(channel_opened, true);
733 // Wait for NUT node to restart it's instance
735 wait_for_event(channel_conn_cb, 60);
736 assert_int_equal(node_restarted, true);
740 // Signal peer to send data to NUT node via channel
742 node_step_in_container("peer", "SIGUSR1");
744 // Wait for peer to receive channel error
746 wait_for_event(channel_conn_cb, 10);
748 mesh_event_destroy();
753 assert_int_equal(received_error, true);
758 static int black_box_group_setup(void **state) {
761 const char *nodes[] = { "peer", "nut", "relay" };
762 int num_nodes = sizeof(nodes) / sizeof(nodes[0]);
764 printf("Creating Containers\n");
765 destroy_containers();
766 create_containers(nodes, num_nodes);
771 static int black_box_group_teardown(void **state) {
774 printf("Destroying Containers\n");
775 destroy_containers();
780 int test_meshlink_channel_conn(void) {
781 const struct CMUnitTest blackbox_group0_tests[] = {
782 cmocka_unit_test_prestate_setup_teardown(test_case_channel_conn_01, setup_test, teardown_test,
783 (void *)&test_case_channel_conn_01_state),
784 cmocka_unit_test_prestate_setup_teardown(test_case_channel_conn_02, setup_test, teardown_test,
785 (void *)&test_case_channel_conn_02_state),
786 cmocka_unit_test_prestate_setup_teardown(test_case_channel_conn_03, setup_test, teardown_test,
787 (void *)&test_case_channel_conn_03_state),
788 cmocka_unit_test_prestate_setup_teardown(test_case_channel_conn_04, setup_test, teardown_test,
789 (void *)&test_case_channel_conn_04_state),
790 cmocka_unit_test_prestate_setup_teardown(test_case_channel_conn_05, setup_test, teardown_test,
791 (void *)&test_case_channel_conn_05_state),
792 cmocka_unit_test_prestate_setup_teardown(test_case_channel_conn_06, setup_test, teardown_test,
793 (void *)&test_case_channel_conn_06_state),
794 cmocka_unit_test_prestate_setup_teardown(test_case_channel_conn_07, setup_test, teardown_test,
795 (void *)&test_case_channel_conn_07_state),
796 cmocka_unit_test_prestate_setup_teardown(test_case_channel_conn_08, setup_test, teardown_test,
797 (void *)&test_case_channel_conn_08_state),
799 total_tests += sizeof(blackbox_group0_tests) / sizeof(blackbox_group0_tests[0]);
801 return cmocka_run_group_tests(blackbox_group0_tests, black_box_group_setup, black_box_group_teardown);