]> Git Repo - qemu.git/blob - tests/test-qmp-input-visitor.c
qapi: Plumb in 'boxed' to qapi generator lower levels
[qemu.git] / tests / test-qmp-input-visitor.c
1 /*
2  * QMP Input Visitor unit-tests.
3  *
4  * Copyright (C) 2011-2016 Red Hat Inc.
5  *
6  * Authors:
7  *  Luiz Capitulino <[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
15 #include "qemu-common.h"
16 #include "qapi/error.h"
17 #include "qapi/qmp-input-visitor.h"
18 #include "test-qapi-types.h"
19 #include "test-qapi-visit.h"
20 #include "qapi/qmp/types.h"
21 #include "qapi/qmp/qjson.h"
22
23 typedef struct TestInputVisitorData {
24     QObject *obj;
25     Visitor *qiv;
26 } TestInputVisitorData;
27
28 static void visitor_input_teardown(TestInputVisitorData *data,
29                                    const void *unused)
30 {
31     qobject_decref(data->obj);
32     data->obj = NULL;
33
34     if (data->qiv) {
35         visit_free(data->qiv);
36         data->qiv = NULL;
37     }
38 }
39
40 /* The various test_init functions are provided instead of a test setup
41    function so that the JSON string used by the tests are kept in the test
42    functions (and not in main()). */
43 static Visitor *visitor_input_test_init_internal(TestInputVisitorData *data,
44                                                  const char *json_string,
45                                                  va_list *ap)
46 {
47     visitor_input_teardown(data, NULL);
48
49     data->obj = qobject_from_jsonv(json_string, ap);
50     g_assert(data->obj);
51
52     data->qiv = qmp_input_visitor_new(data->obj, false);
53     g_assert(data->qiv);
54     return data->qiv;
55 }
56
57 static GCC_FMT_ATTR(2, 3)
58 Visitor *visitor_input_test_init(TestInputVisitorData *data,
59                                  const char *json_string, ...)
60 {
61     Visitor *v;
62     va_list ap;
63
64     va_start(ap, json_string);
65     v = visitor_input_test_init_internal(data, json_string, &ap);
66     va_end(ap);
67     return v;
68 }
69
70 /* similar to visitor_input_test_init(), but does not expect a string
71  * literal/format json_string argument and so can be used for
72  * programatically generated strings (and we can't pass in programatically
73  * generated strings via %s format parameters since qobject_from_jsonv()
74  * will wrap those in double-quotes and treat the entire object as a
75  * string)
76  */
77 static Visitor *visitor_input_test_init_raw(TestInputVisitorData *data,
78                                             const char *json_string)
79 {
80     return visitor_input_test_init_internal(data, json_string, NULL);
81 }
82
83 static void test_visitor_in_int(TestInputVisitorData *data,
84                                 const void *unused)
85 {
86     int64_t res = 0, value = -42;
87     Visitor *v;
88
89     v = visitor_input_test_init(data, "%" PRId64, value);
90
91     visit_type_int(v, NULL, &res, &error_abort);
92     g_assert_cmpint(res, ==, value);
93 }
94
95 static void test_visitor_in_int_overflow(TestInputVisitorData *data,
96                                          const void *unused)
97 {
98     int64_t res = 0;
99     Error *err = NULL;
100     Visitor *v;
101
102     /* this will overflow a Qint/int64, so should be deserialized into
103      * a QFloat/double field instead, leading to an error if we pass it
104      * to visit_type_int. confirm this.
105      */
106     v = visitor_input_test_init(data, "%f", DBL_MAX);
107
108     visit_type_int(v, NULL, &res, &err);
109     error_free_or_abort(&err);
110 }
111
112 static void test_visitor_in_bool(TestInputVisitorData *data,
113                                  const void *unused)
114 {
115     bool res = false;
116     Visitor *v;
117
118     v = visitor_input_test_init(data, "true");
119
120     visit_type_bool(v, NULL, &res, &error_abort);
121     g_assert_cmpint(res, ==, true);
122 }
123
124 static void test_visitor_in_number(TestInputVisitorData *data,
125                                    const void *unused)
126 {
127     double res = 0, value = 3.14;
128     Visitor *v;
129
130     v = visitor_input_test_init(data, "%f", value);
131
132     visit_type_number(v, NULL, &res, &error_abort);
133     g_assert_cmpfloat(res, ==, value);
134 }
135
136 static void test_visitor_in_string(TestInputVisitorData *data,
137                                    const void *unused)
138 {
139     char *res = NULL, *value = (char *) "Q E M U";
140     Visitor *v;
141
142     v = visitor_input_test_init(data, "%s", value);
143
144     visit_type_str(v, NULL, &res, &error_abort);
145     g_assert_cmpstr(res, ==, value);
146
147     g_free(res);
148 }
149
150 static void test_visitor_in_enum(TestInputVisitorData *data,
151                                  const void *unused)
152 {
153     Visitor *v;
154     EnumOne i;
155
156     for (i = 0; EnumOne_lookup[i]; i++) {
157         EnumOne res = -1;
158
159         v = visitor_input_test_init(data, "%s", EnumOne_lookup[i]);
160
161         visit_type_EnumOne(v, NULL, &res, &error_abort);
162         g_assert_cmpint(i, ==, res);
163     }
164 }
165
166
167 static void test_visitor_in_struct(TestInputVisitorData *data,
168                                    const void *unused)
169 {
170     TestStruct *p = NULL;
171     Visitor *v;
172
173     v = visitor_input_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo' }");
174
175     visit_type_TestStruct(v, NULL, &p, &error_abort);
176     g_assert_cmpint(p->integer, ==, -42);
177     g_assert(p->boolean == true);
178     g_assert_cmpstr(p->string, ==, "foo");
179
180     g_free(p->string);
181     g_free(p);
182 }
183
184 static void test_visitor_in_struct_nested(TestInputVisitorData *data,
185                                           const void *unused)
186 {
187     UserDefTwo *udp = NULL;
188     Visitor *v;
189
190     v = visitor_input_test_init(data, "{ 'string0': 'string0', "
191                                 "'dict1': { 'string1': 'string1', "
192                                 "'dict2': { 'userdef': { 'integer': 42, "
193                                 "'string': 'string' }, 'string': 'string2'}}}");
194
195     visit_type_UserDefTwo(v, NULL, &udp, &error_abort);
196
197     g_assert_cmpstr(udp->string0, ==, "string0");
198     g_assert_cmpstr(udp->dict1->string1, ==, "string1");
199     g_assert_cmpint(udp->dict1->dict2->userdef->integer, ==, 42);
200     g_assert_cmpstr(udp->dict1->dict2->userdef->string, ==, "string");
201     g_assert_cmpstr(udp->dict1->dict2->string, ==, "string2");
202     g_assert(udp->dict1->has_dict3 == false);
203
204     qapi_free_UserDefTwo(udp);
205 }
206
207 static void test_visitor_in_list(TestInputVisitorData *data,
208                                  const void *unused)
209 {
210     UserDefOneList *item, *head = NULL;
211     Visitor *v;
212     int i;
213
214     v = visitor_input_test_init(data, "[ { 'string': 'string0', 'integer': 42 }, { 'string': 'string1', 'integer': 43 }, { 'string': 'string2', 'integer': 44 } ]");
215
216     visit_type_UserDefOneList(v, NULL, &head, &error_abort);
217     g_assert(head != NULL);
218
219     for (i = 0, item = head; item; item = item->next, i++) {
220         char string[12];
221
222         snprintf(string, sizeof(string), "string%d", i);
223         g_assert_cmpstr(item->value->string, ==, string);
224         g_assert_cmpint(item->value->integer, ==, 42 + i);
225     }
226
227     qapi_free_UserDefOneList(head);
228     head = NULL;
229
230     /* An empty list is valid */
231     v = visitor_input_test_init(data, "[]");
232     visit_type_UserDefOneList(v, NULL, &head, &error_abort);
233     g_assert(!head);
234 }
235
236 static void test_visitor_in_any(TestInputVisitorData *data,
237                                 const void *unused)
238 {
239     QObject *res = NULL;
240     Visitor *v;
241     QInt *qint;
242     QBool *qbool;
243     QString *qstring;
244     QDict *qdict;
245     QObject *qobj;
246
247     v = visitor_input_test_init(data, "-42");
248     visit_type_any(v, NULL, &res, &error_abort);
249     qint = qobject_to_qint(res);
250     g_assert(qint);
251     g_assert_cmpint(qint_get_int(qint), ==, -42);
252     qobject_decref(res);
253
254     v = visitor_input_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo' }");
255     visit_type_any(v, NULL, &res, &error_abort);
256     qdict = qobject_to_qdict(res);
257     g_assert(qdict && qdict_size(qdict) == 3);
258     qobj = qdict_get(qdict, "integer");
259     g_assert(qobj);
260     qint = qobject_to_qint(qobj);
261     g_assert(qint);
262     g_assert_cmpint(qint_get_int(qint), ==, -42);
263     qobj = qdict_get(qdict, "boolean");
264     g_assert(qobj);
265     qbool = qobject_to_qbool(qobj);
266     g_assert(qbool);
267     g_assert(qbool_get_bool(qbool) == true);
268     qobj = qdict_get(qdict, "string");
269     g_assert(qobj);
270     qstring = qobject_to_qstring(qobj);
271     g_assert(qstring);
272     g_assert_cmpstr(qstring_get_str(qstring), ==, "foo");
273     qobject_decref(res);
274 }
275
276 static void test_visitor_in_null(TestInputVisitorData *data,
277                                  const void *unused)
278 {
279     Visitor *v;
280     Error *err = NULL;
281     char *tmp;
282
283     /*
284      * FIXME: Since QAPI doesn't know the 'null' type yet, we can't
285      * test visit_type_null() by reading into a QAPI struct then
286      * checking that it was populated correctly.  The best we can do
287      * for now is ensure that we consumed null from the input, proven
288      * by the fact that we can't re-read the key; and that we detect
289      * when input is not null.
290      */
291
292     v = visitor_input_test_init(data, "{ 'a': null, 'b': '' }");
293     visit_start_struct(v, NULL, NULL, 0, &error_abort);
294     visit_type_null(v, "a", &error_abort);
295     visit_type_str(v, "a", &tmp, &err);
296     g_assert(!tmp);
297     error_free_or_abort(&err);
298     visit_type_null(v, "b", &err);
299     error_free_or_abort(&err);
300     visit_check_struct(v, &error_abort);
301     visit_end_struct(v, NULL);
302 }
303
304 static void test_visitor_in_union_flat(TestInputVisitorData *data,
305                                        const void *unused)
306 {
307     Visitor *v;
308     UserDefFlatUnion *tmp;
309     UserDefUnionBase *base;
310
311     v = visitor_input_test_init(data,
312                                 "{ 'enum1': 'value1', "
313                                 "'integer': 41, "
314                                 "'string': 'str', "
315                                 "'boolean': true }");
316
317     visit_type_UserDefFlatUnion(v, NULL, &tmp, &error_abort);
318     g_assert_cmpint(tmp->enum1, ==, ENUM_ONE_VALUE1);
319     g_assert_cmpstr(tmp->string, ==, "str");
320     g_assert_cmpint(tmp->integer, ==, 41);
321     g_assert_cmpint(tmp->u.value1.boolean, ==, true);
322
323     base = qapi_UserDefFlatUnion_base(tmp);
324     g_assert(&base->enum1 == &tmp->enum1);
325
326     qapi_free_UserDefFlatUnion(tmp);
327 }
328
329 static void test_visitor_in_alternate(TestInputVisitorData *data,
330                                       const void *unused)
331 {
332     Visitor *v;
333     Error *err = NULL;
334     UserDefAlternate *tmp;
335     WrapAlternate *wrap;
336
337     v = visitor_input_test_init(data, "42");
338     visit_type_UserDefAlternate(v, NULL, &tmp, &error_abort);
339     g_assert_cmpint(tmp->type, ==, QTYPE_QINT);
340     g_assert_cmpint(tmp->u.i, ==, 42);
341     qapi_free_UserDefAlternate(tmp);
342
343     v = visitor_input_test_init(data, "'string'");
344     visit_type_UserDefAlternate(v, NULL, &tmp, &error_abort);
345     g_assert_cmpint(tmp->type, ==, QTYPE_QSTRING);
346     g_assert_cmpstr(tmp->u.s, ==, "string");
347     qapi_free_UserDefAlternate(tmp);
348
349     v = visitor_input_test_init(data, "{'integer':1, 'string':'str', "
350                                 "'enum1':'value1', 'boolean':true}");
351     visit_type_UserDefAlternate(v, NULL, &tmp, &error_abort);
352     g_assert_cmpint(tmp->type, ==, QTYPE_QDICT);
353     g_assert_cmpint(tmp->u.udfu.integer, ==, 1);
354     g_assert_cmpstr(tmp->u.udfu.string, ==, "str");
355     g_assert_cmpint(tmp->u.udfu.enum1, ==, ENUM_ONE_VALUE1);
356     g_assert_cmpint(tmp->u.udfu.u.value1.boolean, ==, true);
357     g_assert_cmpint(tmp->u.udfu.u.value1.has_a_b, ==, false);
358     qapi_free_UserDefAlternate(tmp);
359
360     v = visitor_input_test_init(data, "false");
361     visit_type_UserDefAlternate(v, NULL, &tmp, &err);
362     error_free_or_abort(&err);
363     qapi_free_UserDefAlternate(tmp);
364
365     v = visitor_input_test_init(data, "{ 'alt': 42 }");
366     visit_type_WrapAlternate(v, NULL, &wrap, &error_abort);
367     g_assert_cmpint(wrap->alt->type, ==, QTYPE_QINT);
368     g_assert_cmpint(wrap->alt->u.i, ==, 42);
369     qapi_free_WrapAlternate(wrap);
370
371     v = visitor_input_test_init(data, "{ 'alt': 'string' }");
372     visit_type_WrapAlternate(v, NULL, &wrap, &error_abort);
373     g_assert_cmpint(wrap->alt->type, ==, QTYPE_QSTRING);
374     g_assert_cmpstr(wrap->alt->u.s, ==, "string");
375     qapi_free_WrapAlternate(wrap);
376
377     v = visitor_input_test_init(data, "{ 'alt': {'integer':1, 'string':'str', "
378                                 "'enum1':'value1', 'boolean':true} }");
379     visit_type_WrapAlternate(v, NULL, &wrap, &error_abort);
380     g_assert_cmpint(wrap->alt->type, ==, QTYPE_QDICT);
381     g_assert_cmpint(wrap->alt->u.udfu.integer, ==, 1);
382     g_assert_cmpstr(wrap->alt->u.udfu.string, ==, "str");
383     g_assert_cmpint(wrap->alt->u.udfu.enum1, ==, ENUM_ONE_VALUE1);
384     g_assert_cmpint(wrap->alt->u.udfu.u.value1.boolean, ==, true);
385     g_assert_cmpint(wrap->alt->u.udfu.u.value1.has_a_b, ==, false);
386     qapi_free_WrapAlternate(wrap);
387 }
388
389 static void test_visitor_in_alternate_number(TestInputVisitorData *data,
390                                              const void *unused)
391 {
392     Visitor *v;
393     Error *err = NULL;
394     AltStrBool *asb;
395     AltStrNum *asn;
396     AltNumStr *ans;
397     AltStrInt *asi;
398     AltIntNum *ain;
399     AltNumInt *ani;
400
401     /* Parsing an int */
402
403     v = visitor_input_test_init(data, "42");
404     visit_type_AltStrBool(v, NULL, &asb, &err);
405     error_free_or_abort(&err);
406     qapi_free_AltStrBool(asb);
407
408     v = visitor_input_test_init(data, "42");
409     visit_type_AltStrNum(v, NULL, &asn, &error_abort);
410     g_assert_cmpint(asn->type, ==, QTYPE_QFLOAT);
411     g_assert_cmpfloat(asn->u.n, ==, 42);
412     qapi_free_AltStrNum(asn);
413
414     v = visitor_input_test_init(data, "42");
415     visit_type_AltNumStr(v, NULL, &ans, &error_abort);
416     g_assert_cmpint(ans->type, ==, QTYPE_QFLOAT);
417     g_assert_cmpfloat(ans->u.n, ==, 42);
418     qapi_free_AltNumStr(ans);
419
420     v = visitor_input_test_init(data, "42");
421     visit_type_AltStrInt(v, NULL, &asi, &error_abort);
422     g_assert_cmpint(asi->type, ==, QTYPE_QINT);
423     g_assert_cmpint(asi->u.i, ==, 42);
424     qapi_free_AltStrInt(asi);
425
426     v = visitor_input_test_init(data, "42");
427     visit_type_AltIntNum(v, NULL, &ain, &error_abort);
428     g_assert_cmpint(ain->type, ==, QTYPE_QINT);
429     g_assert_cmpint(ain->u.i, ==, 42);
430     qapi_free_AltIntNum(ain);
431
432     v = visitor_input_test_init(data, "42");
433     visit_type_AltNumInt(v, NULL, &ani, &error_abort);
434     g_assert_cmpint(ani->type, ==, QTYPE_QINT);
435     g_assert_cmpint(ani->u.i, ==, 42);
436     qapi_free_AltNumInt(ani);
437
438     /* Parsing a double */
439
440     v = visitor_input_test_init(data, "42.5");
441     visit_type_AltStrBool(v, NULL, &asb, &err);
442     error_free_or_abort(&err);
443     qapi_free_AltStrBool(asb);
444
445     v = visitor_input_test_init(data, "42.5");
446     visit_type_AltStrNum(v, NULL, &asn, &error_abort);
447     g_assert_cmpint(asn->type, ==, QTYPE_QFLOAT);
448     g_assert_cmpfloat(asn->u.n, ==, 42.5);
449     qapi_free_AltStrNum(asn);
450
451     v = visitor_input_test_init(data, "42.5");
452     visit_type_AltNumStr(v, NULL, &ans, &error_abort);
453     g_assert_cmpint(ans->type, ==, QTYPE_QFLOAT);
454     g_assert_cmpfloat(ans->u.n, ==, 42.5);
455     qapi_free_AltNumStr(ans);
456
457     v = visitor_input_test_init(data, "42.5");
458     visit_type_AltStrInt(v, NULL, &asi, &err);
459     error_free_or_abort(&err);
460     qapi_free_AltStrInt(asi);
461
462     v = visitor_input_test_init(data, "42.5");
463     visit_type_AltIntNum(v, NULL, &ain, &error_abort);
464     g_assert_cmpint(ain->type, ==, QTYPE_QFLOAT);
465     g_assert_cmpfloat(ain->u.n, ==, 42.5);
466     qapi_free_AltIntNum(ain);
467
468     v = visitor_input_test_init(data, "42.5");
469     visit_type_AltNumInt(v, NULL, &ani, &error_abort);
470     g_assert_cmpint(ani->type, ==, QTYPE_QFLOAT);
471     g_assert_cmpfloat(ani->u.n, ==, 42.5);
472     qapi_free_AltNumInt(ani);
473 }
474
475 static void test_native_list_integer_helper(TestInputVisitorData *data,
476                                             const void *unused,
477                                             UserDefNativeListUnionKind kind)
478 {
479     UserDefNativeListUnion *cvalue = NULL;
480     Visitor *v;
481     GString *gstr_list = g_string_new("");
482     GString *gstr_union = g_string_new("");
483     int i;
484
485     for (i = 0; i < 32; i++) {
486         g_string_append_printf(gstr_list, "%d", i);
487         if (i != 31) {
488             g_string_append(gstr_list, ", ");
489         }
490     }
491     g_string_append_printf(gstr_union,  "{ 'type': '%s', 'data': [ %s ] }",
492                            UserDefNativeListUnionKind_lookup[kind],
493                            gstr_list->str);
494     v = visitor_input_test_init_raw(data,  gstr_union->str);
495
496     visit_type_UserDefNativeListUnion(v, NULL, &cvalue, &error_abort);
497     g_assert(cvalue != NULL);
498     g_assert_cmpint(cvalue->type, ==, kind);
499
500     switch (kind) {
501     case USER_DEF_NATIVE_LIST_UNION_KIND_INTEGER: {
502         intList *elem = NULL;
503         for (i = 0, elem = cvalue->u.integer.data;
504              elem; elem = elem->next, i++) {
505             g_assert_cmpint(elem->value, ==, i);
506         }
507         break;
508     }
509     case USER_DEF_NATIVE_LIST_UNION_KIND_S8: {
510         int8List *elem = NULL;
511         for (i = 0, elem = cvalue->u.s8.data; elem; elem = elem->next, i++) {
512             g_assert_cmpint(elem->value, ==, i);
513         }
514         break;
515     }
516     case USER_DEF_NATIVE_LIST_UNION_KIND_S16: {
517         int16List *elem = NULL;
518         for (i = 0, elem = cvalue->u.s16.data; elem; elem = elem->next, i++) {
519             g_assert_cmpint(elem->value, ==, i);
520         }
521         break;
522     }
523     case USER_DEF_NATIVE_LIST_UNION_KIND_S32: {
524         int32List *elem = NULL;
525         for (i = 0, elem = cvalue->u.s32.data; elem; elem = elem->next, i++) {
526             g_assert_cmpint(elem->value, ==, i);
527         }
528         break;
529     }
530     case USER_DEF_NATIVE_LIST_UNION_KIND_S64: {
531         int64List *elem = NULL;
532         for (i = 0, elem = cvalue->u.s64.data; elem; elem = elem->next, i++) {
533             g_assert_cmpint(elem->value, ==, i);
534         }
535         break;
536     }
537     case USER_DEF_NATIVE_LIST_UNION_KIND_U8: {
538         uint8List *elem = NULL;
539         for (i = 0, elem = cvalue->u.u8.data; elem; elem = elem->next, i++) {
540             g_assert_cmpint(elem->value, ==, i);
541         }
542         break;
543     }
544     case USER_DEF_NATIVE_LIST_UNION_KIND_U16: {
545         uint16List *elem = NULL;
546         for (i = 0, elem = cvalue->u.u16.data; elem; elem = elem->next, i++) {
547             g_assert_cmpint(elem->value, ==, i);
548         }
549         break;
550     }
551     case USER_DEF_NATIVE_LIST_UNION_KIND_U32: {
552         uint32List *elem = NULL;
553         for (i = 0, elem = cvalue->u.u32.data; elem; elem = elem->next, i++) {
554             g_assert_cmpint(elem->value, ==, i);
555         }
556         break;
557     }
558     case USER_DEF_NATIVE_LIST_UNION_KIND_U64: {
559         uint64List *elem = NULL;
560         for (i = 0, elem = cvalue->u.u64.data; elem; elem = elem->next, i++) {
561             g_assert_cmpint(elem->value, ==, i);
562         }
563         break;
564     }
565     default:
566         g_assert_not_reached();
567     }
568
569     g_string_free(gstr_union, true);
570     g_string_free(gstr_list, true);
571     qapi_free_UserDefNativeListUnion(cvalue);
572 }
573
574 static void test_visitor_in_native_list_int(TestInputVisitorData *data,
575                                             const void *unused)
576 {
577     test_native_list_integer_helper(data, unused,
578                                     USER_DEF_NATIVE_LIST_UNION_KIND_INTEGER);
579 }
580
581 static void test_visitor_in_native_list_int8(TestInputVisitorData *data,
582                                              const void *unused)
583 {
584     test_native_list_integer_helper(data, unused,
585                                     USER_DEF_NATIVE_LIST_UNION_KIND_S8);
586 }
587
588 static void test_visitor_in_native_list_int16(TestInputVisitorData *data,
589                                               const void *unused)
590 {
591     test_native_list_integer_helper(data, unused,
592                                     USER_DEF_NATIVE_LIST_UNION_KIND_S16);
593 }
594
595 static void test_visitor_in_native_list_int32(TestInputVisitorData *data,
596                                               const void *unused)
597 {
598     test_native_list_integer_helper(data, unused,
599                                     USER_DEF_NATIVE_LIST_UNION_KIND_S32);
600 }
601
602 static void test_visitor_in_native_list_int64(TestInputVisitorData *data,
603                                               const void *unused)
604 {
605     test_native_list_integer_helper(data, unused,
606                                     USER_DEF_NATIVE_LIST_UNION_KIND_S64);
607 }
608
609 static void test_visitor_in_native_list_uint8(TestInputVisitorData *data,
610                                              const void *unused)
611 {
612     test_native_list_integer_helper(data, unused,
613                                     USER_DEF_NATIVE_LIST_UNION_KIND_U8);
614 }
615
616 static void test_visitor_in_native_list_uint16(TestInputVisitorData *data,
617                                                const void *unused)
618 {
619     test_native_list_integer_helper(data, unused,
620                                     USER_DEF_NATIVE_LIST_UNION_KIND_U16);
621 }
622
623 static void test_visitor_in_native_list_uint32(TestInputVisitorData *data,
624                                                const void *unused)
625 {
626     test_native_list_integer_helper(data, unused,
627                                     USER_DEF_NATIVE_LIST_UNION_KIND_U32);
628 }
629
630 static void test_visitor_in_native_list_uint64(TestInputVisitorData *data,
631                                                const void *unused)
632 {
633     test_native_list_integer_helper(data, unused,
634                                     USER_DEF_NATIVE_LIST_UNION_KIND_U64);
635 }
636
637 static void test_visitor_in_native_list_bool(TestInputVisitorData *data,
638                                             const void *unused)
639 {
640     UserDefNativeListUnion *cvalue = NULL;
641     boolList *elem = NULL;
642     Visitor *v;
643     GString *gstr_list = g_string_new("");
644     GString *gstr_union = g_string_new("");
645     int i;
646
647     for (i = 0; i < 32; i++) {
648         g_string_append_printf(gstr_list, "%s",
649                                (i % 3 == 0) ? "true" : "false");
650         if (i != 31) {
651             g_string_append(gstr_list, ", ");
652         }
653     }
654     g_string_append_printf(gstr_union,  "{ 'type': 'boolean', 'data': [ %s ] }",
655                            gstr_list->str);
656     v = visitor_input_test_init_raw(data,  gstr_union->str);
657
658     visit_type_UserDefNativeListUnion(v, NULL, &cvalue, &error_abort);
659     g_assert(cvalue != NULL);
660     g_assert_cmpint(cvalue->type, ==, USER_DEF_NATIVE_LIST_UNION_KIND_BOOLEAN);
661
662     for (i = 0, elem = cvalue->u.boolean.data; elem; elem = elem->next, i++) {
663         g_assert_cmpint(elem->value, ==, (i % 3 == 0) ? 1 : 0);
664     }
665
666     g_string_free(gstr_union, true);
667     g_string_free(gstr_list, true);
668     qapi_free_UserDefNativeListUnion(cvalue);
669 }
670
671 static void test_visitor_in_native_list_string(TestInputVisitorData *data,
672                                                const void *unused)
673 {
674     UserDefNativeListUnion *cvalue = NULL;
675     strList *elem = NULL;
676     Visitor *v;
677     GString *gstr_list = g_string_new("");
678     GString *gstr_union = g_string_new("");
679     int i;
680
681     for (i = 0; i < 32; i++) {
682         g_string_append_printf(gstr_list, "'%d'", i);
683         if (i != 31) {
684             g_string_append(gstr_list, ", ");
685         }
686     }
687     g_string_append_printf(gstr_union,  "{ 'type': 'string', 'data': [ %s ] }",
688                            gstr_list->str);
689     v = visitor_input_test_init_raw(data,  gstr_union->str);
690
691     visit_type_UserDefNativeListUnion(v, NULL, &cvalue, &error_abort);
692     g_assert(cvalue != NULL);
693     g_assert_cmpint(cvalue->type, ==, USER_DEF_NATIVE_LIST_UNION_KIND_STRING);
694
695     for (i = 0, elem = cvalue->u.string.data; elem; elem = elem->next, i++) {
696         gchar str[8];
697         sprintf(str, "%d", i);
698         g_assert_cmpstr(elem->value, ==, str);
699     }
700
701     g_string_free(gstr_union, true);
702     g_string_free(gstr_list, true);
703     qapi_free_UserDefNativeListUnion(cvalue);
704 }
705
706 #define DOUBLE_STR_MAX 16
707
708 static void test_visitor_in_native_list_number(TestInputVisitorData *data,
709                                                const void *unused)
710 {
711     UserDefNativeListUnion *cvalue = NULL;
712     numberList *elem = NULL;
713     Visitor *v;
714     GString *gstr_list = g_string_new("");
715     GString *gstr_union = g_string_new("");
716     int i;
717
718     for (i = 0; i < 32; i++) {
719         g_string_append_printf(gstr_list, "%f", (double)i / 3);
720         if (i != 31) {
721             g_string_append(gstr_list, ", ");
722         }
723     }
724     g_string_append_printf(gstr_union,  "{ 'type': 'number', 'data': [ %s ] }",
725                            gstr_list->str);
726     v = visitor_input_test_init_raw(data,  gstr_union->str);
727
728     visit_type_UserDefNativeListUnion(v, NULL, &cvalue, &error_abort);
729     g_assert(cvalue != NULL);
730     g_assert_cmpint(cvalue->type, ==, USER_DEF_NATIVE_LIST_UNION_KIND_NUMBER);
731
732     for (i = 0, elem = cvalue->u.number.data; elem; elem = elem->next, i++) {
733         GString *double_expected = g_string_new("");
734         GString *double_actual = g_string_new("");
735
736         g_string_printf(double_expected, "%.6f", (double)i / 3);
737         g_string_printf(double_actual, "%.6f", elem->value);
738         g_assert_cmpstr(double_expected->str, ==, double_actual->str);
739
740         g_string_free(double_expected, true);
741         g_string_free(double_actual, true);
742     }
743
744     g_string_free(gstr_union, true);
745     g_string_free(gstr_list, true);
746     qapi_free_UserDefNativeListUnion(cvalue);
747 }
748
749 static void input_visitor_test_add(const char *testpath,
750                                    TestInputVisitorData *data,
751                                    void (*test_func)(TestInputVisitorData *data, const void *user_data))
752 {
753     g_test_add(testpath, TestInputVisitorData, data, NULL, test_func,
754                visitor_input_teardown);
755 }
756
757 static void test_visitor_in_errors(TestInputVisitorData *data,
758                                    const void *unused)
759 {
760     TestStruct *p = NULL;
761     Error *err = NULL;
762     Visitor *v;
763     strList *q = NULL;
764     UserDefTwo *r = NULL;
765     WrapAlternate *s = NULL;
766
767     v = visitor_input_test_init(data, "{ 'integer': false, 'boolean': 'foo', "
768                                 "'string': -42 }");
769
770     visit_type_TestStruct(v, NULL, &p, &err);
771     error_free_or_abort(&err);
772     g_assert(!p);
773
774     v = visitor_input_test_init(data, "[ '1', '2', false, '3' ]");
775     visit_type_strList(v, NULL, &q, &err);
776     error_free_or_abort(&err);
777     assert(!q);
778
779     v = visitor_input_test_init(data, "{ 'str':'hi' }");
780     visit_type_UserDefTwo(v, NULL, &r, &err);
781     error_free_or_abort(&err);
782     assert(!r);
783
784     v = visitor_input_test_init(data, "{ }");
785     visit_type_WrapAlternate(v, NULL, &s, &err);
786     error_free_or_abort(&err);
787     assert(!s);
788 }
789
790 static void test_visitor_in_wrong_type(TestInputVisitorData *data,
791                                        const void *unused)
792 {
793     TestStruct *p = NULL;
794     Visitor *v;
795     strList *q = NULL;
796     int64_t i;
797     Error *err = NULL;
798
799     /* Make sure arrays and structs cannot be confused */
800
801     v = visitor_input_test_init(data, "[]");
802     visit_type_TestStruct(v, NULL, &p, &err);
803     error_free_or_abort(&err);
804     g_assert(!p);
805
806     v = visitor_input_test_init(data, "{}");
807     visit_type_strList(v, NULL, &q, &err);
808     error_free_or_abort(&err);
809     assert(!q);
810
811     /* Make sure primitives and struct cannot be confused */
812
813     v = visitor_input_test_init(data, "1");
814     visit_type_TestStruct(v, NULL, &p, &err);
815     error_free_or_abort(&err);
816     g_assert(!p);
817
818     v = visitor_input_test_init(data, "{}");
819     visit_type_int(v, NULL, &i, &err);
820     error_free_or_abort(&err);
821
822     /* Make sure primitives and arrays cannot be confused */
823
824     v = visitor_input_test_init(data, "1");
825     visit_type_strList(v, NULL, &q, &err);
826     error_free_or_abort(&err);
827     assert(!q);
828
829     v = visitor_input_test_init(data, "[]");
830     visit_type_int(v, NULL, &i, &err);
831     error_free_or_abort(&err);
832 }
833
834 int main(int argc, char **argv)
835 {
836     TestInputVisitorData in_visitor_data;
837
838     g_test_init(&argc, &argv, NULL);
839
840     input_visitor_test_add("/visitor/input/int",
841                            &in_visitor_data, test_visitor_in_int);
842     input_visitor_test_add("/visitor/input/int_overflow",
843                            &in_visitor_data, test_visitor_in_int_overflow);
844     input_visitor_test_add("/visitor/input/bool",
845                            &in_visitor_data, test_visitor_in_bool);
846     input_visitor_test_add("/visitor/input/number",
847                            &in_visitor_data, test_visitor_in_number);
848     input_visitor_test_add("/visitor/input/string",
849                            &in_visitor_data, test_visitor_in_string);
850     input_visitor_test_add("/visitor/input/enum",
851                            &in_visitor_data, test_visitor_in_enum);
852     input_visitor_test_add("/visitor/input/struct",
853                            &in_visitor_data, test_visitor_in_struct);
854     input_visitor_test_add("/visitor/input/struct-nested",
855                            &in_visitor_data, test_visitor_in_struct_nested);
856     input_visitor_test_add("/visitor/input/list",
857                            &in_visitor_data, test_visitor_in_list);
858     input_visitor_test_add("/visitor/input/any",
859                            &in_visitor_data, test_visitor_in_any);
860     input_visitor_test_add("/visitor/input/null",
861                            &in_visitor_data, test_visitor_in_null);
862     input_visitor_test_add("/visitor/input/union-flat",
863                            &in_visitor_data, test_visitor_in_union_flat);
864     input_visitor_test_add("/visitor/input/alternate",
865                            &in_visitor_data, test_visitor_in_alternate);
866     input_visitor_test_add("/visitor/input/errors",
867                            &in_visitor_data, test_visitor_in_errors);
868     input_visitor_test_add("/visitor/input/wrong-type",
869                            &in_visitor_data, test_visitor_in_wrong_type);
870     input_visitor_test_add("/visitor/input/alternate-number",
871                            &in_visitor_data, test_visitor_in_alternate_number);
872     input_visitor_test_add("/visitor/input/native_list/int",
873                            &in_visitor_data,
874                            test_visitor_in_native_list_int);
875     input_visitor_test_add("/visitor/input/native_list/int8",
876                            &in_visitor_data,
877                            test_visitor_in_native_list_int8);
878     input_visitor_test_add("/visitor/input/native_list/int16",
879                            &in_visitor_data,
880                            test_visitor_in_native_list_int16);
881     input_visitor_test_add("/visitor/input/native_list/int32",
882                            &in_visitor_data,
883                            test_visitor_in_native_list_int32);
884     input_visitor_test_add("/visitor/input/native_list/int64",
885                            &in_visitor_data,
886                            test_visitor_in_native_list_int64);
887     input_visitor_test_add("/visitor/input/native_list/uint8",
888                            &in_visitor_data,
889                            test_visitor_in_native_list_uint8);
890     input_visitor_test_add("/visitor/input/native_list/uint16",
891                            &in_visitor_data,
892                            test_visitor_in_native_list_uint16);
893     input_visitor_test_add("/visitor/input/native_list/uint32",
894                            &in_visitor_data,
895                            test_visitor_in_native_list_uint32);
896     input_visitor_test_add("/visitor/input/native_list/uint64",
897                            &in_visitor_data,
898                            test_visitor_in_native_list_uint64);
899     input_visitor_test_add("/visitor/input/native_list/bool",
900                            &in_visitor_data, test_visitor_in_native_list_bool);
901     input_visitor_test_add("/visitor/input/native_list/str",
902                            &in_visitor_data,
903                            test_visitor_in_native_list_string);
904     input_visitor_test_add("/visitor/input/native_list/number",
905                            &in_visitor_data,
906                            test_visitor_in_native_list_number);
907
908     g_test_run();
909
910     return 0;
911 }
This page took 0.077638 seconds and 4 git commands to generate.