xref: /qemu/tests/unit/test-qobject-input-visitor.c (revision 9b4e38fe6a35890bb1d995316d7be08de0b30ee5)
1d88f5fd1SLuiz Capitulino /*
2d88f5fd1SLuiz Capitulino  * QMP Input Visitor unit-tests.
3d88f5fd1SLuiz Capitulino  *
468d07839SEric Blake  * Copyright (C) 2011-2016 Red Hat Inc.
5d88f5fd1SLuiz Capitulino  *
6d88f5fd1SLuiz Capitulino  * Authors:
7d88f5fd1SLuiz Capitulino  *  Luiz Capitulino <lcapitulino@redhat.com>
8d88f5fd1SLuiz Capitulino  *
9d88f5fd1SLuiz Capitulino  * This work is licensed under the terms of the GNU GPL, version 2 or later.
10d88f5fd1SLuiz Capitulino  * See the COPYING file in the top-level directory.
11d88f5fd1SLuiz Capitulino  */
12d88f5fd1SLuiz Capitulino 
13681c28a3SPeter Maydell #include "qemu/osdep.h"
14d88f5fd1SLuiz Capitulino 
1579ee7df8SPaolo Bonzini #include "qemu-common.h"
16da34e65cSMarkus Armbruster #include "qapi/error.h"
17d88f5fd1SLuiz Capitulino #include "qapi/qmp-input-visitor.h"
18d88f5fd1SLuiz Capitulino #include "test-qapi-types.h"
19d88f5fd1SLuiz Capitulino #include "test-qapi-visit.h"
207b1b5d19SPaolo Bonzini #include "qapi/qmp/types.h"
21d88f5fd1SLuiz Capitulino 
22d88f5fd1SLuiz Capitulino typedef struct TestInputVisitorData {
23d88f5fd1SLuiz Capitulino     QObject *obj;
24d88f5fd1SLuiz Capitulino     QmpInputVisitor *qiv;
25d88f5fd1SLuiz Capitulino } TestInputVisitorData;
26d88f5fd1SLuiz Capitulino 
27d88f5fd1SLuiz Capitulino static void visitor_input_teardown(TestInputVisitorData *data,
28d88f5fd1SLuiz Capitulino                                    const void *unused)
29d88f5fd1SLuiz Capitulino {
30d88f5fd1SLuiz Capitulino     qobject_decref(data->obj);
31d88f5fd1SLuiz Capitulino     data->obj = NULL;
32d88f5fd1SLuiz Capitulino 
33d88f5fd1SLuiz Capitulino     if (data->qiv) {
34d88f5fd1SLuiz Capitulino         qmp_input_visitor_cleanup(data->qiv);
35d88f5fd1SLuiz Capitulino         data->qiv = NULL;
36d88f5fd1SLuiz Capitulino     }
37d88f5fd1SLuiz Capitulino }
38d88f5fd1SLuiz Capitulino 
390920a171SEric Blake /* The various test_init functions are provided instead of a test setup
400920a171SEric Blake    function so that the JSON string used by the tests are kept in the test
410920a171SEric Blake    functions (and not in main()). */
420920a171SEric Blake static Visitor *visitor_input_test_init_internal(TestInputVisitorData *data,
430920a171SEric Blake                                                  const char *json_string,
440920a171SEric Blake                                                  va_list *ap)
450920a171SEric Blake {
460920a171SEric Blake     Visitor *v;
470920a171SEric Blake 
48b18f1141SEric Blake     visitor_input_teardown(data, NULL);
49b18f1141SEric Blake 
500920a171SEric Blake     data->obj = qobject_from_jsonv(json_string, ap);
510920a171SEric Blake     g_assert(data->obj);
520920a171SEric Blake 
53fc471c18SEric Blake     data->qiv = qmp_input_visitor_new(data->obj, false);
540920a171SEric Blake     g_assert(data->qiv);
550920a171SEric Blake 
560920a171SEric Blake     v = qmp_input_get_visitor(data->qiv);
570920a171SEric Blake     g_assert(v);
580920a171SEric Blake 
590920a171SEric Blake     return v;
600920a171SEric Blake }
610920a171SEric Blake 
62aba2107aSStefan Weil static GCC_FMT_ATTR(2, 3)
63aba2107aSStefan Weil Visitor *visitor_input_test_init(TestInputVisitorData *data,
64d88f5fd1SLuiz Capitulino                                  const char *json_string, ...)
65d88f5fd1SLuiz Capitulino {
66d88f5fd1SLuiz Capitulino     Visitor *v;
67d88f5fd1SLuiz Capitulino     va_list ap;
68d88f5fd1SLuiz Capitulino 
69d88f5fd1SLuiz Capitulino     va_start(ap, json_string);
700920a171SEric Blake     v = visitor_input_test_init_internal(data, json_string, &ap);
71d88f5fd1SLuiz Capitulino     va_end(ap);
72d88f5fd1SLuiz Capitulino     return v;
73d88f5fd1SLuiz Capitulino }
74d88f5fd1SLuiz Capitulino 
75199e0f17SMichael Roth /* similar to visitor_input_test_init(), but does not expect a string
76199e0f17SMichael Roth  * literal/format json_string argument and so can be used for
77199e0f17SMichael Roth  * programatically generated strings (and we can't pass in programatically
78199e0f17SMichael Roth  * generated strings via %s format parameters since qobject_from_jsonv()
79199e0f17SMichael Roth  * will wrap those in double-quotes and treat the entire object as a
80199e0f17SMichael Roth  * string)
81199e0f17SMichael Roth  */
82199e0f17SMichael Roth static Visitor *visitor_input_test_init_raw(TestInputVisitorData *data,
83199e0f17SMichael Roth                                             const char *json_string)
84199e0f17SMichael Roth {
850920a171SEric Blake     return visitor_input_test_init_internal(data, json_string, NULL);
86199e0f17SMichael Roth }
87199e0f17SMichael Roth 
88d88f5fd1SLuiz Capitulino static void test_visitor_in_int(TestInputVisitorData *data,
89d88f5fd1SLuiz Capitulino                                 const void *unused)
90d88f5fd1SLuiz Capitulino {
91d88f5fd1SLuiz Capitulino     int64_t res = 0, value = -42;
92d88f5fd1SLuiz Capitulino     Visitor *v;
93d88f5fd1SLuiz Capitulino 
94aba2107aSStefan Weil     v = visitor_input_test_init(data, "%" PRId64, value);
95d88f5fd1SLuiz Capitulino 
9651e72bc1SEric Blake     visit_type_int(v, NULL, &res, &error_abort);
97d88f5fd1SLuiz Capitulino     g_assert_cmpint(res, ==, value);
98d88f5fd1SLuiz Capitulino }
99d88f5fd1SLuiz Capitulino 
100e92cfa0dSMichael Roth static void test_visitor_in_int_overflow(TestInputVisitorData *data,
101e92cfa0dSMichael Roth                                          const void *unused)
102e92cfa0dSMichael Roth {
103e92cfa0dSMichael Roth     int64_t res = 0;
104e940f543SMarkus Armbruster     Error *err = NULL;
105e92cfa0dSMichael Roth     Visitor *v;
106e92cfa0dSMichael Roth 
107e92cfa0dSMichael Roth     /* this will overflow a Qint/int64, so should be deserialized into
108e92cfa0dSMichael Roth      * a QFloat/double field instead, leading to an error if we pass it
109e92cfa0dSMichael Roth      * to visit_type_int. confirm this.
110e92cfa0dSMichael Roth      */
111e92cfa0dSMichael Roth     v = visitor_input_test_init(data, "%f", DBL_MAX);
112e92cfa0dSMichael Roth 
11351e72bc1SEric Blake     visit_type_int(v, NULL, &res, &err);
114a12a5a1aSEric Blake     error_free_or_abort(&err);
115e92cfa0dSMichael Roth }
116e92cfa0dSMichael Roth 
117d88f5fd1SLuiz Capitulino static void test_visitor_in_bool(TestInputVisitorData *data,
118d88f5fd1SLuiz Capitulino                                  const void *unused)
119d88f5fd1SLuiz Capitulino {
120d88f5fd1SLuiz Capitulino     bool res = false;
121d88f5fd1SLuiz Capitulino     Visitor *v;
122d88f5fd1SLuiz Capitulino 
123d88f5fd1SLuiz Capitulino     v = visitor_input_test_init(data, "true");
124d88f5fd1SLuiz Capitulino 
12551e72bc1SEric Blake     visit_type_bool(v, NULL, &res, &error_abort);
126d88f5fd1SLuiz Capitulino     g_assert_cmpint(res, ==, true);
127d88f5fd1SLuiz Capitulino }
128d88f5fd1SLuiz Capitulino 
129d88f5fd1SLuiz Capitulino static void test_visitor_in_number(TestInputVisitorData *data,
130d88f5fd1SLuiz Capitulino                                    const void *unused)
131d88f5fd1SLuiz Capitulino {
132d88f5fd1SLuiz Capitulino     double res = 0, value = 3.14;
133d88f5fd1SLuiz Capitulino     Visitor *v;
134d88f5fd1SLuiz Capitulino 
135d88f5fd1SLuiz Capitulino     v = visitor_input_test_init(data, "%f", value);
136d88f5fd1SLuiz Capitulino 
13751e72bc1SEric Blake     visit_type_number(v, NULL, &res, &error_abort);
138d88f5fd1SLuiz Capitulino     g_assert_cmpfloat(res, ==, value);
139d88f5fd1SLuiz Capitulino }
140d88f5fd1SLuiz Capitulino 
141d88f5fd1SLuiz Capitulino static void test_visitor_in_string(TestInputVisitorData *data,
142d88f5fd1SLuiz Capitulino                                    const void *unused)
143d88f5fd1SLuiz Capitulino {
144d88f5fd1SLuiz Capitulino     char *res = NULL, *value = (char *) "Q E M U";
145d88f5fd1SLuiz Capitulino     Visitor *v;
146d88f5fd1SLuiz Capitulino 
147d88f5fd1SLuiz Capitulino     v = visitor_input_test_init(data, "%s", value);
148d88f5fd1SLuiz Capitulino 
14951e72bc1SEric Blake     visit_type_str(v, NULL, &res, &error_abort);
150d88f5fd1SLuiz Capitulino     g_assert_cmpstr(res, ==, value);
151d88f5fd1SLuiz Capitulino 
152d88f5fd1SLuiz Capitulino     g_free(res);
153d88f5fd1SLuiz Capitulino }
154d88f5fd1SLuiz Capitulino 
155d88f5fd1SLuiz Capitulino static void test_visitor_in_enum(TestInputVisitorData *data,
156d88f5fd1SLuiz Capitulino                                  const void *unused)
157d88f5fd1SLuiz Capitulino {
158d88f5fd1SLuiz Capitulino     Visitor *v;
159d88f5fd1SLuiz Capitulino     EnumOne i;
160d88f5fd1SLuiz Capitulino 
161d88f5fd1SLuiz Capitulino     for (i = 0; EnumOne_lookup[i]; i++) {
162d88f5fd1SLuiz Capitulino         EnumOne res = -1;
163d88f5fd1SLuiz Capitulino 
164d88f5fd1SLuiz Capitulino         v = visitor_input_test_init(data, "%s", EnumOne_lookup[i]);
165d88f5fd1SLuiz Capitulino 
16651e72bc1SEric Blake         visit_type_EnumOne(v, NULL, &res, &error_abort);
167d88f5fd1SLuiz Capitulino         g_assert_cmpint(i, ==, res);
168d88f5fd1SLuiz Capitulino     }
169d88f5fd1SLuiz Capitulino }
170d88f5fd1SLuiz Capitulino 
171d88f5fd1SLuiz Capitulino 
172d88f5fd1SLuiz Capitulino static void test_visitor_in_struct(TestInputVisitorData *data,
173d88f5fd1SLuiz Capitulino                                    const void *unused)
174d88f5fd1SLuiz Capitulino {
175d88f5fd1SLuiz Capitulino     TestStruct *p = NULL;
176d88f5fd1SLuiz Capitulino     Visitor *v;
177d88f5fd1SLuiz Capitulino 
178d88f5fd1SLuiz Capitulino     v = visitor_input_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo' }");
179d88f5fd1SLuiz Capitulino 
18051e72bc1SEric Blake     visit_type_TestStruct(v, NULL, &p, &error_abort);
181d88f5fd1SLuiz Capitulino     g_assert_cmpint(p->integer, ==, -42);
182d88f5fd1SLuiz Capitulino     g_assert(p->boolean == true);
183d88f5fd1SLuiz Capitulino     g_assert_cmpstr(p->string, ==, "foo");
184d88f5fd1SLuiz Capitulino 
185d88f5fd1SLuiz Capitulino     g_free(p->string);
186d88f5fd1SLuiz Capitulino     g_free(p);
187d88f5fd1SLuiz Capitulino }
188d88f5fd1SLuiz Capitulino 
189d88f5fd1SLuiz Capitulino static void test_visitor_in_struct_nested(TestInputVisitorData *data,
190d88f5fd1SLuiz Capitulino                                           const void *unused)
191d88f5fd1SLuiz Capitulino {
192b6fcf32dSEric Blake     UserDefTwo *udp = NULL;
193d88f5fd1SLuiz Capitulino     Visitor *v;
194d88f5fd1SLuiz Capitulino 
195b6fcf32dSEric Blake     v = visitor_input_test_init(data, "{ 'string0': 'string0', "
196b6fcf32dSEric Blake                                 "'dict1': { 'string1': 'string1', "
197b6fcf32dSEric Blake                                 "'dict2': { 'userdef': { 'integer': 42, "
198b6fcf32dSEric Blake                                 "'string': 'string' }, 'string': 'string2'}}}");
199d88f5fd1SLuiz Capitulino 
20051e72bc1SEric Blake     visit_type_UserDefTwo(v, NULL, &udp, &error_abort);
201d88f5fd1SLuiz Capitulino 
202b18f1141SEric Blake     g_assert_cmpstr(udp->string0, ==, "string0");
203b18f1141SEric Blake     g_assert_cmpstr(udp->dict1->string1, ==, "string1");
204ddf21908SEric Blake     g_assert_cmpint(udp->dict1->dict2->userdef->integer, ==, 42);
205b18f1141SEric Blake     g_assert_cmpstr(udp->dict1->dict2->userdef->string, ==, "string");
206b18f1141SEric Blake     g_assert_cmpstr(udp->dict1->dict2->string, ==, "string2");
2076446a592SEric Blake     g_assert(udp->dict1->has_dict3 == false);
208d88f5fd1SLuiz Capitulino 
209b18f1141SEric Blake     qapi_free_UserDefTwo(udp);
210d88f5fd1SLuiz Capitulino }
211d88f5fd1SLuiz Capitulino 
212d88f5fd1SLuiz Capitulino static void test_visitor_in_list(TestInputVisitorData *data,
213d88f5fd1SLuiz Capitulino                                  const void *unused)
214d88f5fd1SLuiz Capitulino {
215d88f5fd1SLuiz Capitulino     UserDefOneList *item, *head = NULL;
216d88f5fd1SLuiz Capitulino     Visitor *v;
217d88f5fd1SLuiz Capitulino     int i;
218d88f5fd1SLuiz Capitulino 
219d88f5fd1SLuiz Capitulino     v = visitor_input_test_init(data, "[ { 'string': 'string0', 'integer': 42 }, { 'string': 'string1', 'integer': 43 }, { 'string': 'string2', 'integer': 44 } ]");
220d88f5fd1SLuiz Capitulino 
22151e72bc1SEric Blake     visit_type_UserDefOneList(v, NULL, &head, &error_abort);
222d88f5fd1SLuiz Capitulino     g_assert(head != NULL);
223d88f5fd1SLuiz Capitulino 
224d88f5fd1SLuiz Capitulino     for (i = 0, item = head; item; item = item->next, i++) {
225d88f5fd1SLuiz Capitulino         char string[12];
226d88f5fd1SLuiz Capitulino 
227d88f5fd1SLuiz Capitulino         snprintf(string, sizeof(string), "string%d", i);
228d88f5fd1SLuiz Capitulino         g_assert_cmpstr(item->value->string, ==, string);
229ddf21908SEric Blake         g_assert_cmpint(item->value->integer, ==, 42 + i);
230d88f5fd1SLuiz Capitulino     }
231d88f5fd1SLuiz Capitulino 
232d88f5fd1SLuiz Capitulino     qapi_free_UserDefOneList(head);
2332533377cSEric Blake     head = NULL;
2342533377cSEric Blake 
2352533377cSEric Blake     /* An empty list is valid */
2362533377cSEric Blake     v = visitor_input_test_init(data, "[]");
23751e72bc1SEric Blake     visit_type_UserDefOneList(v, NULL, &head, &error_abort);
2382533377cSEric Blake     g_assert(!head);
239d88f5fd1SLuiz Capitulino }
240d88f5fd1SLuiz Capitulino 
24128770e05SMarkus Armbruster static void test_visitor_in_any(TestInputVisitorData *data,
24228770e05SMarkus Armbruster                                 const void *unused)
24328770e05SMarkus Armbruster {
24428770e05SMarkus Armbruster     QObject *res = NULL;
24528770e05SMarkus Armbruster     Visitor *v;
24628770e05SMarkus Armbruster     QInt *qint;
24728770e05SMarkus Armbruster     QBool *qbool;
24828770e05SMarkus Armbruster     QString *qstring;
24928770e05SMarkus Armbruster     QDict *qdict;
25028770e05SMarkus Armbruster     QObject *qobj;
25128770e05SMarkus Armbruster 
25228770e05SMarkus Armbruster     v = visitor_input_test_init(data, "-42");
25351e72bc1SEric Blake     visit_type_any(v, NULL, &res, &error_abort);
25428770e05SMarkus Armbruster     qint = qobject_to_qint(res);
25528770e05SMarkus Armbruster     g_assert(qint);
25628770e05SMarkus Armbruster     g_assert_cmpint(qint_get_int(qint), ==, -42);
25728770e05SMarkus Armbruster     qobject_decref(res);
25828770e05SMarkus Armbruster 
25928770e05SMarkus Armbruster     v = visitor_input_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo' }");
26051e72bc1SEric Blake     visit_type_any(v, NULL, &res, &error_abort);
26128770e05SMarkus Armbruster     qdict = qobject_to_qdict(res);
26228770e05SMarkus Armbruster     g_assert(qdict && qdict_size(qdict) == 3);
26328770e05SMarkus Armbruster     qobj = qdict_get(qdict, "integer");
26428770e05SMarkus Armbruster     g_assert(qobj);
26528770e05SMarkus Armbruster     qint = qobject_to_qint(qobj);
26628770e05SMarkus Armbruster     g_assert(qint);
26728770e05SMarkus Armbruster     g_assert_cmpint(qint_get_int(qint), ==, -42);
26828770e05SMarkus Armbruster     qobj = qdict_get(qdict, "boolean");
26928770e05SMarkus Armbruster     g_assert(qobj);
27028770e05SMarkus Armbruster     qbool = qobject_to_qbool(qobj);
27128770e05SMarkus Armbruster     g_assert(qbool);
27228770e05SMarkus Armbruster     g_assert(qbool_get_bool(qbool) == true);
27328770e05SMarkus Armbruster     qobj = qdict_get(qdict, "string");
27428770e05SMarkus Armbruster     g_assert(qobj);
27528770e05SMarkus Armbruster     qstring = qobject_to_qstring(qobj);
27628770e05SMarkus Armbruster     g_assert(qstring);
27728770e05SMarkus Armbruster     g_assert_cmpstr(qstring_get_str(qstring), ==, "foo");
27828770e05SMarkus Armbruster     qobject_decref(res);
27928770e05SMarkus Armbruster }
28028770e05SMarkus Armbruster 
2813df016f1SEric Blake static void test_visitor_in_null(TestInputVisitorData *data,
2823df016f1SEric Blake                                  const void *unused)
2833df016f1SEric Blake {
2843df016f1SEric Blake     Visitor *v;
2853df016f1SEric Blake     Error *err = NULL;
2863df016f1SEric Blake     char *tmp;
2873df016f1SEric Blake 
2883df016f1SEric Blake     /*
2893df016f1SEric Blake      * FIXME: Since QAPI doesn't know the 'null' type yet, we can't
2903df016f1SEric Blake      * test visit_type_null() by reading into a QAPI struct then
2913df016f1SEric Blake      * checking that it was populated correctly.  The best we can do
2923df016f1SEric Blake      * for now is ensure that we consumed null from the input, proven
2933df016f1SEric Blake      * by the fact that we can't re-read the key; and that we detect
2943df016f1SEric Blake      * when input is not null.
2953df016f1SEric Blake      */
2963df016f1SEric Blake 
2973df016f1SEric Blake     v = visitor_input_test_init(data, "{ 'a': null, 'b': '' }");
2983df016f1SEric Blake     visit_start_struct(v, NULL, NULL, 0, &error_abort);
2993df016f1SEric Blake     visit_type_null(v, "a", &error_abort);
3003df016f1SEric Blake     visit_type_str(v, "a", &tmp, &err);
3013df016f1SEric Blake     g_assert(!tmp);
3023df016f1SEric Blake     error_free_or_abort(&err);
3033df016f1SEric Blake     visit_type_null(v, "b", &err);
3043df016f1SEric Blake     error_free_or_abort(&err);
30515c2f669SEric Blake     visit_check_struct(v, &error_abort);
30615c2f669SEric Blake     visit_end_struct(v);
3073df016f1SEric Blake }
3083df016f1SEric Blake 
3092fc00432SMarkus Armbruster static void test_visitor_in_union_flat(TestInputVisitorData *data,
3102fc00432SMarkus Armbruster                                        const void *unused)
3112fc00432SMarkus Armbruster {
3122fc00432SMarkus Armbruster     Visitor *v;
3132fc00432SMarkus Armbruster     UserDefFlatUnion *tmp;
31430594fe1SEric Blake     UserDefUnionBase *base;
3152fc00432SMarkus Armbruster 
3165223070cSWenchao Xia     v = visitor_input_test_init(data,
3175223070cSWenchao Xia                                 "{ 'enum1': 'value1', "
318441cbac0SMarkus Armbruster                                 "'integer': 41, "
3195223070cSWenchao Xia                                 "'string': 'str', "
3205223070cSWenchao Xia                                 "'boolean': true }");
3212fc00432SMarkus Armbruster 
32251e72bc1SEric Blake     visit_type_UserDefFlatUnion(v, NULL, &tmp, &error_abort);
3230f61af3eSMarkus Armbruster     g_assert_cmpint(tmp->enum1, ==, ENUM_ONE_VALUE1);
3245223070cSWenchao Xia     g_assert_cmpstr(tmp->string, ==, "str");
325441cbac0SMarkus Armbruster     g_assert_cmpint(tmp->integer, ==, 41);
326544a3731SEric Blake     g_assert_cmpint(tmp->u.value1.boolean, ==, true);
32730594fe1SEric Blake 
32830594fe1SEric Blake     base = qapi_UserDefFlatUnion_base(tmp);
32930594fe1SEric Blake     g_assert(&base->enum1 == &tmp->enum1);
33030594fe1SEric Blake 
3312fc00432SMarkus Armbruster     qapi_free_UserDefFlatUnion(tmp);
3322fc00432SMarkus Armbruster }
3332fc00432SMarkus Armbruster 
334ab045267SEric Blake static void test_visitor_in_alternate(TestInputVisitorData *data,
3352c38b600SMarkus Armbruster                                       const void *unused)
3362c38b600SMarkus Armbruster {
3372c38b600SMarkus Armbruster     Visitor *v;
3382c38b600SMarkus Armbruster     Error *err = NULL;
339ab045267SEric Blake     UserDefAlternate *tmp;
34068d07839SEric Blake     WrapAlternate *wrap;
3412c38b600SMarkus Armbruster 
3422c38b600SMarkus Armbruster     v = visitor_input_test_init(data, "42");
34351e72bc1SEric Blake     visit_type_UserDefAlternate(v, NULL, &tmp, &error_abort);
3440426d53cSEric Blake     g_assert_cmpint(tmp->type, ==, QTYPE_QINT);
345c363acefSEric Blake     g_assert_cmpint(tmp->u.i, ==, 42);
346ab045267SEric Blake     qapi_free_UserDefAlternate(tmp);
3479c51b441SEric Blake 
3489c51b441SEric Blake     v = visitor_input_test_init(data, "'string'");
34951e72bc1SEric Blake     visit_type_UserDefAlternate(v, NULL, &tmp, &error_abort);
3500426d53cSEric Blake     g_assert_cmpint(tmp->type, ==, QTYPE_QSTRING);
351c363acefSEric Blake     g_assert_cmpstr(tmp->u.s, ==, "string");
3529c51b441SEric Blake     qapi_free_UserDefAlternate(tmp);
3539c51b441SEric Blake 
35468d07839SEric Blake     v = visitor_input_test_init(data, "{'integer':1, 'string':'str', "
35568d07839SEric Blake                                 "'enum1':'value1', 'boolean':true}");
35668d07839SEric Blake     visit_type_UserDefAlternate(v, NULL, &tmp, &error_abort);
35768d07839SEric Blake     g_assert_cmpint(tmp->type, ==, QTYPE_QDICT);
358becceedcSEric Blake     g_assert_cmpint(tmp->u.udfu.integer, ==, 1);
359becceedcSEric Blake     g_assert_cmpstr(tmp->u.udfu.string, ==, "str");
360becceedcSEric Blake     g_assert_cmpint(tmp->u.udfu.enum1, ==, ENUM_ONE_VALUE1);
361544a3731SEric Blake     g_assert_cmpint(tmp->u.udfu.u.value1.boolean, ==, true);
362544a3731SEric Blake     g_assert_cmpint(tmp->u.udfu.u.value1.has_a_b, ==, false);
36368d07839SEric Blake     qapi_free_UserDefAlternate(tmp);
36468d07839SEric Blake 
3659c51b441SEric Blake     v = visitor_input_test_init(data, "false");
36651e72bc1SEric Blake     visit_type_UserDefAlternate(v, NULL, &tmp, &err);
367a12a5a1aSEric Blake     error_free_or_abort(&err);
3689c51b441SEric Blake     qapi_free_UserDefAlternate(tmp);
36968d07839SEric Blake 
37068d07839SEric Blake     v = visitor_input_test_init(data, "{ 'alt': 42 }");
37168d07839SEric Blake     visit_type_WrapAlternate(v, NULL, &wrap, &error_abort);
37268d07839SEric Blake     g_assert_cmpint(wrap->alt->type, ==, QTYPE_QINT);
37368d07839SEric Blake     g_assert_cmpint(wrap->alt->u.i, ==, 42);
37468d07839SEric Blake     qapi_free_WrapAlternate(wrap);
37568d07839SEric Blake 
37668d07839SEric Blake     v = visitor_input_test_init(data, "{ 'alt': 'string' }");
37768d07839SEric Blake     visit_type_WrapAlternate(v, NULL, &wrap, &error_abort);
37868d07839SEric Blake     g_assert_cmpint(wrap->alt->type, ==, QTYPE_QSTRING);
37968d07839SEric Blake     g_assert_cmpstr(wrap->alt->u.s, ==, "string");
38068d07839SEric Blake     qapi_free_WrapAlternate(wrap);
38168d07839SEric Blake 
38268d07839SEric Blake     v = visitor_input_test_init(data, "{ 'alt': {'integer':1, 'string':'str', "
38368d07839SEric Blake                                 "'enum1':'value1', 'boolean':true} }");
38468d07839SEric Blake     visit_type_WrapAlternate(v, NULL, &wrap, &error_abort);
38568d07839SEric Blake     g_assert_cmpint(wrap->alt->type, ==, QTYPE_QDICT);
386becceedcSEric Blake     g_assert_cmpint(wrap->alt->u.udfu.integer, ==, 1);
387becceedcSEric Blake     g_assert_cmpstr(wrap->alt->u.udfu.string, ==, "str");
388becceedcSEric Blake     g_assert_cmpint(wrap->alt->u.udfu.enum1, ==, ENUM_ONE_VALUE1);
389544a3731SEric Blake     g_assert_cmpint(wrap->alt->u.udfu.u.value1.boolean, ==, true);
390544a3731SEric Blake     g_assert_cmpint(wrap->alt->u.udfu.u.value1.has_a_b, ==, false);
39168d07839SEric Blake     qapi_free_WrapAlternate(wrap);
3929c51b441SEric Blake }
3939c51b441SEric Blake 
3949c51b441SEric Blake static void test_visitor_in_alternate_number(TestInputVisitorData *data,
3959c51b441SEric Blake                                              const void *unused)
3969c51b441SEric Blake {
3979c51b441SEric Blake     Visitor *v;
3989c51b441SEric Blake     Error *err = NULL;
3999c51b441SEric Blake     AltStrBool *asb;
4009c51b441SEric Blake     AltStrNum *asn;
4019c51b441SEric Blake     AltNumStr *ans;
4029c51b441SEric Blake     AltStrInt *asi;
4039c51b441SEric Blake     AltIntNum *ain;
4049c51b441SEric Blake     AltNumInt *ani;
4059c51b441SEric Blake 
4069c51b441SEric Blake     /* Parsing an int */
4079c51b441SEric Blake 
4089c51b441SEric Blake     v = visitor_input_test_init(data, "42");
40951e72bc1SEric Blake     visit_type_AltStrBool(v, NULL, &asb, &err);
410a12a5a1aSEric Blake     error_free_or_abort(&err);
4119c51b441SEric Blake     qapi_free_AltStrBool(asb);
4129c51b441SEric Blake 
4139c51b441SEric Blake     v = visitor_input_test_init(data, "42");
41451e72bc1SEric Blake     visit_type_AltStrNum(v, NULL, &asn, &error_abort);
415d00341afSEric Blake     g_assert_cmpint(asn->type, ==, QTYPE_QFLOAT);
416d00341afSEric Blake     g_assert_cmpfloat(asn->u.n, ==, 42);
4179c51b441SEric Blake     qapi_free_AltStrNum(asn);
4189c51b441SEric Blake 
4199c51b441SEric Blake     v = visitor_input_test_init(data, "42");
42051e72bc1SEric Blake     visit_type_AltNumStr(v, NULL, &ans, &error_abort);
421d00341afSEric Blake     g_assert_cmpint(ans->type, ==, QTYPE_QFLOAT);
422d00341afSEric Blake     g_assert_cmpfloat(ans->u.n, ==, 42);
4239c51b441SEric Blake     qapi_free_AltNumStr(ans);
4249c51b441SEric Blake 
4259c51b441SEric Blake     v = visitor_input_test_init(data, "42");
42651e72bc1SEric Blake     visit_type_AltStrInt(v, NULL, &asi, &error_abort);
4270426d53cSEric Blake     g_assert_cmpint(asi->type, ==, QTYPE_QINT);
428c363acefSEric Blake     g_assert_cmpint(asi->u.i, ==, 42);
4299c51b441SEric Blake     qapi_free_AltStrInt(asi);
4309c51b441SEric Blake 
4319c51b441SEric Blake     v = visitor_input_test_init(data, "42");
43251e72bc1SEric Blake     visit_type_AltIntNum(v, NULL, &ain, &error_abort);
4330426d53cSEric Blake     g_assert_cmpint(ain->type, ==, QTYPE_QINT);
434c363acefSEric Blake     g_assert_cmpint(ain->u.i, ==, 42);
4359c51b441SEric Blake     qapi_free_AltIntNum(ain);
4369c51b441SEric Blake 
4379c51b441SEric Blake     v = visitor_input_test_init(data, "42");
43851e72bc1SEric Blake     visit_type_AltNumInt(v, NULL, &ani, &error_abort);
4390426d53cSEric Blake     g_assert_cmpint(ani->type, ==, QTYPE_QINT);
440c363acefSEric Blake     g_assert_cmpint(ani->u.i, ==, 42);
4419c51b441SEric Blake     qapi_free_AltNumInt(ani);
4429c51b441SEric Blake 
4439c51b441SEric Blake     /* Parsing a double */
4449c51b441SEric Blake 
4459c51b441SEric Blake     v = visitor_input_test_init(data, "42.5");
44651e72bc1SEric Blake     visit_type_AltStrBool(v, NULL, &asb, &err);
447a12a5a1aSEric Blake     error_free_or_abort(&err);
4489c51b441SEric Blake     qapi_free_AltStrBool(asb);
4499c51b441SEric Blake 
4509c51b441SEric Blake     v = visitor_input_test_init(data, "42.5");
45151e72bc1SEric Blake     visit_type_AltStrNum(v, NULL, &asn, &error_abort);
4520426d53cSEric Blake     g_assert_cmpint(asn->type, ==, QTYPE_QFLOAT);
453c363acefSEric Blake     g_assert_cmpfloat(asn->u.n, ==, 42.5);
4549c51b441SEric Blake     qapi_free_AltStrNum(asn);
4559c51b441SEric Blake 
4569c51b441SEric Blake     v = visitor_input_test_init(data, "42.5");
45751e72bc1SEric Blake     visit_type_AltNumStr(v, NULL, &ans, &error_abort);
4580426d53cSEric Blake     g_assert_cmpint(ans->type, ==, QTYPE_QFLOAT);
459c363acefSEric Blake     g_assert_cmpfloat(ans->u.n, ==, 42.5);
4609c51b441SEric Blake     qapi_free_AltNumStr(ans);
4619c51b441SEric Blake 
4629c51b441SEric Blake     v = visitor_input_test_init(data, "42.5");
46351e72bc1SEric Blake     visit_type_AltStrInt(v, NULL, &asi, &err);
464a12a5a1aSEric Blake     error_free_or_abort(&err);
4659c51b441SEric Blake     qapi_free_AltStrInt(asi);
4669c51b441SEric Blake 
4679c51b441SEric Blake     v = visitor_input_test_init(data, "42.5");
46851e72bc1SEric Blake     visit_type_AltIntNum(v, NULL, &ain, &error_abort);
4690426d53cSEric Blake     g_assert_cmpint(ain->type, ==, QTYPE_QFLOAT);
470c363acefSEric Blake     g_assert_cmpfloat(ain->u.n, ==, 42.5);
4719c51b441SEric Blake     qapi_free_AltIntNum(ain);
4729c51b441SEric Blake 
4739c51b441SEric Blake     v = visitor_input_test_init(data, "42.5");
47451e72bc1SEric Blake     visit_type_AltNumInt(v, NULL, &ani, &error_abort);
4750426d53cSEric Blake     g_assert_cmpint(ani->type, ==, QTYPE_QFLOAT);
476c363acefSEric Blake     g_assert_cmpfloat(ani->u.n, ==, 42.5);
4779c51b441SEric Blake     qapi_free_AltNumInt(ani);
4782c38b600SMarkus Armbruster }
4792c38b600SMarkus Armbruster 
480199e0f17SMichael Roth static void test_native_list_integer_helper(TestInputVisitorData *data,
481199e0f17SMichael Roth                                             const void *unused,
482199e0f17SMichael Roth                                             UserDefNativeListUnionKind kind)
483199e0f17SMichael Roth {
484199e0f17SMichael Roth     UserDefNativeListUnion *cvalue = NULL;
485199e0f17SMichael Roth     Visitor *v;
486199e0f17SMichael Roth     GString *gstr_list = g_string_new("");
487199e0f17SMichael Roth     GString *gstr_union = g_string_new("");
488199e0f17SMichael Roth     int i;
489199e0f17SMichael Roth 
490199e0f17SMichael Roth     for (i = 0; i < 32; i++) {
491199e0f17SMichael Roth         g_string_append_printf(gstr_list, "%d", i);
492199e0f17SMichael Roth         if (i != 31) {
493199e0f17SMichael Roth             g_string_append(gstr_list, ", ");
494199e0f17SMichael Roth         }
495199e0f17SMichael Roth     }
496199e0f17SMichael Roth     g_string_append_printf(gstr_union,  "{ 'type': '%s', 'data': [ %s ] }",
497199e0f17SMichael Roth                            UserDefNativeListUnionKind_lookup[kind],
498199e0f17SMichael Roth                            gstr_list->str);
499199e0f17SMichael Roth     v = visitor_input_test_init_raw(data,  gstr_union->str);
500199e0f17SMichael Roth 
50151e72bc1SEric Blake     visit_type_UserDefNativeListUnion(v, NULL, &cvalue, &error_abort);
502199e0f17SMichael Roth     g_assert(cvalue != NULL);
503c363acefSEric Blake     g_assert_cmpint(cvalue->type, ==, kind);
504199e0f17SMichael Roth 
505199e0f17SMichael Roth     switch (kind) {
506199e0f17SMichael Roth     case USER_DEF_NATIVE_LIST_UNION_KIND_INTEGER: {
507199e0f17SMichael Roth         intList *elem = NULL;
50832bafa8fSEric Blake         for (i = 0, elem = cvalue->u.integer.data;
50932bafa8fSEric Blake              elem; elem = elem->next, i++) {
510199e0f17SMichael Roth             g_assert_cmpint(elem->value, ==, i);
511199e0f17SMichael Roth         }
512199e0f17SMichael Roth         break;
513199e0f17SMichael Roth     }
514199e0f17SMichael Roth     case USER_DEF_NATIVE_LIST_UNION_KIND_S8: {
515199e0f17SMichael Roth         int8List *elem = NULL;
51632bafa8fSEric Blake         for (i = 0, elem = cvalue->u.s8.data; elem; elem = elem->next, i++) {
517199e0f17SMichael Roth             g_assert_cmpint(elem->value, ==, i);
518199e0f17SMichael Roth         }
519199e0f17SMichael Roth         break;
520199e0f17SMichael Roth     }
521199e0f17SMichael Roth     case USER_DEF_NATIVE_LIST_UNION_KIND_S16: {
522199e0f17SMichael Roth         int16List *elem = NULL;
52332bafa8fSEric Blake         for (i = 0, elem = cvalue->u.s16.data; elem; elem = elem->next, i++) {
524199e0f17SMichael Roth             g_assert_cmpint(elem->value, ==, i);
525199e0f17SMichael Roth         }
526199e0f17SMichael Roth         break;
527199e0f17SMichael Roth     }
528199e0f17SMichael Roth     case USER_DEF_NATIVE_LIST_UNION_KIND_S32: {
529199e0f17SMichael Roth         int32List *elem = NULL;
53032bafa8fSEric Blake         for (i = 0, elem = cvalue->u.s32.data; elem; elem = elem->next, i++) {
531199e0f17SMichael Roth             g_assert_cmpint(elem->value, ==, i);
532199e0f17SMichael Roth         }
533199e0f17SMichael Roth         break;
534199e0f17SMichael Roth     }
535199e0f17SMichael Roth     case USER_DEF_NATIVE_LIST_UNION_KIND_S64: {
536199e0f17SMichael Roth         int64List *elem = NULL;
53732bafa8fSEric Blake         for (i = 0, elem = cvalue->u.s64.data; elem; elem = elem->next, i++) {
538199e0f17SMichael Roth             g_assert_cmpint(elem->value, ==, i);
539199e0f17SMichael Roth         }
540199e0f17SMichael Roth         break;
541199e0f17SMichael Roth     }
542199e0f17SMichael Roth     case USER_DEF_NATIVE_LIST_UNION_KIND_U8: {
543199e0f17SMichael Roth         uint8List *elem = NULL;
54432bafa8fSEric Blake         for (i = 0, elem = cvalue->u.u8.data; elem; elem = elem->next, i++) {
545199e0f17SMichael Roth             g_assert_cmpint(elem->value, ==, i);
546199e0f17SMichael Roth         }
547199e0f17SMichael Roth         break;
548199e0f17SMichael Roth     }
549199e0f17SMichael Roth     case USER_DEF_NATIVE_LIST_UNION_KIND_U16: {
550199e0f17SMichael Roth         uint16List *elem = NULL;
55132bafa8fSEric Blake         for (i = 0, elem = cvalue->u.u16.data; elem; elem = elem->next, i++) {
552199e0f17SMichael Roth             g_assert_cmpint(elem->value, ==, i);
553199e0f17SMichael Roth         }
554199e0f17SMichael Roth         break;
555199e0f17SMichael Roth     }
556199e0f17SMichael Roth     case USER_DEF_NATIVE_LIST_UNION_KIND_U32: {
557199e0f17SMichael Roth         uint32List *elem = NULL;
55832bafa8fSEric Blake         for (i = 0, elem = cvalue->u.u32.data; elem; elem = elem->next, i++) {
559199e0f17SMichael Roth             g_assert_cmpint(elem->value, ==, i);
560199e0f17SMichael Roth         }
561199e0f17SMichael Roth         break;
562199e0f17SMichael Roth     }
563199e0f17SMichael Roth     case USER_DEF_NATIVE_LIST_UNION_KIND_U64: {
564199e0f17SMichael Roth         uint64List *elem = NULL;
56532bafa8fSEric Blake         for (i = 0, elem = cvalue->u.u64.data; elem; elem = elem->next, i++) {
566199e0f17SMichael Roth             g_assert_cmpint(elem->value, ==, i);
567199e0f17SMichael Roth         }
568199e0f17SMichael Roth         break;
569199e0f17SMichael Roth     }
570199e0f17SMichael Roth     default:
571dfc6f865SStefan Weil         g_assert_not_reached();
572199e0f17SMichael Roth     }
573199e0f17SMichael Roth 
574199e0f17SMichael Roth     g_string_free(gstr_union, true);
575199e0f17SMichael Roth     g_string_free(gstr_list, true);
576199e0f17SMichael Roth     qapi_free_UserDefNativeListUnion(cvalue);
577199e0f17SMichael Roth }
578199e0f17SMichael Roth 
579199e0f17SMichael Roth static void test_visitor_in_native_list_int(TestInputVisitorData *data,
580199e0f17SMichael Roth                                             const void *unused)
581199e0f17SMichael Roth {
582199e0f17SMichael Roth     test_native_list_integer_helper(data, unused,
583199e0f17SMichael Roth                                     USER_DEF_NATIVE_LIST_UNION_KIND_INTEGER);
584199e0f17SMichael Roth }
585199e0f17SMichael Roth 
586199e0f17SMichael Roth static void test_visitor_in_native_list_int8(TestInputVisitorData *data,
587199e0f17SMichael Roth                                              const void *unused)
588199e0f17SMichael Roth {
589199e0f17SMichael Roth     test_native_list_integer_helper(data, unused,
590199e0f17SMichael Roth                                     USER_DEF_NATIVE_LIST_UNION_KIND_S8);
591199e0f17SMichael Roth }
592199e0f17SMichael Roth 
593199e0f17SMichael Roth static void test_visitor_in_native_list_int16(TestInputVisitorData *data,
594199e0f17SMichael Roth                                               const void *unused)
595199e0f17SMichael Roth {
596199e0f17SMichael Roth     test_native_list_integer_helper(data, unused,
597199e0f17SMichael Roth                                     USER_DEF_NATIVE_LIST_UNION_KIND_S16);
598199e0f17SMichael Roth }
599199e0f17SMichael Roth 
600199e0f17SMichael Roth static void test_visitor_in_native_list_int32(TestInputVisitorData *data,
601199e0f17SMichael Roth                                               const void *unused)
602199e0f17SMichael Roth {
603199e0f17SMichael Roth     test_native_list_integer_helper(data, unused,
604199e0f17SMichael Roth                                     USER_DEF_NATIVE_LIST_UNION_KIND_S32);
605199e0f17SMichael Roth }
606199e0f17SMichael Roth 
607199e0f17SMichael Roth static void test_visitor_in_native_list_int64(TestInputVisitorData *data,
608199e0f17SMichael Roth                                               const void *unused)
609199e0f17SMichael Roth {
610199e0f17SMichael Roth     test_native_list_integer_helper(data, unused,
611199e0f17SMichael Roth                                     USER_DEF_NATIVE_LIST_UNION_KIND_S64);
612199e0f17SMichael Roth }
613199e0f17SMichael Roth 
614199e0f17SMichael Roth static void test_visitor_in_native_list_uint8(TestInputVisitorData *data,
615199e0f17SMichael Roth                                              const void *unused)
616199e0f17SMichael Roth {
617199e0f17SMichael Roth     test_native_list_integer_helper(data, unused,
618199e0f17SMichael Roth                                     USER_DEF_NATIVE_LIST_UNION_KIND_U8);
619199e0f17SMichael Roth }
620199e0f17SMichael Roth 
621199e0f17SMichael Roth static void test_visitor_in_native_list_uint16(TestInputVisitorData *data,
622199e0f17SMichael Roth                                                const void *unused)
623199e0f17SMichael Roth {
624199e0f17SMichael Roth     test_native_list_integer_helper(data, unused,
625199e0f17SMichael Roth                                     USER_DEF_NATIVE_LIST_UNION_KIND_U16);
626199e0f17SMichael Roth }
627199e0f17SMichael Roth 
628199e0f17SMichael Roth static void test_visitor_in_native_list_uint32(TestInputVisitorData *data,
629199e0f17SMichael Roth                                                const void *unused)
630199e0f17SMichael Roth {
631199e0f17SMichael Roth     test_native_list_integer_helper(data, unused,
632199e0f17SMichael Roth                                     USER_DEF_NATIVE_LIST_UNION_KIND_U32);
633199e0f17SMichael Roth }
634199e0f17SMichael Roth 
635199e0f17SMichael Roth static void test_visitor_in_native_list_uint64(TestInputVisitorData *data,
636199e0f17SMichael Roth                                                const void *unused)
637199e0f17SMichael Roth {
638199e0f17SMichael Roth     test_native_list_integer_helper(data, unused,
639199e0f17SMichael Roth                                     USER_DEF_NATIVE_LIST_UNION_KIND_U64);
640199e0f17SMichael Roth }
641199e0f17SMichael Roth 
642199e0f17SMichael Roth static void test_visitor_in_native_list_bool(TestInputVisitorData *data,
643199e0f17SMichael Roth                                             const void *unused)
644199e0f17SMichael Roth {
645199e0f17SMichael Roth     UserDefNativeListUnion *cvalue = NULL;
646199e0f17SMichael Roth     boolList *elem = NULL;
647199e0f17SMichael Roth     Visitor *v;
648199e0f17SMichael Roth     GString *gstr_list = g_string_new("");
649199e0f17SMichael Roth     GString *gstr_union = g_string_new("");
650199e0f17SMichael Roth     int i;
651199e0f17SMichael Roth 
652199e0f17SMichael Roth     for (i = 0; i < 32; i++) {
653199e0f17SMichael Roth         g_string_append_printf(gstr_list, "%s",
654199e0f17SMichael Roth                                (i % 3 == 0) ? "true" : "false");
655199e0f17SMichael Roth         if (i != 31) {
656199e0f17SMichael Roth             g_string_append(gstr_list, ", ");
657199e0f17SMichael Roth         }
658199e0f17SMichael Roth     }
659199e0f17SMichael Roth     g_string_append_printf(gstr_union,  "{ 'type': 'boolean', 'data': [ %s ] }",
660199e0f17SMichael Roth                            gstr_list->str);
661199e0f17SMichael Roth     v = visitor_input_test_init_raw(data,  gstr_union->str);
662199e0f17SMichael Roth 
66351e72bc1SEric Blake     visit_type_UserDefNativeListUnion(v, NULL, &cvalue, &error_abort);
664199e0f17SMichael Roth     g_assert(cvalue != NULL);
665c363acefSEric Blake     g_assert_cmpint(cvalue->type, ==, USER_DEF_NATIVE_LIST_UNION_KIND_BOOLEAN);
666199e0f17SMichael Roth 
66732bafa8fSEric Blake     for (i = 0, elem = cvalue->u.boolean.data; elem; elem = elem->next, i++) {
668199e0f17SMichael Roth         g_assert_cmpint(elem->value, ==, (i % 3 == 0) ? 1 : 0);
669199e0f17SMichael Roth     }
670199e0f17SMichael Roth 
671199e0f17SMichael Roth     g_string_free(gstr_union, true);
672199e0f17SMichael Roth     g_string_free(gstr_list, true);
673199e0f17SMichael Roth     qapi_free_UserDefNativeListUnion(cvalue);
674199e0f17SMichael Roth }
675199e0f17SMichael Roth 
676199e0f17SMichael Roth static void test_visitor_in_native_list_string(TestInputVisitorData *data,
677199e0f17SMichael Roth                                                const void *unused)
678199e0f17SMichael Roth {
679199e0f17SMichael Roth     UserDefNativeListUnion *cvalue = NULL;
680199e0f17SMichael Roth     strList *elem = NULL;
681199e0f17SMichael Roth     Visitor *v;
682199e0f17SMichael Roth     GString *gstr_list = g_string_new("");
683199e0f17SMichael Roth     GString *gstr_union = g_string_new("");
684199e0f17SMichael Roth     int i;
685199e0f17SMichael Roth 
686199e0f17SMichael Roth     for (i = 0; i < 32; i++) {
687199e0f17SMichael Roth         g_string_append_printf(gstr_list, "'%d'", i);
688199e0f17SMichael Roth         if (i != 31) {
689199e0f17SMichael Roth             g_string_append(gstr_list, ", ");
690199e0f17SMichael Roth         }
691199e0f17SMichael Roth     }
692199e0f17SMichael Roth     g_string_append_printf(gstr_union,  "{ 'type': 'string', 'data': [ %s ] }",
693199e0f17SMichael Roth                            gstr_list->str);
694199e0f17SMichael Roth     v = visitor_input_test_init_raw(data,  gstr_union->str);
695199e0f17SMichael Roth 
69651e72bc1SEric Blake     visit_type_UserDefNativeListUnion(v, NULL, &cvalue, &error_abort);
697199e0f17SMichael Roth     g_assert(cvalue != NULL);
698c363acefSEric Blake     g_assert_cmpint(cvalue->type, ==, USER_DEF_NATIVE_LIST_UNION_KIND_STRING);
699199e0f17SMichael Roth 
70032bafa8fSEric Blake     for (i = 0, elem = cvalue->u.string.data; elem; elem = elem->next, i++) {
701199e0f17SMichael Roth         gchar str[8];
702199e0f17SMichael Roth         sprintf(str, "%d", i);
703199e0f17SMichael Roth         g_assert_cmpstr(elem->value, ==, str);
704199e0f17SMichael Roth     }
705199e0f17SMichael Roth 
706199e0f17SMichael Roth     g_string_free(gstr_union, true);
707199e0f17SMichael Roth     g_string_free(gstr_list, true);
708199e0f17SMichael Roth     qapi_free_UserDefNativeListUnion(cvalue);
709199e0f17SMichael Roth }
710199e0f17SMichael Roth 
711199e0f17SMichael Roth #define DOUBLE_STR_MAX 16
712199e0f17SMichael Roth 
713199e0f17SMichael Roth static void test_visitor_in_native_list_number(TestInputVisitorData *data,
714199e0f17SMichael Roth                                                const void *unused)
715199e0f17SMichael Roth {
716199e0f17SMichael Roth     UserDefNativeListUnion *cvalue = NULL;
717199e0f17SMichael Roth     numberList *elem = NULL;
718199e0f17SMichael Roth     Visitor *v;
719199e0f17SMichael Roth     GString *gstr_list = g_string_new("");
720199e0f17SMichael Roth     GString *gstr_union = g_string_new("");
721199e0f17SMichael Roth     int i;
722199e0f17SMichael Roth 
723199e0f17SMichael Roth     for (i = 0; i < 32; i++) {
724199e0f17SMichael Roth         g_string_append_printf(gstr_list, "%f", (double)i / 3);
725199e0f17SMichael Roth         if (i != 31) {
726199e0f17SMichael Roth             g_string_append(gstr_list, ", ");
727199e0f17SMichael Roth         }
728199e0f17SMichael Roth     }
729199e0f17SMichael Roth     g_string_append_printf(gstr_union,  "{ 'type': 'number', 'data': [ %s ] }",
730199e0f17SMichael Roth                            gstr_list->str);
731199e0f17SMichael Roth     v = visitor_input_test_init_raw(data,  gstr_union->str);
732199e0f17SMichael Roth 
73351e72bc1SEric Blake     visit_type_UserDefNativeListUnion(v, NULL, &cvalue, &error_abort);
734199e0f17SMichael Roth     g_assert(cvalue != NULL);
735c363acefSEric Blake     g_assert_cmpint(cvalue->type, ==, USER_DEF_NATIVE_LIST_UNION_KIND_NUMBER);
736199e0f17SMichael Roth 
73732bafa8fSEric Blake     for (i = 0, elem = cvalue->u.number.data; elem; elem = elem->next, i++) {
738199e0f17SMichael Roth         GString *double_expected = g_string_new("");
739199e0f17SMichael Roth         GString *double_actual = g_string_new("");
740199e0f17SMichael Roth 
741199e0f17SMichael Roth         g_string_printf(double_expected, "%.6f", (double)i / 3);
742199e0f17SMichael Roth         g_string_printf(double_actual, "%.6f", elem->value);
743199e0f17SMichael Roth         g_assert_cmpstr(double_expected->str, ==, double_actual->str);
744199e0f17SMichael Roth 
745199e0f17SMichael Roth         g_string_free(double_expected, true);
746199e0f17SMichael Roth         g_string_free(double_actual, true);
747199e0f17SMichael Roth     }
748199e0f17SMichael Roth 
749199e0f17SMichael Roth     g_string_free(gstr_union, true);
750199e0f17SMichael Roth     g_string_free(gstr_list, true);
751199e0f17SMichael Roth     qapi_free_UserDefNativeListUnion(cvalue);
752199e0f17SMichael Roth }
753199e0f17SMichael Roth 
754d88f5fd1SLuiz Capitulino static void input_visitor_test_add(const char *testpath,
755d88f5fd1SLuiz Capitulino                                    TestInputVisitorData *data,
756d88f5fd1SLuiz Capitulino                                    void (*test_func)(TestInputVisitorData *data, const void *user_data))
757d88f5fd1SLuiz Capitulino {
758d88f5fd1SLuiz Capitulino     g_test_add(testpath, TestInputVisitorData, data, NULL, test_func,
759d88f5fd1SLuiz Capitulino                visitor_input_teardown);
760d88f5fd1SLuiz Capitulino }
761d88f5fd1SLuiz Capitulino 
7623dcf71f6SPaolo Bonzini static void test_visitor_in_errors(TestInputVisitorData *data,
7633dcf71f6SPaolo Bonzini                                    const void *unused)
7643dcf71f6SPaolo Bonzini {
7653dcf71f6SPaolo Bonzini     TestStruct *p = NULL;
766e940f543SMarkus Armbruster     Error *err = NULL;
7673dcf71f6SPaolo Bonzini     Visitor *v;
768dd5ee2c2SEric Blake     strList *q = NULL;
7699b4e38feSEric Blake     UserDefTwo *r = NULL;
7709b4e38feSEric Blake     WrapAlternate *s = NULL;
7713dcf71f6SPaolo Bonzini 
772dd5ee2c2SEric Blake     v = visitor_input_test_init(data, "{ 'integer': false, 'boolean': 'foo', "
773dd5ee2c2SEric Blake                                 "'string': -42 }");
7743dcf71f6SPaolo Bonzini 
77551e72bc1SEric Blake     visit_type_TestStruct(v, NULL, &p, &err);
776a12a5a1aSEric Blake     error_free_or_abort(&err);
77768ab47e4SEric Blake     g_assert(!p);
778dd5ee2c2SEric Blake 
779dd5ee2c2SEric Blake     v = visitor_input_test_init(data, "[ '1', '2', false, '3' ]");
78051e72bc1SEric Blake     visit_type_strList(v, NULL, &q, &err);
781dd5ee2c2SEric Blake     error_free_or_abort(&err);
78268ab47e4SEric Blake     assert(!q);
7839b4e38feSEric Blake 
7849b4e38feSEric Blake     v = visitor_input_test_init(data, "{ 'str':'hi' }");
7859b4e38feSEric Blake     visit_type_UserDefTwo(v, NULL, &r, &err);
7869b4e38feSEric Blake     error_free_or_abort(&err);
7879b4e38feSEric Blake     assert(!r);
7889b4e38feSEric Blake 
7899b4e38feSEric Blake     v = visitor_input_test_init(data, "{ }");
7909b4e38feSEric Blake     visit_type_WrapAlternate(v, NULL, &s, &err);
7919b4e38feSEric Blake     error_free_or_abort(&err);
7929b4e38feSEric Blake     assert(!s);
7933dcf71f6SPaolo Bonzini }
7943dcf71f6SPaolo Bonzini 
7952533377cSEric Blake static void test_visitor_in_wrong_type(TestInputVisitorData *data,
7962533377cSEric Blake                                        const void *unused)
7972533377cSEric Blake {
7982533377cSEric Blake     TestStruct *p = NULL;
7992533377cSEric Blake     Visitor *v;
8002533377cSEric Blake     strList *q = NULL;
8012533377cSEric Blake     int64_t i;
8022533377cSEric Blake     Error *err = NULL;
8032533377cSEric Blake 
8042533377cSEric Blake     /* Make sure arrays and structs cannot be confused */
8052533377cSEric Blake 
8062533377cSEric Blake     v = visitor_input_test_init(data, "[]");
80751e72bc1SEric Blake     visit_type_TestStruct(v, NULL, &p, &err);
8082533377cSEric Blake     error_free_or_abort(&err);
8092533377cSEric Blake     g_assert(!p);
8102533377cSEric Blake 
8112533377cSEric Blake     v = visitor_input_test_init(data, "{}");
81251e72bc1SEric Blake     visit_type_strList(v, NULL, &q, &err);
8132533377cSEric Blake     error_free_or_abort(&err);
8142533377cSEric Blake     assert(!q);
8152533377cSEric Blake 
8162533377cSEric Blake     /* Make sure primitives and struct cannot be confused */
8172533377cSEric Blake 
8182533377cSEric Blake     v = visitor_input_test_init(data, "1");
81951e72bc1SEric Blake     visit_type_TestStruct(v, NULL, &p, &err);
8202533377cSEric Blake     error_free_or_abort(&err);
8212533377cSEric Blake     g_assert(!p);
8222533377cSEric Blake 
8232533377cSEric Blake     v = visitor_input_test_init(data, "{}");
82451e72bc1SEric Blake     visit_type_int(v, NULL, &i, &err);
8252533377cSEric Blake     error_free_or_abort(&err);
8262533377cSEric Blake 
8272533377cSEric Blake     /* Make sure primitives and arrays cannot be confused */
8282533377cSEric Blake 
8292533377cSEric Blake     v = visitor_input_test_init(data, "1");
83051e72bc1SEric Blake     visit_type_strList(v, NULL, &q, &err);
8312533377cSEric Blake     error_free_or_abort(&err);
8322533377cSEric Blake     assert(!q);
8332533377cSEric Blake 
8342533377cSEric Blake     v = visitor_input_test_init(data, "[]");
83551e72bc1SEric Blake     visit_type_int(v, NULL, &i, &err);
8362533377cSEric Blake     error_free_or_abort(&err);
8372533377cSEric Blake }
8382533377cSEric Blake 
839d88f5fd1SLuiz Capitulino int main(int argc, char **argv)
840d88f5fd1SLuiz Capitulino {
841d88f5fd1SLuiz Capitulino     TestInputVisitorData in_visitor_data;
842d88f5fd1SLuiz Capitulino 
843d88f5fd1SLuiz Capitulino     g_test_init(&argc, &argv, NULL);
844d88f5fd1SLuiz Capitulino 
845d88f5fd1SLuiz Capitulino     input_visitor_test_add("/visitor/input/int",
846d88f5fd1SLuiz Capitulino                            &in_visitor_data, test_visitor_in_int);
847e92cfa0dSMichael Roth     input_visitor_test_add("/visitor/input/int_overflow",
848e92cfa0dSMichael Roth                            &in_visitor_data, test_visitor_in_int_overflow);
849d88f5fd1SLuiz Capitulino     input_visitor_test_add("/visitor/input/bool",
850d88f5fd1SLuiz Capitulino                            &in_visitor_data, test_visitor_in_bool);
851d88f5fd1SLuiz Capitulino     input_visitor_test_add("/visitor/input/number",
852d88f5fd1SLuiz Capitulino                            &in_visitor_data, test_visitor_in_number);
853d88f5fd1SLuiz Capitulino     input_visitor_test_add("/visitor/input/string",
854d88f5fd1SLuiz Capitulino                            &in_visitor_data, test_visitor_in_string);
855d88f5fd1SLuiz Capitulino     input_visitor_test_add("/visitor/input/enum",
856d88f5fd1SLuiz Capitulino                            &in_visitor_data, test_visitor_in_enum);
857d88f5fd1SLuiz Capitulino     input_visitor_test_add("/visitor/input/struct",
858d88f5fd1SLuiz Capitulino                            &in_visitor_data, test_visitor_in_struct);
859d88f5fd1SLuiz Capitulino     input_visitor_test_add("/visitor/input/struct-nested",
860d88f5fd1SLuiz Capitulino                            &in_visitor_data, test_visitor_in_struct_nested);
861d88f5fd1SLuiz Capitulino     input_visitor_test_add("/visitor/input/list",
862d88f5fd1SLuiz Capitulino                            &in_visitor_data, test_visitor_in_list);
86328770e05SMarkus Armbruster     input_visitor_test_add("/visitor/input/any",
86428770e05SMarkus Armbruster                            &in_visitor_data, test_visitor_in_any);
8653df016f1SEric Blake     input_visitor_test_add("/visitor/input/null",
8663df016f1SEric Blake                            &in_visitor_data, test_visitor_in_null);
8672fc00432SMarkus Armbruster     input_visitor_test_add("/visitor/input/union-flat",
8682fc00432SMarkus Armbruster                            &in_visitor_data, test_visitor_in_union_flat);
869ab045267SEric Blake     input_visitor_test_add("/visitor/input/alternate",
870ab045267SEric Blake                            &in_visitor_data, test_visitor_in_alternate);
8713dcf71f6SPaolo Bonzini     input_visitor_test_add("/visitor/input/errors",
8723dcf71f6SPaolo Bonzini                            &in_visitor_data, test_visitor_in_errors);
8732533377cSEric Blake     input_visitor_test_add("/visitor/input/wrong-type",
8742533377cSEric Blake                            &in_visitor_data, test_visitor_in_wrong_type);
8759c51b441SEric Blake     input_visitor_test_add("/visitor/input/alternate-number",
8769c51b441SEric Blake                            &in_visitor_data, test_visitor_in_alternate_number);
877199e0f17SMichael Roth     input_visitor_test_add("/visitor/input/native_list/int",
878199e0f17SMichael Roth                            &in_visitor_data,
879199e0f17SMichael Roth                            test_visitor_in_native_list_int);
880199e0f17SMichael Roth     input_visitor_test_add("/visitor/input/native_list/int8",
881199e0f17SMichael Roth                            &in_visitor_data,
882199e0f17SMichael Roth                            test_visitor_in_native_list_int8);
883199e0f17SMichael Roth     input_visitor_test_add("/visitor/input/native_list/int16",
884199e0f17SMichael Roth                            &in_visitor_data,
885199e0f17SMichael Roth                            test_visitor_in_native_list_int16);
886199e0f17SMichael Roth     input_visitor_test_add("/visitor/input/native_list/int32",
887199e0f17SMichael Roth                            &in_visitor_data,
888199e0f17SMichael Roth                            test_visitor_in_native_list_int32);
889199e0f17SMichael Roth     input_visitor_test_add("/visitor/input/native_list/int64",
890199e0f17SMichael Roth                            &in_visitor_data,
891199e0f17SMichael Roth                            test_visitor_in_native_list_int64);
892199e0f17SMichael Roth     input_visitor_test_add("/visitor/input/native_list/uint8",
893199e0f17SMichael Roth                            &in_visitor_data,
894199e0f17SMichael Roth                            test_visitor_in_native_list_uint8);
895199e0f17SMichael Roth     input_visitor_test_add("/visitor/input/native_list/uint16",
896199e0f17SMichael Roth                            &in_visitor_data,
897199e0f17SMichael Roth                            test_visitor_in_native_list_uint16);
898199e0f17SMichael Roth     input_visitor_test_add("/visitor/input/native_list/uint32",
899199e0f17SMichael Roth                            &in_visitor_data,
900199e0f17SMichael Roth                            test_visitor_in_native_list_uint32);
901199e0f17SMichael Roth     input_visitor_test_add("/visitor/input/native_list/uint64",
902805017b7SEric Blake                            &in_visitor_data,
903805017b7SEric Blake                            test_visitor_in_native_list_uint64);
904199e0f17SMichael Roth     input_visitor_test_add("/visitor/input/native_list/bool",
905199e0f17SMichael Roth                            &in_visitor_data, test_visitor_in_native_list_bool);
906199e0f17SMichael Roth     input_visitor_test_add("/visitor/input/native_list/str",
907805017b7SEric Blake                            &in_visitor_data,
908805017b7SEric Blake                            test_visitor_in_native_list_string);
909199e0f17SMichael Roth     input_visitor_test_add("/visitor/input/native_list/number",
910805017b7SEric Blake                            &in_visitor_data,
911805017b7SEric Blake                            test_visitor_in_native_list_number);
912d88f5fd1SLuiz Capitulino 
913d88f5fd1SLuiz Capitulino     g_test_run();
914d88f5fd1SLuiz Capitulino 
915d88f5fd1SLuiz Capitulino     return 0;
916d88f5fd1SLuiz Capitulino }
917