1 /* $Id: confparse-t.c 5955 2002-12-08 09:28:32Z rra $ */
2 /* confparse test suite. */
8 #include "inn/confparse.h"
9 #include "inn/messages.h"
10 #include "inn/vector.h"
14 /* Given a FILE *, read from that file, putting the results into a newly
15 allocated buffer, until encountering a line consisting solely of "===".
16 Returns the buffer, NULL on end of file, dies on error. */
18 read_section(FILE *file)
24 status = fgets(buf, sizeof(buf), file);
29 die("Unexpected end of file while reading tests");
30 if (strcmp(buf, "===\n") == 0)
37 new_data = concat(data, buf, (char *) 0);
41 status = fgets(buf, sizeof(buf), file);
46 /* Read from the given file a configuration file and write it out to
47 config/tmp. Returns true on success, false on end of file, and dies on
50 write_test_config(FILE *file)
55 config = read_section(file);
58 tmp = fopen("config/tmp", "w");
60 sysdie("Cannot create config/tmp");
61 if (fputs(config, tmp) == EOF)
62 sysdie("Write error while writing to config/tmp");
68 /* Parse a given config file with errors, setting the appropriate error
69 handler for the duration of the parse to save errors into the errors
70 global. Returns the resulting config_group. */
71 static struct config_group *
72 parse_error_config(const char *filename)
74 struct config_group *group;
77 group = config_parse_file(filename);
82 /* Read in a configuration file from the provided FILE *, write it to disk,
83 parse the temporary config file, and return the resulting config_group in
84 the pointer passed as the second parameter. Returns true on success,
85 false on end of file. */
87 parse_test_config(FILE *file, struct config_group **group)
89 if (!write_test_config(file))
91 *group = parse_error_config("config/tmp");
96 /* Test the error test cases in config/errors, ensuring that they all fail
97 to parse and match the expected error messages. Takes the current test
98 count and returns the new test count. */
104 struct config_group *group;
106 errfile = fopen("config/errors", "r");
108 sysdie("Cannot open config/errors");
109 while (parse_test_config(errfile, &group)) {
110 expected = read_section(errfile);
111 if (expected == NULL)
112 die("Unexpected end of file while reading error tests");
113 ok(n++, group == NULL);
114 ok_string(n++, expected, errors);
121 /* Test the warning test cases in config/warningss, ensuring that they all
122 parse successfully and match the expected error messages. Takes the
123 current test count and returns the new test count. */
129 struct config_group *group;
131 warnfile = fopen("config/warnings", "r");
132 if (warnfile == NULL)
133 sysdie("Cannot open config/warnings");
134 while (parse_test_config(warnfile, &group)) {
135 expected = read_section(warnfile);
136 if (expected == NULL)
137 die("Unexpected end of file while reading error tests");
138 ok(n++, group != NULL);
139 ok_string(n++, expected, errors);
146 /* Test the warning test cases in config/warn-bool, ensuring that they all
147 parse successfully and produce the expected error messages when retrieved
148 as bools. Takes the current test count and returns the new test count. */
150 test_warnings_bool(int n)
154 struct config_group *group;
155 bool b_value = false;
157 warnfile = fopen("config/warn-bool", "r");
158 if (warnfile == NULL)
159 sysdie("Cannot open config/warn-bool");
160 while (parse_test_config(warnfile, &group)) {
161 expected = read_section(warnfile);
162 if (expected == NULL)
163 die("Unexpected end of file while reading error tests");
164 ok(n++, group != NULL);
165 ok(n++, errors == NULL);
167 ok(n++, !config_param_boolean(group, "parameter", &b_value));
168 ok_string(n++, expected, errors);
176 /* Test the warning test cases in config/warn-int, ensuring that they all
177 parse successfully and produce the expected error messages when retrieved
178 as bools. Takes the current test count and returns the new test count. */
180 test_warnings_int(int n)
184 struct config_group *group;
187 warnfile = fopen("config/warn-int", "r");
188 if (warnfile == NULL)
189 sysdie("Cannot open config/warn-int");
190 while (parse_test_config(warnfile, &group)) {
191 expected = read_section(warnfile);
192 if (expected == NULL)
193 die("Unexpected end of file while reading error tests");
194 ok(n++, group != NULL);
195 ok(n++, errors == NULL);
197 ok(n++, !config_param_integer(group, "parameter", &l_value));
198 ok_string(n++, expected, errors);
209 struct config_group *group;
210 bool b_value = false;
213 struct vector *v_value;
214 char *long_param, *long_value;
221 if (access("config/valid", F_OK) < 0)
222 if (access("lib/config/valid", F_OK) == 0)
224 group = config_parse_file("config/valid");
225 ok(1, group != NULL);
230 ok(2, config_param_boolean(group, "param1", &b_value));
233 ok(4, config_param_boolean(group, "param2", &b_value));
236 ok(6, config_param_boolean(group, "param3", &b_value));
238 ok(8, config_param_boolean(group, "param4", &b_value));
241 ok(10, config_param_boolean(group, "param5", &b_value));
244 ok(12, config_param_boolean(group, "param6", &b_value));
248 ok(14, config_param_integer(group, "int1", &l_value));
249 ok(15, l_value == 0);
250 ok(16, config_param_integer(group, "int2", &l_value));
251 ok(17, l_value == -3);
252 ok(18, !config_param_integer(group, "int3", &l_value));
253 ok(19, l_value == -3);
254 ok(20, config_param_integer(group, "int4", &l_value));
255 ok(21, l_value == 5000);
256 ok(22, config_param_integer(group, "int5", &l_value));
257 ok(23, l_value == 2147483647L);
258 ok(24, config_param_integer(group, "int6", &l_value));
259 ok(25, l_value == (-2147483647L - 1));
262 ok(26, config_param_string(group, "string1", &s_value));
263 ok_string(27, "foo", s_value);
264 ok(28, config_param_string(group, "string2", &s_value));
265 ok_string(29, "bar", s_value);
266 ok(30, config_param_string(group, "string3", &s_value));
267 ok_string(31, "this is a test", s_value);
268 ok(32, config_param_string(group, "string4", &s_value));
269 ok_string(33, "this is a test", s_value);
270 ok(34, config_param_string(group, "string5", &s_value));
271 ok_string(35, "this is \a\b\f\n\r\t\v a test \' of \" escapes \?\\",
273 ok(36, config_param_string(group, "string6", &s_value));
274 ok_string(37, "# this is not a comment", s_value);
275 ok(38, config_param_string(group, "string7", &s_value));
276 ok_string(39, "lost \nyet?", s_value);
280 /* Missing newline. */
281 group = config_parse_file("config/no-newline");
282 ok(40, group != NULL);
287 ok(41, config_param_string(group, "parameter", &s_value));
288 ok_string(42, "value", s_value);
292 /* Extremely long parameter and value. */
293 tmpconfig = fopen("config/tmp", "w");
294 if (tmpconfig == NULL)
295 sysdie("cannot create config/tmp");
296 long_param = xcalloc(20001, 1);
297 memset(long_param, 'a', 20000);
298 long_value = xcalloc(64 * 1024 + 1, 1);
299 memset(long_value, 'b', 64 * 1024);
300 fprintf(tmpconfig, "%s: \"%s\"; two: %s", long_param, long_value,
303 group = config_parse_file("config/tmp");
304 ok(43, group != NULL);
311 ok(44, config_param_string(group, long_param, &s_value));
312 ok_string(45, long_value, s_value);
313 ok(46, config_param_string(group, "two", &s_value));
314 ok_string(47, long_value, s_value);
317 unlink("config/tmp");
321 /* Parsing problems exactly on the boundary of a buffer. This test
322 catches a bug in the parser that caused it to miss the colon at the end
323 of a parameter because the colon was the first character read in a new
324 read of the file buffer. */
325 tmpconfig = fopen("config/tmp", "w");
326 if (tmpconfig == NULL)
327 sysdie("cannot create config/tmp");
328 length = 16 * 1024 - strlen(": baz\nfoo:");
329 long_param = xcalloc(length + 1, 1);
330 memset(long_param, 'c', length);
331 fprintf(tmpconfig, "%s: baz\nfoo: bar\n", long_param);
333 group = config_parse_file("config/tmp");
334 ok(48, group != NULL);
341 ok(49, config_param_string(group, long_param, &s_value));
342 ok_string(50, "baz", s_value);
343 ok(51, config_param_string(group, "foo", &s_value));
344 ok_string(52, "bar", s_value);
347 unlink("config/tmp");
350 /* Alternate line endings. */
351 group = config_parse_file("config/line-endings");
352 ok(53, group != NULL);
355 ok(54, config_param_boolean(group, "param1", &b_value));
358 ok(56, config_param_boolean(group, "param2", &b_value));
361 ok(58, config_param_boolean(group, "param3", &b_value));
363 ok(60, config_param_boolean(group, "param4", &b_value));
365 ok(62, config_param_integer(group, "int1", &l_value));
366 ok(63, l_value == 0);
367 ok(64, config_param_integer(group, "int2", &l_value));
368 ok(65, l_value == -3);
371 /* Listing parameters. */
372 group = config_parse_file("config/simple");
373 ok(66, group != NULL);
376 v_value = config_params(group);
377 ok_int(67, 2, v_value->count);
378 ok_int(68, 2, v_value->allocated);
379 if (strcmp(v_value->strings[0], "foo") == 0)
380 ok_string(69, "bar", v_value->strings[1]);
381 else if (strcmp(v_value->strings[0], "bar") == 0)
382 ok_string(69, "foo", v_value->strings[1]);
385 vector_free(v_value);
389 group = parse_error_config("config/null");
390 ok(70, group == NULL);
391 ok_string(71, "config/null: invalid NUL character found in file\n",
394 n = test_warnings(n);
395 n = test_warnings_bool(n);
396 n = test_warnings_int(n);