Imported Upstream version 0.8.4
[platform/upstream/multipath-tools.git] / tests / util.c
1 /*
2  * Copyright (c) 2018 Benjamin Marzinski, Redhat
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
16  *
17  */
18
19 #include <stdbool.h>
20 #include <stdarg.h>
21 #include <stddef.h>
22 #include <setjmp.h>
23 #include <stdlib.h>
24 #include <cmocka.h>
25 #include "util.h"
26
27 #include "globals.c"
28
29 #define BITARR_SZ 4
30
31 static void test_basenamecpy_good0(void **state)
32 {
33         char dst[10];
34
35         assert_int_equal(basenamecpy("foobar", dst, sizeof(dst)), 6);
36         assert_string_equal(dst, "foobar");
37 }
38
39 static void test_basenamecpy_good1(void **state)
40 {
41         char dst[10];
42
43         assert_int_equal(basenamecpy("foo/bar", dst, sizeof(dst)), 3);
44         assert_string_equal(dst, "bar");
45 }
46
47 static void test_basenamecpy_good2(void **state)
48 {
49         char dst[10];
50
51         assert_int_equal(basenamecpy("/thud/blat", dst, sizeof(dst)), 4);
52         assert_string_equal(dst, "blat");
53 }
54
55 static void test_basenamecpy_good3(void **state)
56 {
57         char dst[4];
58
59         assert_int_equal(basenamecpy("foo/bar", dst, sizeof(dst)), 3);
60         assert_string_equal(dst, "bar");
61 }
62
63 static void test_basenamecpy_good4(void **state)
64 {
65         char dst[10];
66
67         assert_int_equal(basenamecpy("/xyzzy", dst, sizeof(dst)), 5);
68         assert_string_equal(dst, "xyzzy");
69 }
70
71 static void test_basenamecpy_good5(void **state)
72 {
73         char dst[4];
74
75         assert_int_equal(basenamecpy("/foo/bar\n", dst, sizeof(dst)), 3);
76         assert_string_equal(dst, "bar");
77 }
78
79 /* multipath expects any trailing whitespace to be stripped off the basename,
80  * so that it will match pp->dev */
81 static void test_basenamecpy_good6(void **state)
82 {
83         char dst[6];
84
85         assert_int_equal(basenamecpy("/xyzzy/plugh   ", dst, sizeof(dst)), 5);
86         assert_string_equal(dst, "plugh");
87 }
88
89 static void test_basenamecpy_good7(void **state)
90 {
91         char src[] = "/foo/bar";
92         char dst[10];
93
94         assert_int_equal(basenamecpy(src, dst, sizeof(dst)), 3);
95
96         strcpy(src, "badbadno");
97         assert_string_equal(dst, "bar");
98 }
99
100 /* buffer too small */
101 static void test_basenamecpy_bad0(void **state)
102 {
103         char dst[3];
104
105         assert_int_equal(basenamecpy("baz", dst, sizeof(dst)), 0);
106 }
107
108 /* ends in slash */
109 static void test_basenamecpy_bad1(void **state)
110 {
111         char dst[10];
112
113         assert_int_equal(basenamecpy("foo/bar/", dst, sizeof(dst)), 0);
114 }
115
116 static void test_basenamecpy_bad2(void **state)
117 {
118         char dst[10];
119
120         assert_int_equal(basenamecpy(NULL, dst, sizeof(dst)), 0);
121 }
122
123 static void test_basenamecpy_bad3(void **state)
124 {
125         char dst[10];
126
127         assert_int_equal(basenamecpy("", dst, sizeof(dst)), 0);
128 }
129
130 static void test_basenamecpy_bad4(void **state)
131 {
132         char dst[10];
133
134         assert_int_equal(basenamecpy("/", dst, sizeof(dst)), 0);
135 }
136
137 static void test_basenamecpy_bad5(void **state)
138 {
139         char dst[10];
140
141         assert_int_equal(basenamecpy("baz/qux", NULL, sizeof(dst)), 0);
142 }
143
144 static void test_bitmask_1(void **state)
145 {
146         uint64_t arr[BITARR_SZ];
147         int i, j, k, m, b;
148
149         memset(arr, 0, sizeof(arr));
150
151         for (j = 0; j < BITARR_SZ; j++) {
152                 for (i = 0; i < 64; i++) {
153                         b = 64 * j + i;
154                         assert(!is_bit_set_in_array(b, arr));
155                         set_bit_in_array(b, arr);
156                         for (k = 0; k < BITARR_SZ; k++) {
157                                 printf("b = %d j = %d k = %d a = %"PRIx64"\n",
158                                        b, j, k, arr[k]);
159                                 if (k == j)
160                                         assert_int_equal(arr[j], 1ULL << i);
161                                 else
162                                         assert_int_equal(arr[k], 0ULL);
163                         }
164                         for (m = 0; m < 64; m++)
165                                 if (i == m)
166                                         assert(is_bit_set_in_array(64 * j + m,
167                                                                    arr));
168                                 else
169                                         assert(!is_bit_set_in_array(64 * j + m,
170                                                                     arr));
171                         clear_bit_in_array(b, arr);
172                         assert(!is_bit_set_in_array(b, arr));
173                         for (k = 0; k < BITARR_SZ; k++)
174                                 assert_int_equal(arr[k], 0ULL);
175                 }
176         }
177 }
178
179 static void test_bitmask_2(void **state)
180 {
181         uint64_t arr[BITARR_SZ];
182         int i, j, k, m, b;
183
184         memset(arr, 0, sizeof(arr));
185
186         for (j = 0; j < BITARR_SZ; j++) {
187                 for (i = 0; i < 64; i++) {
188                         b = 64 * j + i;
189                         assert(!is_bit_set_in_array(b, arr));
190                         set_bit_in_array(b, arr);
191                         for (m = 0; m < 64; m++)
192                                 if (m <= i)
193                                         assert(is_bit_set_in_array(64 * j + m,
194                                                                    arr));
195                                 else
196                                         assert(!is_bit_set_in_array(64 * j + m,
197                                                                     arr));
198                         assert(is_bit_set_in_array(b, arr));
199                         for (k = 0; k < BITARR_SZ; k++) {
200                                 if (k < j || (k == j && i == 63))
201                                         assert_int_equal(arr[k], ~0ULL);
202                                 else if (k > j)
203                                         assert_int_equal(arr[k], 0ULL);
204                                 else
205                                         assert_int_equal(
206                                                 arr[k],
207                                                 (1ULL << (i + 1)) - 1);
208                         }
209                 }
210         }
211         for (j = 0; j < BITARR_SZ; j++) {
212                 for (i = 0; i < 64; i++) {
213                         b = 64 * j + i;
214                         assert(is_bit_set_in_array(b, arr));
215                         clear_bit_in_array(b, arr);
216                         for (m = 0; m < 64; m++)
217                                 if (m <= i)
218                                         assert(!is_bit_set_in_array(64 * j + m,
219                                                                     arr));
220                                 else
221                                         assert(is_bit_set_in_array(64 * j + m,
222                                                                    arr));
223                         assert(!is_bit_set_in_array(b, arr));
224                         for (k = 0; k < BITARR_SZ; k++) {
225                                 if (k < j || (k == j && i == 63))
226                                         assert_int_equal(arr[k], 0ULL);
227                                 else if (k > j)
228                                         assert_int_equal(arr[k], ~0ULL);
229                                 else
230                                         assert_int_equal(
231                                                 arr[k],
232                                                 ~((1ULL << (i + 1)) - 1));
233                         }
234                 }
235         }
236 }
237
238 int test_basenamecpy(void)
239 {
240         const struct CMUnitTest tests[] = {
241                 cmocka_unit_test(test_basenamecpy_good0),
242                 cmocka_unit_test(test_basenamecpy_good1),
243                 cmocka_unit_test(test_basenamecpy_good2),
244                 cmocka_unit_test(test_basenamecpy_good3),
245                 cmocka_unit_test(test_basenamecpy_good4),
246                 cmocka_unit_test(test_basenamecpy_good5),
247                 cmocka_unit_test(test_basenamecpy_good6),
248                 cmocka_unit_test(test_basenamecpy_good7),
249                 cmocka_unit_test(test_basenamecpy_bad0),
250                 cmocka_unit_test(test_basenamecpy_bad1),
251                 cmocka_unit_test(test_basenamecpy_bad2),
252                 cmocka_unit_test(test_basenamecpy_bad3),
253                 cmocka_unit_test(test_basenamecpy_bad4),
254                 cmocka_unit_test(test_basenamecpy_bad5),
255                 cmocka_unit_test(test_bitmask_1),
256                 cmocka_unit_test(test_bitmask_2),
257         };
258         return cmocka_run_group_tests(tests, NULL, NULL);
259 }
260
261 static const char src_str[] = "Hello";
262
263 /* strlcpy with length 0 */
264 static void test_strlcpy_0(void **state)
265 {
266         char tst[] = "word";
267         int rc;
268
269         rc = strlcpy(tst, src_str, 0);
270         assert_int_equal(rc, strlen(src_str));
271         assert_string_equal(tst, "word");
272 }
273
274 /* strlcpy with length 1 */
275 static void test_strlcpy_1(void **state)
276 {
277         char tst[] = "word";
278         int rc;
279
280         rc = strlcpy(tst, src_str, 1);
281         assert_int_equal(rc, strlen(src_str));
282         assert_int_equal(tst[0], '\0');
283         assert_string_equal(tst + 1, "ord");
284 }
285
286 /* strlcpy with length 2 */
287 static void test_strlcpy_2(void **state)
288 {
289         char tst[] = "word";
290         int rc;
291
292         rc = strlcpy(tst, src_str, 2);
293         assert_int_equal(rc, strlen(src_str));
294         assert_int_equal(tst[0], src_str[0]);
295         assert_int_equal(tst[1], '\0');
296         assert_string_equal(tst + 2, "rd");
297 }
298
299 /* strlcpy with dst length < src length */
300 static void test_strlcpy_3(void **state)
301 {
302         char tst[] = "word";
303         int rc;
304
305         rc = strlcpy(tst, src_str, sizeof(tst));
306         assert_int_equal(rc, strlen(src_str));
307         assert_int_equal(sizeof(tst) - 1, strlen(tst));
308         assert_true(strncmp(tst, src_str, sizeof(tst) - 1) == 0);
309 }
310
311 /* strlcpy with dst length > src length */
312 static void test_strlcpy_4(void **state)
313 {
314         static const char old[] = "0123456789";
315         char *tst;
316         int rc;
317
318         tst = strdup(old);
319         rc = strlcpy(tst, src_str, sizeof(old));
320         assert_int_equal(rc, strlen(src_str));
321         assert_string_equal(src_str, tst);
322         assert_string_equal(tst + sizeof(src_str), old + sizeof(src_str));
323         free(tst);
324 }
325
326 /* strlcpy with dst length = src length, dst not terminated */
327 static void test_strlcpy_5(void **state)
328 {
329         char *tst;
330         int rc;
331         const int sz = sizeof(src_str);
332
333         tst = malloc(sz);
334         memset(tst, 'f', sizeof(src_str));
335
336         rc = strlcpy(tst, src_str, sz);
337         assert_int_equal(rc, strlen(src_str));
338         assert_string_equal(src_str, tst);
339
340         free(tst);
341 }
342
343 /* strlcpy with dst length > src length, dst not terminated */
344 static void test_strlcpy_6(void **state)
345 {
346         char *tst;
347         int rc;
348         const int sz = sizeof(src_str);
349
350         tst = malloc(sz + 2);
351         memset(tst, 'f', sz + 2);
352
353         rc = strlcpy(tst, src_str, sz + 2);
354         assert_int_equal(rc, strlen(src_str));
355         assert_string_equal(src_str, tst);
356         assert_int_equal(tst[sz], 'f');
357         assert_int_equal(tst[sz + 1], 'f');
358
359         free(tst);
360 }
361
362 /* strlcpy with empty src */
363 static void test_strlcpy_7(void **state)
364 {
365         char tst[] = "word";
366         static const char empty[] = "";
367         int rc;
368
369         rc = strlcpy(tst, empty, sizeof(tst));
370         assert_int_equal(rc, strlen(empty));
371         assert_string_equal(empty, tst);
372         assert_string_equal(tst + 1, "ord");
373 }
374
375 /* strlcpy with empty src, length 0 */
376 static void test_strlcpy_8(void **state)
377 {
378         char tst[] = "word";
379         static const char empty[] = "";
380         int rc;
381
382         rc = strlcpy(tst, empty, 0);
383         assert_int_equal(rc, strlen(empty));
384         assert_string_equal("word", tst);
385 }
386
387 static int test_strlcpy(void)
388 {
389         const struct CMUnitTest tests[] = {
390                 cmocka_unit_test(test_strlcpy_0),
391                 cmocka_unit_test(test_strlcpy_1),
392                 cmocka_unit_test(test_strlcpy_2),
393                 cmocka_unit_test(test_strlcpy_3),
394                 cmocka_unit_test(test_strlcpy_4),
395                 cmocka_unit_test(test_strlcpy_5),
396                 cmocka_unit_test(test_strlcpy_6),
397                 cmocka_unit_test(test_strlcpy_7),
398                 cmocka_unit_test(test_strlcpy_8),
399         };
400
401         return cmocka_run_group_tests(tests, NULL, NULL);
402 }
403
404 int main(void)
405 {
406         int ret = 0;
407
408         ret += test_basenamecpy();
409         ret += test_strlcpy();
410         return ret;
411 }