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 : 10 : make_tmp_file(char *filename, const char *prefix, const char *data)
22 : : {
23 : 10 : 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 : 10 : int fd = mkstemp(filename);
41 [ + - ]: 10 : if (fd < 0)
42 : : return -1;
43 : :
44 : 10 : f = fdopen(fd, "w");
45 : : #endif
46 [ + - ]: 10 : if (f == NULL)
47 : : return -1;
48 : :
49 : 10 : count = fwrite(data, sizeof(char), len, f);
50 : 10 : fclose(f);
51 : :
52 [ - + ]: 10 : 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 : char tmp[PATH_MAX] = "/tmp/";
182 : : #ifdef RTE_EXEC_ENV_WINDOWS
183 : : ret = GetTempPathA(sizeof(tmp), tmp);
184 : : TEST_ASSERT(ret > 0, "Failed to get tmp directory");
185 : : #endif
186 : : snprintf(filename, sizeof(filename), "%s%s", tmp, "cfg_save.ini");
187 : :
188 : 1 : ret = rte_cfgfile_save(cfgfile, filename);
189 [ - + ]: 1 : TEST_ASSERT_SUCCESS(ret, "Failed to save to %s", filename);
190 : :
191 : 1 : ret = remove(filename);
192 [ - + ]: 1 : TEST_ASSERT_SUCCESS(ret, "Failed to remove file");
193 : :
194 : 1 : ret = rte_cfgfile_close(cfgfile);
195 [ - + ]: 1 : TEST_ASSERT_SUCCESS(ret, "Failed to close cfgfile");
196 : :
197 : : return 0;
198 : : }
199 : :
200 : : static int
201 : 1 : test_cfgfile_invalid_section_header(void)
202 : : {
203 : : struct rte_cfgfile *cfgfile;
204 : : char filename[PATH_MAX];
205 : : int ret;
206 : :
207 : 1 : ret = make_tmp_file(filename, "invalid", invalid_section_ini);
208 [ - + ]: 1 : TEST_ASSERT_SUCCESS(ret, "Failed to setup temp file");
209 : :
210 : 1 : cfgfile = rte_cfgfile_load(filename, 0);
211 [ - + ]: 1 : TEST_ASSERT_NULL(cfgfile, "Expected failure did not occur");
212 : :
213 : 1 : ret = remove(filename);
214 [ - + ]: 1 : TEST_ASSERT_SUCCESS(ret, "Failed to remove file");
215 : :
216 : : return 0;
217 : : }
218 : :
219 : : static int
220 : 1 : test_cfgfile_invalid_comment(void)
221 : : {
222 : : struct rte_cfgfile_parameters params;
223 : : struct rte_cfgfile *cfgfile;
224 : : char filename[PATH_MAX];
225 : : int ret;
226 : :
227 : : /* override comment character with an invalid one */
228 : : memset(¶ms, 0, sizeof(params));
229 : 1 : params.comment_character = '$';
230 : :
231 : 1 : ret = make_tmp_file(filename, "sample2", sample2_ini);
232 [ - + ]: 1 : TEST_ASSERT_SUCCESS(ret, "Failed to setup temp file");
233 : :
234 : 1 : cfgfile = rte_cfgfile_load_with_params(filename, 0, ¶ms);
235 [ - + ]: 1 : TEST_ASSERT_NULL(cfgfile, "Expected failure did not occur");
236 : :
237 : 1 : ret = remove(filename);
238 [ - + ]: 1 : TEST_ASSERT_SUCCESS(ret, "Failed to remove file");
239 : :
240 : : return 0;
241 : : }
242 : :
243 : : static int
244 : 1 : test_cfgfile_invalid_key_value_pair(void)
245 : : {
246 : : struct rte_cfgfile *cfgfile;
247 : : char filename[PATH_MAX];
248 : : int ret;
249 : :
250 : 1 : ret = make_tmp_file(filename, "empty_key", empty_key_value_ini);
251 [ - + ]: 1 : TEST_ASSERT_SUCCESS(ret, "Failed to setup temp file");
252 : :
253 : 1 : cfgfile = rte_cfgfile_load(filename, 0);
254 [ - + ]: 1 : TEST_ASSERT_NULL(cfgfile, "Expected failure did not occur");
255 : :
256 : 1 : ret = remove(filename);
257 [ - + ]: 1 : TEST_ASSERT_SUCCESS(ret, "Failed to remove file");
258 : :
259 : : return 0;
260 : : }
261 : :
262 : : static int
263 : 1 : test_cfgfile_empty_key_value_pair(void)
264 : : {
265 : : struct rte_cfgfile *cfgfile;
266 : : const char *value;
267 : : char filename[PATH_MAX];
268 : : int ret;
269 : :
270 : 1 : ret = make_tmp_file(filename, "empty_key_value", empty_key_value_ini);
271 [ - + ]: 1 : TEST_ASSERT_SUCCESS(ret, "Failed to setup temp file");
272 : :
273 : 1 : cfgfile = rte_cfgfile_load(filename, CFG_FLAG_EMPTY_VALUES);
274 [ - + ]: 1 : TEST_ASSERT_NOT_NULL(cfgfile, "Failed to parse empty_key_value");
275 : :
276 : 1 : ret = rte_cfgfile_num_sections(cfgfile, NULL, 0);
277 [ - + ]: 1 : TEST_ASSERT(ret == 1, "Unexpected number of sections: %d", ret);
278 : :
279 : 1 : ret = rte_cfgfile_has_section(cfgfile, "section1");
280 [ - + ]: 1 : TEST_ASSERT(ret, "section1 missing");
281 : :
282 : 1 : ret = rte_cfgfile_section_num_entries(cfgfile, "section1");
283 [ - + ]: 1 : TEST_ASSERT(ret == 1, "section1 unexpected number of entries: %d", ret);
284 : :
285 : 1 : value = rte_cfgfile_get_entry(cfgfile, "section1", "key");
286 [ - + ]: 1 : TEST_ASSERT(strlen(value) == 0, "key unexpected value: %s", value);
287 : :
288 : 1 : ret = rte_cfgfile_close(cfgfile);
289 [ - + ]: 1 : TEST_ASSERT_SUCCESS(ret, "Failed to close cfgfile");
290 : :
291 : 1 : ret = remove(filename);
292 [ - + ]: 1 : TEST_ASSERT_SUCCESS(ret, "Failed to remove file");
293 : :
294 : : return 0;
295 : : }
296 : :
297 : : static int
298 : 1 : test_cfgfile_missing_section(void)
299 : : {
300 : : struct rte_cfgfile *cfgfile;
301 : : char filename[PATH_MAX];
302 : : int ret;
303 : :
304 : 1 : ret = make_tmp_file(filename, "missing_section", missing_section_ini);
305 [ - + ]: 1 : TEST_ASSERT_SUCCESS(ret, "Failed to setup temp file");
306 : :
307 : 1 : cfgfile = rte_cfgfile_load(filename, 0);
308 [ - + ]: 1 : TEST_ASSERT_NULL(cfgfile, "Expected failure did not occur");
309 : :
310 : 1 : ret = remove(filename);
311 [ - + ]: 1 : TEST_ASSERT_SUCCESS(ret, "Failed to remove file");
312 : :
313 : : return 0;
314 : : }
315 : :
316 : : static int
317 : 1 : test_cfgfile_global_properties(void)
318 : : {
319 : : struct rte_cfgfile *cfgfile;
320 : : const char *value;
321 : : char filename[PATH_MAX];
322 : : int ret;
323 : :
324 : 1 : ret = make_tmp_file(filename, "missing_section", missing_section_ini);
325 [ - + ]: 1 : TEST_ASSERT_SUCCESS(ret, "Failed to setup temp file");
326 : :
327 : 1 : cfgfile = rte_cfgfile_load(filename, CFG_FLAG_GLOBAL_SECTION);
328 [ - + ]: 1 : TEST_ASSERT_NOT_NULL(cfgfile, "Failed to load config file");
329 : :
330 : 1 : ret = rte_cfgfile_num_sections(cfgfile, NULL, 0);
331 [ - + ]: 1 : TEST_ASSERT(ret == 1, "Unexpected number of sections: %d", ret);
332 : :
333 : 1 : ret = rte_cfgfile_has_section(cfgfile, "GLOBAL");
334 [ - + ]: 1 : TEST_ASSERT(ret, "global section missing");
335 : :
336 : 1 : ret = rte_cfgfile_section_num_entries(cfgfile, "GLOBAL");
337 [ - + ]: 1 : TEST_ASSERT(ret == 1, "GLOBAL unexpected number of entries: %d", ret);
338 : :
339 : 1 : value = rte_cfgfile_get_entry(cfgfile, "GLOBAL", "key");
340 [ - + ]: 1 : TEST_ASSERT(strcmp("value", value) == 0,
341 : : "key unexpected value: %s", value);
342 : :
343 : 1 : ret = rte_cfgfile_close(cfgfile);
344 [ - + ]: 1 : TEST_ASSERT_SUCCESS(ret, "Failed to close cfgfile");
345 : :
346 : 1 : ret = remove(filename);
347 [ - + ]: 1 : TEST_ASSERT_SUCCESS(ret, "Failed to remove file");
348 : :
349 : : return 0;
350 : : }
351 : :
352 : : static int
353 : 1 : test_cfgfile_empty_file(void)
354 : : {
355 : : struct rte_cfgfile *cfgfile;
356 : : char filename[PATH_MAX];
357 : : int ret;
358 : :
359 : 1 : ret = make_tmp_file(filename, "empty", empty_ini);
360 [ - + ]: 1 : TEST_ASSERT_SUCCESS(ret, "Failed to setup temp file");
361 : :
362 : 1 : cfgfile = rte_cfgfile_load(filename, 0);
363 [ - + ]: 1 : TEST_ASSERT_NOT_NULL(cfgfile, "Failed to load config file");
364 : :
365 : 1 : ret = rte_cfgfile_num_sections(cfgfile, NULL, 0);
366 [ - + ]: 1 : TEST_ASSERT(ret == 0, "Unexpected number of sections: %d", ret);
367 : :
368 : 1 : ret = rte_cfgfile_close(cfgfile);
369 [ - + ]: 1 : TEST_ASSERT_SUCCESS(ret, "Failed to close cfgfile");
370 : :
371 : 1 : ret = remove(filename);
372 [ - + ]: 1 : TEST_ASSERT_SUCCESS(ret, "Failed to remove file");
373 : :
374 : : return 0;
375 : : }
376 : :
377 : : static struct
378 : : unit_test_suite test_cfgfile_suite = {
379 : : .suite_name = "Test Cfgfile Unit Test Suite",
380 : : .unit_test_cases = {
381 : : TEST_CASE(test_cfgfile_sample1),
382 : : TEST_CASE(test_cfgfile_sample2),
383 : : TEST_CASE(test_cfgfile_realloc_sections),
384 : : TEST_CASE(test_cfgfile_invalid_section_header),
385 : : TEST_CASE(test_cfgfile_invalid_comment),
386 : : TEST_CASE(test_cfgfile_invalid_key_value_pair),
387 : : TEST_CASE(test_cfgfile_empty_key_value_pair),
388 : : TEST_CASE(test_cfgfile_missing_section),
389 : : TEST_CASE(test_cfgfile_global_properties),
390 : : TEST_CASE(test_cfgfile_empty_file),
391 : :
392 : : TEST_CASES_END()
393 : : }
394 : : };
395 : :
396 : : static int
397 : 1 : test_cfgfile(void)
398 : : {
399 : 1 : return unit_test_suite_runner(&test_cfgfile_suite);
400 : : }
401 : :
402 : 252 : REGISTER_FAST_TEST(cfgfile_autotest, true, true, test_cfgfile);
|