Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2017 Wind River Systems, Inc.
3 : : */
4 : :
5 : : #include <stdio.h>
6 : : #include <string.h>
7 : : #include <stdint.h>
8 : : #include <unistd.h>
9 : :
10 : : #ifdef RTE_EXEC_ENV_WINDOWS
11 : : #include <io.h>
12 : : #endif
13 : :
14 : : #include <rte_cfgfile.h>
15 : :
16 : : #include "test.h"
17 : :
18 : : #include "test_cfgfiles.h"
19 : :
20 : : static int
21 : 11 : make_tmp_file(char *filename, const char *prefix, const char *data)
22 : : {
23 : 11 : size_t len = strlen(data);
24 : : size_t count;
25 : : FILE *f;
26 : :
27 : : #ifdef RTE_EXEC_ENV_WINDOWS
28 : : char tempDirName[MAX_PATH - 14];
29 : :
30 : : if (GetTempPathA(sizeof(tempDirName), tempDirName) == 0)
31 : : return -1;
32 : :
33 : : if (GetTempFileNameA(tempDirName, prefix, 0, filename) == 0)
34 : : return -1;
35 : :
36 : : f = fopen(filename, "wt");
37 : : #else
38 : : snprintf(filename, PATH_MAX, "/tmp/%s_XXXXXXX", prefix);
39 : :
40 : 11 : int fd = mkstemp(filename);
41 [ + - ]: 11 : if (fd < 0)
42 : : return -1;
43 : :
44 : 11 : f = fdopen(fd, "w");
45 : : #endif
46 [ + - ]: 11 : if (f == NULL)
47 : : return -1;
48 : :
49 : 11 : count = fwrite(data, sizeof(char), len, f);
50 : 11 : fclose(f);
51 : :
52 [ - + ]: 11 : return (count == len) ? 0 : -1;
53 : : }
54 : :
55 : :
56 : : static int
57 : 2 : _test_cfgfile_sample(struct rte_cfgfile *cfgfile)
58 : : {
59 : : const char *value;
60 : : int ret;
61 : :
62 : 2 : ret = rte_cfgfile_num_sections(cfgfile, NULL, 0);
63 [ - + ]: 2 : TEST_ASSERT(ret == 2, "Unexpected number of sections: %d", ret);
64 : :
65 : 2 : ret = rte_cfgfile_has_section(cfgfile, "section1");
66 [ - + ]: 2 : TEST_ASSERT(ret, "section1 section missing");
67 : :
68 : 2 : ret = rte_cfgfile_section_num_entries(cfgfile, "section1");
69 [ - + ]: 2 : TEST_ASSERT(ret == 1, "section1 unexpected number of entries: %d", ret);
70 : :
71 : 2 : value = rte_cfgfile_get_entry(cfgfile, "section1", "key1");
72 [ - + ]: 2 : TEST_ASSERT(strcmp("value1", value) == 0,
73 : : "key1 unexpected value: %s", value);
74 : :
75 : 2 : ret = rte_cfgfile_has_section(cfgfile, "section2");
76 [ - + ]: 2 : TEST_ASSERT(ret, "section2 section missing");
77 : :
78 : 2 : ret = rte_cfgfile_section_num_entries(cfgfile, "section2");
79 [ - + ]: 2 : TEST_ASSERT(ret == 2, "section2 unexpected number of entries: %d", ret);
80 : :
81 : 2 : value = rte_cfgfile_get_entry(cfgfile, "section2", "key2");
82 [ - + ]: 2 : TEST_ASSERT(strcmp("value2", value) == 0,
83 : : "key2 unexpected value: %s", value);
84 : :
85 : 2 : value = rte_cfgfile_get_entry(cfgfile, "section2", "key3");
86 [ - + ]: 2 : TEST_ASSERT(strcmp("value3", value) == 0,
87 : : "key3 unexpected value: %s", value);
88 : :
89 : : return 0;
90 : : }
91 : :
92 : : static int
93 : 1 : test_cfgfile_sample1(void)
94 : : {
95 : : struct rte_cfgfile *cfgfile;
96 : : char filename[PATH_MAX];
97 : : int ret;
98 : :
99 : 1 : ret = make_tmp_file(filename, "sample1", sample1_ini);
100 [ - + ]: 1 : TEST_ASSERT_SUCCESS(ret, "Failed to setup temp file");
101 : :
102 : 1 : cfgfile = rte_cfgfile_load(filename, 0);
103 [ - + ]: 1 : TEST_ASSERT_NOT_NULL(cfgfile, "Failed to load config file");
104 : :
105 : 1 : ret = _test_cfgfile_sample(cfgfile);
106 [ - + ]: 1 : TEST_ASSERT_SUCCESS(ret, "Failed to validate sample file: %d", ret);
107 : :
108 : 1 : ret = rte_cfgfile_close(cfgfile);
109 [ - + ]: 1 : TEST_ASSERT_SUCCESS(ret, "Failed to close cfgfile");
110 : :
111 : 1 : ret = remove(filename);
112 [ - + ]: 1 : TEST_ASSERT_SUCCESS(ret, "Failed to remove file");
113 : :
114 : : return 0;
115 : : }
116 : :
117 : : static int
118 : 1 : test_cfgfile_sample2(void)
119 : : {
120 : : struct rte_cfgfile_parameters params;
121 : : struct rte_cfgfile *cfgfile;
122 : : char filename[PATH_MAX];
123 : : int ret;
124 : :
125 : 1 : ret = make_tmp_file(filename, "sample2", sample2_ini);
126 [ - + ]: 1 : TEST_ASSERT_SUCCESS(ret, "Failed to setup temp file");
127 : :
128 : : /* override comment character */
129 : : memset(¶ms, 0, sizeof(params));
130 : 1 : params.comment_character = '#';
131 : :
132 : 1 : cfgfile = rte_cfgfile_load_with_params(filename, 0, ¶ms);
133 [ - + ]: 1 : TEST_ASSERT_NOT_NULL(cfgfile, "Failed to parse sample2");
134 : :
135 : 1 : ret = _test_cfgfile_sample(cfgfile);
136 [ - + ]: 1 : TEST_ASSERT_SUCCESS(ret, "Failed to validate sample file: %d", ret);
137 : :
138 : 1 : ret = rte_cfgfile_close(cfgfile);
139 [ - + ]: 1 : TEST_ASSERT_SUCCESS(ret, "Failed to close cfgfile");
140 : :
141 : 1 : ret = remove(filename);
142 [ - + ]: 1 : TEST_ASSERT_SUCCESS(ret, "Failed to remove file");
143 : :
144 : : return 0;
145 : : }
146 : :
147 : : static int
148 : 1 : test_cfgfile_realloc_sections(void)
149 : : {
150 : : struct rte_cfgfile *cfgfile;
151 : : char filename[PATH_MAX];
152 : : int ret;
153 : : const char *value;
154 : :
155 : 1 : ret = make_tmp_file(filename, "realloc", realloc_sections_ini);
156 [ - + ]: 1 : TEST_ASSERT_SUCCESS(ret, "Failed to setup temp file");
157 : :
158 : 1 : cfgfile = rte_cfgfile_load(filename, 0);
159 [ - + ]: 1 : TEST_ASSERT_NOT_NULL(cfgfile, "Failed to load config file");
160 : :
161 : 1 : ret = rte_cfgfile_num_sections(cfgfile, NULL, 0);
162 [ - + ]: 1 : TEST_ASSERT(ret == 9, "Unexpected number of sections: %d", ret);
163 : :
164 : 1 : ret = rte_cfgfile_has_section(cfgfile, "section9");
165 [ - + ]: 1 : TEST_ASSERT(ret, "section9 missing");
166 : :
167 : 1 : ret = rte_cfgfile_section_num_entries(cfgfile, "section3");
168 [ - + ]: 1 : TEST_ASSERT(ret == 21,
169 : : "section3 unexpected number of entries: %d", ret);
170 : :
171 : 1 : ret = rte_cfgfile_section_num_entries(cfgfile, "section9");
172 [ - + ]: 1 : TEST_ASSERT(ret == 8, "section9 unexpected number of entries: %d", ret);
173 : :
174 : 1 : value = rte_cfgfile_get_entry(cfgfile, "section9", "key8");
175 [ - + ]: 1 : TEST_ASSERT(strcmp("value8_section9", value) == 0,
176 : : "key unexpected value: %s", value);
177 : :
178 : 1 : ret = remove(filename);
179 [ - + ]: 1 : TEST_ASSERT_SUCCESS(ret, "Failed to remove file");
180 : :
181 : 1 : ret = make_tmp_file(filename, "save", "");
182 [ - + ]: 1 : TEST_ASSERT(ret == 0, "Failed to make empty tmp filename for save");
183 : :
184 : 1 : ret = rte_cfgfile_save(cfgfile, filename);
185 [ - + ]: 1 : TEST_ASSERT_SUCCESS(ret, "Failed to save to %s", filename);
186 : :
187 : 1 : ret = remove(filename);
188 [ - + ]: 1 : TEST_ASSERT_SUCCESS(ret, "Failed to remove file");
189 : :
190 : 1 : ret = rte_cfgfile_close(cfgfile);
191 [ - + ]: 1 : TEST_ASSERT_SUCCESS(ret, "Failed to close cfgfile");
192 : :
193 : : return 0;
194 : : }
195 : :
196 : : static int
197 : 1 : test_cfgfile_invalid_section_header(void)
198 : : {
199 : : struct rte_cfgfile *cfgfile;
200 : : char filename[PATH_MAX];
201 : : int ret;
202 : :
203 : 1 : ret = make_tmp_file(filename, "invalid", invalid_section_ini);
204 [ - + ]: 1 : TEST_ASSERT_SUCCESS(ret, "Failed to setup temp file");
205 : :
206 : 1 : cfgfile = rte_cfgfile_load(filename, 0);
207 [ - + ]: 1 : TEST_ASSERT_NULL(cfgfile, "Expected failure did not occur");
208 : :
209 : 1 : ret = remove(filename);
210 [ - + ]: 1 : TEST_ASSERT_SUCCESS(ret, "Failed to remove file");
211 : :
212 : : return 0;
213 : : }
214 : :
215 : : static int
216 : 1 : test_cfgfile_invalid_comment(void)
217 : : {
218 : : struct rte_cfgfile_parameters params;
219 : : struct rte_cfgfile *cfgfile;
220 : : char filename[PATH_MAX];
221 : : int ret;
222 : :
223 : : /* override comment character with an invalid one */
224 : : memset(¶ms, 0, sizeof(params));
225 : 1 : params.comment_character = '$';
226 : :
227 : 1 : ret = make_tmp_file(filename, "sample2", sample2_ini);
228 [ - + ]: 1 : TEST_ASSERT_SUCCESS(ret, "Failed to setup temp file");
229 : :
230 : 1 : cfgfile = rte_cfgfile_load_with_params(filename, 0, ¶ms);
231 [ - + ]: 1 : TEST_ASSERT_NULL(cfgfile, "Expected failure did not occur");
232 : :
233 : 1 : ret = remove(filename);
234 [ - + ]: 1 : TEST_ASSERT_SUCCESS(ret, "Failed to remove file");
235 : :
236 : : return 0;
237 : : }
238 : :
239 : : static int
240 : 1 : test_cfgfile_invalid_key_value_pair(void)
241 : : {
242 : : struct rte_cfgfile *cfgfile;
243 : : char filename[PATH_MAX];
244 : : int ret;
245 : :
246 : 1 : ret = make_tmp_file(filename, "empty_key", empty_key_value_ini);
247 [ - + ]: 1 : TEST_ASSERT_SUCCESS(ret, "Failed to setup temp file");
248 : :
249 : 1 : cfgfile = rte_cfgfile_load(filename, 0);
250 [ - + ]: 1 : TEST_ASSERT_NULL(cfgfile, "Expected failure did not occur");
251 : :
252 : 1 : ret = remove(filename);
253 [ - + ]: 1 : TEST_ASSERT_SUCCESS(ret, "Failed to remove file");
254 : :
255 : : return 0;
256 : : }
257 : :
258 : : static int
259 : 1 : test_cfgfile_empty_key_value_pair(void)
260 : : {
261 : : struct rte_cfgfile *cfgfile;
262 : : const char *value;
263 : : char filename[PATH_MAX];
264 : : int ret;
265 : :
266 : 1 : ret = make_tmp_file(filename, "empty_key_value", empty_key_value_ini);
267 [ - + ]: 1 : TEST_ASSERT_SUCCESS(ret, "Failed to setup temp file");
268 : :
269 : 1 : cfgfile = rte_cfgfile_load(filename, CFG_FLAG_EMPTY_VALUES);
270 [ - + ]: 1 : TEST_ASSERT_NOT_NULL(cfgfile, "Failed to parse empty_key_value");
271 : :
272 : 1 : ret = rte_cfgfile_num_sections(cfgfile, NULL, 0);
273 [ - + ]: 1 : TEST_ASSERT(ret == 1, "Unexpected number of sections: %d", ret);
274 : :
275 : 1 : ret = rte_cfgfile_has_section(cfgfile, "section1");
276 [ - + ]: 1 : TEST_ASSERT(ret, "section1 missing");
277 : :
278 : 1 : ret = rte_cfgfile_section_num_entries(cfgfile, "section1");
279 [ - + ]: 1 : TEST_ASSERT(ret == 1, "section1 unexpected number of entries: %d", ret);
280 : :
281 : 1 : value = rte_cfgfile_get_entry(cfgfile, "section1", "key");
282 [ - + ]: 1 : TEST_ASSERT(strlen(value) == 0, "key unexpected value: %s", value);
283 : :
284 : 1 : ret = rte_cfgfile_close(cfgfile);
285 [ - + ]: 1 : TEST_ASSERT_SUCCESS(ret, "Failed to close cfgfile");
286 : :
287 : 1 : ret = remove(filename);
288 [ - + ]: 1 : TEST_ASSERT_SUCCESS(ret, "Failed to remove file");
289 : :
290 : : return 0;
291 : : }
292 : :
293 : : static int
294 : 1 : test_cfgfile_missing_section(void)
295 : : {
296 : : struct rte_cfgfile *cfgfile;
297 : : char filename[PATH_MAX];
298 : : int ret;
299 : :
300 : 1 : ret = make_tmp_file(filename, "missing_section", missing_section_ini);
301 [ - + ]: 1 : TEST_ASSERT_SUCCESS(ret, "Failed to setup temp file");
302 : :
303 : 1 : cfgfile = rte_cfgfile_load(filename, 0);
304 [ - + ]: 1 : TEST_ASSERT_NULL(cfgfile, "Expected failure did not occur");
305 : :
306 : 1 : ret = remove(filename);
307 [ - + ]: 1 : TEST_ASSERT_SUCCESS(ret, "Failed to remove file");
308 : :
309 : : return 0;
310 : : }
311 : :
312 : : static int
313 : 1 : test_cfgfile_global_properties(void)
314 : : {
315 : : struct rte_cfgfile *cfgfile;
316 : : const char *value;
317 : : char filename[PATH_MAX];
318 : : int ret;
319 : :
320 : 1 : ret = make_tmp_file(filename, "missing_section", missing_section_ini);
321 [ - + ]: 1 : TEST_ASSERT_SUCCESS(ret, "Failed to setup temp file");
322 : :
323 : 1 : cfgfile = rte_cfgfile_load(filename, CFG_FLAG_GLOBAL_SECTION);
324 [ - + ]: 1 : TEST_ASSERT_NOT_NULL(cfgfile, "Failed to load config file");
325 : :
326 : 1 : ret = rte_cfgfile_num_sections(cfgfile, NULL, 0);
327 [ - + ]: 1 : TEST_ASSERT(ret == 1, "Unexpected number of sections: %d", ret);
328 : :
329 : 1 : ret = rte_cfgfile_has_section(cfgfile, "GLOBAL");
330 [ - + ]: 1 : TEST_ASSERT(ret, "global section missing");
331 : :
332 : 1 : ret = rte_cfgfile_section_num_entries(cfgfile, "GLOBAL");
333 [ - + ]: 1 : TEST_ASSERT(ret == 1, "GLOBAL unexpected number of entries: %d", ret);
334 : :
335 : 1 : value = rte_cfgfile_get_entry(cfgfile, "GLOBAL", "key");
336 [ - + ]: 1 : TEST_ASSERT(strcmp("value", value) == 0,
337 : : "key unexpected value: %s", value);
338 : :
339 : 1 : ret = rte_cfgfile_close(cfgfile);
340 [ - + ]: 1 : TEST_ASSERT_SUCCESS(ret, "Failed to close cfgfile");
341 : :
342 : 1 : ret = remove(filename);
343 [ - + ]: 1 : TEST_ASSERT_SUCCESS(ret, "Failed to remove file");
344 : :
345 : : return 0;
346 : : }
347 : :
348 : : static int
349 : 1 : test_cfgfile_empty_file(void)
350 : : {
351 : : struct rte_cfgfile *cfgfile;
352 : : char filename[PATH_MAX];
353 : : int ret;
354 : :
355 : 1 : ret = make_tmp_file(filename, "empty", empty_ini);
356 [ - + ]: 1 : TEST_ASSERT_SUCCESS(ret, "Failed to setup temp file");
357 : :
358 : 1 : cfgfile = rte_cfgfile_load(filename, 0);
359 [ - + ]: 1 : TEST_ASSERT_NOT_NULL(cfgfile, "Failed to load config file");
360 : :
361 : 1 : ret = rte_cfgfile_num_sections(cfgfile, NULL, 0);
362 [ - + ]: 1 : TEST_ASSERT(ret == 0, "Unexpected number of sections: %d", ret);
363 : :
364 : 1 : ret = rte_cfgfile_close(cfgfile);
365 [ - + ]: 1 : TEST_ASSERT_SUCCESS(ret, "Failed to close cfgfile");
366 : :
367 : 1 : ret = remove(filename);
368 [ - + ]: 1 : TEST_ASSERT_SUCCESS(ret, "Failed to remove file");
369 : :
370 : : return 0;
371 : : }
372 : :
373 : : static struct
374 : : unit_test_suite test_cfgfile_suite = {
375 : : .suite_name = "Test Cfgfile Unit Test Suite",
376 : : .unit_test_cases = {
377 : : TEST_CASE(test_cfgfile_sample1),
378 : : TEST_CASE(test_cfgfile_sample2),
379 : : TEST_CASE(test_cfgfile_realloc_sections),
380 : : TEST_CASE(test_cfgfile_invalid_section_header),
381 : : TEST_CASE(test_cfgfile_invalid_comment),
382 : : TEST_CASE(test_cfgfile_invalid_key_value_pair),
383 : : TEST_CASE(test_cfgfile_empty_key_value_pair),
384 : : TEST_CASE(test_cfgfile_missing_section),
385 : : TEST_CASE(test_cfgfile_global_properties),
386 : : TEST_CASE(test_cfgfile_empty_file),
387 : :
388 : : TEST_CASES_END()
389 : : }
390 : : };
391 : :
392 : : static int
393 : 1 : test_cfgfile(void)
394 : : {
395 : 1 : return unit_test_suite_runner(&test_cfgfile_suite);
396 : : }
397 : :
398 : 276 : REGISTER_FAST_TEST(cfgfile_autotest, NOHUGE_OK, ASAN_OK, test_cfgfile);
|