]> git.meshlink.io Git - meshlink/blob - test/blackbox/run_blackbox_tests/test_cases.c
Update the blackbox test infrastructure.
[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 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]);
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         return true;
143 }
144
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);
149 }
150
151 /* Test Steps for Meta-connections Test Case # 1 - re-connection to peer after disconnection when
152     connected via a third (relay) node
153
154     Test Steps:
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
158
159     Expected Result:
160     NUT is re-connected to peer
161 */
162 static bool test_steps_meta_conn_01(void) {
163         char *invite_peer, *invite_nut;
164         int i;
165         char *import;
166
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);
176
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);
180
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);
186
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);
191
192         mesh_event_destroy();
193         free(invite_peer);
194         free(invite_nut);
195
196         assert_int_equal(meta_conn01_reconn, true);
197
198         return true;
199 }
200
201
202 static bool meta_conn02_conn;
203
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]);
207
208         switch(payload.mesh_event) {
209         case META_CONN_SUCCESSFUL   :
210                 fprintf(stderr, "Meta Connection Successful\n");
211                 meta_conn02_conn = true;
212                 break;
213
214         case NODE_STARTED           :
215                 fprintf(stderr, "Node started\n");
216                 break;
217         }
218
219         return true;
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         int i;
239         char *import;
240
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);
250
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);
254
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);
260
261         PRINT_TEST_CASE_MSG("Waiting for peer to be connected with NUT\n");
262         wait_for_event(meta_conn02_cb, 60);
263
264         mesh_event_destroy();
265         free(invite_peer);
266         free(invite_nut);
267
268         assert_int_equal(meta_conn02_conn, true);
269
270         return true;
271 }
272
273 static bool meta_conn03_result;
274 static bool meta_conn03_conn;
275
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]);
279
280         switch(payload.mesh_event) {
281         case META_CONN_SUCCESSFUL   :
282                 fprintf(stderr, "Meta Connection Successful\n");
283                 meta_conn03_conn = true;
284                 break;
285
286         case NODE_STARTED           :
287                 fprintf(stderr, "Node started\n");
288                 break;
289
290         case META_RECONN_FAILURE    :
291                 fprintf(stderr, "Failed to reconnect with");
292                 meta_conn03_result = false;
293                 break;
294
295         case META_RECONN_SUCCESSFUL :
296                 fprintf(stderr, "Reconnected\n");
297                 meta_conn03_result = true;
298                 break;
299         }
300
301         return true;
302 }
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);
307 }
308 /* Test Steps for Meta-connections Test Case # 3 - re-connection to peer via third node
309     after changing IP of peer
310
311     Test Steps:
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
314
315     Expected Result:
316     NUT is first disconnected from peer then automatically re-connected to peer
317 */
318 static bool test_steps_meta_conn_03(void) {
319         char *invite_peer, *invite_nut;
320         int i;
321         char *import;
322
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);
332
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);
336
337         PRINT_TEST_CASE_MSG("Changing IP address of PEER container\n");
338         change_ip(1);
339         sleep(3);
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);
344
345         mesh_event_destroy();
346         free(invite_peer);
347         free(invite_nut);
348
349         assert_int_equal(meta_conn03_result, true);
350
351         return true;
352 }
353
354 static char *invite_peer = NULL;
355 static bool meta_conn04 = false;
356
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]);
360
361         switch(payload.mesh_event) {
362         case META_CONN_SUCCESSFUL   :
363                 fprintf(stderr, "Meta Connection Successful\n");
364                 meta_conn04 = true;
365                 break;
366
367         case NODE_INVITATION        :
368                 fprintf(stderr, "Invitation generated\n");
369                 invite_peer = malloc(payload.payload_length);
370                 strcpy(invite_peer, (char *)payload.payload);
371                 break;
372
373         case NODE_STARTED           :
374                 fprintf(stderr, "Node started\n");
375                 break;
376
377         default                     :
378                 fprintf(stderr, "Undefined mesh event\n");
379         }
380
381         return true;
382 }
383
384 /* Execute Meta-connections Test Case # 4 - re-connection to peer after changing IP of
385     NUT and peer */
386 static void test_case_meta_conn_04(void **state) {
387         execute_test(test_steps_meta_conn_04, state);
388 }
389
390 /* Execute Meta-connections Test Case # 4 - re-connection to peer after changing IP of
391     NUT and peer
392
393     Test Steps:
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
396
397     Expected Result:
398     NUT is first disconnected from peer then automatically re-connected to peer
399 */
400 static bool test_steps_meta_conn_04(void) {
401         char *import;
402
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);
406
407         PRINT_TEST_CASE_MSG("Waiting for NUT to generate invitation to PEER\n");
408         wait_for_event(meta_conn04_cb, 5);
409
410         assert(invite_peer);
411
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");
417
418         assert(wait_for_event(meta_conn04_cb, 60));
419
420         PRINT_TEST_CASE_MSG("Changing IP address of NUT container\n");
421         change_ip(1);
422
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");
426         change_ip(0);
427         node_sim_in_container_event("peer", "1", NULL, "0", import);
428         wait_for_event(meta_conn04_cb, 5);
429
430         PRINT_TEST_CASE_MSG("Waiting for peer to be re-connected\n");
431         wait_for_event(meta_conn04_cb, 5);
432
433         mesh_event_destroy();
434         free(invite_peer);
435         free(import);
436
437         assert_int_equal(meta_conn04, true);
438
439         return true;
440 }
441
442 static char *invitation = NULL;
443
444 static bool meta_conn05 = false;
445
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]);
449
450         switch(payload.mesh_event) {
451         case META_CONN_SUCCESSFUL   :
452                 meta_conn05 = true;
453                 break;
454
455         case NODE_INVITATION        :
456                 invitation = malloc(payload.payload_length);
457                 strcpy(invitation, (char *)payload.payload);
458                 break;
459
460         case NODE_STARTED           :
461                 fprintf(stderr, "Node started\n");
462                 break;
463         }
464
465         return true;
466 }
467
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);
471 }
472
473 /* Execute Meta-connections Test Case # 5 - re-connection to peer after changing IP of peer
474
475     Test Steps:
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
478
479     Expected Result:
480     NUT is first disconnected from peer then automatically re-connected to peer
481 */
482 static bool test_steps_meta_conn_05(void) {
483         char *import;
484
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);
488
489         wait_for_event(meta_conn05_cb, 5);
490
491         assert(invitation);
492
493         node_sim_in_container_event("peer", "1", invitation, "0", import);
494         wait_for_event(meta_conn05_cb, 5);
495
496         assert(wait_for_event(meta_conn05_cb, 5));
497
498         change_ip(0);
499         meta_conn05 = false;
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);
504
505         mesh_event_destroy();
506         free(invitation);
507         free(import);
508
509         assert_int_equal(meta_conn05, true);
510
511         return true;
512 }
513
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)
526         };
527         total_tests += sizeof(blackbox_group0_tests) / sizeof(blackbox_group0_tests[0]);
528
529         return cmocka_run_group_tests(blackbox_group0_tests, black_box_group0_setup, black_box_group0_teardown);
530 }