tests: add unit tests for bitmask functions
[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 int main(void)
262 {
263         int ret = 0;
264
265         ret += test_basenamecpy();
266         return ret;
267 }