]>
Commit | Line | Data |
---|---|---|
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" |
d23b6caa | 11 | #include "qemu/units.h" |
922a01a0 | 12 | #include "qemu/option.h" |
37974a97 | 13 | #include "qemu/option_int.h" |
da34e65c | 14 | #include "qapi/error.h" |
452fcdbc | 15 | #include "qapi/qmp/qdict.h" |
4ba6fabf LD |
16 | #include "qapi/qmp/qstring.h" |
17 | #include "qemu/config-file.h" | |
18 | ||
4ba6fabf LD |
19 | |
20 | static 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, | |
575ef8bf KW |
27 | .help = "Help texts are preserved in qemu_opts_append", |
28 | .def_value_str = "default", | |
4ba6fabf LD |
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, | |
575ef8bf | 38 | .help = "Having help texts only for some options is okay", |
694baf57 MA |
39 | },{ |
40 | .name = "number2", | |
41 | .type = QEMU_OPT_NUMBER, | |
4ba6fabf LD |
42 | }, |
43 | { /* end of list */ } | |
44 | }, | |
45 | }; | |
46 | ||
47 | static 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, | |
694baf57 MA |
54 | },{ |
55 | .name = "str2", | |
56 | .type = QEMU_OPT_STRING, | |
4ba6fabf LD |
57 | },{ |
58 | .name = "bool1", | |
59 | .type = QEMU_OPT_BOOL, | |
60 | },{ | |
694baf57 MA |
61 | .name = "bool2", |
62 | .type = QEMU_OPT_BOOL, | |
4ba6fabf LD |
63 | },{ |
64 | .name = "size1", | |
65 | .type = QEMU_OPT_SIZE, | |
694baf57 MA |
66 | },{ |
67 | .name = "size2", | |
68 | .type = QEMU_OPT_SIZE, | |
69 | },{ | |
70 | .name = "size3", | |
71 | .type = QEMU_OPT_SIZE, | |
4ba6fabf LD |
72 | }, |
73 | { /* end of list */ } | |
74 | }, | |
75 | }; | |
76 | ||
748bfb4e | 77 | static QemuOptsList opts_list_03 = { |
4ba6fabf | 78 | .name = "opts_list_03", |
694baf57 | 79 | .implied_opt_name = "implied", |
4ba6fabf LD |
80 | .head = QTAILQ_HEAD_INITIALIZER(opts_list_03.head), |
81 | .desc = { | |
82 | /* no elements => accept any params */ | |
83 | { /* end of list */ } | |
84 | }, | |
85 | }; | |
86 | ||
87 | static 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 | ||
94 | static void test_find_unknown_opts(void) | |
95 | { | |
96 | QemuOptsList *list; | |
97 | Error *err = NULL; | |
98 | ||
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); | |
157db293 | 102 | error_free_or_abort(&err); |
4ba6fabf LD |
103 | } |
104 | ||
105 | static void test_qemu_find_opts(void) | |
106 | { | |
107 | QemuOptsList *list; | |
108 | ||
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"); | |
113 | } | |
114 | ||
115 | static 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 | /* should not find anything at this point */ | |
126 | opts = qemu_opts_find(list, NULL); | |
127 | g_assert(opts == NULL); | |
128 | ||
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)); | |
133 | ||
134 | /* now we've create the opts, must find it */ | |
135 | opts = qemu_opts_find(list, NULL); | |
136 | g_assert(opts != NULL); | |
137 | ||
138 | qemu_opts_del(opts); | |
139 | ||
140 | /* should not find anything at this point */ | |
141 | opts = qemu_opts_find(list, NULL); | |
142 | g_assert(opts == NULL); | |
143 | } | |
144 | ||
145 | static 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 | /* should not find anything at this point */ | |
157 | opts = qemu_opts_find(list, NULL); | |
158 | g_assert(opts == NULL); | |
159 | ||
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)); | |
164 | ||
165 | /* haven't set anything to str2 yet */ | |
166 | opt = qemu_opt_get(opts, "str2"); | |
167 | g_assert(opt == NULL); | |
168 | ||
f43e47db | 169 | qemu_opt_set(opts, "str2", "value", &error_abort); |
4ba6fabf LD |
170 | |
171 | /* now we have set str2, should know about it */ | |
172 | opt = qemu_opt_get(opts, "str2"); | |
173 | g_assert_cmpstr(opt, ==, "value"); | |
174 | ||
f43e47db | 175 | qemu_opt_set(opts, "str2", "value2", &error_abort); |
4ba6fabf LD |
176 | |
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"); | |
180 | ||
181 | qemu_opts_del(opts); | |
182 | ||
183 | /* should not find anything at this point */ | |
184 | opts = qemu_opts_find(list, NULL); | |
185 | g_assert(opts == NULL); | |
186 | } | |
187 | ||
188 | static void test_qemu_opt_get_bool(void) | |
189 | { | |
cccb7967 | 190 | Error *err = NULL; |
4ba6fabf LD |
191 | QemuOptsList *list; |
192 | QemuOpts *opts; | |
193 | bool opt; | |
4ba6fabf LD |
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 | /* should not find anything at this point */ | |
201 | opts = qemu_opts_find(list, NULL); | |
202 | g_assert(opts == NULL); | |
203 | ||
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)); | |
208 | ||
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); | |
212 | ||
cccb7967 MA |
213 | qemu_opt_set_bool(opts, "bool1", true, &err); |
214 | g_assert(!err); | |
4ba6fabf LD |
215 | |
216 | /* now we have set bool1, should know about it */ | |
217 | opt = qemu_opt_get_bool(opts, "bool1", false); | |
218 | g_assert(opt == true); | |
219 | ||
220 | /* having reset the value, opt should be the reset one not defval */ | |
cccb7967 MA |
221 | qemu_opt_set_bool(opts, "bool1", false, &err); |
222 | g_assert(!err); | |
4ba6fabf LD |
223 | |
224 | opt = qemu_opt_get_bool(opts, "bool1", true); | |
225 | g_assert(opt == false); | |
226 | ||
227 | qemu_opts_del(opts); | |
228 | ||
229 | /* should not find anything at this point */ | |
230 | opts = qemu_opts_find(list, NULL); | |
231 | g_assert(opts == NULL); | |
232 | } | |
233 | ||
234 | static void test_qemu_opt_get_number(void) | |
235 | { | |
39101f25 | 236 | Error *err = NULL; |
4ba6fabf LD |
237 | QemuOptsList *list; |
238 | QemuOpts *opts; | |
239 | uint64_t opt; | |
4ba6fabf LD |
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 | /* should not find anything at this point */ | |
247 | opts = qemu_opts_find(list, NULL); | |
248 | g_assert(opts == NULL); | |
249 | ||
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)); | |
254 | ||
255 | /* haven't set anything to number1 yet, so defval should be returned */ | |
256 | opt = qemu_opt_get_number(opts, "number1", 5); | |
257 | g_assert(opt == 5); | |
258 | ||
39101f25 MA |
259 | qemu_opt_set_number(opts, "number1", 10, &err); |
260 | g_assert(!err); | |
4ba6fabf LD |
261 | |
262 | /* now we have set number1, should know about it */ | |
263 | opt = qemu_opt_get_number(opts, "number1", 5); | |
264 | g_assert(opt == 10); | |
265 | ||
266 | /* having reset it, the returned should be the reset one not defval */ | |
39101f25 MA |
267 | qemu_opt_set_number(opts, "number1", 15, &err); |
268 | g_assert(!err); | |
4ba6fabf LD |
269 | |
270 | opt = qemu_opt_get_number(opts, "number1", 5); | |
271 | g_assert(opt == 15); | |
272 | ||
273 | qemu_opts_del(opts); | |
274 | ||
275 | /* should not find anything at this point */ | |
276 | opts = qemu_opts_find(list, NULL); | |
277 | g_assert(opts == NULL); | |
278 | } | |
279 | ||
280 | static 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 | /* should not find anything at this point */ | |
293 | opts = qemu_opts_find(list, NULL); | |
294 | g_assert(opts == NULL); | |
295 | ||
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)); | |
300 | ||
301 | /* haven't set anything to size1 yet, so defval should be returned */ | |
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 | ||
46f5ac20 | 308 | qdict_put_str(dict, "size1", "10"); |
4ba6fabf LD |
309 | |
310 | qemu_opts_absorb_qdict(opts, dict, &error_abort); | |
311 | g_assert(error_abort == NULL); | |
312 | ||
313 | /* now we have set size1, should know about it */ | |
314 | opt = qemu_opt_get_size(opts, "size1", 5); | |
315 | g_assert(opt == 10); | |
316 | ||
317 | /* reset value */ | |
46f5ac20 | 318 | qdict_put_str(dict, "size1", "15"); |
4ba6fabf LD |
319 | |
320 | qemu_opts_absorb_qdict(opts, dict, &error_abort); | |
321 | g_assert(error_abort == NULL); | |
322 | ||
323 | /* test the reset value */ | |
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 | /* should not find anything at this point */ | |
333 | opts = qemu_opts_find(list, NULL); | |
334 | g_assert(opts == NULL); | |
335 | } | |
336 | ||
337 | static void test_qemu_opt_unset(void) | |
338 | { | |
339 | QemuOpts *opts; | |
340 | const char *value; | |
341 | int ret; | |
342 | ||
343 | /* dynamically initialized (parsed) opts */ | |
70b94331 | 344 | opts = qemu_opts_parse(&opts_list_03, "key=value", false, NULL); |
4ba6fabf LD |
345 | g_assert(opts != NULL); |
346 | ||
347 | /* check default/parsed value */ | |
348 | value = qemu_opt_get(opts, "key"); | |
349 | g_assert_cmpstr(value, ==, "value"); | |
350 | ||
351 | /* reset it to value2 */ | |
f43e47db | 352 | qemu_opt_set(opts, "key", "value2", &error_abort); |
4ba6fabf LD |
353 | |
354 | value = qemu_opt_get(opts, "key"); | |
355 | g_assert_cmpstr(value, ==, "value2"); | |
356 | ||
357 | /* unset, valid only for "accept any" */ | |
358 | ret = qemu_opt_unset(opts, "key"); | |
359 | g_assert(ret == 0); | |
360 | ||
361 | /* after reset the value should be the parsed/default one */ | |
362 | value = qemu_opt_get(opts, "key"); | |
363 | g_assert_cmpstr(value, ==, "value"); | |
364 | ||
365 | qemu_opts_del(opts); | |
366 | } | |
367 | ||
368 | static void test_qemu_opts_reset(void) | |
369 | { | |
39101f25 | 370 | Error *err = NULL; |
4ba6fabf LD |
371 | QemuOptsList *list; |
372 | QemuOpts *opts; | |
373 | uint64_t opt; | |
4ba6fabf LD |
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 | /* should not find anything at this point */ | |
381 | opts = qemu_opts_find(list, NULL); | |
382 | g_assert(opts == NULL); | |
383 | ||
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)); | |
388 | ||
389 | /* haven't set anything to number1 yet, so defval should be returned */ | |
390 | opt = qemu_opt_get_number(opts, "number1", 5); | |
391 | g_assert(opt == 5); | |
392 | ||
39101f25 MA |
393 | qemu_opt_set_number(opts, "number1", 10, &err); |
394 | g_assert(!err); | |
4ba6fabf LD |
395 | |
396 | /* now we have set number1, should know about it */ | |
397 | opt = qemu_opt_get_number(opts, "number1", 5); | |
398 | g_assert(opt == 10); | |
399 | ||
400 | qemu_opts_reset(list); | |
401 | ||
402 | /* should not find anything at this point */ | |
403 | opts = qemu_opts_find(list, NULL); | |
404 | g_assert(opts == NULL); | |
405 | } | |
406 | ||
407 | static void test_qemu_opts_set(void) | |
408 | { | |
79087c78 | 409 | Error *err = NULL; |
4ba6fabf LD |
410 | QemuOptsList *list; |
411 | QemuOpts *opts; | |
4ba6fabf LD |
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 | /* should not find anything at this point */ | |
420 | opts = qemu_opts_find(list, NULL); | |
421 | g_assert(opts == NULL); | |
422 | ||
423 | /* implicitly create opts and set str3 value */ | |
79087c78 MA |
424 | qemu_opts_set(list, NULL, "str3", "value", &err); |
425 | g_assert(!err); | |
4ba6fabf LD |
426 | g_assert(!QTAILQ_EMPTY(&list->head)); |
427 | ||
428 | /* get the just created opts */ | |
429 | opts = qemu_opts_find(list, NULL); | |
430 | g_assert(opts != NULL); | |
431 | ||
432 | /* check the str3 value */ | |
433 | opt = qemu_opt_get(opts, "str3"); | |
434 | g_assert_cmpstr(opt, ==, "value"); | |
435 | ||
436 | qemu_opts_del(opts); | |
437 | ||
438 | /* should not find anything at this point */ | |
439 | opts = qemu_opts_find(list, NULL); | |
440 | g_assert(opts == NULL); | |
441 | } | |
442 | ||
694baf57 MA |
443 | static 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 | ||
450 | static 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 | ||
458 | static void test_opts_parse(void) | |
459 | { | |
460 | Error *err = NULL; | |
461 | QemuOpts *opts; | |
694baf57 MA |
462 | |
463 | /* Nothing */ | |
464 | opts = qemu_opts_parse(&opts_list_03, "", false, &error_abort); | |
465 | g_assert_cmpuint(opts_count(opts), ==, 0); | |
466 | ||
467 | /* Empty key */ | |
468 | opts = qemu_opts_parse(&opts_list_03, "=val", false, &error_abort); | |
469 | g_assert_cmpuint(opts_count(opts), ==, 1); | |
470 | g_assert_cmpstr(qemu_opt_get(opts, ""), ==, "val"); | |
471 | ||
694baf57 MA |
472 | /* Multiple keys, last one wins */ |
473 | opts = qemu_opts_parse(&opts_list_03, "a=1,b=2,,x,a=3", | |
474 | false, &error_abort); | |
475 | g_assert_cmpuint(opts_count(opts), ==, 3); | |
476 | g_assert_cmpstr(qemu_opt_get(opts, "a"), ==, "3"); | |
477 | g_assert_cmpstr(qemu_opt_get(opts, "b"), ==, "2,x"); | |
478 | ||
479 | /* Except when it doesn't */ | |
480 | opts = qemu_opts_parse(&opts_list_03, "id=foo,id=bar", | |
481 | false, &error_abort); | |
482 | g_assert_cmpuint(opts_count(opts), ==, 0); | |
483 | g_assert_cmpstr(qemu_opts_id(opts), ==, "foo"); | |
484 | ||
485 | /* TODO Cover low-level access to repeated keys */ | |
486 | ||
487 | /* Trailing comma is ignored */ | |
488 | opts = qemu_opts_parse(&opts_list_03, "x=y,", false, &error_abort); | |
489 | g_assert_cmpuint(opts_count(opts), ==, 1); | |
490 | g_assert_cmpstr(qemu_opt_get(opts, "x"), ==, "y"); | |
491 | ||
492 | /* Except when it isn't */ | |
493 | opts = qemu_opts_parse(&opts_list_03, ",", false, &error_abort); | |
494 | g_assert_cmpuint(opts_count(opts), ==, 1); | |
495 | g_assert_cmpstr(qemu_opt_get(opts, ""), ==, "on"); | |
496 | ||
497 | /* Duplicate ID */ | |
498 | opts = qemu_opts_parse(&opts_list_03, "x=y,id=foo", false, &err); | |
499 | error_free_or_abort(&err); | |
500 | g_assert(!opts); | |
501 | /* TODO Cover .merge_lists = true */ | |
502 | ||
503 | /* Buggy ID recognition */ | |
504 | opts = qemu_opts_parse(&opts_list_03, "x=,,id=bar", false, &error_abort); | |
505 | g_assert_cmpuint(opts_count(opts), ==, 1); | |
506 | g_assert_cmpstr(qemu_opts_id(opts), ==, "bar"); /* BUG */ | |
507 | g_assert_cmpstr(qemu_opt_get(opts, "x"), ==, ",id=bar"); | |
508 | ||
509 | /* Anti-social ID */ | |
510 | opts = qemu_opts_parse(&opts_list_01, "id=666", false, &err); | |
511 | error_free_or_abort(&err); | |
512 | g_assert(!opts); | |
513 | ||
514 | /* Implied value */ | |
515 | opts = qemu_opts_parse(&opts_list_03, "an,noaus,noaus=", | |
516 | false, &error_abort); | |
517 | g_assert_cmpuint(opts_count(opts), ==, 3); | |
518 | g_assert_cmpstr(qemu_opt_get(opts, "an"), ==, "on"); | |
519 | g_assert_cmpstr(qemu_opt_get(opts, "aus"), ==, "off"); | |
520 | g_assert_cmpstr(qemu_opt_get(opts, "noaus"), ==, ""); | |
521 | ||
0e2052b2 MA |
522 | /* Implied value, negated empty key */ |
523 | opts = qemu_opts_parse(&opts_list_03, "no", false, &error_abort); | |
524 | g_assert_cmpuint(opts_count(opts), ==, 1); | |
525 | g_assert_cmpstr(qemu_opt_get(opts, ""), ==, "off"); | |
526 | ||
694baf57 MA |
527 | /* Implied key */ |
528 | opts = qemu_opts_parse(&opts_list_03, "an,noaus,noaus=", true, | |
529 | &error_abort); | |
530 | g_assert_cmpuint(opts_count(opts), ==, 3); | |
531 | g_assert_cmpstr(qemu_opt_get(opts, "implied"), ==, "an"); | |
532 | g_assert_cmpstr(qemu_opt_get(opts, "aus"), ==, "off"); | |
533 | g_assert_cmpstr(qemu_opt_get(opts, "noaus"), ==, ""); | |
534 | ||
535 | /* Implied key with empty value */ | |
536 | opts = qemu_opts_parse(&opts_list_03, ",", true, &error_abort); | |
537 | g_assert_cmpuint(opts_count(opts), ==, 1); | |
538 | g_assert_cmpstr(qemu_opt_get(opts, "implied"), ==, ""); | |
539 | ||
540 | /* Implied key with comma value */ | |
541 | opts = qemu_opts_parse(&opts_list_03, ",,,a=1", true, &error_abort); | |
542 | g_assert_cmpuint(opts_count(opts), ==, 2); | |
543 | g_assert_cmpstr(qemu_opt_get(opts, "implied"), ==, ","); | |
544 | g_assert_cmpstr(qemu_opt_get(opts, "a"), ==, "1"); | |
545 | ||
546 | /* Empty key is not an implied key */ | |
547 | opts = qemu_opts_parse(&opts_list_03, "=val", true, &error_abort); | |
548 | g_assert_cmpuint(opts_count(opts), ==, 1); | |
549 | g_assert_cmpstr(qemu_opt_get(opts, ""), ==, "val"); | |
550 | ||
551 | /* Unknown key */ | |
552 | opts = qemu_opts_parse(&opts_list_01, "nonexistent=", false, &err); | |
553 | error_free_or_abort(&err); | |
554 | g_assert(!opts); | |
555 | ||
556 | qemu_opts_reset(&opts_list_01); | |
557 | qemu_opts_reset(&opts_list_03); | |
558 | } | |
559 | ||
560 | static void test_opts_parse_bool(void) | |
561 | { | |
562 | Error *err = NULL; | |
563 | QemuOpts *opts; | |
564 | ||
565 | opts = qemu_opts_parse(&opts_list_02, "bool1=on,bool2=off", | |
566 | false, &error_abort); | |
567 | g_assert_cmpuint(opts_count(opts), ==, 2); | |
568 | g_assert(qemu_opt_get_bool(opts, "bool1", false)); | |
569 | g_assert(!qemu_opt_get_bool(opts, "bool2", true)); | |
570 | ||
571 | opts = qemu_opts_parse(&opts_list_02, "bool1=offer", false, &err); | |
572 | error_free_or_abort(&err); | |
573 | g_assert(!opts); | |
574 | ||
575 | qemu_opts_reset(&opts_list_02); | |
576 | } | |
577 | ||
578 | static void test_opts_parse_number(void) | |
579 | { | |
580 | Error *err = NULL; | |
581 | QemuOpts *opts; | |
582 | ||
583 | /* Lower limit zero */ | |
584 | opts = qemu_opts_parse(&opts_list_01, "number1=0", false, &error_abort); | |
585 | g_assert_cmpuint(opts_count(opts), ==, 1); | |
586 | g_assert_cmpuint(qemu_opt_get_number(opts, "number1", 1), ==, 0); | |
587 | ||
588 | /* Upper limit 2^64-1 */ | |
589 | opts = qemu_opts_parse(&opts_list_01, | |
590 | "number1=18446744073709551615,number2=-1", | |
591 | false, &error_abort); | |
592 | g_assert_cmpuint(opts_count(opts), ==, 2); | |
593 | g_assert_cmphex(qemu_opt_get_number(opts, "number1", 1), ==, UINT64_MAX); | |
594 | g_assert_cmphex(qemu_opt_get_number(opts, "number2", 0), ==, UINT64_MAX); | |
595 | ||
596 | /* Above upper limit */ | |
597 | opts = qemu_opts_parse(&opts_list_01, "number1=18446744073709551616", | |
3403e5eb MA |
598 | false, &err); |
599 | error_free_or_abort(&err); | |
600 | g_assert(!opts); | |
694baf57 MA |
601 | |
602 | /* Below lower limit */ | |
603 | opts = qemu_opts_parse(&opts_list_01, "number1=-18446744073709551616", | |
3403e5eb MA |
604 | false, &err); |
605 | error_free_or_abort(&err); | |
606 | g_assert(!opts); | |
694baf57 MA |
607 | |
608 | /* Hex and octal */ | |
609 | opts = qemu_opts_parse(&opts_list_01, "number1=0x2a,number2=052", | |
610 | false, &error_abort); | |
611 | g_assert_cmpuint(opts_count(opts), ==, 2); | |
612 | g_assert_cmpuint(qemu_opt_get_number(opts, "number1", 1), ==, 42); | |
613 | g_assert_cmpuint(qemu_opt_get_number(opts, "number2", 0), ==, 42); | |
614 | ||
615 | /* Invalid */ | |
616 | opts = qemu_opts_parse(&opts_list_01, "number1=", false, &err); | |
3403e5eb MA |
617 | error_free_or_abort(&err); |
618 | g_assert(!opts); | |
694baf57 MA |
619 | opts = qemu_opts_parse(&opts_list_01, "number1=eins", false, &err); |
620 | error_free_or_abort(&err); | |
621 | g_assert(!opts); | |
622 | ||
623 | /* Leading whitespace */ | |
624 | opts = qemu_opts_parse(&opts_list_01, "number1= \t42", | |
625 | false, &error_abort); | |
626 | g_assert_cmpuint(opts_count(opts), ==, 1); | |
627 | g_assert_cmpuint(qemu_opt_get_number(opts, "number1", 1), ==, 42); | |
628 | ||
629 | /* Trailing crap */ | |
630 | opts = qemu_opts_parse(&opts_list_01, "number1=3.14", false, &err); | |
631 | error_free_or_abort(&err); | |
632 | g_assert(!opts); | |
633 | opts = qemu_opts_parse(&opts_list_01, "number1=08", false, &err); | |
634 | error_free_or_abort(&err); | |
635 | g_assert(!opts); | |
636 | opts = qemu_opts_parse(&opts_list_01, "number1=0 ", false, &err); | |
637 | error_free_or_abort(&err); | |
638 | g_assert(!opts); | |
639 | ||
640 | qemu_opts_reset(&opts_list_01); | |
641 | } | |
642 | ||
643 | static void test_opts_parse_size(void) | |
644 | { | |
645 | Error *err = NULL; | |
646 | QemuOpts *opts; | |
647 | ||
648 | /* Lower limit zero */ | |
649 | opts = qemu_opts_parse(&opts_list_02, "size1=0", false, &error_abort); | |
650 | g_assert_cmpuint(opts_count(opts), ==, 1); | |
651 | g_assert_cmpuint(qemu_opt_get_size(opts, "size1", 1), ==, 0); | |
652 | ||
653 | /* Note: precision is 53 bits since we're parsing with strtod() */ | |
654 | ||
655 | /* Around limit of precision: 2^53-1, 2^53, 2^54 */ | |
656 | opts = qemu_opts_parse(&opts_list_02, | |
657 | "size1=9007199254740991," | |
658 | "size2=9007199254740992," | |
659 | "size3=9007199254740993", | |
660 | false, &error_abort); | |
661 | g_assert_cmpuint(opts_count(opts), ==, 3); | |
662 | g_assert_cmphex(qemu_opt_get_size(opts, "size1", 1), | |
663 | ==, 0x1fffffffffffff); | |
664 | g_assert_cmphex(qemu_opt_get_size(opts, "size2", 1), | |
665 | ==, 0x20000000000000); | |
666 | g_assert_cmphex(qemu_opt_get_size(opts, "size3", 1), | |
667 | ==, 0x20000000000000); | |
668 | ||
669 | /* Close to signed upper limit 0x7ffffffffffffc00 (53 msbs set) */ | |
670 | opts = qemu_opts_parse(&opts_list_02, | |
671 | "size1=9223372036854774784," /* 7ffffffffffffc00 */ | |
672 | "size2=9223372036854775295", /* 7ffffffffffffdff */ | |
673 | false, &error_abort); | |
674 | g_assert_cmpuint(opts_count(opts), ==, 2); | |
675 | g_assert_cmphex(qemu_opt_get_size(opts, "size1", 1), | |
676 | ==, 0x7ffffffffffffc00); | |
677 | g_assert_cmphex(qemu_opt_get_size(opts, "size2", 1), | |
678 | ==, 0x7ffffffffffffc00); | |
679 | ||
680 | /* Close to actual upper limit 0xfffffffffffff800 (53 msbs set) */ | |
681 | opts = qemu_opts_parse(&opts_list_02, | |
682 | "size1=18446744073709549568," /* fffffffffffff800 */ | |
683 | "size2=18446744073709550591", /* fffffffffffffbff */ | |
684 | false, &error_abort); | |
685 | g_assert_cmpuint(opts_count(opts), ==, 2); | |
686 | g_assert_cmphex(qemu_opt_get_size(opts, "size1", 1), | |
687 | ==, 0xfffffffffffff800); | |
688 | g_assert_cmphex(qemu_opt_get_size(opts, "size2", 1), | |
689 | ==, 0xfffffffffffff800); | |
690 | ||
691 | /* Beyond limits */ | |
692 | opts = qemu_opts_parse(&opts_list_02, "size1=-1", false, &err); | |
693 | error_free_or_abort(&err); | |
694 | g_assert(!opts); | |
695 | opts = qemu_opts_parse(&opts_list_02, | |
696 | "size1=18446744073709550592", /* fffffffffffffc00 */ | |
75cdcd15 MA |
697 | false, &err); |
698 | error_free_or_abort(&err); | |
699 | g_assert(!opts); | |
694baf57 MA |
700 | |
701 | /* Suffixes */ | |
702 | opts = qemu_opts_parse(&opts_list_02, "size1=8b,size2=1.5k,size3=2M", | |
703 | false, &error_abort); | |
704 | g_assert_cmpuint(opts_count(opts), ==, 3); | |
705 | g_assert_cmphex(qemu_opt_get_size(opts, "size1", 0), ==, 8); | |
706 | g_assert_cmphex(qemu_opt_get_size(opts, "size2", 0), ==, 1536); | |
d23b6caa | 707 | g_assert_cmphex(qemu_opt_get_size(opts, "size3", 0), ==, 2 * MiB); |
694baf57 MA |
708 | opts = qemu_opts_parse(&opts_list_02, "size1=0.1G,size2=16777215T", |
709 | false, &error_abort); | |
710 | g_assert_cmpuint(opts_count(opts), ==, 2); | |
d23b6caa PMD |
711 | g_assert_cmphex(qemu_opt_get_size(opts, "size1", 0), ==, GiB / 10); |
712 | g_assert_cmphex(qemu_opt_get_size(opts, "size2", 0), ==, 16777215ULL * TiB); | |
694baf57 MA |
713 | |
714 | /* Beyond limit with suffix */ | |
715 | opts = qemu_opts_parse(&opts_list_02, "size1=16777216T", | |
75cdcd15 MA |
716 | false, &err); |
717 | error_free_or_abort(&err); | |
718 | g_assert(!opts); | |
694baf57 MA |
719 | |
720 | /* Trailing crap */ | |
721 | opts = qemu_opts_parse(&opts_list_02, "size1=16E", false, &err); | |
722 | error_free_or_abort(&err); | |
723 | g_assert(!opts); | |
75cdcd15 MA |
724 | opts = qemu_opts_parse(&opts_list_02, "size1=16Gi", false, &err); |
725 | error_free_or_abort(&err); | |
726 | g_assert(!opts); | |
694baf57 MA |
727 | |
728 | qemu_opts_reset(&opts_list_02); | |
729 | } | |
730 | ||
575ef8bf KW |
731 | static void append_verify_list_01(QemuOptDesc *desc, bool with_overlapping) |
732 | { | |
733 | int i = 0; | |
734 | ||
735 | if (with_overlapping) { | |
736 | g_assert_cmpstr(desc[i].name, ==, "str1"); | |
737 | g_assert_cmpint(desc[i].type, ==, QEMU_OPT_STRING); | |
738 | g_assert_cmpstr(desc[i].help, ==, | |
739 | "Help texts are preserved in qemu_opts_append"); | |
740 | g_assert_cmpstr(desc[i].def_value_str, ==, "default"); | |
741 | i++; | |
742 | ||
743 | g_assert_cmpstr(desc[i].name, ==, "str2"); | |
744 | g_assert_cmpint(desc[i].type, ==, QEMU_OPT_STRING); | |
745 | g_assert_cmpstr(desc[i].help, ==, NULL); | |
746 | g_assert_cmpstr(desc[i].def_value_str, ==, NULL); | |
747 | i++; | |
748 | } | |
749 | ||
750 | g_assert_cmpstr(desc[i].name, ==, "str3"); | |
751 | g_assert_cmpint(desc[i].type, ==, QEMU_OPT_STRING); | |
752 | g_assert_cmpstr(desc[i].help, ==, NULL); | |
753 | g_assert_cmpstr(desc[i].def_value_str, ==, NULL); | |
754 | i++; | |
755 | ||
756 | g_assert_cmpstr(desc[i].name, ==, "number1"); | |
757 | g_assert_cmpint(desc[i].type, ==, QEMU_OPT_NUMBER); | |
758 | g_assert_cmpstr(desc[i].help, ==, | |
759 | "Having help texts only for some options is okay"); | |
760 | g_assert_cmpstr(desc[i].def_value_str, ==, NULL); | |
761 | i++; | |
762 | ||
763 | g_assert_cmpstr(desc[i].name, ==, "number2"); | |
764 | g_assert_cmpint(desc[i].type, ==, QEMU_OPT_NUMBER); | |
765 | g_assert_cmpstr(desc[i].help, ==, NULL); | |
766 | g_assert_cmpstr(desc[i].def_value_str, ==, NULL); | |
767 | i++; | |
768 | ||
769 | g_assert_cmpstr(desc[i].name, ==, NULL); | |
770 | } | |
771 | ||
772 | static void append_verify_list_02(QemuOptDesc *desc) | |
773 | { | |
774 | int i = 0; | |
775 | ||
776 | g_assert_cmpstr(desc[i].name, ==, "str1"); | |
777 | g_assert_cmpint(desc[i].type, ==, QEMU_OPT_STRING); | |
778 | g_assert_cmpstr(desc[i].help, ==, NULL); | |
779 | g_assert_cmpstr(desc[i].def_value_str, ==, NULL); | |
780 | i++; | |
781 | ||
782 | g_assert_cmpstr(desc[i].name, ==, "str2"); | |
783 | g_assert_cmpint(desc[i].type, ==, QEMU_OPT_STRING); | |
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, ==, "bool1"); | |
789 | g_assert_cmpint(desc[i].type, ==, QEMU_OPT_BOOL); | |
790 | g_assert_cmpstr(desc[i].help, ==, NULL); | |
791 | g_assert_cmpstr(desc[i].def_value_str, ==, NULL); | |
792 | i++; | |
793 | ||
794 | g_assert_cmpstr(desc[i].name, ==, "bool2"); | |
795 | g_assert_cmpint(desc[i].type, ==, QEMU_OPT_BOOL); | |
796 | g_assert_cmpstr(desc[i].help, ==, NULL); | |
797 | g_assert_cmpstr(desc[i].def_value_str, ==, NULL); | |
798 | i++; | |
799 | ||
800 | g_assert_cmpstr(desc[i].name, ==, "size1"); | |
801 | g_assert_cmpint(desc[i].type, ==, QEMU_OPT_SIZE); | |
802 | g_assert_cmpstr(desc[i].help, ==, NULL); | |
803 | g_assert_cmpstr(desc[i].def_value_str, ==, NULL); | |
804 | i++; | |
805 | ||
806 | g_assert_cmpstr(desc[i].name, ==, "size2"); | |
807 | g_assert_cmpint(desc[i].type, ==, QEMU_OPT_SIZE); | |
808 | g_assert_cmpstr(desc[i].help, ==, NULL); | |
809 | g_assert_cmpstr(desc[i].def_value_str, ==, NULL); | |
810 | i++; | |
811 | ||
812 | g_assert_cmpstr(desc[i].name, ==, "size3"); | |
813 | g_assert_cmpint(desc[i].type, ==, QEMU_OPT_SIZE); | |
814 | g_assert_cmpstr(desc[i].help, ==, NULL); | |
815 | g_assert_cmpstr(desc[i].def_value_str, ==, NULL); | |
816 | } | |
817 | ||
818 | static void test_opts_append_to_null(void) | |
819 | { | |
820 | QemuOptsList *merged; | |
821 | ||
822 | merged = qemu_opts_append(NULL, &opts_list_01); | |
823 | g_assert(merged != &opts_list_01); | |
824 | ||
825 | g_assert_cmpstr(merged->name, ==, NULL); | |
826 | g_assert_cmpstr(merged->implied_opt_name, ==, NULL); | |
827 | g_assert_false(merged->merge_lists); | |
828 | ||
829 | append_verify_list_01(merged->desc, true); | |
830 | ||
831 | qemu_opts_free(merged); | |
832 | } | |
833 | ||
834 | static void test_opts_append(void) | |
835 | { | |
836 | QemuOptsList *first, *merged; | |
837 | ||
838 | first = qemu_opts_append(NULL, &opts_list_02); | |
839 | merged = qemu_opts_append(first, &opts_list_01); | |
840 | g_assert(first != &opts_list_02); | |
841 | g_assert(merged != &opts_list_01); | |
842 | ||
843 | g_assert_cmpstr(merged->name, ==, NULL); | |
844 | g_assert_cmpstr(merged->implied_opt_name, ==, NULL); | |
845 | g_assert_false(merged->merge_lists); | |
846 | ||
847 | append_verify_list_02(&merged->desc[0]); | |
848 | append_verify_list_01(&merged->desc[7], false); | |
849 | ||
850 | qemu_opts_free(merged); | |
851 | } | |
852 | ||
37974a97 KW |
853 | static void test_opts_to_qdict_basic(void) |
854 | { | |
855 | QemuOpts *opts; | |
856 | QDict *dict; | |
857 | ||
858 | opts = qemu_opts_parse(&opts_list_01, "str1=foo,str2=,str3=bar,number1=42", | |
859 | false, &error_abort); | |
860 | g_assert(opts != NULL); | |
861 | ||
862 | dict = qemu_opts_to_qdict(opts, NULL); | |
863 | g_assert(dict != NULL); | |
864 | ||
865 | g_assert_cmpstr(qdict_get_str(dict, "str1"), ==, "foo"); | |
866 | g_assert_cmpstr(qdict_get_str(dict, "str2"), ==, ""); | |
867 | g_assert_cmpstr(qdict_get_str(dict, "str3"), ==, "bar"); | |
868 | g_assert_cmpstr(qdict_get_str(dict, "number1"), ==, "42"); | |
869 | g_assert_false(qdict_haskey(dict, "number2")); | |
870 | ||
cb3e7f08 | 871 | qobject_unref(dict); |
37974a97 KW |
872 | qemu_opts_del(opts); |
873 | } | |
874 | ||
875 | static void test_opts_to_qdict_filtered(void) | |
876 | { | |
877 | QemuOptsList *first, *merged; | |
878 | QemuOpts *opts; | |
879 | QDict *dict; | |
880 | ||
881 | first = qemu_opts_append(NULL, &opts_list_02); | |
882 | merged = qemu_opts_append(first, &opts_list_01); | |
883 | ||
884 | opts = qemu_opts_parse(merged, | |
885 | "str1=foo,str2=,str3=bar,bool1=off,number1=42", | |
886 | false, &error_abort); | |
887 | g_assert(opts != NULL); | |
888 | ||
889 | /* Convert to QDict without deleting from opts */ | |
890 | dict = qemu_opts_to_qdict_filtered(opts, NULL, &opts_list_01, false); | |
891 | g_assert(dict != NULL); | |
892 | g_assert_cmpstr(qdict_get_str(dict, "str1"), ==, "foo"); | |
893 | g_assert_cmpstr(qdict_get_str(dict, "str2"), ==, ""); | |
894 | g_assert_cmpstr(qdict_get_str(dict, "str3"), ==, "bar"); | |
895 | g_assert_cmpstr(qdict_get_str(dict, "number1"), ==, "42"); | |
896 | g_assert_false(qdict_haskey(dict, "number2")); | |
897 | g_assert_false(qdict_haskey(dict, "bool1")); | |
cb3e7f08 | 898 | qobject_unref(dict); |
37974a97 KW |
899 | |
900 | dict = qemu_opts_to_qdict_filtered(opts, NULL, &opts_list_02, false); | |
901 | g_assert(dict != NULL); | |
902 | g_assert_cmpstr(qdict_get_str(dict, "str1"), ==, "foo"); | |
903 | g_assert_cmpstr(qdict_get_str(dict, "str2"), ==, ""); | |
904 | g_assert_cmpstr(qdict_get_str(dict, "bool1"), ==, "off"); | |
905 | g_assert_false(qdict_haskey(dict, "str3")); | |
906 | g_assert_false(qdict_haskey(dict, "number1")); | |
907 | g_assert_false(qdict_haskey(dict, "number2")); | |
cb3e7f08 | 908 | qobject_unref(dict); |
37974a97 KW |
909 | |
910 | /* Now delete converted options from opts */ | |
911 | dict = qemu_opts_to_qdict_filtered(opts, NULL, &opts_list_01, true); | |
912 | g_assert(dict != NULL); | |
913 | g_assert_cmpstr(qdict_get_str(dict, "str1"), ==, "foo"); | |
914 | g_assert_cmpstr(qdict_get_str(dict, "str2"), ==, ""); | |
915 | g_assert_cmpstr(qdict_get_str(dict, "str3"), ==, "bar"); | |
916 | g_assert_cmpstr(qdict_get_str(dict, "number1"), ==, "42"); | |
917 | g_assert_false(qdict_haskey(dict, "number2")); | |
918 | g_assert_false(qdict_haskey(dict, "bool1")); | |
cb3e7f08 | 919 | qobject_unref(dict); |
37974a97 KW |
920 | |
921 | dict = qemu_opts_to_qdict_filtered(opts, NULL, &opts_list_02, true); | |
922 | g_assert(dict != NULL); | |
923 | g_assert_cmpstr(qdict_get_str(dict, "bool1"), ==, "off"); | |
924 | g_assert_false(qdict_haskey(dict, "str1")); | |
925 | g_assert_false(qdict_haskey(dict, "str2")); | |
926 | g_assert_false(qdict_haskey(dict, "str3")); | |
927 | g_assert_false(qdict_haskey(dict, "number1")); | |
928 | g_assert_false(qdict_haskey(dict, "number2")); | |
cb3e7f08 | 929 | qobject_unref(dict); |
37974a97 KW |
930 | |
931 | g_assert_true(QTAILQ_EMPTY(&opts->head)); | |
932 | ||
933 | qemu_opts_del(opts); | |
934 | qemu_opts_free(merged); | |
935 | } | |
936 | ||
937 | static void test_opts_to_qdict_duplicates(void) | |
938 | { | |
939 | QemuOpts *opts; | |
940 | QemuOpt *opt; | |
941 | QDict *dict; | |
942 | ||
943 | opts = qemu_opts_parse(&opts_list_03, "foo=a,foo=b", false, &error_abort); | |
944 | g_assert(opts != NULL); | |
945 | ||
946 | /* Verify that opts has two options with the same name */ | |
947 | opt = QTAILQ_FIRST(&opts->head); | |
948 | g_assert_cmpstr(opt->name, ==, "foo"); | |
949 | g_assert_cmpstr(opt->str , ==, "a"); | |
950 | ||
951 | opt = QTAILQ_NEXT(opt, next); | |
952 | g_assert_cmpstr(opt->name, ==, "foo"); | |
953 | g_assert_cmpstr(opt->str , ==, "b"); | |
954 | ||
955 | opt = QTAILQ_NEXT(opt, next); | |
956 | g_assert(opt == NULL); | |
957 | ||
958 | /* In the conversion to QDict, the last one wins */ | |
959 | dict = qemu_opts_to_qdict(opts, NULL); | |
960 | g_assert(dict != NULL); | |
961 | g_assert_cmpstr(qdict_get_str(dict, "foo"), ==, "b"); | |
cb3e7f08 | 962 | qobject_unref(dict); |
37974a97 KW |
963 | |
964 | /* The last one still wins if entries are deleted, and both are deleted */ | |
965 | dict = qemu_opts_to_qdict_filtered(opts, NULL, NULL, true); | |
966 | g_assert(dict != NULL); | |
967 | g_assert_cmpstr(qdict_get_str(dict, "foo"), ==, "b"); | |
cb3e7f08 | 968 | qobject_unref(dict); |
37974a97 KW |
969 | |
970 | g_assert_true(QTAILQ_EMPTY(&opts->head)); | |
971 | ||
972 | qemu_opts_del(opts); | |
973 | } | |
575ef8bf | 974 | |
4ba6fabf LD |
975 | int main(int argc, char *argv[]) |
976 | { | |
977 | register_opts(); | |
978 | g_test_init(&argc, &argv, NULL); | |
979 | g_test_add_func("/qemu-opts/find_unknown_opts", test_find_unknown_opts); | |
980 | g_test_add_func("/qemu-opts/find_opts", test_qemu_find_opts); | |
981 | g_test_add_func("/qemu-opts/opts_create", test_qemu_opts_create); | |
982 | g_test_add_func("/qemu-opts/opt_get", test_qemu_opt_get); | |
983 | g_test_add_func("/qemu-opts/opt_get_bool", test_qemu_opt_get_bool); | |
984 | g_test_add_func("/qemu-opts/opt_get_number", test_qemu_opt_get_number); | |
985 | g_test_add_func("/qemu-opts/opt_get_size", test_qemu_opt_get_size); | |
986 | g_test_add_func("/qemu-opts/opt_unset", test_qemu_opt_unset); | |
987 | g_test_add_func("/qemu-opts/opts_reset", test_qemu_opts_reset); | |
988 | g_test_add_func("/qemu-opts/opts_set", test_qemu_opts_set); | |
694baf57 MA |
989 | g_test_add_func("/qemu-opts/opts_parse/general", test_opts_parse); |
990 | g_test_add_func("/qemu-opts/opts_parse/bool", test_opts_parse_bool); | |
991 | g_test_add_func("/qemu-opts/opts_parse/number", test_opts_parse_number); | |
992 | g_test_add_func("/qemu-opts/opts_parse/size", test_opts_parse_size); | |
575ef8bf KW |
993 | g_test_add_func("/qemu-opts/append_to_null", test_opts_append_to_null); |
994 | g_test_add_func("/qemu-opts/append", test_opts_append); | |
37974a97 KW |
995 | g_test_add_func("/qemu-opts/to_qdict/basic", test_opts_to_qdict_basic); |
996 | g_test_add_func("/qemu-opts/to_qdict/filtered", test_opts_to_qdict_filtered); | |
997 | g_test_add_func("/qemu-opts/to_qdict/duplicates", test_opts_to_qdict_duplicates); | |
4ba6fabf LD |
998 | g_test_run(); |
999 | return 0; | |
1000 | } |