]> git.meshlink.io Git - meshlink/blob - test/blackbox/run_blackbox_tests/test_cases.c
942c72c60fcbadd8a2a43fd68aef66b04f6f1736
[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         const char *nodes[] = { "peer", "relay", "nut"};
89         int num_nodes = sizeof(nodes) / sizeof(nodes[0]);
90
91         PRINT_TEST_CASE_MSG("Creating Containers\n");
92         destroy_containers();
93         create_containers(nodes, num_nodes);
94
95         return 0;
96 }
97
98 int black_box_group0_teardown(void **state) {
99         PRINT_TEST_CASE_MSG("Destroying Containers\n");
100         destroy_containers();
101
102         return 0;
103 }
104
105 int black_box_all_nodes_setup(void **state) {
106         const char *nodes[] = { "peer" };
107         int num_nodes = sizeof(nodes) / sizeof(nodes[0]);
108
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");
113         return 0;
114 }
115
116 static bool meta_conn01_conn;
117 static bool meta_conn01_closed;
118 static bool meta_conn01_reconn;
119
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]);
123
124         switch(payload.mesh_event) {
125         case META_CONN_SUCCESSFUL   :
126                 meta_conn01_conn = true;
127                 break;
128
129         case NODE_STARTED           :
130                 fprintf(stderr, "Node started\n");
131                 break;
132
133         case META_CONN_CLOSED       :
134                 meta_conn01_closed = true;
135                 break;
136
137         case META_RECONN_SUCCESSFUL :
138                 meta_conn01_reconn = true;
139                 break;
140         }
141 }
142
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);
147 }
148
149 /* Test Steps for Meta-connections Test Case # 1 - re-connection to peer after disconnection when
150     connected via a third (relay) node
151
152     Test Steps:
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
156
157     Expected Result:
158     NUT is re-connected to peer
159 */
160 static bool test_steps_meta_conn_01(void) {
161         char *invite_peer, *invite_nut;
162         bool result = false;
163         int i;
164         char *import;
165
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);
175
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);
179
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);
185
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);
190
191         assert_int_equal(meta_conn01_reconn, true);
192
193         free(invite_peer);
194         free(invite_nut);
195
196         return true;
197 }
198
199
200 static bool meta_conn02_conn;
201
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]);
205
206         switch(payload.mesh_event) {
207         case META_CONN_SUCCESSFUL   :
208                 fprintf(stderr, "Meta Connection Successful\n");
209                 meta_conn02_conn = true;
210                 break;
211
212         case NODE_STARTED           :
213                 fprintf(stderr, "Node started\n");
214                 break;
215         }
216
217         if(payload.payload_length) {
218                 fprintf(stderr, " %s\n", (char *)payload.payload);
219         }
220 }
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);
225 }
226 /* Test Steps for Meta-connections Test Case # 2 - re-connection to peer via third node
227     after changing IP of NUT and peer
228
229     Test Steps:
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
232
233     Expected Result:
234     NUT is first disconnected from peer then automatically re-connected to peer
235 */
236 static bool test_steps_meta_conn_02(void) {
237         char *invite_peer, *invite_nut;
238         bool result = false;
239         int i;
240         char *import;
241
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);
251
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);
255
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);
261
262         PRINT_TEST_CASE_MSG("Waiting for peer to be connected with NUT\n");
263
264         if(!wait_for_event(meta_conn02_cb, 60)) {
265                 return false;
266         }
267
268         result = meta_conn02_conn;
269
270         free(invite_peer);
271         free(invite_nut);
272
273         return result;
274 }
275
276 static bool meta_conn03_result;
277 static bool meta_conn03_conn;
278
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]);
282
283         switch(payload.mesh_event) {
284         case META_CONN_SUCCESSFUL   :
285                 fprintf(stderr, "Meta Connection Successful\n");
286                 meta_conn03_conn = true;
287                 break;
288
289         case NODE_STARTED           :
290                 fprintf(stderr, "Node started\n");
291                 break;
292
293         case META_RECONN_FAILURE    :
294                 fprintf(stderr, "Failed to reconnect with");
295                 meta_conn03_result = false;
296                 break;
297
298         case META_RECONN_SUCCESSFUL :
299                 fprintf(stderr, "Reconnected\n");
300                 meta_conn03_result = true;
301                 break;
302         }
303 }
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);
308 }
309 /* Test Steps for Meta-connections Test Case # 3 - re-connection to peer via third node
310     after changing IP of peer
311
312     Test Steps:
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
315
316     Expected Result:
317     NUT is first disconnected from peer then automatically re-connected to peer
318 */
319 static bool test_steps_meta_conn_03(void) {
320         char *invite_peer, *invite_nut;
321         bool result = false;
322         int i;
323         char *import;
324
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);
334
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);
338
339         PRINT_TEST_CASE_MSG("Changing IP address of PEER container\n");
340         change_ip(1);
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;
346         free(invite_peer);
347         free(invite_nut);
348
349         return result;
350 }
351
352 static char *invite_peer = NULL;
353 static bool meta_conn04 = false;
354
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]);
358
359         switch(payload.mesh_event) {
360         case META_CONN_SUCCESSFUL   :
361                 fprintf(stderr, "Meta Connection Successful\n");
362                 meta_conn04 = true;
363                 break;
364
365         case NODE_INVITATION        :
366                 fprintf(stderr, "Invitation generated\n");
367                 invite_peer = malloc(payload.payload_length);
368                 strcpy(invite_peer, (char *)payload.payload);
369                 break;
370
371         case NODE_STARTED           :
372                 fprintf(stderr, "Node started\n");
373                 break;
374         }
375 }
376
377 /* Execute Meta-connections Test Case # 4 - re-connection to peer after changing IP of
378     NUT and peer */
379 static void test_case_meta_conn_04(void **state) {
380         execute_test(test_steps_meta_conn_04, state);
381 }
382
383 /* Execute Meta-connections Test Case # 4 - re-connection to peer after changing IP of
384     NUT and peer
385
386     Test Steps:
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
389
390     Expected Result:
391     NUT is first disconnected from peer then automatically re-connected to peer
392 */
393 static bool test_steps_meta_conn_04(void) {
394         bool result = false;
395         char *import;
396
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);
400
401         PRINT_TEST_CASE_MSG("Waiting for NUT to generate invitation to PEER\n");
402         wait_for_event(meta_conn04_cb, 5);
403
404         if(!invite_peer) {
405                 return false;
406         }
407
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");
412
413         if(!wait_for_event(meta_conn04_cb, 60)) {
414                 return false;
415         }
416
417         PRINT_TEST_CASE_MSG("Changing IP address of NUT container\n");
418         change_ip(1);
419
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");
423         change_ip(0);
424         node_sim_in_container_event("peer", "1", NULL, "0", import);
425         wait_for_event(meta_conn04_cb, 5);
426
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;
430
431         free(invite_peer);
432         free(import);
433         return result;
434 }
435
436 static char *invitation = NULL;
437
438 static bool meta_conn05 = false;
439
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]);
443
444         switch(payload.mesh_event) {
445         case META_CONN_SUCCESSFUL   :
446                 meta_conn05 = true;
447                 break;
448
449         case NODE_INVITATION        :
450                 invitation = malloc(payload.payload_length);
451                 strcpy(invitation, (char *)payload.payload);
452                 break;
453
454         case NODE_STARTED           :
455                 fprintf(stderr, "Node started\n");
456                 break;
457         }
458 }
459
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);
463 }
464
465 /* Execute Meta-connections Test Case # 5 - re-connection to peer after changing IP of peer
466
467     Test Steps:
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
470
471     Expected Result:
472     NUT is first disconnected from peer then automatically re-connected to peer
473 */
474 static bool test_steps_meta_conn_05(void) {
475         bool result = false;
476         char *import;
477
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);
481
482         wait_for_event(meta_conn05_cb, 5);
483
484         if(!invitation) {
485                 return false;
486         }
487
488         node_sim_in_container_event("peer", "1", invitation, "0", import);
489         wait_for_event(meta_conn05_cb, 5);
490
491         if(!wait_for_event(meta_conn05_cb, 5)) {
492                 return false;
493         }
494
495         change_ip(0);
496         meta_conn05 = false;
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;
502
503         free(invitation);
504         free(import);
505         return result;
506 }
507
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)
520         };
521         total_tests += sizeof(blackbox_group0_tests) / sizeof(blackbox_group0_tests[0]);
522
523         return cmocka_run_group_tests(blackbox_group0_tests, black_box_group0_setup, black_box_group0_teardown);
524 }