]> git.meshlink.io Git - meshlink/blob - test/blackbox/run_blackbox_tests/test_cases.c
Ensure NDEBUG is not set in the test suite.
[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
20 #ifdef NDEBUG
21 #undef NDEBUG
22 #endif
23
24 #include <stdlib.h>
25 #include <stdarg.h>
26 #include <setjmp.h>
27 #include <cmocka.h>
28 #include <assert.h>
29 #include "execute_tests.h"
30 #include "test_cases.h"
31 #include "pthread.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"
36
37 #define RELAY_ID "0"
38 #define PEER_ID  "1"
39 #define NUT_ID   "2"
40
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);
51
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,
57         .num_nodes =  3,
58 };
59
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,
65         .num_nodes = 3,
66 };
67
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,
73         .num_nodes = 3,
74 };
75
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,
81         .num_nodes = 2,
82 };
83
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,
89         .num_nodes = 2,
90 };
91
92 int black_box_group0_setup(void **state) {
93         (void)state;
94
95         const char *nodes[] = { "peer", "relay", "nut"};
96         int num_nodes = sizeof(nodes) / sizeof(nodes[0]);
97
98         PRINT_TEST_CASE_MSG("Creating Containers\n");
99         destroy_containers();
100         create_containers(nodes, num_nodes);
101
102         return 0;
103 }
104
105 int black_box_group0_teardown(void **state) {
106         (void)state;
107
108         PRINT_TEST_CASE_MSG("Destroying Containers\n");
109         destroy_containers();
110
111         return 0;
112 }
113
114 int black_box_all_nodes_setup(void **state) {
115         (void)state;
116
117         const char *nodes[] = { "peer" };
118         int num_nodes = sizeof(nodes) / sizeof(nodes[0]);
119
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");
124         return 0;
125 }
126
127 static bool meta_conn01_conn;
128 static bool meta_conn01_closed;
129 static bool meta_conn01_reconn;
130
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]);
134
135         switch(payload.mesh_event) {
136         case META_CONN_SUCCESSFUL   :
137                 meta_conn01_conn = true;
138                 break;
139
140         case NODE_STARTED           :
141                 fprintf(stderr, "Node started\n");
142                 break;
143
144         case META_CONN_CLOSED       :
145                 meta_conn01_closed = true;
146                 break;
147
148         case META_RECONN_SUCCESSFUL :
149                 meta_conn01_reconn = true;
150                 break;
151
152         default:
153                 break;
154         }
155
156         return true;
157 }
158
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);
163 }
164
165 /* Test Steps for Meta-connections Test Case # 1 - re-connection to peer after disconnection when
166     connected via a third (relay) node
167
168     Test Steps:
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
172
173     Expected Result:
174     NUT is re-connected to peer
175 */
176 static bool test_steps_meta_conn_01(void) {
177         char *invite_peer, *invite_nut;
178         char *import;
179
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);
189
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);
193
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);
199
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);
204
205         mesh_event_destroy();
206         free(invite_peer);
207         free(invite_nut);
208
209         assert_int_equal(meta_conn01_reconn, true);
210
211         return true;
212 }
213
214
215 static bool meta_conn02_conn;
216
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]);
220
221         switch(payload.mesh_event) {
222         case META_CONN_SUCCESSFUL   :
223                 fprintf(stderr, "Meta Connection Successful\n");
224                 meta_conn02_conn = true;
225                 break;
226
227         case NODE_STARTED           :
228                 fprintf(stderr, "Node started\n");
229                 break;
230
231         default:
232                 break;
233         }
234
235         return true;
236 }
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);
241 }
242 /* Test Steps for Meta-connections Test Case # 2 - re-connection to peer via third node
243     after changing IP of NUT and peer
244
245     Test Steps:
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
248
249     Expected Result:
250     NUT is first disconnected from peer then automatically re-connected to peer
251 */
252 static bool test_steps_meta_conn_02(void) {
253         char *invite_peer, *invite_nut;
254         char *import;
255
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);
265
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);
269
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);
275
276         PRINT_TEST_CASE_MSG("Waiting for peer to be connected with NUT\n");
277         wait_for_event(meta_conn02_cb, 60);
278
279         mesh_event_destroy();
280         free(invite_peer);
281         free(invite_nut);
282
283         assert_int_equal(meta_conn02_conn, true);
284
285         return true;
286 }
287
288 static bool meta_conn03_result;
289 static bool meta_conn03_conn;
290
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]);
294
295         switch(payload.mesh_event) {
296         case META_CONN_SUCCESSFUL   :
297                 fprintf(stderr, "Meta Connection Successful\n");
298                 meta_conn03_conn = true;
299                 break;
300
301         case NODE_STARTED           :
302                 fprintf(stderr, "Node started\n");
303                 break;
304
305         case META_RECONN_FAILURE    :
306                 fprintf(stderr, "Failed to reconnect with");
307                 meta_conn03_result = false;
308                 break;
309
310         case META_RECONN_SUCCESSFUL :
311                 fprintf(stderr, "Reconnected\n");
312                 meta_conn03_result = true;
313                 break;
314
315         default:
316                 break;
317         }
318
319         return true;
320 }
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);
325 }
326 /* Test Steps for Meta-connections Test Case # 3 - re-connection to peer via third node
327     after changing IP of peer
328
329     Test Steps:
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
332
333     Expected Result:
334     NUT is first disconnected from peer then automatically re-connected to peer
335 */
336 static bool test_steps_meta_conn_03(void) {
337         char *invite_peer, *invite_nut;
338         char *import;
339
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);
349
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);
353
354         PRINT_TEST_CASE_MSG("Changing IP address of PEER container\n");
355         change_ip(1);
356         sleep(3);
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);
361
362         mesh_event_destroy();
363         free(invite_peer);
364         free(invite_nut);
365
366         assert_int_equal(meta_conn03_result, true);
367
368         return true;
369 }
370
371 static char *invite_peer = NULL;
372 static bool meta_conn04 = false;
373
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]);
377
378         switch(payload.mesh_event) {
379         case META_CONN_SUCCESSFUL   :
380                 fprintf(stderr, "Meta Connection Successful\n");
381                 meta_conn04 = true;
382                 break;
383
384         case NODE_INVITATION        :
385                 fprintf(stderr, "Invitation generated\n");
386                 invite_peer = malloc(payload.payload_length);
387                 strcpy(invite_peer, (char *)payload.payload);
388                 break;
389
390         case NODE_STARTED           :
391                 fprintf(stderr, "Node started\n");
392                 break;
393
394         default                     :
395                 fprintf(stderr, "Undefined mesh event\n");
396                 break;
397         }
398
399         return true;
400 }
401
402 /* Execute Meta-connections Test Case # 4 - re-connection to peer after changing IP of
403     NUT and peer */
404 static void test_case_meta_conn_04(void **state) {
405         execute_test(test_steps_meta_conn_04, state);
406 }
407
408 /* Execute Meta-connections Test Case # 4 - re-connection to peer after changing IP of
409     NUT and peer
410
411     Test Steps:
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
414
415     Expected Result:
416     NUT is first disconnected from peer then automatically re-connected to peer
417 */
418 static bool test_steps_meta_conn_04(void) {
419         char *import;
420
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);
424
425         PRINT_TEST_CASE_MSG("Waiting for NUT to generate invitation to PEER\n");
426         wait_for_event(meta_conn04_cb, 5);
427
428         assert(invite_peer);
429
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");
435
436         assert(wait_for_event(meta_conn04_cb, 60));
437
438         PRINT_TEST_CASE_MSG("Changing IP address of NUT container\n");
439         change_ip(1);
440
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");
444         change_ip(0);
445         node_sim_in_container_event("peer", "1", NULL, "0", import);
446         wait_for_event(meta_conn04_cb, 5);
447
448         PRINT_TEST_CASE_MSG("Waiting for peer to be re-connected\n");
449         wait_for_event(meta_conn04_cb, 5);
450
451         mesh_event_destroy();
452         free(invite_peer);
453         free(import);
454
455         assert_int_equal(meta_conn04, true);
456
457         return true;
458 }
459
460 static char *invitation = NULL;
461
462 static bool meta_conn05 = false;
463
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]);
467
468         switch(payload.mesh_event) {
469         case META_CONN_SUCCESSFUL   :
470                 meta_conn05 = true;
471                 break;
472
473         case NODE_INVITATION        :
474                 invitation = malloc(payload.payload_length);
475                 strcpy(invitation, (char *)payload.payload);
476                 break;
477
478         case NODE_STARTED           :
479                 fprintf(stderr, "Node started\n");
480                 break;
481
482         default:
483                 break;
484         }
485
486         return true;
487 }
488
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);
492 }
493
494 /* Execute Meta-connections Test Case # 5 - re-connection to peer after changing IP of peer
495
496     Test Steps:
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
499
500     Expected Result:
501     NUT is first disconnected from peer then automatically re-connected to peer
502 */
503 static bool test_steps_meta_conn_05(void) {
504         char *import;
505
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);
509
510         wait_for_event(meta_conn05_cb, 5);
511
512         assert(invitation);
513
514         node_sim_in_container_event("peer", "1", invitation, "0", import);
515         wait_for_event(meta_conn05_cb, 5);
516
517         assert(wait_for_event(meta_conn05_cb, 5));
518
519         change_ip(0);
520         meta_conn05 = false;
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);
525
526         mesh_event_destroy();
527         free(invitation);
528         free(import);
529
530         assert_int_equal(meta_conn05, true);
531
532         return true;
533 }
534
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)
547         };
548         total_tests += sizeof(blackbox_group0_tests) / sizeof(blackbox_group0_tests[0]);
549
550         return cmocka_run_group_tests(blackbox_group0_tests, black_box_group0_setup, black_box_group0_teardown);
551 }