settings: Add settings_value_as_uint64() helper function
[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 <settings/settings.h>
21 #include <utils/chunk.h>
22 #include <utils/utils.h>
23 #include <collections/linked_list.h>
24
25 #ifdef WIN32
26 static char *path = "C:\\Windows\\Temp\\strongswan-settings-test";
27 #else
28 static char *path = "/tmp/strongswan-settings-test";
29 #endif
30 static settings_t *settings;
31
32 static void create_settings(chunk_t contents)
33 {
34 ck_assert(chunk_write(contents, path, 0022, TRUE));
35 settings = settings_create(path);
36 }
37
38 START_SETUP(setup_base_config)
39 {
40 create_settings(chunk_from_str(
41 "main {\n"
42 " key1 = val1\n"
43 " # this gets overridden below\n"
44 " key2 = val2\n"
45 " none = \n"
46 " empty = \"\"\n"
47 " sub1 {\n"
48 " key = value\n"
49 " key2 = value2\n"
50 " subsub {\n"
51 " foo = bar\n"
52 " }\n"
53 " # subsub is a section and a value\n"
54 " subsub = section value\n"
55 " }\n"
56 " sub% {\n"
57 " id = %any\n"
58 " }\n"
59 " key2 = with space\n"
60 " key3 = \"string with\\nnewline\"\n"
61 " key4 = \"multi line\n"
62 "string\"\n"
63 " key5 = \"escaped \\\n"
64 "newline\"\n"
65 "}\n"
66 "out = side\n"
67 "other {\n"
68 " key1 = other val\n"
69 " empty {\n"
70 " }\n"
71 "}"));
72 }
73 END_SETUP
74
75 START_TEARDOWN(teardown_config)
76 {
77 settings->destroy(settings);
78 unlink(path);
79 }
80 END_TEARDOWN
81
82 #define verify_string(expected, key, ...) \
83 ck_assert_str_eq(expected, settings->get_str(settings, key, NULL, ##__VA_ARGS__))
84 #define verify_null(key, ...) \
85 ck_assert(!settings->get_str(settings, key, NULL, ##__VA_ARGS__))
86
87 START_TEST(test_get_str)
88 {
89 verify_string("val1", "main.key1");
90 verify_string("val1", "main..key1");
91 verify_string("val1", ".main.key1");
92 verify_string("", "main.empty");
93 verify_string("with space", "main.key2");
94 verify_string("string with\nnewline", "main.key3");
95 verify_string("multi line\nstring", "main.key4");
96 verify_string("escaped newline", "main.key5");
97 verify_string("value", "main.sub1.key");
98 verify_string("value2", "main.sub1.key2");
99 verify_string("bar", "main.sub1.subsub.foo");
100 verify_string("section value", "main.sub1.subsub");
101 verify_string("%any", "main.sub%%.id");
102 verify_string("side", "out");
103 verify_string("other val", "other.key1");
104
105 verify_null("main.none");
106 verify_null("main.key6");
107 verify_null("other.sub");
108 }
109 END_TEST
110
111 enum {
112 KEY1,
113 SUB1
114 } settings_test_enum;
115
116 enum_name_t *test_settings_test_names;
117
118 ENUM_BEGIN(test_settings_test_names, KEY1, SUB1,
119 "key1", "sub1");
120 ENUM_END(test_settings_test_names, SUB1);
121
122 START_TEST(test_get_str_printf)
123 {
124 verify_string("val1", "%s.key1", "main");
125 verify_string("val1", "%s.%s", "main", "key1");
126 verify_string("val1", "%s.%N", "main", test_settings_test_names, KEY1);
127 verify_string("val1", "%s.%s%d", "main", "key", 1);
128 verify_string("bar", "%s.sub1.%s.foo", "main", "subsub");
129 verify_string("bar", "%s.%N.%s.foo", "main", test_settings_test_names, SUB1, "subsub");
130 verify_string("bar", "%s.sub%d.%s.foo", "main", 1, "subsub");
131 verify_string("%any", "%s.sub%%.id", "main");
132
133 /* FIXME: this is a bit inconsistent, while this works */
134 verify_string("value2", "main.%s%u.key2", "sub", 1);
135 /* this won't because no argument is consumed for %u so key1 will be tried
136 * granted, we never actually used any other specifiers, but we should
137 * probably document it at least */
138 verify_null("main.%s%u.key%d", "sub", 1, 2);
139
140 verify_null("%s.%s%d", "main", "key", 6);
141 }
142 END_TEST
143
144 START_TEST(test_set_str)
145 {
146 char *val1, *val2;
147
148 val1 = settings->get_str(settings, "main.key1", NULL);
149 ck_assert_str_eq("val1", val1);
150 settings->set_str(settings, "main.key1", "val");
151 verify_string("val", "main.key1");
152 /* the pointer we got before is still valid */
153 ck_assert_str_eq("val1", val1);
154
155 val2 = settings->get_str(settings, "main.key1", NULL);
156 ck_assert_str_eq("val", val2);
157 settings->set_str(settings, "main.key1", "longer value");
158 verify_string("longer value", "main.key1");
159 /* the pointers we got before are still valid */
160 ck_assert_str_eq("val1", val1);
161 ck_assert_str_eq("val", val2);
162
163 val1 = settings->get_str(settings, "main.key1", NULL);
164 settings->set_str(settings, "main.key1", "longer value");
165 val2 = settings->get_str(settings, "main.key1", NULL);
166 /* setting the same string should should get us the same pointer */
167 ck_assert(val1 == val2);
168
169 settings->set_str(settings, "main", "main val");
170 verify_string("main val", "main");
171 settings->set_str(settings, "main.sub1.new", "added");
172 verify_string("added", "main.sub1.new");
173 settings->set_str(settings, "main.sub2.newsub.foo", "bar");
174 verify_string("bar", "main.sub2.newsub.foo");
175 settings->set_str(settings, "new.newsub.foo", "bar");
176 verify_string("bar", "new.newsub.foo");
177 settings->set_str(settings, "main.key1", NULL);
178 verify_null("main.key1");
179 }
180 END_TEST
181
182 START_TEST(test_set_str_printf)
183 {
184 settings->set_str(settings, "%s.key1", "val", "main");
185 verify_string("val", "main.key1");
186 settings->set_str(settings, "main.%N.new", "added", test_settings_test_names, SUB1);
187 verify_string("added", "main.sub1.new");
188 settings->set_str(settings, "main.%s%d.newsub.%s", "bar", "sub", 2, "foo");
189 verify_string("bar", "main.sub2.newsub.foo");
190 }
191 END_TEST
192
193 START_TEST(test_set_default_str)
194 {
195 settings->set_default_str(settings, "main.key1", "default");
196 verify_string("val1", "main.key1");
197 settings->set_default_str(settings, "main.sub1.new", "added");
198 verify_string("added", "main.sub1.new");
199 settings->set_str(settings, "main.sub1.new", "changed");
200 verify_string("changed", "main.sub1.new");
201 }
202 END_TEST
203
204 START_SETUP(setup_bool_config)
205 {
206 create_settings(chunk_from_str(
207 "main {\n"
208 " key1 = yes\n"
209 " key2 = true\n"
210 " key3 = Enabled\n"
211 " key4 = 1\n"
212 " key5 = no\n"
213 " key6 = FALSE\n"
214 " key7 = disabled\n"
215 " key8 = 0\n"
216 " key9 = 5\n"
217 " empty = \"\"\n"
218 " none = \n"
219 " foo = bar\n"
220 "}"));
221 }
222 END_SETUP
223
224 #define verify_bool(expected, def, key, ...) \
225 ck_assert(expected == settings->get_bool(settings, key, def, ##__VA_ARGS__))
226
227 START_TEST(test_get_bool)
228 {
229 verify_bool(TRUE, FALSE, "main.key1");
230 verify_bool(TRUE, FALSE, "main.key2");
231 verify_bool(TRUE, FALSE, "main.key3");
232 verify_bool(TRUE, FALSE, "main.key4");
233 verify_bool(FALSE, TRUE, "main.key5");
234 verify_bool(FALSE, TRUE, "main.key6");
235 verify_bool(FALSE, TRUE, "main.key7");
236 verify_bool(FALSE, TRUE, "main.key8");
237
238 verify_bool(FALSE, FALSE, "main.empty");
239 verify_bool(TRUE, TRUE, "main.empty");
240 verify_bool(FALSE, FALSE, "main.none");
241 verify_bool(TRUE, TRUE, "main.none");
242 verify_bool(FALSE, FALSE, "main.foo");
243 verify_bool(TRUE, TRUE, "main.foo");
244
245 verify_bool(FALSE, FALSE, "main.key9");
246 verify_bool(TRUE, TRUE, "main.key9");
247 verify_bool(FALSE, FALSE, "main");
248 verify_bool(TRUE, TRUE, "main");
249
250 }
251 END_TEST
252
253 START_TEST(test_set_bool)
254 {
255 settings->set_str(settings, "main.key1", "no");
256 verify_bool(FALSE, TRUE, "main.key1");
257 settings->set_bool(settings, "main.key2", FALSE);
258 verify_bool(FALSE, TRUE, "main.key2");
259 settings->set_str(settings, "main.key3", NULL);
260 verify_bool(FALSE, FALSE, "main.key3");
261 verify_bool(TRUE, TRUE, "main.key3");
262 settings->set_bool(settings, "main.key5", TRUE);
263 verify_bool(TRUE, FALSE, "main.key5");
264 settings->set_bool(settings, "main.new", TRUE);
265 verify_bool(TRUE, FALSE, "main.new");
266 }
267 END_TEST
268
269 START_SETUP(setup_int_config)
270 {
271 create_settings(chunk_from_str(
272 "main {\n"
273 " key1 = 5\n"
274 " key2 = 5.5\n"
275 " key3 = -42\n"
276 " empty = \"\"\n"
277 " none = \n"
278 " foo1 = bar\n"
279 " foo2 = bar13\n"
280 " foo3 = 13bar\n"
281 "}"));
282 }
283 END_SETUP
284
285 #define verify_int(expected, def, key, ...) \
286 ck_assert_int_eq(expected, settings->get_int(settings, key, def, ##__VA_ARGS__))
287
288 START_TEST(test_get_int)
289 {
290 verify_int(5, 0, "main.key1");
291 verify_int(0, 0, "main.key2");
292 verify_int(-42, 0, "main.key3");
293
294 verify_int(11, 11, "main.empty");
295 verify_int(11, 11, "main.none");
296 verify_int(11, 11, "main.foo1");
297 verify_int(11, 11, "main.foo2");
298 verify_int(11, 11, "main.foo3");
299
300 verify_int(13, 13, "main.key4");
301 verify_int(-13, -13, "main");
302 }
303 END_TEST
304
305 START_TEST(test_set_int)
306 {
307 settings->set_str(settings, "main.key1", "13");
308 verify_int(13, 0, "main.key1");
309 settings->set_int(settings, "main.key2", 6);
310 verify_int(6, 0, "main.key2");
311 settings->set_int(settings, "main.key3", -6);
312 verify_int(-6, 0, "main.key3");
313 settings->set_str(settings, "main.key3", NULL);
314 verify_int(15, 15, "main.key3");
315 settings->set_int(settings, "main.new", 314);
316 verify_int(314, 0, "main.new");
317 }
318 END_TEST
319
320 START_TEST(test_value_as_unit64)
321 {
322 test_int_eq(1, settings_value_as_uint64(NULL, 1));
323 test_int_eq(1, settings_value_as_uint64("", 1));
324 test_int_eq(1, settings_value_as_uint64("2a", 1));
325 test_int_eq(1, settings_value_as_uint64("a2", 1));
326 test_int_eq(1, settings_value_as_uint64("2.0", 1));
327
328 test_int_eq(10, settings_value_as_uint64("10", 0));
329 test_int_eq(10, settings_value_as_uint64("010", 0));
330 test_int_eq(16, settings_value_as_uint64("0x010", 0));
331 test_int_eq(0x2a, settings_value_as_uint64("0x2a", 0));
332
333 test_int_eq(0xffffffffffffffffLL, settings_value_as_uint64("0xffffffffffffffff", 0));
334 test_int_eq(0xffffffff00000000LL, settings_value_as_uint64("0xffffffff00000000", 0));
335 test_int_eq(0xffffffff00000000LL, settings_value_as_uint64("18446744069414584320", 0));
336 test_int_eq(0xffffffff00000001LL, settings_value_as_uint64("18446744069414584321", 0));
337 }
338 END_TEST
339
340 START_SETUP(setup_double_config)
341 {
342 create_settings(chunk_from_str(
343 "main {\n"
344 " key1 = 5\n"
345 " key2 = 5.5\n"
346 " key3 = -42\n"
347 " key4 = -42.5\n"
348 " empty = \"\"\n"
349 " none = \n"
350 " foo1 = bar\n"
351 " foo2 = bar13.5\n"
352 " foo3 = 13.5bar\n"
353 "}"));
354 }
355 END_SETUP
356
357 #define verify_double(expected, def, key, ...) \
358 ck_assert(expected == settings->get_double(settings, key, def, ##__VA_ARGS__))
359
360 START_TEST(test_get_double)
361 {
362 verify_double(5, 0, "main.key1");
363 verify_double(5.5, 0, "main.key2");
364 verify_double(-42, 0, "main.key3");
365 verify_double(-42.5, 0, "main.key4");
366
367 verify_double(11.5, 11.5, "main.empty");
368 verify_double(11.5, 11.5, "main.none");
369 verify_double(11.5, 11.5, "main.foo1");
370 verify_double(11.5, 11.5, "main.foo2");
371 verify_double(11.5, 11.5, "main.foo3");
372
373 verify_double(11.5, 11.5, "main.key5");
374 verify_double(-11.5, -11.5, "main");
375 }
376 END_TEST
377
378 START_TEST(test_set_double)
379 {
380 settings->set_str(settings, "main.key1", "5.5");
381 verify_double(5.5, 0, "main.key1");
382 settings->set_double(settings, "main.key2", 13);
383 verify_double(13, 0, "main.key2");
384 settings->set_double(settings, "main.key3", -13.5);
385 verify_double(-13.5, 0, "main.key3");
386 settings->set_double(settings, "main.key4", 11.5);
387 verify_double(11.5, 0, "main.key4");
388 settings->set_str(settings, "main.key4", NULL);
389 verify_double(42.5, 42.5, "main.key4");
390 settings->set_double(settings, "main.new", 3.14);
391 verify_double(3.14, 0, "main.new");
392 }
393 END_TEST
394
395 START_SETUP(setup_time_config)
396 {
397 create_settings(chunk_from_str(
398 "main {\n"
399 " key0 = 5\n"
400 " key1 = 5s\n"
401 " key2 = 5m\n"
402 " key3 = 5 h\n"
403 " key4 = 5\td\n"
404 " empty = \"\"\n"
405 " none = \n"
406 " foo1 = bar\n"
407 " foo2 = bar13\n"
408 " foo3 = 13bar\n"
409 "}"));
410 }
411 END_SETUP
412
413 #define verify_time(expected, def, key, ...) \
414 ck_assert_int_eq(expected, settings->get_time(settings, key, def, ##__VA_ARGS__))
415
416 START_TEST(test_get_time)
417 {
418 verify_time(5, 0, "main.key0");
419 verify_time(5, 0, "main.key1");
420 verify_time(300, 0, "main.key2");
421 verify_time(18000, 0, "main.key3");
422 verify_time(432000, 0, "main.key4");
423
424 verify_time(11, 11, "main.empty");
425 verify_time(11, 11, "main.none");
426 verify_time(11, 11, "main.foo1");
427 verify_time(11, 11, "main.foo2");
428 verify_time(11, 11, "main.foo3");
429
430 verify_time(11, 11, "main.key5");
431 verify_time(11, 11, "main");
432 }
433 END_TEST
434
435 START_TEST(test_set_time)
436 {
437 settings->set_str(settings, "main.key1", "15m");
438 verify_time(900, 0, "main.key1");
439 settings->set_time(settings, "main.key2", 15);
440 verify_time(15, 0, "main.key2");
441 settings->set_str(settings, "main.key3", NULL);
442 verify_time(300, 300, "main.key3");
443 settings->set_time(settings, "main.new", 314);
444 verify_time(314, 0, "main.new");
445 }
446 END_TEST
447
448 static void verify_sections(linked_list_t *verifier, char *parent)
449 {
450 enumerator_t *enumerator, *ver;
451 char *section, *current;
452
453 enumerator = settings->create_section_enumerator(settings, parent);
454 ver = verifier->create_enumerator(verifier);
455 while (enumerator->enumerate(enumerator, &section) &&
456 ver->enumerate(ver, &current))
457 {
458 ck_assert_str_eq(section, current);
459 verifier->remove_at(verifier, ver);
460 }
461 enumerator->destroy(enumerator);
462 ver->destroy(ver);
463 ck_assert_int_eq(0, verifier->get_count(verifier));
464 verifier->destroy(verifier);
465 }
466
467 START_TEST(test_section_enumerator)
468 {
469 linked_list_t *verifier;
470
471 verifier = linked_list_create_with_items("sub1", "sub%", NULL);
472 verify_sections(verifier, "main");
473
474 settings->set_str(settings, "main.sub0.new", "added");
475 verifier = linked_list_create_with_items("sub1", "sub%", "sub0", NULL);
476 verify_sections(verifier, "main");
477
478 verifier = linked_list_create_with_items("subsub", NULL);
479 verify_sections(verifier, "main.sub1");
480
481 verifier = linked_list_create_with_items(NULL);
482 verify_sections(verifier, "main.sub%%");
483
484 verifier = linked_list_create_with_items(NULL);
485 verify_sections(verifier, "main.key1");
486
487 verifier = linked_list_create_with_items(NULL);
488 verify_sections(verifier, "main.unknown");
489 }
490 END_TEST
491
492 static void verify_key_values(linked_list_t *keys, linked_list_t *values,
493 char *parent)
494 {
495 enumerator_t *enumerator, *enum_keys, *enum_values;
496 char *key, *value, *current_key, *current_value;
497
498 enumerator = settings->create_key_value_enumerator(settings, parent);
499 enum_keys = keys->create_enumerator(keys);
500 enum_values = values->create_enumerator(values);
501 while (enumerator->enumerate(enumerator, &key, &value) &&
502 enum_keys->enumerate(enum_keys, &current_key) &&
503 enum_values->enumerate(enum_values, &current_value))
504 {
505 ck_assert_str_eq(current_key, key);
506 ck_assert_str_eq(current_value, value);
507 keys->remove_at(keys, enum_keys);
508 values->remove_at(values, enum_values);
509 }
510 enumerator->destroy(enumerator);
511 enum_keys->destroy(enum_keys);
512 enum_values->destroy(enum_values);
513 ck_assert_int_eq(0, keys->get_count(keys));
514 keys->destroy(keys);
515 values->destroy(values);
516 }
517
518 START_TEST(test_key_value_enumerator)
519 {
520 linked_list_t *keys, *values;
521
522 keys = linked_list_create_with_items("key1", "key2", "empty", "key3", NULL);
523 values = linked_list_create_with_items("val1", "with space", "", "string with\nnewline", NULL);
524 verify_key_values(keys, values, "main");
525
526 keys = linked_list_create_with_items("key", "key2", "subsub", NULL);
527 values = linked_list_create_with_items("value", "value2", "section value", NULL);
528 verify_key_values(keys, values, "main.sub1");
529
530 settings->set_str(settings, "main.sub2.new", "added");
531 keys = linked_list_create_with_items("new", NULL);
532 values = linked_list_create_with_items("added", NULL);
533 verify_key_values(keys, values, "main.sub2");
534
535 keys = linked_list_create_with_items(NULL);
536 values = linked_list_create_with_items(NULL);
537 verify_key_values(keys, values, "other.empty");
538
539 settings->set_str(settings, "other.empty.new", "added");
540 keys = linked_list_create_with_items("new", NULL);
541 values = linked_list_create_with_items("added", NULL);
542 verify_key_values(keys, values, "other.empty");
543
544 keys = linked_list_create_with_items(NULL);
545 values = linked_list_create_with_items(NULL);
546 verify_key_values(keys, values, "main.unknown");
547 }
548 END_TEST
549
550 #ifdef WIN32
551 # define include1 "C:\\Windows\\Temp\\strongswan-settings-test-include1"
552 # define include2 "C:\\Windows\\Temp\\strongswan-settings-test-include2"
553 #else
554 # define include1 "/tmp/strongswan-settings-test-include1"
555 # define include2 "/tmp/strongswan-settings-test-include2"
556 #endif
557
558 static char *include_content1 =
559 "main {\n"
560 " key1 = n1\n"
561 " key2 = n2\n"
562 " key3 = val3\n"
563 " none = \n"
564 " sub1 {\n"
565 " key3 = value\n"
566 " }\n"
567 " sub2 {\n"
568 " sub3 = val3\n"
569 " }\n"
570 " include " include2 "\n"
571 "}";
572 static char *include_content2 =
573 "key2 = v2\n"
574 "sub1 {\n"
575 " key = val\n"
576 "}";
577
578 START_SETUP(setup_include_config)
579 {
580 ck_assert(chunk_write(chunk_from_str(include_content1), include1, 0022, TRUE));
581 ck_assert(chunk_write(chunk_from_str(include_content2), include2, 0022, TRUE));
582 }
583 END_SETUP
584
585 START_TEARDOWN(teardown_include_config)
586 {
587 settings->destroy(settings);
588 unlink(include2);
589 unlink(include1);
590 unlink(path);
591 }
592 END_TEARDOWN
593
594 static void verify_include()
595 {
596 verify_string("n1", "main.key1");
597 verify_string("v2", "main.key2");
598 verify_string("val3", "main.key3");
599 verify_string("val", "main.sub1.key");
600 verify_string("v2", "main.sub1.key2");
601 verify_string("val", "main.sub1.sub1.key");
602 verify_string("value", "main.sub1.key3");
603 verify_string("value", "main.sub1.include");
604 verify_string("val3", "main.sub2.sub3");
605
606 verify_null("main.none");
607 }
608
609 START_TEST(test_include)
610 {
611 chunk_t contents = chunk_from_str(
612 "main {\n"
613 " key1 = val1\n"
614 " key2 = val2\n"
615 " none = x\n"
616 " sub1 {\n"
617 " include this/does/not/exist.conf\n"
618 " include = value\n"
619 " key2 = value2\n"
620 " include " include2 "\n"
621 " }\n"
622 "}\n"
623 "include " include1);
624
625 create_settings(contents);
626 verify_include();
627 }
628 END_TEST
629
630 START_TEST(test_include_string)
631 {
632 chunk_t contents = chunk_from_str(
633 "main {\n"
634 " key1 = val1\n"
635 " key2 = val2\n"
636 " none = x\n"
637 " sub1 {\n"
638 " include this/does/not/exist.conf\n"
639 " include = value\n"
640 " key2 = value2\n"
641 " include \"" include2 "\"\n"
642 " }\n"
643 "}\n"
644 "include \"" include1 "\"");
645
646 create_settings(contents);
647 verify_include();
648 }
649 END_TEST
650
651 START_TEST(test_load_files)
652 {
653 chunk_t contents = chunk_from_str(
654 "main {\n"
655 " key1 = val1\n"
656 " key2 = val2\n"
657 " key3 = val3\n"
658 " none = x\n"
659 " sub1 {\n"
660 " include = value\n"
661 " key2 = v2\n"
662 " sub1 {\n"
663 " key = val\n"
664 " }\n"
665 " }\n"
666 "}");
667 char *val1, *val2, *val3;
668
669 create_settings(contents);
670
671 val1 = settings->get_str(settings, "main.key1", NULL);
672 val2 = settings->get_str(settings, "main.sub1.key2", NULL);
673 /* loading the same file twice should not change anything, with... */
674 ck_assert(settings->load_files(settings, path, TRUE));
675 ck_assert(val1 == settings->get_str(settings, "main.key1", NULL));
676 ck_assert(val2 == settings->get_str(settings, "main.sub1.key2", NULL));
677 /* ...or without merging */
678 ck_assert(settings->load_files(settings, path, FALSE));
679 ck_assert(val1 == settings->get_str(settings, "main.key1", NULL));
680 ck_assert(val2 == settings->get_str(settings, "main.sub1.key2", NULL));
681
682 val1 = settings->get_str(settings, "main.key2", NULL);
683 val2 = settings->get_str(settings, "main.key3", NULL);
684 val3 = settings->get_str(settings, "main.none", NULL);
685 /* only pointers for modified settings should change, but still be valid */
686 ck_assert(settings->load_files(settings, include1, FALSE));
687 ck_assert(val1 != settings->get_str(settings, "main.key2", NULL));
688 ck_assert_str_eq(val1, "val2");
689 ck_assert(val2 == settings->get_str(settings, "main.key3", NULL));
690 ck_assert(val3 != settings->get_str(settings, "main.none", NULL));
691 ck_assert_str_eq(val3, "x");
692
693 settings->destroy(settings);
694 create_settings(contents);
695
696 ck_assert(settings->load_files(settings, include1, TRUE));
697 verify_include();
698
699 ck_assert(settings->load_files(settings, include2, FALSE));
700 verify_null("main.key1");
701 verify_string("v2", "key2");
702 verify_string("val", "sub1.key");
703 verify_null("main.sub1.key3");
704 }
705 END_TEST
706
707 START_TEST(test_load_files_section)
708 {
709 chunk_t contents = chunk_from_str(
710 "main {\n"
711 " key1 = val1\n"
712 " key2 = val2\n"
713 " none = x\n"
714 " sub1 {\n"
715 " include = value\n"
716 " key2 = value2\n"
717 " }\n"
718 "}");
719
720 create_settings(contents);
721
722 ck_assert(settings->load_files_section(settings, include1, TRUE, ""));
723 ck_assert(settings->load_files_section(settings, include2, TRUE, "main.sub1"));
724 verify_include();
725
726 /* non existing files are a failure here */
727 ck_assert(!settings->load_files_section(settings, include1".conf", TRUE, ""));
728 verify_include();
729
730 #ifndef WIN32
731 /* unreadable files are too (only fails when not running as root) */
732 if (getuid() != 0)
733 {
734 ck_assert(chunk_write(contents, include1".no", 0444, TRUE));
735 ck_assert(!settings->load_files_section(settings, include1".no", TRUE, ""));
736 unlink(include1".no");
737 verify_include();
738 }
739 #endif
740
741 ck_assert(settings->load_files_section(settings, include2, FALSE, "main"));
742 verify_null("main.key1");
743 verify_string("v2", "main.key2");
744 verify_string("val", "main.sub1.key");
745 verify_null("main.sub1.key3");
746 verify_null("main.sub2.sub3");
747
748 ck_assert(settings->load_files_section(settings, include2, TRUE, "main.sub2"));
749 verify_string("v2", "main.sub2.key2");
750 verify_string("val", "main.sub2.sub1.key");
751 }
752 END_TEST
753
754 START_TEST(test_order_kv)
755 {
756 chunk_t base = chunk_from_str(
757 "main {\n"
758 " key1 = val1\n"
759 " key2 = val2\n"
760 " key3 = val3\n"
761 "}");
762 chunk_t include = chunk_from_str(
763 "main {\n"
764 " key0 = val0\n"
765 " key3 = val3\n"
766 " key1 = val1\n"
767 "}");
768 linked_list_t *keys, *values;
769
770 create_settings(base);
771 ck_assert(chunk_write(include, include1, 0022, TRUE));
772
773 keys = linked_list_create_with_items("key1", "key2", "key3", NULL);
774 values = linked_list_create_with_items("val1", "val2", "val3", NULL);
775 verify_key_values(keys, values, "main");
776
777 /* the original order is maintained if the settings are merged */
778 ck_assert(settings->load_files(settings, include1, TRUE));
779 keys = linked_list_create_with_items("key1", "key2", "key3", "key0", NULL);
780 values = linked_list_create_with_items("val1", "val2", "val3", "val0", NULL);
781 verify_key_values(keys, values, "main");
782
783 /* but the new order is adopted if the settings are replaced */
784 ck_assert(settings->load_files(settings, include1, FALSE));
785 keys = linked_list_create_with_items("key0", "key3", "key1", NULL);
786 values = linked_list_create_with_items("val0", "val3", "val1", NULL);
787 verify_key_values(keys, values, "main");
788
789 unlink(include1);
790 }
791 END_TEST
792
793 START_TEST(test_order_section)
794 {
795 chunk_t base = chunk_from_str(
796 "main {\n"
797 " sub1 {\n"
798 " }\n"
799 " sub2 {\n"
800 " }\n"
801 " sub3 {\n"
802 " }\n"
803 "}");
804 chunk_t include = chunk_from_str(
805 "main {\n"
806 " sub0 {\n"
807 " }\n"
808 " sub3 {\n"
809 " }\n"
810 " sub1 {\n"
811 " }\n"
812 "}");
813 linked_list_t *sections;
814
815 create_settings(base);
816 ck_assert(chunk_write(include, include1, 0022, TRUE));
817
818 sections = linked_list_create_with_items("sub1", "sub2", "sub3", NULL);
819 verify_sections(sections, "main");
820
821 /* the original order is maintained if the settings are merged */
822 ck_assert(settings->load_files(settings, include1, TRUE));
823 sections = linked_list_create_with_items("sub1", "sub2", "sub3", "sub0", NULL);
824 verify_sections(sections, "main");
825
826 /* but the new order is adopted if the settings are replaced */
827 ck_assert(settings->load_files(settings, include1, FALSE));
828 sections = linked_list_create_with_items("sub0", "sub3", "sub1", NULL);
829 verify_sections(sections, "main");
830
831 unlink(include1);
832 }
833 END_TEST
834
835
836 START_TEST(test_load_string)
837 {
838 char *content =
839 "main {\n"
840 " key1 = val1\n"
841 " key2 = val2\n"
842 " key3 = val3\n"
843 " none = x\n"
844 " sub1 {\n"
845 " include = value\n"
846 " key2 = v2\n"
847 " sub1 {\n"
848 " key = val\n"
849 " }\n"
850 " }\n"
851 "}";
852 char *val1, *val2, *val3;
853
854 settings = settings_create_string(content);
855
856 val1 = settings->get_str(settings, "main.key1", NULL);
857 val2 = settings->get_str(settings, "main.sub1.key2", NULL);
858 /* loading the same content twice should not change anything, with... */
859 ck_assert(settings->load_string(settings, content, TRUE));
860 ck_assert(val1 == settings->get_str(settings, "main.key1", NULL));
861 ck_assert(val2 == settings->get_str(settings, "main.sub1.key2", NULL));
862 /* ...or without merging */
863 ck_assert(settings->load_string(settings, content, FALSE));
864 ck_assert(val1 == settings->get_str(settings, "main.key1", NULL));
865 ck_assert(val2 == settings->get_str(settings, "main.sub1.key2", NULL));
866
867 val1 = settings->get_str(settings, "main.key2", NULL);
868 val2 = settings->get_str(settings, "main.key3", NULL);
869 val3 = settings->get_str(settings, "main.none", NULL);
870 /* only pointers for modified settings should change, but still be valid */
871 ck_assert(settings->load_string(settings, include_content1, FALSE));
872 ck_assert(val1 != settings->get_str(settings, "main.key2", NULL));
873 ck_assert_str_eq(val1, "val2");
874 ck_assert(val2 == settings->get_str(settings, "main.key3", NULL));
875 ck_assert(val3 != settings->get_str(settings, "main.none", NULL));
876 ck_assert_str_eq(val3, "x");
877
878 settings->destroy(settings);
879 settings = settings_create_string(content);
880 ck_assert(settings);
881
882 ck_assert(settings->load_string(settings, include_content1, TRUE));
883 verify_include();
884
885 ck_assert(settings->load_string(settings, include_content2, FALSE));
886 verify_null("main.key1");
887 verify_string("v2", "key2");
888 verify_string("val", "sub1.key");
889 verify_null("main.sub1.key3");
890 }
891 END_TEST
892
893
894 START_TEST(test_load_string_section)
895 {
896 char *content =
897 "main {\n"
898 " key1 = val1\n"
899 " key2 = val2\n"
900 " none = x\n"
901 " sub1 {\n"
902 " include = value\n"
903 " key2 = value2\n"
904 " }\n"
905 "}";
906
907 settings = settings_create_string(content);
908
909 ck_assert(settings->load_string_section(settings, include_content1, TRUE, ""));
910 ck_assert(settings->load_string_section(settings, include_content2, TRUE, "main.sub1"));
911 verify_include();
912
913 /* invalid strings are a failure */
914 ck_assert(!settings->load_string_section(settings, "conf {", TRUE, ""));
915 /* NULL or empty strings are OK though */
916 ck_assert(settings->load_string_section(settings, "", TRUE, ""));
917 ck_assert(settings->load_string_section(settings, NULL, TRUE, ""));
918 verify_include();
919
920 ck_assert(settings->load_string_section(settings, include_content2, FALSE, "main"));
921 verify_null("main.key1");
922 verify_string("v2", "main.key2");
923 verify_string("val", "main.sub1.key");
924 verify_null("main.sub1.key3");
925 verify_null("main.sub2.sub3");
926
927 ck_assert(settings->load_string_section(settings, include_content2, TRUE, "main.sub2"));
928 verify_string("v2", "main.sub2.key2");
929 verify_string("val", "main.sub2.sub1.key");
930 }
931 END_TEST
932
933 START_SETUP(setup_fallback_config)
934 {
935 create_settings(chunk_from_str(
936 "main {\n"
937 " key1 = val1\n"
938 " sub1 {\n"
939 " key1 = val1\n"
940 " }\n"
941 "}\n"
942 "sub {\n"
943 " key1 = subval1\n"
944 " key2 = subval2\n"
945 " subsub {\n"
946 " subkey1 = subsubval1\n"
947 " }\n"
948 "}\n"
949 "base {\n"
950 " key1 = baseval1\n"
951 " key2 = baseval2\n"
952 " sub1 {\n"
953 " key1 = subbase1\n"
954 " key2 = subbase2\n"
955 " key3 = subbase3\n"
956 " subsub {\n"
957 " subkey1 = subsubbaseval1\n"
958 " subkey2 = subsubbaseval2\n"
959 " }\n"
960 " }\n"
961 " sub2 {\n"
962 " key4 = subbase4\n"
963 " }\n"
964 "}"));
965 }
966 END_SETUP
967
968 START_TEST(test_add_fallback)
969 {
970 linked_list_t *keys, *values;
971
972 settings->add_fallback(settings, "main.sub1", "sub");
973 verify_string("val1", "main.sub1.key1");
974 verify_string("subval2", "main.sub1.key2");
975 verify_string("subsubval1", "main.sub1.subsub.subkey1");
976
977 /* fallbacks are preserved even if the complete config is replaced */
978 settings->load_files(settings, path, FALSE);
979 verify_string("val1", "main.sub1.key1");
980 verify_string("subval2", "main.sub1.key2");
981 verify_string("subsubval1", "main.sub1.subsub.subkey1");
982
983 keys = linked_list_create_with_items("sub1", NULL);
984 verify_sections(keys, "main");
985 keys = linked_list_create_with_items("subsub", NULL);
986 verify_sections(keys, "main.sub1");
987
988 keys = linked_list_create_with_items("key1", NULL);
989 values = linked_list_create_with_items("val1", NULL);
990 verify_key_values(keys, values, "main");
991
992 keys = linked_list_create_with_items("key1", "key2", NULL);
993 values = linked_list_create_with_items("val1", "subval2", NULL);
994 verify_key_values(keys, values, "main.sub1");
995
996 keys = linked_list_create_with_items("subkey1", NULL);
997 values = linked_list_create_with_items("subsubval1", NULL);
998 verify_key_values(keys, values, "main.sub1.subsub");
999
1000 settings->add_fallback(settings, "main", "base");
1001 verify_string("val1", "main.key1");
1002 verify_string("baseval2", "main.key2");
1003 verify_string("val1", "main.sub1.key1");
1004 verify_string("subval2", "main.sub1.key2");
1005 verify_string("subsubval1", "main.sub1.subsub.subkey1");
1006 verify_string("subsubbaseval2", "main.sub1.subsub.subkey2");
1007 verify_string("subbase3", "main.sub1.key3");
1008 verify_string("subbase4", "main.sub2.key4");
1009
1010
1011 keys = linked_list_create_with_items("sub1", "sub2", NULL);
1012 verify_sections(keys, "main");
1013 keys = linked_list_create_with_items("subsub", NULL);
1014 verify_sections(keys, "main.sub1");
1015
1016 keys = linked_list_create_with_items("key1", "key2", NULL);
1017 values = linked_list_create_with_items("val1", "baseval2", NULL);
1018 verify_key_values(keys, values, "main");
1019
1020 keys = linked_list_create_with_items("key1", "key2", "key3", NULL);
1021 values = linked_list_create_with_items("val1", "subval2", "subbase3", NULL);
1022 verify_key_values(keys, values, "main.sub1");
1023
1024 keys = linked_list_create_with_items("subkey1", "subkey2", NULL);
1025 values = linked_list_create_with_items("subsubval1", "subsubbaseval2", NULL);
1026 verify_key_values(keys, values, "main.sub1.subsub");
1027
1028 settings->set_str(settings, "main.sub1.key2", "val2");
1029 verify_string("val2", "main.sub1.key2");
1030 settings->set_str(settings, "main.sub1.subsub.subkey2", "val2");
1031 verify_string("val2", "main.sub1.subsub.subkey2");
1032 verify_string("subsubval1", "main.sub1.subsub.subkey1");
1033 }
1034 END_TEST
1035
1036 START_TEST(test_add_fallback_printf)
1037 {
1038 settings->add_fallback(settings, "%s.sub1", "sub", "main");
1039 verify_string("val1", "main.sub1.key1");
1040 verify_string("subval2", "main.sub1.key2");
1041 verify_string("subsubval1", "main.sub1.subsub.subkey1");
1042
1043 settings->add_fallback(settings, "%s.%s2", "%s.%s1", "main", "sub");
1044 verify_string("val1", "main.sub2.key1");
1045 verify_string("subval2", "main.sub2.key2");
1046 verify_string("subsubval1", "main.sub2.subsub.subkey1");
1047 }
1048 END_TEST
1049
1050 START_SETUP(setup_string_config)
1051 {
1052 create_settings(chunk_from_str(
1053 "string = \" with accurate\twhite\\tspace\"\n"
1054 "special = \"all { special } characters # can be used.\"\n"
1055 "newlines = \"can be encoded explicitly\\nor implicitly\n"
1056 "or \\\n"
1057 "escaped\"\n"
1058 "quotes = \"\\\"and\\\" slashes \\\\ can \\\\ be\" # escaped too\n"
1059 "multiple = \"strings\" are \"combined\"\n"
1060 ));
1061 }
1062 END_SETUP
1063
1064 START_TEST(test_strings)
1065 {
1066 verify_string(" with accurate\twhite\tspace", "string");
1067 verify_string("all { special } characters # can be used.", "special");
1068 verify_string("can be encoded explicitly\nor implicitly\nor escaped", "newlines");
1069 verify_string("\"and\" slashes \\ can \\ be", "quotes");
1070 verify_string("strings are combined", "multiple");
1071 }
1072 END_TEST
1073
1074 START_TEST(test_valid)
1075 {
1076 chunk_t contents;
1077
1078 contents = chunk_from_str(
1079 "single = value");
1080 ck_assert(chunk_write(contents, path, 0022, TRUE));
1081 ck_assert(settings->load_files(settings, path, FALSE));
1082 verify_string("value", "single");
1083
1084 contents = chunk_from_str(
1085 "singleline { single = value }");
1086 ck_assert(chunk_write(contents, path, 0022, TRUE));
1087 ck_assert(settings->load_files(settings, path, FALSE));
1088 verify_string("value", "singleline.single");
1089
1090 contents = chunk_from_str(
1091 "singleline { sub { sub1 = val1 } single = value }");
1092 ck_assert(chunk_write(contents, path, 0022, TRUE));
1093 ck_assert(settings->load_files(settings, path, FALSE));
1094 verify_string("val1", "singleline.sub.sub1");
1095
1096 contents = chunk_from_str(
1097 "newline\n { single = value }");
1098 ck_assert(chunk_write(contents, path, 0022, TRUE));
1099 ck_assert(settings->load_files(settings, path, FALSE));
1100 verify_string("value", "newline.single");
1101
1102 contents = chunk_from_str(
1103 "section {\n"
1104 " include # without pattern produces a warning, but is fine\n"
1105 "}\n");
1106 ck_assert(chunk_write(contents, path, 0022, TRUE));
1107 ck_assert(settings->load_files(settings, path, FALSE));
1108 }
1109 END_TEST
1110
1111 START_TEST(test_invalid)
1112 {
1113 chunk_t contents;
1114
1115 contents = chunk_from_str(
1116 "{\n"
1117 " no = section name\n"
1118 "}\n");
1119 ck_assert(chunk_write(contents, path, 0022, TRUE));
1120 ck_assert(!settings->load_files(settings, path, FALSE));
1121
1122 contents = chunk_from_str(
1123 "no {\n"
1124 " = key name\n"
1125 "}\n");
1126 ck_assert(chunk_write(contents, path, 0022, TRUE));
1127 ck_assert(!settings->load_files(settings, path, FALSE));
1128
1129 contents = chunk_from_str(
1130 "unterminated {\n"
1131 " not = valid\n");
1132 ck_assert(chunk_write(contents, path, 0022, TRUE));
1133 ck_assert(!settings->load_files(settings, path, FALSE));
1134
1135 contents = chunk_from_str(
1136 "unterminated {\n"
1137 " strings = \"are invalid\n");
1138 ck_assert(chunk_write(contents, path, 0022, TRUE));
1139 ck_assert(!settings->load_files(settings, path, FALSE));
1140
1141 contents = chunk_from_str(
1142 "spaces in name {}");
1143 ck_assert(chunk_write(contents, path, 0022, TRUE));
1144 ck_assert(!settings->load_files(settings, path, FALSE));
1145
1146 contents = chunk_from_str(
1147 "only = a single setting = per line");
1148 ck_assert(chunk_write(contents, path, 0022, TRUE));
1149 ck_assert(!settings->load_files(settings, path, FALSE));
1150 }
1151 END_TEST
1152
1153 Suite *settings_suite_create()
1154 {
1155 Suite *s;
1156 TCase *tc;
1157
1158 s = suite_create("settings");
1159
1160 tc = tcase_create("get/set_str (basic behavior)");
1161 tcase_add_checked_fixture(tc, setup_base_config, teardown_config);
1162 tcase_add_test(tc, test_get_str);
1163 tcase_add_test(tc, test_get_str_printf);
1164 tcase_add_test(tc, test_set_str);
1165 tcase_add_test(tc, test_set_str_printf);
1166 tcase_add_test(tc, test_set_default_str);
1167 suite_add_tcase(s, tc);
1168
1169 tc = tcase_create("get/set_bool");
1170 tcase_add_checked_fixture(tc, setup_bool_config, teardown_config);
1171 tcase_add_test(tc, test_get_bool);
1172 tcase_add_test(tc, test_set_bool);
1173 suite_add_tcase(s, tc);
1174
1175 tc = tcase_create("get/set_int");
1176 tcase_add_checked_fixture(tc, setup_int_config, teardown_config);
1177 tcase_add_test(tc, test_get_int);
1178 tcase_add_test(tc, test_set_int);
1179 suite_add_tcase(s, tc);
1180
1181 tc = tcase_create("settings_value_as_uint64");
1182 tcase_add_test(tc, test_value_as_unit64);
1183 suite_add_tcase(s, tc);
1184
1185 tc = tcase_create("get/set_double");
1186 tcase_add_checked_fixture(tc, setup_double_config, teardown_config);
1187 tcase_add_test(tc, test_get_double);
1188 tcase_add_test(tc, test_set_double);
1189 suite_add_tcase(s, tc);
1190
1191 tc = tcase_create("get/set_time");
1192 tcase_add_checked_fixture(tc, setup_time_config, teardown_config);
1193 tcase_add_test(tc, test_get_time);
1194 tcase_add_test(tc, test_set_time);
1195 suite_add_tcase(s, tc);
1196
1197 tc = tcase_create("section enumerator");
1198 tcase_add_checked_fixture(tc, setup_base_config, teardown_config);
1199 tcase_add_test(tc, test_section_enumerator);
1200 suite_add_tcase(s, tc);
1201
1202 tc = tcase_create("key/value enumerator");
1203 tcase_add_checked_fixture(tc, setup_base_config, teardown_config);
1204 tcase_add_test(tc, test_key_value_enumerator);
1205 suite_add_tcase(s, tc);
1206
1207 tc = tcase_create("include/load_files[_section]");
1208 tcase_add_checked_fixture(tc, setup_include_config, teardown_include_config);
1209 tcase_add_test(tc, test_include);
1210 tcase_add_test(tc, test_include_string);
1211 tcase_add_test(tc, test_load_files);
1212 tcase_add_test(tc, test_load_files_section);
1213 tcase_add_test(tc, test_order_kv);
1214 tcase_add_test(tc, test_order_section);
1215 suite_add_tcase(s, tc);
1216
1217 tc = tcase_create("load_string[_section]");
1218 tcase_add_checked_fixture(tc, setup_include_config, teardown_config);
1219 tcase_add_test(tc, test_load_string);
1220 tcase_add_test(tc, test_load_string_section);
1221 suite_add_tcase(s, tc);
1222
1223 tc = tcase_create("fallback");
1224 tcase_add_checked_fixture(tc, setup_fallback_config, teardown_config);
1225 tcase_add_test(tc, test_add_fallback);
1226 tcase_add_test(tc, test_add_fallback_printf);
1227 suite_add_tcase(s, tc);
1228
1229 tc = tcase_create("strings");
1230 tcase_add_checked_fixture(tc, setup_string_config, teardown_config);
1231 tcase_add_test(tc, test_strings);
1232 suite_add_tcase(s, tc);
1233
1234 tc = tcase_create("valid/invalid data");
1235 tcase_add_checked_fixture(tc, setup_base_config, teardown_config);
1236 tcase_add_test(tc, test_valid);
1237 tcase_add_test(tc, test_invalid);
1238 suite_add_tcase(s, tc);
1239
1240 return s;
1241 }