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.
29 #include "execute_tests.h"
30 #include "test_cases.h"
32 #include "../common/containers.h"
33 #include "../common/test_step.h"
34 #include "../common/common_handlers.h"
35 #include "../common/mesh_event_handler.h"
41 static void test_case_meta_conn_01(void **state);
42 static bool test_steps_meta_conn_01(void);
43 static void test_case_meta_conn_02(void **state);
44 static bool test_steps_meta_conn_02(void);
45 static void test_case_meta_conn_03(void **state);
46 static bool test_steps_meta_conn_03(void);
47 static void test_case_meta_conn_04(void **state);
48 static bool test_steps_meta_conn_04(void);
49 static void test_case_meta_conn_05(void **state);
50 static bool test_steps_meta_conn_05(void);
52 /* State structure for Meta-connections Test Case #1 */
53 static char *test_meta_conn_1_nodes[] = { "relay", "peer", "nut" };
54 static black_box_state_t test_meta_conn_1_state = {
55 .test_case_name = "test_case_meta_conn_01",
56 .node_names = test_meta_conn_1_nodes,
60 /* State structure for Meta-connections Test Case #2 */
61 static char *test_meta_conn_2_nodes[] = { "relay", "peer", "nut" };
62 static black_box_state_t test_meta_conn_2_state = {
63 .test_case_name = "test_case_meta_conn_02",
64 .node_names = test_meta_conn_2_nodes,
68 /* State structure for Meta-connections Test Case #3 */
69 static char *test_meta_conn_3_nodes[] = { "relay", "peer", "nut" };
70 static black_box_state_t test_meta_conn_3_state = {
71 .test_case_name = "test_case_meta_conn_03",
72 .node_names = test_meta_conn_3_nodes,
76 /* State structure for Meta-connections Test Case #4 */
77 static char *test_meta_conn_4_nodes[] = { "peer", "nut" };
78 static black_box_state_t test_meta_conn_4_state = {
79 .test_case_name = "test_case_meta_conn_04",
80 .node_names = test_meta_conn_4_nodes,
84 /* State structure for Meta-connections Test Case #5 */
85 static char *test_meta_conn_5_nodes[] = { "peer", "nut" };
86 static black_box_state_t test_meta_conn_5_state = {
87 .test_case_name = "test_case_meta_conn_05",
88 .node_names = test_meta_conn_5_nodes,
92 int black_box_group0_setup(void **state) {
95 const char *nodes[] = { "peer", "relay", "nut"};
96 int num_nodes = sizeof(nodes) / sizeof(nodes[0]);
98 PRINT_TEST_CASE_MSG("Creating Containers\n");
100 create_containers(nodes, num_nodes);
105 int black_box_group0_teardown(void **state) {
108 PRINT_TEST_CASE_MSG("Destroying Containers\n");
109 destroy_containers();
114 int black_box_all_nodes_setup(void **state) {
117 const char *nodes[] = { "peer" };
118 int num_nodes = sizeof(nodes) / sizeof(nodes[0]);
120 PRINT_TEST_CASE_MSG("Creating Containers\n");
121 destroy_containers();
122 create_containers(nodes, num_nodes);
123 PRINT_TEST_CASE_MSG("Created Containers\n");
127 static bool meta_conn01_conn;
128 static bool meta_conn01_closed;
129 static bool meta_conn01_reconn;
131 static bool meta_conn01_cb(mesh_event_payload_t payload) {
132 char event_node_name[][10] = {"RELAY", "PEER", "NUT"};
133 fprintf(stderr, "%s : ", event_node_name[payload.client_id]);
135 switch(payload.mesh_event) {
136 case META_CONN_SUCCESSFUL :
137 meta_conn01_conn = true;
141 fprintf(stderr, "Node started\n");
144 case META_CONN_CLOSED :
145 meta_conn01_closed = true;
148 case META_RECONN_SUCCESSFUL :
149 meta_conn01_reconn = true;
159 /* Execute Meta-connections Test Case # 1 - re-connection to peer after disconnection when
160 connected via a third node */
161 static void test_case_meta_conn_01(void **state) {
162 execute_test(test_steps_meta_conn_01, state);
165 /* Test Steps for Meta-connections Test Case # 1 - re-connection to peer after disconnection when
166 connected via a third (relay) node
169 1. Run NUT, relay and peer nodes with relay inviting the other two nodes
170 2. After connection to peer, terminate the peer node's running instance
171 3. After peer becomes unreachable, wait 60 seconds then re-start the peer node's instance
174 NUT is re-connected to peer
176 static bool test_steps_meta_conn_01(void) {
177 char *invite_peer, *invite_nut;
180 import = mesh_event_sock_create(eth_if_name);
181 invite_peer = invite_in_container("relay", "peer");
182 invite_nut = invite_in_container("relay", NUT_NODE_NAME);
183 node_sim_in_container_event("relay", "1", NULL, RELAY_ID, import);
184 wait_for_event(meta_conn01_cb, 5);
185 node_sim_in_container_event("peer", "1", invite_peer, PEER_ID, import);
186 wait_for_event(meta_conn01_cb, 5);
187 node_sim_in_container_event("nut", "1", invite_nut, NUT_ID, import);
188 wait_for_event(meta_conn01_cb, 5);
190 PRINT_TEST_CASE_MSG("Waiting for peer to be connected with NUT\n");
191 assert(wait_for_event(meta_conn01_cb, 60));
192 assert(meta_conn01_conn);
194 PRINT_TEST_CASE_MSG("Sending SIGTERM to peer\n");
195 node_step_in_container("peer", "SIGTERM");
196 PRINT_TEST_CASE_MSG("Waiting for peer to become unreachable\n");
197 assert(wait_for_event(meta_conn01_cb, 60));
198 assert(meta_conn01_closed);
200 node_sim_in_container_event("peer", "1", NULL, PEER_ID, import);
201 wait_for_event(meta_conn01_cb, 5);
202 PRINT_TEST_CASE_MSG("Waiting for peer to be re-connected\n");
203 wait_for_event(meta_conn01_cb, 60);
205 mesh_event_destroy();
209 assert_int_equal(meta_conn01_reconn, true);
215 static bool meta_conn02_conn;
217 static bool meta_conn02_cb(mesh_event_payload_t payload) {
218 char event_node_name[][10] = {"RELAY", "PEER", "NUT"};
219 fprintf(stderr, "%s : ", event_node_name[payload.client_id]);
221 switch(payload.mesh_event) {
222 case META_CONN_SUCCESSFUL :
223 fprintf(stderr, "Meta Connection Successful\n");
224 meta_conn02_conn = true;
228 fprintf(stderr, "Node started\n");
237 /* Execute Meta-connections Test Case # 2 - re-connection to peer via third node
238 after changing IP of NUT and peer */
239 static void test_case_meta_conn_02(void **state) {
240 execute_test(test_steps_meta_conn_02, state);
242 /* Test Steps for Meta-connections Test Case # 2 - re-connection to peer via third node
243 after changing IP of NUT and peer
246 1. Run NUT, relay and peer nodes with relay inviting the other two nodes
247 2. After connection to peer, change the NUT's IP Address and the peer node's IP Address
250 NUT is first disconnected from peer then automatically re-connected to peer
252 static bool test_steps_meta_conn_02(void) {
253 char *invite_peer, *invite_nut;
256 import = mesh_event_sock_create(eth_if_name);
257 invite_peer = invite_in_container("relay", "peer");
258 invite_nut = invite_in_container("relay", NUT_NODE_NAME);
259 node_sim_in_container_event("relay", "1", NULL, RELAY_ID, import);
260 wait_for_event(meta_conn02_cb, 5);
261 node_sim_in_container_event("peer", "1", invite_peer, PEER_ID, import);
262 wait_for_event(meta_conn02_cb, 5);
263 node_sim_in_container_event("nut", "1", invite_nut, NUT_ID, import);
264 wait_for_event(meta_conn02_cb, 5);
266 PRINT_TEST_CASE_MSG("Waiting for peer to be connected with NUT\n");
267 assert(wait_for_event(meta_conn02_cb, 60));
268 assert(meta_conn02_conn);
270 meta_conn02_conn = false;
271 node_sim_in_container_event("peer", "1", NULL, PEER_ID, import);
272 wait_for_event(meta_conn02_cb, 5);
273 node_sim_in_container_event("nut", "1", NULL, NUT_ID, import);
274 wait_for_event(meta_conn02_cb, 5);
276 PRINT_TEST_CASE_MSG("Waiting for peer to be connected with NUT\n");
277 wait_for_event(meta_conn02_cb, 60);
279 mesh_event_destroy();
283 assert_int_equal(meta_conn02_conn, true);
288 static bool meta_conn03_result;
289 static bool meta_conn03_conn;
291 static bool meta_conn03_cb(mesh_event_payload_t payload) {
292 char event_node_name[][10] = {"RELAY", "PEER", "NUT"};
293 fprintf(stderr, "%s : ", event_node_name[payload.client_id]);
295 switch(payload.mesh_event) {
296 case META_CONN_SUCCESSFUL :
297 fprintf(stderr, "Meta Connection Successful\n");
298 meta_conn03_conn = true;
302 fprintf(stderr, "Node started\n");
305 case META_RECONN_FAILURE :
306 fprintf(stderr, "Failed to reconnect with");
307 meta_conn03_result = false;
310 case META_RECONN_SUCCESSFUL :
311 fprintf(stderr, "Reconnected\n");
312 meta_conn03_result = true;
321 /* Execute Meta-connections Test Case # 3 - re-connection to peer via third node
322 after changing IP of peer */
323 static void test_case_meta_conn_03(void **state) {
324 execute_test(test_steps_meta_conn_03, state);
326 /* Test Steps for Meta-connections Test Case # 3 - re-connection to peer via third node
327 after changing IP of peer
330 1. Run NUT, relay and peer nodes with relay inviting the other two nodes
331 2. After connection to peer, change the peer node's IP Address
334 NUT is first disconnected from peer then automatically re-connected to peer
336 static bool test_steps_meta_conn_03(void) {
337 char *invite_peer, *invite_nut;
340 import = mesh_event_sock_create(eth_if_name);
341 invite_peer = invite_in_container("relay", "peer");
342 invite_nut = invite_in_container("relay", NUT_NODE_NAME);
343 node_sim_in_container_event("relay", "1", NULL, RELAY_ID, import);
344 wait_for_event(meta_conn03_cb, 5);
345 node_sim_in_container_event("peer", "1", invite_peer, PEER_ID, import);
346 wait_for_event(meta_conn03_cb, 5);
347 node_sim_in_container_event("nut", "1", invite_nut, NUT_ID, import);
348 wait_for_event(meta_conn03_cb, 5);
350 PRINT_TEST_CASE_MSG("Waiting for peer to be connected with NUT\n");
351 assert(wait_for_event(meta_conn03_cb, 60));
352 assert(meta_conn03_conn);
354 PRINT_TEST_CASE_MSG("Changing IP address of PEER container\n");
357 node_sim_in_container_event("peer", "1", NULL, PEER_ID, import);
358 wait_for_event(meta_conn03_cb, 5);
359 PRINT_TEST_CASE_MSG("Waiting for peer to be re-connected\n");
360 wait_for_event(meta_conn03_cb, 5);
362 mesh_event_destroy();
366 assert_int_equal(meta_conn03_result, true);
371 static char *invite_peer = NULL;
372 static bool meta_conn04 = false;
374 static bool meta_conn04_cb(mesh_event_payload_t payload) {
375 char event_node_name[][10] = {"PEER", "NUT"};
376 fprintf(stderr, "%s : ", event_node_name[payload.client_id]);
378 switch(payload.mesh_event) {
379 case META_CONN_SUCCESSFUL :
380 fprintf(stderr, "Meta Connection Successful\n");
384 case NODE_INVITATION :
385 fprintf(stderr, "Invitation generated\n");
386 invite_peer = malloc(payload.payload_length);
387 strcpy(invite_peer, (char *)payload.payload);
391 fprintf(stderr, "Node started\n");
395 fprintf(stderr, "Undefined mesh event\n");
402 /* Execute Meta-connections Test Case # 4 - re-connection to peer after changing IP of
404 static void test_case_meta_conn_04(void **state) {
405 execute_test(test_steps_meta_conn_04, state);
408 /* Execute Meta-connections Test Case # 4 - re-connection to peer after changing IP of
412 1. Run NUT and peer nodes with NUT inviting the peer node
413 2. After connection to peer, change the NUT's IP Address and the peer node's IP Address
416 NUT is first disconnected from peer then automatically re-connected to peer
418 static bool test_steps_meta_conn_04(void) {
421 import = mesh_event_sock_create(eth_if_name);
422 node_sim_in_container_event("nut", "1", NULL, "1", import);
423 wait_for_event(meta_conn04_cb, 5);
425 PRINT_TEST_CASE_MSG("Waiting for NUT to generate invitation to PEER\n");
426 wait_for_event(meta_conn04_cb, 5);
430 PRINT_TEST_CASE_MSG("Running PEER node in the container\n");
431 fprintf(stderr, "inv: %s\n", invite_peer);
432 node_sim_in_container_event("peer", "1", invite_peer, "0", import);
433 wait_for_event(meta_conn04_cb, 5);
434 PRINT_TEST_CASE_MSG("Waiting for peer to be connected with NUT\n");
436 assert(wait_for_event(meta_conn04_cb, 60));
438 PRINT_TEST_CASE_MSG("Changing IP address of NUT container\n");
441 node_sim_in_container_event("nut", "1", "restart", "1", import);
442 wait_for_event(meta_conn04_cb, 5);
443 PRINT_TEST_CASE_MSG("Changing IP address of PEER container\n");
445 node_sim_in_container_event("peer", "1", NULL, "0", import);
446 wait_for_event(meta_conn04_cb, 5);
448 PRINT_TEST_CASE_MSG("Waiting for peer to be re-connected\n");
449 wait_for_event(meta_conn04_cb, 5);
451 mesh_event_destroy();
455 assert_int_equal(meta_conn04, true);
460 static char *invitation = NULL;
462 static bool meta_conn05 = false;
464 static bool meta_conn05_cb(mesh_event_payload_t payload) {
465 char event_node_name[][10] = {"PEER", "NUT"};
466 fprintf(stderr, "%s : ", event_node_name[payload.client_id]);
468 switch(payload.mesh_event) {
469 case META_CONN_SUCCESSFUL :
473 case NODE_INVITATION :
474 invitation = malloc(payload.payload_length);
475 strcpy(invitation, (char *)payload.payload);
479 fprintf(stderr, "Node started\n");
489 /* Execute Meta-connections Test Case # 5 - re-connection to peer after changing IP of peer */
490 static void test_case_meta_conn_05(void **state) {
491 execute_test(test_steps_meta_conn_05, state);
494 /* Execute Meta-connections Test Case # 5 - re-connection to peer after changing IP of peer
497 1. Run NUT and peer nodes with NUT inviting the peer node
498 2. After connection to peer, change the peer node's IP Address
501 NUT is first disconnected from peer then automatically re-connected to peer
503 static bool test_steps_meta_conn_05(void) {
506 import = mesh_event_sock_create(eth_if_name);
507 node_sim_in_container_event("nut", "1", NULL, "1", import);
508 wait_for_event(meta_conn05_cb, 5);
510 wait_for_event(meta_conn05_cb, 5);
514 node_sim_in_container_event("peer", "1", invitation, "0", import);
515 wait_for_event(meta_conn05_cb, 5);
517 assert(wait_for_event(meta_conn05_cb, 5));
521 node_sim_in_container_event("peer", "1", NULL, "0", import);
522 wait_for_event(meta_conn05_cb, 5);
523 PRINT_TEST_CASE_MSG("Waiting for peer to be re-connected\n");
524 wait_for_event(meta_conn05_cb, 5);
526 mesh_event_destroy();
530 assert_int_equal(meta_conn05, true);
535 int test_meta_conn(void) {
536 const struct CMUnitTest blackbox_group0_tests[] = {
537 cmocka_unit_test_prestate_setup_teardown(test_case_meta_conn_01, setup_test, teardown_test,
538 (void *)&test_meta_conn_1_state),
539 cmocka_unit_test_prestate_setup_teardown(test_case_meta_conn_02, setup_test, teardown_test,
540 (void *)&test_meta_conn_2_state),
541 cmocka_unit_test_prestate_setup_teardown(test_case_meta_conn_03, setup_test, teardown_test,
542 (void *)&test_meta_conn_3_state),
543 cmocka_unit_test_prestate_setup_teardown(test_case_meta_conn_04, setup_test, teardown_test,
544 (void *)&test_meta_conn_4_state),
545 cmocka_unit_test_prestate_setup_teardown(test_case_meta_conn_05, setup_test, teardown_test,
546 (void *)&test_meta_conn_5_state)
548 total_tests += sizeof(blackbox_group0_tests) / sizeof(blackbox_group0_tests[0]);
550 return cmocka_run_group_tests(blackbox_group0_tests, black_box_group0_setup, black_box_group0_teardown);