]> git.meshlink.io Git - meshlink/blob - test/blackbox/run_blackbox_tests/test_cases.c
Fix compiler warnings in the test suites.
[meshlink] / test / blackbox / run_blackbox_tests / test_cases.c
1 /*
2     test_cases.c -- Execution of specific meshlink black box test cases
3     Copyright (C) 2018  Guus Sliepen <guus@meshlink.io>
4
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.
9
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.
14
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.
18 */
19 #include <stdlib.h>
20 #include <stdarg.h>
21 #include <setjmp.h>
22 #include <cmocka.h>
23 #include <assert.h>
24 #include "execute_tests.h"
25 #include "test_cases.h"
26 #include "pthread.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"
31
32 #define RELAY_ID "0"
33 #define PEER_ID  "1"
34 #define NUT_ID   "2"
35
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);
46
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,
52         .num_nodes =  3,
53 };
54
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,
60         .num_nodes = 3,
61 };
62
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,
68         .num_nodes = 3,
69 };
70
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,
76         .num_nodes = 2,
77 };
78
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,
84         .num_nodes = 2,
85 };
86
87 int black_box_group0_setup(void **state) {
88         (void)state;
89
90         const char *nodes[] = { "peer", "relay", "nut"};
91         int num_nodes = sizeof(nodes) / sizeof(nodes[0]);
92
93         PRINT_TEST_CASE_MSG("Creating Containers\n");
94         destroy_containers();
95         create_containers(nodes, num_nodes);
96
97         return 0;
98 }
99
100 int black_box_group0_teardown(void **state) {
101         (void)state;
102
103         PRINT_TEST_CASE_MSG("Destroying Containers\n");
104         destroy_containers();
105
106         return 0;
107 }
108
109 int black_box_all_nodes_setup(void **state) {
110         (void)state;
111
112         const char *nodes[] = { "peer" };
113         int num_nodes = sizeof(nodes) / sizeof(nodes[0]);
114
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");
119         return 0;
120 }
121
122 static bool meta_conn01_conn;
123 static bool meta_conn01_closed;
124 static bool meta_conn01_reconn;
125
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]);
129
130         switch(payload.mesh_event) {
131         case META_CONN_SUCCESSFUL   :
132                 meta_conn01_conn = true;
133                 break;
134
135         case NODE_STARTED           :
136                 fprintf(stderr, "Node started\n");
137                 break;
138
139         case META_CONN_CLOSED       :
140                 meta_conn01_closed = true;
141                 break;
142
143         case META_RECONN_SUCCESSFUL :
144                 meta_conn01_reconn = true;
145                 break;
146
147         default:
148                 break;
149         }
150
151         return true;
152 }
153
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);
158 }
159
160 /* Test Steps for Meta-connections Test Case # 1 - re-connection to peer after disconnection when
161     connected via a third (relay) node
162
163     Test Steps:
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
167
168     Expected Result:
169     NUT is re-connected to peer
170 */
171 static bool test_steps_meta_conn_01(void) {
172         char *invite_peer, *invite_nut;
173         char *import;
174
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);
184
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);
188
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);
194
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);
199
200         mesh_event_destroy();
201         free(invite_peer);
202         free(invite_nut);
203
204         assert_int_equal(meta_conn01_reconn, true);
205
206         return true;
207 }
208
209
210 static bool meta_conn02_conn;
211
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]);
215
216         switch(payload.mesh_event) {
217         case META_CONN_SUCCESSFUL   :
218                 fprintf(stderr, "Meta Connection Successful\n");
219                 meta_conn02_conn = true;
220                 break;
221
222         case NODE_STARTED           :
223                 fprintf(stderr, "Node started\n");
224                 break;
225
226         default:
227                 break;
228         }
229
230         return true;
231 }
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);
236 }
237 /* Test Steps for Meta-connections Test Case # 2 - re-connection to peer via third node
238     after changing IP of NUT and peer
239
240     Test Steps:
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
243
244     Expected Result:
245     NUT is first disconnected from peer then automatically re-connected to peer
246 */
247 static bool test_steps_meta_conn_02(void) {
248         char *invite_peer, *invite_nut;
249         char *import;
250
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);
260
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);
264
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);
270
271         PRINT_TEST_CASE_MSG("Waiting for peer to be connected with NUT\n");
272         wait_for_event(meta_conn02_cb, 60);
273
274         mesh_event_destroy();
275         free(invite_peer);
276         free(invite_nut);
277
278         assert_int_equal(meta_conn02_conn, true);
279
280         return true;
281 }
282
283 static bool meta_conn03_result;
284 static bool meta_conn03_conn;
285
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]);
289
290         switch(payload.mesh_event) {
291         case META_CONN_SUCCESSFUL   :
292                 fprintf(stderr, "Meta Connection Successful\n");
293                 meta_conn03_conn = true;
294                 break;
295
296         case NODE_STARTED           :
297                 fprintf(stderr, "Node started\n");
298                 break;
299
300         case META_RECONN_FAILURE    :
301                 fprintf(stderr, "Failed to reconnect with");
302                 meta_conn03_result = false;
303                 break;
304
305         case META_RECONN_SUCCESSFUL :
306                 fprintf(stderr, "Reconnected\n");
307                 meta_conn03_result = true;
308                 break;
309
310         default:
311                 break;
312         }
313
314         return true;
315 }
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);
320 }
321 /* Test Steps for Meta-connections Test Case # 3 - re-connection to peer via third node
322     after changing IP of peer
323
324     Test Steps:
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
327
328     Expected Result:
329     NUT is first disconnected from peer then automatically re-connected to peer
330 */
331 static bool test_steps_meta_conn_03(void) {
332         char *invite_peer, *invite_nut;
333         char *import;
334
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);
344
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);
348
349         PRINT_TEST_CASE_MSG("Changing IP address of PEER container\n");
350         change_ip(1);
351         sleep(3);
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);
356
357         mesh_event_destroy();
358         free(invite_peer);
359         free(invite_nut);
360
361         assert_int_equal(meta_conn03_result, true);
362
363         return true;
364 }
365
366 static char *invite_peer = NULL;
367 static bool meta_conn04 = false;
368
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]);
372
373         switch(payload.mesh_event) {
374         case META_CONN_SUCCESSFUL   :
375                 fprintf(stderr, "Meta Connection Successful\n");
376                 meta_conn04 = true;
377                 break;
378
379         case NODE_INVITATION        :
380                 fprintf(stderr, "Invitation generated\n");
381                 invite_peer = malloc(payload.payload_length);
382                 strcpy(invite_peer, (char *)payload.payload);
383                 break;
384
385         case NODE_STARTED           :
386                 fprintf(stderr, "Node started\n");
387                 break;
388
389         default                     :
390                 fprintf(stderr, "Undefined mesh event\n");
391                 break;
392         }
393
394         return true;
395 }
396
397 /* Execute Meta-connections Test Case # 4 - re-connection to peer after changing IP of
398     NUT and peer */
399 static void test_case_meta_conn_04(void **state) {
400         execute_test(test_steps_meta_conn_04, state);
401 }
402
403 /* Execute Meta-connections Test Case # 4 - re-connection to peer after changing IP of
404     NUT and peer
405
406     Test Steps:
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
409
410     Expected Result:
411     NUT is first disconnected from peer then automatically re-connected to peer
412 */
413 static bool test_steps_meta_conn_04(void) {
414         char *import;
415
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);
419
420         PRINT_TEST_CASE_MSG("Waiting for NUT to generate invitation to PEER\n");
421         wait_for_event(meta_conn04_cb, 5);
422
423         assert(invite_peer);
424
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");
430
431         assert(wait_for_event(meta_conn04_cb, 60));
432
433         PRINT_TEST_CASE_MSG("Changing IP address of NUT container\n");
434         change_ip(1);
435
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");
439         change_ip(0);
440         node_sim_in_container_event("peer", "1", NULL, "0", import);
441         wait_for_event(meta_conn04_cb, 5);
442
443         PRINT_TEST_CASE_MSG("Waiting for peer to be re-connected\n");
444         wait_for_event(meta_conn04_cb, 5);
445
446         mesh_event_destroy();
447         free(invite_peer);
448         free(import);
449
450         assert_int_equal(meta_conn04, true);
451
452         return true;
453 }
454
455 static char *invitation = NULL;
456
457 static bool meta_conn05 = false;
458
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]);
462
463         switch(payload.mesh_event) {
464         case META_CONN_SUCCESSFUL   :
465                 meta_conn05 = true;
466                 break;
467
468         case NODE_INVITATION        :
469                 invitation = malloc(payload.payload_length);
470                 strcpy(invitation, (char *)payload.payload);
471                 break;
472
473         case NODE_STARTED           :
474                 fprintf(stderr, "Node started\n");
475                 break;
476
477         default:
478                 break;
479         }
480
481         return true;
482 }
483
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);
487 }
488
489 /* Execute Meta-connections Test Case # 5 - re-connection to peer after changing IP of peer
490
491     Test Steps:
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
494
495     Expected Result:
496     NUT is first disconnected from peer then automatically re-connected to peer
497 */
498 static bool test_steps_meta_conn_05(void) {
499         char *import;
500
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);
504
505         wait_for_event(meta_conn05_cb, 5);
506
507         assert(invitation);
508
509         node_sim_in_container_event("peer", "1", invitation, "0", import);
510         wait_for_event(meta_conn05_cb, 5);
511
512         assert(wait_for_event(meta_conn05_cb, 5));
513
514         change_ip(0);
515         meta_conn05 = false;
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);
520
521         mesh_event_destroy();
522         free(invitation);
523         free(import);
524
525         assert_int_equal(meta_conn05, true);
526
527         return true;
528 }
529
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)
542         };
543         total_tests += sizeof(blackbox_group0_tests) / sizeof(blackbox_group0_tests[0]);
544
545         return cmocka_run_group_tests(blackbox_group0_tests, black_box_group0_setup, black_box_group0_teardown);
546 }