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/cutils.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)
195 list
= qemu_find_opts("opts_list_02");
196 g_assert(list
!= NULL
);
197 g_assert(QTAILQ_EMPTY(&list
->head
));
198 g_assert_cmpstr(list
->name
, ==, "opts_list_02");
200 /* should not find anything at this point */
201 opts
= qemu_opts_find(list
, NULL
);
202 g_assert(opts
== NULL
);
204 /* create the opts */
205 opts
= qemu_opts_create(list
, NULL
, 0, &error_abort
);
206 g_assert(opts
!= NULL
);
207 g_assert(!QTAILQ_EMPTY(&list
->head
));
209 /* haven't set anything to bool1 yet, so defval should be returned */
210 opt
= qemu_opt_get_bool(opts
, "bool1", false);
211 g_assert(opt
== false);
213 qemu_opt_set_bool(opts
, "bool1", true, &err
);
216 /* now we have set bool1, should know about it */
217 opt
= qemu_opt_get_bool(opts
, "bool1", false);
218 g_assert(opt
== true);
220 /* having reset the value, opt should be the reset one not defval */
221 qemu_opt_set_bool(opts
, "bool1", false, &err
);
224 opt
= qemu_opt_get_bool(opts
, "bool1", true);
225 g_assert(opt
== false);
229 /* should not find anything at this point */
230 opts
= qemu_opts_find(list
, NULL
);
231 g_assert(opts
== NULL
);
234 static void test_qemu_opt_get_number(void)
241 list
= qemu_find_opts("opts_list_01");
242 g_assert(list
!= NULL
);
243 g_assert(QTAILQ_EMPTY(&list
->head
));
244 g_assert_cmpstr(list
->name
, ==, "opts_list_01");
246 /* should not find anything at this point */
247 opts
= qemu_opts_find(list
, NULL
);
248 g_assert(opts
== NULL
);
250 /* create the opts */
251 opts
= qemu_opts_create(list
, NULL
, 0, &error_abort
);
252 g_assert(opts
!= NULL
);
253 g_assert(!QTAILQ_EMPTY(&list
->head
));
255 /* haven't set anything to number1 yet, so defval should be returned */
256 opt
= qemu_opt_get_number(opts
, "number1", 5);
259 qemu_opt_set_number(opts
, "number1", 10, &err
);
262 /* now we have set number1, should know about it */
263 opt
= qemu_opt_get_number(opts
, "number1", 5);
266 /* having reset it, the returned should be the reset one not defval */
267 qemu_opt_set_number(opts
, "number1", 15, &err
);
270 opt
= qemu_opt_get_number(opts
, "number1", 5);
275 /* should not find anything at this point */
276 opts
= qemu_opts_find(list
, NULL
);
277 g_assert(opts
== NULL
);
280 static void test_qemu_opt_get_size(void)
287 list
= qemu_find_opts("opts_list_02");
288 g_assert(list
!= NULL
);
289 g_assert(QTAILQ_EMPTY(&list
->head
));
290 g_assert_cmpstr(list
->name
, ==, "opts_list_02");
292 /* should not find anything at this point */
293 opts
= qemu_opts_find(list
, NULL
);
294 g_assert(opts
== NULL
);
296 /* create the opts */
297 opts
= qemu_opts_create(list
, NULL
, 0, &error_abort
);
298 g_assert(opts
!= NULL
);
299 g_assert(!QTAILQ_EMPTY(&list
->head
));
301 /* haven't set anything to size1 yet, so defval should be returned */
302 opt
= qemu_opt_get_size(opts
, "size1", 5);
306 g_assert(dict
!= NULL
);
308 qdict_put_str(dict
, "size1", "10");
310 qemu_opts_absorb_qdict(opts
, dict
, &error_abort
);
311 g_assert(error_abort
== NULL
);
313 /* now we have set size1, should know about it */
314 opt
= qemu_opt_get_size(opts
, "size1", 5);
318 qdict_put_str(dict
, "size1", "15");
320 qemu_opts_absorb_qdict(opts
, dict
, &error_abort
);
321 g_assert(error_abort
== NULL
);
323 /* test the reset value */
324 opt
= qemu_opt_get_size(opts
, "size1", 5);
327 qdict_del(dict
, "size1");
332 /* should not find anything at this point */
333 opts
= qemu_opts_find(list
, NULL
);
334 g_assert(opts
== NULL
);
337 static void test_qemu_opt_unset(void)
343 /* dynamically initialized (parsed) opts */
344 opts
= qemu_opts_parse(&opts_list_03
, "key=value", false, NULL
);
345 g_assert(opts
!= NULL
);
347 /* check default/parsed value */
348 value
= qemu_opt_get(opts
, "key");
349 g_assert_cmpstr(value
, ==, "value");
351 /* reset it to value2 */
352 qemu_opt_set(opts
, "key", "value2", &error_abort
);
354 value
= qemu_opt_get(opts
, "key");
355 g_assert_cmpstr(value
, ==, "value2");
357 /* unset, valid only for "accept any" */
358 ret
= qemu_opt_unset(opts
, "key");
361 /* after reset the value should be the parsed/default one */
362 value
= qemu_opt_get(opts
, "key");
363 g_assert_cmpstr(value
, ==, "value");
368 static void test_qemu_opts_reset(void)
375 list
= qemu_find_opts("opts_list_01");
376 g_assert(list
!= NULL
);
377 g_assert(QTAILQ_EMPTY(&list
->head
));
378 g_assert_cmpstr(list
->name
, ==, "opts_list_01");
380 /* should not find anything at this point */
381 opts
= qemu_opts_find(list
, NULL
);
382 g_assert(opts
== NULL
);
384 /* create the opts */
385 opts
= qemu_opts_create(list
, NULL
, 0, &error_abort
);
386 g_assert(opts
!= NULL
);
387 g_assert(!QTAILQ_EMPTY(&list
->head
));
389 /* haven't set anything to number1 yet, so defval should be returned */
390 opt
= qemu_opt_get_number(opts
, "number1", 5);
393 qemu_opt_set_number(opts
, "number1", 10, &err
);
396 /* now we have set number1, should know about it */
397 opt
= qemu_opt_get_number(opts
, "number1", 5);
400 qemu_opts_reset(list
);
402 /* should not find anything at this point */
403 opts
= qemu_opts_find(list
, NULL
);
404 g_assert(opts
== NULL
);
407 static void test_qemu_opts_set(void)
414 list
= qemu_find_opts("opts_list_01");
415 g_assert(list
!= NULL
);
416 g_assert(QTAILQ_EMPTY(&list
->head
));
417 g_assert_cmpstr(list
->name
, ==, "opts_list_01");
419 /* should not find anything at this point */
420 opts
= qemu_opts_find(list
, NULL
);
421 g_assert(opts
== NULL
);
423 /* implicitly create opts and set str3 value */
424 qemu_opts_set(list
, NULL
, "str3", "value", &err
);
426 g_assert(!QTAILQ_EMPTY(&list
->head
));
428 /* get the just created opts */
429 opts
= qemu_opts_find(list
, NULL
);
430 g_assert(opts
!= NULL
);
432 /* check the str3 value */
433 opt
= qemu_opt_get(opts
, "str3");
434 g_assert_cmpstr(opt
, ==, "value");
438 /* should not find anything at this point */
439 opts
= qemu_opts_find(list
, NULL
);
440 g_assert(opts
== NULL
);
443 static int opts_count_iter(void *opaque
, const char *name
, const char *value
,
446 (*(size_t *)opaque
)++;
450 static size_t opts_count(QemuOpts
*opts
)
454 qemu_opt_foreach(opts
, opts_count_iter
, &n
, NULL
);
458 static void test_opts_parse(void)
466 opts
= qemu_opts_parse(&opts_list_03
, "", false, &error_abort
);
467 g_assert_cmpuint(opts_count(opts
), ==, 0);
470 opts
= qemu_opts_parse(&opts_list_03
, "=val", false, &error_abort
);
471 g_assert_cmpuint(opts_count(opts
), ==, 1);
472 g_assert_cmpstr(qemu_opt_get(opts
, ""), ==, "val");
475 memset(long_key
, 'a', 127);
478 params
= g_strdup_printf("%s=v", long_key
);
479 opts
= qemu_opts_parse(&opts_list_03
, params
+ 1, NULL
, &error_abort
);
480 g_assert_cmpuint(opts_count(opts
), ==, 1);
481 g_assert_cmpstr(qemu_opt_get(opts
, long_key
+ 1), ==, "v");
483 /* Overlong key gets truncated */
484 opts
= qemu_opts_parse(&opts_list_03
, params
, NULL
, &error_abort
);
485 g_assert(opts_count(opts
) == 1);
487 g_assert_cmpstr(qemu_opt_get(opts
, long_key
), ==, "v");
490 /* Multiple keys, last one wins */
491 opts
= qemu_opts_parse(&opts_list_03
, "a=1,b=2,,x,a=3",
492 false, &error_abort
);
493 g_assert_cmpuint(opts_count(opts
), ==, 3);
494 g_assert_cmpstr(qemu_opt_get(opts
, "a"), ==, "3");
495 g_assert_cmpstr(qemu_opt_get(opts
, "b"), ==, "2,x");
497 /* Except when it doesn't */
498 opts
= qemu_opts_parse(&opts_list_03
, "id=foo,id=bar",
499 false, &error_abort
);
500 g_assert_cmpuint(opts_count(opts
), ==, 0);
501 g_assert_cmpstr(qemu_opts_id(opts
), ==, "foo");
503 /* TODO Cover low-level access to repeated keys */
505 /* Trailing comma is ignored */
506 opts
= qemu_opts_parse(&opts_list_03
, "x=y,", false, &error_abort
);
507 g_assert_cmpuint(opts_count(opts
), ==, 1);
508 g_assert_cmpstr(qemu_opt_get(opts
, "x"), ==, "y");
510 /* Except when it isn't */
511 opts
= qemu_opts_parse(&opts_list_03
, ",", false, &error_abort
);
512 g_assert_cmpuint(opts_count(opts
), ==, 1);
513 g_assert_cmpstr(qemu_opt_get(opts
, ""), ==, "on");
516 opts
= qemu_opts_parse(&opts_list_03
, "x=y,id=foo", false, &err
);
517 error_free_or_abort(&err
);
519 /* TODO Cover .merge_lists = true */
521 /* Buggy ID recognition */
522 opts
= qemu_opts_parse(&opts_list_03
, "x=,,id=bar", false, &error_abort
);
523 g_assert_cmpuint(opts_count(opts
), ==, 1);
524 g_assert_cmpstr(qemu_opts_id(opts
), ==, "bar"); /* BUG */
525 g_assert_cmpstr(qemu_opt_get(opts
, "x"), ==, ",id=bar");
528 opts
= qemu_opts_parse(&opts_list_01
, "id=666", false, &err
);
529 error_free_or_abort(&err
);
533 opts
= qemu_opts_parse(&opts_list_03
, "an,noaus,noaus=",
534 false, &error_abort
);
535 g_assert_cmpuint(opts_count(opts
), ==, 3);
536 g_assert_cmpstr(qemu_opt_get(opts
, "an"), ==, "on");
537 g_assert_cmpstr(qemu_opt_get(opts
, "aus"), ==, "off");
538 g_assert_cmpstr(qemu_opt_get(opts
, "noaus"), ==, "");
540 /* Implied value, negated empty key */
541 opts
= qemu_opts_parse(&opts_list_03
, "no", false, &error_abort
);
542 g_assert_cmpuint(opts_count(opts
), ==, 1);
543 g_assert_cmpstr(qemu_opt_get(opts
, ""), ==, "off");
546 opts
= qemu_opts_parse(&opts_list_03
, "an,noaus,noaus=", true,
548 g_assert_cmpuint(opts_count(opts
), ==, 3);
549 g_assert_cmpstr(qemu_opt_get(opts
, "implied"), ==, "an");
550 g_assert_cmpstr(qemu_opt_get(opts
, "aus"), ==, "off");
551 g_assert_cmpstr(qemu_opt_get(opts
, "noaus"), ==, "");
553 /* Implied key with empty value */
554 opts
= qemu_opts_parse(&opts_list_03
, ",", true, &error_abort
);
555 g_assert_cmpuint(opts_count(opts
), ==, 1);
556 g_assert_cmpstr(qemu_opt_get(opts
, "implied"), ==, "");
558 /* Implied key with comma value */
559 opts
= qemu_opts_parse(&opts_list_03
, ",,,a=1", true, &error_abort
);
560 g_assert_cmpuint(opts_count(opts
), ==, 2);
561 g_assert_cmpstr(qemu_opt_get(opts
, "implied"), ==, ",");
562 g_assert_cmpstr(qemu_opt_get(opts
, "a"), ==, "1");
564 /* Empty key is not an implied key */
565 opts
= qemu_opts_parse(&opts_list_03
, "=val", true, &error_abort
);
566 g_assert_cmpuint(opts_count(opts
), ==, 1);
567 g_assert_cmpstr(qemu_opt_get(opts
, ""), ==, "val");
570 opts
= qemu_opts_parse(&opts_list_01
, "nonexistent=", false, &err
);
571 error_free_or_abort(&err
);
574 qemu_opts_reset(&opts_list_01
);
575 qemu_opts_reset(&opts_list_03
);
578 static void test_opts_parse_bool(void)
583 opts
= qemu_opts_parse(&opts_list_02
, "bool1=on,bool2=off",
584 false, &error_abort
);
585 g_assert_cmpuint(opts_count(opts
), ==, 2);
586 g_assert(qemu_opt_get_bool(opts
, "bool1", false));
587 g_assert(!qemu_opt_get_bool(opts
, "bool2", true));
589 opts
= qemu_opts_parse(&opts_list_02
, "bool1=offer", false, &err
);
590 error_free_or_abort(&err
);
593 qemu_opts_reset(&opts_list_02
);
596 static void test_opts_parse_number(void)
601 /* Lower limit zero */
602 opts
= qemu_opts_parse(&opts_list_01
, "number1=0", false, &error_abort
);
603 g_assert_cmpuint(opts_count(opts
), ==, 1);
604 g_assert_cmpuint(qemu_opt_get_number(opts
, "number1", 1), ==, 0);
606 /* Upper limit 2^64-1 */
607 opts
= qemu_opts_parse(&opts_list_01
,
608 "number1=18446744073709551615,number2=-1",
609 false, &error_abort
);
610 g_assert_cmpuint(opts_count(opts
), ==, 2);
611 g_assert_cmphex(qemu_opt_get_number(opts
, "number1", 1), ==, UINT64_MAX
);
612 g_assert_cmphex(qemu_opt_get_number(opts
, "number2", 0), ==, UINT64_MAX
);
614 /* Above upper limit */
615 opts
= qemu_opts_parse(&opts_list_01
, "number1=18446744073709551616",
617 error_free_or_abort(&err
);
620 /* Below lower limit */
621 opts
= qemu_opts_parse(&opts_list_01
, "number1=-18446744073709551616",
623 error_free_or_abort(&err
);
627 opts
= qemu_opts_parse(&opts_list_01
, "number1=0x2a,number2=052",
628 false, &error_abort
);
629 g_assert_cmpuint(opts_count(opts
), ==, 2);
630 g_assert_cmpuint(qemu_opt_get_number(opts
, "number1", 1), ==, 42);
631 g_assert_cmpuint(qemu_opt_get_number(opts
, "number2", 0), ==, 42);
634 opts
= qemu_opts_parse(&opts_list_01
, "number1=", false, &err
);
635 error_free_or_abort(&err
);
637 opts
= qemu_opts_parse(&opts_list_01
, "number1=eins", false, &err
);
638 error_free_or_abort(&err
);
641 /* Leading whitespace */
642 opts
= qemu_opts_parse(&opts_list_01
, "number1= \t42",
643 false, &error_abort
);
644 g_assert_cmpuint(opts_count(opts
), ==, 1);
645 g_assert_cmpuint(qemu_opt_get_number(opts
, "number1", 1), ==, 42);
648 opts
= qemu_opts_parse(&opts_list_01
, "number1=3.14", false, &err
);
649 error_free_or_abort(&err
);
651 opts
= qemu_opts_parse(&opts_list_01
, "number1=08", false, &err
);
652 error_free_or_abort(&err
);
654 opts
= qemu_opts_parse(&opts_list_01
, "number1=0 ", false, &err
);
655 error_free_or_abort(&err
);
658 qemu_opts_reset(&opts_list_01
);
661 static void test_opts_parse_size(void)
666 /* Lower limit zero */
667 opts
= qemu_opts_parse(&opts_list_02
, "size1=0", false, &error_abort
);
668 g_assert_cmpuint(opts_count(opts
), ==, 1);
669 g_assert_cmpuint(qemu_opt_get_size(opts
, "size1", 1), ==, 0);
671 /* Note: precision is 53 bits since we're parsing with strtod() */
673 /* Around limit of precision: 2^53-1, 2^53, 2^54 */
674 opts
= qemu_opts_parse(&opts_list_02
,
675 "size1=9007199254740991,"
676 "size2=9007199254740992,"
677 "size3=9007199254740993",
678 false, &error_abort
);
679 g_assert_cmpuint(opts_count(opts
), ==, 3);
680 g_assert_cmphex(qemu_opt_get_size(opts
, "size1", 1),
681 ==, 0x1fffffffffffff);
682 g_assert_cmphex(qemu_opt_get_size(opts
, "size2", 1),
683 ==, 0x20000000000000);
684 g_assert_cmphex(qemu_opt_get_size(opts
, "size3", 1),
685 ==, 0x20000000000000);
687 /* Close to signed upper limit 0x7ffffffffffffc00 (53 msbs set) */
688 opts
= qemu_opts_parse(&opts_list_02
,
689 "size1=9223372036854774784," /* 7ffffffffffffc00 */
690 "size2=9223372036854775295", /* 7ffffffffffffdff */
691 false, &error_abort
);
692 g_assert_cmpuint(opts_count(opts
), ==, 2);
693 g_assert_cmphex(qemu_opt_get_size(opts
, "size1", 1),
694 ==, 0x7ffffffffffffc00);
695 g_assert_cmphex(qemu_opt_get_size(opts
, "size2", 1),
696 ==, 0x7ffffffffffffc00);
698 /* Close to actual upper limit 0xfffffffffffff800 (53 msbs set) */
699 opts
= qemu_opts_parse(&opts_list_02
,
700 "size1=18446744073709549568," /* fffffffffffff800 */
701 "size2=18446744073709550591", /* fffffffffffffbff */
702 false, &error_abort
);
703 g_assert_cmpuint(opts_count(opts
), ==, 2);
704 g_assert_cmphex(qemu_opt_get_size(opts
, "size1", 1),
705 ==, 0xfffffffffffff800);
706 g_assert_cmphex(qemu_opt_get_size(opts
, "size2", 1),
707 ==, 0xfffffffffffff800);
710 opts
= qemu_opts_parse(&opts_list_02
, "size1=-1", false, &err
);
711 error_free_or_abort(&err
);
713 opts
= qemu_opts_parse(&opts_list_02
,
714 "size1=18446744073709550592", /* fffffffffffffc00 */
716 error_free_or_abort(&err
);
720 opts
= qemu_opts_parse(&opts_list_02
, "size1=8b,size2=1.5k,size3=2M",
721 false, &error_abort
);
722 g_assert_cmpuint(opts_count(opts
), ==, 3);
723 g_assert_cmphex(qemu_opt_get_size(opts
, "size1", 0), ==, 8);
724 g_assert_cmphex(qemu_opt_get_size(opts
, "size2", 0), ==, 1536);
725 g_assert_cmphex(qemu_opt_get_size(opts
, "size3", 0), ==, 2 * M_BYTE
);
726 opts
= qemu_opts_parse(&opts_list_02
, "size1=0.1G,size2=16777215T",
727 false, &error_abort
);
728 g_assert_cmpuint(opts_count(opts
), ==, 2);
729 g_assert_cmphex(qemu_opt_get_size(opts
, "size1", 0), ==, G_BYTE
/ 10);
730 g_assert_cmphex(qemu_opt_get_size(opts
, "size2", 0),
731 ==, 16777215 * T_BYTE
);
733 /* Beyond limit with suffix */
734 opts
= qemu_opts_parse(&opts_list_02
, "size1=16777216T",
736 error_free_or_abort(&err
);
740 opts
= qemu_opts_parse(&opts_list_02
, "size1=16E", false, &err
);
741 error_free_or_abort(&err
);
743 opts
= qemu_opts_parse(&opts_list_02
, "size1=16Gi", false, &err
);
744 error_free_or_abort(&err
);
747 qemu_opts_reset(&opts_list_02
);
750 static void append_verify_list_01(QemuOptDesc
*desc
, bool with_overlapping
)
754 if (with_overlapping
) {
755 g_assert_cmpstr(desc
[i
].name
, ==, "str1");
756 g_assert_cmpint(desc
[i
].type
, ==, QEMU_OPT_STRING
);
757 g_assert_cmpstr(desc
[i
].help
, ==,
758 "Help texts are preserved in qemu_opts_append");
759 g_assert_cmpstr(desc
[i
].def_value_str
, ==, "default");
762 g_assert_cmpstr(desc
[i
].name
, ==, "str2");
763 g_assert_cmpint(desc
[i
].type
, ==, QEMU_OPT_STRING
);
764 g_assert_cmpstr(desc
[i
].help
, ==, NULL
);
765 g_assert_cmpstr(desc
[i
].def_value_str
, ==, NULL
);
769 g_assert_cmpstr(desc
[i
].name
, ==, "str3");
770 g_assert_cmpint(desc
[i
].type
, ==, QEMU_OPT_STRING
);
771 g_assert_cmpstr(desc
[i
].help
, ==, NULL
);
772 g_assert_cmpstr(desc
[i
].def_value_str
, ==, NULL
);
775 g_assert_cmpstr(desc
[i
].name
, ==, "number1");
776 g_assert_cmpint(desc
[i
].type
, ==, QEMU_OPT_NUMBER
);
777 g_assert_cmpstr(desc
[i
].help
, ==,
778 "Having help texts only for some options is okay");
779 g_assert_cmpstr(desc
[i
].def_value_str
, ==, NULL
);
782 g_assert_cmpstr(desc
[i
].name
, ==, "number2");
783 g_assert_cmpint(desc
[i
].type
, ==, QEMU_OPT_NUMBER
);
784 g_assert_cmpstr(desc
[i
].help
, ==, NULL
);
785 g_assert_cmpstr(desc
[i
].def_value_str
, ==, NULL
);
788 g_assert_cmpstr(desc
[i
].name
, ==, NULL
);
791 static void append_verify_list_02(QemuOptDesc
*desc
)
795 g_assert_cmpstr(desc
[i
].name
, ==, "str1");
796 g_assert_cmpint(desc
[i
].type
, ==, QEMU_OPT_STRING
);
797 g_assert_cmpstr(desc
[i
].help
, ==, NULL
);
798 g_assert_cmpstr(desc
[i
].def_value_str
, ==, NULL
);
801 g_assert_cmpstr(desc
[i
].name
, ==, "str2");
802 g_assert_cmpint(desc
[i
].type
, ==, QEMU_OPT_STRING
);
803 g_assert_cmpstr(desc
[i
].help
, ==, NULL
);
804 g_assert_cmpstr(desc
[i
].def_value_str
, ==, NULL
);
807 g_assert_cmpstr(desc
[i
].name
, ==, "bool1");
808 g_assert_cmpint(desc
[i
].type
, ==, QEMU_OPT_BOOL
);
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
, ==, "bool2");
814 g_assert_cmpint(desc
[i
].type
, ==, QEMU_OPT_BOOL
);
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
, ==, "size1");
820 g_assert_cmpint(desc
[i
].type
, ==, QEMU_OPT_SIZE
);
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
, ==, "size2");
826 g_assert_cmpint(desc
[i
].type
, ==, QEMU_OPT_SIZE
);
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
, ==, "size3");
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 static void test_opts_append_to_null(void)
839 QemuOptsList
*merged
;
841 merged
= qemu_opts_append(NULL
, &opts_list_01
);
842 g_assert(merged
!= &opts_list_01
);
844 g_assert_cmpstr(merged
->name
, ==, NULL
);
845 g_assert_cmpstr(merged
->implied_opt_name
, ==, NULL
);
846 g_assert_false(merged
->merge_lists
);
848 append_verify_list_01(merged
->desc
, true);
850 qemu_opts_free(merged
);
853 static void test_opts_append(void)
855 QemuOptsList
*first
, *merged
;
857 first
= qemu_opts_append(NULL
, &opts_list_02
);
858 merged
= qemu_opts_append(first
, &opts_list_01
);
859 g_assert(first
!= &opts_list_02
);
860 g_assert(merged
!= &opts_list_01
);
862 g_assert_cmpstr(merged
->name
, ==, NULL
);
863 g_assert_cmpstr(merged
->implied_opt_name
, ==, NULL
);
864 g_assert_false(merged
->merge_lists
);
866 append_verify_list_02(&merged
->desc
[0]);
867 append_verify_list_01(&merged
->desc
[7], false);
869 qemu_opts_free(merged
);
872 static void test_opts_to_qdict_basic(void)
877 opts
= qemu_opts_parse(&opts_list_01
, "str1=foo,str2=,str3=bar,number1=42",
878 false, &error_abort
);
879 g_assert(opts
!= NULL
);
881 dict
= qemu_opts_to_qdict(opts
, NULL
);
882 g_assert(dict
!= NULL
);
884 g_assert_cmpstr(qdict_get_str(dict
, "str1"), ==, "foo");
885 g_assert_cmpstr(qdict_get_str(dict
, "str2"), ==, "");
886 g_assert_cmpstr(qdict_get_str(dict
, "str3"), ==, "bar");
887 g_assert_cmpstr(qdict_get_str(dict
, "number1"), ==, "42");
888 g_assert_false(qdict_haskey(dict
, "number2"));
894 static void test_opts_to_qdict_filtered(void)
896 QemuOptsList
*first
, *merged
;
900 first
= qemu_opts_append(NULL
, &opts_list_02
);
901 merged
= qemu_opts_append(first
, &opts_list_01
);
903 opts
= qemu_opts_parse(merged
,
904 "str1=foo,str2=,str3=bar,bool1=off,number1=42",
905 false, &error_abort
);
906 g_assert(opts
!= NULL
);
908 /* Convert to QDict without deleting from opts */
909 dict
= qemu_opts_to_qdict_filtered(opts
, NULL
, &opts_list_01
, false);
910 g_assert(dict
!= NULL
);
911 g_assert_cmpstr(qdict_get_str(dict
, "str1"), ==, "foo");
912 g_assert_cmpstr(qdict_get_str(dict
, "str2"), ==, "");
913 g_assert_cmpstr(qdict_get_str(dict
, "str3"), ==, "bar");
914 g_assert_cmpstr(qdict_get_str(dict
, "number1"), ==, "42");
915 g_assert_false(qdict_haskey(dict
, "number2"));
916 g_assert_false(qdict_haskey(dict
, "bool1"));
919 dict
= qemu_opts_to_qdict_filtered(opts
, NULL
, &opts_list_02
, false);
920 g_assert(dict
!= NULL
);
921 g_assert_cmpstr(qdict_get_str(dict
, "str1"), ==, "foo");
922 g_assert_cmpstr(qdict_get_str(dict
, "str2"), ==, "");
923 g_assert_cmpstr(qdict_get_str(dict
, "bool1"), ==, "off");
924 g_assert_false(qdict_haskey(dict
, "str3"));
925 g_assert_false(qdict_haskey(dict
, "number1"));
926 g_assert_false(qdict_haskey(dict
, "number2"));
929 /* Now delete converted options from opts */
930 dict
= qemu_opts_to_qdict_filtered(opts
, NULL
, &opts_list_01
, true);
931 g_assert(dict
!= NULL
);
932 g_assert_cmpstr(qdict_get_str(dict
, "str1"), ==, "foo");
933 g_assert_cmpstr(qdict_get_str(dict
, "str2"), ==, "");
934 g_assert_cmpstr(qdict_get_str(dict
, "str3"), ==, "bar");
935 g_assert_cmpstr(qdict_get_str(dict
, "number1"), ==, "42");
936 g_assert_false(qdict_haskey(dict
, "number2"));
937 g_assert_false(qdict_haskey(dict
, "bool1"));
940 dict
= qemu_opts_to_qdict_filtered(opts
, NULL
, &opts_list_02
, true);
941 g_assert(dict
!= NULL
);
942 g_assert_cmpstr(qdict_get_str(dict
, "bool1"), ==, "off");
943 g_assert_false(qdict_haskey(dict
, "str1"));
944 g_assert_false(qdict_haskey(dict
, "str2"));
945 g_assert_false(qdict_haskey(dict
, "str3"));
946 g_assert_false(qdict_haskey(dict
, "number1"));
947 g_assert_false(qdict_haskey(dict
, "number2"));
950 g_assert_true(QTAILQ_EMPTY(&opts
->head
));
953 qemu_opts_free(merged
);
956 static void test_opts_to_qdict_duplicates(void)
962 opts
= qemu_opts_parse(&opts_list_03
, "foo=a,foo=b", false, &error_abort
);
963 g_assert(opts
!= NULL
);
965 /* Verify that opts has two options with the same name */
966 opt
= QTAILQ_FIRST(&opts
->head
);
967 g_assert_cmpstr(opt
->name
, ==, "foo");
968 g_assert_cmpstr(opt
->str
, ==, "a");
970 opt
= QTAILQ_NEXT(opt
, next
);
971 g_assert_cmpstr(opt
->name
, ==, "foo");
972 g_assert_cmpstr(opt
->str
, ==, "b");
974 opt
= QTAILQ_NEXT(opt
, next
);
975 g_assert(opt
== NULL
);
977 /* In the conversion to QDict, the last one wins */
978 dict
= qemu_opts_to_qdict(opts
, NULL
);
979 g_assert(dict
!= NULL
);
980 g_assert_cmpstr(qdict_get_str(dict
, "foo"), ==, "b");
983 /* The last one still wins if entries are deleted, and both are deleted */
984 dict
= qemu_opts_to_qdict_filtered(opts
, NULL
, NULL
, true);
985 g_assert(dict
!= NULL
);
986 g_assert_cmpstr(qdict_get_str(dict
, "foo"), ==, "b");
989 g_assert_true(QTAILQ_EMPTY(&opts
->head
));
994 int main(int argc
, char *argv
[])
997 g_test_init(&argc
, &argv
, NULL
);
998 g_test_add_func("/qemu-opts/find_unknown_opts", test_find_unknown_opts
);
999 g_test_add_func("/qemu-opts/find_opts", test_qemu_find_opts
);
1000 g_test_add_func("/qemu-opts/opts_create", test_qemu_opts_create
);
1001 g_test_add_func("/qemu-opts/opt_get", test_qemu_opt_get
);
1002 g_test_add_func("/qemu-opts/opt_get_bool", test_qemu_opt_get_bool
);
1003 g_test_add_func("/qemu-opts/opt_get_number", test_qemu_opt_get_number
);
1004 g_test_add_func("/qemu-opts/opt_get_size", test_qemu_opt_get_size
);
1005 g_test_add_func("/qemu-opts/opt_unset", test_qemu_opt_unset
);
1006 g_test_add_func("/qemu-opts/opts_reset", test_qemu_opts_reset
);
1007 g_test_add_func("/qemu-opts/opts_set", test_qemu_opts_set
);
1008 g_test_add_func("/qemu-opts/opts_parse/general", test_opts_parse
);
1009 g_test_add_func("/qemu-opts/opts_parse/bool", test_opts_parse_bool
);
1010 g_test_add_func("/qemu-opts/opts_parse/number", test_opts_parse_number
);
1011 g_test_add_func("/qemu-opts/opts_parse/size", test_opts_parse_size
);
1012 g_test_add_func("/qemu-opts/append_to_null", test_opts_append_to_null
);
1013 g_test_add_func("/qemu-opts/append", test_opts_append
);
1014 g_test_add_func("/qemu-opts/to_qdict/basic", test_opts_to_qdict_basic
);
1015 g_test_add_func("/qemu-opts/to_qdict/filtered", test_opts_to_qdict_filtered
);
1016 g_test_add_func("/qemu-opts/to_qdict/duplicates", test_opts_to_qdict_duplicates
);