0172d52654a3aae3a58d78c2e5c65bd2a5aa3fca
[strongswan.git] / src / libstrongswan / tests / suites / test_settings.c
1 /*
2 * Copyright (C) 2014 Tobias Brunner
3 * Hochschule fuer Technik Rapperswil
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16 #include "test_suite.h"
17
18 #include <unistd.h>
19
20 #include <utils/settings.h>
21 #include <utils/chunk.h>
22 #include <utils/utils.h>
23 #include <collections/linked_list.h>
24
25 static char *path = "/tmp/strongswan-settings-test";
26 static settings_t *settings;
27
28 static void create_settings(chunk_t contents)
29 {
30 ck_assert(chunk_write(contents, path, 0022, TRUE));
31 settings = settings_create(path);
32 }
33
34 START_SETUP(setup_base_config)
35 {
36 create_settings(chunk_from_str(
37 "main {\n"
38 " key1 = val1\n"
39 " # this gets overridden below\n"
40 " key2 = val2\n"
41 " none = \n"
42 " sub1 {\n"
43 " key = value\n"
44 " key2 = value2\n"
45 " subsub {\n"
46 " foo = bar\n"
47 " }\n"
48 " # subsub is a section and a value\n"
49 " subsub = section value\n"
50 " }\n"
51 " sub% {\n"
52 " id = %any\n"
53 " }\n"
54 " key2 = with spaces\n"
55 "}\n"
56 "out = side\n"
57 "other {\n"
58 " key1 = other val\n"
59 " empty {\n"
60 " }\n"
61 "}"));
62 }
63 END_SETUP
64
65 START_TEARDOWN(teardown_config)
66 {
67 settings->destroy(settings);
68 unlink(path);
69 }
70 END_TEARDOWN
71
72 #define verify_string(expected, key, ...) \
73 ck_assert_str_eq(expected, settings->get_str(settings, key, NULL, ##__VA_ARGS__))
74 #define verify_null(key, ...) \
75 ck_assert(!settings->get_str(settings, key, NULL, ##__VA_ARGS__))
76
77 START_TEST(test_get_str)
78 {
79 verify_string("val1", "main.key1");
80 verify_string("val1", "main..key1");
81 verify_string("val1", ".main.key1");
82 verify_string("with spaces", "main.key2");
83 verify_string("value", "main.sub1.key");
84 verify_string("value2", "main.sub1.key2");
85 verify_string("bar", "main.sub1.subsub.foo");
86 verify_string("section value", "main.sub1.subsub");
87 verify_string("%any", "main.sub%%.id");
88 verify_string("side", "out");
89 verify_string("other val", "other.key1");
90
91 /* FIXME: should this rather be undefined i.e. return the default value? */
92 verify_string("", "main.none");
93
94 verify_null("main.key3");
95 verify_null("other.sub");
96 }
97 END_TEST
98
99 enum {
100 KEY1,
101 SUB1
102 } settings_test_enum;
103
104 enum_name_t *test_settings_test_names;
105
106 ENUM_BEGIN(test_settings_test_names, KEY1, SUB1,
107 "key1", "sub1");
108 ENUM_END(test_settings_test_names, SUB1);
109
110 START_TEST(test_get_str_printf)
111 {
112 verify_string("val1", "%s.key1", "main");
113 verify_string("val1", "%s.%s", "main", "key1");
114 verify_string("val1", "%s.%N", "main", test_settings_test_names, KEY1);
115 verify_string("val1", "%s.%s%d", "main", "key", 1);
116 verify_string("bar", "%s.sub1.%s.foo", "main", "subsub");
117 verify_string("bar", "%s.%N.%s.foo", "main", test_settings_test_names, SUB1, "subsub");
118 verify_string("bar", "%s.sub%d.%s.foo", "main", 1, "subsub");
119 verify_string("%any", "%s.sub%%.id", "main");
120
121 /* FIXME: this is a bit inconsistent, while this works */
122 verify_string("value2", "main.%s%u.key2", "sub", 1);
123 /* this won't because no argument is consumed for %u so key1 will be tried
124 * granted, we never actually used any other specifiers, but we should
125 * probably document it at least */
126 verify_null("main.%s%u.key%d", "sub", 1, 2);
127
128 verify_null("%s.%s%d", "main", "key", 3);
129 }
130 END_TEST
131
132 START_TEST(test_set_str)
133 {
134 settings->set_str(settings, "main.key1", "val");
135 verify_string("val", "main.key1");
136 settings->set_str(settings, "main.key1", "longer value");
137 verify_string("longer value", "main.key1");
138 settings->set_str(settings, "main", "main val");
139 verify_string("main val", "main");
140 settings->set_str(settings, "main.sub1.new", "added");
141 verify_string("added", "main.sub1.new");
142 settings->set_str(settings, "main.sub2.newsub.foo", "bar");
143 verify_string("bar", "main.sub2.newsub.foo");
144 settings->set_str(settings, "new.newsub.foo", "bar");
145 verify_string("bar", "new.newsub.foo");
146 settings->set_str(settings, "main.key1", NULL);
147 verify_null("main.key1");
148 }
149 END_TEST
150
151 START_TEST(test_set_str_printf)
152 {
153 settings->set_str(settings, "%s.key1", "val", "main");
154 verify_string("val", "main.key1");
155 settings->set_str(settings, "main.%N.new", "added", test_settings_test_names, SUB1);
156 verify_string("added", "main.sub1.new");
157 settings->set_str(settings, "main.%s%d.newsub.%s", "bar", "sub", 2, "foo");
158 verify_string("bar", "main.sub2.newsub.foo");
159 }
160 END_TEST
161
162 START_TEST(test_set_default_str)
163 {
164 settings->set_default_str(settings, "main.key1", "default");
165 verify_string("val1", "main.key1");
166 settings->set_default_str(settings, "main.sub1.new", "added");
167 verify_string("added", "main.sub1.new");
168 settings->set_str(settings, "main.sub1.new", "changed");
169 verify_string("changed", "main.sub1.new");
170 }
171 END_TEST
172
173 START_SETUP(setup_bool_config)
174 {
175 create_settings(chunk_from_str(
176 "main {\n"
177 " key1 = yes\n"
178 " key2 = true\n"
179 " key3 = Enabled\n"
180 " key4 = 1\n"
181 " key5 = no\n"
182 " key6 = FALSE\n"
183 " key7 = disabled\n"
184 " key8 = 0\n"
185 " key9 = 5\n"
186 " none = \n"
187 " foo = bar\n"
188 "}"));
189 }
190 END_SETUP
191
192 #define verify_bool(expected, def, key, ...) \
193 ck_assert(expected == settings->get_bool(settings, key, def, ##__VA_ARGS__))
194
195 START_TEST(test_get_bool)
196 {
197 verify_bool(TRUE, FALSE, "main.key1");
198 verify_bool(TRUE, FALSE, "main.key2");
199 verify_bool(TRUE, FALSE, "main.key3");
200 verify_bool(TRUE, FALSE, "main.key4");
201 verify_bool(FALSE, TRUE, "main.key5");
202 verify_bool(FALSE, TRUE, "main.key6");
203 verify_bool(FALSE, TRUE, "main.key7");
204 verify_bool(FALSE, TRUE, "main.key8");
205
206 verify_bool(FALSE, FALSE, "main.none");
207 verify_bool(TRUE, TRUE, "main.none");
208 verify_bool(FALSE, FALSE, "main.foo");
209 verify_bool(TRUE, TRUE, "main.foo");
210
211 verify_bool(FALSE, FALSE, "main.key9");
212 verify_bool(TRUE, TRUE, "main.key9");
213 verify_bool(FALSE, FALSE, "main");
214 verify_bool(TRUE, TRUE, "main");
215
216 }
217 END_TEST
218
219 START_TEST(test_set_bool)
220 {
221 settings->set_str(settings, "main.key1", "no");
222 verify_bool(FALSE, TRUE, "main.key1");
223 settings->set_bool(settings, "main.key2", FALSE);
224 verify_bool(FALSE, TRUE, "main.key2");
225 settings->set_str(settings, "main.key3", NULL);
226 verify_bool(FALSE, FALSE, "main.key3");
227 verify_bool(TRUE, TRUE, "main.key3");
228 settings->set_bool(settings, "main.key5", TRUE);
229 verify_bool(TRUE, FALSE, "main.key5");
230 settings->set_bool(settings, "main.new", TRUE);
231 verify_bool(TRUE, FALSE, "main.new");
232 }
233 END_TEST
234
235 START_SETUP(setup_int_config)
236 {
237 create_settings(chunk_from_str(
238 "main {\n"
239 " key1 = 5\n"
240 " # gets cut off\n"
241 " key2 = 5.5\n"
242 " key3 = -42\n"
243 " none = \n"
244 " foo1 = bar\n"
245 " foo2 = bar13\n"
246 " foo3 = 13bar\n"
247 "}"));
248 }
249 END_SETUP
250
251 #define verify_int(expected, def, key, ...) \
252 ck_assert_int_eq(expected, settings->get_int(settings, key, def, ##__VA_ARGS__))
253
254 START_TEST(test_get_int)
255 {
256 verify_int(5, 0, "main.key1");
257 verify_int(5, 0, "main.key2");
258 verify_int(-42, 0, "main.key3");
259
260 /* FIXME: do we want this behavior? */
261 verify_int(0, 11, "main.none");
262 verify_int(0, 11, "main.foo1");
263 verify_int(0, 11, "main.foo2");
264 verify_int(13, 11, "main.foo3");
265
266 verify_int(13, 13, "main.key4");
267 verify_int(-13, -13, "main");
268 }
269 END_TEST
270
271 START_TEST(test_set_int)
272 {
273 settings->set_str(settings, "main.key1", "13");
274 verify_int(13, 0, "main.key1");
275 settings->set_int(settings, "main.key2", 6);
276 verify_int(6, 0, "main.key2");
277 settings->set_int(settings, "main.key3", -6);
278 verify_int(-6, 0, "main.key3");
279 settings->set_str(settings, "main.key3", NULL);
280 verify_int(15, 15, "main.key3");
281 settings->set_int(settings, "main.new", 314);
282 verify_int(314, 0, "main.new");
283 }
284 END_TEST
285
286 START_SETUP(setup_double_config)
287 {
288 create_settings(chunk_from_str(
289 "main {\n"
290 " key1 = 5\n"
291 " key2 = 5.5\n"
292 " key3 = -42\n"
293 " key4 = -42.5\n"
294 " none = \n"
295 " foo1 = bar\n"
296 " foo2 = bar13.5\n"
297 " foo3 = 13.5bar\n"
298 "}"));
299 }
300 END_SETUP
301
302 #define verify_double(expected, def, key, ...) \
303 ck_assert(expected == settings->get_double(settings, key, def, ##__VA_ARGS__))
304
305 START_TEST(test_get_double)
306 {
307 verify_double(5, 0, "main.key1");
308 verify_double(5.5, 0, "main.key2");
309 verify_double(-42, 0, "main.key3");
310 verify_double(-42.5, 0, "main.key4");
311
312 /* FIXME: do we want this behavior? */
313 verify_double(0, 11.5, "main.none");
314 verify_double(0, 11.5, "main.foo1");
315 verify_double(0, 11.5, "main.foo2");
316 verify_double(13.5, 11.5, "main.foo3");
317
318 verify_double(11.5, 11.5, "main.key5");
319 verify_double(-11.5, -11.5, "main");
320 }
321 END_TEST
322
323 START_TEST(test_set_double)
324 {
325 settings->set_str(settings, "main.key1", "5.5");
326 verify_double(5.5, 0, "main.key1");
327 settings->set_double(settings, "main.key2", 13);
328 verify_double(13, 0, "main.key2");
329 settings->set_double(settings, "main.key3", -13.5);
330 verify_double(-13.5, 0, "main.key3");
331 settings->set_double(settings, "main.key4", 11.5);
332 verify_double(11.5, 0, "main.key4");
333 settings->set_str(settings, "main.key4", NULL);
334 verify_double(42.5, 42.5, "main.key4");
335 settings->set_double(settings, "main.new", 3.14);
336 verify_double(3.14, 0, "main.new");
337 }
338 END_TEST
339
340 START_SETUP(setup_time_config)
341 {
342 create_settings(chunk_from_str(
343 "main {\n"
344 " key1 = 5s\n"
345 " key2 = 5m\n"
346 " key3 = 5h\n"
347 " key4 = 5d\n"
348 " none = \n"
349 " foo1 = bar\n"
350 " foo2 = bar13\n"
351 " foo3 = 13bar\n"
352 "}"));
353 }
354 END_SETUP
355
356 #define verify_time(expected, def, key, ...) \
357 ck_assert_int_eq(expected, settings->get_time(settings, key, def, ##__VA_ARGS__))
358
359 START_TEST(test_get_time)
360 {
361 verify_time(5, 0, "main.key1");
362 verify_time(300, 0, "main.key2");
363 verify_time(18000, 0, "main.key3");
364 verify_time(432000, 0, "main.key4");
365
366 /* FIXME: do we want this behavior? */
367 verify_time(0, 11, "main.none");
368 verify_time(0, 11, "main.foo1");
369 verify_time(0, 11, "main.foo2");
370 verify_time(13, 11, "main.foo3");
371
372 verify_time(11, 11, "main.key5");
373 verify_time(11, 11, "main");
374 }
375 END_TEST
376
377 START_TEST(test_set_time)
378 {
379 settings->set_str(settings, "main.key1", "15m");
380 verify_time(900, 0, "main.key1");
381 settings->set_time(settings, "main.key2", 15);
382 verify_time(15, 0, "main.key2");
383 settings->set_str(settings, "main.key3", NULL);
384 verify_time(300, 300, "main.key3");
385 settings->set_time(settings, "main.new", 314);
386 verify_time(314, 0, "main.new");
387 }
388 END_TEST
389
390 static bool verify_section(linked_list_t *verifier, char *section)
391 {
392 enumerator_t *enumerator;
393 char *current;
394 bool result = FALSE;
395
396 enumerator = verifier->create_enumerator(verifier);
397 while (enumerator->enumerate(enumerator, &current))
398 {
399 if (streq(current, section))
400 {
401 verifier->remove_at(verifier, enumerator);
402 result = TRUE;
403 break;
404 }
405 }
406 enumerator->destroy(enumerator);
407 return result;
408 }
409
410 static void verify_sections(linked_list_t *verifier, char *parent)
411 {
412 enumerator_t *enumerator;
413 char *section;
414
415 enumerator = settings->create_section_enumerator(settings, parent);
416 while (enumerator->enumerate(enumerator, &section))
417 {
418 ck_assert(verify_section(verifier, section));
419 }
420 enumerator->destroy(enumerator);
421 ck_assert_int_eq(0, verifier->get_count(verifier));
422 verifier->destroy(verifier);
423 }
424
425 START_TEST(test_section_enumerator)
426 {
427 linked_list_t *verifier;
428
429 verifier = linked_list_create_with_items("sub1", "sub%", NULL);
430 verify_sections(verifier, "main");
431
432 settings->set_str(settings, "main.sub2.new", "added");
433 verifier = linked_list_create_with_items("sub1", "sub%", "sub2", NULL);
434 verify_sections(verifier, "main");
435
436 verifier = linked_list_create_with_items("subsub", NULL);
437 verify_sections(verifier, "main.sub1");
438
439 verifier = linked_list_create_with_items(NULL);
440 verify_sections(verifier, "main.sub%%");
441
442 verifier = linked_list_create_with_items(NULL);
443 verify_sections(verifier, "main.key1");
444
445 verifier = linked_list_create_with_items(NULL);
446 verify_sections(verifier, "main.unknown");
447 }
448 END_TEST
449
450 static bool verify_key_value(linked_list_t *keys, linked_list_t *values,
451 char *key, char *value)
452 {
453 enumerator_t *enum_keys, *enum_values;
454 char *current_key, *current_value;
455 bool result = FALSE;
456
457 enum_keys = keys->create_enumerator(keys);
458 enum_values = values->create_enumerator(values);
459 while (enum_keys->enumerate(enum_keys, &current_key) &&
460 enum_values->enumerate(enum_values, &current_value))
461 {
462 if (streq(current_key, key))
463 {
464 ck_assert_str_eq(current_value, value);
465 keys->remove_at(keys, enum_keys);
466 values->remove_at(values, enum_values);
467 result = TRUE;
468 break;
469 }
470 }
471 enum_keys->destroy(enum_keys);
472 enum_values->destroy(enum_values);
473 return result;
474 }
475
476 static void verify_key_values(linked_list_t *keys, linked_list_t *values,
477 char *parent)
478 {
479 enumerator_t *enumerator;
480 char *key, *value;
481
482 enumerator = settings->create_key_value_enumerator(settings, parent);
483 while (enumerator->enumerate(enumerator, &key, &value))
484 {
485 ck_assert(verify_key_value(keys, values, key, value));
486 }
487 enumerator->destroy(enumerator);
488 ck_assert_int_eq(0, keys->get_count(keys));
489 keys->destroy(keys);
490 values->destroy(values);
491 }
492
493 START_TEST(test_key_value_enumerator)
494 {
495 linked_list_t *keys, *values;
496
497 keys = linked_list_create_with_items("key1", "key2", "none", NULL);
498 values = linked_list_create_with_items("val1", "with spaces", "", NULL);
499 verify_key_values(keys, values, "main");
500
501 keys = linked_list_create_with_items("key", "key2", "subsub", NULL);
502 values = linked_list_create_with_items("value", "value2", "section value", NULL);
503 verify_key_values(keys, values, "main.sub1");
504
505 settings->set_str(settings, "main.sub2.new", "added");
506 keys = linked_list_create_with_items("new", NULL);
507 values = linked_list_create_with_items("added", NULL);
508 verify_key_values(keys, values, "main.sub2");
509
510 keys = linked_list_create_with_items(NULL);
511 values = linked_list_create_with_items(NULL);
512 verify_key_values(keys, values, "other.empty");
513
514 settings->set_str(settings, "other.empty.new", "added");
515 keys = linked_list_create_with_items("new", NULL);
516 values = linked_list_create_with_items("added", NULL);
517 verify_key_values(keys, values, "other.empty");
518
519 keys = linked_list_create_with_items(NULL);
520 values = linked_list_create_with_items(NULL);
521 verify_key_values(keys, values, "main.unknown");
522 }
523 END_TEST
524
525 #define include1 "/tmp/strongswan-settings-test-include1"
526 #define include2 "/tmp/strongswan-settings-test-include2"
527
528 START_SETUP(setup_include_config)
529 {
530 chunk_t inc1 = chunk_from_str(
531 "main {\n"
532 " key1 = n1\n"
533 " key2 = n2\n"
534 " none = \n"
535 " sub1 {\n"
536 " key3 = value\n"
537 " }\n"
538 " sub2 {\n"
539 " sub3 = val3\n"
540 " }\n"
541 " include " include2 "\n"
542 "}");
543 chunk_t inc2 = chunk_from_str(
544 "key2 = v2\n"
545 "sub1 {\n"
546 " key = val\n"
547 "}");
548 ck_assert(chunk_write(inc1, include1, 0022, TRUE));
549 ck_assert(chunk_write(inc2, include2, 0022, TRUE));
550 }
551 END_SETUP
552
553 START_TEARDOWN(teardown_include_config)
554 {
555 settings->destroy(settings);
556 unlink(include2);
557 unlink(include1);
558 unlink(path);
559 }
560 END_TEARDOWN
561
562 static void verify_include()
563 {
564 verify_string("n1", "main.key1");
565 verify_string("v2", "main.key2");
566 verify_string("", "main.none");
567 verify_string("val", "main.sub1.key");
568 verify_string("v2", "main.sub1.key2");
569 verify_string("val", "main.sub1.sub1.key");
570 verify_string("value", "main.sub1.key3");
571 verify_string("value", "main.sub1.include");
572 verify_string("val3", "main.sub2.sub3");
573 }
574
575 START_TEST(test_include)
576 {
577 chunk_t contents = chunk_from_str(
578 "main {\n"
579 " key1 = val1\n"
580 " key2 = val2\n"
581 " none = x\n"
582 " sub1 {\n"
583 " include = value\n"
584 " key2 = value2\n"
585 " include " include2 "\n"
586 " }\n"
587 "}\n"
588 "# currently there must be a newline after include statements\n"
589 "include " include1 "\n");
590
591 create_settings(contents);
592 verify_include();
593 }
594 END_TEST
595
596 START_TEST(test_load_files)
597 {
598 chunk_t contents = chunk_from_str(
599 "main {\n"
600 " key1 = val1\n"
601 " key2 = val2\n"
602 " none = x\n"
603 " sub1 {\n"
604 " include = value\n"
605 " key2 = v2\n"
606 " sub1 {\n"
607 " key = val\n"
608 " }\n"
609 " }\n"
610 "}");
611
612 create_settings(contents);
613
614 ck_assert(settings->load_files(settings, include1, TRUE));
615 verify_include();
616
617 ck_assert(settings->load_files(settings, include2, FALSE));
618 verify_null("main.key1");
619 verify_string("v2", "key2");
620 verify_string("val", "sub1.key");
621 verify_null("main.sub1.key3");
622 }
623 END_TEST
624
625 START_TEST(test_load_files_section)
626 {
627 chunk_t contents = chunk_from_str(
628 "main {\n"
629 " key1 = val1\n"
630 " key2 = val2\n"
631 " none = x\n"
632 " sub1 {\n"
633 " include = value\n"
634 " key2 = value2\n"
635 " }\n"
636 "}");
637
638 create_settings(contents);
639
640 ck_assert(settings->load_files_section(settings, include1, TRUE, ""));
641 ck_assert(settings->load_files_section(settings, include2, TRUE, "main.sub1"));
642 verify_include();
643
644 /* non existing files are no failure */
645 ck_assert(settings->load_files_section(settings, include1".conf", TRUE, ""));
646 verify_include();
647
648 /* unreadable files are */
649 ck_assert(chunk_write(contents, include1".no", 0444, TRUE));
650 ck_assert(!settings->load_files_section(settings, include1".no", TRUE, ""));
651 unlink(include1".no");
652 verify_include();
653
654 ck_assert(settings->load_files_section(settings, include2, FALSE, "main"));
655 verify_null("main.key1");
656 verify_string("v2", "main.key2");
657 verify_string("val", "main.sub1.key");
658 verify_null("main.sub1.key3");
659 verify_null("main.sub2.sub3");
660
661 ck_assert(settings->load_files_section(settings, include2, TRUE, "main.sub2"));
662 verify_string("v2", "main.sub2.key2");
663 verify_string("val", "main.sub2.sub1.key");
664 }
665 END_TEST
666
667 START_SETUP(setup_fallback_config)
668 {
669 create_settings(chunk_from_str(
670 "main {\n"
671 " key1 = val1\n"
672 " sub1 {\n"
673 " key1 = val1\n"
674 " }\n"
675 "}\n"
676 "sub {\n"
677 " key1 = subval1\n"
678 " key2 = subval2\n"
679 " subsub {\n"
680 " subkey1 = subsubval1\n"
681 " }\n"
682 "}\n"
683 "base {\n"
684 " key1 = baseval1\n"
685 " key2 = baseval2\n"
686 " sub1 {\n"
687 " key1 = subbase1\n"
688 " key2 = subbase2\n"
689 " key3 = subbase3\n"
690 " subsub {\n"
691 " subkey1 = subsubbaseval1\n"
692 " subkey2 = subsubbaseval2\n"
693 " }\n"
694 " }\n"
695 " sub2 {\n"
696 " key4 = subbase4\n"
697 " }\n"
698 "}"));
699 }
700 END_SETUP
701
702 START_TEST(test_add_fallback)
703 {
704 linked_list_t *keys, *values;
705
706 settings->add_fallback(settings, "main.sub1", "sub");
707 verify_string("val1", "main.sub1.key1");
708 verify_string("subval2", "main.sub1.key2");
709 verify_string("subsubval1", "main.sub1.subsub.subkey1");
710
711 /* fallbacks are preserved even if the complete config is replaced */
712 settings->load_files(settings, path, FALSE);
713 verify_string("val1", "main.sub1.key1");
714 verify_string("subval2", "main.sub1.key2");
715 verify_string("subsubval1", "main.sub1.subsub.subkey1");
716
717 /* fallbacks currently have no effect on section & key/value enumerators */
718 keys = linked_list_create_with_items(NULL);
719 verify_sections(keys, "main.sub1");
720
721 keys = linked_list_create_with_items("key1", NULL);
722 values = linked_list_create_with_items("val1", NULL);
723 verify_key_values(keys, values, "main.sub1");
724
725 settings->add_fallback(settings, "main", "base");
726 verify_string("val1", "main.key1");
727 verify_string("baseval2", "main.key2");
728 verify_string("val1", "main.sub1.key1");
729 verify_string("subval2", "main.sub1.key2");
730 verify_string("subsubval1", "main.sub1.subsub.subkey1");
731 verify_string("subsubbaseval2", "main.sub1.subsub.subkey2");
732 verify_string("subbase3", "main.sub1.key3");
733 verify_string("subbase4", "main.sub2.key4");
734
735 keys = linked_list_create_with_items(NULL);
736 verify_sections(keys, "main.sub1");
737 keys = linked_list_create_with_items("sub1", NULL);
738 verify_sections(keys, "main");
739
740 keys = linked_list_create_with_items("key1", NULL);
741 values = linked_list_create_with_items("val1", NULL);
742 verify_key_values(keys, values, "main.sub1");
743
744 keys = linked_list_create_with_items("key1", NULL);
745 values = linked_list_create_with_items("val1", NULL);
746 verify_key_values(keys, values, "main");
747
748 settings->set_str(settings, "main.sub1.key2", "val2");
749 verify_string("val2", "main.sub1.key2");
750 settings->set_str(settings, "main.sub1.subsub.subkey2", "val2");
751 verify_string("val2", "main.sub1.subsub.subkey2");
752 verify_string("subsubval1", "main.sub1.subsub.subkey1");
753 }
754 END_TEST
755
756 START_TEST(test_add_fallback_printf)
757 {
758 settings->add_fallback(settings, "%s.sub1", "sub", "main");
759 verify_string("val1", "main.sub1.key1");
760 verify_string("subval2", "main.sub1.key2");
761 verify_string("subsubval1", "main.sub1.subsub.subkey1");
762
763 settings->add_fallback(settings, "%s.%s2", "%s.%s1", "main", "sub");
764 verify_string("val1", "main.sub2.key1");
765 verify_string("subval2", "main.sub2.key2");
766 verify_string("subsubval1", "main.sub2.subsub.subkey1");
767 }
768 END_TEST
769
770 Suite *settings_suite_create()
771 {
772 Suite *s;
773 TCase *tc;
774
775 s = suite_create("settings");
776
777 tc = tcase_create("get/set_str (basic behavior)");
778 tcase_add_checked_fixture(tc, setup_base_config, teardown_config);
779 tcase_add_test(tc, test_get_str);
780 tcase_add_test(tc, test_get_str_printf);
781 tcase_add_test(tc, test_set_str);
782 tcase_add_test(tc, test_set_str_printf);
783 tcase_add_test(tc, test_set_default_str);
784 suite_add_tcase(s, tc);
785
786 tc = tcase_create("get/set_bool");
787 tcase_add_checked_fixture(tc, setup_bool_config, teardown_config);
788 tcase_add_test(tc, test_get_bool);
789 tcase_add_test(tc, test_set_bool);
790 suite_add_tcase(s, tc);
791
792 tc = tcase_create("get/set_int");
793 tcase_add_checked_fixture(tc, setup_int_config, teardown_config);
794 tcase_add_test(tc, test_get_int);
795 tcase_add_test(tc, test_set_int);
796 suite_add_tcase(s, tc);
797
798 tc = tcase_create("get/set_double");
799 tcase_add_checked_fixture(tc, setup_double_config, teardown_config);
800 tcase_add_test(tc, test_get_double);
801 tcase_add_test(tc, test_set_double);
802 suite_add_tcase(s, tc);
803
804 tc = tcase_create("get/set_time");
805 tcase_add_checked_fixture(tc, setup_time_config, teardown_config);
806 tcase_add_test(tc, test_get_time);
807 tcase_add_test(tc, test_set_time);
808 suite_add_tcase(s, tc);
809
810 tc = tcase_create("section enumerator");
811 tcase_add_checked_fixture(tc, setup_base_config, teardown_config);
812 tcase_add_test(tc, test_section_enumerator);
813 suite_add_tcase(s, tc);
814
815 tc = tcase_create("key/value enumerator");
816 tcase_add_checked_fixture(tc, setup_base_config, teardown_config);
817 tcase_add_test(tc, test_key_value_enumerator);
818 suite_add_tcase(s, tc);
819
820 tc = tcase_create("include/load_files[_section]");
821 tcase_add_checked_fixture(tc, setup_include_config, teardown_include_config);
822 tcase_add_test(tc, test_include);
823 tcase_add_test(tc, test_load_files);
824 tcase_add_test(tc, test_load_files_section);
825 suite_add_tcase(s, tc);
826
827 tc = tcase_create("fallback");
828 tcase_add_checked_fixture(tc, setup_fallback_config, teardown_config);
829 tcase_add_test(tc, test_add_fallback);
830 tcase_add_test(tc, test_add_fallback_printf);
831 suite_add_tcase(s, tc);
832
833 return s;
834 }