Annotation of embedaddon/strongswan/src/starter/tests/suites/test_parser.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (C) 2014 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 <unistd.h>
17:
18: #include <test_suite.h>
19:
20: #include "../../parser/conf_parser.h"
21:
22: static char *path = "/tmp/strongswan-starter-parser-test";
23: static conf_parser_t *parser;
24:
25: static void create_parser(chunk_t contents)
26: {
27: ck_assert(chunk_write(contents, path, 0022, TRUE));
28: parser = conf_parser_create(path);
29: }
30:
31: START_TEARDOWN(teardown_parser)
32: {
33: parser->destroy(parser);
34: unlink(path);
35: }
36: END_TEARDOWN
37:
38: START_TEST(test_get_sections_config_setup)
39: {
40: enumerator_t *enumerator;
41:
42: create_parser(chunk_from_str(""));
43: ck_assert(parser->parse(parser));
44: enumerator = parser->get_sections(parser, CONF_PARSER_CONFIG_SETUP);
45: ck_assert(enumerator);
46: ck_assert(!enumerator->enumerate(enumerator, NULL));
47: enumerator->destroy(enumerator);
48: parser->destroy(parser);
49:
50: create_parser(chunk_from_str("config setup\n\tfoo=bar"));
51: ck_assert(parser->parse(parser));
52: enumerator = parser->get_sections(parser, CONF_PARSER_CONFIG_SETUP);
53: ck_assert(enumerator);
54: ck_assert(!enumerator->enumerate(enumerator, NULL));
55: enumerator->destroy(enumerator);
56: }
57: END_TEST
58:
59: START_TEST(test_get_sections_conn)
60: {
61: enumerator_t *enumerator;
62: char *name;
63:
64: create_parser(chunk_from_str(""));
65: ck_assert(parser->parse(parser));
66: enumerator = parser->get_sections(parser, CONF_PARSER_CONN);
67: ck_assert(enumerator);
68: ck_assert(!enumerator->enumerate(enumerator, NULL));
69: enumerator->destroy(enumerator);
70: parser->destroy(parser);
71:
72: create_parser(chunk_from_str(
73: "conn foo\n"
74: "conn bar\n"
75: "conn foo\n"));
76: ck_assert(parser->parse(parser));
77: enumerator = parser->get_sections(parser, CONF_PARSER_CONN);
78: ck_assert(enumerator);
79: ck_assert(enumerator->enumerate(enumerator, &name));
80: ck_assert_str_eq("foo", name);
81: ck_assert(enumerator->enumerate(enumerator, &name));
82: ck_assert_str_eq("bar", name);
83: ck_assert(!enumerator->enumerate(enumerator, &name));
84: enumerator->destroy(enumerator);
85: }
86: END_TEST
87:
88: START_TEST(test_get_section_config_setup)
89: {
90: dictionary_t *dict;
91:
92: create_parser(chunk_from_str(""));
93: ck_assert(parser->parse(parser));
94: dict = parser->get_section(parser, CONF_PARSER_CONFIG_SETUP, "foo");
95: ck_assert(dict);
96: dict->destroy(dict);
97: parser->destroy(parser);
98:
99: create_parser(chunk_from_str("config setup\n\tfoo=bar"));
100: ck_assert(parser->parse(parser));
101: dict = parser->get_section(parser, CONF_PARSER_CONFIG_SETUP, NULL);
102: ck_assert(dict);
103: dict->destroy(dict);
104: parser->destroy(parser);
105:
106: create_parser(chunk_from_str("config setup\n\tfoo=bar"));
107: ck_assert(parser->parse(parser));
108: dict = parser->get_section(parser, CONF_PARSER_CONFIG_SETUP, "foo");
109: ck_assert(dict);
110: dict->destroy(dict);
111: }
112: END_TEST
113:
114: START_TEST(test_get_section_conn)
115: {
116: dictionary_t *dict;
117:
118: create_parser(chunk_from_str(""));
119: ck_assert(parser->parse(parser));
120: dict = parser->get_section(parser, CONF_PARSER_CONN, "foo");
121: ck_assert(!dict);
122: parser->destroy(parser);
123:
124: create_parser(chunk_from_str("conn foo\n"));
125: ck_assert(parser->parse(parser));
126: dict = parser->get_section(parser, CONF_PARSER_CONN, "foo");
127: ck_assert(!parser->get_section(parser, CONF_PARSER_CONN, "bar"));
128: ck_assert(dict);
129: dict->destroy(dict);
130: parser->destroy(parser);
131:
132: create_parser(chunk_from_str("conn foo\n\tfoo=bar"));
133: ck_assert(parser->parse(parser));
134: dict = parser->get_section(parser, CONF_PARSER_CONN, "foo");
135: ck_assert(dict);
136: dict->destroy(dict);
137: }
138: END_TEST
139:
140: START_TEST(test_enumerate_values)
141: {
142: enumerator_t *enumerator;
143: dictionary_t *dict;
144: char *key, *value;
145: int i;
146:
147: create_parser(chunk_from_str(
148: "conn foo\n"
149: " foo=bar\n"
150: " bar=baz"));
151: ck_assert(parser->parse(parser));
152: dict = parser->get_section(parser, CONF_PARSER_CONN, "foo");
153: ck_assert(dict);
154: ck_assert_str_eq("bar", dict->get(dict, "foo"));
155: ck_assert_str_eq("baz", dict->get(dict, "bar"));
156: enumerator = dict->create_enumerator(dict);
157: for (i = 0; enumerator->enumerate(enumerator, &key, &value); i++)
158: {
159: if ((streq(key, "foo") && !streq(value, "bar")) ||
160: (streq(key, "bar") && !streq(value, "baz")))
161: {
162: fail("unexpected setting %s=%s", key, value);
163: }
164: }
165: enumerator->destroy(enumerator);
166: ck_assert_int_eq(i, 2);
167: dict->destroy(dict);
168: }
169: END_TEST
170:
171: #define extensibility_config(section) \
172: section "\n" \
173: " foo=bar\n" \
174: " dup=one\n" \
175: " dup=two\n" \
176: "\n" \
177: " nope=val\n" \
178: "\n" \
179: section "\n" \
180: " foo=baz\n" \
181: section "\n" \
182: " answer=42\n" \
183: " nope=\n"
184:
185: static struct {
186: char *conf;
187: conf_parser_section_t type;
188: char *name;
189: } extensibility_data[] = {
190: { extensibility_config("config setup"), CONF_PARSER_CONFIG_SETUP, NULL },
191: { extensibility_config("ca ca-foo"), CONF_PARSER_CA, "ca-foo" },
192: { extensibility_config("conn conn-foo"), CONF_PARSER_CONN, "conn-foo" },
193: };
194:
195: START_TEST(test_extensibility)
196: {
197: dictionary_t *dict;
198:
199: create_parser(chunk_from_str(extensibility_data[_i].conf));
200: ck_assert(parser->parse(parser));
201:
202: dict = parser->get_section(parser, extensibility_data[_i].type,
203: extensibility_data[_i].name);
204: ck_assert(dict);
205: ck_assert_str_eq("baz", dict->get(dict, "foo"));
206: ck_assert_str_eq("two", dict->get(dict, "dup"));
207: ck_assert_str_eq("42", dict->get(dict, "answer"));
208: ck_assert(!dict->get(dict, "nope"));
209: ck_assert(!dict->get(dict, "anything"));
210: dict->destroy(dict);
211: }
212: END_TEST
213:
214: static struct {
215: char *conf;
216: bool check_section;
217: char *value;
218: } comments_data[] = {
219: { "# conn foo", FALSE, NULL },
220: { "# conn foo\n", FALSE, NULL },
221: { "conn foo # asdf", TRUE, NULL },
222: { "conn foo # asdf", TRUE, NULL },
223: { "conn foo# asdf\n", TRUE, NULL },
224: { "conn foo # asdf\n\tkey=val", TRUE, "val" },
225: { "conn foo # asdf\n#\tkey=val", TRUE, NULL },
226: { "conn foo # asdf\n\t#key=val", TRUE, NULL },
227: { "conn foo # asdf\n\tkey=@#keyid", TRUE, "@#keyid" },
228: { "conn foo # asdf\n\tkey=\"@#keyid\"", TRUE, "@#keyid" },
229: { "conn foo # asdf\n\tkey=asdf@#keyid", TRUE, "asdf@" },
230: { "conn foo # asdf\n\tkey=#val", TRUE, NULL },
231: { "conn foo # asdf\n\tkey=val#asdf", TRUE, "val" },
232: { "conn foo # asdf\n\tkey=\"val#asdf\"", TRUE, "val#asdf" },
233: { "conn foo # asdf\n\tkey=val # asdf\n", TRUE, "val" },
234: { "conn foo # asdf\n# asdf\n\tkey=val\n", TRUE, "val" },
235: { "conn foo # asdf\n\t# asdf\n\tkey=val\n", TRUE, "val" },
236: };
237:
238: START_TEST(test_comments)
239: {
240: dictionary_t *dict;
241:
242: create_parser(chunk_from_str(comments_data[_i].conf));
243: ck_assert(parser->parse(parser));
244: if (comments_data[_i].check_section)
245: {
246: dict = parser->get_section(parser, CONF_PARSER_CONN, "foo");
247: ck_assert(dict);
248: if (comments_data[_i].value)
249: {
250: ck_assert_str_eq(comments_data[_i].value, dict->get(dict, "key"));
251: }
252: else
253: {
254: ck_assert(!dict->get(dict, "key"));
255: }
256: dict->destroy(dict);
257: }
258: else
259: {
260: ck_assert(!parser->get_section(parser, CONF_PARSER_CONN, "foo"));
261: }
262: }
263: END_TEST
264:
265: static struct {
266: char *conf;
267: bool check_section;
268: char *value;
269: } whitespace_data[] = {
270: { "conn foo ", FALSE, NULL },
271: { "conn foo", FALSE, NULL },
272: { "conn foo\n", FALSE, NULL },
273: { "conn foo \n", FALSE, NULL },
274: { "conn foo\n ", FALSE, NULL },
275: { "conn foo\n \n", FALSE, NULL },
276: { "conn foo\nconn bar", TRUE, NULL },
277: { "conn foo\n \nconn bar", TRUE, NULL },
278: { "conn foo\n key=val", FALSE, "val" },
279: { "conn foo\n\tkey=val", FALSE, "val" },
280: { "conn foo\n\t \tkey=val", FALSE, "val" },
281: { "conn foo\n\tkey = val ", FALSE, "val" },
282: };
283:
284: START_TEST(test_whitespace)
285: {
286: dictionary_t *dict;
287:
288: create_parser(chunk_from_str(whitespace_data[_i].conf));
289: ck_assert(parser->parse(parser));
290: dict = parser->get_section(parser, CONF_PARSER_CONN, "foo");
291: ck_assert(dict);
292: if (whitespace_data[_i].value)
293: {
294: ck_assert_str_eq(whitespace_data[_i].value, dict->get(dict, "key"));
295: }
296: else
297: {
298: ck_assert(!dict->get(dict, "key"));
299: }
300: dict->destroy(dict);
301: if (whitespace_data[_i].check_section)
302: {
303: dict = parser->get_section(parser, CONF_PARSER_CONN, "bar");
304: ck_assert(dict);
305: dict->destroy(dict);
306: }
307: else
308: {
309: ck_assert(!parser->get_section(parser, CONF_PARSER_CONN, "bar"));
310: }
311: }
312: END_TEST
313:
314: static struct {
315: bool valid;
316: char *conf;
317: char *section;
318: char *value;
319: } strings_data[] = {
320: { FALSE, "\"conn foo\"", NULL, NULL },
321: { TRUE, "conn \"foo\"", "foo", NULL },
322: { FALSE, "conn foo bar", NULL, NULL },
323: { TRUE, "conn \"foo bar\"", "foo bar", NULL },
324: { TRUE, "conn \"#foo\"", "#foo", NULL },
325: { FALSE, "conn foo\n\t\"key=val\"", "foo", NULL },
326: { TRUE, "conn foo\n\t\"key\"=val", "foo", "val" },
327: { TRUE, "conn foo\n\tkey=val ue", "foo", "val ue" },
328: { TRUE, "conn foo\n\tkey=val ue", "foo", "val ue" },
329: { TRUE, "conn foo\n\tkey=\"val ue\"", "foo", "val ue" },
330: { TRUE, "conn foo\n\tkey=\"val\\nue\"", "foo", "val\nue" },
331: { TRUE, "conn foo\n\tkey=\"val\nue\"", "foo", "val\nue" },
332: { TRUE, "conn foo\n\tkey=\"val\\\nue\"", "foo", "value" },
333: { FALSE, "conn foo\n\tkey=\"unterminated", "foo", NULL },
334: };
335:
336: START_TEST(test_strings)
337: {
338: dictionary_t *dict;
339:
340: create_parser(chunk_from_str(strings_data[_i].conf));
341: ck_assert(parser->parse(parser) == strings_data[_i].valid);
342: if (strings_data[_i].section)
343: {
344: dict = parser->get_section(parser, CONF_PARSER_CONN,
345: strings_data[_i].section);
346: ck_assert(dict);
347: if (strings_data[_i].value)
348: {
349: ck_assert_str_eq(strings_data[_i].value, dict->get(dict, "key"));
350: }
351: else
352: {
353: ck_assert(!dict->get(dict, "key"));
354: }
355: dict->destroy(dict);
356: }
357: }
358: END_TEST
359:
360: START_TEST(test_refcounting)
361: {
362: dictionary_t *dict;
363:
364: create_parser(chunk_from_str(
365: "conn foo\n"
366: " key=val"));
367:
368: ck_assert(parser->parse(parser));
369: dict = parser->get_section(parser, CONF_PARSER_CONN, "foo");
370: ck_assert(dict);
371: ck_assert_str_eq("val", dict->get(dict, "key"));
372: parser->destroy(parser);
373: ck_assert_str_eq("val", dict->get(dict, "key"));
374: dict->destroy(dict);
375: }
376: END_TEST
377:
378: START_TEST(test_default)
379: {
380: enumerator_t *enumerator;
381: dictionary_t *dict;
382: char *name;
383:
384: create_parser(chunk_from_str(
385: "conn %default\n"
386: " key=valdef\n"
387: " unset=set\n"
388: "conn A\n"
389: " key=vala\n"
390: " unset=\n"
391: "conn B\n"
392: " keyb=valb\n"
393: ""));
394:
395: ck_assert(parser->parse(parser));
396: dict = parser->get_section(parser, CONF_PARSER_CONN, "%default");
397: ck_assert(!dict);
398: enumerator = parser->get_sections(parser, CONF_PARSER_CONN);
399: ck_assert(enumerator);
400: ck_assert(enumerator->enumerate(enumerator, &name));
401: ck_assert_str_eq("A", name);
402: ck_assert(enumerator->enumerate(enumerator, &name));
403: ck_assert_str_eq("B", name);
404: ck_assert(!enumerator->enumerate(enumerator, &name));
405: enumerator->destroy(enumerator);
406:
407: dict = parser->get_section(parser, CONF_PARSER_CONN, "A");
408: ck_assert(dict);
409: ck_assert_str_eq("vala", dict->get(dict, "key"));
410: ck_assert(!dict->get(dict, "unset"));
411: dict->destroy(dict);
412: dict = parser->get_section(parser, CONF_PARSER_CONN, "B");
413: ck_assert(dict);
414: ck_assert_str_eq("valdef", dict->get(dict, "key"));
415: ck_assert_str_eq("valb", dict->get(dict, "keyb"));
416: ck_assert_str_eq("set", dict->get(dict, "unset"));
417: dict->destroy(dict);
418: }
419: END_TEST
420:
421: START_TEST(test_also)
422: {
423: dictionary_t *dict;
424:
425: create_parser(chunk_from_str(
426: "conn A\n"
427: " key=vala\n"
428: " keya=val1\n"
429: " unset=set\n"
430: "conn B\n"
431: " also=A\n"
432: " key=valb\n"
433: " keyb=val2\n"
434: " unset=\n"
435: "conn C\n"
436: " keyc=val3\n"
437: " unset=set again\n"
438: " also=B\n"
439: "conn D\n"
440: " keyd=val4\n"
441: " also=A\n"
442: " also=B\n"
443: "conn E\n"
444: " keye=val5\n"
445: " also=B\n"
446: " also=A\n"
447: ""));
448:
449: ck_assert(parser->parse(parser));
450: dict = parser->get_section(parser, CONF_PARSER_CONN, "B");
451: ck_assert(dict);
452: ck_assert_str_eq("valb", dict->get(dict, "key"));
453: ck_assert_str_eq("val1", dict->get(dict, "keya"));
454: ck_assert_str_eq("val2", dict->get(dict, "keyb"));
455: ck_assert(!dict->get(dict, "unset"));
456: dict->destroy(dict);
457: dict = parser->get_section(parser, CONF_PARSER_CONN, "C");
458: ck_assert(dict);
459: ck_assert_str_eq("valb", dict->get(dict, "key"));
460: ck_assert_str_eq("val1", dict->get(dict, "keya"));
461: ck_assert_str_eq("val2", dict->get(dict, "keyb"));
462: ck_assert_str_eq("val3", dict->get(dict, "keyc"));
463: ck_assert_str_eq("set again", dict->get(dict, "unset"));
464: dict->destroy(dict);
465: /* since B includes A too the inclusion in D and E has no effect */
466: dict = parser->get_section(parser, CONF_PARSER_CONN, "D");
467: ck_assert(dict);
468: ck_assert_str_eq("valb", dict->get(dict, "key"));
469: ck_assert_str_eq("val1", dict->get(dict, "keya"));
470: ck_assert_str_eq("val2", dict->get(dict, "keyb"));
471: ck_assert(!dict->get(dict, "keyc"));
472: ck_assert_str_eq("val4", dict->get(dict, "keyd"));
473: ck_assert(!dict->get(dict, "unset"));
474: dict->destroy(dict);
475: dict = parser->get_section(parser, CONF_PARSER_CONN, "E");
476: ck_assert(dict);
477: ck_assert_str_eq("valb", dict->get(dict, "key"));
478: ck_assert_str_eq("val1", dict->get(dict, "keya"));
479: ck_assert_str_eq("val2", dict->get(dict, "keyb"));
480: ck_assert(!dict->get(dict, "keyc"));
481: ck_assert(!dict->get(dict, "keyd"));
482: ck_assert_str_eq("val5", dict->get(dict, "keye"));
483: ck_assert(!dict->get(dict, "unset"));
484: dict->destroy(dict);
485: }
486: END_TEST
487:
488: START_TEST(test_ambiguous)
489: {
490: dictionary_t *dict;
491:
492: create_parser(chunk_from_str(
493: "conn A\n"
494: " key=vala\n"
495: "conn B\n"
496: " key=valb\n"
497: "conn C\n"
498: " also=A\n"
499: " also=B\n"
500: "conn D\n"
501: " also=B\n"
502: " also=A\n"
503: "conn E\n"
504: " also=C\n"
505: " also=D\n"
506: "conn F\n"
507: " also=D\n"
508: " also=C\n"));
509:
510: ck_assert(parser->parse(parser));
511: dict = parser->get_section(parser, CONF_PARSER_CONN, "E");
512: ck_assert(dict);
513: ck_assert_str_eq("valb", dict->get(dict, "key"));
514: dict->destroy(dict);
515: dict = parser->get_section(parser, CONF_PARSER_CONN, "F");
516: ck_assert(dict);
517: ck_assert_str_eq("vala", dict->get(dict, "key"));
518: dict->destroy(dict);
519: }
520: END_TEST
521:
522: Suite *parser_suite_create()
523: {
524: Suite *s;
525: TCase *tc;
526:
527: s = suite_create("ipsec.conf parser");
528:
529: tc = tcase_create("get_section(s)");
530: tcase_add_checked_fixture(tc, NULL, teardown_parser);
531: tcase_add_test(tc, test_get_sections_config_setup);
532: tcase_add_test(tc, test_get_sections_conn);
533: tcase_add_test(tc, test_get_section_config_setup);
534: tcase_add_test(tc, test_get_section_conn);
535: suite_add_tcase(s, tc);
536:
537: tc = tcase_create("enumerate settings");
538: tcase_add_checked_fixture(tc, NULL, teardown_parser);
539: tcase_add_test(tc, test_enumerate_values);
540: suite_add_tcase(s, tc);
541:
542: tc = tcase_create("extensibility");
543: tcase_add_checked_fixture(tc, NULL, teardown_parser);
544: tcase_add_loop_test(tc, test_extensibility, 0, countof(extensibility_data));
545: suite_add_tcase(s, tc);
546:
547: tc = tcase_create("comments");
548: tcase_add_checked_fixture(tc, NULL, teardown_parser);
549: tcase_add_loop_test(tc, test_comments, 0, countof(comments_data));
550: suite_add_tcase(s, tc);
551:
552: tc = tcase_create("whitespace");
553: tcase_add_checked_fixture(tc, NULL, teardown_parser);
554: tcase_add_loop_test(tc, test_whitespace, 0, countof(whitespace_data));
555: suite_add_tcase(s, tc);
556:
557: tc = tcase_create("strings");
558: tcase_add_checked_fixture(tc, NULL, teardown_parser);
559: tcase_add_loop_test(tc, test_strings, 0, countof(strings_data));
560: suite_add_tcase(s, tc);
561:
562: tc = tcase_create("refcounting");
563: tcase_add_test(tc, test_refcounting);
564: suite_add_tcase(s, tc);
565:
566: tc = tcase_create("%default");
567: tcase_add_checked_fixture(tc, NULL, teardown_parser);
568: tcase_add_test(tc, test_default);
569: suite_add_tcase(s, tc);
570:
571: tc = tcase_create("also=");
572: tcase_add_checked_fixture(tc, NULL, teardown_parser);
573: tcase_add_test(tc, test_also);
574: tcase_add_test(tc, test_ambiguous);
575: suite_add_tcase(s, tc);
576:
577: return s;
578: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>