1
2
3
4
5
6
7
8
9
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"
18
19
20static QemuOptsList opts_list_01 = {
21 .name = "opts_list_01",
22 .head = QTAILQ_HEAD_INITIALIZER(opts_list_01.head),
23 .desc = {
24 {
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,
42 },
43 { }
44 },
45};
46
47static QemuOptsList opts_list_02 = {
48 .name = "opts_list_02",
49 .head = QTAILQ_HEAD_INITIALIZER(opts_list_02.head),
50 .desc = {
51 {
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,
72 },
73 { }
74 },
75};
76
77static 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
83 { }
84 },
85};
86
87static void register_opts(void)
88{
89 qemu_add_opts(&opts_list_01);
90 qemu_add_opts(&opts_list_02);
91 qemu_add_opts(&opts_list_03);
92}
93
94static void test_find_unknown_opts(void)
95{
96 QemuOptsList *list;
97 Error *err = NULL;
98
99
100 list = qemu_find_opts_err("unknown", &err);
101 g_assert(list == NULL);
102 error_free_or_abort(&err);
103}
104
105static void test_qemu_find_opts(void)
106{
107 QemuOptsList *list;
108
109
110 list = qemu_find_opts("opts_list_01");
111 g_assert(list != NULL);
112 g_assert_cmpstr(list->name, ==, "opts_list_01");
113}
114
115static void test_qemu_opts_create(void)
116{
117 QemuOptsList *list;
118 QemuOpts *opts;
119
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");
124
125
126 opts = qemu_opts_find(list, NULL);
127 g_assert(opts == NULL);
128
129
130 opts = qemu_opts_create(list, NULL, 0, &error_abort);
131 g_assert(opts != NULL);
132 g_assert(!QTAILQ_EMPTY(&list->head));
133
134
135 opts = qemu_opts_find(list, NULL);
136 g_assert(opts != NULL);
137
138 qemu_opts_del(opts);
139
140
141 opts = qemu_opts_find(list, NULL);
142 g_assert(opts == NULL);
143}
144
145static void test_qemu_opt_get(void)
146{
147 QemuOptsList *list;
148 QemuOpts *opts;
149 const char *opt = NULL;
150
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");
155
156
157 opts = qemu_opts_find(list, NULL);
158 g_assert(opts == NULL);
159
160
161 opts = qemu_opts_create(list, NULL, 0, &error_abort);
162 g_assert(opts != NULL);
163 g_assert(!QTAILQ_EMPTY(&list->head));
164
165
166 opt = qemu_opt_get(opts, "str2");
167 g_assert(opt == NULL);
168
169 qemu_opt_set(opts, "str2", "value", &error_abort);
170
171
172 opt = qemu_opt_get(opts, "str2");
173 g_assert_cmpstr(opt, ==, "value");
174
175 qemu_opt_set(opts, "str2", "value2", &error_abort);
176
177
178 opt = qemu_opt_get(opts, "str2");
179 g_assert_cmpstr(opt, ==, "value2");
180
181 qemu_opts_del(opts);
182
183
184 opts = qemu_opts_find(list, NULL);
185 g_assert(opts == NULL);
186}
187
188static void test_qemu_opt_get_bool(void)
189{
190 Error *err = NULL;
191 QemuOptsList *list;
192 QemuOpts *opts;
193 bool opt;
194
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");
199
200
201 opts = qemu_opts_find(list, NULL);
202 g_assert(opts == NULL);
203
204
205 opts = qemu_opts_create(list, NULL, 0, &error_abort);
206 g_assert(opts != NULL);
207 g_assert(!QTAILQ_EMPTY(&list->head));
208
209
210 opt = qemu_opt_get_bool(opts, "bool1", false);
211 g_assert(opt == false);
212
213 qemu_opt_set_bool(opts, "bool1", true, &err);
214 g_assert(!err);
215
216
217 opt = qemu_opt_get_bool(opts, "bool1", false);
218 g_assert(opt == true);
219
220
221 qemu_opt_set_bool(opts, "bool1", false, &err);
222 g_assert(!err);
223
224 opt = qemu_opt_get_bool(opts, "bool1", true);
225 g_assert(opt == false);
226
227 qemu_opts_del(opts);
228
229
230 opts = qemu_opts_find(list, NULL);
231 g_assert(opts == NULL);
232}
233
234static void test_qemu_opt_get_number(void)
235{
236 Error *err = NULL;
237 QemuOptsList *list;
238 QemuOpts *opts;
239 uint64_t opt;
240
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");
245
246
247 opts = qemu_opts_find(list, NULL);
248 g_assert(opts == NULL);
249
250
251 opts = qemu_opts_create(list, NULL, 0, &error_abort);
252 g_assert(opts != NULL);
253 g_assert(!QTAILQ_EMPTY(&list->head));
254
255
256 opt = qemu_opt_get_number(opts, "number1", 5);
257 g_assert(opt == 5);
258
259 qemu_opt_set_number(opts, "number1", 10, &err);
260 g_assert(!err);
261
262
263 opt = qemu_opt_get_number(opts, "number1", 5);
264 g_assert(opt == 10);
265
266
267 qemu_opt_set_number(opts, "number1", 15, &err);
268 g_assert(!err);
269
270 opt = qemu_opt_get_number(opts, "number1", 5);
271 g_assert(opt == 15);
272
273 qemu_opts_del(opts);
274
275
276 opts = qemu_opts_find(list, NULL);
277 g_assert(opts == NULL);
278}
279
280static void test_qemu_opt_get_size(void)
281{
282 QemuOptsList *list;
283 QemuOpts *opts;
284 uint64_t opt;
285 QDict *dict;
286
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");
291
292
293 opts = qemu_opts_find(list, NULL);
294 g_assert(opts == NULL);
295
296
297 opts = qemu_opts_create(list, NULL, 0, &error_abort);
298 g_assert(opts != NULL);
299 g_assert(!QTAILQ_EMPTY(&list->head));
300
301
302 opt = qemu_opt_get_size(opts, "size1", 5);
303 g_assert(opt == 5);
304
305 dict = qdict_new();
306 g_assert(dict != NULL);
307
308 qdict_put_str(dict, "size1", "10");
309
310 qemu_opts_absorb_qdict(opts, dict, &error_abort);
311 g_assert(error_abort == NULL);
312
313
314 opt = qemu_opt_get_size(opts, "size1", 5);
315 g_assert(opt == 10);
316
317
318 qdict_put_str(dict, "size1", "15");
319
320 qemu_opts_absorb_qdict(opts, dict, &error_abort);
321 g_assert(error_abort == NULL);
322
323
324 opt = qemu_opt_get_size(opts, "size1", 5);
325 g_assert(opt == 15);
326
327 qdict_del(dict, "size1");
328 g_free(dict);
329
330 qemu_opts_del(opts);
331
332
333 opts = qemu_opts_find(list, NULL);
334 g_assert(opts == NULL);
335}
336
337static void test_qemu_opt_unset(void)
338{
339 QemuOpts *opts;
340 const char *value;
341 int ret;
342
343
344 opts = qemu_opts_parse(&opts_list_03, "key=value", false, NULL);
345 g_assert(opts != NULL);
346
347
348 value = qemu_opt_get(opts, "key");
349 g_assert_cmpstr(value, ==, "value");
350
351
352 qemu_opt_set(opts, "key", "value2", &error_abort);
353
354 value = qemu_opt_get(opts, "key");
355 g_assert_cmpstr(value, ==, "value2");
356
357
358 ret = qemu_opt_unset(opts, "key");
359 g_assert(ret == 0);
360
361
362 value = qemu_opt_get(opts, "key");
363 g_assert_cmpstr(value, ==, "value");
364
365 qemu_opts_del(opts);
366}
367
368static void test_qemu_opts_reset(void)
369{
370 Error *err = NULL;
371 QemuOptsList *list;
372 QemuOpts *opts;
373 uint64_t opt;
374
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");
379
380
381 opts = qemu_opts_find(list, NULL);
382 g_assert(opts == NULL);
383
384
385 opts = qemu_opts_create(list, NULL, 0, &error_abort);
386 g_assert(opts != NULL);
387 g_assert(!QTAILQ_EMPTY(&list->head));
388
389
390 opt = qemu_opt_get_number(opts, "number1", 5);
391 g_assert(opt == 5);
392
393 qemu_opt_set_number(opts, "number1", 10, &err);
394 g_assert(!err);
395
396
397 opt = qemu_opt_get_number(opts, "number1", 5);
398 g_assert(opt == 10);
399
400 qemu_opts_reset(list);
401
402
403 opts = qemu_opts_find(list, NULL);
404 g_assert(opts == NULL);
405}
406
407static void test_qemu_opts_set(void)
408{
409 Error *err = NULL;
410 QemuOptsList *list;
411 QemuOpts *opts;
412 const char *opt;
413
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");
418
419
420 opts = qemu_opts_find(list, NULL);
421 g_assert(opts == NULL);
422
423
424 qemu_opts_set(list, NULL, "str3", "value", &err);
425 g_assert(!err);
426 g_assert(!QTAILQ_EMPTY(&list->head));
427
428
429 opts = qemu_opts_find(list, NULL);
430 g_assert(opts != NULL);
431
432
433 opt = qemu_opt_get(opts, "str3");
434 g_assert_cmpstr(opt, ==, "value");
435
436 qemu_opts_del(opts);
437
438
439 opts = qemu_opts_find(list, NULL);
440 g_assert(opts == NULL);
441}
442
443static int opts_count_iter(void *opaque, const char *name, const char *value,
444 Error **errp)
445{
446 (*(size_t *)opaque)++;
447 return 0;
448}
449
450static size_t opts_count(QemuOpts *opts)
451{
452 size_t n = 0;
453
454 qemu_opt_foreach(opts, opts_count_iter, &n, NULL);
455 return n;
456}
457
458static void test_opts_parse(void)
459{
460 Error *err = NULL;
461 QemuOpts *opts;
462 char long_key[129];
463 char *params;
464
465
466 opts = qemu_opts_parse(&opts_list_03, "", false, &error_abort);
467 g_assert_cmpuint(opts_count(opts), ==, 0);
468
469
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");
473
474
475 memset(long_key, 'a', 127);
476 long_key[127] = 'z';
477 long_key[128] = 0;
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");
482
483
484 opts = qemu_opts_parse(&opts_list_03, params, NULL, &error_abort);
485 g_assert(opts_count(opts) == 1);
486 long_key[127] = 0;
487 g_assert_cmpstr(qemu_opt_get(opts, long_key), ==, "v");
488 g_free(params);
489
490
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");
496
497
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");
502
503
504
505
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");
509
510
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");
514
515
516 opts = qemu_opts_parse(&opts_list_03, "x=y,id=foo", false, &err);
517 error_free_or_abort(&err);
518 g_assert(!opts);
519
520
521
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");
525 g_assert_cmpstr(qemu_opt_get(opts, "x"), ==, ",id=bar");
526
527
528 opts = qemu_opts_parse(&opts_list_01, "id=666", false, &err);
529 error_free_or_abort(&err);
530 g_assert(!opts);
531
532
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"), ==, "");
539
540
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");
544
545
546 opts = qemu_opts_parse(&opts_list_03, "an,noaus,noaus=", true,
547 &error_abort);
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"), ==, "");
552
553
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"), ==, "");
557
558
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");
563
564
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");
568
569
570 opts = qemu_opts_parse(&opts_list_01, "nonexistent=", false, &err);
571 error_free_or_abort(&err);
572 g_assert(!opts);
573
574 qemu_opts_reset(&opts_list_01);
575 qemu_opts_reset(&opts_list_03);
576}
577
578static void test_opts_parse_bool(void)
579{
580 Error *err = NULL;
581 QemuOpts *opts;
582
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));
588
589 opts = qemu_opts_parse(&opts_list_02, "bool1=offer", false, &err);
590 error_free_or_abort(&err);
591 g_assert(!opts);
592
593 qemu_opts_reset(&opts_list_02);
594}
595
596static void test_opts_parse_number(void)
597{
598 Error *err = NULL;
599 QemuOpts *opts;
600
601
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);
605
606
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);
613
614
615 opts = qemu_opts_parse(&opts_list_01, "number1=18446744073709551616",
616 false, &err);
617 error_free_or_abort(&err);
618 g_assert(!opts);
619
620
621 opts = qemu_opts_parse(&opts_list_01, "number1=-18446744073709551616",
622 false, &err);
623 error_free_or_abort(&err);
624 g_assert(!opts);
625
626
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);
632
633
634 opts = qemu_opts_parse(&opts_list_01, "number1=", false, &err);
635 error_free_or_abort(&err);
636 g_assert(!opts);
637 opts = qemu_opts_parse(&opts_list_01, "number1=eins", false, &err);
638 error_free_or_abort(&err);
639 g_assert(!opts);
640
641
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);
646
647
648 opts = qemu_opts_parse(&opts_list_01, "number1=3.14", false, &err);
649 error_free_or_abort(&err);
650 g_assert(!opts);
651 opts = qemu_opts_parse(&opts_list_01, "number1=08", false, &err);
652 error_free_or_abort(&err);
653 g_assert(!opts);
654 opts = qemu_opts_parse(&opts_list_01, "number1=0 ", false, &err);
655 error_free_or_abort(&err);
656 g_assert(!opts);
657
658 qemu_opts_reset(&opts_list_01);
659}
660
661static void test_opts_parse_size(void)
662{
663 Error *err = NULL;
664 QemuOpts *opts;
665
666
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);
670
671
672
673
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);
686
687
688 opts = qemu_opts_parse(&opts_list_02,
689 "size1=9223372036854774784,"
690 "size2=9223372036854775295",
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);
697
698
699 opts = qemu_opts_parse(&opts_list_02,
700 "size1=18446744073709549568,"
701 "size2=18446744073709550591",
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);
708
709
710 opts = qemu_opts_parse(&opts_list_02, "size1=-1", false, &err);
711 error_free_or_abort(&err);
712 g_assert(!opts);
713 opts = qemu_opts_parse(&opts_list_02,
714 "size1=18446744073709550592",
715 false, &err);
716 error_free_or_abort(&err);
717 g_assert(!opts);
718
719
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);
732
733
734 opts = qemu_opts_parse(&opts_list_02, "size1=16777216T",
735 false, &err);
736 error_free_or_abort(&err);
737 g_assert(!opts);
738
739
740 opts = qemu_opts_parse(&opts_list_02, "size1=16E", false, &err);
741 error_free_or_abort(&err);
742 g_assert(!opts);
743 opts = qemu_opts_parse(&opts_list_02, "size1=16Gi", false, &err);
744 error_free_or_abort(&err);
745 g_assert(!opts);
746
747 qemu_opts_reset(&opts_list_02);
748}
749
750static void append_verify_list_01(QemuOptDesc *desc, bool with_overlapping)
751{
752 int i = 0;
753
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");
760 i++;
761
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);
766 i++;
767 }
768
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);
773 i++;
774
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);
780 i++;
781
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);
786 i++;
787
788 g_assert_cmpstr(desc[i].name, ==, NULL);
789}
790
791static void append_verify_list_02(QemuOptDesc *desc)
792{
793 int i = 0;
794
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);
799 i++;
800
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);
805 i++;
806
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);
811 i++;
812
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);
817 i++;
818
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);
823 i++;
824
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);
829 i++;
830
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);
835}
836
837static void test_opts_append_to_null(void)
838{
839 QemuOptsList *merged;
840
841 merged = qemu_opts_append(NULL, &opts_list_01);
842 g_assert(merged != &opts_list_01);
843
844 g_assert_cmpstr(merged->name, ==, NULL);
845 g_assert_cmpstr(merged->implied_opt_name, ==, NULL);
846 g_assert_false(merged->merge_lists);
847
848 append_verify_list_01(merged->desc, true);
849
850 qemu_opts_free(merged);
851}
852
853static void test_opts_append(void)
854{
855 QemuOptsList *first, *merged;
856
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);
861
862 g_assert_cmpstr(merged->name, ==, NULL);
863 g_assert_cmpstr(merged->implied_opt_name, ==, NULL);
864 g_assert_false(merged->merge_lists);
865
866 append_verify_list_02(&merged->desc[0]);
867 append_verify_list_01(&merged->desc[7], false);
868
869 qemu_opts_free(merged);
870}
871
872static void test_opts_to_qdict_basic(void)
873{
874 QemuOpts *opts;
875 QDict *dict;
876
877 opts = qemu_opts_parse(&opts_list_01, "str1=foo,str2=,str3=bar,number1=42",
878 false, &error_abort);
879 g_assert(opts != NULL);
880
881 dict = qemu_opts_to_qdict(opts, NULL);
882 g_assert(dict != NULL);
883
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"));
889
890 QDECREF(dict);
891 qemu_opts_del(opts);
892}
893
894static void test_opts_to_qdict_filtered(void)
895{
896 QemuOptsList *first, *merged;
897 QemuOpts *opts;
898 QDict *dict;
899
900 first = qemu_opts_append(NULL, &opts_list_02);
901 merged = qemu_opts_append(first, &opts_list_01);
902
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);
907
908
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"));
917 QDECREF(dict);
918
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"));
927 QDECREF(dict);
928
929
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"));
938 QDECREF(dict);
939
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"));
948 QDECREF(dict);
949
950 g_assert_true(QTAILQ_EMPTY(&opts->head));
951
952 qemu_opts_del(opts);
953 qemu_opts_free(merged);
954}
955
956static void test_opts_to_qdict_duplicates(void)
957{
958 QemuOpts *opts;
959 QemuOpt *opt;
960 QDict *dict;
961
962 opts = qemu_opts_parse(&opts_list_03, "foo=a,foo=b", false, &error_abort);
963 g_assert(opts != NULL);
964
965
966 opt = QTAILQ_FIRST(&opts->head);
967 g_assert_cmpstr(opt->name, ==, "foo");
968 g_assert_cmpstr(opt->str , ==, "a");
969
970 opt = QTAILQ_NEXT(opt, next);
971 g_assert_cmpstr(opt->name, ==, "foo");
972 g_assert_cmpstr(opt->str , ==, "b");
973
974 opt = QTAILQ_NEXT(opt, next);
975 g_assert(opt == NULL);
976
977
978 dict = qemu_opts_to_qdict(opts, NULL);
979 g_assert(dict != NULL);
980 g_assert_cmpstr(qdict_get_str(dict, "foo"), ==, "b");
981 QDECREF(dict);
982
983
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");
987 QDECREF(dict);
988
989 g_assert_true(QTAILQ_EMPTY(&opts->head));
990
991 qemu_opts_del(opts);
992}
993
994int main(int argc, char *argv[])
995{
996 register_opts();
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);
1017 g_test_run();
1018 return 0;
1019}
1020