2 test_cases.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.
24 #include "execute_tests.h"
25 #include "test_cases.h"
27 #include "../common/containers.h"
28 #include "../common/test_step.h"
29 #include "../common/common_handlers.h"
30 #include "../common/mesh_event_handler.h"
36 static void test_case_meta_conn_01(void **state);
37 static bool test_steps_meta_conn_01(void);
38 static void test_case_meta_conn_02(void **state);
39 static bool test_steps_meta_conn_02(void);
40 static void test_case_meta_conn_03(void **state);
41 static bool test_steps_meta_conn_03(void);
42 static void test_case_meta_conn_04(void **state);
43 static bool test_steps_meta_conn_04(void);
44 static void test_case_meta_conn_05(void **state);
45 static bool test_steps_meta_conn_05(void);
47 /* State structure for Meta-connections Test Case #1 */
48 static char *test_meta_conn_1_nodes[] = { "relay", "peer", "nut" };
49 static black_box_state_t test_meta_conn_1_state = {
50 .test_case_name = "test_case_meta_conn_01",
51 .node_names = test_meta_conn_1_nodes,
55 /* State structure for Meta-connections Test Case #2 */
56 static char *test_meta_conn_2_nodes[] = { "relay", "peer", "nut" };
57 static black_box_state_t test_meta_conn_2_state = {
58 .test_case_name = "test_case_meta_conn_02",
59 .node_names = test_meta_conn_2_nodes,
63 /* State structure for Meta-connections Test Case #3 */
64 static char *test_meta_conn_3_nodes[] = { "relay", "peer", "nut" };
65 static black_box_state_t test_meta_conn_3_state = {
66 .test_case_name = "test_case_meta_conn_03",
67 .node_names = test_meta_conn_3_nodes,
71 /* State structure for Meta-connections Test Case #4 */
72 static char *test_meta_conn_4_nodes[] = { "peer", "nut" };
73 static black_box_state_t test_meta_conn_4_state = {
74 .test_case_name = "test_case_meta_conn_04",
75 .node_names = test_meta_conn_4_nodes,
79 /* State structure for Meta-connections Test Case #5 */
80 static char *test_meta_conn_5_nodes[] = { "peer", "nut" };
81 static black_box_state_t test_meta_conn_5_state = {
82 .test_case_name = "test_case_meta_conn_05",
83 .node_names = test_meta_conn_5_nodes,
87 int black_box_group0_setup(void **state) {
90 const char *nodes[] = { "peer", "relay", "nut"};
91 int num_nodes = sizeof(nodes) / sizeof(nodes[0]);
93 PRINT_TEST_CASE_MSG("Creating Containers\n");
95 create_containers(nodes, num_nodes);
100 int black_box_group0_teardown(void **state) {
103 PRINT_TEST_CASE_MSG("Destroying Containers\n");
104 destroy_containers();
109 int black_box_all_nodes_setup(void **state) {
112 const char *nodes[] = { "peer" };
113 int num_nodes = sizeof(nodes) / sizeof(nodes[0]);
115 PRINT_TEST_CASE_MSG("Creating Containers\n");
116 destroy_containers();
117 create_containers(nodes, num_nodes);
118 PRINT_TEST_CASE_MSG("Created Containers\n");
122 static bool meta_conn01_conn;
123 static bool meta_conn01_closed;
124 static bool meta_conn01_reconn;
126 static bool meta_conn01_cb(mesh_event_payload_t payload) {
127 char event_node_name[][10] = {"RELAY", "PEER", "NUT"};
128 fprintf(stderr, "%s : ", event_node_name[payload.client_id]);
130 switch(payload.mesh_event) {
131 case META_CONN_SUCCESSFUL :
132 meta_conn01_conn = true;
136 fprintf(stderr, "Node started\n");
139 case META_CONN_CLOSED :
140 meta_conn01_closed = true;
143 case META_RECONN_SUCCESSFUL :
144 meta_conn01_reconn = true;
154 /* Execute Meta-connections Test Case # 1 - re-connection to peer after disconnection when
155 connected via a third node */
156 static void test_case_meta_conn_01(void **state) {
157 execute_test(test_steps_meta_conn_01, state);
160 /* Test Steps for Meta-connections Test Case # 1 - re-connection to peer after disconnection when
161 connected via a third (relay) node
164 1. Run NUT, relay and peer nodes with relay inviting the other two nodes
165 2. After connection to peer, terminate the peer node's running instance
166 3. After peer becomes unreachable, wait 60 seconds then re-start the peer node's instance
169 NUT is re-connected to peer
171 static bool test_steps_meta_conn_01(void) {
172 char *invite_peer, *invite_nut;
175 import = mesh_event_sock_create(eth_if_name);
176 invite_peer = invite_in_container("relay", "peer");
177 invite_nut = invite_in_container("relay", NUT_NODE_NAME);
178 node_sim_in_container_event("relay", "1", NULL, RELAY_ID, import);
179 wait_for_event(meta_conn01_cb, 5);
180 node_sim_in_container_event("peer", "1", invite_peer, PEER_ID, import);
181 wait_for_event(meta_conn01_cb, 5);
182 node_sim_in_container_event("nut", "1", invite_nut, NUT_ID, import);
183 wait_for_event(meta_conn01_cb, 5);
185 PRINT_TEST_CASE_MSG("Waiting for peer to be connected with NUT\n");
186 assert(wait_for_event(meta_conn01_cb, 60));
187 assert(meta_conn01_conn);
189 PRINT_TEST_CASE_MSG("Sending SIGTERM to peer\n");
190 node_step_in_container("peer", "SIGTERM");
191 PRINT_TEST_CASE_MSG("Waiting for peer to become unreachable\n");
192 assert(wait_for_event(meta_conn01_cb, 60));
193 assert(meta_conn01_closed);
195 node_sim_in_container_event("peer", "1", NULL, PEER_ID, import);
196 wait_for_event(meta_conn01_cb, 5);
197 PRINT_TEST_CASE_MSG("Waiting for peer to be re-connected\n");
198 wait_for_event(meta_conn01_cb, 60);
200 mesh_event_destroy();
204 assert_int_equal(meta_conn01_reconn, true);
210 static bool meta_conn02_conn;
212 static bool meta_conn02_cb(mesh_event_payload_t payload) {
213 char event_node_name[][10] = {"RELAY", "PEER", "NUT"};
214 fprintf(stderr, "%s : ", event_node_name[payload.client_id]);
216 switch(payload.mesh_event) {
217 case META_CONN_SUCCESSFUL :
218 fprintf(stderr, "Meta Connection Successful\n");
219 meta_conn02_conn = true;
223 fprintf(stderr, "Node started\n");
232 /* Execute Meta-connections Test Case # 2 - re-connection to peer via third node
233 after changing IP of NUT and peer */
234 static void test_case_meta_conn_02(void **state) {
235 execute_test(test_steps_meta_conn_02, state);
237 /* Test Steps for Meta-connections Test Case # 2 - re-connection to peer via third node
238 after changing IP of NUT and peer
241 1. Run NUT, relay and peer nodes with relay inviting the other two nodes
242 2. After connection to peer, change the NUT's IP Address and the peer node's IP Address
245 NUT is first disconnected from peer then automatically re-connected to peer
247 static bool test_steps_meta_conn_02(void) {
248 char *invite_peer, *invite_nut;
251 import = mesh_event_sock_create(eth_if_name);
252 invite_peer = invite_in_container("relay", "peer");
253 invite_nut = invite_in_container("relay", NUT_NODE_NAME);
254 node_sim_in_container_event("relay", "1", NULL, RELAY_ID, import);
255 wait_for_event(meta_conn02_cb, 5);
256 node_sim_in_container_event("peer", "1", invite_peer, PEER_ID, import);
257 wait_for_event(meta_conn02_cb, 5);
258 node_sim_in_container_event("nut", "1", invite_nut, NUT_ID, import);
259 wait_for_event(meta_conn02_cb, 5);
261 PRINT_TEST_CASE_MSG("Waiting for peer to be connected with NUT\n");
262 assert(wait_for_event(meta_conn02_cb, 60));
263 assert(meta_conn02_conn);
265 meta_conn02_conn = false;
266 node_sim_in_container_event("peer", "1", NULL, PEER_ID, import);
267 wait_for_event(meta_conn02_cb, 5);
268 node_sim_in_container_event("nut", "1", NULL, NUT_ID, import);
269 wait_for_event(meta_conn02_cb, 5);
271 PRINT_TEST_CASE_MSG("Waiting for peer to be connected with NUT\n");
272 wait_for_event(meta_conn02_cb, 60);
274 mesh_event_destroy();
278 assert_int_equal(meta_conn02_conn, true);
283 static bool meta_conn03_result;
284 static bool meta_conn03_conn;
286 static bool meta_conn03_cb(mesh_event_payload_t payload) {
287 char event_node_name[][10] = {"RELAY", "PEER", "NUT"};
288 fprintf(stderr, "%s : ", event_node_name[payload.client_id]);
290 switch(payload.mesh_event) {
291 case META_CONN_SUCCESSFUL :
292 fprintf(stderr, "Meta Connection Successful\n");
293 meta_conn03_conn = true;
297 fprintf(stderr, "Node started\n");
300 case META_RECONN_FAILURE :
301 fprintf(stderr, "Failed to reconnect with");
302 meta_conn03_result = false;
305 case META_RECONN_SUCCESSFUL :
306 fprintf(stderr, "Reconnected\n");
307 meta_conn03_result = true;
316 /* Execute Meta-connections Test Case # 3 - re-connection to peer via third node
317 after changing IP of peer */
318 static void test_case_meta_conn_03(void **state) {
319 execute_test(test_steps_meta_conn_03, state);
321 /* Test Steps for Meta-connections Test Case # 3 - re-connection to peer via third node
322 after changing IP of peer
325 1. Run NUT, relay and peer nodes with relay inviting the other two nodes
326 2. After connection to peer, change the peer node's IP Address
329 NUT is first disconnected from peer then automatically re-connected to peer
331 static bool test_steps_meta_conn_03(void) {
332 char *invite_peer, *invite_nut;
335 import = mesh_event_sock_create(eth_if_name);
336 invite_peer = invite_in_container("relay", "peer");
337 invite_nut = invite_in_container("relay", NUT_NODE_NAME);
338 node_sim_in_container_event("relay", "1", NULL, RELAY_ID, import);
339 wait_for_event(meta_conn03_cb, 5);
340 node_sim_in_container_event("peer", "1", invite_peer, PEER_ID, import);
341 wait_for_event(meta_conn03_cb, 5);
342 node_sim_in_container_event("nut", "1", invite_nut, NUT_ID, import);
343 wait_for_event(meta_conn03_cb, 5);
345 PRINT_TEST_CASE_MSG("Waiting for peer to be connected with NUT\n");
346 assert(wait_for_event(meta_conn03_cb, 60));
347 assert(meta_conn03_conn);
349 PRINT_TEST_CASE_MSG("Changing IP address of PEER container\n");
352 node_sim_in_container_event("peer", "1", NULL, PEER_ID, import);
353 wait_for_event(meta_conn03_cb, 5);
354 PRINT_TEST_CASE_MSG("Waiting for peer to be re-connected\n");
355 wait_for_event(meta_conn03_cb, 5);
357 mesh_event_destroy();
361 assert_int_equal(meta_conn03_result, true);
366 static char *invite_peer = NULL;
367 static bool meta_conn04 = false;
369 static bool meta_conn04_cb(mesh_event_payload_t payload) {
370 char event_node_name[][10] = {"PEER", "NUT"};
371 fprintf(stderr, "%s : ", event_node_name[payload.client_id]);
373 switch(payload.mesh_event) {
374 case META_CONN_SUCCESSFUL :
375 fprintf(stderr, "Meta Connection Successful\n");
379 case NODE_INVITATION :
380 fprintf(stderr, "Invitation generated\n");
381 invite_peer = malloc(payload.payload_length);
382 strcpy(invite_peer, (char *)payload.payload);
386 fprintf(stderr, "Node started\n");
390 fprintf(stderr, "Undefined mesh event\n");
397 /* Execute Meta-connections Test Case # 4 - re-connection to peer after changing IP of
399 static void test_case_meta_conn_04(void **state) {
400 execute_test(test_steps_meta_conn_04, state);
403 /* Execute Meta-connections Test Case # 4 - re-connection to peer after changing IP of
407 1. Run NUT and peer nodes with NUT inviting the peer node
408 2. After connection to peer, change the NUT's IP Address and the peer node's IP Address
411 NUT is first disconnected from peer then automatically re-connected to peer
413 static bool test_steps_meta_conn_04(void) {
416 import = mesh_event_sock_create(eth_if_name);
417 node_sim_in_container_event("nut", "1", NULL, "1", import);
418 wait_for_event(meta_conn04_cb, 5);
420 PRINT_TEST_CASE_MSG("Waiting for NUT to generate invitation to PEER\n");
421 wait_for_event(meta_conn04_cb, 5);
425 PRINT_TEST_CASE_MSG("Running PEER node in the container\n");
426 fprintf(stderr, "inv: %s\n", invite_peer);
427 node_sim_in_container_event("peer", "1", invite_peer, "0", import);
428 wait_for_event(meta_conn04_cb, 5);
429 PRINT_TEST_CASE_MSG("Waiting for peer to be connected with NUT\n");
431 assert(wait_for_event(meta_conn04_cb, 60));
433 PRINT_TEST_CASE_MSG("Changing IP address of NUT container\n");
436 node_sim_in_container_event("nut", "1", "restart", "1", import);
437 wait_for_event(meta_conn04_cb, 5);
438 PRINT_TEST_CASE_MSG("Changing IP address of PEER container\n");
440 node_sim_in_container_event("peer", "1", NULL, "0", import);
441 wait_for_event(meta_conn04_cb, 5);
443 PRINT_TEST_CASE_MSG("Waiting for peer to be re-connected\n");
444 wait_for_event(meta_conn04_cb, 5);
446 mesh_event_destroy();
450 assert_int_equal(meta_conn04, true);
455 static char *invitation = NULL;
457 static bool meta_conn05 = false;
459 static bool meta_conn05_cb(mesh_event_payload_t payload) {
460 char event_node_name[][10] = {"PEER", "NUT"};
461 fprintf(stderr, "%s : ", event_node_name[payload.client_id]);
463 switch(payload.mesh_event) {
464 case META_CONN_SUCCESSFUL :
468 case NODE_INVITATION :
469 invitation = malloc(payload.payload_length);
470 strcpy(invitation, (char *)payload.payload);
474 fprintf(stderr, "Node started\n");
484 /* Execute Meta-connections Test Case # 5 - re-connection to peer after changing IP of peer */
485 static void test_case_meta_conn_05(void **state) {
486 execute_test(test_steps_meta_conn_05, state);
489 /* Execute Meta-connections Test Case # 5 - re-connection to peer after changing IP of peer
492 1. Run NUT and peer nodes with NUT inviting the peer node
493 2. After connection to peer, change the peer node's IP Address
496 NUT is first disconnected from peer then automatically re-connected to peer
498 static bool test_steps_meta_conn_05(void) {
501 import = mesh_event_sock_create(eth_if_name);
502 node_sim_in_container_event("nut", "1", NULL, "1", import);
503 wait_for_event(meta_conn05_cb, 5);
505 wait_for_event(meta_conn05_cb, 5);
509 node_sim_in_container_event("peer", "1", invitation, "0", import);
510 wait_for_event(meta_conn05_cb, 5);
512 assert(wait_for_event(meta_conn05_cb, 5));
516 node_sim_in_container_event("peer", "1", NULL, "0", import);
517 wait_for_event(meta_conn05_cb, 5);
518 PRINT_TEST_CASE_MSG("Waiting for peer to be re-connected\n");
519 wait_for_event(meta_conn05_cb, 5);
521 mesh_event_destroy();
525 assert_int_equal(meta_conn05, true);
530 int test_meta_conn(void) {
531 const struct CMUnitTest blackbox_group0_tests[] = {
532 cmocka_unit_test_prestate_setup_teardown(test_case_meta_conn_01, setup_test, teardown_test,
533 (void *)&test_meta_conn_1_state),
534 cmocka_unit_test_prestate_setup_teardown(test_case_meta_conn_02, setup_test, teardown_test,
535 (void *)&test_meta_conn_2_state),
536 cmocka_unit_test_prestate_setup_teardown(test_case_meta_conn_03, setup_test, teardown_test,
537 (void *)&test_meta_conn_3_state),
538 cmocka_unit_test_prestate_setup_teardown(test_case_meta_conn_04, setup_test, teardown_test,
539 (void *)&test_meta_conn_4_state),
540 cmocka_unit_test_prestate_setup_teardown(test_case_meta_conn_05, setup_test, teardown_test,
541 (void *)&test_meta_conn_5_state)
543 total_tests += sizeof(blackbox_group0_tests) / sizeof(blackbox_group0_tests[0]);
545 return cmocka_run_group_tests(blackbox_group0_tests, black_box_group0_setup, black_box_group0_teardown);