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.
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
),
26 .type
= QEMU_OPT_STRING
,
27 .help
= "Help texts are preserved in qemu_opts_append",
28 .def_value_str
= "default",
31 .type
= QEMU_OPT_STRING
,
34 .type
= QEMU_OPT_STRING
,
37 .type
= QEMU_OPT_NUMBER
,
38 .help
= "Having help texts only for some options is okay",
41 .type
= QEMU_OPT_NUMBER
,
47 static QemuOptsList opts_list_02
= {
48 .name
= "opts_list_02",
49 .head
= QTAILQ_HEAD_INITIALIZER(opts_list_02
.head
),
53 .type
= QEMU_OPT_STRING
,
56 .type
= QEMU_OPT_STRING
,
59 .type
= QEMU_OPT_BOOL
,
62 .type
= QEMU_OPT_BOOL
,
65 .type
= QEMU_OPT_SIZE
,
68 .type
= QEMU_OPT_SIZE
,
71 .type
= QEMU_OPT_SIZE
,
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
),
82 /* no elements => accept any params */
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)
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)
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)
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
);
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)
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");
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)
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);
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)
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);
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);
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);
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)
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);
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);
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);
321 qdict_del(dict
, "size1");
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)
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");
355 /* after reset the value should be the parsed/default one */
356 value
= qemu_opt_get(opts
, "key");
357 g_assert_cmpstr(value
, ==, "value");
362 static void test_qemu_opts_reset(void)
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);
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);
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)
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");
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
,
436 (*(size_t *)opaque
)++;
440 static size_t opts_count(QemuOpts
*opts
)
444 qemu_opt_foreach(opts
, opts_count_iter
, &n
, NULL
);
448 static void test_opts_parse(void)
454 opts
= qemu_opts_parse(&opts_list_03
, "", false, &error_abort
);
455 g_assert_cmpuint(opts_count(opts
), ==, 0);
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");
488 opts
= qemu_opts_parse(&opts_list_03
, "x=y,id=foo", false, &err
);
489 error_free_or_abort(&err
);
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");
500 opts
= qemu_opts_parse(&opts_list_01
, "id=666", false, &err
);
501 error_free_or_abort(&err
);
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");
518 opts
= qemu_opts_parse(&opts_list_03
, "an,noaus,noaus=", true,
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");
542 opts
= qemu_opts_parse(&opts_list_01
, "nonexistent=", false, &err
);
543 error_free_or_abort(&err
);
546 qemu_opts_reset(&opts_list_01
);
547 qemu_opts_reset(&opts_list_03
);
550 static void test_opts_parse_bool(void)
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
);
565 qemu_opts_reset(&opts_list_02
);
568 static void test_opts_parse_number(void)
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",
589 error_free_or_abort(&err
);
592 /* Below lower limit */
593 opts
= qemu_opts_parse(&opts_list_01
, "number1=-18446744073709551616",
595 error_free_or_abort(&err
);
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);
606 opts
= qemu_opts_parse(&opts_list_01
, "number1=", false, &err
);
607 error_free_or_abort(&err
);
609 opts
= qemu_opts_parse(&opts_list_01
, "number1=eins", false, &err
);
610 error_free_or_abort(&err
);
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);
620 opts
= qemu_opts_parse(&opts_list_01
, "number1=3.14", false, &err
);
621 error_free_or_abort(&err
);
623 opts
= qemu_opts_parse(&opts_list_01
, "number1=08", false, &err
);
624 error_free_or_abort(&err
);
626 opts
= qemu_opts_parse(&opts_list_01
, "number1=0 ", false, &err
);
627 error_free_or_abort(&err
);
630 qemu_opts_reset(&opts_list_01
);
633 static void test_opts_parse_size(void)
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);
682 opts
= qemu_opts_parse(&opts_list_02
, "size1=-1", false, &err
);
683 error_free_or_abort(&err
);
685 opts
= qemu_opts_parse(&opts_list_02
,
686 "size1=18446744073709550592", /* fffffffffffffc00 */
688 error_free_or_abort(&err
);
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",
707 error_free_or_abort(&err
);
711 opts
= qemu_opts_parse(&opts_list_02
, "size1=16E", false, &err
);
712 error_free_or_abort(&err
);
714 opts
= qemu_opts_parse(&opts_list_02
, "size1=16Gi", false, &err
);
715 error_free_or_abort(&err
);
718 qemu_opts_reset(&opts_list_02
);
721 static void test_has_help_option(void)
723 static const struct {
725 /* expected value of qemu_opt_has_help_opt() with implied=false */
727 /* expected value of qemu_opt_has_help_opt() with implied=true */
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 },
746 for (i
= 0; i
< ARRAY_SIZE(test
); i
++) {
747 g_assert_cmpint(has_help_option(test
[i
].params
),
749 opts
= qemu_opts_parse(&opts_list_03
, test
[i
].params
, false,
751 g_assert_cmpint(qemu_opt_has_help_opt(opts
),
754 opts
= qemu_opts_parse(&opts_list_03
, test
[i
].params
, true,
756 g_assert_cmpint(qemu_opt_has_help_opt(opts
),
757 ==, test
[i
].expect_implied
);
762 static void append_verify_list_01(QemuOptDesc
*desc
, bool with_overlapping
)
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");
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
);
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
);
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
);
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
);
800 g_assert_cmpstr(desc
[i
].name
, ==, NULL
);
803 static void append_verify_list_02(QemuOptDesc
*desc
)
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
);
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
);
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
);
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
);
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
);
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
);
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)
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"));
906 static void test_opts_to_qdict_filtered(void)
908 QemuOptsList
*first
, *merged
;
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"));
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"));
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"));
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"));
962 g_assert_true(QTAILQ_EMPTY(&opts
->head
));
965 qemu_opts_free(merged
);
968 static void test_opts_to_qdict_duplicates(void)
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");
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");
1001 g_assert_true(QTAILQ_EMPTY(&opts
->head
));
1003 qemu_opts_del(opts
);
1006 int main(int argc
, char *argv
[])
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
);