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