]> git.meshlink.io Git - meshlink/blob - test/blackbox/run_blackbox_tests/test_cases_invite.c
Add missing atomic test cases to the APIs that affects disk writes
[meshlink] / test / blackbox / run_blackbox_tests / test_cases_invite.c
1 /*
2     test_cases_invite.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 "execute_tests.h"
25 #include "test_cases_invite.h"
26 #include "../common/containers.h"
27 #include "../common/test_step.h"
28 #include "../common/common_handlers.h"
29 #include "../../utils.h"
30 #include <assert.h>
31 #include <string.h>
32 #include <stdlib.h>
33 #include <stdarg.h>
34 #include <setjmp.h>
35 #include <cmocka.h>
36 #include <signal.h>
37 #include <linux/limits.h>
38
39 /* Modify this to change the logging level of Meshlink */
40 #define TEST_MESHLINK_LOG_LEVEL MESHLINK_DEBUG
41
42 #define NUT                         "nut"
43 #define PEER                        "peer"
44 #define TEST_MESHLINK_INVITE        "test_invite"
45 #define create_path(confbase, node_name, test_case_no)   assert(snprintf(confbase, sizeof(confbase), TEST_MESHLINK_INVITE "_%ld_%s_%02d", (long) getpid(), node_name, test_case_no) > 0)
46
47 static void test_case_invite_01(void **state);
48 static bool test_invite_01(void);
49 static void test_case_invite_02(void **state);
50 static bool test_invite_02(void);
51 static void test_case_invite_03(void **state);
52 static bool test_invite_03(void);
53 static void test_case_invite_04(void **state);
54 static bool test_invite_04(void);
55 static void test_case_invite_05(void **state);
56 static bool test_invite_05(void);
57
58 /* State structure for invite API Test Case #1 */
59 static black_box_state_t test_case_invite_01_state = {
60         .test_case_name = "test_case_invite_01",
61 };
62
63 /* State structure for invite API Test Case #2 */
64 static black_box_state_t test_case_invite_02_state = {
65         .test_case_name = "test_case_invite_02",
66 };
67
68 /* State structure for invite API Test Case #3 */
69 static black_box_state_t test_case_invite_03_state = {
70         .test_case_name = "test_case_invite_03",
71 };
72
73 /* State structure for invite API Test Case #4 */
74 static black_box_state_t test_case_invite_04_state = {
75         .test_case_name = "test_case_invite_04",
76 };
77
78 /* State structure for invite API Test Case #5 */
79 static black_box_state_t test_case_invite_05_state = {
80         .test_case_name = "test_case_invite_05",
81 };
82
83 /* Execute invite Test Case # 1 - valid case*/
84 static void test_case_invite_01(void **state) {
85         execute_test(test_invite_01, state);
86 }
87 /*Test Steps for meshlink_invite Test Case # 1 - Valid case
88     Test Steps:
89     1. Run NUT
90     2. Invite 'new' node
91
92     Expected Result:
93     Generates an invitation
94 */
95 static bool test_invite_01(void) {
96         char nut_confbase[PATH_MAX];
97         char peer_invitation[1000];
98         create_path(nut_confbase, NUT, 1);
99
100         // Create meshlink instance
101
102         meshlink_set_log_cb(NULL, MESHLINK_DEBUG, log_cb);
103         meshlink_handle_t *mesh = meshlink_open(nut_confbase, NUT, TEST_MESHLINK_INVITE, DEV_CLASS_STATIONARY);
104         assert_non_null(mesh);
105
106         char *invitation = meshlink_invite(mesh, NULL, "new");
107         assert_non_null(invitation);
108
109         free(invitation);
110         meshlink_close(mesh);
111         assert_true(meshlink_destroy(nut_confbase));
112         return true;
113 }
114
115 /* Execute invite Test Case # 2 - Invalid case*/
116 static void test_case_invite_02(void **state) {
117         execute_test(test_invite_02, state);
118 }
119 /*Test Steps for meshlink_invite Test Case # 2 - Invalid case
120     Test Steps:
121     1. Calling meshlink_invite API with NULL as mesh handle argument
122
123     Expected Result:
124     Reports appropriate error by returning NULL
125 */
126 static bool test_invite_02(void) {
127         // Trying to generate INVITATION by passing NULL as mesh link handle
128         char *invitation = meshlink_invite(NULL, NULL, "nut");
129         assert_int_equal(invitation, NULL);
130
131         return true;
132 }
133
134 /* Execute invite Test Case # 3 - Invalid case*/
135 static void test_case_invite_03(void **state) {
136         execute_test(test_invite_03, state);
137 }
138 /*Test Steps for meshlink_invite Test Case # 3 - Invalid case
139     Test Steps:
140     1. Run NUT
141     2. Call meshlink_invite with NULL node name argument
142
143     Expected Result:
144     Reports appropriate error by returning NULL
145 */
146 static bool test_invite_03(void) {
147         char nut_confbase[PATH_MAX];
148         char peer_invitation[1000];
149         create_path(nut_confbase, NUT, 3);
150
151         // Create meshlink instance
152
153         meshlink_set_log_cb(NULL, MESHLINK_DEBUG, log_cb);
154         meshlink_handle_t *mesh = meshlink_open(nut_confbase, NUT, TEST_MESHLINK_INVITE, DEV_CLASS_STATIONARY);
155         assert_non_null(mesh);
156
157         char *invitation = meshlink_invite(mesh, NULL, NULL);
158         assert_int_equal(invitation, NULL);
159
160         free(invitation);
161         meshlink_close(mesh);
162         assert_true(meshlink_destroy(nut_confbase));
163         return true;
164 }
165
166 /* Execute invite Test Case # 4 - Functionality test*/
167 static void test_case_invite_04(void **state) {
168         execute_test(test_invite_04, state);
169 }
170 /*Test Steps for meshlink_invite Test Case # 4 - Functionality test
171
172     Test Steps:
173     1. Create node instance
174     2. Add a new address to the mesh and invite a node
175     3. Add another new address and invite a node
176
177     Expected Result:
178     Newly added address should be there in the invitation.
179 */
180 static bool test_invite_04(void) {
181         char nut_confbase[PATH_MAX];
182         char peer_invitation[1000];
183         create_path(nut_confbase, NUT, 4);
184
185         // Create meshlink instance
186
187         meshlink_set_log_cb(NULL, MESHLINK_DEBUG, log_cb);
188         meshlink_handle_t *mesh = meshlink_open(nut_confbase, NUT, TEST_MESHLINK_INVITE, DEV_CLASS_STATIONARY);
189         assert_non_null(mesh);
190
191         assert_true(meshlink_add_invitation_address(mesh, "11.11.11.11", "2020"));
192         char *invitation = meshlink_invite(mesh, NULL, "foo");
193         assert_non_null(strstr(invitation, "11.11.11.11:2020"));
194         free(invitation);
195
196         assert_true(meshlink_add_invitation_address(mesh, "fe80::1548:d713:3899:f645", "3030"));
197         invitation = meshlink_invite(mesh, NULL, "bar");
198         assert_non_null(strstr(invitation, "11.11.11.11:2020"));
199         assert_non_null(strstr(invitation, "[fe80::1548:d713:3899:f645]:3030"));
200         free(invitation);
201
202         meshlink_close(mesh);
203         assert_true(meshlink_destroy(nut_confbase));
204         return true;
205 }
206
207 /* Execute invite Test Case # 5 - Synchronization testing */
208 static void test_case_invite_05(void **state) {
209         execute_test(test_invite_05, state);
210 }
211
212 static bool test_invite_05(void) {
213         bool status;
214         pid_t pid;
215         int pid_status;
216         int pipefd[2];
217         char nut_confbase[PATH_MAX];
218         char peer_confbase[PATH_MAX];
219         char peer_invitation[1000];
220         create_path(nut_confbase, NUT, 5);
221         create_path(peer_confbase, PEER, 5);
222
223         assert_int_not_equal(pipe(pipefd), -1);
224
225         // Fork a new process in which NUT opens it's instance and raises SIGINT to terminate.
226
227         pid = fork();
228         assert_int_not_equal(pid, -1);
229
230         if(!pid) {
231                 assert(!close(pipefd[0]));
232                 meshlink_set_log_cb(NULL, MESHLINK_DEBUG, log_cb);
233                 meshlink_handle_t *mesh = meshlink_open(nut_confbase, NUT, TEST_MESHLINK_INVITE, DEV_CLASS_STATIONARY);
234                 assert(mesh);
235
236                 char *invitation = meshlink_invite(mesh, NULL, PEER);
237                 write(pipefd[1], invitation, strlen(invitation) + 1);
238
239                 raise(SIGINT);
240         }
241
242         // Wait for child exit and verify which signal terminated it
243
244         assert_int_not_equal(waitpid(pid, &pid_status, 0), -1);
245         assert_int_equal(WIFSIGNALED(pid_status), true);
246         assert_int_equal(WTERMSIG(pid_status), SIGINT);
247
248         assert_int_equal(close(pipefd[1]), 0);
249         assert_int_not_equal(read(pipefd[0], peer_invitation, sizeof(peer_invitation)), -1);
250
251         // Reopen the NUT instance in the same test suite
252
253         meshlink_set_log_cb(NULL, MESHLINK_DEBUG, log_cb);
254         meshlink_handle_t *mesh = meshlink_open(nut_confbase, NUT, TEST_MESHLINK_INVITE, DEV_CLASS_STATIONARY);
255         assert_non_null(mesh);
256         meshlink_handle_t *mesh_peer = meshlink_open(peer_confbase, PEER, TEST_MESHLINK_INVITE, DEV_CLASS_STATIONARY);
257         assert_non_null(mesh);
258         assert_true(meshlink_start(mesh));
259         assert_true(meshlink_join(mesh_peer, peer_invitation));
260
261         // Cleanup
262
263         meshlink_close(mesh);
264         meshlink_close(mesh_peer);
265         assert_true(meshlink_destroy(nut_confbase));
266         assert_true(meshlink_destroy(peer_confbase));
267         return true;
268 }
269
270 int test_meshlink_invite(void) {
271         const struct CMUnitTest blackbox_invite_tests[] = {
272                 cmocka_unit_test_prestate_setup_teardown(test_case_invite_01, NULL, NULL,
273                                 (void *)&test_case_invite_01_state),
274                 cmocka_unit_test_prestate_setup_teardown(test_case_invite_02, NULL, NULL,
275                                 (void *)&test_case_invite_02_state),
276                 cmocka_unit_test_prestate_setup_teardown(test_case_invite_03, NULL, NULL,
277                                 (void *)&test_case_invite_03_state),
278                 cmocka_unit_test_prestate_setup_teardown(test_case_invite_04, NULL, NULL,
279                                 (void *)&test_case_invite_04_state),
280                 cmocka_unit_test_prestate_setup_teardown(test_case_invite_05, NULL, NULL,
281                                 (void *)&test_case_invite_05_state)
282         };
283
284         total_tests += sizeof(blackbox_invite_tests) / sizeof(blackbox_invite_tests[0]);
285
286         return cmocka_run_group_tests(blackbox_invite_tests, NULL, NULL);
287 }