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