xref: /qemu/tests/unit/test-qemu-opts.c (revision 681c28a33e305923a717815808056d2d5a89c8f9)
1 /*
2  * QemuOpts unit-tests.
3  *
4  * Copyright (C) 2014 Leandro Dorileo <l@dorileo.org>
5  *
6  * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
7  * See the COPYING.LIB file in the top-level directory.
8  */
9 
10 #include "qemu/osdep.h"
11 #include "qapi/qmp/qstring.h"
12 #include "qemu/config-file.h"
13 
14 #include <glib.h>
15 
16 static QemuOptsList opts_list_01 = {
17     .name = "opts_list_01",
18     .head = QTAILQ_HEAD_INITIALIZER(opts_list_01.head),
19     .desc = {
20         {
21             .name = "str1",
22             .type = QEMU_OPT_STRING,
23         },{
24             .name = "str2",
25             .type = QEMU_OPT_STRING,
26         },{
27             .name = "str3",
28             .type = QEMU_OPT_STRING,
29         },{
30             .name = "number1",
31             .type = QEMU_OPT_NUMBER,
32         },
33         { /* end of list */ }
34     },
35 };
36 
37 static QemuOptsList opts_list_02 = {
38     .name = "opts_list_02",
39     .head = QTAILQ_HEAD_INITIALIZER(opts_list_02.head),
40     .desc = {
41         {
42             .name = "str1",
43             .type = QEMU_OPT_STRING,
44         },{
45             .name = "bool1",
46             .type = QEMU_OPT_BOOL,
47         },{
48             .name = "str2",
49             .type = QEMU_OPT_STRING,
50         },{
51             .name = "size1",
52             .type = QEMU_OPT_SIZE,
53         },
54         { /* end of list */ }
55     },
56 };
57 
58 static QemuOptsList opts_list_03 = {
59     .name = "opts_list_03",
60     .head = QTAILQ_HEAD_INITIALIZER(opts_list_03.head),
61     .desc = {
62         /* no elements => accept any params */
63         { /* end of list */ }
64     },
65 };
66 
67 static void register_opts(void)
68 {
69     qemu_add_opts(&opts_list_01);
70     qemu_add_opts(&opts_list_02);
71     qemu_add_opts(&opts_list_03);
72 }
73 
74 static void test_find_unknown_opts(void)
75 {
76     QemuOptsList *list;
77     Error *err = NULL;
78 
79     /* should not return anything, we don't have an "unknown" option */
80     list = qemu_find_opts_err("unknown", &err);
81     g_assert(list == NULL);
82     g_assert(err);
83     error_free(err);
84 }
85 
86 static void test_qemu_find_opts(void)
87 {
88     QemuOptsList *list;
89 
90     /* we have an "opts_list_01" option, should return it */
91     list = qemu_find_opts("opts_list_01");
92     g_assert(list != NULL);
93     g_assert_cmpstr(list->name, ==, "opts_list_01");
94 }
95 
96 static void test_qemu_opts_create(void)
97 {
98     QemuOptsList *list;
99     QemuOpts *opts;
100 
101     list = qemu_find_opts("opts_list_01");
102     g_assert(list != NULL);
103     g_assert(QTAILQ_EMPTY(&list->head));
104     g_assert_cmpstr(list->name, ==, "opts_list_01");
105 
106     /* should not find anything at this point */
107     opts = qemu_opts_find(list, NULL);
108     g_assert(opts == NULL);
109 
110     /* create the opts */
111     opts = qemu_opts_create(list, NULL, 0, &error_abort);
112     g_assert(opts != NULL);
113     g_assert(!QTAILQ_EMPTY(&list->head));
114 
115     /* now we've create the opts, must find it */
116     opts = qemu_opts_find(list, NULL);
117     g_assert(opts != NULL);
118 
119     qemu_opts_del(opts);
120 
121     /* should not find anything at this point */
122     opts = qemu_opts_find(list, NULL);
123     g_assert(opts == NULL);
124 }
125 
126 static void test_qemu_opt_get(void)
127 {
128     QemuOptsList *list;
129     QemuOpts *opts;
130     const char *opt = NULL;
131 
132     list = qemu_find_opts("opts_list_01");
133     g_assert(list != NULL);
134     g_assert(QTAILQ_EMPTY(&list->head));
135     g_assert_cmpstr(list->name, ==, "opts_list_01");
136 
137     /* should not find anything at this point */
138     opts = qemu_opts_find(list, NULL);
139     g_assert(opts == NULL);
140 
141     /* create the opts */
142     opts = qemu_opts_create(list, NULL, 0, &error_abort);
143     g_assert(opts != NULL);
144     g_assert(!QTAILQ_EMPTY(&list->head));
145 
146     /* haven't set anything to str2 yet */
147     opt = qemu_opt_get(opts, "str2");
148     g_assert(opt == NULL);
149 
150     qemu_opt_set(opts, "str2", "value", &error_abort);
151 
152     /* now we have set str2, should know about it */
153     opt = qemu_opt_get(opts, "str2");
154     g_assert_cmpstr(opt, ==, "value");
155 
156     qemu_opt_set(opts, "str2", "value2", &error_abort);
157 
158     /* having reset the value, the returned should be the reset one */
159     opt = qemu_opt_get(opts, "str2");
160     g_assert_cmpstr(opt, ==, "value2");
161 
162     qemu_opts_del(opts);
163 
164     /* should not find anything at this point */
165     opts = qemu_opts_find(list, NULL);
166     g_assert(opts == NULL);
167 }
168 
169 static void test_qemu_opt_get_bool(void)
170 {
171     Error *err = NULL;
172     QemuOptsList *list;
173     QemuOpts *opts;
174     bool opt;
175 
176     list = qemu_find_opts("opts_list_02");
177     g_assert(list != NULL);
178     g_assert(QTAILQ_EMPTY(&list->head));
179     g_assert_cmpstr(list->name, ==, "opts_list_02");
180 
181     /* should not find anything at this point */
182     opts = qemu_opts_find(list, NULL);
183     g_assert(opts == NULL);
184 
185     /* create the opts */
186     opts = qemu_opts_create(list, NULL, 0, &error_abort);
187     g_assert(opts != NULL);
188     g_assert(!QTAILQ_EMPTY(&list->head));
189 
190     /* haven't set anything to bool1 yet, so defval should be returned */
191     opt = qemu_opt_get_bool(opts, "bool1", false);
192     g_assert(opt == false);
193 
194     qemu_opt_set_bool(opts, "bool1", true, &err);
195     g_assert(!err);
196 
197     /* now we have set bool1, should know about it */
198     opt = qemu_opt_get_bool(opts, "bool1", false);
199     g_assert(opt == true);
200 
201     /* having reset the value, opt should be the reset one not defval */
202     qemu_opt_set_bool(opts, "bool1", false, &err);
203     g_assert(!err);
204 
205     opt = qemu_opt_get_bool(opts, "bool1", true);
206     g_assert(opt == false);
207 
208     qemu_opts_del(opts);
209 
210     /* should not find anything at this point */
211     opts = qemu_opts_find(list, NULL);
212     g_assert(opts == NULL);
213 }
214 
215 static void test_qemu_opt_get_number(void)
216 {
217     Error *err = NULL;
218     QemuOptsList *list;
219     QemuOpts *opts;
220     uint64_t opt;
221 
222     list = qemu_find_opts("opts_list_01");
223     g_assert(list != NULL);
224     g_assert(QTAILQ_EMPTY(&list->head));
225     g_assert_cmpstr(list->name, ==, "opts_list_01");
226 
227     /* should not find anything at this point */
228     opts = qemu_opts_find(list, NULL);
229     g_assert(opts == NULL);
230 
231     /* create the opts */
232     opts = qemu_opts_create(list, NULL, 0, &error_abort);
233     g_assert(opts != NULL);
234     g_assert(!QTAILQ_EMPTY(&list->head));
235 
236     /* haven't set anything to number1 yet, so defval should be returned */
237     opt = qemu_opt_get_number(opts, "number1", 5);
238     g_assert(opt == 5);
239 
240     qemu_opt_set_number(opts, "number1", 10, &err);
241     g_assert(!err);
242 
243     /* now we have set number1, should know about it */
244     opt = qemu_opt_get_number(opts, "number1", 5);
245     g_assert(opt == 10);
246 
247     /* having reset it, the returned should be the reset one not defval */
248     qemu_opt_set_number(opts, "number1", 15, &err);
249     g_assert(!err);
250 
251     opt = qemu_opt_get_number(opts, "number1", 5);
252     g_assert(opt == 15);
253 
254     qemu_opts_del(opts);
255 
256     /* should not find anything at this point */
257     opts = qemu_opts_find(list, NULL);
258     g_assert(opts == NULL);
259 }
260 
261 static void test_qemu_opt_get_size(void)
262 {
263     QemuOptsList *list;
264     QemuOpts *opts;
265     uint64_t opt;
266     QDict *dict;
267 
268     list = qemu_find_opts("opts_list_02");
269     g_assert(list != NULL);
270     g_assert(QTAILQ_EMPTY(&list->head));
271     g_assert_cmpstr(list->name, ==, "opts_list_02");
272 
273     /* should not find anything at this point */
274     opts = qemu_opts_find(list, NULL);
275     g_assert(opts == NULL);
276 
277     /* create the opts */
278     opts = qemu_opts_create(list, NULL, 0, &error_abort);
279     g_assert(opts != NULL);
280     g_assert(!QTAILQ_EMPTY(&list->head));
281 
282     /* haven't set anything to size1 yet, so defval should be returned */
283     opt = qemu_opt_get_size(opts, "size1", 5);
284     g_assert(opt == 5);
285 
286     dict = qdict_new();
287     g_assert(dict != NULL);
288 
289     qdict_put(dict, "size1", qstring_from_str("10"));
290 
291     qemu_opts_absorb_qdict(opts, dict, &error_abort);
292     g_assert(error_abort == NULL);
293 
294     /* now we have set size1, should know about it */
295     opt = qemu_opt_get_size(opts, "size1", 5);
296     g_assert(opt == 10);
297 
298     /* reset value */
299     qdict_put(dict, "size1", qstring_from_str("15"));
300 
301     qemu_opts_absorb_qdict(opts, dict, &error_abort);
302     g_assert(error_abort == NULL);
303 
304     /* test the reset value */
305     opt = qemu_opt_get_size(opts, "size1", 5);
306     g_assert(opt == 15);
307 
308     qdict_del(dict, "size1");
309     g_free(dict);
310 
311     qemu_opts_del(opts);
312 
313     /* should not find anything at this point */
314     opts = qemu_opts_find(list, NULL);
315     g_assert(opts == NULL);
316 }
317 
318 static void test_qemu_opt_unset(void)
319 {
320     QemuOpts *opts;
321     const char *value;
322     int ret;
323 
324     /* dynamically initialized (parsed) opts */
325     opts = qemu_opts_parse(&opts_list_03, "key=value", false, NULL);
326     g_assert(opts != NULL);
327 
328     /* check default/parsed value */
329     value = qemu_opt_get(opts, "key");
330     g_assert_cmpstr(value, ==, "value");
331 
332     /* reset it to value2 */
333     qemu_opt_set(opts, "key", "value2", &error_abort);
334 
335     value = qemu_opt_get(opts, "key");
336     g_assert_cmpstr(value, ==, "value2");
337 
338     /* unset, valid only for "accept any" */
339     ret = qemu_opt_unset(opts, "key");
340     g_assert(ret == 0);
341 
342     /* after reset the value should be the parsed/default one */
343     value = qemu_opt_get(opts, "key");
344     g_assert_cmpstr(value, ==, "value");
345 
346     qemu_opts_del(opts);
347 }
348 
349 static void test_qemu_opts_reset(void)
350 {
351     Error *err = NULL;
352     QemuOptsList *list;
353     QemuOpts *opts;
354     uint64_t opt;
355 
356     list = qemu_find_opts("opts_list_01");
357     g_assert(list != NULL);
358     g_assert(QTAILQ_EMPTY(&list->head));
359     g_assert_cmpstr(list->name, ==, "opts_list_01");
360 
361     /* should not find anything at this point */
362     opts = qemu_opts_find(list, NULL);
363     g_assert(opts == NULL);
364 
365     /* create the opts */
366     opts = qemu_opts_create(list, NULL, 0, &error_abort);
367     g_assert(opts != NULL);
368     g_assert(!QTAILQ_EMPTY(&list->head));
369 
370     /* haven't set anything to number1 yet, so defval should be returned */
371     opt = qemu_opt_get_number(opts, "number1", 5);
372     g_assert(opt == 5);
373 
374     qemu_opt_set_number(opts, "number1", 10, &err);
375     g_assert(!err);
376 
377     /* now we have set number1, should know about it */
378     opt = qemu_opt_get_number(opts, "number1", 5);
379     g_assert(opt == 10);
380 
381     qemu_opts_reset(list);
382 
383     /* should not find anything at this point */
384     opts = qemu_opts_find(list, NULL);
385     g_assert(opts == NULL);
386 }
387 
388 static void test_qemu_opts_set(void)
389 {
390     Error *err = NULL;
391     QemuOptsList *list;
392     QemuOpts *opts;
393     const char *opt;
394 
395     list = qemu_find_opts("opts_list_01");
396     g_assert(list != NULL);
397     g_assert(QTAILQ_EMPTY(&list->head));
398     g_assert_cmpstr(list->name, ==, "opts_list_01");
399 
400     /* should not find anything at this point */
401     opts = qemu_opts_find(list, NULL);
402     g_assert(opts == NULL);
403 
404     /* implicitly create opts and set str3 value */
405     qemu_opts_set(list, NULL, "str3", "value", &err);
406     g_assert(!err);
407     g_assert(!QTAILQ_EMPTY(&list->head));
408 
409     /* get the just created opts */
410     opts = qemu_opts_find(list, NULL);
411     g_assert(opts != NULL);
412 
413     /* check the str3 value */
414     opt = qemu_opt_get(opts, "str3");
415     g_assert_cmpstr(opt, ==, "value");
416 
417     qemu_opts_del(opts);
418 
419     /* should not find anything at this point */
420     opts = qemu_opts_find(list, NULL);
421     g_assert(opts == NULL);
422 }
423 
424 int main(int argc, char *argv[])
425 {
426     register_opts();
427     g_test_init(&argc, &argv, NULL);
428     g_test_add_func("/qemu-opts/find_unknown_opts", test_find_unknown_opts);
429     g_test_add_func("/qemu-opts/find_opts", test_qemu_find_opts);
430     g_test_add_func("/qemu-opts/opts_create", test_qemu_opts_create);
431     g_test_add_func("/qemu-opts/opt_get", test_qemu_opt_get);
432     g_test_add_func("/qemu-opts/opt_get_bool", test_qemu_opt_get_bool);
433     g_test_add_func("/qemu-opts/opt_get_number", test_qemu_opt_get_number);
434     g_test_add_func("/qemu-opts/opt_get_size", test_qemu_opt_get_size);
435     g_test_add_func("/qemu-opts/opt_unset", test_qemu_opt_unset);
436     g_test_add_func("/qemu-opts/opts_reset", test_qemu_opts_reset);
437     g_test_add_func("/qemu-opts/opts_set", test_qemu_opts_set);
438     g_test_run();
439     return 0;
440 }
441