xref: /qemu/tests/unit/test-qemu-opts.c (revision 904806c6)
1*da668aa1SThomas Huth /*
2*da668aa1SThomas Huth  * QemuOpts unit-tests.
3*da668aa1SThomas Huth  *
4*da668aa1SThomas Huth  * Copyright (C) 2014 Leandro Dorileo <l@dorileo.org>
5*da668aa1SThomas Huth  *
6*da668aa1SThomas Huth  * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
7*da668aa1SThomas Huth  * See the COPYING.LIB file in the top-level directory.
8*da668aa1SThomas Huth  */
9*da668aa1SThomas Huth 
10*da668aa1SThomas Huth #include "qemu/osdep.h"
11*da668aa1SThomas Huth #include "qemu/units.h"
12*da668aa1SThomas Huth #include "qemu/option.h"
13*da668aa1SThomas Huth #include "qemu/option_int.h"
14*da668aa1SThomas Huth #include "qapi/error.h"
15*da668aa1SThomas Huth #include "qapi/qmp/qdict.h"
16*da668aa1SThomas Huth #include "qapi/qmp/qstring.h"
17*da668aa1SThomas Huth #include "qemu/config-file.h"
18*da668aa1SThomas Huth 
19*da668aa1SThomas Huth 
20*da668aa1SThomas Huth static QemuOptsList opts_list_01 = {
21*da668aa1SThomas Huth     .name = "opts_list_01",
22*da668aa1SThomas Huth     .head = QTAILQ_HEAD_INITIALIZER(opts_list_01.head),
23*da668aa1SThomas Huth     .desc = {
24*da668aa1SThomas Huth         {
25*da668aa1SThomas Huth             .name = "str1",
26*da668aa1SThomas Huth             .type = QEMU_OPT_STRING,
27*da668aa1SThomas Huth             .help = "Help texts are preserved in qemu_opts_append",
28*da668aa1SThomas Huth             .def_value_str = "default",
29*da668aa1SThomas Huth         },{
30*da668aa1SThomas Huth             .name = "str2",
31*da668aa1SThomas Huth             .type = QEMU_OPT_STRING,
32*da668aa1SThomas Huth         },{
33*da668aa1SThomas Huth             .name = "str3",
34*da668aa1SThomas Huth             .type = QEMU_OPT_STRING,
35*da668aa1SThomas Huth         },{
36*da668aa1SThomas Huth             .name = "number1",
37*da668aa1SThomas Huth             .type = QEMU_OPT_NUMBER,
38*da668aa1SThomas Huth             .help = "Having help texts only for some options is okay",
39*da668aa1SThomas Huth         },{
40*da668aa1SThomas Huth             .name = "number2",
41*da668aa1SThomas Huth             .type = QEMU_OPT_NUMBER,
42*da668aa1SThomas Huth         },
43*da668aa1SThomas Huth         { /* end of list */ }
44*da668aa1SThomas Huth     },
45*da668aa1SThomas Huth };
46*da668aa1SThomas Huth 
47*da668aa1SThomas Huth static QemuOptsList opts_list_02 = {
48*da668aa1SThomas Huth     .name = "opts_list_02",
49*da668aa1SThomas Huth     .head = QTAILQ_HEAD_INITIALIZER(opts_list_02.head),
50*da668aa1SThomas Huth     .desc = {
51*da668aa1SThomas Huth         {
52*da668aa1SThomas Huth             .name = "str1",
53*da668aa1SThomas Huth             .type = QEMU_OPT_STRING,
54*da668aa1SThomas Huth         },{
55*da668aa1SThomas Huth             .name = "str2",
56*da668aa1SThomas Huth             .type = QEMU_OPT_STRING,
57*da668aa1SThomas Huth         },{
58*da668aa1SThomas Huth             .name = "bool1",
59*da668aa1SThomas Huth             .type = QEMU_OPT_BOOL,
60*da668aa1SThomas Huth         },{
61*da668aa1SThomas Huth             .name = "bool2",
62*da668aa1SThomas Huth             .type = QEMU_OPT_BOOL,
63*da668aa1SThomas Huth         },{
64*da668aa1SThomas Huth             .name = "size1",
65*da668aa1SThomas Huth             .type = QEMU_OPT_SIZE,
66*da668aa1SThomas Huth         },{
67*da668aa1SThomas Huth             .name = "size2",
68*da668aa1SThomas Huth             .type = QEMU_OPT_SIZE,
69*da668aa1SThomas Huth         },{
70*da668aa1SThomas Huth             .name = "size3",
71*da668aa1SThomas Huth             .type = QEMU_OPT_SIZE,
72*da668aa1SThomas Huth         },
73*da668aa1SThomas Huth         { /* end of list */ }
74*da668aa1SThomas Huth     },
75*da668aa1SThomas Huth };
76*da668aa1SThomas Huth 
77*da668aa1SThomas Huth static QemuOptsList opts_list_03 = {
78*da668aa1SThomas Huth     .name = "opts_list_03",
79*da668aa1SThomas Huth     .implied_opt_name = "implied",
80*da668aa1SThomas Huth     .head = QTAILQ_HEAD_INITIALIZER(opts_list_03.head),
81*da668aa1SThomas Huth     .desc = {
82*da668aa1SThomas Huth         /* no elements => accept any params */
83*da668aa1SThomas Huth         { /* end of list */ }
84*da668aa1SThomas Huth     },
85*da668aa1SThomas Huth };
86*da668aa1SThomas Huth 
87*da668aa1SThomas Huth static QemuOptsList opts_list_04 = {
88*da668aa1SThomas Huth     .name = "opts_list_04",
89*da668aa1SThomas Huth     .head = QTAILQ_HEAD_INITIALIZER(opts_list_04.head),
90*da668aa1SThomas Huth     .merge_lists = true,
91*da668aa1SThomas Huth     .desc = {
92*da668aa1SThomas Huth         {
93*da668aa1SThomas Huth             .name = "str3",
94*da668aa1SThomas Huth             .type = QEMU_OPT_STRING,
95*da668aa1SThomas Huth         },
96*da668aa1SThomas Huth         { /* end of list */ }
97*da668aa1SThomas Huth     },
98*da668aa1SThomas Huth };
99*da668aa1SThomas Huth 
register_opts(void)100*da668aa1SThomas Huth static void register_opts(void)
101*da668aa1SThomas Huth {
102*da668aa1SThomas Huth     qemu_add_opts(&opts_list_01);
103*da668aa1SThomas Huth     qemu_add_opts(&opts_list_02);
104*da668aa1SThomas Huth     qemu_add_opts(&opts_list_03);
105*da668aa1SThomas Huth     qemu_add_opts(&opts_list_04);
106*da668aa1SThomas Huth }
107*da668aa1SThomas Huth 
test_find_unknown_opts(void)108*da668aa1SThomas Huth static void test_find_unknown_opts(void)
109*da668aa1SThomas Huth {
110*da668aa1SThomas Huth     QemuOptsList *list;
111*da668aa1SThomas Huth     Error *err = NULL;
112*da668aa1SThomas Huth 
113*da668aa1SThomas Huth     /* should not return anything, we don't have an "unknown" option */
114*da668aa1SThomas Huth     list = qemu_find_opts_err("unknown", &err);
115*da668aa1SThomas Huth     g_assert(list == NULL);
116*da668aa1SThomas Huth     error_free_or_abort(&err);
117*da668aa1SThomas Huth }
118*da668aa1SThomas Huth 
test_qemu_find_opts(void)119*da668aa1SThomas Huth static void test_qemu_find_opts(void)
120*da668aa1SThomas Huth {
121*da668aa1SThomas Huth     QemuOptsList *list;
122*da668aa1SThomas Huth 
123*da668aa1SThomas Huth     /* we have an "opts_list_01" option, should return it */
124*da668aa1SThomas Huth     list = qemu_find_opts("opts_list_01");
125*da668aa1SThomas Huth     g_assert(list != NULL);
126*da668aa1SThomas Huth     g_assert_cmpstr(list->name, ==, "opts_list_01");
127*da668aa1SThomas Huth }
128*da668aa1SThomas Huth 
test_qemu_opts_create(void)129*da668aa1SThomas Huth static void test_qemu_opts_create(void)
130*da668aa1SThomas Huth {
131*da668aa1SThomas Huth     QemuOptsList *list;
132*da668aa1SThomas Huth     QemuOpts *opts;
133*da668aa1SThomas Huth 
134*da668aa1SThomas Huth     list = qemu_find_opts("opts_list_01");
135*da668aa1SThomas Huth     g_assert(list != NULL);
136*da668aa1SThomas Huth     g_assert(QTAILQ_EMPTY(&list->head));
137*da668aa1SThomas Huth     g_assert_cmpstr(list->name, ==, "opts_list_01");
138*da668aa1SThomas Huth 
139*da668aa1SThomas Huth     /* should not find anything at this point */
140*da668aa1SThomas Huth     opts = qemu_opts_find(list, NULL);
141*da668aa1SThomas Huth     g_assert(opts == NULL);
142*da668aa1SThomas Huth 
143*da668aa1SThomas Huth     /* create the opts */
144*da668aa1SThomas Huth     opts = qemu_opts_create(list, NULL, 0, &error_abort);
145*da668aa1SThomas Huth     g_assert(opts != NULL);
146*da668aa1SThomas Huth     g_assert(!QTAILQ_EMPTY(&list->head));
147*da668aa1SThomas Huth 
148*da668aa1SThomas Huth     /* now we've create the opts, must find it */
149*da668aa1SThomas Huth     opts = qemu_opts_find(list, NULL);
150*da668aa1SThomas Huth     g_assert(opts != NULL);
151*da668aa1SThomas Huth 
152*da668aa1SThomas Huth     qemu_opts_del(opts);
153*da668aa1SThomas Huth 
154*da668aa1SThomas Huth     /* should not find anything at this point */
155*da668aa1SThomas Huth     opts = qemu_opts_find(list, NULL);
156*da668aa1SThomas Huth     g_assert(opts == NULL);
157*da668aa1SThomas Huth }
158*da668aa1SThomas Huth 
test_qemu_opt_get(void)159*da668aa1SThomas Huth static void test_qemu_opt_get(void)
160*da668aa1SThomas Huth {
161*da668aa1SThomas Huth     QemuOptsList *list;
162*da668aa1SThomas Huth     QemuOpts *opts;
163*da668aa1SThomas Huth     const char *opt = NULL;
164*da668aa1SThomas Huth 
165*da668aa1SThomas Huth     list = qemu_find_opts("opts_list_01");
166*da668aa1SThomas Huth     g_assert(list != NULL);
167*da668aa1SThomas Huth     g_assert(QTAILQ_EMPTY(&list->head));
168*da668aa1SThomas Huth     g_assert_cmpstr(list->name, ==, "opts_list_01");
169*da668aa1SThomas Huth 
170*da668aa1SThomas Huth     /* should not find anything at this point */
171*da668aa1SThomas Huth     opts = qemu_opts_find(list, NULL);
172*da668aa1SThomas Huth     g_assert(opts == NULL);
173*da668aa1SThomas Huth 
174*da668aa1SThomas Huth     /* create the opts */
175*da668aa1SThomas Huth     opts = qemu_opts_create(list, NULL, 0, &error_abort);
176*da668aa1SThomas Huth     g_assert(opts != NULL);
177*da668aa1SThomas Huth     g_assert(!QTAILQ_EMPTY(&list->head));
178*da668aa1SThomas Huth 
179*da668aa1SThomas Huth     /* haven't set anything to str2 yet */
180*da668aa1SThomas Huth     opt = qemu_opt_get(opts, "str2");
181*da668aa1SThomas Huth     g_assert(opt == NULL);
182*da668aa1SThomas Huth 
183*da668aa1SThomas Huth     qemu_opt_set(opts, "str2", "value", &error_abort);
184*da668aa1SThomas Huth 
185*da668aa1SThomas Huth     /* now we have set str2, should know about it */
186*da668aa1SThomas Huth     opt = qemu_opt_get(opts, "str2");
187*da668aa1SThomas Huth     g_assert_cmpstr(opt, ==, "value");
188*da668aa1SThomas Huth 
189*da668aa1SThomas Huth     qemu_opt_set(opts, "str2", "value2", &error_abort);
190*da668aa1SThomas Huth 
191*da668aa1SThomas Huth     /* having reset the value, the returned should be the reset one */
192*da668aa1SThomas Huth     opt = qemu_opt_get(opts, "str2");
193*da668aa1SThomas Huth     g_assert_cmpstr(opt, ==, "value2");
194*da668aa1SThomas Huth 
195*da668aa1SThomas Huth     qemu_opts_del(opts);
196*da668aa1SThomas Huth 
197*da668aa1SThomas Huth     /* should not find anything at this point */
198*da668aa1SThomas Huth     opts = qemu_opts_find(list, NULL);
199*da668aa1SThomas Huth     g_assert(opts == NULL);
200*da668aa1SThomas Huth }
201*da668aa1SThomas Huth 
test_qemu_opt_get_bool(void)202*da668aa1SThomas Huth static void test_qemu_opt_get_bool(void)
203*da668aa1SThomas Huth {
204*da668aa1SThomas Huth     QemuOptsList *list;
205*da668aa1SThomas Huth     QemuOpts *opts;
206*da668aa1SThomas Huth     bool opt;
207*da668aa1SThomas Huth 
208*da668aa1SThomas Huth     list = qemu_find_opts("opts_list_02");
209*da668aa1SThomas Huth     g_assert(list != NULL);
210*da668aa1SThomas Huth     g_assert(QTAILQ_EMPTY(&list->head));
211*da668aa1SThomas Huth     g_assert_cmpstr(list->name, ==, "opts_list_02");
212*da668aa1SThomas Huth 
213*da668aa1SThomas Huth     /* should not find anything at this point */
214*da668aa1SThomas Huth     opts = qemu_opts_find(list, NULL);
215*da668aa1SThomas Huth     g_assert(opts == NULL);
216*da668aa1SThomas Huth 
217*da668aa1SThomas Huth     /* create the opts */
218*da668aa1SThomas Huth     opts = qemu_opts_create(list, NULL, 0, &error_abort);
219*da668aa1SThomas Huth     g_assert(opts != NULL);
220*da668aa1SThomas Huth     g_assert(!QTAILQ_EMPTY(&list->head));
221*da668aa1SThomas Huth 
222*da668aa1SThomas Huth     /* haven't set anything to bool1 yet, so defval should be returned */
223*da668aa1SThomas Huth     opt = qemu_opt_get_bool(opts, "bool1", false);
224*da668aa1SThomas Huth     g_assert(opt == false);
225*da668aa1SThomas Huth 
226*da668aa1SThomas Huth     qemu_opt_set_bool(opts, "bool1", true, &error_abort);
227*da668aa1SThomas Huth 
228*da668aa1SThomas Huth     /* now we have set bool1, should know about it */
229*da668aa1SThomas Huth     opt = qemu_opt_get_bool(opts, "bool1", false);
230*da668aa1SThomas Huth     g_assert(opt == true);
231*da668aa1SThomas Huth 
232*da668aa1SThomas Huth     /* having reset the value, opt should be the reset one not defval */
233*da668aa1SThomas Huth     qemu_opt_set_bool(opts, "bool1", false, &error_abort);
234*da668aa1SThomas Huth 
235*da668aa1SThomas Huth     opt = qemu_opt_get_bool(opts, "bool1", true);
236*da668aa1SThomas Huth     g_assert(opt == false);
237*da668aa1SThomas Huth 
238*da668aa1SThomas Huth     qemu_opts_del(opts);
239*da668aa1SThomas Huth 
240*da668aa1SThomas Huth     /* should not find anything at this point */
241*da668aa1SThomas Huth     opts = qemu_opts_find(list, NULL);
242*da668aa1SThomas Huth     g_assert(opts == NULL);
243*da668aa1SThomas Huth }
244*da668aa1SThomas Huth 
test_qemu_opt_get_number(void)245*da668aa1SThomas Huth static void test_qemu_opt_get_number(void)
246*da668aa1SThomas Huth {
247*da668aa1SThomas Huth     QemuOptsList *list;
248*da668aa1SThomas Huth     QemuOpts *opts;
249*da668aa1SThomas Huth     uint64_t opt;
250*da668aa1SThomas Huth 
251*da668aa1SThomas Huth     list = qemu_find_opts("opts_list_01");
252*da668aa1SThomas Huth     g_assert(list != NULL);
253*da668aa1SThomas Huth     g_assert(QTAILQ_EMPTY(&list->head));
254*da668aa1SThomas Huth     g_assert_cmpstr(list->name, ==, "opts_list_01");
255*da668aa1SThomas Huth 
256*da668aa1SThomas Huth     /* should not find anything at this point */
257*da668aa1SThomas Huth     opts = qemu_opts_find(list, NULL);
258*da668aa1SThomas Huth     g_assert(opts == NULL);
259*da668aa1SThomas Huth 
260*da668aa1SThomas Huth     /* create the opts */
261*da668aa1SThomas Huth     opts = qemu_opts_create(list, NULL, 0, &error_abort);
262*da668aa1SThomas Huth     g_assert(opts != NULL);
263*da668aa1SThomas Huth     g_assert(!QTAILQ_EMPTY(&list->head));
264*da668aa1SThomas Huth 
265*da668aa1SThomas Huth     /* haven't set anything to number1 yet, so defval should be returned */
266*da668aa1SThomas Huth     opt = qemu_opt_get_number(opts, "number1", 5);
267*da668aa1SThomas Huth     g_assert(opt == 5);
268*da668aa1SThomas Huth 
269*da668aa1SThomas Huth     qemu_opt_set_number(opts, "number1", 10, &error_abort);
270*da668aa1SThomas Huth 
271*da668aa1SThomas Huth     /* now we have set number1, should know about it */
272*da668aa1SThomas Huth     opt = qemu_opt_get_number(opts, "number1", 5);
273*da668aa1SThomas Huth     g_assert(opt == 10);
274*da668aa1SThomas Huth 
275*da668aa1SThomas Huth     /* having reset it, the returned should be the reset one not defval */
276*da668aa1SThomas Huth     qemu_opt_set_number(opts, "number1", 15, &error_abort);
277*da668aa1SThomas Huth 
278*da668aa1SThomas Huth     opt = qemu_opt_get_number(opts, "number1", 5);
279*da668aa1SThomas Huth     g_assert(opt == 15);
280*da668aa1SThomas Huth 
281*da668aa1SThomas Huth     qemu_opts_del(opts);
282*da668aa1SThomas Huth 
283*da668aa1SThomas Huth     /* should not find anything at this point */
284*da668aa1SThomas Huth     opts = qemu_opts_find(list, NULL);
285*da668aa1SThomas Huth     g_assert(opts == NULL);
286*da668aa1SThomas Huth }
287*da668aa1SThomas Huth 
test_qemu_opt_get_size(void)288*da668aa1SThomas Huth static void test_qemu_opt_get_size(void)
289*da668aa1SThomas Huth {
290*da668aa1SThomas Huth     QemuOptsList *list;
291*da668aa1SThomas Huth     QemuOpts *opts;
292*da668aa1SThomas Huth     uint64_t opt;
293*da668aa1SThomas Huth     QDict *dict;
294*da668aa1SThomas Huth 
295*da668aa1SThomas Huth     list = qemu_find_opts("opts_list_02");
296*da668aa1SThomas Huth     g_assert(list != NULL);
297*da668aa1SThomas Huth     g_assert(QTAILQ_EMPTY(&list->head));
298*da668aa1SThomas Huth     g_assert_cmpstr(list->name, ==, "opts_list_02");
299*da668aa1SThomas Huth 
300*da668aa1SThomas Huth     /* should not find anything at this point */
301*da668aa1SThomas Huth     opts = qemu_opts_find(list, NULL);
302*da668aa1SThomas Huth     g_assert(opts == NULL);
303*da668aa1SThomas Huth 
304*da668aa1SThomas Huth     /* create the opts */
305*da668aa1SThomas Huth     opts = qemu_opts_create(list, NULL, 0, &error_abort);
306*da668aa1SThomas Huth     g_assert(opts != NULL);
307*da668aa1SThomas Huth     g_assert(!QTAILQ_EMPTY(&list->head));
308*da668aa1SThomas Huth 
309*da668aa1SThomas Huth     /* haven't set anything to size1 yet, so defval should be returned */
310*da668aa1SThomas Huth     opt = qemu_opt_get_size(opts, "size1", 5);
311*da668aa1SThomas Huth     g_assert(opt == 5);
312*da668aa1SThomas Huth 
313*da668aa1SThomas Huth     dict = qdict_new();
314*da668aa1SThomas Huth     g_assert(dict != NULL);
315*da668aa1SThomas Huth 
316*da668aa1SThomas Huth     qdict_put_str(dict, "size1", "10");
317*da668aa1SThomas Huth 
318*da668aa1SThomas Huth     qemu_opts_absorb_qdict(opts, dict, &error_abort);
319*da668aa1SThomas Huth     g_assert(error_abort == NULL);
320*da668aa1SThomas Huth 
321*da668aa1SThomas Huth     /* now we have set size1, should know about it */
322*da668aa1SThomas Huth     opt = qemu_opt_get_size(opts, "size1", 5);
323*da668aa1SThomas Huth     g_assert(opt == 10);
324*da668aa1SThomas Huth 
325*da668aa1SThomas Huth     /* reset value */
326*da668aa1SThomas Huth     qdict_put_str(dict, "size1", "15");
327*da668aa1SThomas Huth 
328*da668aa1SThomas Huth     qemu_opts_absorb_qdict(opts, dict, &error_abort);
329*da668aa1SThomas Huth     g_assert(error_abort == NULL);
330*da668aa1SThomas Huth 
331*da668aa1SThomas Huth     /* test the reset value */
332*da668aa1SThomas Huth     opt = qemu_opt_get_size(opts, "size1", 5);
333*da668aa1SThomas Huth     g_assert(opt == 15);
334*da668aa1SThomas Huth 
335*da668aa1SThomas Huth     qdict_del(dict, "size1");
336*da668aa1SThomas Huth     g_free(dict);
337*da668aa1SThomas Huth 
338*da668aa1SThomas Huth     qemu_opts_del(opts);
339*da668aa1SThomas Huth 
340*da668aa1SThomas Huth     /* should not find anything at this point */
341*da668aa1SThomas Huth     opts = qemu_opts_find(list, NULL);
342*da668aa1SThomas Huth     g_assert(opts == NULL);
343*da668aa1SThomas Huth }
344*da668aa1SThomas Huth 
test_qemu_opt_unset(void)345*da668aa1SThomas Huth static void test_qemu_opt_unset(void)
346*da668aa1SThomas Huth {
347*da668aa1SThomas Huth     QemuOpts *opts;
348*da668aa1SThomas Huth     const char *value;
349*da668aa1SThomas Huth     int ret;
350*da668aa1SThomas Huth 
351*da668aa1SThomas Huth     /* dynamically initialized (parsed) opts */
352*da668aa1SThomas Huth     opts = qemu_opts_parse(&opts_list_03, "key=value", false, NULL);
353*da668aa1SThomas Huth     g_assert(opts != NULL);
354*da668aa1SThomas Huth 
355*da668aa1SThomas Huth     /* check default/parsed value */
356*da668aa1SThomas Huth     value = qemu_opt_get(opts, "key");
357*da668aa1SThomas Huth     g_assert_cmpstr(value, ==, "value");
358*da668aa1SThomas Huth 
359*da668aa1SThomas Huth     /* reset it to value2 */
360*da668aa1SThomas Huth     qemu_opt_set(opts, "key", "value2", &error_abort);
361*da668aa1SThomas Huth 
362*da668aa1SThomas Huth     value = qemu_opt_get(opts, "key");
363*da668aa1SThomas Huth     g_assert_cmpstr(value, ==, "value2");
364*da668aa1SThomas Huth 
365*da668aa1SThomas Huth     /* unset, valid only for "accept any" */
366*da668aa1SThomas Huth     ret = qemu_opt_unset(opts, "key");
367*da668aa1SThomas Huth     g_assert(ret == 0);
368*da668aa1SThomas Huth 
369*da668aa1SThomas Huth     /* after reset the value should be the parsed/default one */
370*da668aa1SThomas Huth     value = qemu_opt_get(opts, "key");
371*da668aa1SThomas Huth     g_assert_cmpstr(value, ==, "value");
372*da668aa1SThomas Huth 
373*da668aa1SThomas Huth     qemu_opts_del(opts);
374*da668aa1SThomas Huth }
375*da668aa1SThomas Huth 
test_qemu_opts_reset(void)376*da668aa1SThomas Huth static void test_qemu_opts_reset(void)
377*da668aa1SThomas Huth {
378*da668aa1SThomas Huth     QemuOptsList *list;
379*da668aa1SThomas Huth     QemuOpts *opts;
380*da668aa1SThomas Huth     uint64_t opt;
381*da668aa1SThomas Huth 
382*da668aa1SThomas Huth     list = qemu_find_opts("opts_list_01");
383*da668aa1SThomas Huth     g_assert(list != NULL);
384*da668aa1SThomas Huth     g_assert(QTAILQ_EMPTY(&list->head));
385*da668aa1SThomas Huth     g_assert_cmpstr(list->name, ==, "opts_list_01");
386*da668aa1SThomas Huth 
387*da668aa1SThomas Huth     /* should not find anything at this point */
388*da668aa1SThomas Huth     opts = qemu_opts_find(list, NULL);
389*da668aa1SThomas Huth     g_assert(opts == NULL);
390*da668aa1SThomas Huth 
391*da668aa1SThomas Huth     /* create the opts */
392*da668aa1SThomas Huth     opts = qemu_opts_create(list, NULL, 0, &error_abort);
393*da668aa1SThomas Huth     g_assert(opts != NULL);
394*da668aa1SThomas Huth     g_assert(!QTAILQ_EMPTY(&list->head));
395*da668aa1SThomas Huth 
396*da668aa1SThomas Huth     /* haven't set anything to number1 yet, so defval should be returned */
397*da668aa1SThomas Huth     opt = qemu_opt_get_number(opts, "number1", 5);
398*da668aa1SThomas Huth     g_assert(opt == 5);
399*da668aa1SThomas Huth 
400*da668aa1SThomas Huth     qemu_opt_set_number(opts, "number1", 10, &error_abort);
401*da668aa1SThomas Huth 
402*da668aa1SThomas Huth     /* now we have set number1, should know about it */
403*da668aa1SThomas Huth     opt = qemu_opt_get_number(opts, "number1", 5);
404*da668aa1SThomas Huth     g_assert(opt == 10);
405*da668aa1SThomas Huth 
406*da668aa1SThomas Huth     qemu_opts_reset(list);
407*da668aa1SThomas Huth 
408*da668aa1SThomas Huth     /* should not find anything at this point */
409*da668aa1SThomas Huth     opts = qemu_opts_find(list, NULL);
410*da668aa1SThomas Huth     g_assert(opts == NULL);
411*da668aa1SThomas Huth }
412*da668aa1SThomas Huth 
opts_count_iter(void * opaque,const char * name,const char * value,Error ** errp)413*da668aa1SThomas Huth static int opts_count_iter(void *opaque, const char *name, const char *value,
414*da668aa1SThomas Huth                            Error **errp)
415*da668aa1SThomas Huth {
416*da668aa1SThomas Huth     (*(size_t *)opaque)++;
417*da668aa1SThomas Huth     return 0;
418*da668aa1SThomas Huth }
419*da668aa1SThomas Huth 
opts_count(QemuOpts * opts)420*da668aa1SThomas Huth static size_t opts_count(QemuOpts *opts)
421*da668aa1SThomas Huth {
422*da668aa1SThomas Huth     size_t n = 0;
423*da668aa1SThomas Huth 
424*da668aa1SThomas Huth     qemu_opt_foreach(opts, opts_count_iter, &n, NULL);
425*da668aa1SThomas Huth     return n;
426*da668aa1SThomas Huth }
427*da668aa1SThomas Huth 
test_opts_parse(void)428*da668aa1SThomas Huth static void test_opts_parse(void)
429*da668aa1SThomas Huth {
430*da668aa1SThomas Huth     Error *err = NULL;
431*da668aa1SThomas Huth     QemuOpts *opts;
432*da668aa1SThomas Huth 
433*da668aa1SThomas Huth     /* Nothing */
434*da668aa1SThomas Huth     opts = qemu_opts_parse(&opts_list_03, "", false, &error_abort);
435*da668aa1SThomas Huth     g_assert_cmpuint(opts_count(opts), ==, 0);
436*da668aa1SThomas Huth 
437*da668aa1SThomas Huth     /* Empty key */
438*da668aa1SThomas Huth     opts = qemu_opts_parse(&opts_list_03, "=val", false, &error_abort);
439*da668aa1SThomas Huth     g_assert_cmpuint(opts_count(opts), ==, 1);
440*da668aa1SThomas Huth     g_assert_cmpstr(qemu_opt_get(opts, ""), ==, "val");
441*da668aa1SThomas Huth 
442*da668aa1SThomas Huth     /* Multiple keys, last one wins */
443*da668aa1SThomas Huth     opts = qemu_opts_parse(&opts_list_03, "a=1,b=2,,x,a=3",
444*da668aa1SThomas Huth                            false, &error_abort);
445*da668aa1SThomas Huth     g_assert_cmpuint(opts_count(opts), ==, 3);
446*da668aa1SThomas Huth     g_assert_cmpstr(qemu_opt_get(opts, "a"), ==, "3");
447*da668aa1SThomas Huth     g_assert_cmpstr(qemu_opt_get(opts, "b"), ==, "2,x");
448*da668aa1SThomas Huth 
449*da668aa1SThomas Huth     /* Except when it doesn't */
450*da668aa1SThomas Huth     opts = qemu_opts_parse(&opts_list_03, "id=foo,id=bar",
451*da668aa1SThomas Huth                            false, &error_abort);
452*da668aa1SThomas Huth     g_assert_cmpuint(opts_count(opts), ==, 0);
453*da668aa1SThomas Huth     g_assert_cmpstr(qemu_opts_id(opts), ==, "foo");
454*da668aa1SThomas Huth 
455*da668aa1SThomas Huth     /* TODO Cover low-level access to repeated keys */
456*da668aa1SThomas Huth 
457*da668aa1SThomas Huth     /* Trailing comma is ignored */
458*da668aa1SThomas Huth     opts = qemu_opts_parse(&opts_list_03, "x=y,", false, &error_abort);
459*da668aa1SThomas Huth     g_assert_cmpuint(opts_count(opts), ==, 1);
460*da668aa1SThomas Huth     g_assert_cmpstr(qemu_opt_get(opts, "x"), ==, "y");
461*da668aa1SThomas Huth 
462*da668aa1SThomas Huth     /* Except when it isn't */
463*da668aa1SThomas Huth     opts = qemu_opts_parse(&opts_list_03, ",", false, &error_abort);
464*da668aa1SThomas Huth     g_assert_cmpuint(opts_count(opts), ==, 1);
465*da668aa1SThomas Huth     g_assert_cmpstr(qemu_opt_get(opts, ""), ==, "on");
466*da668aa1SThomas Huth 
467*da668aa1SThomas Huth     /* Duplicate ID */
468*da668aa1SThomas Huth     opts = qemu_opts_parse(&opts_list_03, "x=y,id=foo", false, &err);
469*da668aa1SThomas Huth     error_free_or_abort(&err);
470*da668aa1SThomas Huth     g_assert(!opts);
471*da668aa1SThomas Huth     /* TODO Cover .merge_lists = true */
472*da668aa1SThomas Huth 
473*da668aa1SThomas Huth     /* Buggy ID recognition (fixed) */
474*da668aa1SThomas Huth     opts = qemu_opts_parse(&opts_list_03, "x=,,id=bar", false, &error_abort);
475*da668aa1SThomas Huth     g_assert_cmpuint(opts_count(opts), ==, 1);
476*da668aa1SThomas Huth     g_assert(!qemu_opts_id(opts));
477*da668aa1SThomas Huth     g_assert_cmpstr(qemu_opt_get(opts, "x"), ==, ",id=bar");
478*da668aa1SThomas Huth 
479*da668aa1SThomas Huth     /* Anti-social ID */
480*da668aa1SThomas Huth     opts = qemu_opts_parse(&opts_list_01, "id=666", false, &err);
481*da668aa1SThomas Huth     error_free_or_abort(&err);
482*da668aa1SThomas Huth     g_assert(!opts);
483*da668aa1SThomas Huth 
484*da668aa1SThomas Huth     /* Implied value (qemu_opts_parse warns but accepts it) */
485*da668aa1SThomas Huth     opts = qemu_opts_parse(&opts_list_03, "an,noaus,noaus=",
486*da668aa1SThomas Huth                            false, &error_abort);
487*da668aa1SThomas Huth     g_assert_cmpuint(opts_count(opts), ==, 3);
488*da668aa1SThomas Huth     g_assert_cmpstr(qemu_opt_get(opts, "an"), ==, "on");
489*da668aa1SThomas Huth     g_assert_cmpstr(qemu_opt_get(opts, "aus"), ==, "off");
490*da668aa1SThomas Huth     g_assert_cmpstr(qemu_opt_get(opts, "noaus"), ==, "");
491*da668aa1SThomas Huth 
492*da668aa1SThomas Huth     /* Implied value, negated empty key */
493*da668aa1SThomas Huth     opts = qemu_opts_parse(&opts_list_03, "no", false, &error_abort);
494*da668aa1SThomas Huth     g_assert_cmpuint(opts_count(opts), ==, 1);
495*da668aa1SThomas Huth     g_assert_cmpstr(qemu_opt_get(opts, ""), ==, "off");
496*da668aa1SThomas Huth 
497*da668aa1SThomas Huth     /* Implied key */
498*da668aa1SThomas Huth     opts = qemu_opts_parse(&opts_list_03, "an,noaus,noaus=", true,
499*da668aa1SThomas Huth                            &error_abort);
500*da668aa1SThomas Huth     g_assert_cmpuint(opts_count(opts), ==, 3);
501*da668aa1SThomas Huth     g_assert_cmpstr(qemu_opt_get(opts, "implied"), ==, "an");
502*da668aa1SThomas Huth     g_assert_cmpstr(qemu_opt_get(opts, "aus"), ==, "off");
503*da668aa1SThomas Huth     g_assert_cmpstr(qemu_opt_get(opts, "noaus"), ==, "");
504*da668aa1SThomas Huth 
505*da668aa1SThomas Huth     /* Implied key with empty value */
506*da668aa1SThomas Huth     opts = qemu_opts_parse(&opts_list_03, ",", true, &error_abort);
507*da668aa1SThomas Huth     g_assert_cmpuint(opts_count(opts), ==, 1);
508*da668aa1SThomas Huth     g_assert_cmpstr(qemu_opt_get(opts, "implied"), ==, "");
509*da668aa1SThomas Huth 
510*da668aa1SThomas Huth     /* Implied key with comma value */
511*da668aa1SThomas Huth     opts = qemu_opts_parse(&opts_list_03, ",,,a=1", true, &error_abort);
512*da668aa1SThomas Huth     g_assert_cmpuint(opts_count(opts), ==, 2);
513*da668aa1SThomas Huth     g_assert_cmpstr(qemu_opt_get(opts, "implied"), ==, ",");
514*da668aa1SThomas Huth     g_assert_cmpstr(qemu_opt_get(opts, "a"), ==, "1");
515*da668aa1SThomas Huth 
516*da668aa1SThomas Huth     /* Empty key is not an implied key */
517*da668aa1SThomas Huth     opts = qemu_opts_parse(&opts_list_03, "=val", true, &error_abort);
518*da668aa1SThomas Huth     g_assert_cmpuint(opts_count(opts), ==, 1);
519*da668aa1SThomas Huth     g_assert_cmpstr(qemu_opt_get(opts, ""), ==, "val");
520*da668aa1SThomas Huth 
521*da668aa1SThomas Huth     /* Unknown key */
522*da668aa1SThomas Huth     opts = qemu_opts_parse(&opts_list_01, "nonexistent=", false, &err);
523*da668aa1SThomas Huth     error_free_or_abort(&err);
524*da668aa1SThomas Huth     g_assert(!opts);
525*da668aa1SThomas Huth 
526*da668aa1SThomas Huth     qemu_opts_reset(&opts_list_01);
527*da668aa1SThomas Huth     qemu_opts_reset(&opts_list_03);
528*da668aa1SThomas Huth }
529*da668aa1SThomas Huth 
test_opts_parse_bool(void)530*da668aa1SThomas Huth static void test_opts_parse_bool(void)
531*da668aa1SThomas Huth {
532*da668aa1SThomas Huth     Error *err = NULL;
533*da668aa1SThomas Huth     QemuOpts *opts;
534*da668aa1SThomas Huth 
535*da668aa1SThomas Huth     opts = qemu_opts_parse(&opts_list_02, "bool1=on,bool2=off",
536*da668aa1SThomas Huth                            false, &error_abort);
537*da668aa1SThomas Huth     g_assert_cmpuint(opts_count(opts), ==, 2);
538*da668aa1SThomas Huth     g_assert(qemu_opt_get_bool(opts, "bool1", false));
539*da668aa1SThomas Huth     g_assert(!qemu_opt_get_bool(opts, "bool2", true));
540*da668aa1SThomas Huth 
541*da668aa1SThomas Huth     opts = qemu_opts_parse(&opts_list_02, "bool1=offer", false, &err);
542*da668aa1SThomas Huth     error_free_or_abort(&err);
543*da668aa1SThomas Huth     g_assert(!opts);
544*da668aa1SThomas Huth 
545*da668aa1SThomas Huth     qemu_opts_reset(&opts_list_02);
546*da668aa1SThomas Huth }
547*da668aa1SThomas Huth 
test_opts_parse_number(void)548*da668aa1SThomas Huth static void test_opts_parse_number(void)
549*da668aa1SThomas Huth {
550*da668aa1SThomas Huth     Error *err = NULL;
551*da668aa1SThomas Huth     QemuOpts *opts;
552*da668aa1SThomas Huth 
553*da668aa1SThomas Huth     /* Lower limit zero */
554*da668aa1SThomas Huth     opts = qemu_opts_parse(&opts_list_01, "number1=0", false, &error_abort);
555*da668aa1SThomas Huth     g_assert_cmpuint(opts_count(opts), ==, 1);
556*da668aa1SThomas Huth     g_assert_cmpuint(qemu_opt_get_number(opts, "number1", 1), ==, 0);
557*da668aa1SThomas Huth 
558*da668aa1SThomas Huth     /* Upper limit 2^64-1 */
559*da668aa1SThomas Huth     opts = qemu_opts_parse(&opts_list_01,
560*da668aa1SThomas Huth                            "number1=18446744073709551615,number2=-1",
561*da668aa1SThomas Huth                            false, &error_abort);
562*da668aa1SThomas Huth     g_assert_cmpuint(opts_count(opts), ==, 2);
563*da668aa1SThomas Huth     g_assert_cmphex(qemu_opt_get_number(opts, "number1", 1), ==, UINT64_MAX);
564*da668aa1SThomas Huth     g_assert_cmphex(qemu_opt_get_number(opts, "number2", 0), ==, UINT64_MAX);
565*da668aa1SThomas Huth 
566*da668aa1SThomas Huth     /* Above upper limit */
567*da668aa1SThomas Huth     opts = qemu_opts_parse(&opts_list_01, "number1=18446744073709551616",
568*da668aa1SThomas Huth                            false, &err);
569*da668aa1SThomas Huth     error_free_or_abort(&err);
570*da668aa1SThomas Huth     g_assert(!opts);
571*da668aa1SThomas Huth 
572*da668aa1SThomas Huth     /* Below lower limit */
573*da668aa1SThomas Huth     opts = qemu_opts_parse(&opts_list_01, "number1=-18446744073709551616",
574*da668aa1SThomas Huth                            false, &err);
575*da668aa1SThomas Huth     error_free_or_abort(&err);
576*da668aa1SThomas Huth     g_assert(!opts);
577*da668aa1SThomas Huth 
578*da668aa1SThomas Huth     /* Hex and octal */
579*da668aa1SThomas Huth     opts = qemu_opts_parse(&opts_list_01, "number1=0x2a,number2=052",
580*da668aa1SThomas Huth                            false, &error_abort);
581*da668aa1SThomas Huth     g_assert_cmpuint(opts_count(opts), ==, 2);
582*da668aa1SThomas Huth     g_assert_cmpuint(qemu_opt_get_number(opts, "number1", 1), ==, 42);
583*da668aa1SThomas Huth     g_assert_cmpuint(qemu_opt_get_number(opts, "number2", 0), ==, 42);
584*da668aa1SThomas Huth 
585*da668aa1SThomas Huth     /* Invalid */
586*da668aa1SThomas Huth     opts = qemu_opts_parse(&opts_list_01, "number1=", false, &err);
587*da668aa1SThomas Huth     error_free_or_abort(&err);
588*da668aa1SThomas Huth     g_assert(!opts);
589*da668aa1SThomas Huth     opts = qemu_opts_parse(&opts_list_01, "number1=eins", false, &err);
590*da668aa1SThomas Huth     error_free_or_abort(&err);
591*da668aa1SThomas Huth     g_assert(!opts);
592*da668aa1SThomas Huth 
593*da668aa1SThomas Huth     /* Leading whitespace */
594*da668aa1SThomas Huth     opts = qemu_opts_parse(&opts_list_01, "number1= \t42",
595*da668aa1SThomas Huth                            false, &error_abort);
596*da668aa1SThomas Huth     g_assert_cmpuint(opts_count(opts), ==, 1);
597*da668aa1SThomas Huth     g_assert_cmpuint(qemu_opt_get_number(opts, "number1", 1), ==, 42);
598*da668aa1SThomas Huth 
599*da668aa1SThomas Huth     /* Trailing crap */
600*da668aa1SThomas Huth     opts = qemu_opts_parse(&opts_list_01, "number1=3.14", false, &err);
601*da668aa1SThomas Huth     error_free_or_abort(&err);
602*da668aa1SThomas Huth     g_assert(!opts);
603*da668aa1SThomas Huth     opts = qemu_opts_parse(&opts_list_01, "number1=08", false, &err);
604*da668aa1SThomas Huth     error_free_or_abort(&err);
605*da668aa1SThomas Huth     g_assert(!opts);
606*da668aa1SThomas Huth     opts = qemu_opts_parse(&opts_list_01, "number1=0 ", false, &err);
607*da668aa1SThomas Huth     error_free_or_abort(&err);
608*da668aa1SThomas Huth     g_assert(!opts);
609*da668aa1SThomas Huth 
610*da668aa1SThomas Huth     qemu_opts_reset(&opts_list_01);
611*da668aa1SThomas Huth }
612*da668aa1SThomas Huth 
test_opts_parse_size(void)613*da668aa1SThomas Huth static void test_opts_parse_size(void)
614*da668aa1SThomas Huth {
615*da668aa1SThomas Huth     Error *err = NULL;
616*da668aa1SThomas Huth     QemuOpts *opts;
617*da668aa1SThomas Huth 
618*da668aa1SThomas Huth     /* Lower limit zero */
619*da668aa1SThomas Huth     opts = qemu_opts_parse(&opts_list_02, "size1=0", false, &error_abort);
620*da668aa1SThomas Huth     g_assert_cmpuint(opts_count(opts), ==, 1);
621*da668aa1SThomas Huth     g_assert_cmpuint(qemu_opt_get_size(opts, "size1", 1), ==, 0);
622*da668aa1SThomas Huth 
623757acb9aSPeter Maydell     /* Note: full 64 bits of precision */
624*da668aa1SThomas Huth 
625757acb9aSPeter Maydell     /* Around double limit of precision: 2^53-1, 2^53, 2^53+1 */
626*da668aa1SThomas Huth     opts = qemu_opts_parse(&opts_list_02,
627*da668aa1SThomas Huth                            "size1=9007199254740991,"
628*da668aa1SThomas Huth                            "size2=9007199254740992,"
629*da668aa1SThomas Huth                            "size3=9007199254740993",
630*da668aa1SThomas Huth                            false, &error_abort);
631*da668aa1SThomas Huth     g_assert_cmpuint(opts_count(opts), ==, 3);
632*da668aa1SThomas Huth     g_assert_cmphex(qemu_opt_get_size(opts, "size1", 1),
633*da668aa1SThomas Huth                      ==, 0x1fffffffffffff);
634*da668aa1SThomas Huth     g_assert_cmphex(qemu_opt_get_size(opts, "size2", 1),
635*da668aa1SThomas Huth                      ==, 0x20000000000000);
636*da668aa1SThomas Huth     g_assert_cmphex(qemu_opt_get_size(opts, "size3", 1),
637757acb9aSPeter Maydell                      ==, 0x20000000000001);
638*da668aa1SThomas Huth 
639757acb9aSPeter Maydell     /* Close to signed int limit: 2^63-1, 2^63, 2^63+1 */
640*da668aa1SThomas Huth     opts = qemu_opts_parse(&opts_list_02,
641757acb9aSPeter Maydell                            "size1=9223372036854775807," /* 7fffffffffffffff */
642757acb9aSPeter Maydell                            "size2=9223372036854775808," /* 8000000000000000 */
643757acb9aSPeter Maydell                            "size3=9223372036854775809", /* 8000000000000001 */
644*da668aa1SThomas Huth                            false, &error_abort);
645757acb9aSPeter Maydell     g_assert_cmpuint(opts_count(opts), ==, 3);
646*da668aa1SThomas Huth     g_assert_cmphex(qemu_opt_get_size(opts, "size1", 1),
647757acb9aSPeter Maydell                      ==, 0x7fffffffffffffff);
648*da668aa1SThomas Huth     g_assert_cmphex(qemu_opt_get_size(opts, "size2", 1),
649757acb9aSPeter Maydell                      ==, 0x8000000000000000);
650757acb9aSPeter Maydell     g_assert_cmphex(qemu_opt_get_size(opts, "size3", 1),
651757acb9aSPeter Maydell                      ==, 0x8000000000000001);
652*da668aa1SThomas Huth 
653*da668aa1SThomas Huth     /* Close to actual upper limit 0xfffffffffffff800 (53 msbs set) */
654*da668aa1SThomas Huth     opts = qemu_opts_parse(&opts_list_02,
655*da668aa1SThomas Huth                            "size1=18446744073709549568," /* fffffffffffff800 */
656*da668aa1SThomas Huth                            "size2=18446744073709550591", /* fffffffffffffbff */
657*da668aa1SThomas Huth                            false, &error_abort);
658*da668aa1SThomas Huth     g_assert_cmpuint(opts_count(opts), ==, 2);
659*da668aa1SThomas Huth     g_assert_cmphex(qemu_opt_get_size(opts, "size1", 1),
660*da668aa1SThomas Huth                      ==, 0xfffffffffffff800);
661*da668aa1SThomas Huth     g_assert_cmphex(qemu_opt_get_size(opts, "size2", 1),
662757acb9aSPeter Maydell                      ==, 0xfffffffffffffbff);
663757acb9aSPeter Maydell 
664757acb9aSPeter Maydell     /* Actual limit, 2^64-1 */
665757acb9aSPeter Maydell     opts = qemu_opts_parse(&opts_list_02,
666757acb9aSPeter Maydell                            "size1=18446744073709551615", /* ffffffffffffffff */
667757acb9aSPeter Maydell                            false, &error_abort);
668757acb9aSPeter Maydell     g_assert_cmpuint(opts_count(opts), ==, 1);
669757acb9aSPeter Maydell     g_assert_cmphex(qemu_opt_get_size(opts, "size1", 1),
670757acb9aSPeter Maydell                      ==, 0xffffffffffffffff);
671*da668aa1SThomas Huth 
672*da668aa1SThomas Huth     /* Beyond limits */
673*da668aa1SThomas Huth     opts = qemu_opts_parse(&opts_list_02, "size1=-1", false, &err);
674*da668aa1SThomas Huth     error_free_or_abort(&err);
675*da668aa1SThomas Huth     g_assert(!opts);
676*da668aa1SThomas Huth     opts = qemu_opts_parse(&opts_list_02,
677757acb9aSPeter Maydell                            "size1=18446744073709551616", /* 2^64 */
678*da668aa1SThomas Huth                            false, &err);
679*da668aa1SThomas Huth     error_free_or_abort(&err);
680*da668aa1SThomas Huth     g_assert(!opts);
681*da668aa1SThomas Huth 
682*da668aa1SThomas Huth     /* Suffixes */
683*da668aa1SThomas Huth     opts = qemu_opts_parse(&opts_list_02, "size1=8b,size2=1.5k,size3=2M",
684*da668aa1SThomas Huth                            false, &error_abort);
685*da668aa1SThomas Huth     g_assert_cmpuint(opts_count(opts), ==, 3);
686*da668aa1SThomas Huth     g_assert_cmphex(qemu_opt_get_size(opts, "size1", 0), ==, 8);
687*da668aa1SThomas Huth     g_assert_cmphex(qemu_opt_get_size(opts, "size2", 0), ==, 1536);
688*da668aa1SThomas Huth     g_assert_cmphex(qemu_opt_get_size(opts, "size3", 0), ==, 2 * MiB);
689*da668aa1SThomas Huth     opts = qemu_opts_parse(&opts_list_02, "size1=0.1G,size2=16777215T",
690*da668aa1SThomas Huth                            false, &error_abort);
691*da668aa1SThomas Huth     g_assert_cmpuint(opts_count(opts), ==, 2);
692*da668aa1SThomas Huth     g_assert_cmphex(qemu_opt_get_size(opts, "size1", 0), ==, GiB / 10);
693*da668aa1SThomas Huth     g_assert_cmphex(qemu_opt_get_size(opts, "size2", 0), ==, 16777215ULL * TiB);
694*da668aa1SThomas Huth 
695*da668aa1SThomas Huth     /* Beyond limit with suffix */
696*da668aa1SThomas Huth     opts = qemu_opts_parse(&opts_list_02, "size1=16777216T",
697*da668aa1SThomas Huth                            false, &err);
698*da668aa1SThomas Huth     error_free_or_abort(&err);
699*da668aa1SThomas Huth     g_assert(!opts);
700*da668aa1SThomas Huth 
701*da668aa1SThomas Huth     /* Trailing crap */
702*da668aa1SThomas Huth     opts = qemu_opts_parse(&opts_list_02, "size1=16E", false, &err);
703*da668aa1SThomas Huth     error_free_or_abort(&err);
704*da668aa1SThomas Huth     g_assert(!opts);
705*da668aa1SThomas Huth     opts = qemu_opts_parse(&opts_list_02, "size1=16Gi", false, &err);
706*da668aa1SThomas Huth     error_free_or_abort(&err);
707*da668aa1SThomas Huth     g_assert(!opts);
708*da668aa1SThomas Huth 
709*da668aa1SThomas Huth     qemu_opts_reset(&opts_list_02);
710*da668aa1SThomas Huth }
711*da668aa1SThomas Huth 
test_has_help_option(void)712*da668aa1SThomas Huth static void test_has_help_option(void)
713*da668aa1SThomas Huth {
714*da668aa1SThomas Huth     static const struct {
715*da668aa1SThomas Huth         const char *params;
716*da668aa1SThomas Huth         /* expected value of qemu_opt_has_help_opt() with implied=false */
717*da668aa1SThomas Huth         bool expect;
718*da668aa1SThomas Huth         /* expected value of qemu_opt_has_help_opt() with implied=true */
719*da668aa1SThomas Huth         bool expect_implied;
720*da668aa1SThomas Huth     } test[] = {
721*da668aa1SThomas Huth         { "help", true, false },
722*da668aa1SThomas Huth         { "?", true, false },
723*da668aa1SThomas Huth         { "helpme", false, false },
724*da668aa1SThomas Huth         { "?me", false, false },
725*da668aa1SThomas Huth         { "a,help", true, true },
726*da668aa1SThomas Huth         { "a,?", true, true },
727*da668aa1SThomas Huth         { "a=0,help,b", true, true },
728*da668aa1SThomas Huth         { "a=0,?,b", true, true },
729*da668aa1SThomas Huth         { "help,b=1", true, false },
730*da668aa1SThomas Huth         { "?,b=1", true, false },
731*da668aa1SThomas Huth         { "a,b,,help", true, true },
732*da668aa1SThomas Huth         { "a,b,,?", true, true },
733*da668aa1SThomas Huth     };
734*da668aa1SThomas Huth     int i;
735*da668aa1SThomas Huth     QemuOpts *opts;
736*da668aa1SThomas Huth 
737*da668aa1SThomas Huth     for (i = 0; i < ARRAY_SIZE(test); i++) {
738*da668aa1SThomas Huth         g_assert_cmpint(has_help_option(test[i].params),
739*da668aa1SThomas Huth                         ==, test[i].expect);
740*da668aa1SThomas Huth         opts = qemu_opts_parse(&opts_list_03, test[i].params, false,
741*da668aa1SThomas Huth                                &error_abort);
742*da668aa1SThomas Huth         g_assert_cmpint(qemu_opt_has_help_opt(opts),
743*da668aa1SThomas Huth                         ==, test[i].expect);
744*da668aa1SThomas Huth         qemu_opts_del(opts);
745*da668aa1SThomas Huth         opts = qemu_opts_parse(&opts_list_03, test[i].params, true,
746*da668aa1SThomas Huth                                &error_abort);
747*da668aa1SThomas Huth         g_assert_cmpint(qemu_opt_has_help_opt(opts),
748*da668aa1SThomas Huth                         ==, test[i].expect_implied);
749*da668aa1SThomas Huth         qemu_opts_del(opts);
750*da668aa1SThomas Huth     }
751*da668aa1SThomas Huth }
752*da668aa1SThomas Huth 
append_verify_list_01(QemuOptDesc * desc,bool with_overlapping)753*da668aa1SThomas Huth static void append_verify_list_01(QemuOptDesc *desc, bool with_overlapping)
754*da668aa1SThomas Huth {
755*da668aa1SThomas Huth     int i = 0;
756*da668aa1SThomas Huth 
757*da668aa1SThomas Huth     if (with_overlapping) {
758*da668aa1SThomas Huth         g_assert_cmpstr(desc[i].name, ==, "str1");
759*da668aa1SThomas Huth         g_assert_cmpint(desc[i].type, ==, QEMU_OPT_STRING);
760*da668aa1SThomas Huth         g_assert_cmpstr(desc[i].help, ==,
761*da668aa1SThomas Huth                         "Help texts are preserved in qemu_opts_append");
762*da668aa1SThomas Huth         g_assert_cmpstr(desc[i].def_value_str, ==, "default");
763*da668aa1SThomas Huth         i++;
764*da668aa1SThomas Huth 
765*da668aa1SThomas Huth         g_assert_cmpstr(desc[i].name, ==, "str2");
766*da668aa1SThomas Huth         g_assert_cmpint(desc[i].type, ==, QEMU_OPT_STRING);
767*da668aa1SThomas Huth         g_assert_cmpstr(desc[i].help, ==, NULL);
768*da668aa1SThomas Huth         g_assert_cmpstr(desc[i].def_value_str, ==, NULL);
769*da668aa1SThomas Huth         i++;
770*da668aa1SThomas Huth     }
771*da668aa1SThomas Huth 
772*da668aa1SThomas Huth     g_assert_cmpstr(desc[i].name, ==, "str3");
773*da668aa1SThomas Huth     g_assert_cmpint(desc[i].type, ==, QEMU_OPT_STRING);
774*da668aa1SThomas Huth     g_assert_cmpstr(desc[i].help, ==, NULL);
775*da668aa1SThomas Huth     g_assert_cmpstr(desc[i].def_value_str, ==, NULL);
776*da668aa1SThomas Huth     i++;
777*da668aa1SThomas Huth 
778*da668aa1SThomas Huth     g_assert_cmpstr(desc[i].name, ==, "number1");
779*da668aa1SThomas Huth     g_assert_cmpint(desc[i].type, ==, QEMU_OPT_NUMBER);
780*da668aa1SThomas Huth     g_assert_cmpstr(desc[i].help, ==,
781*da668aa1SThomas Huth                     "Having help texts only for some options is okay");
782*da668aa1SThomas Huth     g_assert_cmpstr(desc[i].def_value_str, ==, NULL);
783*da668aa1SThomas Huth     i++;
784*da668aa1SThomas Huth 
785*da668aa1SThomas Huth     g_assert_cmpstr(desc[i].name, ==, "number2");
786*da668aa1SThomas Huth     g_assert_cmpint(desc[i].type, ==, QEMU_OPT_NUMBER);
787*da668aa1SThomas Huth     g_assert_cmpstr(desc[i].help, ==, NULL);
788*da668aa1SThomas Huth     g_assert_cmpstr(desc[i].def_value_str, ==, NULL);
789*da668aa1SThomas Huth     i++;
790*da668aa1SThomas Huth 
791*da668aa1SThomas Huth     g_assert_cmpstr(desc[i].name, ==, NULL);
792*da668aa1SThomas Huth }
793*da668aa1SThomas Huth 
append_verify_list_02(QemuOptDesc * desc)794*da668aa1SThomas Huth static void append_verify_list_02(QemuOptDesc *desc)
795*da668aa1SThomas Huth {
796*da668aa1SThomas Huth     int i = 0;
797*da668aa1SThomas Huth 
798*da668aa1SThomas Huth     g_assert_cmpstr(desc[i].name, ==, "str1");
799*da668aa1SThomas Huth     g_assert_cmpint(desc[i].type, ==, QEMU_OPT_STRING);
800*da668aa1SThomas Huth     g_assert_cmpstr(desc[i].help, ==, NULL);
801*da668aa1SThomas Huth     g_assert_cmpstr(desc[i].def_value_str, ==, NULL);
802*da668aa1SThomas Huth     i++;
803*da668aa1SThomas Huth 
804*da668aa1SThomas Huth     g_assert_cmpstr(desc[i].name, ==, "str2");
805*da668aa1SThomas Huth     g_assert_cmpint(desc[i].type, ==, QEMU_OPT_STRING);
806*da668aa1SThomas Huth     g_assert_cmpstr(desc[i].help, ==, NULL);
807*da668aa1SThomas Huth     g_assert_cmpstr(desc[i].def_value_str, ==, NULL);
808*da668aa1SThomas Huth     i++;
809*da668aa1SThomas Huth 
810*da668aa1SThomas Huth     g_assert_cmpstr(desc[i].name, ==, "bool1");
811*da668aa1SThomas Huth     g_assert_cmpint(desc[i].type, ==, QEMU_OPT_BOOL);
812*da668aa1SThomas Huth     g_assert_cmpstr(desc[i].help, ==, NULL);
813*da668aa1SThomas Huth     g_assert_cmpstr(desc[i].def_value_str, ==, NULL);
814*da668aa1SThomas Huth     i++;
815*da668aa1SThomas Huth 
816*da668aa1SThomas Huth     g_assert_cmpstr(desc[i].name, ==, "bool2");
817*da668aa1SThomas Huth     g_assert_cmpint(desc[i].type, ==, QEMU_OPT_BOOL);
818*da668aa1SThomas Huth     g_assert_cmpstr(desc[i].help, ==, NULL);
819*da668aa1SThomas Huth     g_assert_cmpstr(desc[i].def_value_str, ==, NULL);
820*da668aa1SThomas Huth     i++;
821*da668aa1SThomas Huth 
822*da668aa1SThomas Huth     g_assert_cmpstr(desc[i].name, ==, "size1");
823*da668aa1SThomas Huth     g_assert_cmpint(desc[i].type, ==, QEMU_OPT_SIZE);
824*da668aa1SThomas Huth     g_assert_cmpstr(desc[i].help, ==, NULL);
825*da668aa1SThomas Huth     g_assert_cmpstr(desc[i].def_value_str, ==, NULL);
826*da668aa1SThomas Huth     i++;
827*da668aa1SThomas Huth 
828*da668aa1SThomas Huth     g_assert_cmpstr(desc[i].name, ==, "size2");
829*da668aa1SThomas Huth     g_assert_cmpint(desc[i].type, ==, QEMU_OPT_SIZE);
830*da668aa1SThomas Huth     g_assert_cmpstr(desc[i].help, ==, NULL);
831*da668aa1SThomas Huth     g_assert_cmpstr(desc[i].def_value_str, ==, NULL);
832*da668aa1SThomas Huth     i++;
833*da668aa1SThomas Huth 
834*da668aa1SThomas Huth     g_assert_cmpstr(desc[i].name, ==, "size3");
835*da668aa1SThomas Huth     g_assert_cmpint(desc[i].type, ==, QEMU_OPT_SIZE);
836*da668aa1SThomas Huth     g_assert_cmpstr(desc[i].help, ==, NULL);
837*da668aa1SThomas Huth     g_assert_cmpstr(desc[i].def_value_str, ==, NULL);
838*da668aa1SThomas Huth }
839*da668aa1SThomas Huth 
test_opts_append_to_null(void)840*da668aa1SThomas Huth static void test_opts_append_to_null(void)
841*da668aa1SThomas Huth {
842*da668aa1SThomas Huth     QemuOptsList *merged;
843*da668aa1SThomas Huth 
844*da668aa1SThomas Huth     merged = qemu_opts_append(NULL, &opts_list_01);
845*da668aa1SThomas Huth     g_assert(merged != &opts_list_01);
846*da668aa1SThomas Huth 
847*da668aa1SThomas Huth     g_assert_cmpstr(merged->name, ==, NULL);
848*da668aa1SThomas Huth     g_assert_cmpstr(merged->implied_opt_name, ==, NULL);
849*da668aa1SThomas Huth     g_assert_false(merged->merge_lists);
850*da668aa1SThomas Huth 
851*da668aa1SThomas Huth     append_verify_list_01(merged->desc, true);
852*da668aa1SThomas Huth 
853*da668aa1SThomas Huth     qemu_opts_free(merged);
854*da668aa1SThomas Huth }
855*da668aa1SThomas Huth 
test_opts_append(void)856*da668aa1SThomas Huth static void test_opts_append(void)
857*da668aa1SThomas Huth {
858*da668aa1SThomas Huth     QemuOptsList *first, *merged;
859*da668aa1SThomas Huth 
860*da668aa1SThomas Huth     first = qemu_opts_append(NULL, &opts_list_02);
861*da668aa1SThomas Huth     merged = qemu_opts_append(first, &opts_list_01);
862*da668aa1SThomas Huth     g_assert(first != &opts_list_02);
863*da668aa1SThomas Huth     g_assert(merged != &opts_list_01);
864*da668aa1SThomas Huth 
865*da668aa1SThomas Huth     g_assert_cmpstr(merged->name, ==, NULL);
866*da668aa1SThomas Huth     g_assert_cmpstr(merged->implied_opt_name, ==, NULL);
867*da668aa1SThomas Huth     g_assert_false(merged->merge_lists);
868*da668aa1SThomas Huth 
869*da668aa1SThomas Huth     append_verify_list_02(&merged->desc[0]);
870*da668aa1SThomas Huth     append_verify_list_01(&merged->desc[7], false);
871*da668aa1SThomas Huth 
872*da668aa1SThomas Huth     qemu_opts_free(merged);
873*da668aa1SThomas Huth }
874*da668aa1SThomas Huth 
test_opts_to_qdict_basic(void)875*da668aa1SThomas Huth static void test_opts_to_qdict_basic(void)
876*da668aa1SThomas Huth {
877*da668aa1SThomas Huth     QemuOpts *opts;
878*da668aa1SThomas Huth     QDict *dict;
879*da668aa1SThomas Huth 
880*da668aa1SThomas Huth     opts = qemu_opts_parse(&opts_list_01, "str1=foo,str2=,str3=bar,number1=42",
881*da668aa1SThomas Huth                            false, &error_abort);
882*da668aa1SThomas Huth     g_assert(opts != NULL);
883*da668aa1SThomas Huth 
884*da668aa1SThomas Huth     dict = qemu_opts_to_qdict(opts, NULL);
885*da668aa1SThomas Huth     g_assert(dict != NULL);
886*da668aa1SThomas Huth 
887*da668aa1SThomas Huth     g_assert_cmpstr(qdict_get_str(dict, "str1"), ==, "foo");
888*da668aa1SThomas Huth     g_assert_cmpstr(qdict_get_str(dict, "str2"), ==, "");
889*da668aa1SThomas Huth     g_assert_cmpstr(qdict_get_str(dict, "str3"), ==, "bar");
890*da668aa1SThomas Huth     g_assert_cmpstr(qdict_get_str(dict, "number1"), ==, "42");
891*da668aa1SThomas Huth     g_assert_false(qdict_haskey(dict, "number2"));
892*da668aa1SThomas Huth 
893*da668aa1SThomas Huth     qobject_unref(dict);
894*da668aa1SThomas Huth     qemu_opts_del(opts);
895*da668aa1SThomas Huth }
896*da668aa1SThomas Huth 
test_opts_to_qdict_filtered(void)897*da668aa1SThomas Huth static void test_opts_to_qdict_filtered(void)
898*da668aa1SThomas Huth {
899*da668aa1SThomas Huth     QemuOptsList *first, *merged;
900*da668aa1SThomas Huth     QemuOpts *opts;
901*da668aa1SThomas Huth     QDict *dict;
902*da668aa1SThomas Huth 
903*da668aa1SThomas Huth     first = qemu_opts_append(NULL, &opts_list_02);
904*da668aa1SThomas Huth     merged = qemu_opts_append(first, &opts_list_01);
905*da668aa1SThomas Huth 
906*da668aa1SThomas Huth     opts = qemu_opts_parse(merged,
907*da668aa1SThomas Huth                            "str1=foo,str2=,str3=bar,bool1=off,number1=42",
908*da668aa1SThomas Huth                            false, &error_abort);
909*da668aa1SThomas Huth     g_assert(opts != NULL);
910*da668aa1SThomas Huth 
911*da668aa1SThomas Huth     /* Convert to QDict without deleting from opts */
912*da668aa1SThomas Huth     dict = qemu_opts_to_qdict_filtered(opts, NULL, &opts_list_01, false);
913*da668aa1SThomas Huth     g_assert(dict != NULL);
914*da668aa1SThomas Huth     g_assert_cmpstr(qdict_get_str(dict, "str1"), ==, "foo");
915*da668aa1SThomas Huth     g_assert_cmpstr(qdict_get_str(dict, "str2"), ==, "");
916*da668aa1SThomas Huth     g_assert_cmpstr(qdict_get_str(dict, "str3"), ==, "bar");
917*da668aa1SThomas Huth     g_assert_cmpstr(qdict_get_str(dict, "number1"), ==, "42");
918*da668aa1SThomas Huth     g_assert_false(qdict_haskey(dict, "number2"));
919*da668aa1SThomas Huth     g_assert_false(qdict_haskey(dict, "bool1"));
920*da668aa1SThomas Huth     qobject_unref(dict);
921*da668aa1SThomas Huth 
922*da668aa1SThomas Huth     dict = qemu_opts_to_qdict_filtered(opts, NULL, &opts_list_02, false);
923*da668aa1SThomas Huth     g_assert(dict != NULL);
924*da668aa1SThomas Huth     g_assert_cmpstr(qdict_get_str(dict, "str1"), ==, "foo");
925*da668aa1SThomas Huth     g_assert_cmpstr(qdict_get_str(dict, "str2"), ==, "");
926*da668aa1SThomas Huth     g_assert_cmpstr(qdict_get_str(dict, "bool1"), ==, "off");
927*da668aa1SThomas Huth     g_assert_false(qdict_haskey(dict, "str3"));
928*da668aa1SThomas Huth     g_assert_false(qdict_haskey(dict, "number1"));
929*da668aa1SThomas Huth     g_assert_false(qdict_haskey(dict, "number2"));
930*da668aa1SThomas Huth     qobject_unref(dict);
931*da668aa1SThomas Huth 
932*da668aa1SThomas Huth     /* Now delete converted options from opts */
933*da668aa1SThomas Huth     dict = qemu_opts_to_qdict_filtered(opts, NULL, &opts_list_01, true);
934*da668aa1SThomas Huth     g_assert(dict != NULL);
935*da668aa1SThomas Huth     g_assert_cmpstr(qdict_get_str(dict, "str1"), ==, "foo");
936*da668aa1SThomas Huth     g_assert_cmpstr(qdict_get_str(dict, "str2"), ==, "");
937*da668aa1SThomas Huth     g_assert_cmpstr(qdict_get_str(dict, "str3"), ==, "bar");
938*da668aa1SThomas Huth     g_assert_cmpstr(qdict_get_str(dict, "number1"), ==, "42");
939*da668aa1SThomas Huth     g_assert_false(qdict_haskey(dict, "number2"));
940*da668aa1SThomas Huth     g_assert_false(qdict_haskey(dict, "bool1"));
941*da668aa1SThomas Huth     qobject_unref(dict);
942*da668aa1SThomas Huth 
943*da668aa1SThomas Huth     dict = qemu_opts_to_qdict_filtered(opts, NULL, &opts_list_02, true);
944*da668aa1SThomas Huth     g_assert(dict != NULL);
945*da668aa1SThomas Huth     g_assert_cmpstr(qdict_get_str(dict, "bool1"), ==, "off");
946*da668aa1SThomas Huth     g_assert_false(qdict_haskey(dict, "str1"));
947*da668aa1SThomas Huth     g_assert_false(qdict_haskey(dict, "str2"));
948*da668aa1SThomas Huth     g_assert_false(qdict_haskey(dict, "str3"));
949*da668aa1SThomas Huth     g_assert_false(qdict_haskey(dict, "number1"));
950*da668aa1SThomas Huth     g_assert_false(qdict_haskey(dict, "number2"));
951*da668aa1SThomas Huth     qobject_unref(dict);
952*da668aa1SThomas Huth 
953*da668aa1SThomas Huth     g_assert_true(QTAILQ_EMPTY(&opts->head));
954*da668aa1SThomas Huth 
955*da668aa1SThomas Huth     qemu_opts_del(opts);
956*da668aa1SThomas Huth     qemu_opts_free(merged);
957*da668aa1SThomas Huth }
958*da668aa1SThomas Huth 
test_opts_to_qdict_duplicates(void)959*da668aa1SThomas Huth static void test_opts_to_qdict_duplicates(void)
960*da668aa1SThomas Huth {
961*da668aa1SThomas Huth     QemuOpts *opts;
962*da668aa1SThomas Huth     QemuOpt *opt;
963*da668aa1SThomas Huth     QDict *dict;
964*da668aa1SThomas Huth 
965*da668aa1SThomas Huth     opts = qemu_opts_parse(&opts_list_03, "foo=a,foo=b", false, &error_abort);
966*da668aa1SThomas Huth     g_assert(opts != NULL);
967*da668aa1SThomas Huth 
968*da668aa1SThomas Huth     /* Verify that opts has two options with the same name */
969*da668aa1SThomas Huth     opt = QTAILQ_FIRST(&opts->head);
970*da668aa1SThomas Huth     g_assert_cmpstr(opt->name, ==, "foo");
971*da668aa1SThomas Huth     g_assert_cmpstr(opt->str , ==, "a");
972*da668aa1SThomas Huth 
973*da668aa1SThomas Huth     opt = QTAILQ_NEXT(opt, next);
974*da668aa1SThomas Huth     g_assert_cmpstr(opt->name, ==, "foo");
975*da668aa1SThomas Huth     g_assert_cmpstr(opt->str , ==, "b");
976*da668aa1SThomas Huth 
977*da668aa1SThomas Huth     opt = QTAILQ_NEXT(opt, next);
978*da668aa1SThomas Huth     g_assert(opt == NULL);
979*da668aa1SThomas Huth 
980*da668aa1SThomas Huth     /* In the conversion to QDict, the last one wins */
981*da668aa1SThomas Huth     dict = qemu_opts_to_qdict(opts, NULL);
982*da668aa1SThomas Huth     g_assert(dict != NULL);
983*da668aa1SThomas Huth     g_assert_cmpstr(qdict_get_str(dict, "foo"), ==, "b");
984*da668aa1SThomas Huth     qobject_unref(dict);
985*da668aa1SThomas Huth 
986*da668aa1SThomas Huth     /* The last one still wins if entries are deleted, and both are deleted */
987*da668aa1SThomas Huth     dict = qemu_opts_to_qdict_filtered(opts, NULL, NULL, true);
988*da668aa1SThomas Huth     g_assert(dict != NULL);
989*da668aa1SThomas Huth     g_assert_cmpstr(qdict_get_str(dict, "foo"), ==, "b");
990*da668aa1SThomas Huth     qobject_unref(dict);
991*da668aa1SThomas Huth 
992*da668aa1SThomas Huth     g_assert_true(QTAILQ_EMPTY(&opts->head));
993*da668aa1SThomas Huth 
994*da668aa1SThomas Huth     qemu_opts_del(opts);
995*da668aa1SThomas Huth }
996*da668aa1SThomas Huth 
main(int argc,char * argv[])997*da668aa1SThomas Huth int main(int argc, char *argv[])
998*da668aa1SThomas Huth {
999*da668aa1SThomas Huth     register_opts();
1000*da668aa1SThomas Huth     g_test_init(&argc, &argv, NULL);
1001*da668aa1SThomas Huth     g_test_add_func("/qemu-opts/find_unknown_opts", test_find_unknown_opts);
1002*da668aa1SThomas Huth     g_test_add_func("/qemu-opts/find_opts", test_qemu_find_opts);
1003*da668aa1SThomas Huth     g_test_add_func("/qemu-opts/opts_create", test_qemu_opts_create);
1004*da668aa1SThomas Huth     g_test_add_func("/qemu-opts/opt_get", test_qemu_opt_get);
1005*da668aa1SThomas Huth     g_test_add_func("/qemu-opts/opt_get_bool", test_qemu_opt_get_bool);
1006*da668aa1SThomas Huth     g_test_add_func("/qemu-opts/opt_get_number", test_qemu_opt_get_number);
1007*da668aa1SThomas Huth     g_test_add_func("/qemu-opts/opt_get_size", test_qemu_opt_get_size);
1008*da668aa1SThomas Huth     g_test_add_func("/qemu-opts/opt_unset", test_qemu_opt_unset);
1009*da668aa1SThomas Huth     g_test_add_func("/qemu-opts/opts_reset", test_qemu_opts_reset);
1010*da668aa1SThomas Huth     g_test_add_func("/qemu-opts/opts_parse/general", test_opts_parse);
1011*da668aa1SThomas Huth     g_test_add_func("/qemu-opts/opts_parse/bool", test_opts_parse_bool);
1012*da668aa1SThomas Huth     g_test_add_func("/qemu-opts/opts_parse/number", test_opts_parse_number);
1013*da668aa1SThomas Huth     g_test_add_func("/qemu-opts/opts_parse/size", test_opts_parse_size);
1014*da668aa1SThomas Huth     g_test_add_func("/qemu-opts/has_help_option", test_has_help_option);
1015*da668aa1SThomas Huth     g_test_add_func("/qemu-opts/append_to_null", test_opts_append_to_null);
1016*da668aa1SThomas Huth     g_test_add_func("/qemu-opts/append", test_opts_append);
1017*da668aa1SThomas Huth     g_test_add_func("/qemu-opts/to_qdict/basic", test_opts_to_qdict_basic);
1018*da668aa1SThomas Huth     g_test_add_func("/qemu-opts/to_qdict/filtered", test_opts_to_qdict_filtered);
1019*da668aa1SThomas Huth     g_test_add_func("/qemu-opts/to_qdict/duplicates", test_opts_to_qdict_duplicates);
1020*da668aa1SThomas Huth     g_test_run();
1021*da668aa1SThomas Huth     return 0;
1022*da668aa1SThomas Huth }
1023