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 void 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);
208 assert_int_equal(channel_received, true);
215 /* Execute channel connections Test Case # 2 - a simulated network failure
216 of more than 1 minute, and sending messages over the channel during the
217 failure. Then after about 1 minute, the channel should receive an error */
218 static void test_case_channel_conn_02(void **state) {
219 execute_test(test_steps_channel_conn_02, state);
223 /* Test Steps for channel connections Test Case # 2
226 1. Run NUT and peer node instances in containers and open a channel between them.
227 2. Create a network failure for about 90 secs in NUT container
228 and signal NUT node about the network failure.
229 3. Meanwhile NUT sends data to peer via channel and restore the network after
233 Peer node should receive error closing the channel after channel timeout(60 secs).
235 static bool test_steps_channel_conn_02(void) {
240 channel_opened = false;
241 received_error = false;
245 install_in_container("nut", "iptables");
246 accept_port_rule("nut", "OUTPUT", "udp", 9000);
247 import = mesh_event_sock_create(eth_if_name);
248 invite_nut = invite_in_container("peer", "nut");
251 // Run NUT and peer node instances in containers & open a channel
253 node_sim_in_container_event("peer", "1", NULL, PEER_ID, import);
254 node_sim_in_container_event("nut", "1", invite_nut, NUT_ID, import);
256 wait_for_event(channel_conn_cb, 30);
257 assert_int_equal(joined, true);
259 wait_for_event(channel_conn_cb, 10);
260 assert_int_equal(channel_opened, true);
262 // Simulate network failure in NUT's LXC container with it's IP address as NAT rule
264 block_node_ip("nut");
266 // Sending SIGUSR1 signal to node-under-test indicating the network failure
268 node_step_in_container("nut", "SIGUSR1");
271 // Restore NUT containers network after 90 secs
273 unblock_node_ip("nut");
275 // Wait for peer node to send the event about the channel error occurred with length = 0
277 wait_for_event(channel_conn_cb, 90);
278 assert_int_equal(received_error, true);
285 /* Execute channel connections Test Case # 3 - a simulated network failure
286 once node instance is made offline restore the network and send data via
288 static void test_case_channel_conn_03(void **state) {
289 execute_test(test_steps_channel_conn_03, state);
293 /* Test Steps for channel connections Test Case # 3
296 1. Run NUT and peer node instances and open a channel between them.
297 2. Create a network failure in NUT container, bring NUT node offline
298 and receive the status at test driver and restore the network
299 3. After peer node instance is reachable to NUT node send data via channel
302 Peer node should receive data from NUT without any error.
304 static bool test_steps_channel_conn_03(void) {
309 channel_opened = false;
310 node_unreachable = false;
311 node_reachable = false;
312 channel_received = false;
316 install_in_container("nut", "iptables");
317 accept_port_rule("nut", "OUTPUT", "udp", 9000);
318 import = mesh_event_sock_create(eth_if_name);
319 invite_nut = invite_in_container("peer", "nut");
322 // Run NUT and peer node instances in containers & open a channel
324 node_sim_in_container_event("peer", "1", NULL, PEER_ID, import);
325 node_sim_in_container_event("nut", "1", invite_nut, NUT_ID, import);
327 wait_for_event(channel_conn_cb, 30);
328 assert_int_equal(joined, true);
330 wait_for_event(channel_conn_cb, 10);
331 assert_int_equal(channel_opened, true);
333 // Simulate network failure in NUT's LXC container with it's IP address as NAT rule
335 node_reachable = false;
336 block_node_ip("nut");
338 // Sending SIGUSR1 signal to node-under-test indicating the network failure
340 node_step_in_container("nut", "SIGUSR1");
342 // Wait for the node status to become unreachable
344 wait_for_event(channel_conn_cb, 100);
345 assert_int_equal(node_unreachable, true);
347 // Restore NUT container's network
349 unblock_node_ip("nut");
351 // Wait for the node status to become reachable
353 wait_for_event(channel_conn_cb, 100);
354 assert_int_equal(node_reachable, true);
356 // Wait for data to be received at peer via channel from NUT after restoring n/w
358 wait_for_event(channel_conn_cb, 90);
359 assert_int_equal(channel_received, true);
366 /* Execute channel connections Test Case # 4 - receiving an error when node-under-test
367 tries to send data on channel to peer node after peer node stops and starts the
369 static void test_case_channel_conn_04(void **state) {
370 execute_test(test_steps_channel_conn_04, state);
374 /* Test Steps for Meta-connections Test Case # 4
377 1. Run peer and NUT node instances in containers and open a channel between them.
378 2. Stop and start the NUT node instance and wait for about > 60 secs.
379 3. Send data via channel from Peer node and wait for event in test driver.
382 Peer node should receive error(as length = 0) in receive callback of peer node's instance.
384 static bool test_steps_channel_conn_04(void) {
389 channel_opened = false;
390 node_restarted = false;
391 received_error = false;
392 import = mesh_event_sock_create(eth_if_name);
393 invite_nut = invite_in_container("peer", "nut");
396 // Run NUT and peer node instances in containers and open a channel
398 node_sim_in_container_event("peer", "1", NULL, PEER_ID, import);
399 node_sim_in_container_event("nut", "1", invite_nut, NUT_ID, import);
401 wait_for_event(channel_conn_cb, 10);
402 assert_int_equal(joined, true);
404 wait_for_event(channel_conn_cb, 10);
405 assert_int_equal(channel_opened, true);
407 // Wait for NUT node instance to stop and start
409 wait_for_event(channel_conn_cb, 60);
410 assert_int_equal(node_restarted, true);
414 // After 1 min the channel between NUT and peer should result in error
416 wait_for_event(channel_conn_cb, 10);
417 assert_int_equal(received_error, true);
422 /* Execute channel connections Test Case # 5 - simulate a temporary network
423 failure of about 30 seconds, messages sent while the network was down
424 should be received by the other side after the network comes up again. */
425 static void test_case_channel_conn_05(void **state) {
426 execute_test(test_steps_channel_conn_05, state);
430 /* Test Steps for channel connections Test Case # 5
433 1. Run NUT, relay & peer node instances with relay inviting NUT and peer
434 and open a channel between them
435 2. Simulate a network failure in NUT's container for about 30 secs,
436 meanwhile send data via channel from NUT to peer.
437 3. After restoring network, peer node receive's data via channel.
440 Peer node receives data via channel without any error after restoring network.
442 static bool test_steps_channel_conn_05(void) {
443 char *invite_nut, *invite_peer;
447 channel_opened = false;
448 channel_received = false;
452 install_in_container("nut", "iptables");
453 accept_port_rule("nut", "OUTPUT", "udp", 9000);
454 import = mesh_event_sock_create(eth_if_name);
455 invite_peer = invite_in_container("relay", "peer");
456 invite_nut = invite_in_container("relay", "nut");
460 // Run node instances and open a channel between NUT and peer nodes
462 node_sim_in_container_event("relay", "1", NULL, RELAY_ID, import);
463 node_sim_in_container_event("peer", "1", invite_peer, PEER_ID, import);
464 node_sim_in_container_event("nut", "1", invite_nut, NUT_ID, import);
466 wait_for_event(channel_conn_cb, 30);
467 assert_int_equal(joined, true);
469 wait_for_event(channel_conn_cb, 30);
470 assert_int_equal(channel_opened, true);
472 // Create a network failure in NUT node's container with it's IP address
474 block_node_ip("nut");
476 // Sending SIGUSR1 signal to node-under-test indicating the network failure
478 node_step_in_container("nut", "SIGUSR1");
481 // Restore the network
483 unblock_node_ip("nut");
485 // Wait for peer to get data from NUT node via channel after restoring network in < 60 secs
487 wait_for_event(channel_conn_cb, 60);
488 assert_int_equal(channel_received, true);
496 /* Execute channel connections Test Case # 6 - a simulated network failure
497 of more than 1 minute, and sending messages over the channel during the
498 failure. Then after about 1 minute, the channel should receive an error */
499 static void test_case_channel_conn_06(void **state) {
500 execute_test(test_steps_channel_conn_06, state);
504 /* Test Steps for channel connections Test Case # 6
507 1. Run NUT, relay & peer node instances with relay inviting NUT and peer
508 and open a channel between them
509 2. Create a network failure for about 90 secs in NUT container
510 and signal NUT node about the network failure.
511 3. Meanwhile NUT sends data to peer via channel and restore the network after
515 Peer node should receive error closing the channel after channel timeout(60 secs).
517 static bool test_steps_channel_conn_06(void) {
518 char *invite_nut, *invite_peer;
522 channel_opened = false;
523 received_error = false;
527 install_in_container("nut", "iptables");
528 accept_port_rule("nut", "OUTPUT", "udp", 9000);
529 import = mesh_event_sock_create(eth_if_name);
530 invite_peer = invite_in_container("relay", "peer");
532 invite_nut = invite_in_container("relay", "nut");
535 // Run nodes in containers and open a channel between NUt and peer
537 node_sim_in_container_event("relay", "1", NULL, RELAY_ID, import);
538 node_sim_in_container_event("peer", "1", invite_peer, PEER_ID, import);
539 node_sim_in_container_event("nut", "1", invite_nut, NUT_ID, import);
541 wait_for_event(channel_conn_cb, 30);
542 assert_int_equal(joined, true);
544 wait_for_event(channel_conn_cb, 10);
545 assert_int_equal(channel_opened, true);
547 // Simulate a network failure in NUT's container for > 60 secs
549 block_node_ip("nut");
551 // Sending SIGUSR1 signal to node-under-test indicating the network failure
553 node_step_in_container("nut", "SIGUSR1");
556 // Restore the network after 90 secs
558 unblock_node_ip("nut");
560 // Wait for channel to receive error and receive the event
562 wait_for_event(channel_conn_cb, 90);
563 assert_int_equal(received_error, true);
571 /* Execute channel connections Test Case # 7 - a simulated network failure
572 once node instance is made offline restore the network and send data via
574 static void test_case_channel_conn_07(void **state) {
575 execute_test(test_steps_channel_conn_07, state);
579 /* Test Steps for channel connections Test Case # 7
582 1. Run NUT, relay & peer node instances with relay inviting NUT and peer
583 and open a channel between them
584 2. Create a network failure in NUT container, bring NUT node offline
585 and receive the status at test driver and restore the network
586 3. After peer node instance is reachable to NUT node send data via channel
589 Peer node should receive data from NUT without any error.
591 static bool test_steps_channel_conn_07(void) {
592 char *invite_nut, *invite_peer;
596 channel_opened = false;
597 node_unreachable = false;
598 node_reachable = false;
599 channel_received = false;
603 install_in_container("nut", "iptables");
604 accept_port_rule("nut", "OUTPUT", "udp", 9000);
605 import = mesh_event_sock_create(eth_if_name);
606 invite_peer = invite_in_container("relay", "peer");
607 invite_nut = invite_in_container("relay", "nut");
611 // Run nodes and open a channel
613 node_sim_in_container_event("relay", "1", NULL, RELAY_ID, import);
614 node_sim_in_container_event("peer", "1", invite_peer, PEER_ID, import);
615 node_sim_in_container_event("nut", "1", invite_nut, NUT_ID, import);
617 wait_for_event(channel_conn_cb, 30);
618 assert_int_equal(joined, true);
620 wait_for_event(channel_conn_cb, 15);
621 assert_int_equal(channel_opened, true);
623 // Simulate a network failure
625 node_reachable = false;
626 block_node_ip("nut");
628 // Sending SIGUSR1 signal to node-under-test indicating the network failure
630 node_step_in_container("nut", "SIGUSR1");
632 // Wait for node to become unreachable
634 wait_for_event(channel_conn_cb, 100);
635 assert_int_equal(node_unreachable, true);
637 // Restore the network
639 unblock_node_ip("nut");
641 // Wait for node to become reachable after restoring n/w
643 wait_for_event(channel_conn_cb, 100);
644 assert_int_equal(node_reachable, true);
646 // Wait for peer node to receive data via channel without any error
648 wait_for_event(channel_conn_cb, 90);
649 assert_int_equal(channel_received, true);
657 /* Execute channel connections Test Case # 8 - receiving an error when node-under-test
658 tries to send data on channel to peer node after peer node stops and starts the
660 static void test_case_channel_conn_08(void **state) {
661 execute_test(test_steps_channel_conn_08, state);
665 /* Test Steps for Meta-connections Test Case # 8
668 1. Run NUT, relay & peer node instances with relay inviting NUT and peer
669 and open a channel between them
670 2. Stop and start the NUT node instance and wait for about > 60 secs.
671 3. Send data via channel from Peer node and wait for event in test driver.
674 Peer node should receive error(as length = 0) in receive callback of peer node's instance.
676 static bool test_steps_channel_conn_08(void) {
677 char *invite_nut, *invite_peer;
681 channel_opened = false;
682 node_restarted = false;
683 received_error = false;
687 import = mesh_event_sock_create(eth_if_name);
688 invite_peer = invite_in_container("relay", "peer");
689 invite_nut = invite_in_container("relay", "nut");
693 // Run nodes and open a channel between NUT and peer
695 node_sim_in_container_event("relay", "1", NULL, RELAY_ID, import);
696 node_sim_in_container_event("peer", "1", invite_peer, PEER_ID, import);
697 node_sim_in_container_event("nut", "1", invite_nut, NUT_ID, import);
699 wait_for_event(channel_conn_cb, 10);
700 assert_int_equal(joined, true);
702 wait_for_event(channel_conn_cb, 10);
703 assert_int_equal(channel_opened, true);
705 // Wait for NUT node to restart it's instance
707 wait_for_event(channel_conn_cb, 60);
708 assert_int_equal(node_restarted, true);
712 // Signal peer to send data to NUT node via channel
714 node_step_in_container("peer", "SIGUSR1");
716 // Wait for peer to receive channel error
718 wait_for_event(channel_conn_cb, 10);
719 assert_int_equal(received_error, true);
727 static int black_box_group_setup(void **state) {
728 const char *nodes[] = { "peer", "nut", "relay" };
729 int num_nodes = sizeof(nodes) / sizeof(nodes[0]);
731 printf("Creating Containers\n");
732 destroy_containers();
733 create_containers(nodes, num_nodes);
738 static int black_box_group_teardown(void **state) {
739 printf("Destroying Containers\n");
740 destroy_containers();
745 int test_meshlink_channel_conn(void) {
746 const struct CMUnitTest blackbox_group0_tests[] = {
747 cmocka_unit_test_prestate_setup_teardown(test_case_channel_conn_01, setup_test, teardown_test,
748 (void *)&test_case_channel_conn_01_state),
749 cmocka_unit_test_prestate_setup_teardown(test_case_channel_conn_02, setup_test, teardown_test,
750 (void *)&test_case_channel_conn_02_state),
751 cmocka_unit_test_prestate_setup_teardown(test_case_channel_conn_03, setup_test, teardown_test,
752 (void *)&test_case_channel_conn_03_state),
753 cmocka_unit_test_prestate_setup_teardown(test_case_channel_conn_04, setup_test, teardown_test,
754 (void *)&test_case_channel_conn_04_state),
755 cmocka_unit_test_prestate_setup_teardown(test_case_channel_conn_05, setup_test, teardown_test,
756 (void *)&test_case_channel_conn_05_state),
757 cmocka_unit_test_prestate_setup_teardown(test_case_channel_conn_06, setup_test, teardown_test,
758 (void *)&test_case_channel_conn_06_state),
759 cmocka_unit_test_prestate_setup_teardown(test_case_channel_conn_07, setup_test, teardown_test,
760 (void *)&test_case_channel_conn_07_state),
761 cmocka_unit_test_prestate_setup_teardown(test_case_channel_conn_08, setup_test, teardown_test,
762 (void *)&test_case_channel_conn_08_state)
764 total_tests += sizeof(blackbox_group0_tests) / sizeof(blackbox_group0_tests[0]);
766 return cmocka_run_group_tests(blackbox_group0_tests, black_box_group_setup, black_box_group_teardown);