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) {
88 const char *nodes[] = { "peer", "relay", "nut"};
89 int num_nodes = sizeof(nodes) / sizeof(nodes[0]);
91 PRINT_TEST_CASE_MSG("Creating Containers\n");
93 create_containers(nodes, num_nodes);
98 int black_box_group0_teardown(void **state) {
99 PRINT_TEST_CASE_MSG("Destroying Containers\n");
100 destroy_containers();
105 int black_box_all_nodes_setup(void **state) {
106 const char *nodes[] = { "peer" };
107 int num_nodes = sizeof(nodes) / sizeof(nodes[0]);
109 PRINT_TEST_CASE_MSG("Creating Containers\n");
110 destroy_containers();
111 create_containers(nodes, num_nodes);
112 PRINT_TEST_CASE_MSG("Created Containers\n");
116 static bool meta_conn01_conn;
117 static bool meta_conn01_closed;
118 static bool meta_conn01_reconn;
120 static bool meta_conn01_cb(mesh_event_payload_t payload) {
121 char event_node_name[][10] = {"RELAY", "PEER", "NUT"};
122 fprintf(stderr, "%s : ", event_node_name[payload.client_id]);
124 switch(payload.mesh_event) {
125 case META_CONN_SUCCESSFUL :
126 meta_conn01_conn = true;
130 fprintf(stderr, "Node started\n");
133 case META_CONN_CLOSED :
134 meta_conn01_closed = true;
137 case META_RECONN_SUCCESSFUL :
138 meta_conn01_reconn = true;
145 /* Execute Meta-connections Test Case # 1 - re-connection to peer after disconnection when
146 connected via a third node */
147 static void test_case_meta_conn_01(void **state) {
148 execute_test(test_steps_meta_conn_01, state);
151 /* Test Steps for Meta-connections Test Case # 1 - re-connection to peer after disconnection when
152 connected via a third (relay) node
155 1. Run NUT, relay and peer nodes with relay inviting the other two nodes
156 2. After connection to peer, terminate the peer node's running instance
157 3. After peer becomes unreachable, wait 60 seconds then re-start the peer node's instance
160 NUT is re-connected to peer
162 static bool test_steps_meta_conn_01(void) {
163 char *invite_peer, *invite_nut;
167 import = mesh_event_sock_create(eth_if_name);
168 invite_peer = invite_in_container("relay", "peer");
169 invite_nut = invite_in_container("relay", NUT_NODE_NAME);
170 node_sim_in_container_event("relay", "1", NULL, RELAY_ID, import);
171 wait_for_event(meta_conn01_cb, 5);
172 node_sim_in_container_event("peer", "1", invite_peer, PEER_ID, import);
173 wait_for_event(meta_conn01_cb, 5);
174 node_sim_in_container_event("nut", "1", invite_nut, NUT_ID, import);
175 wait_for_event(meta_conn01_cb, 5);
177 PRINT_TEST_CASE_MSG("Waiting for peer to be connected with NUT\n");
178 assert(wait_for_event(meta_conn01_cb, 60));
179 assert(meta_conn01_conn);
181 PRINT_TEST_CASE_MSG("Sending SIGTERM to peer\n");
182 node_step_in_container("peer", "SIGTERM");
183 PRINT_TEST_CASE_MSG("Waiting for peer to become unreachable\n");
184 assert(wait_for_event(meta_conn01_cb, 60));
185 assert(meta_conn01_closed);
187 node_sim_in_container_event("peer", "1", NULL, PEER_ID, import);
188 wait_for_event(meta_conn01_cb, 5);
189 PRINT_TEST_CASE_MSG("Waiting for peer to be re-connected\n");
190 wait_for_event(meta_conn01_cb, 60);
192 mesh_event_destroy();
196 assert_int_equal(meta_conn01_reconn, true);
202 static bool meta_conn02_conn;
204 static bool meta_conn02_cb(mesh_event_payload_t payload) {
205 char event_node_name[][10] = {"RELAY", "PEER", "NUT"};
206 fprintf(stderr, "%s : ", event_node_name[payload.client_id]);
208 switch(payload.mesh_event) {
209 case META_CONN_SUCCESSFUL :
210 fprintf(stderr, "Meta Connection Successful\n");
211 meta_conn02_conn = true;
215 fprintf(stderr, "Node started\n");
221 /* Execute Meta-connections Test Case # 2 - re-connection to peer via third node
222 after changing IP of NUT and peer */
223 static void test_case_meta_conn_02(void **state) {
224 execute_test(test_steps_meta_conn_02, state);
226 /* Test Steps for Meta-connections Test Case # 2 - re-connection to peer via third node
227 after changing IP of NUT and peer
230 1. Run NUT, relay and peer nodes with relay inviting the other two nodes
231 2. After connection to peer, change the NUT's IP Address and the peer node's IP Address
234 NUT is first disconnected from peer then automatically re-connected to peer
236 static bool test_steps_meta_conn_02(void) {
237 char *invite_peer, *invite_nut;
241 import = mesh_event_sock_create(eth_if_name);
242 invite_peer = invite_in_container("relay", "peer");
243 invite_nut = invite_in_container("relay", NUT_NODE_NAME);
244 node_sim_in_container_event("relay", "1", NULL, RELAY_ID, import);
245 wait_for_event(meta_conn02_cb, 5);
246 node_sim_in_container_event("peer", "1", invite_peer, PEER_ID, import);
247 wait_for_event(meta_conn02_cb, 5);
248 node_sim_in_container_event("nut", "1", invite_nut, NUT_ID, import);
249 wait_for_event(meta_conn02_cb, 5);
251 PRINT_TEST_CASE_MSG("Waiting for peer to be connected with NUT\n");
252 assert(wait_for_event(meta_conn02_cb, 60));
253 assert(meta_conn02_conn);
255 meta_conn02_conn = false;
256 node_sim_in_container_event("peer", "1", NULL, PEER_ID, import);
257 wait_for_event(meta_conn02_cb, 5);
258 node_sim_in_container_event("nut", "1", NULL, 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 wait_for_event(meta_conn02_cb, 60);
264 mesh_event_destroy();
268 assert_int_equal(meta_conn02_conn, true);
273 static bool meta_conn03_result;
274 static bool meta_conn03_conn;
276 static bool meta_conn03_cb(mesh_event_payload_t payload) {
277 char event_node_name[][10] = {"RELAY", "PEER", "NUT"};
278 fprintf(stderr, "%s : ", event_node_name[payload.client_id]);
280 switch(payload.mesh_event) {
281 case META_CONN_SUCCESSFUL :
282 fprintf(stderr, "Meta Connection Successful\n");
283 meta_conn03_conn = true;
287 fprintf(stderr, "Node started\n");
290 case META_RECONN_FAILURE :
291 fprintf(stderr, "Failed to reconnect with");
292 meta_conn03_result = false;
295 case META_RECONN_SUCCESSFUL :
296 fprintf(stderr, "Reconnected\n");
297 meta_conn03_result = true;
303 /* Execute Meta-connections Test Case # 3 - re-connection to peer via third node
304 after changing IP of peer */
305 static void test_case_meta_conn_03(void **state) {
306 execute_test(test_steps_meta_conn_03, state);
308 /* Test Steps for Meta-connections Test Case # 3 - re-connection to peer via third node
309 after changing IP of peer
312 1. Run NUT, relay and peer nodes with relay inviting the other two nodes
313 2. After connection to peer, change the peer node's IP Address
316 NUT is first disconnected from peer then automatically re-connected to peer
318 static bool test_steps_meta_conn_03(void) {
319 char *invite_peer, *invite_nut;
323 import = mesh_event_sock_create(eth_if_name);
324 invite_peer = invite_in_container("relay", "peer");
325 invite_nut = invite_in_container("relay", NUT_NODE_NAME);
326 node_sim_in_container_event("relay", "1", NULL, RELAY_ID, import);
327 wait_for_event(meta_conn03_cb, 5);
328 node_sim_in_container_event("peer", "1", invite_peer, PEER_ID, import);
329 wait_for_event(meta_conn03_cb, 5);
330 node_sim_in_container_event("nut", "1", invite_nut, NUT_ID, import);
331 wait_for_event(meta_conn03_cb, 5);
333 PRINT_TEST_CASE_MSG("Waiting for peer to be connected with NUT\n");
334 assert(wait_for_event(meta_conn03_cb, 60));
335 assert(meta_conn03_conn);
337 PRINT_TEST_CASE_MSG("Changing IP address of PEER container\n");
340 node_sim_in_container_event("peer", "1", NULL, PEER_ID, import);
341 wait_for_event(meta_conn03_cb, 5);
342 PRINT_TEST_CASE_MSG("Waiting for peer to be re-connected\n");
343 wait_for_event(meta_conn03_cb, 5);
345 mesh_event_destroy();
349 assert_int_equal(meta_conn03_result, true);
354 static char *invite_peer = NULL;
355 static bool meta_conn04 = false;
357 static bool meta_conn04_cb(mesh_event_payload_t payload) {
358 char event_node_name[][10] = {"PEER", "NUT"};
359 fprintf(stderr, "%s : ", event_node_name[payload.client_id]);
361 switch(payload.mesh_event) {
362 case META_CONN_SUCCESSFUL :
363 fprintf(stderr, "Meta Connection Successful\n");
367 case NODE_INVITATION :
368 fprintf(stderr, "Invitation generated\n");
369 invite_peer = malloc(payload.payload_length);
370 strcpy(invite_peer, (char *)payload.payload);
374 fprintf(stderr, "Node started\n");
378 fprintf(stderr, "Undefined mesh event\n");
384 /* Execute Meta-connections Test Case # 4 - re-connection to peer after changing IP of
386 static void test_case_meta_conn_04(void **state) {
387 execute_test(test_steps_meta_conn_04, state);
390 /* Execute Meta-connections Test Case # 4 - re-connection to peer after changing IP of
394 1. Run NUT and peer nodes with NUT inviting the peer node
395 2. After connection to peer, change the NUT's IP Address and the peer node's IP Address
398 NUT is first disconnected from peer then automatically re-connected to peer
400 static bool test_steps_meta_conn_04(void) {
403 import = mesh_event_sock_create(eth_if_name);
404 node_sim_in_container_event("nut", "1", NULL, "1", import);
405 wait_for_event(meta_conn04_cb, 5);
407 PRINT_TEST_CASE_MSG("Waiting for NUT to generate invitation to PEER\n");
408 wait_for_event(meta_conn04_cb, 5);
412 PRINT_TEST_CASE_MSG("Running PEER node in the container\n");
413 fprintf(stderr, "inv: %s\n", invite_peer);
414 node_sim_in_container_event("peer", "1", invite_peer, "0", import);
415 wait_for_event(meta_conn04_cb, 5);
416 PRINT_TEST_CASE_MSG("Waiting for peer to be connected with NUT\n");
418 assert(wait_for_event(meta_conn04_cb, 60));
420 PRINT_TEST_CASE_MSG("Changing IP address of NUT container\n");
423 node_sim_in_container_event("nut", "1", "restart", "1", import);
424 wait_for_event(meta_conn04_cb, 5);
425 PRINT_TEST_CASE_MSG("Changing IP address of PEER container\n");
427 node_sim_in_container_event("peer", "1", NULL, "0", import);
428 wait_for_event(meta_conn04_cb, 5);
430 PRINT_TEST_CASE_MSG("Waiting for peer to be re-connected\n");
431 wait_for_event(meta_conn04_cb, 5);
433 mesh_event_destroy();
437 assert_int_equal(meta_conn04, true);
442 static char *invitation = NULL;
444 static bool meta_conn05 = false;
446 static bool meta_conn05_cb(mesh_event_payload_t payload) {
447 char event_node_name[][10] = {"PEER", "NUT"};
448 fprintf(stderr, "%s : ", event_node_name[payload.client_id]);
450 switch(payload.mesh_event) {
451 case META_CONN_SUCCESSFUL :
455 case NODE_INVITATION :
456 invitation = malloc(payload.payload_length);
457 strcpy(invitation, (char *)payload.payload);
461 fprintf(stderr, "Node started\n");
468 /* Execute Meta-connections Test Case # 5 - re-connection to peer after changing IP of peer */
469 static void test_case_meta_conn_05(void **state) {
470 execute_test(test_steps_meta_conn_05, state);
473 /* Execute Meta-connections Test Case # 5 - re-connection to peer after changing IP of peer
476 1. Run NUT and peer nodes with NUT inviting the peer node
477 2. After connection to peer, change the peer node's IP Address
480 NUT is first disconnected from peer then automatically re-connected to peer
482 static bool test_steps_meta_conn_05(void) {
485 import = mesh_event_sock_create(eth_if_name);
486 node_sim_in_container_event("nut", "1", NULL, "1", import);
487 wait_for_event(meta_conn05_cb, 5);
489 wait_for_event(meta_conn05_cb, 5);
493 node_sim_in_container_event("peer", "1", invitation, "0", import);
494 wait_for_event(meta_conn05_cb, 5);
496 assert(wait_for_event(meta_conn05_cb, 5));
500 node_sim_in_container_event("peer", "1", NULL, "0", import);
501 wait_for_event(meta_conn05_cb, 5);
502 PRINT_TEST_CASE_MSG("Waiting for peer to be re-connected\n");
503 wait_for_event(meta_conn05_cb, 5);
505 mesh_event_destroy();
509 assert_int_equal(meta_conn05, true);
514 int test_meta_conn(void) {
515 const struct CMUnitTest blackbox_group0_tests[] = {
516 cmocka_unit_test_prestate_setup_teardown(test_case_meta_conn_01, setup_test, teardown_test,
517 (void *)&test_meta_conn_1_state),
518 cmocka_unit_test_prestate_setup_teardown(test_case_meta_conn_02, setup_test, teardown_test,
519 (void *)&test_meta_conn_2_state),
520 cmocka_unit_test_prestate_setup_teardown(test_case_meta_conn_03, setup_test, teardown_test,
521 (void *)&test_meta_conn_3_state),
522 cmocka_unit_test_prestate_setup_teardown(test_case_meta_conn_04, setup_test, teardown_test,
523 (void *)&test_meta_conn_4_state),
524 cmocka_unit_test_prestate_setup_teardown(test_case_meta_conn_05, setup_test, teardown_test,
525 (void *)&test_meta_conn_5_state)
527 total_tests += sizeof(blackbox_group0_tests) / sizeof(blackbox_group0_tests[0]);
529 return cmocka_run_group_tests(blackbox_group0_tests, black_box_group0_setup, black_box_group0_teardown);