]> git.proxmox.com Git - mirror_qemu.git/blame - tests/test-qemu-opts.c
check-qjson: Test errors from qobject_from_json()
[mirror_qemu.git] / tests / test-qemu-opts.c
CommitLineData
4ba6fabf
LD
1/*
2 * QemuOpts unit-tests.
3 *
4 * Copyright (C) 2014 Leandro Dorileo <l@dorileo.org>
5 *
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 */
9
681c28a3 10#include "qemu/osdep.h"
694baf57 11#include "qemu/cutils.h"
da34e65c 12#include "qapi/error.h"
4ba6fabf
LD
13#include "qapi/qmp/qstring.h"
14#include "qemu/config-file.h"
15
4ba6fabf
LD
16
17static QemuOptsList opts_list_01 = {
18 .name = "opts_list_01",
19 .head = QTAILQ_HEAD_INITIALIZER(opts_list_01.head),
20 .desc = {
21 {
22 .name = "str1",
23 .type = QEMU_OPT_STRING,
24 },{
25 .name = "str2",
26 .type = QEMU_OPT_STRING,
27 },{
28 .name = "str3",
29 .type = QEMU_OPT_STRING,
30 },{
31 .name = "number1",
32 .type = QEMU_OPT_NUMBER,
694baf57
MA
33 },{
34 .name = "number2",
35 .type = QEMU_OPT_NUMBER,
4ba6fabf
LD
36 },
37 { /* end of list */ }
38 },
39};
40
41static QemuOptsList opts_list_02 = {
42 .name = "opts_list_02",
43 .head = QTAILQ_HEAD_INITIALIZER(opts_list_02.head),
44 .desc = {
45 {
46 .name = "str1",
47 .type = QEMU_OPT_STRING,
694baf57
MA
48 },{
49 .name = "str2",
50 .type = QEMU_OPT_STRING,
4ba6fabf
LD
51 },{
52 .name = "bool1",
53 .type = QEMU_OPT_BOOL,
54 },{
694baf57
MA
55 .name = "bool2",
56 .type = QEMU_OPT_BOOL,
4ba6fabf
LD
57 },{
58 .name = "size1",
59 .type = QEMU_OPT_SIZE,
694baf57
MA
60 },{
61 .name = "size2",
62 .type = QEMU_OPT_SIZE,
63 },{
64 .name = "size3",
65 .type = QEMU_OPT_SIZE,
4ba6fabf
LD
66 },
67 { /* end of list */ }
68 },
69};
70
748bfb4e 71static QemuOptsList opts_list_03 = {
4ba6fabf 72 .name = "opts_list_03",
694baf57 73 .implied_opt_name = "implied",
4ba6fabf
LD
74 .head = QTAILQ_HEAD_INITIALIZER(opts_list_03.head),
75 .desc = {
76 /* no elements => accept any params */
77 { /* end of list */ }
78 },
79};
80
81static void register_opts(void)
82{
83 qemu_add_opts(&opts_list_01);
84 qemu_add_opts(&opts_list_02);
85 qemu_add_opts(&opts_list_03);
86}
87
88static void test_find_unknown_opts(void)
89{
90 QemuOptsList *list;
91 Error *err = NULL;
92
93 /* should not return anything, we don't have an "unknown" option */
94 list = qemu_find_opts_err("unknown", &err);
95 g_assert(list == NULL);
96 g_assert(err);
97 error_free(err);
98}
99
100static void test_qemu_find_opts(void)
101{
102 QemuOptsList *list;
103
104 /* we have an "opts_list_01" option, should return it */
105 list = qemu_find_opts("opts_list_01");
106 g_assert(list != NULL);
107 g_assert_cmpstr(list->name, ==, "opts_list_01");
108}
109
110static void test_qemu_opts_create(void)
111{
112 QemuOptsList *list;
113 QemuOpts *opts;
114
115 list = qemu_find_opts("opts_list_01");
116 g_assert(list != NULL);
117 g_assert(QTAILQ_EMPTY(&list->head));
118 g_assert_cmpstr(list->name, ==, "opts_list_01");
119
120 /* should not find anything at this point */
121 opts = qemu_opts_find(list, NULL);
122 g_assert(opts == NULL);
123
124 /* create the opts */
125 opts = qemu_opts_create(list, NULL, 0, &error_abort);
126 g_assert(opts != NULL);
127 g_assert(!QTAILQ_EMPTY(&list->head));
128
129 /* now we've create the opts, must find it */
130 opts = qemu_opts_find(list, NULL);
131 g_assert(opts != NULL);
132
133 qemu_opts_del(opts);
134
135 /* should not find anything at this point */
136 opts = qemu_opts_find(list, NULL);
137 g_assert(opts == NULL);
138}
139
140static void test_qemu_opt_get(void)
141{
142 QemuOptsList *list;
143 QemuOpts *opts;
144 const char *opt = NULL;
145
146 list = qemu_find_opts("opts_list_01");
147 g_assert(list != NULL);
148 g_assert(QTAILQ_EMPTY(&list->head));
149 g_assert_cmpstr(list->name, ==, "opts_list_01");
150
151 /* should not find anything at this point */
152 opts = qemu_opts_find(list, NULL);
153 g_assert(opts == NULL);
154
155 /* create the opts */
156 opts = qemu_opts_create(list, NULL, 0, &error_abort);
157 g_assert(opts != NULL);
158 g_assert(!QTAILQ_EMPTY(&list->head));
159
160 /* haven't set anything to str2 yet */
161 opt = qemu_opt_get(opts, "str2");
162 g_assert(opt == NULL);
163
f43e47db 164 qemu_opt_set(opts, "str2", "value", &error_abort);
4ba6fabf
LD
165
166 /* now we have set str2, should know about it */
167 opt = qemu_opt_get(opts, "str2");
168 g_assert_cmpstr(opt, ==, "value");
169
f43e47db 170 qemu_opt_set(opts, "str2", "value2", &error_abort);
4ba6fabf
LD
171
172 /* having reset the value, the returned should be the reset one */
173 opt = qemu_opt_get(opts, "str2");
174 g_assert_cmpstr(opt, ==, "value2");
175
176 qemu_opts_del(opts);
177
178 /* should not find anything at this point */
179 opts = qemu_opts_find(list, NULL);
180 g_assert(opts == NULL);
181}
182
183static void test_qemu_opt_get_bool(void)
184{
cccb7967 185 Error *err = NULL;
4ba6fabf
LD
186 QemuOptsList *list;
187 QemuOpts *opts;
188 bool opt;
4ba6fabf
LD
189
190 list = qemu_find_opts("opts_list_02");
191 g_assert(list != NULL);
192 g_assert(QTAILQ_EMPTY(&list->head));
193 g_assert_cmpstr(list->name, ==, "opts_list_02");
194
195 /* should not find anything at this point */
196 opts = qemu_opts_find(list, NULL);
197 g_assert(opts == NULL);
198
199 /* create the opts */
200 opts = qemu_opts_create(list, NULL, 0, &error_abort);
201 g_assert(opts != NULL);
202 g_assert(!QTAILQ_EMPTY(&list->head));
203
204 /* haven't set anything to bool1 yet, so defval should be returned */
205 opt = qemu_opt_get_bool(opts, "bool1", false);
206 g_assert(opt == false);
207
cccb7967
MA
208 qemu_opt_set_bool(opts, "bool1", true, &err);
209 g_assert(!err);
4ba6fabf
LD
210
211 /* now we have set bool1, should know about it */
212 opt = qemu_opt_get_bool(opts, "bool1", false);
213 g_assert(opt == true);
214
215 /* having reset the value, opt should be the reset one not defval */
cccb7967
MA
216 qemu_opt_set_bool(opts, "bool1", false, &err);
217 g_assert(!err);
4ba6fabf
LD
218
219 opt = qemu_opt_get_bool(opts, "bool1", true);
220 g_assert(opt == false);
221
222 qemu_opts_del(opts);
223
224 /* should not find anything at this point */
225 opts = qemu_opts_find(list, NULL);
226 g_assert(opts == NULL);
227}
228
229static void test_qemu_opt_get_number(void)
230{
39101f25 231 Error *err = NULL;
4ba6fabf
LD
232 QemuOptsList *list;
233 QemuOpts *opts;
234 uint64_t opt;
4ba6fabf
LD
235
236 list = qemu_find_opts("opts_list_01");
237 g_assert(list != NULL);
238 g_assert(QTAILQ_EMPTY(&list->head));
239 g_assert_cmpstr(list->name, ==, "opts_list_01");
240
241 /* should not find anything at this point */
242 opts = qemu_opts_find(list, NULL);
243 g_assert(opts == NULL);
244
245 /* create the opts */
246 opts = qemu_opts_create(list, NULL, 0, &error_abort);
247 g_assert(opts != NULL);
248 g_assert(!QTAILQ_EMPTY(&list->head));
249
250 /* haven't set anything to number1 yet, so defval should be returned */
251 opt = qemu_opt_get_number(opts, "number1", 5);
252 g_assert(opt == 5);
253
39101f25
MA
254 qemu_opt_set_number(opts, "number1", 10, &err);
255 g_assert(!err);
4ba6fabf
LD
256
257 /* now we have set number1, should know about it */
258 opt = qemu_opt_get_number(opts, "number1", 5);
259 g_assert(opt == 10);
260
261 /* having reset it, the returned should be the reset one not defval */
39101f25
MA
262 qemu_opt_set_number(opts, "number1", 15, &err);
263 g_assert(!err);
4ba6fabf
LD
264
265 opt = qemu_opt_get_number(opts, "number1", 5);
266 g_assert(opt == 15);
267
268 qemu_opts_del(opts);
269
270 /* should not find anything at this point */
271 opts = qemu_opts_find(list, NULL);
272 g_assert(opts == NULL);
273}
274
275static void test_qemu_opt_get_size(void)
276{
277 QemuOptsList *list;
278 QemuOpts *opts;
279 uint64_t opt;
280 QDict *dict;
281
282 list = qemu_find_opts("opts_list_02");
283 g_assert(list != NULL);
284 g_assert(QTAILQ_EMPTY(&list->head));
285 g_assert_cmpstr(list->name, ==, "opts_list_02");
286
287 /* should not find anything at this point */
288 opts = qemu_opts_find(list, NULL);
289 g_assert(opts == NULL);
290
291 /* create the opts */
292 opts = qemu_opts_create(list, NULL, 0, &error_abort);
293 g_assert(opts != NULL);
294 g_assert(!QTAILQ_EMPTY(&list->head));
295
296 /* haven't set anything to size1 yet, so defval should be returned */
297 opt = qemu_opt_get_size(opts, "size1", 5);
298 g_assert(opt == 5);
299
300 dict = qdict_new();
301 g_assert(dict != NULL);
302
303 qdict_put(dict, "size1", qstring_from_str("10"));
304
305 qemu_opts_absorb_qdict(opts, dict, &error_abort);
306 g_assert(error_abort == NULL);
307
308 /* now we have set size1, should know about it */
309 opt = qemu_opt_get_size(opts, "size1", 5);
310 g_assert(opt == 10);
311
312 /* reset value */
313 qdict_put(dict, "size1", qstring_from_str("15"));
314
315 qemu_opts_absorb_qdict(opts, dict, &error_abort);
316 g_assert(error_abort == NULL);
317
318 /* test the reset value */
319 opt = qemu_opt_get_size(opts, "size1", 5);
320 g_assert(opt == 15);
321
322 qdict_del(dict, "size1");
323 g_free(dict);
324
325 qemu_opts_del(opts);
326
327 /* should not find anything at this point */
328 opts = qemu_opts_find(list, NULL);
329 g_assert(opts == NULL);
330}
331
332static void test_qemu_opt_unset(void)
333{
334 QemuOpts *opts;
335 const char *value;
336 int ret;
337
338 /* dynamically initialized (parsed) opts */
70b94331 339 opts = qemu_opts_parse(&opts_list_03, "key=value", false, NULL);
4ba6fabf
LD
340 g_assert(opts != NULL);
341
342 /* check default/parsed value */
343 value = qemu_opt_get(opts, "key");
344 g_assert_cmpstr(value, ==, "value");
345
346 /* reset it to value2 */
f43e47db 347 qemu_opt_set(opts, "key", "value2", &error_abort);
4ba6fabf
LD
348
349 value = qemu_opt_get(opts, "key");
350 g_assert_cmpstr(value, ==, "value2");
351
352 /* unset, valid only for "accept any" */
353 ret = qemu_opt_unset(opts, "key");
354 g_assert(ret == 0);
355
356 /* after reset the value should be the parsed/default one */
357 value = qemu_opt_get(opts, "key");
358 g_assert_cmpstr(value, ==, "value");
359
360 qemu_opts_del(opts);
361}
362
363static void test_qemu_opts_reset(void)
364{
39101f25 365 Error *err = NULL;
4ba6fabf
LD
366 QemuOptsList *list;
367 QemuOpts *opts;
368 uint64_t opt;
4ba6fabf
LD
369
370 list = qemu_find_opts("opts_list_01");
371 g_assert(list != NULL);
372 g_assert(QTAILQ_EMPTY(&list->head));
373 g_assert_cmpstr(list->name, ==, "opts_list_01");
374
375 /* should not find anything at this point */
376 opts = qemu_opts_find(list, NULL);
377 g_assert(opts == NULL);
378
379 /* create the opts */
380 opts = qemu_opts_create(list, NULL, 0, &error_abort);
381 g_assert(opts != NULL);
382 g_assert(!QTAILQ_EMPTY(&list->head));
383
384 /* haven't set anything to number1 yet, so defval should be returned */
385 opt = qemu_opt_get_number(opts, "number1", 5);
386 g_assert(opt == 5);
387
39101f25
MA
388 qemu_opt_set_number(opts, "number1", 10, &err);
389 g_assert(!err);
4ba6fabf
LD
390
391 /* now we have set number1, should know about it */
392 opt = qemu_opt_get_number(opts, "number1", 5);
393 g_assert(opt == 10);
394
395 qemu_opts_reset(list);
396
397 /* should not find anything at this point */
398 opts = qemu_opts_find(list, NULL);
399 g_assert(opts == NULL);
400}
401
402static void test_qemu_opts_set(void)
403{
79087c78 404 Error *err = NULL;
4ba6fabf
LD
405 QemuOptsList *list;
406 QemuOpts *opts;
4ba6fabf
LD
407 const char *opt;
408
409 list = qemu_find_opts("opts_list_01");
410 g_assert(list != NULL);
411 g_assert(QTAILQ_EMPTY(&list->head));
412 g_assert_cmpstr(list->name, ==, "opts_list_01");
413
414 /* should not find anything at this point */
415 opts = qemu_opts_find(list, NULL);
416 g_assert(opts == NULL);
417
418 /* implicitly create opts and set str3 value */
79087c78
MA
419 qemu_opts_set(list, NULL, "str3", "value", &err);
420 g_assert(!err);
4ba6fabf
LD
421 g_assert(!QTAILQ_EMPTY(&list->head));
422
423 /* get the just created opts */
424 opts = qemu_opts_find(list, NULL);
425 g_assert(opts != NULL);
426
427 /* check the str3 value */
428 opt = qemu_opt_get(opts, "str3");
429 g_assert_cmpstr(opt, ==, "value");
430
431 qemu_opts_del(opts);
432
433 /* should not find anything at this point */
434 opts = qemu_opts_find(list, NULL);
435 g_assert(opts == NULL);
436}
437
694baf57
MA
438static int opts_count_iter(void *opaque, const char *name, const char *value,
439 Error **errp)
440{
441 (*(size_t *)opaque)++;
442 return 0;
443}
444
445static size_t opts_count(QemuOpts *opts)
446{
447 size_t n = 0;
448
449 qemu_opt_foreach(opts, opts_count_iter, &n, NULL);
450 return n;
451}
452
453static void test_opts_parse(void)
454{
455 Error *err = NULL;
456 QemuOpts *opts;
457 char long_key[129];
458 char *params;
459
460 /* Nothing */
461 opts = qemu_opts_parse(&opts_list_03, "", false, &error_abort);
462 g_assert_cmpuint(opts_count(opts), ==, 0);
463
464 /* Empty key */
465 opts = qemu_opts_parse(&opts_list_03, "=val", false, &error_abort);
466 g_assert_cmpuint(opts_count(opts), ==, 1);
467 g_assert_cmpstr(qemu_opt_get(opts, ""), ==, "val");
468
469 /* Long key */
470 memset(long_key, 'a', 127);
471 long_key[127] = 'z';
472 long_key[128] = 0;
473 params = g_strdup_printf("%s=v", long_key);
474 opts = qemu_opts_parse(&opts_list_03, params + 1, NULL, &error_abort);
475 g_assert_cmpuint(opts_count(opts), ==, 1);
476 g_assert_cmpstr(qemu_opt_get(opts, long_key + 1), ==, "v");
477
478 /* Overlong key gets truncated */
479 opts = qemu_opts_parse(&opts_list_03, params, NULL, &error_abort);
480 g_assert(opts_count(opts) == 1);
481 long_key[127] = 0;
482 g_assert_cmpstr(qemu_opt_get(opts, long_key), ==, "v");
483 g_free(params);
484
485 /* Multiple keys, last one wins */
486 opts = qemu_opts_parse(&opts_list_03, "a=1,b=2,,x,a=3",
487 false, &error_abort);
488 g_assert_cmpuint(opts_count(opts), ==, 3);
489 g_assert_cmpstr(qemu_opt_get(opts, "a"), ==, "3");
490 g_assert_cmpstr(qemu_opt_get(opts, "b"), ==, "2,x");
491
492 /* Except when it doesn't */
493 opts = qemu_opts_parse(&opts_list_03, "id=foo,id=bar",
494 false, &error_abort);
495 g_assert_cmpuint(opts_count(opts), ==, 0);
496 g_assert_cmpstr(qemu_opts_id(opts), ==, "foo");
497
498 /* TODO Cover low-level access to repeated keys */
499
500 /* Trailing comma is ignored */
501 opts = qemu_opts_parse(&opts_list_03, "x=y,", false, &error_abort);
502 g_assert_cmpuint(opts_count(opts), ==, 1);
503 g_assert_cmpstr(qemu_opt_get(opts, "x"), ==, "y");
504
505 /* Except when it isn't */
506 opts = qemu_opts_parse(&opts_list_03, ",", false, &error_abort);
507 g_assert_cmpuint(opts_count(opts), ==, 1);
508 g_assert_cmpstr(qemu_opt_get(opts, ""), ==, "on");
509
510 /* Duplicate ID */
511 opts = qemu_opts_parse(&opts_list_03, "x=y,id=foo", false, &err);
512 error_free_or_abort(&err);
513 g_assert(!opts);
514 /* TODO Cover .merge_lists = true */
515
516 /* Buggy ID recognition */
517 opts = qemu_opts_parse(&opts_list_03, "x=,,id=bar", false, &error_abort);
518 g_assert_cmpuint(opts_count(opts), ==, 1);
519 g_assert_cmpstr(qemu_opts_id(opts), ==, "bar"); /* BUG */
520 g_assert_cmpstr(qemu_opt_get(opts, "x"), ==, ",id=bar");
521
522 /* Anti-social ID */
523 opts = qemu_opts_parse(&opts_list_01, "id=666", false, &err);
524 error_free_or_abort(&err);
525 g_assert(!opts);
526
527 /* Implied value */
528 opts = qemu_opts_parse(&opts_list_03, "an,noaus,noaus=",
529 false, &error_abort);
530 g_assert_cmpuint(opts_count(opts), ==, 3);
531 g_assert_cmpstr(qemu_opt_get(opts, "an"), ==, "on");
532 g_assert_cmpstr(qemu_opt_get(opts, "aus"), ==, "off");
533 g_assert_cmpstr(qemu_opt_get(opts, "noaus"), ==, "");
534
0e2052b2
MA
535 /* Implied value, negated empty key */
536 opts = qemu_opts_parse(&opts_list_03, "no", false, &error_abort);
537 g_assert_cmpuint(opts_count(opts), ==, 1);
538 g_assert_cmpstr(qemu_opt_get(opts, ""), ==, "off");
539
694baf57
MA
540 /* Implied key */
541 opts = qemu_opts_parse(&opts_list_03, "an,noaus,noaus=", true,
542 &error_abort);
543 g_assert_cmpuint(opts_count(opts), ==, 3);
544 g_assert_cmpstr(qemu_opt_get(opts, "implied"), ==, "an");
545 g_assert_cmpstr(qemu_opt_get(opts, "aus"), ==, "off");
546 g_assert_cmpstr(qemu_opt_get(opts, "noaus"), ==, "");
547
548 /* Implied key with empty value */
549 opts = qemu_opts_parse(&opts_list_03, ",", true, &error_abort);
550 g_assert_cmpuint(opts_count(opts), ==, 1);
551 g_assert_cmpstr(qemu_opt_get(opts, "implied"), ==, "");
552
553 /* Implied key with comma value */
554 opts = qemu_opts_parse(&opts_list_03, ",,,a=1", true, &error_abort);
555 g_assert_cmpuint(opts_count(opts), ==, 2);
556 g_assert_cmpstr(qemu_opt_get(opts, "implied"), ==, ",");
557 g_assert_cmpstr(qemu_opt_get(opts, "a"), ==, "1");
558
559 /* Empty key is not an implied key */
560 opts = qemu_opts_parse(&opts_list_03, "=val", true, &error_abort);
561 g_assert_cmpuint(opts_count(opts), ==, 1);
562 g_assert_cmpstr(qemu_opt_get(opts, ""), ==, "val");
563
564 /* Unknown key */
565 opts = qemu_opts_parse(&opts_list_01, "nonexistent=", false, &err);
566 error_free_or_abort(&err);
567 g_assert(!opts);
568
569 qemu_opts_reset(&opts_list_01);
570 qemu_opts_reset(&opts_list_03);
571}
572
573static void test_opts_parse_bool(void)
574{
575 Error *err = NULL;
576 QemuOpts *opts;
577
578 opts = qemu_opts_parse(&opts_list_02, "bool1=on,bool2=off",
579 false, &error_abort);
580 g_assert_cmpuint(opts_count(opts), ==, 2);
581 g_assert(qemu_opt_get_bool(opts, "bool1", false));
582 g_assert(!qemu_opt_get_bool(opts, "bool2", true));
583
584 opts = qemu_opts_parse(&opts_list_02, "bool1=offer", false, &err);
585 error_free_or_abort(&err);
586 g_assert(!opts);
587
588 qemu_opts_reset(&opts_list_02);
589}
590
591static void test_opts_parse_number(void)
592{
593 Error *err = NULL;
594 QemuOpts *opts;
595
596 /* Lower limit zero */
597 opts = qemu_opts_parse(&opts_list_01, "number1=0", false, &error_abort);
598 g_assert_cmpuint(opts_count(opts), ==, 1);
599 g_assert_cmpuint(qemu_opt_get_number(opts, "number1", 1), ==, 0);
600
601 /* Upper limit 2^64-1 */
602 opts = qemu_opts_parse(&opts_list_01,
603 "number1=18446744073709551615,number2=-1",
604 false, &error_abort);
605 g_assert_cmpuint(opts_count(opts), ==, 2);
606 g_assert_cmphex(qemu_opt_get_number(opts, "number1", 1), ==, UINT64_MAX);
607 g_assert_cmphex(qemu_opt_get_number(opts, "number2", 0), ==, UINT64_MAX);
608
609 /* Above upper limit */
610 opts = qemu_opts_parse(&opts_list_01, "number1=18446744073709551616",
3403e5eb
MA
611 false, &err);
612 error_free_or_abort(&err);
613 g_assert(!opts);
694baf57
MA
614
615 /* Below lower limit */
616 opts = qemu_opts_parse(&opts_list_01, "number1=-18446744073709551616",
3403e5eb
MA
617 false, &err);
618 error_free_or_abort(&err);
619 g_assert(!opts);
694baf57
MA
620
621 /* Hex and octal */
622 opts = qemu_opts_parse(&opts_list_01, "number1=0x2a,number2=052",
623 false, &error_abort);
624 g_assert_cmpuint(opts_count(opts), ==, 2);
625 g_assert_cmpuint(qemu_opt_get_number(opts, "number1", 1), ==, 42);
626 g_assert_cmpuint(qemu_opt_get_number(opts, "number2", 0), ==, 42);
627
628 /* Invalid */
629 opts = qemu_opts_parse(&opts_list_01, "number1=", false, &err);
3403e5eb
MA
630 error_free_or_abort(&err);
631 g_assert(!opts);
694baf57
MA
632 opts = qemu_opts_parse(&opts_list_01, "number1=eins", false, &err);
633 error_free_or_abort(&err);
634 g_assert(!opts);
635
636 /* Leading whitespace */
637 opts = qemu_opts_parse(&opts_list_01, "number1= \t42",
638 false, &error_abort);
639 g_assert_cmpuint(opts_count(opts), ==, 1);
640 g_assert_cmpuint(qemu_opt_get_number(opts, "number1", 1), ==, 42);
641
642 /* Trailing crap */
643 opts = qemu_opts_parse(&opts_list_01, "number1=3.14", false, &err);
644 error_free_or_abort(&err);
645 g_assert(!opts);
646 opts = qemu_opts_parse(&opts_list_01, "number1=08", false, &err);
647 error_free_or_abort(&err);
648 g_assert(!opts);
649 opts = qemu_opts_parse(&opts_list_01, "number1=0 ", false, &err);
650 error_free_or_abort(&err);
651 g_assert(!opts);
652
653 qemu_opts_reset(&opts_list_01);
654}
655
656static void test_opts_parse_size(void)
657{
658 Error *err = NULL;
659 QemuOpts *opts;
660
661 /* Lower limit zero */
662 opts = qemu_opts_parse(&opts_list_02, "size1=0", false, &error_abort);
663 g_assert_cmpuint(opts_count(opts), ==, 1);
664 g_assert_cmpuint(qemu_opt_get_size(opts, "size1", 1), ==, 0);
665
666 /* Note: precision is 53 bits since we're parsing with strtod() */
667
668 /* Around limit of precision: 2^53-1, 2^53, 2^54 */
669 opts = qemu_opts_parse(&opts_list_02,
670 "size1=9007199254740991,"
671 "size2=9007199254740992,"
672 "size3=9007199254740993",
673 false, &error_abort);
674 g_assert_cmpuint(opts_count(opts), ==, 3);
675 g_assert_cmphex(qemu_opt_get_size(opts, "size1", 1),
676 ==, 0x1fffffffffffff);
677 g_assert_cmphex(qemu_opt_get_size(opts, "size2", 1),
678 ==, 0x20000000000000);
679 g_assert_cmphex(qemu_opt_get_size(opts, "size3", 1),
680 ==, 0x20000000000000);
681
682 /* Close to signed upper limit 0x7ffffffffffffc00 (53 msbs set) */
683 opts = qemu_opts_parse(&opts_list_02,
684 "size1=9223372036854774784," /* 7ffffffffffffc00 */
685 "size2=9223372036854775295", /* 7ffffffffffffdff */
686 false, &error_abort);
687 g_assert_cmpuint(opts_count(opts), ==, 2);
688 g_assert_cmphex(qemu_opt_get_size(opts, "size1", 1),
689 ==, 0x7ffffffffffffc00);
690 g_assert_cmphex(qemu_opt_get_size(opts, "size2", 1),
691 ==, 0x7ffffffffffffc00);
692
693 /* Close to actual upper limit 0xfffffffffffff800 (53 msbs set) */
694 opts = qemu_opts_parse(&opts_list_02,
695 "size1=18446744073709549568," /* fffffffffffff800 */
696 "size2=18446744073709550591", /* fffffffffffffbff */
697 false, &error_abort);
698 g_assert_cmpuint(opts_count(opts), ==, 2);
699 g_assert_cmphex(qemu_opt_get_size(opts, "size1", 1),
700 ==, 0xfffffffffffff800);
701 g_assert_cmphex(qemu_opt_get_size(opts, "size2", 1),
702 ==, 0xfffffffffffff800);
703
704 /* Beyond limits */
705 opts = qemu_opts_parse(&opts_list_02, "size1=-1", false, &err);
706 error_free_or_abort(&err);
707 g_assert(!opts);
708 opts = qemu_opts_parse(&opts_list_02,
709 "size1=18446744073709550592", /* fffffffffffffc00 */
75cdcd15
MA
710 false, &err);
711 error_free_or_abort(&err);
712 g_assert(!opts);
694baf57
MA
713
714 /* Suffixes */
715 opts = qemu_opts_parse(&opts_list_02, "size1=8b,size2=1.5k,size3=2M",
716 false, &error_abort);
717 g_assert_cmpuint(opts_count(opts), ==, 3);
718 g_assert_cmphex(qemu_opt_get_size(opts, "size1", 0), ==, 8);
719 g_assert_cmphex(qemu_opt_get_size(opts, "size2", 0), ==, 1536);
720 g_assert_cmphex(qemu_opt_get_size(opts, "size3", 0), ==, 2 * M_BYTE);
721 opts = qemu_opts_parse(&opts_list_02, "size1=0.1G,size2=16777215T",
722 false, &error_abort);
723 g_assert_cmpuint(opts_count(opts), ==, 2);
724 g_assert_cmphex(qemu_opt_get_size(opts, "size1", 0), ==, G_BYTE / 10);
725 g_assert_cmphex(qemu_opt_get_size(opts, "size2", 0),
726 ==, 16777215 * T_BYTE);
727
728 /* Beyond limit with suffix */
729 opts = qemu_opts_parse(&opts_list_02, "size1=16777216T",
75cdcd15
MA
730 false, &err);
731 error_free_or_abort(&err);
732 g_assert(!opts);
694baf57
MA
733
734 /* Trailing crap */
735 opts = qemu_opts_parse(&opts_list_02, "size1=16E", false, &err);
736 error_free_or_abort(&err);
737 g_assert(!opts);
75cdcd15
MA
738 opts = qemu_opts_parse(&opts_list_02, "size1=16Gi", false, &err);
739 error_free_or_abort(&err);
740 g_assert(!opts);
694baf57
MA
741
742 qemu_opts_reset(&opts_list_02);
743}
744
4ba6fabf
LD
745int main(int argc, char *argv[])
746{
747 register_opts();
748 g_test_init(&argc, &argv, NULL);
749 g_test_add_func("/qemu-opts/find_unknown_opts", test_find_unknown_opts);
750 g_test_add_func("/qemu-opts/find_opts", test_qemu_find_opts);
751 g_test_add_func("/qemu-opts/opts_create", test_qemu_opts_create);
752 g_test_add_func("/qemu-opts/opt_get", test_qemu_opt_get);
753 g_test_add_func("/qemu-opts/opt_get_bool", test_qemu_opt_get_bool);
754 g_test_add_func("/qemu-opts/opt_get_number", test_qemu_opt_get_number);
755 g_test_add_func("/qemu-opts/opt_get_size", test_qemu_opt_get_size);
756 g_test_add_func("/qemu-opts/opt_unset", test_qemu_opt_unset);
757 g_test_add_func("/qemu-opts/opts_reset", test_qemu_opts_reset);
758 g_test_add_func("/qemu-opts/opts_set", test_qemu_opts_set);
694baf57
MA
759 g_test_add_func("/qemu-opts/opts_parse/general", test_opts_parse);
760 g_test_add_func("/qemu-opts/opts_parse/bool", test_opts_parse_bool);
761 g_test_add_func("/qemu-opts/opts_parse/number", test_opts_parse_number);
762 g_test_add_func("/qemu-opts/opts_parse/size", test_opts_parse_size);
4ba6fabf
LD
763 g_test_run();
764 return 0;
765}