]> Git Repo - qemu.git/blob - tests/test-keyval.c
ppc4xx_i2c: Rewrite to model hardware more closely
[qemu.git] / tests / test-keyval.c
1 /*
2  * Unit tests for parsing of KEY=VALUE,... strings
3  *
4  * Copyright (C) 2017 Red Hat Inc.
5  *
6  * Authors:
7  *  Markus Armbruster <[email protected]>,
8  *
9  * This work is licensed under the terms of the GNU GPL, version 2 or later.
10  * See the COPYING file in the top-level directory.
11  */
12
13 #include "qemu/osdep.h"
14 #include "qapi/error.h"
15 #include "qapi/qmp/qdict.h"
16 #include "qapi/qmp/qlist.h"
17 #include "qapi/qmp/qstring.h"
18 #include "qapi/qobject-input-visitor.h"
19 #include "test-qapi-visit.h"
20 #include "qemu/cutils.h"
21 #include "qemu/option.h"
22
23 static void test_keyval_parse(void)
24 {
25     Error *err = NULL;
26     QDict *qdict, *sub_qdict;
27     char long_key[129];
28     char *params;
29
30     /* Nothing */
31     qdict = keyval_parse("", NULL, &error_abort);
32     g_assert_cmpuint(qdict_size(qdict), ==, 0);
33     qobject_unref(qdict);
34
35     /* Empty key (qemu_opts_parse() accepts this) */
36     qdict = keyval_parse("=val", NULL, &err);
37     error_free_or_abort(&err);
38     g_assert(!qdict);
39
40     /* Empty key fragment */
41     qdict = keyval_parse(".", NULL, &err);
42     error_free_or_abort(&err);
43     g_assert(!qdict);
44     qdict = keyval_parse("key.", NULL, &err);
45     error_free_or_abort(&err);
46     g_assert(!qdict);
47
48     /* Invalid non-empty key (qemu_opts_parse() doesn't care) */
49     qdict = keyval_parse("7up=val", NULL, &err);
50     error_free_or_abort(&err);
51     g_assert(!qdict);
52
53     /* Overlong key */
54     memset(long_key, 'a', 127);
55     long_key[127] = 'z';
56     long_key[128] = 0;
57     params = g_strdup_printf("k.%s=v", long_key);
58     qdict = keyval_parse(params + 2, NULL, &err);
59     error_free_or_abort(&err);
60     g_assert(!qdict);
61
62     /* Overlong key fragment */
63     qdict = keyval_parse(params, NULL, &err);
64     error_free_or_abort(&err);
65     g_assert(!qdict);
66     g_free(params);
67
68     /* Long key (qemu_opts_parse() accepts and truncates silently) */
69     params = g_strdup_printf("k.%s=v", long_key + 1);
70     qdict = keyval_parse(params + 2, NULL, &error_abort);
71     g_assert_cmpuint(qdict_size(qdict), ==, 1);
72     g_assert_cmpstr(qdict_get_try_str(qdict, long_key + 1), ==, "v");
73     qobject_unref(qdict);
74
75     /* Long key fragment */
76     qdict = keyval_parse(params, NULL, &error_abort);
77     g_assert_cmpuint(qdict_size(qdict), ==, 1);
78     sub_qdict = qdict_get_qdict(qdict, "k");
79     g_assert(sub_qdict);
80     g_assert_cmpuint(qdict_size(sub_qdict), ==, 1);
81     g_assert_cmpstr(qdict_get_try_str(sub_qdict, long_key + 1), ==, "v");
82     qobject_unref(qdict);
83     g_free(params);
84
85     /* Crap after valid key */
86     qdict = keyval_parse("key[0]=val", NULL, &err);
87     error_free_or_abort(&err);
88     g_assert(!qdict);
89
90     /* Multiple keys, last one wins */
91     qdict = keyval_parse("a=1,b=2,,x,a=3", NULL, &error_abort);
92     g_assert_cmpuint(qdict_size(qdict), ==, 2);
93     g_assert_cmpstr(qdict_get_try_str(qdict, "a"), ==, "3");
94     g_assert_cmpstr(qdict_get_try_str(qdict, "b"), ==, "2,x");
95     qobject_unref(qdict);
96
97     /* Even when it doesn't in qemu_opts_parse() */
98     qdict = keyval_parse("id=foo,id=bar", NULL, &error_abort);
99     g_assert_cmpuint(qdict_size(qdict), ==, 1);
100     g_assert_cmpstr(qdict_get_try_str(qdict, "id"), ==, "bar");
101     qobject_unref(qdict);
102
103     /* Dotted keys */
104     qdict = keyval_parse("a.b.c=1,a.b.c=2,d=3", NULL, &error_abort);
105     g_assert_cmpuint(qdict_size(qdict), ==, 2);
106     sub_qdict = qdict_get_qdict(qdict, "a");
107     g_assert(sub_qdict);
108     g_assert_cmpuint(qdict_size(sub_qdict), ==, 1);
109     sub_qdict = qdict_get_qdict(sub_qdict, "b");
110     g_assert(sub_qdict);
111     g_assert_cmpuint(qdict_size(sub_qdict), ==, 1);
112     g_assert_cmpstr(qdict_get_try_str(sub_qdict, "c"), ==, "2");
113     g_assert_cmpstr(qdict_get_try_str(qdict, "d"), ==, "3");
114     qobject_unref(qdict);
115
116     /* Inconsistent dotted keys */
117     qdict = keyval_parse("a.b=1,a=2", NULL, &err);
118     error_free_or_abort(&err);
119     g_assert(!qdict);
120     qdict = keyval_parse("a.b=1,a.b.c=2", NULL, &err);
121     error_free_or_abort(&err);
122     g_assert(!qdict);
123
124     /* Trailing comma is ignored */
125     qdict = keyval_parse("x=y,", NULL, &error_abort);
126     g_assert_cmpuint(qdict_size(qdict), ==, 1);
127     g_assert_cmpstr(qdict_get_try_str(qdict, "x"), ==, "y");
128     qobject_unref(qdict);
129
130     /* Except when it isn't */
131     qdict = keyval_parse(",", NULL, &err);
132     error_free_or_abort(&err);
133     g_assert(!qdict);
134
135     /* Value containing ,id= not misinterpreted as qemu_opts_parse() does */
136     qdict = keyval_parse("x=,,id=bar", NULL, &error_abort);
137     g_assert_cmpuint(qdict_size(qdict), ==, 1);
138     g_assert_cmpstr(qdict_get_try_str(qdict, "x"), ==, ",id=bar");
139     qobject_unref(qdict);
140
141     /* Anti-social ID is left to caller (qemu_opts_parse() rejects it) */
142     qdict = keyval_parse("id=666", NULL, &error_abort);
143     g_assert_cmpuint(qdict_size(qdict), ==, 1);
144     g_assert_cmpstr(qdict_get_try_str(qdict, "id"), ==, "666");
145     qobject_unref(qdict);
146
147     /* Implied value not supported (unlike qemu_opts_parse()) */
148     qdict = keyval_parse("an,noaus,noaus=", NULL, &err);
149     error_free_or_abort(&err);
150     g_assert(!qdict);
151
152     /* Implied value, key "no" (qemu_opts_parse(): negated empty key) */
153     qdict = keyval_parse("no", NULL, &err);
154     error_free_or_abort(&err);
155     g_assert(!qdict);
156
157     /* Implied key */
158     qdict = keyval_parse("an,aus=off,noaus=", "implied", &error_abort);
159     g_assert_cmpuint(qdict_size(qdict), ==, 3);
160     g_assert_cmpstr(qdict_get_try_str(qdict, "implied"), ==, "an");
161     g_assert_cmpstr(qdict_get_try_str(qdict, "aus"), ==, "off");
162     g_assert_cmpstr(qdict_get_try_str(qdict, "noaus"), ==, "");
163     qobject_unref(qdict);
164
165     /* Implied dotted key */
166     qdict = keyval_parse("val", "eins.zwei", &error_abort);
167     g_assert_cmpuint(qdict_size(qdict), ==, 1);
168     sub_qdict = qdict_get_qdict(qdict, "eins");
169     g_assert(sub_qdict);
170     g_assert_cmpuint(qdict_size(sub_qdict), ==, 1);
171     g_assert_cmpstr(qdict_get_try_str(sub_qdict, "zwei"), ==, "val");
172     qobject_unref(qdict);
173
174     /* Implied key with empty value (qemu_opts_parse() accepts this) */
175     qdict = keyval_parse(",", "implied", &err);
176     error_free_or_abort(&err);
177     g_assert(!qdict);
178
179     /* Likewise (qemu_opts_parse(): implied key with comma value) */
180     qdict = keyval_parse(",,,a=1", "implied", &err);
181     error_free_or_abort(&err);
182     g_assert(!qdict);
183
184     /* Empty key is not an implied key */
185     qdict = keyval_parse("=val", "implied", &err);
186     error_free_or_abort(&err);
187     g_assert(!qdict);
188 }
189
190 static void check_list012(QList *qlist)
191 {
192     static const char *expected[] = { "null", "eins", "zwei" };
193     int i;
194     QString *qstr;
195
196     g_assert(qlist);
197     for (i = 0; i < ARRAY_SIZE(expected); i++) {
198         qstr = qobject_to(QString, qlist_pop(qlist));
199         g_assert(qstr);
200         g_assert_cmpstr(qstring_get_str(qstr), ==, expected[i]);
201         qobject_unref(qstr);
202     }
203     g_assert(qlist_empty(qlist));
204 }
205
206 static void test_keyval_parse_list(void)
207 {
208     Error *err = NULL;
209     QDict *qdict, *sub_qdict;
210
211     /* Root can't be a list */
212     qdict = keyval_parse("0=1", NULL, &err);
213     error_free_or_abort(&err);
214     g_assert(!qdict);
215
216     /* List elements need not be in order */
217     qdict = keyval_parse("list.0=null,list.2=zwei,list.1=eins",
218                          NULL, &error_abort);
219     g_assert_cmpint(qdict_size(qdict), ==, 1);
220     check_list012(qdict_get_qlist(qdict, "list"));
221     qobject_unref(qdict);
222
223     /* Multiple indexes, last one wins */
224     qdict = keyval_parse("list.1=goner,list.0=null,list.01=eins,list.2=zwei",
225                          NULL, &error_abort);
226     g_assert_cmpint(qdict_size(qdict), ==, 1);
227     check_list012(qdict_get_qlist(qdict, "list"));
228     qobject_unref(qdict);
229
230     /* List at deeper nesting */
231     qdict = keyval_parse("a.list.1=eins,a.list.00=null,a.list.2=zwei",
232                          NULL, &error_abort);
233     g_assert_cmpint(qdict_size(qdict), ==, 1);
234     sub_qdict = qdict_get_qdict(qdict, "a");
235     g_assert_cmpint(qdict_size(sub_qdict), ==, 1);
236     check_list012(qdict_get_qlist(sub_qdict, "list"));
237     qobject_unref(qdict);
238
239     /* Inconsistent dotted keys: both list and dictionary */
240     qdict = keyval_parse("a.b.c=1,a.b.0=2", NULL, &err);
241     error_free_or_abort(&err);
242     g_assert(!qdict);
243     qdict = keyval_parse("a.0.c=1,a.b.c=2", NULL, &err);
244     error_free_or_abort(&err);
245     g_assert(!qdict);
246
247     /* Missing list indexes */
248     qdict = keyval_parse("list.1=lonely", NULL, &err);
249     error_free_or_abort(&err);
250     g_assert(!qdict);
251     qdict = keyval_parse("list.0=null,list.2=eins,list.02=zwei", NULL, &err);
252     error_free_or_abort(&err);
253     g_assert(!qdict);
254 }
255
256 static void test_keyval_visit_bool(void)
257 {
258     Error *err = NULL;
259     Visitor *v;
260     QDict *qdict;
261     bool b;
262
263     qdict = keyval_parse("bool1=on,bool2=off", NULL, &error_abort);
264     v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
265     qobject_unref(qdict);
266     visit_start_struct(v, NULL, NULL, 0, &error_abort);
267     visit_type_bool(v, "bool1", &b, &error_abort);
268     g_assert(b);
269     visit_type_bool(v, "bool2", &b, &error_abort);
270     g_assert(!b);
271     visit_check_struct(v, &error_abort);
272     visit_end_struct(v, NULL);
273     visit_free(v);
274
275     qdict = keyval_parse("bool1=offer", NULL, &error_abort);
276     v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
277     qobject_unref(qdict);
278     visit_start_struct(v, NULL, NULL, 0, &error_abort);
279     visit_type_bool(v, "bool1", &b, &err);
280     error_free_or_abort(&err);
281     visit_end_struct(v, NULL);
282     visit_free(v);
283 }
284
285 static void test_keyval_visit_number(void)
286 {
287     Error *err = NULL;
288     Visitor *v;
289     QDict *qdict;
290     uint64_t u;
291
292     /* Lower limit zero */
293     qdict = keyval_parse("number1=0", NULL, &error_abort);
294     v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
295     qobject_unref(qdict);
296     visit_start_struct(v, NULL, NULL, 0, &error_abort);
297     visit_type_uint64(v, "number1", &u, &error_abort);
298     g_assert_cmpuint(u, ==, 0);
299     visit_check_struct(v, &error_abort);
300     visit_end_struct(v, NULL);
301     visit_free(v);
302
303     /* Upper limit 2^64-1 */
304     qdict = keyval_parse("number1=18446744073709551615,number2=-1",
305                          NULL, &error_abort);
306     v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
307     qobject_unref(qdict);
308     visit_start_struct(v, NULL, NULL, 0, &error_abort);
309     visit_type_uint64(v, "number1", &u, &error_abort);
310     g_assert_cmphex(u, ==, UINT64_MAX);
311     visit_type_uint64(v, "number2", &u, &error_abort);
312     g_assert_cmphex(u, ==, UINT64_MAX);
313     visit_check_struct(v, &error_abort);
314     visit_end_struct(v, NULL);
315     visit_free(v);
316
317     /* Above upper limit */
318     qdict = keyval_parse("number1=18446744073709551616",
319                          NULL, &error_abort);
320     v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
321     qobject_unref(qdict);
322     visit_start_struct(v, NULL, NULL, 0, &error_abort);
323     visit_type_uint64(v, "number1", &u, &err);
324     error_free_or_abort(&err);
325     visit_end_struct(v, NULL);
326     visit_free(v);
327
328     /* Below lower limit */
329     qdict = keyval_parse("number1=-18446744073709551616",
330                          NULL, &error_abort);
331     v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
332     qobject_unref(qdict);
333     visit_start_struct(v, NULL, NULL, 0, &error_abort);
334     visit_type_uint64(v, "number1", &u, &err);
335     error_free_or_abort(&err);
336     visit_end_struct(v, NULL);
337     visit_free(v);
338
339     /* Hex and octal */
340     qdict = keyval_parse("number1=0x2a,number2=052",
341                          NULL, &error_abort);
342     v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
343     qobject_unref(qdict);
344     visit_start_struct(v, NULL, NULL, 0, &error_abort);
345     visit_type_uint64(v, "number1", &u, &error_abort);
346     g_assert_cmpuint(u, ==, 42);
347     visit_type_uint64(v, "number2", &u, &error_abort);
348     g_assert_cmpuint(u, ==, 42);
349     visit_check_struct(v, &error_abort);
350     visit_end_struct(v, NULL);
351     visit_free(v);
352
353     /* Trailing crap */
354     qdict = keyval_parse("number1=3.14,number2=08",
355                          NULL, &error_abort);
356     v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
357     qobject_unref(qdict);
358     visit_start_struct(v, NULL, NULL, 0, &error_abort);
359     visit_type_uint64(v, "number1", &u, &err);
360     error_free_or_abort(&err);
361     visit_type_uint64(v, "number2", &u, &err);
362     error_free_or_abort(&err);
363     visit_end_struct(v, NULL);
364     visit_free(v);
365 }
366
367 static void test_keyval_visit_size(void)
368 {
369     Error *err = NULL;
370     Visitor *v;
371     QDict *qdict;
372     uint64_t sz;
373
374     /* Lower limit zero */
375     qdict = keyval_parse("sz1=0", NULL, &error_abort);
376     v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
377     qobject_unref(qdict);
378     visit_start_struct(v, NULL, NULL, 0, &error_abort);
379     visit_type_size(v, "sz1", &sz, &error_abort);
380     g_assert_cmpuint(sz, ==, 0);
381     visit_check_struct(v, &error_abort);
382     visit_end_struct(v, NULL);
383     visit_free(v);
384
385     /* Note: precision is 53 bits since we're parsing with strtod() */
386
387     /* Around limit of precision: 2^53-1, 2^53, 2^53+1 */
388     qdict = keyval_parse("sz1=9007199254740991,"
389                          "sz2=9007199254740992,"
390                          "sz3=9007199254740993",
391                          NULL, &error_abort);
392     v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
393     qobject_unref(qdict);
394     visit_start_struct(v, NULL, NULL, 0, &error_abort);
395     visit_type_size(v, "sz1", &sz, &error_abort);
396     g_assert_cmphex(sz, ==, 0x1fffffffffffff);
397     visit_type_size(v, "sz2", &sz, &error_abort);
398     g_assert_cmphex(sz, ==, 0x20000000000000);
399     visit_type_size(v, "sz3", &sz, &error_abort);
400     g_assert_cmphex(sz, ==, 0x20000000000000);
401     visit_check_struct(v, &error_abort);
402     visit_end_struct(v, NULL);
403     visit_free(v);
404
405     /* Close to signed upper limit 0x7ffffffffffffc00 (53 msbs set) */
406     qdict = keyval_parse("sz1=9223372036854774784," /* 7ffffffffffffc00 */
407                          "sz2=9223372036854775295", /* 7ffffffffffffdff */
408                          NULL, &error_abort);
409     v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
410     qobject_unref(qdict);
411     visit_start_struct(v, NULL, NULL, 0, &error_abort);
412     visit_type_size(v, "sz1", &sz, &error_abort);
413     g_assert_cmphex(sz, ==, 0x7ffffffffffffc00);
414     visit_type_size(v, "sz2", &sz, &error_abort);
415     g_assert_cmphex(sz, ==, 0x7ffffffffffffc00);
416     visit_check_struct(v, &error_abort);
417     visit_end_struct(v, NULL);
418     visit_free(v);
419
420     /* Close to actual upper limit 0xfffffffffffff800 (53 msbs set) */
421     qdict = keyval_parse("sz1=18446744073709549568," /* fffffffffffff800 */
422                          "sz2=18446744073709550591", /* fffffffffffffbff */
423                          NULL, &error_abort);
424     v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
425     qobject_unref(qdict);
426     visit_start_struct(v, NULL, NULL, 0, &error_abort);
427     visit_type_size(v, "sz1", &sz, &error_abort);
428     g_assert_cmphex(sz, ==, 0xfffffffffffff800);
429     visit_type_size(v, "sz2", &sz, &error_abort);
430     g_assert_cmphex(sz, ==, 0xfffffffffffff800);
431     visit_check_struct(v, &error_abort);
432     visit_end_struct(v, NULL);
433     visit_free(v);
434
435     /* Beyond limits */
436     qdict = keyval_parse("sz1=-1,"
437                          "sz2=18446744073709550592", /* fffffffffffffc00 */
438                          NULL, &error_abort);
439     v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
440     qobject_unref(qdict);
441     visit_start_struct(v, NULL, NULL, 0, &error_abort);
442     visit_type_size(v, "sz1", &sz, &err);
443     error_free_or_abort(&err);
444     visit_type_size(v, "sz2", &sz, &err);
445     error_free_or_abort(&err);
446     visit_end_struct(v, NULL);
447     visit_free(v);
448
449     /* Suffixes */
450     qdict = keyval_parse("sz1=8b,sz2=1.5k,sz3=2M,sz4=0.1G,sz5=16777215T",
451                          NULL, &error_abort);
452     v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
453     qobject_unref(qdict);
454     visit_start_struct(v, NULL, NULL, 0, &error_abort);
455     visit_type_size(v, "sz1", &sz, &error_abort);
456     g_assert_cmpuint(sz, ==, 8);
457     visit_type_size(v, "sz2", &sz, &error_abort);
458     g_assert_cmpuint(sz, ==, 1536);
459     visit_type_size(v, "sz3", &sz, &error_abort);
460     g_assert_cmphex(sz, ==, 2 * M_BYTE);
461     visit_type_size(v, "sz4", &sz, &error_abort);
462     g_assert_cmphex(sz, ==, G_BYTE / 10);
463     visit_type_size(v, "sz5", &sz, &error_abort);
464     g_assert_cmphex(sz, ==, 16777215 * T_BYTE);
465     visit_check_struct(v, &error_abort);
466     visit_end_struct(v, NULL);
467     visit_free(v);
468
469     /* Beyond limit with suffix */
470     qdict = keyval_parse("sz1=16777216T", NULL, &error_abort);
471     v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
472     qobject_unref(qdict);
473     visit_start_struct(v, NULL, NULL, 0, &error_abort);
474     visit_type_size(v, "sz1", &sz, &err);
475     error_free_or_abort(&err);
476     visit_end_struct(v, NULL);
477     visit_free(v);
478
479     /* Trailing crap */
480     qdict = keyval_parse("sz1=16E,sz2=16Gi", NULL, &error_abort);
481     v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
482     qobject_unref(qdict);
483     visit_start_struct(v, NULL, NULL, 0, &error_abort);
484     visit_type_size(v, "sz1", &sz, &err);
485     error_free_or_abort(&err);
486     visit_type_size(v, "sz2", &sz, &err);
487     error_free_or_abort(&err);
488     visit_end_struct(v, NULL);
489     visit_free(v);
490 }
491
492 static void test_keyval_visit_dict(void)
493 {
494     Error *err = NULL;
495     Visitor *v;
496     QDict *qdict;
497     int64_t i;
498
499     qdict = keyval_parse("a.b.c=1,a.b.c=2,d=3", NULL, &error_abort);
500     v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
501     qobject_unref(qdict);
502     visit_start_struct(v, NULL, NULL, 0, &error_abort);
503     visit_start_struct(v, "a", NULL, 0, &error_abort);
504     visit_start_struct(v, "b", NULL, 0, &error_abort);
505     visit_type_int(v, "c", &i, &error_abort);
506     g_assert_cmpint(i, ==, 2);
507     visit_check_struct(v, &error_abort);
508     visit_end_struct(v, NULL);
509     visit_check_struct(v, &error_abort);
510     visit_end_struct(v, NULL);
511     visit_type_int(v, "d", &i, &error_abort);
512     g_assert_cmpint(i, ==, 3);
513     visit_check_struct(v, &error_abort);
514     visit_end_struct(v, NULL);
515     visit_free(v);
516
517     qdict = keyval_parse("a.b=", NULL, &error_abort);
518     v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
519     qobject_unref(qdict);
520     visit_start_struct(v, NULL, NULL, 0, &error_abort);
521     visit_start_struct(v, "a", NULL, 0, &error_abort);
522     visit_type_int(v, "c", &i, &err);   /* a.c missing */
523     error_free_or_abort(&err);
524     visit_check_struct(v, &err);
525     error_free_or_abort(&err);          /* a.b unexpected */
526     visit_end_struct(v, NULL);
527     visit_check_struct(v, &error_abort);
528     visit_end_struct(v, NULL);
529     visit_free(v);
530 }
531
532 static void test_keyval_visit_list(void)
533 {
534     Error *err = NULL;
535     Visitor *v;
536     QDict *qdict;
537     char *s;
538
539     qdict = keyval_parse("a.0=,a.1=I,a.2.0=II", NULL, &error_abort);
540     /* TODO empty list */
541     v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
542     qobject_unref(qdict);
543     visit_start_struct(v, NULL, NULL, 0, &error_abort);
544     visit_start_list(v, "a", NULL, 0, &error_abort);
545     visit_type_str(v, NULL, &s, &error_abort);
546     g_assert_cmpstr(s, ==, "");
547     g_free(s);
548     visit_type_str(v, NULL, &s, &error_abort);
549     g_assert_cmpstr(s, ==, "I");
550     g_free(s);
551     visit_start_list(v, NULL, NULL, 0, &error_abort);
552     visit_type_str(v, NULL, &s, &error_abort);
553     g_assert_cmpstr(s, ==, "II");
554     g_free(s);
555     visit_check_list(v, &error_abort);
556     visit_end_list(v, NULL);
557     visit_check_list(v, &error_abort);
558     visit_end_list(v, NULL);
559     visit_check_struct(v, &error_abort);
560     visit_end_struct(v, NULL);
561     visit_free(v);
562
563     qdict = keyval_parse("a.0=,b.0.0=head", NULL, &error_abort);
564     v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
565     qobject_unref(qdict);
566     visit_start_struct(v, NULL, NULL, 0, &error_abort);
567     visit_start_list(v, "a", NULL, 0, &error_abort);
568     visit_check_list(v, &err);  /* a[0] unexpected */
569     error_free_or_abort(&err);
570     visit_end_list(v, NULL);
571     visit_start_list(v, "b", NULL, 0, &error_abort);
572     visit_start_list(v, NULL, NULL, 0, &error_abort);
573     visit_type_str(v, NULL, &s, &error_abort);
574     g_assert_cmpstr(s, ==, "head");
575     g_free(s);
576     visit_type_str(v, NULL, &s, &err); /* b[0][1] missing */
577     error_free_or_abort(&err);
578     visit_end_list(v, NULL);
579     visit_end_list(v, NULL);
580     visit_check_struct(v, &error_abort);
581     visit_end_struct(v, NULL);
582     visit_free(v);
583 }
584
585 static void test_keyval_visit_optional(void)
586 {
587     Visitor *v;
588     QDict *qdict;
589     bool present;
590     int64_t i;
591
592     qdict = keyval_parse("a.b=1", NULL, &error_abort);
593     v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
594     qobject_unref(qdict);
595     visit_start_struct(v, NULL, NULL, 0, &error_abort);
596     visit_optional(v, "b", &present);
597     g_assert(!present);         /* b missing */
598     visit_optional(v, "a", &present);
599     g_assert(present);          /* a present */
600     visit_start_struct(v, "a", NULL, 0, &error_abort);
601     visit_optional(v, "b", &present);
602     g_assert(present);          /* a.b present */
603     visit_type_int(v, "b", &i, &error_abort);
604     g_assert_cmpint(i, ==, 1);
605     visit_optional(v, "a", &present);
606     g_assert(!present);         /* a.a missing */
607     visit_check_struct(v, &error_abort);
608     visit_end_struct(v, NULL);
609     visit_check_struct(v, &error_abort);
610     visit_end_struct(v, NULL);
611     visit_free(v);
612 }
613
614 static void test_keyval_visit_alternate(void)
615 {
616     Error *err = NULL;
617     Visitor *v;
618     QDict *qdict;
619     AltStrObj *aso;
620     AltNumEnum *ane;
621     AltEnumBool *aeb;
622
623     /*
624      * Can't do scalar alternate variants other than string.  You get
625      * the string variant if there is one, else an error.
626      * TODO make it work for unambiguous cases like AltEnumBool below
627      */
628     qdict = keyval_parse("a=1,b=2,c=on", NULL, &error_abort);
629     v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
630     qobject_unref(qdict);
631     visit_start_struct(v, NULL, NULL, 0, &error_abort);
632     visit_type_AltStrObj(v, "a", &aso, &error_abort);
633     g_assert_cmpint(aso->type, ==, QTYPE_QSTRING);
634     g_assert_cmpstr(aso->u.s, ==, "1");
635     qapi_free_AltStrObj(aso);
636     visit_type_AltNumEnum(v, "b", &ane, &err);
637     error_free_or_abort(&err);
638     visit_type_AltEnumBool(v, "c", &aeb, &err);
639     error_free_or_abort(&err);
640     visit_end_struct(v, NULL);
641     visit_free(v);
642 }
643
644 static void test_keyval_visit_any(void)
645 {
646     Visitor *v;
647     QDict *qdict;
648     QObject *any;
649     QList *qlist;
650     QString *qstr;
651
652     qdict = keyval_parse("a.0=null,a.1=1", NULL, &error_abort);
653     v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
654     qobject_unref(qdict);
655     visit_start_struct(v, NULL, NULL, 0, &error_abort);
656     visit_type_any(v, "a", &any, &error_abort);
657     qlist = qobject_to(QList, any);
658     g_assert(qlist);
659     qstr = qobject_to(QString, qlist_pop(qlist));
660     g_assert_cmpstr(qstring_get_str(qstr), ==, "null");
661     qobject_unref(qstr);
662     qstr = qobject_to(QString, qlist_pop(qlist));
663     g_assert_cmpstr(qstring_get_str(qstr), ==, "1");
664     g_assert(qlist_empty(qlist));
665     qobject_unref(qstr);
666     qobject_unref(any);
667     visit_check_struct(v, &error_abort);
668     visit_end_struct(v, NULL);
669     visit_free(v);
670 }
671
672 int main(int argc, char *argv[])
673 {
674     g_test_init(&argc, &argv, NULL);
675     g_test_add_func("/keyval/keyval_parse", test_keyval_parse);
676     g_test_add_func("/keyval/keyval_parse/list", test_keyval_parse_list);
677     g_test_add_func("/keyval/visit/bool", test_keyval_visit_bool);
678     g_test_add_func("/keyval/visit/number", test_keyval_visit_number);
679     g_test_add_func("/keyval/visit/size", test_keyval_visit_size);
680     g_test_add_func("/keyval/visit/dict", test_keyval_visit_dict);
681     g_test_add_func("/keyval/visit/list", test_keyval_visit_list);
682     g_test_add_func("/keyval/visit/optional", test_keyval_visit_optional);
683     g_test_add_func("/keyval/visit/alternate", test_keyval_visit_alternate);
684     g_test_add_func("/keyval/visit/any", test_keyval_visit_any);
685     g_test_run();
686     return 0;
687 }
This page took 0.064044 seconds and 4 git commands to generate.