• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2013 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining
5  * a copy of this software and associated documentation files (the
6  * "Software"), to deal in the Software without restriction, including
7  * without limitation the rights to use, copy, modify, merge, publish,
8  * distribute, sublicense, and/or sell copies of the Software, and to
9  * permit persons to whom the Software is furnished to do so, subject to
10  * the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the
13  * next paragraph) shall be included in all copies or substantial
14  * portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19  * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
20  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
21  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23  * SOFTWARE.
24  */
25 
26 #include "config.h"
27 
28 #include <stdlib.h>
29 #include <stdint.h>
30 #include <stdio.h>
31 #include <string.h>
32 #include <assert.h>
33 #include <errno.h>
34 #include <unistd.h>
35 
36 #include <libweston/config-parser.h>
37 
38 #include "shared/helpers.h"
39 #include "zunitc/zunitc.h"
40 
41 struct fixture_data {
42 	const char *text;
43 	struct weston_config *config;
44 };
45 
46 static struct weston_config *
load_config(const char * text)47 load_config(const char *text)
48 {
49 	struct weston_config *config = NULL;
50 	int len = 0;
51 	int fd = -1;
52 	char file[] = "/tmp/weston-config-parser-test-XXXXXX";
53 
54 	ZUC_ASSERTG_NOT_NULL(text, out);
55 
56 	fd = mkstemp(file);
57 	ZUC_ASSERTG_NE(-1, fd, out);
58 
59 	len = write(fd, text, strlen(text));
60 	ZUC_ASSERTG_EQ((int)strlen(text), len, out_close);
61 
62 	config = weston_config_parse(file);
63 
64 out_close:
65 	close(fd);
66 	unlink(file);
67 out:
68 	return config;
69 }
70 
71 static void *
setup_test_config(void * data)72 setup_test_config(void *data)
73 {
74 	struct weston_config *config = load_config(data);
75 	ZUC_ASSERTG_NOT_NULL(config, out);
76 
77 out:
78 	return config;
79 }
80 
81 static void *
setup_test_config_failing(void * data)82 setup_test_config_failing(void *data)
83 {
84 	struct weston_config *config = load_config(data);
85 	ZUC_ASSERTG_NULL(config, err_free);
86 
87 	return config;
88 err_free:
89 	weston_config_destroy(config);
90 	return NULL;
91 }
92 
93 static void
cleanup_test_config(void * data)94 cleanup_test_config(void *data)
95 {
96 	struct weston_config *config = data;
97 	ZUC_ASSERT_NOT_NULL(config);
98 	weston_config_destroy(config);
99 }
100 
101 static struct zuc_fixture config_test_t0 = {
102 	.data = "# nothing in this file...\n",
103 	.set_up = setup_test_config,
104 	.tear_down = cleanup_test_config
105 };
106 
107 static struct zuc_fixture config_test_t1 = {
108 	.data =
109 	"# comment line here...\n"
110 	"\n"
111 	"[foo]\n"
112 	"a=b\n"
113 	"name=  Roy Batty    \n"
114 	"\n"
115 	"\n"
116 	"[bar]\n"
117 	"# more comments\n"
118 	"number=5252\n"
119 	"zero=0\n"
120 	"negative=-42\n"
121 	"flag=false\n"
122 	"\n"
123 	"[colors]\n"
124 	"none=0x00000000\n"
125 	"low=0x11223344\n"
126 	"high=0xff00ff00\n"
127 	"oct=01234567\n"
128 	"dec=12345670\n"
129 	"short=1234567\n"
130 	"\n"
131 	"[stuff]\n"
132 	"flag=     true \n"
133 	"\n"
134 	"[bucket]\n"
135 	"color=blue \n"
136 	"contents=live crabs\n"
137 	"pinchy=true\n"
138 	"\n"
139 	"[bucket]\n"
140 	"material=plastic \n"
141 	"color=red\n"
142 	"contents=sand\n",
143 	.set_up = setup_test_config,
144 	.tear_down = cleanup_test_config
145 };
146 
147 static const char *section_names[] = {
148 	"foo", "bar", "colors", "stuff", "bucket", "bucket"
149 };
150 
151 /*
152  * Since these next few won't parse, we don't add the tear_down to
153  * attempt cleanup.
154  */
155 
156 static struct zuc_fixture config_test_t2 = {
157 	.data =
158 	"# invalid section...\n"
159 	"[this bracket isn't closed\n",
160 	.set_up = setup_test_config_failing,
161 };
162 
163 static struct zuc_fixture config_test_t3 = {
164 	.data =
165 	"# line without = ...\n"
166 	"[bambam]\n"
167 	"this line isn't any kind of valid\n",
168 	.set_up = setup_test_config_failing,
169 };
170 
171 static struct zuc_fixture config_test_t4 = {
172 	.data =
173 	"# starting with = ...\n"
174 	"[bambam]\n"
175 	"=not valid at all\n",
176 	.set_up = setup_test_config_failing,
177 };
178 
ZUC_TEST_F(config_test_t0,comment_only,data)179 ZUC_TEST_F(config_test_t0, comment_only, data)
180 {
181 	struct weston_config *config = data;
182 	ZUC_ASSERT_NOT_NULL(config);
183 }
184 
185 /** @todo individual t1 tests should have more descriptive names. */
186 
ZUC_TEST_F(config_test_t1,test001,data)187 ZUC_TEST_F(config_test_t1, test001, data)
188 {
189 	struct weston_config_section *section;
190 	struct weston_config *config = data;
191 	ZUC_ASSERT_NOT_NULL(config);
192 	section = weston_config_get_section(config,
193 					    "mollusc", NULL, NULL);
194 	ZUC_ASSERT_NULL(section);
195 }
196 
ZUC_TEST_F(config_test_t1,test002,data)197 ZUC_TEST_F(config_test_t1, test002, data)
198 {
199 	char *s;
200 	int r;
201 	struct weston_config_section *section;
202 	struct weston_config *config = data;
203 
204 	section = weston_config_get_section(config, "foo", NULL, NULL);
205 	r = weston_config_section_get_string(section, "a", &s, NULL);
206 
207 	ZUC_ASSERTG_EQ(0, r, out_free);
208 	ZUC_ASSERTG_STREQ("b", s, out_free);
209 
210 out_free:
211 	free(s);
212 }
213 
ZUC_TEST_F(config_test_t1,test003,data)214 ZUC_TEST_F(config_test_t1, test003, data)
215 {
216 	char *s;
217 	int r;
218 	struct weston_config_section *section;
219 	struct weston_config *config = data;
220 
221 	section = weston_config_get_section(config, "foo", NULL, NULL);
222 	r = weston_config_section_get_string(section, "b", &s, NULL);
223 
224 	ZUC_ASSERT_EQ(-1, r);
225 	ZUC_ASSERT_EQ(ENOENT, errno);
226 	ZUC_ASSERT_NULL(s);
227 }
228 
ZUC_TEST_F(config_test_t1,test004,data)229 ZUC_TEST_F(config_test_t1, test004, data)
230 {
231 	char *s;
232 	int r;
233 	struct weston_config_section *section;
234 	struct weston_config *config = data;
235 
236 	section = weston_config_get_section(config, "foo", NULL, NULL);
237 	r = weston_config_section_get_string(section, "name", &s, NULL);
238 
239 	ZUC_ASSERTG_EQ(0, r, out_free);
240 	ZUC_ASSERTG_STREQ("Roy Batty", s, out_free);
241 
242 out_free:
243 	free(s);
244 }
245 
ZUC_TEST_F(config_test_t1,test005,data)246 ZUC_TEST_F(config_test_t1, test005, data)
247 {
248 	char *s;
249 	int r;
250 	struct weston_config_section *section;
251 	struct weston_config *config = data;
252 
253 	section = weston_config_get_section(config, "bar", NULL, NULL);
254 	r = weston_config_section_get_string(section, "a", &s, "boo");
255 
256 	ZUC_ASSERTG_EQ(-1, r, out_free);
257 	ZUC_ASSERTG_EQ(ENOENT, errno, out_free);
258 	ZUC_ASSERTG_STREQ("boo", s, out_free);
259 
260 out_free:
261 	free(s);
262 }
263 
ZUC_TEST_F(config_test_t1,test006,data)264 ZUC_TEST_F(config_test_t1, test006, data)
265 {
266 	int r;
267 	int32_t n;
268 	struct weston_config_section *section;
269 	struct weston_config *config = data;
270 
271 	section = weston_config_get_section(config, "bar", NULL, NULL);
272 	r = weston_config_section_get_int(section, "number", &n, 600);
273 
274 	ZUC_ASSERT_EQ(0, r);
275 	ZUC_ASSERT_EQ(5252, n);
276 	ZUC_ASSERT_EQ(0, errno);
277 }
278 
ZUC_TEST_F(config_test_t1,test007,data)279 ZUC_TEST_F(config_test_t1, test007, data)
280 {
281 	int r;
282 	int32_t n;
283 	struct weston_config_section *section;
284 	struct weston_config *config = data;
285 
286 	section = weston_config_get_section(config, "bar", NULL, NULL);
287 	r = weston_config_section_get_int(section, "+++", &n, 700);
288 
289 	ZUC_ASSERT_EQ(-1, r);
290 	ZUC_ASSERT_EQ(ENOENT, errno);
291 	ZUC_ASSERT_EQ(700, n);
292 }
293 
ZUC_TEST_F(config_test_t1,test008,data)294 ZUC_TEST_F(config_test_t1, test008, data)
295 {
296 	int r;
297 	uint32_t u;
298 	struct weston_config_section *section;
299 	struct weston_config *config = data;
300 
301 	section = weston_config_get_section(config, "bar", NULL, NULL);
302 	r = weston_config_section_get_uint(section, "number", &u, 600);
303 
304 	ZUC_ASSERT_EQ(0, r);
305 	ZUC_ASSERT_EQ(5252, u);
306 	ZUC_ASSERT_EQ(0, errno);
307 }
308 
ZUC_TEST_F(config_test_t1,test009,data)309 ZUC_TEST_F(config_test_t1, test009, data)
310 {
311 	int r;
312 	uint32_t u;
313 	struct weston_config_section *section;
314 	struct weston_config *config = data;
315 
316 	section = weston_config_get_section(config, "bar", NULL, NULL);
317 	r = weston_config_section_get_uint(section, "+++", &u, 600);
318 	ZUC_ASSERT_EQ(-1, r);
319 	ZUC_ASSERT_EQ(ENOENT, errno);
320 	ZUC_ASSERT_EQ(600, u);
321 }
322 
ZUC_TEST_F(config_test_t1,test010,data)323 ZUC_TEST_F(config_test_t1, test010, data)
324 {
325 	int r;
326 	bool b;
327 	struct weston_config_section *section;
328 	struct weston_config *config = data;
329 
330 	section = weston_config_get_section(config, "bar", NULL, NULL);
331 	r = weston_config_section_get_bool(section, "flag", &b, true);
332 	ZUC_ASSERT_EQ(0, r);
333 	ZUC_ASSERT_EQ(false, b);
334 }
335 
ZUC_TEST_F(config_test_t1,test011,data)336 ZUC_TEST_F(config_test_t1, test011, data)
337 {
338 	int r;
339 	bool b;
340 	struct weston_config_section *section;
341 	struct weston_config *config = data;
342 
343 	section = weston_config_get_section(config, "stuff", NULL, NULL);
344 	r = weston_config_section_get_bool(section, "flag", &b, false);
345 	ZUC_ASSERT_EQ(0, r);
346 	ZUC_ASSERT_EQ(true, b);
347 }
348 
ZUC_TEST_F(config_test_t1,test012,data)349 ZUC_TEST_F(config_test_t1, test012, data)
350 {
351 	int r;
352 	bool b;
353 	struct weston_config_section *section;
354 	struct weston_config *config = data;
355 
356 	section = weston_config_get_section(config, "stuff", NULL, NULL);
357 	r = weston_config_section_get_bool(section, "bonk", &b, false);
358 	ZUC_ASSERT_EQ(-1, r);
359 	ZUC_ASSERT_EQ(ENOENT, errno);
360 	ZUC_ASSERT_EQ(false, b);
361 }
362 
ZUC_TEST_F(config_test_t1,test013,data)363 ZUC_TEST_F(config_test_t1, test013, data)
364 {
365 	char *s;
366 	int r;
367 	struct weston_config_section *section;
368 	struct weston_config *config = data;
369 
370 	section = weston_config_get_section(config,
371 					    "bucket", "color", "blue");
372 	r = weston_config_section_get_string(section, "contents", &s, NULL);
373 
374 	ZUC_ASSERTG_EQ(0, r, out_free);
375 	ZUC_ASSERTG_STREQ("live crabs", s, out_free);
376 
377 out_free:
378 	free(s);
379 }
380 
ZUC_TEST_F(config_test_t1,test014,data)381 ZUC_TEST_F(config_test_t1, test014, data)
382 {
383 	char *s;
384 	int r;
385 	struct weston_config_section *section;
386 	struct weston_config *config = data;
387 
388 	section = weston_config_get_section(config,
389 					    "bucket", "color", "red");
390 	r = weston_config_section_get_string(section, "contents", &s, NULL);
391 
392 	ZUC_ASSERTG_EQ(0, r, out_free);
393 	ZUC_ASSERTG_STREQ("sand", s, out_free);
394 
395 out_free:
396 	free(s);
397 }
398 
ZUC_TEST_F(config_test_t1,test015,data)399 ZUC_TEST_F(config_test_t1, test015, data)
400 {
401 	char *s;
402 	int r;
403 	struct weston_config_section *section;
404 	struct weston_config *config = data;
405 
406 	section = weston_config_get_section(config,
407 					    "bucket", "color", "pink");
408 	ZUC_ASSERT_NULL(section);
409 	r = weston_config_section_get_string(section, "contents", &s, "eels");
410 
411 	ZUC_ASSERTG_EQ(-1, r, out_free);
412 	ZUC_ASSERTG_EQ(ENOENT, errno, out_free);
413 	ZUC_ASSERTG_STREQ("eels", s, out_free);
414 
415 out_free:
416 	free(s);
417 }
418 
ZUC_TEST_F(config_test_t1,test016,data)419 ZUC_TEST_F(config_test_t1, test016, data)
420 {
421 	const char *name;
422 	int i;
423 	struct weston_config_section *section;
424 	struct weston_config *config = data;
425 
426 	section = NULL;
427 	i = 0;
428 	while (weston_config_next_section(config, &section, &name))
429 		ZUC_ASSERT_STREQ(section_names[i++], name);
430 
431 	ZUC_ASSERT_EQ(6, i);
432 }
433 
ZUC_TEST_F(config_test_t1,test017,data)434 ZUC_TEST_F(config_test_t1, test017, data)
435 {
436 	int r;
437 	int32_t n;
438 	struct weston_config_section *section;
439 	struct weston_config *config = data;
440 
441 	section = weston_config_get_section(config, "bar", NULL, NULL);
442 	r = weston_config_section_get_int(section, "zero", &n, 600);
443 
444 	ZUC_ASSERT_EQ(0, r);
445 	ZUC_ASSERT_EQ(0, n);
446 	ZUC_ASSERT_EQ(0, errno);
447 }
448 
ZUC_TEST_F(config_test_t1,test018,data)449 ZUC_TEST_F(config_test_t1, test018, data)
450 {
451 	int r;
452 	uint32_t n;
453 	struct weston_config_section *section;
454 	struct weston_config *config = data;
455 
456 	section = weston_config_get_section(config, "bar", NULL, NULL);
457 	r = weston_config_section_get_uint(section, "zero", &n, 600);
458 
459 	ZUC_ASSERT_EQ(0, r);
460 	ZUC_ASSERT_EQ(0, n);
461 	ZUC_ASSERT_EQ(0, errno);
462 }
463 
ZUC_TEST_F(config_test_t1,test019,data)464 ZUC_TEST_F(config_test_t1, test019, data)
465 {
466 	int r;
467 	uint32_t n;
468 	struct weston_config_section *section;
469 	struct weston_config *config = data;
470 
471 	section = weston_config_get_section(config, "colors", NULL, NULL);
472 	r = weston_config_section_get_color(section, "none", &n, 0xff336699);
473 
474 	ZUC_ASSERT_EQ(0, r);
475 	ZUC_ASSERT_EQ(0x000000, n);
476 	ZUC_ASSERT_EQ(0, errno);
477 }
478 
ZUC_TEST_F(config_test_t1,test020,data)479 ZUC_TEST_F(config_test_t1, test020, data)
480 {
481 	int r;
482 	uint32_t n;
483 	struct weston_config_section *section;
484 	struct weston_config *config = data;
485 
486 	section = weston_config_get_section(config, "colors", NULL, NULL);
487 	r = weston_config_section_get_color(section, "low", &n, 0xff336699);
488 
489 	ZUC_ASSERT_EQ(0, r);
490 	ZUC_ASSERT_EQ(0x11223344, n);
491 	ZUC_ASSERT_EQ(0, errno);
492 }
493 
ZUC_TEST_F(config_test_t1,test021,data)494 ZUC_TEST_F(config_test_t1, test021, data)
495 {
496 	int r;
497 	uint32_t n;
498 	struct weston_config_section *section;
499 	struct weston_config *config = data;
500 
501 	section = weston_config_get_section(config, "colors", NULL, NULL);
502 	r = weston_config_section_get_color(section, "high", &n, 0xff336699);
503 
504 	ZUC_ASSERT_EQ(0, r);
505 	ZUC_ASSERT_EQ(0xff00ff00, n);
506 	ZUC_ASSERT_EQ(0, errno);
507 }
508 
ZUC_TEST_F(config_test_t1,test022,data)509 ZUC_TEST_F(config_test_t1, test022, data)
510 {
511 	int r;
512 	uint32_t n;
513 	struct weston_config_section *section;
514 	struct weston_config *config = data;
515 
516 	// Treat colors as hex values even if missing the leading 0x
517 	section = weston_config_get_section(config, "colors", NULL, NULL);
518 	r = weston_config_section_get_color(section, "oct", &n, 0xff336699);
519 
520 	ZUC_ASSERT_EQ(0, r);
521 	ZUC_ASSERT_EQ(0x01234567, n);
522 	ZUC_ASSERT_EQ(0, errno);
523 }
524 
ZUC_TEST_F(config_test_t1,test023,data)525 ZUC_TEST_F(config_test_t1, test023, data)
526 {
527 	int r;
528 	uint32_t n;
529 	struct weston_config_section *section;
530 	struct weston_config *config = data;
531 
532 	// Treat colors as hex values even if missing the leading 0x
533 	section = weston_config_get_section(config, "colors", NULL, NULL);
534 	r = weston_config_section_get_color(section, "dec", &n, 0xff336699);
535 
536 	ZUC_ASSERT_EQ(0, r);
537 	ZUC_ASSERT_EQ(0x12345670, n);
538 	ZUC_ASSERT_EQ(0, errno);
539 }
540 
ZUC_TEST_F(config_test_t1,test024,data)541 ZUC_TEST_F(config_test_t1, test024, data)
542 {
543 	int r;
544 	uint32_t n;
545 	struct weston_config_section *section;
546 	struct weston_config *config = data;
547 
548 	// 7-digit colors are not valid (most likely typos)
549 	section = weston_config_get_section(config, "colors", NULL, NULL);
550 	r = weston_config_section_get_color(section, "short", &n, 0xff336699);
551 
552 	ZUC_ASSERT_EQ(-1, r);
553 	ZUC_ASSERT_EQ(0xff336699, n);
554 	ZUC_ASSERT_EQ(EINVAL, errno);
555 }
556 
ZUC_TEST_F(config_test_t1,test025,data)557 ZUC_TEST_F(config_test_t1, test025, data)
558 {
559 	int r;
560 	uint32_t n;
561 	struct weston_config_section *section;
562 	struct weston_config *config = data;
563 
564 	// String color names are unsupported
565 	section = weston_config_get_section(config, "bucket", NULL, NULL);
566 	r = weston_config_section_get_color(section, "color", &n, 0xff336699);
567 
568 	ZUC_ASSERT_EQ(-1, r);
569 	ZUC_ASSERT_EQ(0xff336699, n);
570 	ZUC_ASSERT_EQ(EINVAL, errno);
571 }
572 
ZUC_TEST_F(config_test_t1,test026,data)573 ZUC_TEST_F(config_test_t1, test026, data)
574 {
575 	int r;
576 	int32_t n;
577 	struct weston_config_section *section;
578 	struct weston_config *config = data;
579 
580 	section = weston_config_get_section(config, "bar", NULL, NULL);
581 	r = weston_config_section_get_int(section, "negative", &n, 600);
582 
583 	ZUC_ASSERT_EQ(0, r);
584 	ZUC_ASSERT_EQ(-42, n);
585 	ZUC_ASSERT_EQ(0, errno);
586 }
587 
ZUC_TEST_F(config_test_t1,test027,data)588 ZUC_TEST_F(config_test_t1, test027, data)
589 {
590 	int r;
591 	uint32_t n;
592 	struct weston_config_section *section;
593 	struct weston_config *config = data;
594 
595 	section = weston_config_get_section(config, "bar", NULL, NULL);
596 	r = weston_config_section_get_uint(section, "negative", &n, 600);
597 
598 	ZUC_ASSERT_EQ(-1, r);
599 	ZUC_ASSERT_EQ(600, n);
600 	ZUC_ASSERT_EQ(ERANGE, errno);
601 }
602 
ZUC_TEST_F(config_test_t2,doesnt_parse,data)603 ZUC_TEST_F(config_test_t2, doesnt_parse, data)
604 {
605 	struct weston_config *config = data;
606 	ZUC_ASSERT_NULL(config);
607 }
608 
ZUC_TEST_F(config_test_t3,doesnt_parse,data)609 ZUC_TEST_F(config_test_t3, doesnt_parse, data)
610 {
611 	struct weston_config *config = data;
612 	ZUC_ASSERT_NULL(config);
613 }
614 
ZUC_TEST_F(config_test_t4,doesnt_parse,data)615 ZUC_TEST_F(config_test_t4, doesnt_parse, data)
616 {
617 	struct weston_config *config = data;
618 	ZUC_ASSERT_NULL(config);
619 }
620 
ZUC_TEST(config_test,destroy_null)621 ZUC_TEST(config_test, destroy_null)
622 {
623 	weston_config_destroy(NULL);
624 	ZUC_ASSERT_EQ(0, weston_config_next_section(NULL, NULL, NULL));
625 }
626 
ZUC_TEST(config_test,section_from_null)627 ZUC_TEST(config_test, section_from_null)
628 {
629 	struct weston_config_section *section;
630 	section = weston_config_get_section(NULL, "bucket", NULL, NULL);
631 	ZUC_ASSERT_NULL(section);
632 }
633