]> git.meshlink.io Git - meshlink/blob - test/blackbox/run_blackbox_tests/test_cases_random_port_bindings02.c
Fix compiler warnings in the test suites.
[meshlink] / test / blackbox / run_blackbox_tests / test_cases_random_port_bindings02.c
1 /*
2     test_optimal_pmtu.c -- Execution of specific meshlink black box test cases
3     Copyright (C) 2019  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 <pthread.h>
25 #include "../../../src/meshlink.h"
26 #include "../common/containers.h"
27 #include "../common/test_step.h"
28 #include "../common/common_handlers.h"
29 #include "../common/network_namespace_framework.h"
30 #include "../../utils.h"
31 #include "test_cases_random_port_bindings02.h"
32
33 static void test_case_mesh_random_port_bindings_04(void **state);
34 static bool test_steps_mesh_random_port_bindings_04(void);
35 static void test_case_mesh_random_port_bindings_05(void **state);
36 static bool test_steps_mesh_random_port_bindings_05(void);
37
38 typedef bool (*test_step_func_t)(void);
39 static int setup_test(void **state);
40
41 static meshlink_handle_t *peer, *nut_instance, *relay;
42 static char *peer_invite, *nut_invite;
43 struct sync_flag test_random_port_binding_node_connected = {.mutex  = PTHREAD_MUTEX_INITIALIZER, .cond = PTHREAD_COND_INITIALIZER};
44 struct sync_flag test_random_port_binding_node_started = {.mutex  = PTHREAD_MUTEX_INITIALIZER, .cond = PTHREAD_COND_INITIALIZER};
45 struct sync_flag test_random_port_binding_peer_reachable = {.mutex  = PTHREAD_MUTEX_INITIALIZER, .cond = PTHREAD_COND_INITIALIZER};
46 struct sync_flag test_random_port_binding_make_switch = {.mutex  = PTHREAD_MUTEX_INITIALIZER, .cond = PTHREAD_COND_INITIALIZER};
47 struct sync_flag test_random_port_binding_relay_closed = {.mutex  = PTHREAD_MUTEX_INITIALIZER, .cond = PTHREAD_COND_INITIALIZER};
48 struct sync_flag test_random_port_binding_peer_closed = {.mutex  = PTHREAD_MUTEX_INITIALIZER, .cond = PTHREAD_COND_INITIALIZER};
49 struct sync_flag test_random_port_binding_nut_closed = {.mutex  = PTHREAD_MUTEX_INITIALIZER, .cond = PTHREAD_COND_INITIALIZER};
50 static netns_state_t *test_random_port_bindings_state;
51 static bool localnode = false;
52
53 static int setup_test(void **state) {
54         (void)state;
55
56         netns_create_topology(test_random_port_bindings_state);
57         fprintf(stderr, "\nCreated topology\n");
58
59         set_sync_flag(&test_random_port_binding_node_connected, false);
60         set_sync_flag(&test_random_port_binding_node_started, false);
61         set_sync_flag(&test_random_port_binding_peer_reachable, false);
62         set_sync_flag(&test_random_port_binding_make_switch, false);
63         set_sync_flag(&test_random_port_binding_relay_closed, false);
64         set_sync_flag(&test_random_port_binding_peer_closed, false);
65         set_sync_flag(&test_random_port_binding_nut_closed, false);
66
67         meshlink_destroy("nut");
68         meshlink_destroy("peer");
69         meshlink_destroy("relay");
70
71         return EXIT_SUCCESS;
72 }
73
74 static int teardown_test(void **state) {
75         (void)state;
76
77         meshlink_destroy("nut");
78         meshlink_destroy("peer");
79         meshlink_destroy("relay");
80         netns_destroy_topology(test_random_port_bindings_state);
81
82         return EXIT_SUCCESS;
83 }
84
85 static void execute_test(test_step_func_t step_func, void **state) {
86         (void)state;
87
88
89         fprintf(stderr, "\n\x1b[32mRunning Test\x1b[0m\n");
90         bool test_result = step_func();
91
92         if(!test_result) {
93                 fail();
94         }
95 }
96
97 static void message_log(meshlink_handle_t *mesh, meshlink_log_level_t level, const char *text) {
98         (void)level;
99
100         char *levelstr = "\x1b[32mRELAY";
101
102         if(strcmp(mesh->name, "peer") == 0) {
103                 if(strcmp("Connection with nut activated", text) == 0) {
104                         set_sync_flag(&test_random_port_binding_node_connected, true);
105                 }
106
107                 levelstr = "\x1b[34mPEER";
108         } else if(strcmp(mesh->name, "nut") == 0) {
109                 if(strcmp("Connection with peer activated", text) == 0) {
110                         set_sync_flag(&test_random_port_binding_node_connected, true);
111                 }
112
113                 levelstr = "\x1b[33mNUT";
114         }
115
116         fprintf(stderr, "%s:\x1b[0m %s\n", levelstr, text);
117 }
118
119 static void node_status(meshlink_handle_t *mesh, meshlink_node_t *node, bool reachable) {
120         (void)mesh;
121
122         if(reachable) {
123                 if((strcmp(mesh->name, "nut") == 0) && (strcmp(node->name, "peer") == 0)) {
124                         set_sync_flag(&test_random_port_binding_peer_reachable, true);
125                 }
126
127                 fprintf(stderr, "%s: %s joined.\n", mesh->name, node->name);
128         }
129 }
130
131 static void *relay_node(void *arg) {
132         mesh_arg_t *mesh_arg = (mesh_arg_t *)arg;
133
134         //system("ifconfig");
135
136         meshlink_destroy("relay");
137
138         relay = meshlink_open(mesh_arg->node_name, mesh_arg->confbase, mesh_arg->app_name, mesh_arg->dev_class);
139         assert(relay);
140
141         assert_true(meshlink_start(relay));
142         fprintf(stderr, "\n\x1b[32mRelay Started\x1b[0m\n");
143
144         assert((peer_invite = meshlink_invite(relay, NULL, "peer")));
145         assert((nut_invite = meshlink_invite(relay, NULL, "nut")));
146
147         set_sync_flag(&test_random_port_binding_node_started, true);
148
149         meshlink_set_log_cb(relay, MESHLINK_DEBUG, message_log);
150
151         if(localnode == true) {
152                 assert(wait_sync_flag(&test_random_port_binding_make_switch, 300));
153                 meshlink_close(relay);
154                 meshlink_destroy("relay");
155
156
157                 set_sync_flag(&test_random_port_binding_relay_closed, true);
158
159                 return NULL;
160         }
161
162         assert(wait_sync_flag(&test_random_port_binding_node_connected, 300));
163
164         meshlink_close(relay);
165         meshlink_destroy("relay");
166
167
168         set_sync_flag(&test_random_port_binding_relay_closed, true);
169
170         return NULL;
171 }
172
173 static void *peer_node(void *arg) {
174         mesh_arg_t *mesh_arg = (mesh_arg_t *)arg;
175
176         fprintf(stderr, "\n\x1b[32mPeer Thread Started\x1b[0m\n");
177
178         meshlink_destroy("peer");
179
180         peer = meshlink_open(mesh_arg->node_name, mesh_arg->confbase, mesh_arg->app_name, mesh_arg->dev_class);
181         assert(peer);
182         meshlink_set_log_cb(peer, MESHLINK_DEBUG, message_log);
183
184         fprintf(stderr, "\n\x1b[32mPeer joining relay\x1b[0m\n");
185
186         assert_true(meshlink_join(peer, (const char *)mesh_arg->join_invitation));
187
188         assert_true(meshlink_start(peer));
189
190         fprintf(stderr, "\n\x1b[32mPeer Started\x1b[0m\n");
191
192         set_sync_flag(&test_random_port_binding_node_started, true);
193
194         assert(wait_sync_flag(&test_random_port_binding_make_switch, 300));
195
196         meshlink_stop(peer);
197
198         //meshlink_set_log_cb(peer, MESHLINK_DEBUG, message_log);
199
200         assert(meshlink_set_port(peer, 20000));
201
202         assert_true(meshlink_start(peer));
203
204         assert(wait_sync_flag(&test_random_port_binding_node_connected, 300));
205
206         meshlink_close(peer);
207         meshlink_destroy("peer");
208
209         set_sync_flag(&test_random_port_binding_peer_closed, true);
210
211         return NULL;
212 }
213
214 static void *nut_node(void *arg) {
215         mesh_arg_t *mesh_arg = (mesh_arg_t *)arg;
216
217         fprintf(stderr, "\n\x1b[32mNut Thread Started\x1b[0m\n");
218
219         meshlink_destroy("nut");
220
221         nut_instance = meshlink_open(mesh_arg->node_name, mesh_arg->confbase, mesh_arg->app_name, mesh_arg->dev_class);
222         assert(nut_instance);
223
224         meshlink_set_log_cb(nut_instance, MESHLINK_DEBUG, message_log);
225
226         fprintf(stderr, "\n\x1b[32mNut joining relay\x1b[0m\n");
227
228         assert_true(meshlink_join(nut_instance, (const char *)mesh_arg->join_invitation));
229
230         meshlink_set_node_status_cb(nut_instance, node_status);
231
232         assert_true(meshlink_start(nut_instance));
233
234         fprintf(stderr, "\n\x1b[32mNut Started\x1b[0m\n");
235         sleep(5);
236
237         set_sync_flag(&test_random_port_binding_node_started, true);
238
239         assert(wait_sync_flag(&test_random_port_binding_make_switch, 300));
240
241         meshlink_stop(nut_instance);
242
243         //meshlink_set_log_cb(nut_instance, MESHLINK_DEBUG, message_log);
244
245         assert(meshlink_set_port(nut_instance, 30000));
246
247         assert_true(meshlink_start(nut_instance));
248
249         assert(wait_sync_flag(&test_random_port_binding_node_connected, 300));
250
251         meshlink_close(nut_instance);
252         meshlink_destroy("nut");
253
254         set_sync_flag(&test_random_port_binding_nut_closed, true);
255
256         return NULL;
257 }
258
259 /* Test Steps for Random port bindings Test Case # 4 */
260 static void test_case_mesh_random_port_bindings_04(void **state) {
261         execute_test(test_steps_mesh_random_port_bindings_04, state);
262         return;
263 }
264
265 /* Test Steps for Random port bindings Test Case # 4
266
267     Test Steps:
268     1. Create three node nut, peer and relay in three different name spaces.
269     2. Join nut and peer to relay with invitation.
270     3. Stop the three nodes and change the ports of nut and peer.
271     4. Start all the nodes again.
272     Expected Result:
273       NUT and Peer should be able to discover each others port with the help
274       of RELAY and form the direct meta connection.
275 */
276 static bool test_steps_mesh_random_port_bindings_04(void) {
277         mesh_arg_t relay_arg = {.node_name = "relay", .confbase = "relay", .app_name = "chat", .dev_class = 0 };
278         mesh_arg_t peer_arg = {.node_name = "peer", .confbase = "peer", .app_name = "chat", .dev_class = 1 };
279         mesh_arg_t nut_arg = {.node_name = "nut", .confbase = "nut", .app_name = "chat", .dev_class = 1 };
280
281         netns_thread_t netns_relay_handle = {.namespace_name = "relay", .netns_thread = relay_node, .arg = &relay_arg};
282         run_node_in_namespace_thread(&netns_relay_handle);
283
284         assert(wait_sync_flag(&test_random_port_binding_node_started, 5));
285         fprintf(stderr, "\n\x1b[32mTest-04 : Relay Started\x1b[0m\n");
286
287         set_sync_flag(&test_random_port_binding_node_started, false);
288         peer_arg.join_invitation = peer_invite;
289         fprintf(stderr, "\n\x1b[32mTest-04: Got Invite {%s} for peer\x1b[0m\n", peer_arg.join_invitation);
290         netns_thread_t netns_peer_handle = {.namespace_name = "peer", .netns_thread = peer_node, .arg = &peer_arg};
291         run_node_in_namespace_thread(&netns_peer_handle);
292
293         assert(wait_sync_flag(&test_random_port_binding_node_started, 20));
294         fprintf(stderr, "\n\x1b[32mTest-04 : Peer Started\x1b[0m\n");
295
296         set_sync_flag(&test_random_port_binding_node_started, false);
297         nut_arg.join_invitation = nut_invite;
298         fprintf(stderr, "\n\x1b[32mTest-04: Got Invite {%s} for nut\x1b[0m\n", nut_arg.join_invitation);
299         netns_thread_t netns_nut_handle = {.namespace_name = "nut", .netns_thread = nut_node, .arg = &nut_arg};
300         run_node_in_namespace_thread(&netns_nut_handle);
301
302         assert(wait_sync_flag(&test_random_port_binding_node_started, 20));
303         fprintf(stderr, "\n\x1b[32mTest-04 : Nut Started\x1b[0m\n");
304
305         set_sync_flag(&test_random_port_binding_make_switch, true);
306         fprintf(stderr, "\n\x1b[32mTest-04 : Making Switch\x1b[0m\n");
307
308         assert(wait_sync_flag(&test_random_port_binding_node_connected, 300));
309
310         fprintf(stderr, "\n\x1b[32mDone Test-04\x1b[0m\n");
311
312         assert(wait_sync_flag(&test_random_port_binding_relay_closed, 10));
313         assert(wait_sync_flag(&test_random_port_binding_peer_closed, 10));
314         assert(wait_sync_flag(&test_random_port_binding_nut_closed, 10));
315
316         return true;
317 }
318
319 /* Test Steps for Random port bindings Test Case # 5 */
320 static void test_case_mesh_random_port_bindings_05(void **state) {
321         execute_test(test_steps_mesh_random_port_bindings_05, state);
322         return;
323 }
324
325 /* Test Steps for Random port bindings Test Case # 5
326
327     Test Steps:
328     1. Create three node nut, peer and relay in same name spaces.
329     2. Join nut and peer to relay with invitation.
330     3. Stop the three nodes and change the ports of nut and peer.
331     4. Close the relay node and start nut and peer nodes again.
332     Expected Result:
333       NUT and Peer should be able to discover each others port with the help
334       of CATTA and form the direct meta connection.
335 */
336 static bool test_steps_mesh_random_port_bindings_05(void) {
337         localnode = true;
338
339         mesh_arg_t relay_arg = {.node_name = "relay", .confbase = "relay", .app_name = "chat", .dev_class = 1 };
340         mesh_arg_t peer_arg = {.node_name = "peer", .confbase = "peer", .app_name = "chat", .dev_class = 1 };
341         mesh_arg_t nut_arg = {.node_name = "nut", .confbase = "nut", .app_name = "chat", .dev_class = 1 };
342
343         netns_thread_t netns_relay_handle = {.namespace_name = "relay", .netns_thread = relay_node, .arg = &relay_arg};
344         run_node_in_namespace_thread(&netns_relay_handle);
345
346         assert(wait_sync_flag(&test_random_port_binding_node_started, 20));
347
348         set_sync_flag(&test_random_port_binding_node_started, false);
349         peer_arg.join_invitation = peer_invite;
350         netns_thread_t netns_peer_handle = {.namespace_name = "peer", .netns_thread = peer_node, .arg = &peer_arg};
351         run_node_in_namespace_thread(&netns_peer_handle);
352
353         assert(wait_sync_flag(&test_random_port_binding_node_started, 20));
354
355         set_sync_flag(&test_random_port_binding_node_started, false);
356         nut_arg.join_invitation = nut_invite;
357         netns_thread_t netns_nut_handle = {.namespace_name = "nut", .netns_thread = nut_node, .arg = &nut_arg};
358         run_node_in_namespace_thread(&netns_nut_handle);
359
360         assert(wait_sync_flag(&test_random_port_binding_node_started, 20));
361
362         assert(wait_sync_flag(&test_random_port_binding_peer_reachable, 300));
363
364         set_sync_flag(&test_random_port_binding_make_switch, true);
365
366         assert(wait_sync_flag(&test_random_port_binding_node_connected, 300));
367
368         fprintf(stderr, "\n\x1b[32mDone Test-05\x1b[0m\n");
369
370         assert(wait_sync_flag(&test_random_port_binding_relay_closed, 10));
371         assert(wait_sync_flag(&test_random_port_binding_peer_closed, 10));
372         assert(wait_sync_flag(&test_random_port_binding_nut_closed, 10));
373
374         return true;
375 }
376
377 // Optimal PMTU test case driver
378
379 int test_meshlink_random_port_bindings02(void) {
380         interface_t nut_ifs[] = {{.if_peer = "wan_bridge"}};
381         namespace_t nut = {
382                 .name = "nut",
383                 .type = HOST,
384                 .interfaces = nut_ifs,
385                 .interfaces_no = 1,
386         };
387
388         interface_t peer_ifs[] = {{.if_peer = "wan_bridge"}};
389         namespace_t peer = {
390                 .name = "peer",
391                 .type = HOST,
392                 .interfaces = peer_ifs,
393                 .interfaces_no = 1,
394         };
395
396         interface_t relay_ifs[] = {{.if_peer = "wan_bridge"}};
397         namespace_t relay = {
398                 .name = "relay",
399                 .type = HOST,
400                 .interfaces = relay_ifs,
401                 .interfaces_no = 1,
402         };
403
404         interface_t wan_ifs[] = { { .if_peer = "nut" }, { .if_peer = "peer" }, { .if_peer = "relay" } };
405         namespace_t wan_bridge = {
406                 .name = "wan_bridge",
407                 .type = BRIDGE,
408                 .interfaces = wan_ifs,
409                 .interfaces_no = 3,
410         };
411
412         namespace_t test_random_port_bindings_02_nodes[] = {wan_bridge, nut, peer, relay };
413
414         netns_state_t test_port_bindings_nodes = {
415                 .test_case_name =  "test_case_random_port_bindings_02",
416                 .namespaces =  test_random_port_bindings_02_nodes,
417                 .num_namespaces = 4,
418         };
419         test_random_port_bindings_state = &test_port_bindings_nodes;
420
421         const struct CMUnitTest blackbox_group0_tests[] = {
422                 cmocka_unit_test_prestate_setup_teardown(test_case_mesh_random_port_bindings_04, setup_test, teardown_test,
423                                 (void *)&test_random_port_bindings_state),
424                 cmocka_unit_test_prestate_setup_teardown(test_case_mesh_random_port_bindings_05, setup_test, teardown_test,
425                                 (void *)&test_random_port_bindings_state)
426         };
427         total_tests += sizeof(blackbox_group0_tests) / sizeof(blackbox_group0_tests[0]);
428
429         return cmocka_run_group_tests(blackbox_group0_tests, NULL, NULL);
430 }