error: Reduce unnecessary error propagation
[qemu/ar7.git] / tests / test-qemu-opts.c
blob297ffe79ddb4de150fbd2ebbe6aa9fa2e37a904a
1 /*
2 * QemuOpts unit-tests.
4 * Copyright (C) 2014 Leandro Dorileo <l@dorileo.org>
6 * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
7 * See the COPYING.LIB file in the top-level directory.
8 */
10 #include "qemu/osdep.h"
11 #include "qemu/units.h"
12 #include "qemu/option.h"
13 #include "qemu/option_int.h"
14 #include "qapi/error.h"
15 #include "qapi/qmp/qdict.h"
16 #include "qapi/qmp/qstring.h"
17 #include "qemu/config-file.h"
20 static QemuOptsList opts_list_01 = {
21 .name = "opts_list_01",
22 .head = QTAILQ_HEAD_INITIALIZER(opts_list_01.head),
23 .desc = {
25 .name = "str1",
26 .type = QEMU_OPT_STRING,
27 .help = "Help texts are preserved in qemu_opts_append",
28 .def_value_str = "default",
29 },{
30 .name = "str2",
31 .type = QEMU_OPT_STRING,
32 },{
33 .name = "str3",
34 .type = QEMU_OPT_STRING,
35 },{
36 .name = "number1",
37 .type = QEMU_OPT_NUMBER,
38 .help = "Having help texts only for some options is okay",
39 },{
40 .name = "number2",
41 .type = QEMU_OPT_NUMBER,
43 { /* end of list */ }
47 static QemuOptsList opts_list_02 = {
48 .name = "opts_list_02",
49 .head = QTAILQ_HEAD_INITIALIZER(opts_list_02.head),
50 .desc = {
52 .name = "str1",
53 .type = QEMU_OPT_STRING,
54 },{
55 .name = "str2",
56 .type = QEMU_OPT_STRING,
57 },{
58 .name = "bool1",
59 .type = QEMU_OPT_BOOL,
60 },{
61 .name = "bool2",
62 .type = QEMU_OPT_BOOL,
63 },{
64 .name = "size1",
65 .type = QEMU_OPT_SIZE,
66 },{
67 .name = "size2",
68 .type = QEMU_OPT_SIZE,
69 },{
70 .name = "size3",
71 .type = QEMU_OPT_SIZE,
73 { /* end of list */ }
77 static QemuOptsList opts_list_03 = {
78 .name = "opts_list_03",
79 .implied_opt_name = "implied",
80 .head = QTAILQ_HEAD_INITIALIZER(opts_list_03.head),
81 .desc = {
82 /* no elements => accept any params */
83 { /* end of list */ }
87 static void register_opts(void)
89 qemu_add_opts(&opts_list_01);
90 qemu_add_opts(&opts_list_02);
91 qemu_add_opts(&opts_list_03);
94 static void test_find_unknown_opts(void)
96 QemuOptsList *list;
97 Error *err = NULL;
99 /* should not return anything, we don't have an "unknown" option */
100 list = qemu_find_opts_err("unknown", &err);
101 g_assert(list == NULL);
102 error_free_or_abort(&err);
105 static void test_qemu_find_opts(void)
107 QemuOptsList *list;
109 /* we have an "opts_list_01" option, should return it */
110 list = qemu_find_opts("opts_list_01");
111 g_assert(list != NULL);
112 g_assert_cmpstr(list->name, ==, "opts_list_01");
115 static void test_qemu_opts_create(void)
117 QemuOptsList *list;
118 QemuOpts *opts;
120 list = qemu_find_opts("opts_list_01");
121 g_assert(list != NULL);
122 g_assert(QTAILQ_EMPTY(&list->head));
123 g_assert_cmpstr(list->name, ==, "opts_list_01");
125 /* should not find anything at this point */
126 opts = qemu_opts_find(list, NULL);
127 g_assert(opts == NULL);
129 /* create the opts */
130 opts = qemu_opts_create(list, NULL, 0, &error_abort);
131 g_assert(opts != NULL);
132 g_assert(!QTAILQ_EMPTY(&list->head));
134 /* now we've create the opts, must find it */
135 opts = qemu_opts_find(list, NULL);
136 g_assert(opts != NULL);
138 qemu_opts_del(opts);
140 /* should not find anything at this point */
141 opts = qemu_opts_find(list, NULL);
142 g_assert(opts == NULL);
145 static void test_qemu_opt_get(void)
147 QemuOptsList *list;
148 QemuOpts *opts;
149 const char *opt = NULL;
151 list = qemu_find_opts("opts_list_01");
152 g_assert(list != NULL);
153 g_assert(QTAILQ_EMPTY(&list->head));
154 g_assert_cmpstr(list->name, ==, "opts_list_01");
156 /* should not find anything at this point */
157 opts = qemu_opts_find(list, NULL);
158 g_assert(opts == NULL);
160 /* create the opts */
161 opts = qemu_opts_create(list, NULL, 0, &error_abort);
162 g_assert(opts != NULL);
163 g_assert(!QTAILQ_EMPTY(&list->head));
165 /* haven't set anything to str2 yet */
166 opt = qemu_opt_get(opts, "str2");
167 g_assert(opt == NULL);
169 qemu_opt_set(opts, "str2", "value", &error_abort);
171 /* now we have set str2, should know about it */
172 opt = qemu_opt_get(opts, "str2");
173 g_assert_cmpstr(opt, ==, "value");
175 qemu_opt_set(opts, "str2", "value2", &error_abort);
177 /* having reset the value, the returned should be the reset one */
178 opt = qemu_opt_get(opts, "str2");
179 g_assert_cmpstr(opt, ==, "value2");
181 qemu_opts_del(opts);
183 /* should not find anything at this point */
184 opts = qemu_opts_find(list, NULL);
185 g_assert(opts == NULL);
188 static void test_qemu_opt_get_bool(void)
190 QemuOptsList *list;
191 QemuOpts *opts;
192 bool opt;
194 list = qemu_find_opts("opts_list_02");
195 g_assert(list != NULL);
196 g_assert(QTAILQ_EMPTY(&list->head));
197 g_assert_cmpstr(list->name, ==, "opts_list_02");
199 /* should not find anything at this point */
200 opts = qemu_opts_find(list, NULL);
201 g_assert(opts == NULL);
203 /* create the opts */
204 opts = qemu_opts_create(list, NULL, 0, &error_abort);
205 g_assert(opts != NULL);
206 g_assert(!QTAILQ_EMPTY(&list->head));
208 /* haven't set anything to bool1 yet, so defval should be returned */
209 opt = qemu_opt_get_bool(opts, "bool1", false);
210 g_assert(opt == false);
212 qemu_opt_set_bool(opts, "bool1", true, &error_abort);
214 /* now we have set bool1, should know about it */
215 opt = qemu_opt_get_bool(opts, "bool1", false);
216 g_assert(opt == true);
218 /* having reset the value, opt should be the reset one not defval */
219 qemu_opt_set_bool(opts, "bool1", false, &error_abort);
221 opt = qemu_opt_get_bool(opts, "bool1", true);
222 g_assert(opt == false);
224 qemu_opts_del(opts);
226 /* should not find anything at this point */
227 opts = qemu_opts_find(list, NULL);
228 g_assert(opts == NULL);
231 static void test_qemu_opt_get_number(void)
233 QemuOptsList *list;
234 QemuOpts *opts;
235 uint64_t opt;
237 list = qemu_find_opts("opts_list_01");
238 g_assert(list != NULL);
239 g_assert(QTAILQ_EMPTY(&list->head));
240 g_assert_cmpstr(list->name, ==, "opts_list_01");
242 /* should not find anything at this point */
243 opts = qemu_opts_find(list, NULL);
244 g_assert(opts == NULL);
246 /* create the opts */
247 opts = qemu_opts_create(list, NULL, 0, &error_abort);
248 g_assert(opts != NULL);
249 g_assert(!QTAILQ_EMPTY(&list->head));
251 /* haven't set anything to number1 yet, so defval should be returned */
252 opt = qemu_opt_get_number(opts, "number1", 5);
253 g_assert(opt == 5);
255 qemu_opt_set_number(opts, "number1", 10, &error_abort);
257 /* now we have set number1, should know about it */
258 opt = qemu_opt_get_number(opts, "number1", 5);
259 g_assert(opt == 10);
261 /* having reset it, the returned should be the reset one not defval */
262 qemu_opt_set_number(opts, "number1", 15, &error_abort);
264 opt = qemu_opt_get_number(opts, "number1", 5);
265 g_assert(opt == 15);
267 qemu_opts_del(opts);
269 /* should not find anything at this point */
270 opts = qemu_opts_find(list, NULL);
271 g_assert(opts == NULL);
274 static void test_qemu_opt_get_size(void)
276 QemuOptsList *list;
277 QemuOpts *opts;
278 uint64_t opt;
279 QDict *dict;
281 list = qemu_find_opts("opts_list_02");
282 g_assert(list != NULL);
283 g_assert(QTAILQ_EMPTY(&list->head));
284 g_assert_cmpstr(list->name, ==, "opts_list_02");
286 /* should not find anything at this point */
287 opts = qemu_opts_find(list, NULL);
288 g_assert(opts == NULL);
290 /* create the opts */
291 opts = qemu_opts_create(list, NULL, 0, &error_abort);
292 g_assert(opts != NULL);
293 g_assert(!QTAILQ_EMPTY(&list->head));
295 /* haven't set anything to size1 yet, so defval should be returned */
296 opt = qemu_opt_get_size(opts, "size1", 5);
297 g_assert(opt == 5);
299 dict = qdict_new();
300 g_assert(dict != NULL);
302 qdict_put_str(dict, "size1", "10");
304 qemu_opts_absorb_qdict(opts, dict, &error_abort);
305 g_assert(error_abort == NULL);
307 /* now we have set size1, should know about it */
308 opt = qemu_opt_get_size(opts, "size1", 5);
309 g_assert(opt == 10);
311 /* reset value */
312 qdict_put_str(dict, "size1", "15");
314 qemu_opts_absorb_qdict(opts, dict, &error_abort);
315 g_assert(error_abort == NULL);
317 /* test the reset value */
318 opt = qemu_opt_get_size(opts, "size1", 5);
319 g_assert(opt == 15);
321 qdict_del(dict, "size1");
322 g_free(dict);
324 qemu_opts_del(opts);
326 /* should not find anything at this point */
327 opts = qemu_opts_find(list, NULL);
328 g_assert(opts == NULL);
331 static void test_qemu_opt_unset(void)
333 QemuOpts *opts;
334 const char *value;
335 int ret;
337 /* dynamically initialized (parsed) opts */
338 opts = qemu_opts_parse(&opts_list_03, "key=value", false, NULL);
339 g_assert(opts != NULL);
341 /* check default/parsed value */
342 value = qemu_opt_get(opts, "key");
343 g_assert_cmpstr(value, ==, "value");
345 /* reset it to value2 */
346 qemu_opt_set(opts, "key", "value2", &error_abort);
348 value = qemu_opt_get(opts, "key");
349 g_assert_cmpstr(value, ==, "value2");
351 /* unset, valid only for "accept any" */
352 ret = qemu_opt_unset(opts, "key");
353 g_assert(ret == 0);
355 /* after reset the value should be the parsed/default one */
356 value = qemu_opt_get(opts, "key");
357 g_assert_cmpstr(value, ==, "value");
359 qemu_opts_del(opts);
362 static void test_qemu_opts_reset(void)
364 QemuOptsList *list;
365 QemuOpts *opts;
366 uint64_t opt;
368 list = qemu_find_opts("opts_list_01");
369 g_assert(list != NULL);
370 g_assert(QTAILQ_EMPTY(&list->head));
371 g_assert_cmpstr(list->name, ==, "opts_list_01");
373 /* should not find anything at this point */
374 opts = qemu_opts_find(list, NULL);
375 g_assert(opts == NULL);
377 /* create the opts */
378 opts = qemu_opts_create(list, NULL, 0, &error_abort);
379 g_assert(opts != NULL);
380 g_assert(!QTAILQ_EMPTY(&list->head));
382 /* haven't set anything to number1 yet, so defval should be returned */
383 opt = qemu_opt_get_number(opts, "number1", 5);
384 g_assert(opt == 5);
386 qemu_opt_set_number(opts, "number1", 10, &error_abort);
388 /* now we have set number1, should know about it */
389 opt = qemu_opt_get_number(opts, "number1", 5);
390 g_assert(opt == 10);
392 qemu_opts_reset(list);
394 /* should not find anything at this point */
395 opts = qemu_opts_find(list, NULL);
396 g_assert(opts == NULL);
399 static void test_qemu_opts_set(void)
401 QemuOptsList *list;
402 QemuOpts *opts;
403 const char *opt;
405 list = qemu_find_opts("opts_list_01");
406 g_assert(list != NULL);
407 g_assert(QTAILQ_EMPTY(&list->head));
408 g_assert_cmpstr(list->name, ==, "opts_list_01");
410 /* should not find anything at this point */
411 opts = qemu_opts_find(list, NULL);
412 g_assert(opts == NULL);
414 /* implicitly create opts and set str3 value */
415 qemu_opts_set(list, NULL, "str3", "value", &error_abort);
416 g_assert(!QTAILQ_EMPTY(&list->head));
418 /* get the just created opts */
419 opts = qemu_opts_find(list, NULL);
420 g_assert(opts != NULL);
422 /* check the str3 value */
423 opt = qemu_opt_get(opts, "str3");
424 g_assert_cmpstr(opt, ==, "value");
426 qemu_opts_del(opts);
428 /* should not find anything at this point */
429 opts = qemu_opts_find(list, NULL);
430 g_assert(opts == NULL);
433 static int opts_count_iter(void *opaque, const char *name, const char *value,
434 Error **errp)
436 (*(size_t *)opaque)++;
437 return 0;
440 static size_t opts_count(QemuOpts *opts)
442 size_t n = 0;
444 qemu_opt_foreach(opts, opts_count_iter, &n, NULL);
445 return n;
448 static void test_opts_parse(void)
450 Error *err = NULL;
451 QemuOpts *opts;
453 /* Nothing */
454 opts = qemu_opts_parse(&opts_list_03, "", false, &error_abort);
455 g_assert_cmpuint(opts_count(opts), ==, 0);
457 /* Empty key */
458 opts = qemu_opts_parse(&opts_list_03, "=val", false, &error_abort);
459 g_assert_cmpuint(opts_count(opts), ==, 1);
460 g_assert_cmpstr(qemu_opt_get(opts, ""), ==, "val");
462 /* Multiple keys, last one wins */
463 opts = qemu_opts_parse(&opts_list_03, "a=1,b=2,,x,a=3",
464 false, &error_abort);
465 g_assert_cmpuint(opts_count(opts), ==, 3);
466 g_assert_cmpstr(qemu_opt_get(opts, "a"), ==, "3");
467 g_assert_cmpstr(qemu_opt_get(opts, "b"), ==, "2,x");
469 /* Except when it doesn't */
470 opts = qemu_opts_parse(&opts_list_03, "id=foo,id=bar",
471 false, &error_abort);
472 g_assert_cmpuint(opts_count(opts), ==, 0);
473 g_assert_cmpstr(qemu_opts_id(opts), ==, "foo");
475 /* TODO Cover low-level access to repeated keys */
477 /* Trailing comma is ignored */
478 opts = qemu_opts_parse(&opts_list_03, "x=y,", false, &error_abort);
479 g_assert_cmpuint(opts_count(opts), ==, 1);
480 g_assert_cmpstr(qemu_opt_get(opts, "x"), ==, "y");
482 /* Except when it isn't */
483 opts = qemu_opts_parse(&opts_list_03, ",", false, &error_abort);
484 g_assert_cmpuint(opts_count(opts), ==, 1);
485 g_assert_cmpstr(qemu_opt_get(opts, ""), ==, "on");
487 /* Duplicate ID */
488 opts = qemu_opts_parse(&opts_list_03, "x=y,id=foo", false, &err);
489 error_free_or_abort(&err);
490 g_assert(!opts);
491 /* TODO Cover .merge_lists = true */
493 /* Buggy ID recognition (fixed) */
494 opts = qemu_opts_parse(&opts_list_03, "x=,,id=bar", false, &error_abort);
495 g_assert_cmpuint(opts_count(opts), ==, 1);
496 g_assert(!qemu_opts_id(opts));
497 g_assert_cmpstr(qemu_opt_get(opts, "x"), ==, ",id=bar");
499 /* Anti-social ID */
500 opts = qemu_opts_parse(&opts_list_01, "id=666", false, &err);
501 error_free_or_abort(&err);
502 g_assert(!opts);
504 /* Implied value */
505 opts = qemu_opts_parse(&opts_list_03, "an,noaus,noaus=",
506 false, &error_abort);
507 g_assert_cmpuint(opts_count(opts), ==, 3);
508 g_assert_cmpstr(qemu_opt_get(opts, "an"), ==, "on");
509 g_assert_cmpstr(qemu_opt_get(opts, "aus"), ==, "off");
510 g_assert_cmpstr(qemu_opt_get(opts, "noaus"), ==, "");
512 /* Implied value, negated empty key */
513 opts = qemu_opts_parse(&opts_list_03, "no", false, &error_abort);
514 g_assert_cmpuint(opts_count(opts), ==, 1);
515 g_assert_cmpstr(qemu_opt_get(opts, ""), ==, "off");
517 /* Implied key */
518 opts = qemu_opts_parse(&opts_list_03, "an,noaus,noaus=", true,
519 &error_abort);
520 g_assert_cmpuint(opts_count(opts), ==, 3);
521 g_assert_cmpstr(qemu_opt_get(opts, "implied"), ==, "an");
522 g_assert_cmpstr(qemu_opt_get(opts, "aus"), ==, "off");
523 g_assert_cmpstr(qemu_opt_get(opts, "noaus"), ==, "");
525 /* Implied key with empty value */
526 opts = qemu_opts_parse(&opts_list_03, ",", true, &error_abort);
527 g_assert_cmpuint(opts_count(opts), ==, 1);
528 g_assert_cmpstr(qemu_opt_get(opts, "implied"), ==, "");
530 /* Implied key with comma value */
531 opts = qemu_opts_parse(&opts_list_03, ",,,a=1", true, &error_abort);
532 g_assert_cmpuint(opts_count(opts), ==, 2);
533 g_assert_cmpstr(qemu_opt_get(opts, "implied"), ==, ",");
534 g_assert_cmpstr(qemu_opt_get(opts, "a"), ==, "1");
536 /* Empty key is not an implied key */
537 opts = qemu_opts_parse(&opts_list_03, "=val", true, &error_abort);
538 g_assert_cmpuint(opts_count(opts), ==, 1);
539 g_assert_cmpstr(qemu_opt_get(opts, ""), ==, "val");
541 /* Unknown key */
542 opts = qemu_opts_parse(&opts_list_01, "nonexistent=", false, &err);
543 error_free_or_abort(&err);
544 g_assert(!opts);
546 qemu_opts_reset(&opts_list_01);
547 qemu_opts_reset(&opts_list_03);
550 static void test_opts_parse_bool(void)
552 Error *err = NULL;
553 QemuOpts *opts;
555 opts = qemu_opts_parse(&opts_list_02, "bool1=on,bool2=off",
556 false, &error_abort);
557 g_assert_cmpuint(opts_count(opts), ==, 2);
558 g_assert(qemu_opt_get_bool(opts, "bool1", false));
559 g_assert(!qemu_opt_get_bool(opts, "bool2", true));
561 opts = qemu_opts_parse(&opts_list_02, "bool1=offer", false, &err);
562 error_free_or_abort(&err);
563 g_assert(!opts);
565 qemu_opts_reset(&opts_list_02);
568 static void test_opts_parse_number(void)
570 Error *err = NULL;
571 QemuOpts *opts;
573 /* Lower limit zero */
574 opts = qemu_opts_parse(&opts_list_01, "number1=0", false, &error_abort);
575 g_assert_cmpuint(opts_count(opts), ==, 1);
576 g_assert_cmpuint(qemu_opt_get_number(opts, "number1", 1), ==, 0);
578 /* Upper limit 2^64-1 */
579 opts = qemu_opts_parse(&opts_list_01,
580 "number1=18446744073709551615,number2=-1",
581 false, &error_abort);
582 g_assert_cmpuint(opts_count(opts), ==, 2);
583 g_assert_cmphex(qemu_opt_get_number(opts, "number1", 1), ==, UINT64_MAX);
584 g_assert_cmphex(qemu_opt_get_number(opts, "number2", 0), ==, UINT64_MAX);
586 /* Above upper limit */
587 opts = qemu_opts_parse(&opts_list_01, "number1=18446744073709551616",
588 false, &err);
589 error_free_or_abort(&err);
590 g_assert(!opts);
592 /* Below lower limit */
593 opts = qemu_opts_parse(&opts_list_01, "number1=-18446744073709551616",
594 false, &err);
595 error_free_or_abort(&err);
596 g_assert(!opts);
598 /* Hex and octal */
599 opts = qemu_opts_parse(&opts_list_01, "number1=0x2a,number2=052",
600 false, &error_abort);
601 g_assert_cmpuint(opts_count(opts), ==, 2);
602 g_assert_cmpuint(qemu_opt_get_number(opts, "number1", 1), ==, 42);
603 g_assert_cmpuint(qemu_opt_get_number(opts, "number2", 0), ==, 42);
605 /* Invalid */
606 opts = qemu_opts_parse(&opts_list_01, "number1=", false, &err);
607 error_free_or_abort(&err);
608 g_assert(!opts);
609 opts = qemu_opts_parse(&opts_list_01, "number1=eins", false, &err);
610 error_free_or_abort(&err);
611 g_assert(!opts);
613 /* Leading whitespace */
614 opts = qemu_opts_parse(&opts_list_01, "number1= \t42",
615 false, &error_abort);
616 g_assert_cmpuint(opts_count(opts), ==, 1);
617 g_assert_cmpuint(qemu_opt_get_number(opts, "number1", 1), ==, 42);
619 /* Trailing crap */
620 opts = qemu_opts_parse(&opts_list_01, "number1=3.14", false, &err);
621 error_free_or_abort(&err);
622 g_assert(!opts);
623 opts = qemu_opts_parse(&opts_list_01, "number1=08", false, &err);
624 error_free_or_abort(&err);
625 g_assert(!opts);
626 opts = qemu_opts_parse(&opts_list_01, "number1=0 ", false, &err);
627 error_free_or_abort(&err);
628 g_assert(!opts);
630 qemu_opts_reset(&opts_list_01);
633 static void test_opts_parse_size(void)
635 Error *err = NULL;
636 QemuOpts *opts;
638 /* Lower limit zero */
639 opts = qemu_opts_parse(&opts_list_02, "size1=0", false, &error_abort);
640 g_assert_cmpuint(opts_count(opts), ==, 1);
641 g_assert_cmpuint(qemu_opt_get_size(opts, "size1", 1), ==, 0);
643 /* Note: precision is 53 bits since we're parsing with strtod() */
645 /* Around limit of precision: 2^53-1, 2^53, 2^54 */
646 opts = qemu_opts_parse(&opts_list_02,
647 "size1=9007199254740991,"
648 "size2=9007199254740992,"
649 "size3=9007199254740993",
650 false, &error_abort);
651 g_assert_cmpuint(opts_count(opts), ==, 3);
652 g_assert_cmphex(qemu_opt_get_size(opts, "size1", 1),
653 ==, 0x1fffffffffffff);
654 g_assert_cmphex(qemu_opt_get_size(opts, "size2", 1),
655 ==, 0x20000000000000);
656 g_assert_cmphex(qemu_opt_get_size(opts, "size3", 1),
657 ==, 0x20000000000000);
659 /* Close to signed upper limit 0x7ffffffffffffc00 (53 msbs set) */
660 opts = qemu_opts_parse(&opts_list_02,
661 "size1=9223372036854774784," /* 7ffffffffffffc00 */
662 "size2=9223372036854775295", /* 7ffffffffffffdff */
663 false, &error_abort);
664 g_assert_cmpuint(opts_count(opts), ==, 2);
665 g_assert_cmphex(qemu_opt_get_size(opts, "size1", 1),
666 ==, 0x7ffffffffffffc00);
667 g_assert_cmphex(qemu_opt_get_size(opts, "size2", 1),
668 ==, 0x7ffffffffffffc00);
670 /* Close to actual upper limit 0xfffffffffffff800 (53 msbs set) */
671 opts = qemu_opts_parse(&opts_list_02,
672 "size1=18446744073709549568," /* fffffffffffff800 */
673 "size2=18446744073709550591", /* fffffffffffffbff */
674 false, &error_abort);
675 g_assert_cmpuint(opts_count(opts), ==, 2);
676 g_assert_cmphex(qemu_opt_get_size(opts, "size1", 1),
677 ==, 0xfffffffffffff800);
678 g_assert_cmphex(qemu_opt_get_size(opts, "size2", 1),
679 ==, 0xfffffffffffff800);
681 /* Beyond limits */
682 opts = qemu_opts_parse(&opts_list_02, "size1=-1", false, &err);
683 error_free_or_abort(&err);
684 g_assert(!opts);
685 opts = qemu_opts_parse(&opts_list_02,
686 "size1=18446744073709550592", /* fffffffffffffc00 */
687 false, &err);
688 error_free_or_abort(&err);
689 g_assert(!opts);
691 /* Suffixes */
692 opts = qemu_opts_parse(&opts_list_02, "size1=8b,size2=1.5k,size3=2M",
693 false, &error_abort);
694 g_assert_cmpuint(opts_count(opts), ==, 3);
695 g_assert_cmphex(qemu_opt_get_size(opts, "size1", 0), ==, 8);
696 g_assert_cmphex(qemu_opt_get_size(opts, "size2", 0), ==, 1536);
697 g_assert_cmphex(qemu_opt_get_size(opts, "size3", 0), ==, 2 * MiB);
698 opts = qemu_opts_parse(&opts_list_02, "size1=0.1G,size2=16777215T",
699 false, &error_abort);
700 g_assert_cmpuint(opts_count(opts), ==, 2);
701 g_assert_cmphex(qemu_opt_get_size(opts, "size1", 0), ==, GiB / 10);
702 g_assert_cmphex(qemu_opt_get_size(opts, "size2", 0), ==, 16777215ULL * TiB);
704 /* Beyond limit with suffix */
705 opts = qemu_opts_parse(&opts_list_02, "size1=16777216T",
706 false, &err);
707 error_free_or_abort(&err);
708 g_assert(!opts);
710 /* Trailing crap */
711 opts = qemu_opts_parse(&opts_list_02, "size1=16E", false, &err);
712 error_free_or_abort(&err);
713 g_assert(!opts);
714 opts = qemu_opts_parse(&opts_list_02, "size1=16Gi", false, &err);
715 error_free_or_abort(&err);
716 g_assert(!opts);
718 qemu_opts_reset(&opts_list_02);
721 static void test_has_help_option(void)
723 static const struct {
724 const char *params;
725 /* expected value of qemu_opt_has_help_opt() with implied=false */
726 bool expect;
727 /* expected value of qemu_opt_has_help_opt() with implied=true */
728 bool expect_implied;
729 } test[] = {
730 { "help", true, false },
731 { "?", true, false },
732 { "helpme", false, false },
733 { "?me", false, false },
734 { "a,help", true, true },
735 { "a,?", true, true },
736 { "a=0,help,b", true, true },
737 { "a=0,?,b", true, true },
738 { "help,b=1", true, false },
739 { "?,b=1", true, false },
740 { "a,b,,help", true, true },
741 { "a,b,,?", true, true },
743 int i;
744 QemuOpts *opts;
746 for (i = 0; i < ARRAY_SIZE(test); i++) {
747 g_assert_cmpint(has_help_option(test[i].params),
748 ==, test[i].expect);
749 opts = qemu_opts_parse(&opts_list_03, test[i].params, false,
750 &error_abort);
751 g_assert_cmpint(qemu_opt_has_help_opt(opts),
752 ==, test[i].expect);
753 qemu_opts_del(opts);
754 opts = qemu_opts_parse(&opts_list_03, test[i].params, true,
755 &error_abort);
756 g_assert_cmpint(qemu_opt_has_help_opt(opts),
757 ==, test[i].expect_implied);
758 qemu_opts_del(opts);
762 static void append_verify_list_01(QemuOptDesc *desc, bool with_overlapping)
764 int i = 0;
766 if (with_overlapping) {
767 g_assert_cmpstr(desc[i].name, ==, "str1");
768 g_assert_cmpint(desc[i].type, ==, QEMU_OPT_STRING);
769 g_assert_cmpstr(desc[i].help, ==,
770 "Help texts are preserved in qemu_opts_append");
771 g_assert_cmpstr(desc[i].def_value_str, ==, "default");
772 i++;
774 g_assert_cmpstr(desc[i].name, ==, "str2");
775 g_assert_cmpint(desc[i].type, ==, QEMU_OPT_STRING);
776 g_assert_cmpstr(desc[i].help, ==, NULL);
777 g_assert_cmpstr(desc[i].def_value_str, ==, NULL);
778 i++;
781 g_assert_cmpstr(desc[i].name, ==, "str3");
782 g_assert_cmpint(desc[i].type, ==, QEMU_OPT_STRING);
783 g_assert_cmpstr(desc[i].help, ==, NULL);
784 g_assert_cmpstr(desc[i].def_value_str, ==, NULL);
785 i++;
787 g_assert_cmpstr(desc[i].name, ==, "number1");
788 g_assert_cmpint(desc[i].type, ==, QEMU_OPT_NUMBER);
789 g_assert_cmpstr(desc[i].help, ==,
790 "Having help texts only for some options is okay");
791 g_assert_cmpstr(desc[i].def_value_str, ==, NULL);
792 i++;
794 g_assert_cmpstr(desc[i].name, ==, "number2");
795 g_assert_cmpint(desc[i].type, ==, QEMU_OPT_NUMBER);
796 g_assert_cmpstr(desc[i].help, ==, NULL);
797 g_assert_cmpstr(desc[i].def_value_str, ==, NULL);
798 i++;
800 g_assert_cmpstr(desc[i].name, ==, NULL);
803 static void append_verify_list_02(QemuOptDesc *desc)
805 int i = 0;
807 g_assert_cmpstr(desc[i].name, ==, "str1");
808 g_assert_cmpint(desc[i].type, ==, QEMU_OPT_STRING);
809 g_assert_cmpstr(desc[i].help, ==, NULL);
810 g_assert_cmpstr(desc[i].def_value_str, ==, NULL);
811 i++;
813 g_assert_cmpstr(desc[i].name, ==, "str2");
814 g_assert_cmpint(desc[i].type, ==, QEMU_OPT_STRING);
815 g_assert_cmpstr(desc[i].help, ==, NULL);
816 g_assert_cmpstr(desc[i].def_value_str, ==, NULL);
817 i++;
819 g_assert_cmpstr(desc[i].name, ==, "bool1");
820 g_assert_cmpint(desc[i].type, ==, QEMU_OPT_BOOL);
821 g_assert_cmpstr(desc[i].help, ==, NULL);
822 g_assert_cmpstr(desc[i].def_value_str, ==, NULL);
823 i++;
825 g_assert_cmpstr(desc[i].name, ==, "bool2");
826 g_assert_cmpint(desc[i].type, ==, QEMU_OPT_BOOL);
827 g_assert_cmpstr(desc[i].help, ==, NULL);
828 g_assert_cmpstr(desc[i].def_value_str, ==, NULL);
829 i++;
831 g_assert_cmpstr(desc[i].name, ==, "size1");
832 g_assert_cmpint(desc[i].type, ==, QEMU_OPT_SIZE);
833 g_assert_cmpstr(desc[i].help, ==, NULL);
834 g_assert_cmpstr(desc[i].def_value_str, ==, NULL);
835 i++;
837 g_assert_cmpstr(desc[i].name, ==, "size2");
838 g_assert_cmpint(desc[i].type, ==, QEMU_OPT_SIZE);
839 g_assert_cmpstr(desc[i].help, ==, NULL);
840 g_assert_cmpstr(desc[i].def_value_str, ==, NULL);
841 i++;
843 g_assert_cmpstr(desc[i].name, ==, "size3");
844 g_assert_cmpint(desc[i].type, ==, QEMU_OPT_SIZE);
845 g_assert_cmpstr(desc[i].help, ==, NULL);
846 g_assert_cmpstr(desc[i].def_value_str, ==, NULL);
849 static void test_opts_append_to_null(void)
851 QemuOptsList *merged;
853 merged = qemu_opts_append(NULL, &opts_list_01);
854 g_assert(merged != &opts_list_01);
856 g_assert_cmpstr(merged->name, ==, NULL);
857 g_assert_cmpstr(merged->implied_opt_name, ==, NULL);
858 g_assert_false(merged->merge_lists);
860 append_verify_list_01(merged->desc, true);
862 qemu_opts_free(merged);
865 static void test_opts_append(void)
867 QemuOptsList *first, *merged;
869 first = qemu_opts_append(NULL, &opts_list_02);
870 merged = qemu_opts_append(first, &opts_list_01);
871 g_assert(first != &opts_list_02);
872 g_assert(merged != &opts_list_01);
874 g_assert_cmpstr(merged->name, ==, NULL);
875 g_assert_cmpstr(merged->implied_opt_name, ==, NULL);
876 g_assert_false(merged->merge_lists);
878 append_verify_list_02(&merged->desc[0]);
879 append_verify_list_01(&merged->desc[7], false);
881 qemu_opts_free(merged);
884 static void test_opts_to_qdict_basic(void)
886 QemuOpts *opts;
887 QDict *dict;
889 opts = qemu_opts_parse(&opts_list_01, "str1=foo,str2=,str3=bar,number1=42",
890 false, &error_abort);
891 g_assert(opts != NULL);
893 dict = qemu_opts_to_qdict(opts, NULL);
894 g_assert(dict != NULL);
896 g_assert_cmpstr(qdict_get_str(dict, "str1"), ==, "foo");
897 g_assert_cmpstr(qdict_get_str(dict, "str2"), ==, "");
898 g_assert_cmpstr(qdict_get_str(dict, "str3"), ==, "bar");
899 g_assert_cmpstr(qdict_get_str(dict, "number1"), ==, "42");
900 g_assert_false(qdict_haskey(dict, "number2"));
902 qobject_unref(dict);
903 qemu_opts_del(opts);
906 static void test_opts_to_qdict_filtered(void)
908 QemuOptsList *first, *merged;
909 QemuOpts *opts;
910 QDict *dict;
912 first = qemu_opts_append(NULL, &opts_list_02);
913 merged = qemu_opts_append(first, &opts_list_01);
915 opts = qemu_opts_parse(merged,
916 "str1=foo,str2=,str3=bar,bool1=off,number1=42",
917 false, &error_abort);
918 g_assert(opts != NULL);
920 /* Convert to QDict without deleting from opts */
921 dict = qemu_opts_to_qdict_filtered(opts, NULL, &opts_list_01, false);
922 g_assert(dict != NULL);
923 g_assert_cmpstr(qdict_get_str(dict, "str1"), ==, "foo");
924 g_assert_cmpstr(qdict_get_str(dict, "str2"), ==, "");
925 g_assert_cmpstr(qdict_get_str(dict, "str3"), ==, "bar");
926 g_assert_cmpstr(qdict_get_str(dict, "number1"), ==, "42");
927 g_assert_false(qdict_haskey(dict, "number2"));
928 g_assert_false(qdict_haskey(dict, "bool1"));
929 qobject_unref(dict);
931 dict = qemu_opts_to_qdict_filtered(opts, NULL, &opts_list_02, false);
932 g_assert(dict != NULL);
933 g_assert_cmpstr(qdict_get_str(dict, "str1"), ==, "foo");
934 g_assert_cmpstr(qdict_get_str(dict, "str2"), ==, "");
935 g_assert_cmpstr(qdict_get_str(dict, "bool1"), ==, "off");
936 g_assert_false(qdict_haskey(dict, "str3"));
937 g_assert_false(qdict_haskey(dict, "number1"));
938 g_assert_false(qdict_haskey(dict, "number2"));
939 qobject_unref(dict);
941 /* Now delete converted options from opts */
942 dict = qemu_opts_to_qdict_filtered(opts, NULL, &opts_list_01, true);
943 g_assert(dict != NULL);
944 g_assert_cmpstr(qdict_get_str(dict, "str1"), ==, "foo");
945 g_assert_cmpstr(qdict_get_str(dict, "str2"), ==, "");
946 g_assert_cmpstr(qdict_get_str(dict, "str3"), ==, "bar");
947 g_assert_cmpstr(qdict_get_str(dict, "number1"), ==, "42");
948 g_assert_false(qdict_haskey(dict, "number2"));
949 g_assert_false(qdict_haskey(dict, "bool1"));
950 qobject_unref(dict);
952 dict = qemu_opts_to_qdict_filtered(opts, NULL, &opts_list_02, true);
953 g_assert(dict != NULL);
954 g_assert_cmpstr(qdict_get_str(dict, "bool1"), ==, "off");
955 g_assert_false(qdict_haskey(dict, "str1"));
956 g_assert_false(qdict_haskey(dict, "str2"));
957 g_assert_false(qdict_haskey(dict, "str3"));
958 g_assert_false(qdict_haskey(dict, "number1"));
959 g_assert_false(qdict_haskey(dict, "number2"));
960 qobject_unref(dict);
962 g_assert_true(QTAILQ_EMPTY(&opts->head));
964 qemu_opts_del(opts);
965 qemu_opts_free(merged);
968 static void test_opts_to_qdict_duplicates(void)
970 QemuOpts *opts;
971 QemuOpt *opt;
972 QDict *dict;
974 opts = qemu_opts_parse(&opts_list_03, "foo=a,foo=b", false, &error_abort);
975 g_assert(opts != NULL);
977 /* Verify that opts has two options with the same name */
978 opt = QTAILQ_FIRST(&opts->head);
979 g_assert_cmpstr(opt->name, ==, "foo");
980 g_assert_cmpstr(opt->str , ==, "a");
982 opt = QTAILQ_NEXT(opt, next);
983 g_assert_cmpstr(opt->name, ==, "foo");
984 g_assert_cmpstr(opt->str , ==, "b");
986 opt = QTAILQ_NEXT(opt, next);
987 g_assert(opt == NULL);
989 /* In the conversion to QDict, the last one wins */
990 dict = qemu_opts_to_qdict(opts, NULL);
991 g_assert(dict != NULL);
992 g_assert_cmpstr(qdict_get_str(dict, "foo"), ==, "b");
993 qobject_unref(dict);
995 /* The last one still wins if entries are deleted, and both are deleted */
996 dict = qemu_opts_to_qdict_filtered(opts, NULL, NULL, true);
997 g_assert(dict != NULL);
998 g_assert_cmpstr(qdict_get_str(dict, "foo"), ==, "b");
999 qobject_unref(dict);
1001 g_assert_true(QTAILQ_EMPTY(&opts->head));
1003 qemu_opts_del(opts);
1006 int main(int argc, char *argv[])
1008 register_opts();
1009 g_test_init(&argc, &argv, NULL);
1010 g_test_add_func("/qemu-opts/find_unknown_opts", test_find_unknown_opts);
1011 g_test_add_func("/qemu-opts/find_opts", test_qemu_find_opts);
1012 g_test_add_func("/qemu-opts/opts_create", test_qemu_opts_create);
1013 g_test_add_func("/qemu-opts/opt_get", test_qemu_opt_get);
1014 g_test_add_func("/qemu-opts/opt_get_bool", test_qemu_opt_get_bool);
1015 g_test_add_func("/qemu-opts/opt_get_number", test_qemu_opt_get_number);
1016 g_test_add_func("/qemu-opts/opt_get_size", test_qemu_opt_get_size);
1017 g_test_add_func("/qemu-opts/opt_unset", test_qemu_opt_unset);
1018 g_test_add_func("/qemu-opts/opts_reset", test_qemu_opts_reset);
1019 g_test_add_func("/qemu-opts/opts_set", test_qemu_opts_set);
1020 g_test_add_func("/qemu-opts/opts_parse/general", test_opts_parse);
1021 g_test_add_func("/qemu-opts/opts_parse/bool", test_opts_parse_bool);
1022 g_test_add_func("/qemu-opts/opts_parse/number", test_opts_parse_number);
1023 g_test_add_func("/qemu-opts/opts_parse/size", test_opts_parse_size);
1024 g_test_add_func("/qemu-opts/has_help_option", test_has_help_option);
1025 g_test_add_func("/qemu-opts/append_to_null", test_opts_append_to_null);
1026 g_test_add_func("/qemu-opts/append", test_opts_append);
1027 g_test_add_func("/qemu-opts/to_qdict/basic", test_opts_to_qdict_basic);
1028 g_test_add_func("/qemu-opts/to_qdict/filtered", test_opts_to_qdict_filtered);
1029 g_test_add_func("/qemu-opts/to_qdict/duplicates", test_opts_to_qdict_duplicates);
1030 g_test_run();
1031 return 0;