tests: add unit tests for config file parser
[multipath-tools/.git] / tests / parser.c
1 /*
2  * Copyright (c) 2018 SUSE Linux GmbH
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, write to the Free Software
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 "list.h"
26 #include "parser.h"
27 #include "vector.h"
28
29 #include "globals.c"
30
31 /* Set these to 1 to get success for current broken behavior */
32 /* Strip leading whitespace between quotes */
33 #define LSTRIP_QUOTED_WSP 0
34 /* Stop parsing at 2nd quote */
35 #define TWO_QUOTES_ONLY 0
36
37 static bool is_quote(const char *s)
38 {
39         return *s == '"';
40 }
41
42 static char *test_file = "test.conf";
43
44 /* Missing declaration */
45 int validate_config_strvec(vector strvec, char *file);
46
47 /* Stringify helpers */
48 #define _str_(x) #x
49 #define str(x) _str_(x)
50
51 static int setup(void **state)
52 {
53         return 0;
54 }
55
56 static int teardown(void **state)
57 {
58         return 0;
59 }
60
61 static void test01(void **state)
62 {
63         vector v = alloc_strvec("keyword value");
64         char *val;
65
66         assert_int_equal(validate_config_strvec(v, test_file), 0);
67         assert_int_equal(VECTOR_SIZE(v), 2);
68         assert_string_equal(VECTOR_SLOT(v, 0), "keyword");
69         assert_string_equal(VECTOR_SLOT(v, 1), "value");
70
71         val = set_value(v);
72         assert_string_equal(val, "value");
73
74         free(val);
75         free_strvec(v);
76 }
77
78 static void test02(void **state)
79 {
80         vector v = alloc_strvec("keyword \"value\"");
81         char *val;
82
83         assert_int_equal(validate_config_strvec(v, test_file), 0);
84         assert_int_equal(VECTOR_SIZE(v), 4);
85         assert_string_equal(VECTOR_SLOT(v, 0), "keyword");
86         assert_true(is_quote(VECTOR_SLOT(v, 1)));;
87         assert_string_equal(VECTOR_SLOT(v, 2), "value");
88         assert_true(is_quote(VECTOR_SLOT(v, 3)));;
89
90         val = set_value(v);
91         assert_string_equal(val, "value");
92
93         free(val);
94         free_strvec(v);
95 }
96
97 static void test03(void **state)
98 {
99         vector v = alloc_strvec("keyword value\n");
100         char *val;
101
102         assert_int_equal(validate_config_strvec(v, test_file), 0);
103         assert_int_equal(VECTOR_SIZE(v), 2);
104         assert_string_equal(VECTOR_SLOT(v, 0), "keyword");
105         assert_string_equal(VECTOR_SLOT(v, 1), "value");
106
107         val = set_value(v);
108         assert_string_equal(val, "value");
109
110         free(val);
111         free_strvec(v);
112 }
113
114 static void test04(void **state)
115 {
116         vector v = alloc_strvec("keyword \t   value   \t \n   ");
117         char *val;
118
119         assert_int_equal(validate_config_strvec(v, test_file), 0);
120         assert_int_equal(VECTOR_SIZE(v), 2);
121         assert_string_equal(VECTOR_SLOT(v, 0), "keyword");
122         assert_string_equal(VECTOR_SLOT(v, 1), "value");
123
124         val = set_value(v);
125         assert_string_equal(val, "value");
126
127         free(val);
128         free_strvec(v);
129 }
130
131 static void test05(void **state)
132 {
133         vector v = alloc_strvec("keyword \t   value   \t ! comment  ");
134         char *val;
135
136         assert_int_equal(validate_config_strvec(v, test_file), 0);
137         assert_int_equal(VECTOR_SIZE(v), 2);
138         assert_string_equal(VECTOR_SLOT(v, 0), "keyword");
139         assert_string_equal(VECTOR_SLOT(v, 1), "value");
140
141         val = set_value(v);
142         assert_string_equal(val, "value");
143
144         free(val);
145         free_strvec(v);
146 }
147
148 static void test06(void **state)
149 {
150         vector v = alloc_strvec("keyword \t   value   # \n comment  ");
151         char *val;
152
153         assert_int_equal(validate_config_strvec(v, test_file), 0);
154         assert_int_equal(VECTOR_SIZE(v), 2);
155         assert_string_equal(VECTOR_SLOT(v, 0), "keyword");
156         assert_string_equal(VECTOR_SLOT(v, 1), "value");
157
158         val = set_value(v);
159         assert_string_equal(val, "value");
160
161         free(val);
162         free_strvec(v);
163 }
164
165 static void test07(void **state)
166 {
167         vector v = alloc_strvec("keyword \t   value   more  ");
168         char *val;
169
170         assert_int_equal(validate_config_strvec(v, test_file), 0);
171         assert_int_equal(VECTOR_SIZE(v), 3);
172         assert_string_equal(VECTOR_SLOT(v, 0), "keyword");
173         assert_string_equal(VECTOR_SLOT(v, 1), "value");
174         assert_string_equal(VECTOR_SLOT(v, 2), "more");
175
176         val = set_value(v);
177         assert_string_equal(val, "value");
178
179         free(val);
180         free_strvec(v);
181 }
182
183 static void test08(void **state)
184 {
185 #define QUOTED08 "  value   more  "
186 #define QUOTED08B "value   more  "
187         vector v = alloc_strvec("keyword \t \"" QUOTED08 "\"");
188         char *val;
189
190         assert_int_equal(validate_config_strvec(v, test_file), 0);
191         assert_int_equal(VECTOR_SIZE(v), 4);
192         assert_string_equal(VECTOR_SLOT(v, 0), "keyword");
193         assert_true(is_quote(VECTOR_SLOT(v, 1)));;
194 #if LSTRIP_QUOTED_WSP
195         assert_string_equal(VECTOR_SLOT(v, 2), QUOTED08B);
196 #else
197         assert_string_equal(VECTOR_SLOT(v, 2), QUOTED08);
198 #endif
199         assert_true(is_quote(VECTOR_SLOT(v, 3)));;
200
201         val = set_value(v);
202 #if LSTRIP_QUOTED_WSP
203         assert_string_equal(val, QUOTED08B);
204 #else
205         assert_string_equal(val, QUOTED08);
206 #endif
207         free(val);
208         free_strvec(v);
209 }
210
211 static void test09(void **state)
212 {
213 #define QUOTED09 "value # more"
214         vector v = alloc_strvec("keyword \"" QUOTED09 "\"");
215         char *val;
216
217         assert_int_equal(validate_config_strvec(v, test_file), 0);
218         assert_int_equal(VECTOR_SIZE(v), 4);
219         assert_string_equal(VECTOR_SLOT(v, 0), "keyword");
220         assert_true(is_quote(VECTOR_SLOT(v, 1)));;
221         assert_string_equal(VECTOR_SLOT(v, 2), QUOTED09);
222         assert_true(is_quote(VECTOR_SLOT(v, 3)));;
223
224         val = set_value(v);
225         assert_string_equal(val, QUOTED09);
226
227         free(val);
228         free_strvec(v);
229 }
230
231 static void test10(void **state)
232 {
233 #define QUOTED10 "value ! more"
234         vector v = alloc_strvec("keyword \"" QUOTED10 "\"");
235         char *val;
236
237         assert_int_equal(validate_config_strvec(v, test_file), 0);
238         assert_int_equal(VECTOR_SIZE(v), 4);
239         assert_string_equal(VECTOR_SLOT(v, 0), "keyword");
240         assert_true(is_quote(VECTOR_SLOT(v, 1)));;
241         assert_string_equal(VECTOR_SLOT(v, 2), QUOTED10);
242         assert_true(is_quote(VECTOR_SLOT(v, 3)));;
243
244         val = set_value(v);
245         assert_string_equal(val, QUOTED10);
246
247         free(val);
248         free_strvec(v);
249 }
250
251 static void test11(void **state)
252 {
253 #define QUOTED11 "value comment"
254         vector v = alloc_strvec("keyword\"" QUOTED11 "\"");
255         char *val;
256
257         assert_int_equal(validate_config_strvec(v, test_file), 0);
258         assert_int_equal(VECTOR_SIZE(v), 4);
259         assert_string_equal(VECTOR_SLOT(v, 0), "keyword");
260         assert_true(is_quote(VECTOR_SLOT(v, 1)));;
261         assert_string_equal(VECTOR_SLOT(v, 2), QUOTED11);
262         assert_true(is_quote(VECTOR_SLOT(v, 3)));;
263
264         val = set_value(v);
265         assert_string_equal(val, QUOTED11);
266
267         free(val);
268         free_strvec(v);
269 }
270
271 static void test12(void **state)
272 {
273         vector v = alloc_strvec("key\"word\"");
274         char *val;
275
276         assert_int_equal(validate_config_strvec(v, test_file), 0);
277         assert_int_equal(VECTOR_SIZE(v), 4);
278         assert_string_equal(VECTOR_SLOT(v, 0), "key");
279         assert_true(is_quote(VECTOR_SLOT(v, 1)));;
280         assert_string_equal(VECTOR_SLOT(v, 2), "word");
281         assert_true(is_quote(VECTOR_SLOT(v, 3)));;
282
283         val = set_value(v);
284         assert_string_equal(val, "word");
285
286         free(val);
287         free_strvec(v);
288 }
289
290 static void test13(void **state)
291 {
292         vector v = alloc_strvec("keyword value \"quoted\"");
293         char *val;
294
295         assert_int_equal(validate_config_strvec(v, test_file), 0);
296         assert_int_equal(VECTOR_SIZE(v), 5);
297         assert_string_equal(VECTOR_SLOT(v, 0), "keyword");
298         assert_string_equal(VECTOR_SLOT(v, 1), "value");
299         assert_true(is_quote(VECTOR_SLOT(v, 2)));;
300         assert_string_equal(VECTOR_SLOT(v, 3), "quoted");
301         assert_true(is_quote(VECTOR_SLOT(v, 4)));;
302
303         val = set_value(v);
304         assert_string_equal(val, "value");
305
306         free(val);
307         free_strvec(v);
308 }
309
310 static void test14(void **state)
311 {
312         vector v = alloc_strvec("keyword \"value \"  comment\"\"");
313         char *val;
314
315         assert_int_equal(validate_config_strvec(v, test_file), 0);
316         assert_int_equal(VECTOR_SIZE(v), 7);
317         assert_string_equal(VECTOR_SLOT(v, 0), "keyword");
318         assert_true(is_quote(VECTOR_SLOT(v, 1)));;
319         assert_string_equal(VECTOR_SLOT(v, 2), "value ");
320         assert_true(is_quote(VECTOR_SLOT(v, 3)));;
321         assert_string_equal(VECTOR_SLOT(v, 4), "comment");
322         assert_true(is_quote(VECTOR_SLOT(v, 5)));;
323         assert_true(is_quote(VECTOR_SLOT(v, 6)));;
324
325         val = set_value(v);
326         assert_string_equal(val, "value ");
327
328         free(val);
329         free_strvec(v);
330 }
331
332 static void test15(void **state)
333 {
334 #define QUOTED15 "word  value\n  comment"
335         vector v = alloc_strvec("key\"" QUOTED15 "\"");
336         char *val;
337
338         assert_int_equal(VECTOR_SIZE(v), 4);
339         assert_string_equal(VECTOR_SLOT(v, 0), "key");
340         assert_true(is_quote(VECTOR_SLOT(v, 1)));;
341         assert_string_equal(VECTOR_SLOT(v, 2), QUOTED15);
342         assert_true(is_quote(VECTOR_SLOT(v, 3)));;
343         assert_int_equal(validate_config_strvec(v, test_file), 0);
344
345         val = set_value(v);
346         assert_string_equal(val, QUOTED15);
347
348         free(val);
349         free_strvec(v);
350 }
351
352 static void test16(void **state)
353 {
354         vector v = alloc_strvec("keyword \"2.5\"\" SSD\"");
355         char *val;
356
357 #if TWO_QUOTES_ONLY
358         assert_int_equal(validate_config_strvec(v, test_file), 0);
359         assert_int_equal(VECTOR_SIZE(v), 6);
360         assert_string_equal(VECTOR_SLOT(v, 0), "keyword");
361         assert_true(is_quote(VECTOR_SLOT(v, 1)));;
362         assert_string_equal(VECTOR_SLOT(v, 2), "2.5");
363         assert_true(is_quote(VECTOR_SLOT(v, 3)));;
364         assert_string_equal(VECTOR_SLOT(v, 4), "SSD");
365         assert_true(is_quote(VECTOR_SLOT(v, 5)));;
366
367         val = set_value(v);
368         assert_string_equal(val, "2.5");
369 #else
370         assert_int_equal(VECTOR_SIZE(v), 4);
371         assert_string_equal(VECTOR_SLOT(v, 0), "keyword");
372         assert_true(is_quote(VECTOR_SLOT(v, 1)));;
373         assert_string_equal(VECTOR_SLOT(v, 2), "2.5\" SSD");
374         assert_true(is_quote(VECTOR_SLOT(v, 3)));;
375
376         val = set_value(v);
377         assert_string_equal(val, "2.5\" SSD");
378 #endif
379         free(val);
380         free_strvec(v);
381 }
382
383 static void test17(void **state)
384 {
385         vector v = alloc_strvec("keyword \"\"\"\"\" is empty\"");
386         char *val;
387 #if TWO_QUOTES_ONLY
388         assert_int_equal(validate_config_strvec(v, test_file), 0);
389         assert_int_equal(VECTOR_SIZE(v), 6);
390         assert_string_equal(VECTOR_SLOT(v, 0), "keyword");
391         assert_true(is_quote(VECTOR_SLOT(v, 1)));;
392         assert_true(is_quote(VECTOR_SLOT(v, 2)));;
393         assert_true(is_quote(VECTOR_SLOT(v, 3)));;
394 #if LSTRIP_QUOTED_WSP
395         assert_string_equal(VECTOR_SLOT(v, 4), "is empty");
396 #else
397         assert_string_equal(VECTOR_SLOT(v, 4), " is empty");
398 #endif
399         assert_true(is_quote(VECTOR_SLOT(v, 5)));;
400
401         val = set_value(v);
402         assert_string_equal(val, "");
403 #else
404         assert_int_equal(validate_config_strvec(v, test_file), 0);
405         assert_int_equal(VECTOR_SIZE(v), 4);
406         assert_string_equal(VECTOR_SLOT(v, 0), "keyword");
407         assert_true(is_quote(VECTOR_SLOT(v, 1)));;
408         assert_string_equal(VECTOR_SLOT(v, 2), "\"\" is empty");
409         assert_true(is_quote(VECTOR_SLOT(v, 3)));;
410
411         val = set_value(v);
412         assert_string_equal(val, "\"\" is empty");
413 #endif
414         free(val);
415         free_strvec(v);
416 }
417
418 static void test18(void **state)
419 {
420         vector v = alloc_strvec("keyword \"\"\"\"");
421         char *val;
422 #if TWO_QUOTES_ONLY
423         assert_int_equal(validate_config_strvec(v, test_file), 0);
424         assert_int_equal(VECTOR_SIZE(v), 5);
425         assert_string_equal(VECTOR_SLOT(v, 0), "keyword");
426         assert_true(is_quote(VECTOR_SLOT(v, 1)));;
427         assert_true(is_quote(VECTOR_SLOT(v, 2)));;
428         assert_true(is_quote(VECTOR_SLOT(v, 3)));;
429         assert_true(is_quote(VECTOR_SLOT(v, 4)));;
430
431         val = set_value(v);
432         assert_string_equal(val, "");
433 #else
434         assert_int_equal(validate_config_strvec(v, test_file), 0);
435         assert_int_equal(VECTOR_SIZE(v), 4);
436         assert_string_equal(VECTOR_SLOT(v, 0), "keyword");
437         assert_true(is_quote(VECTOR_SLOT(v, 1)));;
438         assert_string_equal(VECTOR_SLOT(v, 2), "\"");
439         assert_true(is_quote(VECTOR_SLOT(v, 3)));;
440
441         val = set_value(v);
442         assert_string_equal(val, "\"");
443 #endif
444         free(val);
445         free_strvec(v);
446 }
447
448 int test_config_parser(void)
449 {
450         const struct CMUnitTest tests[] = {
451                 cmocka_unit_test(test01),
452                 cmocka_unit_test(test02),
453                 cmocka_unit_test(test03),
454                 cmocka_unit_test(test04),
455                 cmocka_unit_test(test05),
456                 cmocka_unit_test(test06),
457                 cmocka_unit_test(test07),
458                 cmocka_unit_test(test08),
459                 cmocka_unit_test(test09),
460                 cmocka_unit_test(test10),
461                 cmocka_unit_test(test11),
462                 cmocka_unit_test(test12),
463                 cmocka_unit_test(test13),
464                 cmocka_unit_test(test14),
465                 cmocka_unit_test(test15),
466                 cmocka_unit_test(test16),
467                 cmocka_unit_test(test17),
468                 cmocka_unit_test(test18),
469         };
470         return cmocka_run_group_tests(tests, setup, teardown);
471 }
472
473 int main(void)
474 {
475         int ret = 0;
476
477         ret += test_config_parser();
478         return ret;
479 }