Annotation of embedaddon/strongswan/src/libstrongswan/tests/suites/test_settings.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (C) 2014-2018 Tobias Brunner
3: * HSR 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, §ion))
456: {
457: ck_assert_msg(ver->enumerate(ver, ¤t),
458: "no more sections expected, found %s", section);
459: ck_assert_str_eq(section, current);
460: verifier->remove_at(verifier, ver);
461: }
462: enumerator->destroy(enumerator);
463: ver->destroy(ver);
464: ck_assert_int_eq(0, verifier->get_count(verifier));
465: verifier->destroy(verifier);
466: }
467:
468: START_TEST(test_section_enumerator)
469: {
470: linked_list_t *verifier;
471:
472: verifier = linked_list_create_with_items("sub1", "sub%", NULL);
473: verify_sections(verifier, "main");
474:
475: settings->set_str(settings, "main.sub0.new", "added");
476: verifier = linked_list_create_with_items("sub1", "sub%", "sub0", NULL);
477: verify_sections(verifier, "main");
478:
479: verifier = linked_list_create_with_items("subsub", NULL);
480: verify_sections(verifier, "main.sub1");
481:
482: verifier = linked_list_create_with_items(NULL);
483: verify_sections(verifier, "main.sub%%");
484:
485: verifier = linked_list_create_with_items(NULL);
486: verify_sections(verifier, "main.key1");
487:
488: verifier = linked_list_create_with_items(NULL);
489: verify_sections(verifier, "main.unknown");
490: }
491: END_TEST
492:
493: static void verify_key_values(linked_list_t *keys, linked_list_t *values,
494: char *parent)
495: {
496: enumerator_t *enumerator, *enum_keys, *enum_values;
497: char *key, *value, *current_key, *current_value;
498:
499: enumerator = settings->create_key_value_enumerator(settings, parent);
500: enum_keys = keys->create_enumerator(keys);
501: enum_values = values->create_enumerator(values);
502: while (enumerator->enumerate(enumerator, &key, &value))
503: {
504: ck_assert_msg(enum_keys->enumerate(enum_keys, ¤t_key),
505: "no more key/value expected, found %s = %s", key, value);
506: ck_assert(enum_values->enumerate(enum_values, ¤t_value));
507: ck_assert_str_eq(current_key, key);
508: ck_assert_str_eq(current_value, value);
509: keys->remove_at(keys, enum_keys);
510: values->remove_at(values, enum_values);
511: }
512: enumerator->destroy(enumerator);
513: enum_keys->destroy(enum_keys);
514: enum_values->destroy(enum_values);
515: ck_assert_int_eq(0, keys->get_count(keys));
516: keys->destroy(keys);
517: values->destroy(values);
518: }
519:
520: START_TEST(test_key_value_enumerator)
521: {
522: linked_list_t *keys, *values;
523:
524: keys = linked_list_create_with_items("key1", "key2", "empty", "key3", "key4", "key5", NULL);
525: values = linked_list_create_with_items("val1", "with space", "", "string with\nnewline", "multi line\nstring", "escaped newline", NULL);
526: verify_key_values(keys, values, "main");
527:
528: keys = linked_list_create_with_items("key", "key2", "subsub", NULL);
529: values = linked_list_create_with_items("value", "value2", "section value", NULL);
530: verify_key_values(keys, values, "main.sub1");
531:
532: settings->set_str(settings, "main.sub2.new", "added");
533: keys = linked_list_create_with_items("new", NULL);
534: values = linked_list_create_with_items("added", NULL);
535: verify_key_values(keys, values, "main.sub2");
536:
537: keys = linked_list_create_with_items(NULL);
538: values = linked_list_create_with_items(NULL);
539: verify_key_values(keys, values, "other.empty");
540:
541: settings->set_str(settings, "other.empty.new", "added");
542: keys = linked_list_create_with_items("new", NULL);
543: values = linked_list_create_with_items("added", NULL);
544: verify_key_values(keys, values, "other.empty");
545:
546: keys = linked_list_create_with_items(NULL);
547: values = linked_list_create_with_items(NULL);
548: verify_key_values(keys, values, "main.unknown");
549: }
550: END_TEST
551:
552: #ifdef WIN32
553: # define include1 "C:\\Windows\\Temp\\strongswan-settings-test-include1"
554: # define include1_str "C:\\\\Windows\\\\Temp\\\\strongswan-settings-test-include1"
555: # define include2 "C:\\Windows\\Temp\\strongswan-settings-test-include2"
556: # define include2_str "C:\\\\Windows\\\\Temp\\\\strongswan-settings-test-include2"
557: #else
558: # define include1 "/tmp/strongswan-settings-test-include1"
559: # define include1_str include1
560: # define include2 "/tmp/strongswan-settings-test-include2"
561: # define include2_str include2
562: #endif
563:
564: static char *include_content1 =
565: "main {\n"
566: " key1 = n1\n"
567: " key2 = n2\n"
568: " key3 = val3\n"
569: " none = \n"
570: " sub1 {\n"
571: " key3 = value\n"
572: " }\n"
573: " sub2 {\n"
574: " sub3 = val3\n"
575: " }\n"
576: " include " include2 "\n"
577: "}";
578: static char *include_content2 =
579: "key2 = v2\n"
580: "sub1 {\n"
581: " key = val\n"
582: "}";
583:
584: START_SETUP(setup_include_config)
585: {
586: ck_assert(chunk_write(chunk_from_str(include_content1), include1, 0022, TRUE));
587: ck_assert(chunk_write(chunk_from_str(include_content2), include2, 0022, TRUE));
588: }
589: END_SETUP
590:
591: START_TEARDOWN(teardown_include_config)
592: {
593: settings->destroy(settings);
594: unlink(include2);
595: unlink(include1);
596: unlink(path);
597: }
598: END_TEARDOWN
599:
600: static void verify_include()
601: {
602: verify_string("n1", "main.key1");
603: verify_string("v2", "main.key2");
604: verify_string("val3", "main.key3");
605: verify_string("val", "main.sub1.key");
606: verify_string("v2", "main.sub1.key2");
607: verify_string("val", "main.sub1.sub1.key");
608: verify_string("value", "main.sub1.key3");
609: verify_string("value", "main.sub1.include");
610: verify_string("val3", "main.sub2.sub3");
611:
612: verify_null("main.none");
613: }
614:
615: START_TEST(test_include)
616: {
617: chunk_t contents = chunk_from_str(
618: "main {\n"
619: " key1 = val1\n"
620: " key2 = val2\n"
621: " none = x\n"
622: " sub1 {\n"
623: " include this/does/not/exist.conf\n"
624: " include = value\n"
625: " key2 = value2\n"
626: " include " include2 "\n"
627: " }\n"
628: "}\n"
629: "include " include1);
630:
631: create_settings(contents);
632: verify_include();
633: }
634: END_TEST
635:
636: START_TEST(test_include_string)
637: {
638: chunk_t contents = chunk_from_str(
639: "main {\n"
640: " key1 = val1\n"
641: " key2 = val2\n"
642: " none = x\n"
643: " sub1 {\n"
644: " include this/does/not/exist.conf\n"
645: " include = value\n"
646: " key2 = value2\n"
647: " include \"" include2_str "\"\n"
648: " }\n"
649: "}\n"
650: "include \"" include1_str "\"");
651:
652: create_settings(contents);
653: verify_include();
654: }
655: END_TEST
656:
657: START_TEST(test_load_files)
658: {
659: chunk_t contents = chunk_from_str(
660: "main {\n"
661: " key1 = val1\n"
662: " key2 = val2\n"
663: " key3 = val3\n"
664: " none = x\n"
665: " sub1 {\n"
666: " include = value\n"
667: " key2 = v2\n"
668: " sub1 {\n"
669: " key = val\n"
670: " }\n"
671: " }\n"
672: "}");
673: char *val1, *val2, *val3;
674:
675: create_settings(contents);
676:
677: val1 = settings->get_str(settings, "main.key1", NULL);
678: val2 = settings->get_str(settings, "main.sub1.key2", NULL);
679: /* loading the same file twice should not change anything, with... */
680: ck_assert(settings->load_files(settings, path, TRUE));
681: ck_assert(val1 == settings->get_str(settings, "main.key1", NULL));
682: ck_assert(val2 == settings->get_str(settings, "main.sub1.key2", NULL));
683: /* ...or without merging */
684: ck_assert(settings->load_files(settings, path, FALSE));
685: ck_assert(val1 == settings->get_str(settings, "main.key1", NULL));
686: ck_assert(val2 == settings->get_str(settings, "main.sub1.key2", NULL));
687:
688: val1 = settings->get_str(settings, "main.key2", NULL);
689: val2 = settings->get_str(settings, "main.key3", NULL);
690: val3 = settings->get_str(settings, "main.none", NULL);
691: /* only pointers for modified settings should change, but still be valid */
692: ck_assert(settings->load_files(settings, include1, FALSE));
693: ck_assert(val1 != settings->get_str(settings, "main.key2", NULL));
694: ck_assert_str_eq(val1, "val2");
695: ck_assert(val2 == settings->get_str(settings, "main.key3", NULL));
696: ck_assert(val3 != settings->get_str(settings, "main.none", NULL));
697: ck_assert_str_eq(val3, "x");
698:
699: settings->destroy(settings);
700: create_settings(contents);
701:
702: ck_assert(settings->load_files(settings, include1, TRUE));
703: verify_include();
704:
705: ck_assert(settings->load_files(settings, include2, FALSE));
706: verify_null("main.key1");
707: verify_string("v2", "key2");
708: verify_string("val", "sub1.key");
709: verify_null("main.sub1.key3");
710: }
711: END_TEST
712:
713: START_TEST(test_load_files_section)
714: {
715: chunk_t contents = chunk_from_str(
716: "main {\n"
717: " key1 = val1\n"
718: " key2 = val2\n"
719: " none = x\n"
720: " sub1 {\n"
721: " include = value\n"
722: " key2 = value2\n"
723: " }\n"
724: "}");
725:
726: create_settings(contents);
727:
728: ck_assert(settings->load_files_section(settings, include1, TRUE, ""));
729: ck_assert(settings->load_files_section(settings, include2, TRUE, "main.sub1"));
730: verify_include();
731:
732: /* non existing files are a failure here */
733: ck_assert(!settings->load_files_section(settings, include1".conf", TRUE, ""));
734: verify_include();
735:
736: #ifndef WIN32
737: /* unreadable files are too (only fails when not running as root) */
738: if (getuid() != 0)
739: {
740: ck_assert(chunk_write(contents, include1".no", 0444, TRUE));
741: ck_assert(!settings->load_files_section(settings, include1".no", TRUE, ""));
742: unlink(include1".no");
743: verify_include();
744: }
745: #endif
746:
747: ck_assert(settings->load_files_section(settings, include2, FALSE, "main"));
748: verify_null("main.key1");
749: verify_string("v2", "main.key2");
750: verify_string("val", "main.sub1.key");
751: verify_null("main.sub1.key3");
752: verify_null("main.sub2.sub3");
753:
754: ck_assert(settings->load_files_section(settings, include2, TRUE, "main.sub2"));
755: verify_string("v2", "main.sub2.key2");
756: verify_string("val", "main.sub2.sub1.key");
757: }
758: END_TEST
759:
760: START_TEST(test_order_kv)
761: {
762: chunk_t base = chunk_from_str(
763: "main {\n"
764: " key1 = val1\n"
765: " key2 = val2\n"
766: " key3 = val3\n"
767: "}");
768: chunk_t include = chunk_from_str(
769: "main {\n"
770: " key0 = val0\n"
771: " key3 = val3\n"
772: " key1 = val1\n"
773: "}");
774: linked_list_t *keys, *values;
775:
776: create_settings(base);
777: ck_assert(chunk_write(include, include1, 0022, TRUE));
778:
779: keys = linked_list_create_with_items("key1", "key2", "key3", NULL);
780: values = linked_list_create_with_items("val1", "val2", "val3", NULL);
781: verify_key_values(keys, values, "main");
782:
783: /* the original order is maintained if the settings are merged */
784: ck_assert(settings->load_files(settings, include1, TRUE));
785: keys = linked_list_create_with_items("key1", "key2", "key3", "key0", NULL);
786: values = linked_list_create_with_items("val1", "val2", "val3", "val0", NULL);
787: verify_key_values(keys, values, "main");
788:
789: /* but the new order is adopted if the settings are replaced */
790: ck_assert(settings->load_files(settings, include1, FALSE));
791: keys = linked_list_create_with_items("key0", "key3", "key1", NULL);
792: values = linked_list_create_with_items("val0", "val3", "val1", NULL);
793: verify_key_values(keys, values, "main");
794:
795: unlink(include1);
796: }
797: END_TEST
798:
799: START_TEST(test_order_section)
800: {
801: chunk_t base = chunk_from_str(
802: "main {\n"
803: " sub1 {\n"
804: " }\n"
805: " sub2 {\n"
806: " }\n"
807: " sub3 {\n"
808: " }\n"
809: "}");
810: chunk_t include = chunk_from_str(
811: "main {\n"
812: " sub0 {\n"
813: " }\n"
814: " sub3 {\n"
815: " }\n"
816: " sub1 {\n"
817: " }\n"
818: "}");
819: linked_list_t *sections;
820:
821: create_settings(base);
822: ck_assert(chunk_write(include, include1, 0022, TRUE));
823:
824: sections = linked_list_create_with_items("sub1", "sub2", "sub3", NULL);
825: verify_sections(sections, "main");
826:
827: /* the original order is maintained if the settings are merged */
828: ck_assert(settings->load_files(settings, include1, TRUE));
829: sections = linked_list_create_with_items("sub1", "sub2", "sub3", "sub0", NULL);
830: verify_sections(sections, "main");
831:
832: /* but the new order is adopted if the settings are replaced */
833: ck_assert(settings->load_files(settings, include1, FALSE));
834: sections = linked_list_create_with_items("sub0", "sub3", "sub1", NULL);
835: verify_sections(sections, "main");
836:
837: unlink(include1);
838: }
839: END_TEST
840:
841:
842: START_TEST(test_load_string)
843: {
844: char *content =
845: "main {\n"
846: " key1 = val1\n"
847: " key2 = val2\n"
848: " key3 = val3\n"
849: " none = x\n"
850: " sub1 {\n"
851: " include = value\n"
852: " key2 = v2\n"
853: " sub1 {\n"
854: " key = val\n"
855: " }\n"
856: " }\n"
857: "}";
858: char *val1, *val2, *val3;
859:
860: settings = settings_create_string(content);
861:
862: val1 = settings->get_str(settings, "main.key1", NULL);
863: val2 = settings->get_str(settings, "main.sub1.key2", NULL);
864: /* loading the same content twice should not change anything, with... */
865: ck_assert(settings->load_string(settings, content, TRUE));
866: ck_assert(val1 == settings->get_str(settings, "main.key1", NULL));
867: ck_assert(val2 == settings->get_str(settings, "main.sub1.key2", NULL));
868: /* ...or without merging */
869: ck_assert(settings->load_string(settings, content, FALSE));
870: ck_assert(val1 == settings->get_str(settings, "main.key1", NULL));
871: ck_assert(val2 == settings->get_str(settings, "main.sub1.key2", NULL));
872:
873: val1 = settings->get_str(settings, "main.key2", NULL);
874: val2 = settings->get_str(settings, "main.key3", NULL);
875: val3 = settings->get_str(settings, "main.none", NULL);
876: /* only pointers for modified settings should change, but still be valid */
877: ck_assert(settings->load_string(settings, include_content1, FALSE));
878: ck_assert(val1 != settings->get_str(settings, "main.key2", NULL));
879: ck_assert_str_eq(val1, "val2");
880: ck_assert(val2 == settings->get_str(settings, "main.key3", NULL));
881: ck_assert(val3 != settings->get_str(settings, "main.none", NULL));
882: ck_assert_str_eq(val3, "x");
883:
884: settings->destroy(settings);
885: settings = settings_create_string(content);
886: ck_assert(settings);
887:
888: ck_assert(settings->load_string(settings, include_content1, TRUE));
889: verify_include();
890:
891: ck_assert(settings->load_string(settings, include_content2, FALSE));
892: verify_null("main.key1");
893: verify_string("v2", "key2");
894: verify_string("val", "sub1.key");
895: verify_null("main.sub1.key3");
896: }
897: END_TEST
898:
899: START_TEST(test_load_string_section)
900: {
901: char *content =
902: "main {\n"
903: " key1 = val1\n"
904: " key2 = val2\n"
905: " none = x\n"
906: " sub1 {\n"
907: " include = value\n"
908: " key2 = value2\n"
909: " }\n"
910: "}";
911:
912: settings = settings_create_string(content);
913:
914: ck_assert(settings->load_string_section(settings, include_content1, TRUE, ""));
915: ck_assert(settings->load_string_section(settings, include_content2, TRUE, "main.sub1"));
916: verify_include();
917:
918: ck_assert(settings->load_string_section(settings, include_content2, FALSE, "main"));
919: verify_null("main.key1");
920: verify_string("v2", "main.key2");
921: verify_string("val", "main.sub1.key");
922: verify_null("main.sub1.key3");
923: verify_null("main.sub2.sub3");
924:
925: ck_assert(settings->load_string_section(settings, include_content2, TRUE, "main.sub2"));
926: verify_string("v2", "main.sub2.key2");
927: verify_string("val", "main.sub2.sub1.key");
928: }
929: END_TEST
930:
931: START_TEST(test_load_string_section_null)
932: {
933: linked_list_t *keys, *values;
934:
935: char *content =
936: "main {\n"
937: " key1 = val1\n"
938: " key2 = val2\n"
939: " none = x\n"
940: " sub1 {\n"
941: " include = value\n"
942: " key2 = value2\n"
943: " }\n"
944: "}";
945:
946: settings = settings_create_string(content);
947:
948: ck_assert(settings->load_string_section(settings, include_content1, TRUE, ""));
949: ck_assert(settings->load_string_section(settings, include_content2, TRUE, "main.sub1"));
950: verify_include();
951:
952: /* invalid strings are a failure */
953: ck_assert(!settings->load_string_section(settings, "conf {", TRUE, ""));
954: /* NULL or empty strings are OK though when merging */
955: ck_assert(settings->load_string_section(settings, "", TRUE, ""));
956: ck_assert(settings->load_string_section(settings, NULL, TRUE, ""));
957: verify_include();
958:
959: /* they do purge the settings if merge is not TRUE */
960: ck_assert(settings->load_string_section(settings, "", FALSE, "main"));
961: verify_null("main.key1");
962: verify_null("main.sub1.key2");
963:
964: keys = linked_list_create_with_items(NULL);
965: verify_sections(keys, "main");
966:
967: keys = linked_list_create_with_items(NULL);
968: values = linked_list_create_with_items(NULL);
969: verify_key_values(keys, values, "main");
970:
971: keys = linked_list_create_with_items("main", NULL);
972: verify_sections(keys, "");
973:
974: ck_assert(settings->load_string_section(settings, NULL, FALSE, ""));
975:
976: keys = linked_list_create_with_items(NULL);
977: verify_sections(keys, "");
978: }
979: END_TEST
980:
981: START_SETUP(setup_fallback_config)
982: {
983: create_settings(chunk_from_str(
984: "main {\n"
985: " key1 = val1\n"
986: " sub1 {\n"
987: " key1 = val1\n"
988: " }\n"
989: "}\n"
990: "sub {\n"
991: " key1 = subval1\n"
992: " key2 = subval2\n"
993: " subsub {\n"
994: " subkey1 = subsubval1\n"
995: " }\n"
996: "}\n"
997: "base {\n"
998: " key1 = baseval1\n"
999: " key2 = baseval2\n"
1000: " sub1 {\n"
1001: " key1 = subbase1\n"
1002: " key2 = subbase2\n"
1003: " key3 = subbase3\n"
1004: " subsub {\n"
1005: " subkey1 = subsubbaseval1\n"
1006: " subkey2 = subsubbaseval2\n"
1007: " }\n"
1008: " }\n"
1009: " sub2 {\n"
1010: " key4 = subbase4\n"
1011: " }\n"
1012: "}"));
1013: }
1014: END_SETUP
1015:
1016: START_TEST(test_add_fallback)
1017: {
1018: linked_list_t *keys, *values;
1019:
1020: settings->add_fallback(settings, "main.sub1", "sub");
1021: verify_string("val1", "main.sub1.key1");
1022: verify_string("subval2", "main.sub1.key2");
1023: verify_string("subsubval1", "main.sub1.subsub.subkey1");
1024:
1025: /* fallbacks are preserved even if the complete config is replaced */
1026: settings->load_files(settings, path, FALSE);
1027: verify_string("val1", "main.sub1.key1");
1028: verify_string("subval2", "main.sub1.key2");
1029: verify_string("subsubval1", "main.sub1.subsub.subkey1");
1030:
1031: keys = linked_list_create_with_items("sub1", NULL);
1032: verify_sections(keys, "main");
1033: keys = linked_list_create_with_items("subsub", NULL);
1034: verify_sections(keys, "main.sub1");
1035:
1036: keys = linked_list_create_with_items("key1", NULL);
1037: values = linked_list_create_with_items("val1", NULL);
1038: verify_key_values(keys, values, "main");
1039:
1040: keys = linked_list_create_with_items("key1", "key2", NULL);
1041: values = linked_list_create_with_items("val1", "subval2", NULL);
1042: verify_key_values(keys, values, "main.sub1");
1043:
1044: keys = linked_list_create_with_items("subkey1", NULL);
1045: values = linked_list_create_with_items("subsubval1", NULL);
1046: verify_key_values(keys, values, "main.sub1.subsub");
1047:
1048: settings->add_fallback(settings, "main", "base");
1049: verify_string("val1", "main.key1");
1050: verify_string("baseval2", "main.key2");
1051: verify_string("val1", "main.sub1.key1");
1052: verify_string("subval2", "main.sub1.key2");
1053: verify_string("subsubval1", "main.sub1.subsub.subkey1");
1054: verify_string("subsubbaseval2", "main.sub1.subsub.subkey2");
1055: verify_string("subbase3", "main.sub1.key3");
1056: verify_string("subbase4", "main.sub2.key4");
1057:
1058:
1059: keys = linked_list_create_with_items("sub1", "sub2", NULL);
1060: verify_sections(keys, "main");
1061: keys = linked_list_create_with_items("subsub", NULL);
1062: verify_sections(keys, "main.sub1");
1063:
1064: keys = linked_list_create_with_items("key1", "key2", NULL);
1065: values = linked_list_create_with_items("val1", "baseval2", NULL);
1066: verify_key_values(keys, values, "main");
1067:
1068: keys = linked_list_create_with_items("key1", "key2", "key3", NULL);
1069: values = linked_list_create_with_items("val1", "subval2", "subbase3", NULL);
1070: verify_key_values(keys, values, "main.sub1");
1071:
1072: keys = linked_list_create_with_items("subkey1", "subkey2", NULL);
1073: values = linked_list_create_with_items("subsubval1", "subsubbaseval2", NULL);
1074: verify_key_values(keys, values, "main.sub1.subsub");
1075:
1076: settings->set_str(settings, "main.sub1.key2", "val2");
1077: verify_string("val2", "main.sub1.key2");
1078: settings->set_str(settings, "main.sub1.subsub.subkey2", "val2");
1079: verify_string("val2", "main.sub1.subsub.subkey2");
1080: verify_string("subsubval1", "main.sub1.subsub.subkey1");
1081: }
1082: END_TEST
1083:
1084: START_TEST(test_fallback_resolution)
1085: {
1086: linked_list_t *keys, *values;
1087:
1088: settings->destroy(settings);
1089: create_settings(chunk_from_str(
1090: "base {\n"
1091: " sub {\n"
1092: " key1 = val1\n"
1093: " key2 = val2\n"
1094: " key5 = val5\n"
1095: " subsub {\n"
1096: " subkey1 = subval1\n"
1097: " }\n"
1098: " }\n"
1099: "}\n"
1100: "other {\n"
1101: " sub {\n"
1102: " key3 = val3\n"
1103: " key4 = val4\n"
1104: " }\n"
1105: "}\n"
1106: "main {\n"
1107: " sub {\n"
1108: " key4=\n"
1109: " key5 = \n"
1110: " }\n"
1111: "}"));
1112:
1113: settings->add_fallback(settings, "other", "base");
1114: settings->add_fallback(settings, "main.sub", "other.sub");
1115:
1116: verify_string("val1", "main.sub.key1");
1117: verify_string("val3", "main.sub.key3");
1118: verify_null("main.sub.key4");
1119: verify_null("main.sub.key5");
1120: verify_string("subval1", "main.sub.subsub.subkey1");
1121:
1122: keys = linked_list_create_with_items("key3", "key1", "key2", NULL);
1123: values = linked_list_create_with_items("val3", "val1", "val2", NULL);
1124: verify_key_values(keys, values, "main.sub");
1125: }
1126: END_TEST
1127:
1128: START_TEST(test_add_fallback_printf)
1129: {
1130: settings->add_fallback(settings, "%s.sub1", "sub", "main");
1131: verify_string("val1", "main.sub1.key1");
1132: verify_string("subval2", "main.sub1.key2");
1133: verify_string("subsubval1", "main.sub1.subsub.subkey1");
1134:
1135: settings->add_fallback(settings, "%s.%s2", "%s.%s1", "main", "sub");
1136: verify_string("val1", "main.sub2.key1");
1137: verify_string("subval2", "main.sub2.key2");
1138: verify_string("subsubval1", "main.sub2.subsub.subkey1");
1139: }
1140: END_TEST
1141:
1142: START_TEST(test_references)
1143: {
1144: linked_list_t *keys, *values;
1145:
1146: create_settings(chunk_from_str(
1147: "main {\n"
1148: " sub1 {\n"
1149: " key1 = sub1val1\n"
1150: " key2 = sub1val2\n"
1151: " key4 = sub1val4\n"
1152: " subsub {\n"
1153: " subkey1 = sub1subsubval1\n"
1154: " subkey2 = sub1subsubval2\n"
1155: " }\n"
1156: " subsub1 {\n"
1157: " subkey1 = sub1subsub1val1\n"
1158: " }\n"
1159: " }\n"
1160: " sub2 : main.sub1 {\n"
1161: " key2 = sub2val2\n"
1162: " key3 = sub2val3\n"
1163: " key4 =\n"
1164: " subsub {\n"
1165: " subkey1 = sub2subsubval1\n"
1166: " subkey3 = sub2subsubval3\n"
1167: " }\n"
1168: " }\n"
1169: "}"));
1170:
1171: verify_string("sub1val1", "main.sub2.key1");
1172: verify_string("sub2val2", "main.sub2.key2");
1173: verify_string("sub2val3", "main.sub2.key3");
1174: verify_null("main.sub2.key4");
1175: verify_string("sub2subsubval1", "main.sub2.subsub.subkey1");
1176: verify_string("sub1subsubval2", "main.sub2.subsub.subkey2");
1177: verify_string("sub2subsubval3", "main.sub2.subsub.subkey3");
1178: verify_string("sub1subsub1val1", "main.sub2.subsub1.subkey1");
1179:
1180: keys = linked_list_create_with_items("subsub", "subsub1", NULL);
1181: verify_sections(keys, "main.sub2");
1182:
1183: keys = linked_list_create_with_items("key2", "key3", "key1", NULL);
1184: values = linked_list_create_with_items("sub2val2", "sub2val3", "sub1val1", NULL);
1185: verify_key_values(keys, values, "main.sub2");
1186:
1187: keys = linked_list_create_with_items("subkey1", "subkey3", "subkey2", NULL);
1188: values = linked_list_create_with_items("sub2subsubval1", "sub2subsubval3", "sub1subsubval2", NULL);
1189: verify_key_values(keys, values, "main.sub2.subsub");
1190: }
1191: END_TEST
1192:
1193: START_TEST(test_references_templates)
1194: {
1195: create_settings(chunk_from_str(
1196: "sub-def {\n"
1197: " key1 = sub1val1\n"
1198: " key2 = sub1val2\n"
1199: " subsub {\n"
1200: " subkey1 = sub1subsubval1\n"
1201: " }\n"
1202: "}\n"
1203: "subsub-def {\n"
1204: " subkey1 = sub1subval1\n"
1205: " subkey2 = sub1subval1\n"
1206: "}\n"
1207: "main {\n"
1208: " sub1 : sub-def {\n"
1209: " key1 = mainsub1val1\n"
1210: " subsub : subsub-def {\n"
1211: " subkey1 = mainsub1subval1\n"
1212: " }\n"
1213: " subsub1 {\n"
1214: " subkey1 = mainsub1sub1val1\n"
1215: " }\n"
1216: " }\n"
1217: " sub2 : sub-def {\n"
1218: " key2 = mainsub2val2\n"
1219: " key3 = mainsub2val3\n"
1220: " subsub {\n"
1221: " subkey3 = mainsub2subsubval3\n"
1222: " }\n"
1223: " }\n"
1224: "}"));
1225:
1226: verify_string("mainsub1val1", "main.sub1.key1");
1227: verify_string("sub1val2", "main.sub1.key2");
1228: verify_string("mainsub1subval1", "main.sub1.subsub.subkey1");
1229: verify_string("sub1subval1", "main.sub1.subsub.subkey2");
1230: verify_string("mainsub1sub1val1", "main.sub1.subsub1.subkey1");
1231: verify_string("sub1val1", "main.sub2.key1");
1232: verify_string("mainsub2val2", "main.sub2.key2");
1233: verify_string("mainsub2val3", "main.sub2.key3");
1234: verify_string("sub1subsubval1", "main.sub2.subsub.subkey1");
1235: verify_null("main.sub2.subsub.subkey2");
1236: verify_string("mainsub2subsubval3", "main.sub2.subsub.subkey3");
1237: }
1238: END_TEST
1239:
1240: START_TEST(test_references_order)
1241: {
1242: linked_list_t *keys, *values;
1243:
1244: create_settings(chunk_from_str(
1245: "main {\n"
1246: " sub1 {\n"
1247: " key1 = sub1val1\n"
1248: " key2 = sub1val2\n"
1249: " subsub1 {\n"
1250: " }\n"
1251: " }\n"
1252: " sub2 {\n"
1253: " key2 = sub2val2\n"
1254: " key3 = sub2val3\n"
1255: " subsub2 {\n"
1256: " }\n"
1257: " }\n"
1258: " sub3 : main.sub1, main.sub2 {\n"
1259: " key3 = sub3val3\n"
1260: " }\n"
1261: " sub4 : main.sub2, main.sub1 {\n"
1262: " key3 = sub4val3\n"
1263: " }\n"
1264: "}"));
1265:
1266: verify_string("sub1val2", "main.sub3.key2");
1267: verify_string("sub3val3", "main.sub3.key3");
1268: verify_string("sub2val2", "main.sub4.key2");
1269: verify_string("sub4val3", "main.sub4.key3");
1270:
1271: /* the order of referenced keys/subsections depends on the reference
1272: * statement's order */
1273: keys = linked_list_create_with_items("subsub1", "subsub2", NULL);
1274: verify_sections(keys, "main.sub3");
1275:
1276: keys = linked_list_create_with_items("subsub2", "subsub1", NULL);
1277: verify_sections(keys, "main.sub4");
1278:
1279: /* local keys are always enumerated first */
1280: keys = linked_list_create_with_items("key3", "key1", "key2", NULL);
1281: values = linked_list_create_with_items("sub3val3", "sub1val1", "sub1val2", NULL);
1282: verify_key_values(keys, values, "main.sub3");
1283:
1284: keys = linked_list_create_with_items("key3", "key2", "key1", NULL);
1285: values = linked_list_create_with_items("sub4val3", "sub2val2", "sub1val1", NULL);
1286: verify_key_values(keys, values, "main.sub4");
1287: }
1288: END_TEST
1289:
1290: START_TEST(test_references_resolution)
1291: {
1292: linked_list_t *keys, *values;
1293:
1294: create_settings(chunk_from_str(
1295: "sec-a {\n"
1296: " sub1 {\n"
1297: " a1 = val-a1\n"
1298: " key = sec-a-val1\n"
1299: " sub-a {\n"
1300: " }\n"
1301: " }\n"
1302: "}\n"
1303: "sec-b : sec-a {\n"
1304: " sub1 {\n"
1305: " b1 = val-b1\n"
1306: " key = sec-b-val1\n"
1307: " sub-b1 {\n"
1308: " }\n"
1309: " }\n"
1310: " sub2 {\n"
1311: " b2 = val-b2\n"
1312: " key = sec-b-val2\n"
1313: " sub-b2 {\n"
1314: " }\n"
1315: " }\n"
1316: "}\n"
1317: "sec-c : sec-b {\n"
1318: " sub2 : sec-b.sub1 {\n"
1319: " c2 = val-c2\n"
1320: " key = sec-c-val2\n"
1321: " sub-c2 {\n"
1322: " }\n"
1323: " }\n"
1324: "}"));
1325:
1326: verify_string("sec-c-val2", "sec-c.sub2.key");
1327: settings_remove_value(settings, "sec-c.sub2.key");
1328: verify_string("sec-b-val1", "sec-c.sub2.key");
1329: settings_remove_value(settings, "sec-b.sub1.key");
1330: verify_string("sec-a-val1", "sec-c.sub2.key");
1331: settings_remove_value(settings, "sec-a.sub1.key");
1332: verify_string("sec-b-val2", "sec-c.sub2.key");
1333: settings_remove_value(settings, "sec-b.sub2.key");
1334: verify_null("sec-c.sub2.key");
1335:
1336: keys = linked_list_create_with_items("sub-c2", "sub-b1", "sub-a", "sub-b2", NULL);
1337: verify_sections(keys, "sec-c.sub2");
1338:
1339: keys = linked_list_create_with_items("c2", "b1", "a1", "b2", NULL);
1340: values = linked_list_create_with_items("val-c2", "val-b1", "val-a1", "val-b2", NULL);
1341: verify_key_values(keys, values, "sec-c.sub2");
1342: }
1343: END_TEST
1344:
1345: START_TEST(test_references_fallback)
1346: {
1347: linked_list_t *keys, *values;
1348:
1349: #define test_references_fallback_base_settings \
1350: "lib {\n" \
1351: " key1 = libval1\n" \
1352: " keylib = libval\n" \
1353: " sub {\n" \
1354: " key1 = libsubval1\n" \
1355: " }\n" \
1356: " libsub {\n" \
1357: " }\n" \
1358: "}\n" \
1359: "other {\n" \
1360: " key1 = otherval1\n" \
1361: " keyother = otherval\n" \
1362: " sub {\n" \
1363: " key1 = othersubval1\n" \
1364: " }\n" \
1365: " othersub {\n" \
1366: " }\n" \
1367: "}\n"
1368:
1369: create_settings(chunk_from_str(
1370: test_references_fallback_base_settings "app : other {}"));
1371:
1372: /* references have precedence over fallbacks */
1373: settings->add_fallback(settings, "app", "lib");
1374: verify_string("otherval1", "app.key1");
1375: verify_string("libval", "app.keylib");
1376: verify_string("othersubval1", "app.sub.key1");
1377:
1378: keys = linked_list_create_with_items("sub", "othersub", "libsub", NULL);
1379: verify_sections(keys, "app");
1380:
1381: keys = linked_list_create_with_items("key1", "keyother", "keylib", NULL);
1382: values = linked_list_create_with_items("otherval1", "otherval", "libval", NULL);
1383: verify_key_values(keys, values, "app");
1384:
1385: /* fallbacks are unaffected when reloading configs with references */
1386: ck_assert(settings->load_string_section(settings,
1387: test_references_fallback_base_settings "app {}", FALSE, ""));
1388: verify_string("libval1", "app.key1");
1389: verify_string("libval", "app.keylib");
1390: verify_string("libsubval1", "app.sub.key1");
1391:
1392: ck_assert(settings->load_string_section(settings,
1393: test_references_fallback_base_settings "app : other {}", FALSE, ""));
1394: verify_string("otherval1", "app.key1");
1395: verify_string("libval", "app.keylib");
1396: verify_string("othersubval1", "app.sub.key1");
1397: }
1398: END_TEST
1399:
1400: START_SETUP(setup_string_config)
1401: {
1402: create_settings(chunk_from_str(
1403: "string = \" with accurate\twhite\\tspace\"\n"
1404: "special = \"all { special } characters # can be used.\"\n"
1405: "newlines = \"can be encoded explicitly\\nor implicitly\n"
1406: "or \\\n"
1407: "escaped\"\n"
1408: "quotes = \"\\\"and\\\" slashes \\\\ can \\\\ be\" # escaped too\n"
1409: "multiple = \"strings\" are \"combined\"\n"
1410: ));
1411: }
1412: END_SETUP
1413:
1414: START_TEST(test_strings)
1415: {
1416: verify_string(" with accurate\twhite\tspace", "string");
1417: verify_string("all { special } characters # can be used.", "special");
1418: verify_string("can be encoded explicitly\nor implicitly\nor escaped", "newlines");
1419: verify_string("\"and\" slashes \\ can \\ be", "quotes");
1420: verify_string("strings are combined", "multiple");
1421: }
1422: END_TEST
1423:
1424: START_TEST(test_valid)
1425: {
1426: chunk_t contents;
1427:
1428: contents = chunk_from_str(
1429: "single = value");
1430: ck_assert(chunk_write(contents, path, 0022, TRUE));
1431: ck_assert(settings->load_files(settings, path, FALSE));
1432: verify_string("value", "single");
1433:
1434: contents = chunk_from_str(
1435: "singleline { single = value }");
1436: ck_assert(chunk_write(contents, path, 0022, TRUE));
1437: ck_assert(settings->load_files(settings, path, FALSE));
1438: verify_string("value", "singleline.single");
1439:
1440: contents = chunk_from_str(
1441: "singleline { sub { sub1 = val1 } single = value }");
1442: ck_assert(chunk_write(contents, path, 0022, TRUE));
1443: ck_assert(settings->load_files(settings, path, FALSE));
1444: verify_string("val1", "singleline.sub.sub1");
1445:
1446: contents = chunk_from_str(
1447: "newline\n { single = value }");
1448: ck_assert(chunk_write(contents, path, 0022, TRUE));
1449: ck_assert(settings->load_files(settings, path, FALSE));
1450: verify_string("value", "newline.single");
1451:
1452: contents = chunk_from_str(
1453: "section {\n"
1454: " include # without pattern produces a warning, but is fine\n"
1455: "}\n");
1456: ck_assert(chunk_write(contents, path, 0022, TRUE));
1457: ck_assert(settings->load_files(settings, path, FALSE));
1458:
1459: contents = chunk_from_str(
1460: "equals = a setting with = and { character");
1461: ck_assert(chunk_write(contents, path, 0022, TRUE));
1462: ck_assert(settings->load_files(settings, path, FALSE));
1463: verify_string("a setting with = and { character", "equals");
1464:
1465: contents = chunk_from_str(
1466: "ref { key = value }\nvalid:ref {}");
1467: ck_assert(chunk_write(contents, path, 0022, TRUE));
1468: ck_assert(settings->load_files(settings, path, FALSE));
1469: verify_string("value", "valid.key");
1470:
1471: contents = chunk_from_str(
1472: "ref { key = value }\nvalid\n:\nref {}");
1473: ck_assert(chunk_write(contents, path, 0022, TRUE));
1474: ck_assert(settings->load_files(settings, path, FALSE));
1475: verify_string("value", "valid.key");
1476:
1477: contents = chunk_from_str(
1478: "ref { key = value }\nother { key1 = value1 }\nvalid\n:\nref\n\t,\nother {}");
1479: ck_assert(chunk_write(contents, path, 0022, TRUE));
1480: ck_assert(settings->load_files(settings, path, FALSE));
1481: verify_string("value", "valid.key");
1482: verify_string("value1", "valid.key1");
1483: }
1484: END_TEST
1485:
1486: START_TEST(test_invalid)
1487: {
1488: chunk_t contents;
1489:
1490: contents = chunk_from_str(
1491: "{\n"
1492: " no = section name\n"
1493: "}\n");
1494: ck_assert(chunk_write(contents, path, 0022, TRUE));
1495: ck_assert(!settings->load_files(settings, path, FALSE));
1496:
1497: contents = chunk_from_str(
1498: "no {\n"
1499: " = key name\n"
1500: "}\n");
1501: ck_assert(chunk_write(contents, path, 0022, TRUE));
1502: ck_assert(!settings->load_files(settings, path, FALSE));
1503:
1504: contents = chunk_from_str(
1505: "unterminated {\n"
1506: " not = valid\n");
1507: ck_assert(chunk_write(contents, path, 0022, TRUE));
1508: ck_assert(!settings->load_files(settings, path, FALSE));
1509:
1510: contents = chunk_from_str(
1511: "unterminated {\n"
1512: " strings = \"are invalid\n");
1513: ck_assert(chunk_write(contents, path, 0022, TRUE));
1514: ck_assert(!settings->load_files(settings, path, FALSE));
1515:
1516: contents = chunk_from_str(
1517: "spaces in name {}");
1518: ck_assert(chunk_write(contents, path, 0022, TRUE));
1519: ck_assert(!settings->load_files(settings, path, FALSE));
1520:
1521: contents = chunk_from_str(
1522: "\"unexpected\" = string");
1523: ck_assert(chunk_write(contents, path, 0022, TRUE));
1524: ck_assert(!settings->load_files(settings, path, FALSE));
1525:
1526: contents = chunk_from_str(
1527: "incorrect :: ref {}");
1528: ck_assert(chunk_write(contents, path, 0022, TRUE));
1529: ck_assert(!settings->load_files(settings, path, FALSE));
1530:
1531: contents = chunk_from_str(
1532: "/var/log/daemon.log { dmn = 1 }");
1533: ck_assert(chunk_write(contents, path, 0022, TRUE));
1534: ck_assert(!settings->load_files(settings, path, FALSE));
1535:
1536: contents = chunk_from_str(
1537: "filelog { /var/log/daemon.log = 1 }");
1538: ck_assert(chunk_write(contents, path, 0022, TRUE));
1539: ck_assert(!settings->load_files(settings, path, FALSE));
1540: }
1541: END_TEST
1542:
1543: START_SETUP(setup_crlf_config)
1544: {
1545: chunk_t inc1 = chunk_from_str(
1546: "main {\r\n"
1547: " key1 = n1\r\n"
1548: " key2 = n2\n"
1549: " key3 = val3\n"
1550: " none = \n"
1551: " sub1 {\n"
1552: " key3 = value\n"
1553: " }\n"
1554: " sub2 {\n"
1555: " sub3 = val3\n"
1556: " }\n"
1557: " include " include2 "\n"
1558: "}");
1559: chunk_t inc2 = chunk_from_str(
1560: "key2 = v2\n"
1561: "sub1 {\n"
1562: " key = val\n"
1563: "}");
1564: ck_assert(chunk_write(inc1, include1, 0022, TRUE));
1565: ck_assert(chunk_write(inc2, include2, 0022, TRUE));
1566: }
1567: END_SETUP
1568:
1569: START_TEST(test_crlf)
1570: {
1571: chunk_t contents = chunk_from_str(
1572: "main {\r\n"
1573: " key1 = val1\r\n"
1574: " none =\r\n"
1575: " sub1 {\r\n"
1576: " key2 = v2\r\n"
1577: " # key2 = v3\r\n"
1578: " sub1 {\r\n"
1579: " key = val\r\n"
1580: " }\r\n"
1581: " }\r\n"
1582: "}");
1583:
1584: create_settings(contents);
1585:
1586: verify_string("val1", "main.key1");
1587: verify_string("v2", "main.sub1.key2");
1588: verify_string("val", "main.sub1.sub1.key");
1589: verify_null("main.none");
1590: }
1591: END_TEST
1592:
1593: START_TEST(test_crlf_string)
1594: {
1595: chunk_t contents = chunk_from_str(
1596: "main {\r\n"
1597: " key1 = \"new\r\nline\"\r\n"
1598: " key2 = \"joi\\\r\nned\"\r\n"
1599: " none =\r\n"
1600: " sub1 {\r\n"
1601: " key2 = v2\r\n"
1602: " sub1 {\r\n"
1603: " key = val\r\n"
1604: " }\r\n"
1605: " }\r\n"
1606: "}");
1607:
1608: create_settings(contents);
1609:
1610: verify_string("new\nline", "main.key1");
1611: verify_string("joined", "main.key2");
1612: verify_string("v2", "main.sub1.key2");
1613: verify_string("val", "main.sub1.sub1.key");
1614: verify_null("main.none");
1615: }
1616: END_TEST
1617:
1618: START_TEST(test_crlf_include)
1619: {
1620: chunk_t contents = chunk_from_str(
1621: "main {\r\n"
1622: " key1 = val1\r\n"
1623: " none =\r\n"
1624: " sub1 {\r\n"
1625: " key2 = v2\r\n"
1626: " sub1 {\r\n"
1627: " key = val\r\n"
1628: " }\r\n"
1629: " }\r\n"
1630: "}");
1631:
1632: create_settings(contents);
1633:
1634: verify_string("val1", "main.key1");
1635: verify_string("v2", "main.sub1.key2");
1636: verify_string("val", "main.sub1.sub1.key");
1637: verify_null("main.none");
1638: }
1639: END_TEST
1640:
1641: Suite *settings_suite_create()
1642: {
1643: Suite *s;
1644: TCase *tc;
1645:
1646: s = suite_create("settings");
1647:
1648: tc = tcase_create("get/set_str (basic behavior)");
1649: tcase_add_checked_fixture(tc, setup_base_config, teardown_config);
1650: tcase_add_test(tc, test_get_str);
1651: tcase_add_test(tc, test_get_str_printf);
1652: tcase_add_test(tc, test_set_str);
1653: tcase_add_test(tc, test_set_str_printf);
1654: tcase_add_test(tc, test_set_default_str);
1655: suite_add_tcase(s, tc);
1656:
1657: tc = tcase_create("get/set_bool");
1658: tcase_add_checked_fixture(tc, setup_bool_config, teardown_config);
1659: tcase_add_test(tc, test_get_bool);
1660: tcase_add_test(tc, test_set_bool);
1661: suite_add_tcase(s, tc);
1662:
1663: tc = tcase_create("get/set_int");
1664: tcase_add_checked_fixture(tc, setup_int_config, teardown_config);
1665: tcase_add_test(tc, test_get_int);
1666: tcase_add_test(tc, test_set_int);
1667: suite_add_tcase(s, tc);
1668:
1669: tc = tcase_create("settings_value_as_uint64");
1670: tcase_add_test(tc, test_value_as_unit64);
1671: suite_add_tcase(s, tc);
1672:
1673: tc = tcase_create("get/set_double");
1674: tcase_add_checked_fixture(tc, setup_double_config, teardown_config);
1675: tcase_add_test(tc, test_get_double);
1676: tcase_add_test(tc, test_set_double);
1677: suite_add_tcase(s, tc);
1678:
1679: tc = tcase_create("get/set_time");
1680: tcase_add_checked_fixture(tc, setup_time_config, teardown_config);
1681: tcase_add_test(tc, test_get_time);
1682: tcase_add_test(tc, test_set_time);
1683: suite_add_tcase(s, tc);
1684:
1685: tc = tcase_create("section enumerator");
1686: tcase_add_checked_fixture(tc, setup_base_config, teardown_config);
1687: tcase_add_test(tc, test_section_enumerator);
1688: suite_add_tcase(s, tc);
1689:
1690: tc = tcase_create("key/value enumerator");
1691: tcase_add_checked_fixture(tc, setup_base_config, teardown_config);
1692: tcase_add_test(tc, test_key_value_enumerator);
1693: suite_add_tcase(s, tc);
1694:
1695: tc = tcase_create("include/load_files[_section]");
1696: tcase_add_checked_fixture(tc, setup_include_config, teardown_include_config);
1697: tcase_add_test(tc, test_include);
1698: tcase_add_test(tc, test_include_string);
1699: tcase_add_test(tc, test_load_files);
1700: tcase_add_test(tc, test_load_files_section);
1701: tcase_add_test(tc, test_order_kv);
1702: tcase_add_test(tc, test_order_section);
1703: suite_add_tcase(s, tc);
1704:
1705: tc = tcase_create("load_string[_section]");
1706: tcase_add_checked_fixture(tc, setup_include_config, teardown_config);
1707: tcase_add_test(tc, test_load_string);
1708: tcase_add_test(tc, test_load_string_section);
1709: tcase_add_test(tc, test_load_string_section_null);
1710: suite_add_tcase(s, tc);
1711:
1712: tc = tcase_create("fallback");
1713: tcase_add_checked_fixture(tc, setup_fallback_config, teardown_config);
1714: tcase_add_test(tc, test_add_fallback);
1715: tcase_add_test(tc, test_fallback_resolution);
1716: tcase_add_test(tc, test_add_fallback_printf);
1717: suite_add_tcase(s, tc);
1718:
1719: tc = tcase_create("references");
1720: tcase_add_checked_fixture(tc, NULL, teardown_config);
1721: tcase_add_test(tc, test_references);
1722: tcase_add_test(tc, test_references_templates);
1723: tcase_add_test(tc, test_references_order);
1724: tcase_add_test(tc, test_references_resolution);
1725: tcase_add_test(tc, test_references_fallback);
1726: suite_add_tcase(s, tc);
1727:
1728: tc = tcase_create("strings");
1729: tcase_add_checked_fixture(tc, setup_string_config, teardown_config);
1730: tcase_add_test(tc, test_strings);
1731: suite_add_tcase(s, tc);
1732:
1733: tc = tcase_create("valid/invalid data");
1734: tcase_add_checked_fixture(tc, setup_base_config, teardown_config);
1735: tcase_add_test(tc, test_valid);
1736: tcase_add_test(tc, test_invalid);
1737: suite_add_tcase(s, tc);
1738:
1739: tc = tcase_create("crlf");
1740: tcase_add_checked_fixture(tc, setup_crlf_config, teardown_include_config);
1741: tcase_add_test(tc, test_crlf);
1742: tcase_add_test(tc, test_crlf_string);
1743: tcase_add_test(tc, test_crlf_include);
1744: suite_add_tcase(s, tc);
1745:
1746: return s;
1747: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>