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 void 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;
143 /* Execute Meta-connections Test Case # 1 - re-connection to peer after disconnection when
144 connected via a third node */
145 static void test_case_meta_conn_01(void **state) {
146 execute_test(test_steps_meta_conn_01, state);
149 /* Test Steps for Meta-connections Test Case # 1 - re-connection to peer after disconnection when
150 connected via a third (relay) node
153 1. Run NUT, relay and peer nodes with relay inviting the other two nodes
154 2. After connection to peer, terminate the peer node's running instance
155 3. After peer becomes unreachable, wait 60 seconds then re-start the peer node's instance
158 NUT is re-connected to peer
160 static bool test_steps_meta_conn_01(void) {
161 char *invite_peer, *invite_nut;
166 import = mesh_event_sock_create(eth_if_name);
167 invite_peer = invite_in_container("relay", "peer");
168 invite_nut = invite_in_container("relay", NUT_NODE_NAME);
169 node_sim_in_container_event("relay", "1", NULL, RELAY_ID, import);
170 wait_for_event(meta_conn01_cb, 5);
171 node_sim_in_container_event("peer", "1", invite_peer, PEER_ID, import);
172 wait_for_event(meta_conn01_cb, 5);
173 node_sim_in_container_event("nut", "1", invite_nut, NUT_ID, import);
174 wait_for_event(meta_conn01_cb, 5);
176 PRINT_TEST_CASE_MSG("Waiting for peer to be connected with NUT\n");
177 assert(wait_for_event(meta_conn01_cb, 60));
178 assert(meta_conn01_conn);
180 PRINT_TEST_CASE_MSG("Sending SIGTERM to peer\n");
181 node_step_in_container("peer", "SIGTERM");
182 PRINT_TEST_CASE_MSG("Waiting for peer to become unreachable\n");
183 assert(wait_for_event(meta_conn01_cb, 60));
184 assert(meta_conn01_closed);
186 node_sim_in_container_event("peer", "1", NULL, PEER_ID, import);
187 wait_for_event(meta_conn01_cb, 5);
188 PRINT_TEST_CASE_MSG("Waiting for peer to be re-connected\n");
189 wait_for_event(meta_conn01_cb, 60);
191 assert_int_equal(meta_conn01_reconn, true);
200 static bool meta_conn02_conn;
202 static void meta_conn02_cb(mesh_event_payload_t payload) {
203 char event_node_name[][10] = {"RELAY", "PEER", "NUT"};
204 fprintf(stderr, "%s : ", event_node_name[payload.client_id]);
206 switch(payload.mesh_event) {
207 case META_CONN_SUCCESSFUL :
208 fprintf(stderr, "Meta Connection Successful\n");
209 meta_conn02_conn = true;
213 fprintf(stderr, "Node started\n");
217 if(payload.payload_length) {
218 fprintf(stderr, " %s\n", (char *)payload.payload);
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;
242 import = mesh_event_sock_create(eth_if_name);
243 invite_peer = invite_in_container("relay", "peer");
244 invite_nut = invite_in_container("relay", NUT_NODE_NAME);
245 node_sim_in_container_event("relay", "1", NULL, RELAY_ID, import);
246 wait_for_event(meta_conn02_cb, 5);
247 node_sim_in_container_event("peer", "1", invite_peer, PEER_ID, import);
248 wait_for_event(meta_conn02_cb, 5);
249 node_sim_in_container_event("nut", "1", invite_nut, NUT_ID, import);
250 wait_for_event(meta_conn02_cb, 5);
252 PRINT_TEST_CASE_MSG("Waiting for peer to be connected with NUT\n");
253 assert(wait_for_event(meta_conn02_cb, 60));
254 assert(meta_conn02_conn);
256 meta_conn02_conn = false;
257 node_sim_in_container_event("peer", "1", NULL, PEER_ID, import);
258 wait_for_event(meta_conn02_cb, 5);
259 node_sim_in_container_event("nut", "1", NULL, NUT_ID, import);
260 wait_for_event(meta_conn02_cb, 5);
262 PRINT_TEST_CASE_MSG("Waiting for peer to be connected with NUT\n");
264 if(!wait_for_event(meta_conn02_cb, 60)) {
268 result = meta_conn02_conn;
276 static bool meta_conn03_result;
277 static bool meta_conn03_conn;
279 static void meta_conn03_cb(mesh_event_payload_t payload) {
280 char event_node_name[][10] = {"RELAY", "PEER", "NUT"};
281 fprintf(stderr, "%s : ", event_node_name[payload.client_id]);
283 switch(payload.mesh_event) {
284 case META_CONN_SUCCESSFUL :
285 fprintf(stderr, "Meta Connection Successful\n");
286 meta_conn03_conn = true;
290 fprintf(stderr, "Node started\n");
293 case META_RECONN_FAILURE :
294 fprintf(stderr, "Failed to reconnect with");
295 meta_conn03_result = false;
298 case META_RECONN_SUCCESSFUL :
299 fprintf(stderr, "Reconnected\n");
300 meta_conn03_result = true;
304 /* Execute Meta-connections Test Case # 3 - re-connection to peer via third node
305 after changing IP of peer */
306 static void test_case_meta_conn_03(void **state) {
307 execute_test(test_steps_meta_conn_03, state);
309 /* Test Steps for Meta-connections Test Case # 3 - re-connection to peer via third node
310 after changing IP of peer
313 1. Run NUT, relay and peer nodes with relay inviting the other two nodes
314 2. After connection to peer, change the peer node's IP Address
317 NUT is first disconnected from peer then automatically re-connected to peer
319 static bool test_steps_meta_conn_03(void) {
320 char *invite_peer, *invite_nut;
325 import = mesh_event_sock_create(eth_if_name);
326 invite_peer = invite_in_container("relay", "peer");
327 invite_nut = invite_in_container("relay", NUT_NODE_NAME);
328 node_sim_in_container_event("relay", "1", NULL, RELAY_ID, import);
329 wait_for_event(meta_conn03_cb, 5);
330 node_sim_in_container_event("peer", "1", invite_peer, PEER_ID, import);
331 wait_for_event(meta_conn03_cb, 5);
332 node_sim_in_container_event("nut", "1", invite_nut, NUT_ID, import);
333 wait_for_event(meta_conn03_cb, 5);
335 PRINT_TEST_CASE_MSG("Waiting for peer to be connected with NUT\n");
336 assert(wait_for_event(meta_conn03_cb, 60));
337 assert(meta_conn03_conn);
339 PRINT_TEST_CASE_MSG("Changing IP address of PEER container\n");
341 node_sim_in_container_event("peer", "1", NULL, PEER_ID, import);
342 wait_for_event(meta_conn03_cb, 5);
343 PRINT_TEST_CASE_MSG("Waiting for peer to be re-connected\n");
344 wait_for_event(meta_conn03_cb, 5);
345 result = meta_conn03_result;
352 static char *invite_peer = NULL;
353 static bool meta_conn04 = false;
355 static void meta_conn04_cb(mesh_event_payload_t payload) {
356 char event_node_name[][10] = {"PEER", "NUT"};
357 fprintf(stderr, "%s : ", event_node_name[payload.client_id]);
359 switch(payload.mesh_event) {
360 case META_CONN_SUCCESSFUL :
361 fprintf(stderr, "Meta Connection Successful\n");
365 case NODE_INVITATION :
366 fprintf(stderr, "Invitation generated\n");
367 invite_peer = malloc(payload.payload_length);
368 strcpy(invite_peer, (char *)payload.payload);
372 fprintf(stderr, "Node started\n");
377 /* Execute Meta-connections Test Case # 4 - re-connection to peer after changing IP of
379 static void test_case_meta_conn_04(void **state) {
380 execute_test(test_steps_meta_conn_04, state);
383 /* Execute Meta-connections Test Case # 4 - re-connection to peer after changing IP of
387 1. Run NUT and peer nodes with NUT inviting the peer node
388 2. After connection to peer, change the NUT's IP Address and the peer node's IP Address
391 NUT is first disconnected from peer then automatically re-connected to peer
393 static bool test_steps_meta_conn_04(void) {
397 import = mesh_event_sock_create(eth_if_name);
398 node_sim_in_container_event("nut", "1", NULL, "1", import);
399 wait_for_event(meta_conn04_cb, 5);
401 PRINT_TEST_CASE_MSG("Waiting for NUT to generate invitation to PEER\n");
402 wait_for_event(meta_conn04_cb, 5);
408 PRINT_TEST_CASE_MSG("Running PEER node in the container\n");
409 node_sim_in_container_event("peer", "1", invite_peer, "0", import);
410 wait_for_event(meta_conn04_cb, 5);
411 PRINT_TEST_CASE_MSG("Waiting for peer to be connected with NUT\n");
413 if(!wait_for_event(meta_conn04_cb, 60)) {
417 PRINT_TEST_CASE_MSG("Changing IP address of NUT container\n");
420 node_sim_in_container_event("nut", "1", "restart", "1", import);
421 wait_for_event(meta_conn04_cb, 5);
422 PRINT_TEST_CASE_MSG("Changing IP address of PEER container\n");
424 node_sim_in_container_event("peer", "1", NULL, "0", import);
425 wait_for_event(meta_conn04_cb, 5);
427 PRINT_TEST_CASE_MSG("Waiting for peer to be re-connected\n");
428 wait_for_event(meta_conn04_cb, 5);
429 result = meta_conn04;
436 static char *invitation = NULL;
438 static bool meta_conn05 = false;
440 static void meta_conn05_cb(mesh_event_payload_t payload) {
441 char event_node_name[][10] = {"PEER", "NUT"};
442 fprintf(stderr, "%s : ", event_node_name[payload.client_id]);
444 switch(payload.mesh_event) {
445 case META_CONN_SUCCESSFUL :
449 case NODE_INVITATION :
450 invitation = malloc(payload.payload_length);
451 strcpy(invitation, (char *)payload.payload);
455 fprintf(stderr, "Node started\n");
460 /* Execute Meta-connections Test Case # 5 - re-connection to peer after changing IP of peer */
461 static void test_case_meta_conn_05(void **state) {
462 execute_test(test_steps_meta_conn_05, state);
465 /* Execute Meta-connections Test Case # 5 - re-connection to peer after changing IP of peer
468 1. Run NUT and peer nodes with NUT inviting the peer node
469 2. After connection to peer, change the peer node's IP Address
472 NUT is first disconnected from peer then automatically re-connected to peer
474 static bool test_steps_meta_conn_05(void) {
478 import = mesh_event_sock_create(eth_if_name);
479 node_sim_in_container_event("nut", "1", NULL, "1", import);
480 wait_for_event(meta_conn05_cb, 5);
482 wait_for_event(meta_conn05_cb, 5);
488 node_sim_in_container_event("peer", "1", invitation, "0", import);
489 wait_for_event(meta_conn05_cb, 5);
491 if(!wait_for_event(meta_conn05_cb, 5)) {
497 node_sim_in_container_event("peer", "1", NULL, "0", import);
498 wait_for_event(meta_conn05_cb, 5);
499 PRINT_TEST_CASE_MSG("Waiting for peer to be re-connected\n");
500 wait_for_event(meta_conn05_cb, 5);
501 result = meta_conn05;
508 int test_meta_conn(void) {
509 const struct CMUnitTest blackbox_group0_tests[] = {
510 cmocka_unit_test_prestate_setup_teardown(test_case_meta_conn_01, setup_test, teardown_test,
511 (void *)&test_meta_conn_1_state),
512 cmocka_unit_test_prestate_setup_teardown(test_case_meta_conn_02, setup_test, teardown_test,
513 (void *)&test_meta_conn_2_state),
514 cmocka_unit_test_prestate_setup_teardown(test_case_meta_conn_03, setup_test, teardown_test,
515 (void *)&test_meta_conn_3_state),
516 cmocka_unit_test_prestate_setup_teardown(test_case_meta_conn_04, setup_test, teardown_test,
517 (void *)&test_meta_conn_4_state),
518 cmocka_unit_test_prestate_setup_teardown(test_case_meta_conn_05, setup_test, teardown_test,
519 (void *)&test_meta_conn_5_state)
521 total_tests += sizeof(blackbox_group0_tests) / sizeof(blackbox_group0_tests[0]);
523 return cmocka_run_group_tests(blackbox_group0_tests, black_box_group0_setup, black_box_group0_teardown);