xref: /qemu/tests/unit/test-qobject-input-visitor.c (revision e7a76fe25aa0b2856f6b86ad15ffe974b8727bdb)
1d88f5fd1SLuiz Capitulino /*
2b3db211fSDaniel P. Berrange  * QObject 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>
877c47de2SMarkus Armbruster  *  Paolo Bonzini <pbonzini@redhat.com>
9d88f5fd1SLuiz Capitulino  *
10d88f5fd1SLuiz Capitulino  * This work is licensed under the terms of the GNU GPL, version 2 or later.
11d88f5fd1SLuiz Capitulino  * See the COPYING file in the top-level directory.
12d88f5fd1SLuiz Capitulino  */
13d88f5fd1SLuiz Capitulino 
14681c28a3SPeter Maydell #include "qemu/osdep.h"
15d88f5fd1SLuiz Capitulino 
1679ee7df8SPaolo Bonzini #include "qemu-common.h"
17da34e65cSMarkus Armbruster #include "qapi/error.h"
18112ed241SMarkus Armbruster #include "qapi/qapi-visit-introspect.h"
19b3db211fSDaniel P. Berrange #include "qapi/qobject-input-visitor.h"
20d88f5fd1SLuiz Capitulino #include "test-qapi-visit.h"
216b673957SMarkus Armbruster #include "qapi/qmp/qbool.h"
22452fcdbcSMarkus Armbruster #include "qapi/qmp/qdict.h"
2315280c36SMarkus Armbruster #include "qapi/qmp/qnull.h"
2415280c36SMarkus Armbruster #include "qapi/qmp/qnum.h"
25fc81fa1eSMarkus Armbruster #include "qapi/qmp/qstring.h"
26c7eb39cbSEric Blake #include "qapi/qmp/qjson.h"
27eb815e24SMarkus Armbruster #include "test-qapi-introspect.h"
28eb815e24SMarkus Armbruster #include "qapi/qapi-introspect.h"
29d88f5fd1SLuiz Capitulino 
30d88f5fd1SLuiz Capitulino typedef struct TestInputVisitorData {
31d88f5fd1SLuiz Capitulino     QObject *obj;
32b70ce101SEric Blake     Visitor *qiv;
33d88f5fd1SLuiz Capitulino } TestInputVisitorData;
34d88f5fd1SLuiz Capitulino 
35d88f5fd1SLuiz Capitulino static void visitor_input_teardown(TestInputVisitorData *data,
36d88f5fd1SLuiz Capitulino                                    const void *unused)
37d88f5fd1SLuiz Capitulino {
38cb3e7f08SMarc-André Lureau     qobject_unref(data->obj);
39d88f5fd1SLuiz Capitulino     data->obj = NULL;
40d88f5fd1SLuiz Capitulino 
41d88f5fd1SLuiz Capitulino     if (data->qiv) {
42b70ce101SEric Blake         visit_free(data->qiv);
43d88f5fd1SLuiz Capitulino         data->qiv = NULL;
44d88f5fd1SLuiz Capitulino     }
45d88f5fd1SLuiz Capitulino }
46d88f5fd1SLuiz Capitulino 
470920a171SEric Blake /* The various test_init functions are provided instead of a test setup
480920a171SEric Blake    function so that the JSON string used by the tests are kept in the test
490920a171SEric Blake    functions (and not in main()). */
50eac78bd4SMarkus Armbruster 
51eac78bd4SMarkus Armbruster static Visitor *test_init_internal(TestInputVisitorData *data, bool keyval,
52eac78bd4SMarkus Armbruster                                    QObject *obj)
530920a171SEric Blake {
54b18f1141SEric Blake     visitor_input_teardown(data, NULL);
55b18f1141SEric Blake 
56eac78bd4SMarkus Armbruster     data->obj = obj;
570920a171SEric Blake 
58cbd8acf3SDaniel P. Berrange     if (keyval) {
59cbd8acf3SDaniel P. Berrange         data->qiv = qobject_input_visitor_new_keyval(data->obj);
60cbd8acf3SDaniel P. Berrange     } else {
61048abb7bSMarkus Armbruster         data->qiv = qobject_input_visitor_new(data->obj);
62cbd8acf3SDaniel P. Berrange     }
630920a171SEric Blake     g_assert(data->qiv);
64b70ce101SEric Blake     return data->qiv;
650920a171SEric Blake }
660920a171SEric Blake 
67cbd8acf3SDaniel P. Berrange static GCC_FMT_ATTR(3, 4)
68cbd8acf3SDaniel P. Berrange Visitor *visitor_input_test_init_full(TestInputVisitorData *data,
69cbd8acf3SDaniel P. Berrange                                       bool keyval,
70cbd8acf3SDaniel P. Berrange                                       const char *json_string, ...)
71cbd8acf3SDaniel P. Berrange {
72cbd8acf3SDaniel P. Berrange     Visitor *v;
73cbd8acf3SDaniel P. Berrange     va_list ap;
74cbd8acf3SDaniel P. Berrange 
75cbd8acf3SDaniel P. Berrange     va_start(ap, json_string);
76eac78bd4SMarkus Armbruster     v = test_init_internal(data, keyval,
77eac78bd4SMarkus Armbruster                            qobject_from_vjsonf_nofail(json_string, ap));
78cbd8acf3SDaniel P. Berrange     va_end(ap);
79cbd8acf3SDaniel P. Berrange     return v;
80cbd8acf3SDaniel P. Berrange }
81cbd8acf3SDaniel P. Berrange 
82aba2107aSStefan Weil static GCC_FMT_ATTR(2, 3)
83aba2107aSStefan Weil Visitor *visitor_input_test_init(TestInputVisitorData *data,
84d88f5fd1SLuiz Capitulino                                  const char *json_string, ...)
85d88f5fd1SLuiz Capitulino {
86d88f5fd1SLuiz Capitulino     Visitor *v;
87d88f5fd1SLuiz Capitulino     va_list ap;
88d88f5fd1SLuiz Capitulino 
89d88f5fd1SLuiz Capitulino     va_start(ap, json_string);
90eac78bd4SMarkus Armbruster     v = test_init_internal(data, false,
91eac78bd4SMarkus Armbruster                            qobject_from_vjsonf_nofail(json_string, ap));
92d88f5fd1SLuiz Capitulino     va_end(ap);
93d88f5fd1SLuiz Capitulino     return v;
94d88f5fd1SLuiz Capitulino }
95d88f5fd1SLuiz Capitulino 
96199e0f17SMichael Roth /* similar to visitor_input_test_init(), but does not expect a string
97199e0f17SMichael Roth  * literal/format json_string argument and so can be used for
98199e0f17SMichael Roth  * programatically generated strings (and we can't pass in programatically
99199e0f17SMichael Roth  * generated strings via %s format parameters since qobject_from_jsonv()
100199e0f17SMichael Roth  * will wrap those in double-quotes and treat the entire object as a
101199e0f17SMichael Roth  * string)
102199e0f17SMichael Roth  */
103199e0f17SMichael Roth static Visitor *visitor_input_test_init_raw(TestInputVisitorData *data,
104199e0f17SMichael Roth                                             const char *json_string)
105199e0f17SMichael Roth {
106eac78bd4SMarkus Armbruster     return test_init_internal(data, false,
107eac78bd4SMarkus Armbruster                               qobject_from_json(json_string, &error_abort));
108199e0f17SMichael Roth }
109199e0f17SMichael Roth 
110d88f5fd1SLuiz Capitulino static void test_visitor_in_int(TestInputVisitorData *data,
111d88f5fd1SLuiz Capitulino                                 const void *unused)
112d88f5fd1SLuiz Capitulino {
11329a6731aSEric Blake     int64_t res = 0;
114c1214ad3SMarc-André Lureau     double dbl;
11529a6731aSEric Blake     int value = -42;
116d88f5fd1SLuiz Capitulino     Visitor *v;
117d88f5fd1SLuiz Capitulino 
11829a6731aSEric Blake     v = visitor_input_test_init(data, "%d", value);
119d88f5fd1SLuiz Capitulino 
12051e72bc1SEric Blake     visit_type_int(v, NULL, &res, &error_abort);
121d88f5fd1SLuiz Capitulino     g_assert_cmpint(res, ==, value);
122c1214ad3SMarc-André Lureau 
123c1214ad3SMarc-André Lureau     visit_type_number(v, NULL, &dbl, &error_abort);
124c1214ad3SMarc-André Lureau     g_assert_cmpfloat(dbl, ==, -42.0);
125d88f5fd1SLuiz Capitulino }
126d88f5fd1SLuiz Capitulino 
1274bc0c94dSMarkus Armbruster static void test_visitor_in_uint(TestInputVisitorData *data,
1284bc0c94dSMarkus Armbruster                                 const void *unused)
1294bc0c94dSMarkus Armbruster {
1304bc0c94dSMarkus Armbruster     uint64_t res = 0;
131c1214ad3SMarc-André Lureau     int64_t i64;
132c1214ad3SMarc-André Lureau     double dbl;
1334bc0c94dSMarkus Armbruster     int value = 42;
1344bc0c94dSMarkus Armbruster     Visitor *v;
1354bc0c94dSMarkus Armbruster 
1364bc0c94dSMarkus Armbruster     v = visitor_input_test_init(data, "%d", value);
1374bc0c94dSMarkus Armbruster 
1384bc0c94dSMarkus Armbruster     visit_type_uint64(v, NULL, &res, &error_abort);
1394bc0c94dSMarkus Armbruster     g_assert_cmpuint(res, ==, (uint64_t)value);
1404bc0c94dSMarkus Armbruster 
141c1214ad3SMarc-André Lureau     visit_type_int(v, NULL, &i64, &error_abort);
142c1214ad3SMarc-André Lureau     g_assert_cmpint(i64, ==, value);
1434bc0c94dSMarkus Armbruster 
144c1214ad3SMarc-André Lureau     visit_type_number(v, NULL, &dbl, &error_abort);
145c1214ad3SMarc-André Lureau     g_assert_cmpfloat(dbl, ==, value);
146c1214ad3SMarc-André Lureau 
147c1214ad3SMarc-André Lureau     /* BUG: value between INT64_MIN and -1 accepted modulo 2^64 */
1484bc0c94dSMarkus Armbruster     v = visitor_input_test_init(data, "%d", -value);
1494bc0c94dSMarkus Armbruster 
1504bc0c94dSMarkus Armbruster     visit_type_uint64(v, NULL, &res, &error_abort);
1514bc0c94dSMarkus Armbruster     g_assert_cmpuint(res, ==, (uint64_t)-value);
1524bc0c94dSMarkus Armbruster 
1534bc0c94dSMarkus Armbruster     v = visitor_input_test_init(data, "18446744073709551574");
1544bc0c94dSMarkus Armbruster 
1555923f85fSMarc-André Lureau     visit_type_uint64(v, NULL, &res, &error_abort);
1565923f85fSMarc-André Lureau     g_assert_cmpuint(res, ==, 18446744073709551574U);
157c1214ad3SMarc-André Lureau 
158c1214ad3SMarc-André Lureau     visit_type_number(v, NULL, &dbl, &error_abort);
159c1214ad3SMarc-André Lureau     g_assert_cmpfloat(dbl, ==, 18446744073709552000.0);
1604bc0c94dSMarkus Armbruster }
1614bc0c94dSMarkus Armbruster 
162e92cfa0dSMichael Roth static void test_visitor_in_int_overflow(TestInputVisitorData *data,
163e92cfa0dSMichael Roth                                          const void *unused)
164e92cfa0dSMichael Roth {
165e92cfa0dSMichael Roth     int64_t res = 0;
166e940f543SMarkus Armbruster     Error *err = NULL;
167e92cfa0dSMichael Roth     Visitor *v;
168e92cfa0dSMichael Roth 
16901b2ffceSMarc-André Lureau     /*
17001b2ffceSMarc-André Lureau      * This will overflow a QNUM_I64, so should be deserialized into a
17101b2ffceSMarc-André Lureau      * QNUM_DOUBLE field instead, leading to an error if we pass it to
17201b2ffceSMarc-André Lureau      * visit_type_int().  Confirm this.
173e92cfa0dSMichael Roth      */
174e92cfa0dSMichael Roth     v = visitor_input_test_init(data, "%f", DBL_MAX);
175e92cfa0dSMichael Roth 
17651e72bc1SEric Blake     visit_type_int(v, NULL, &res, &err);
177a12a5a1aSEric Blake     error_free_or_abort(&err);
178e92cfa0dSMichael Roth }
179e92cfa0dSMichael Roth 
180cbd8acf3SDaniel P. Berrange static void test_visitor_in_int_keyval(TestInputVisitorData *data,
181cbd8acf3SDaniel P. Berrange                                        const void *unused)
182cbd8acf3SDaniel P. Berrange {
183cbd8acf3SDaniel P. Berrange     int64_t res = 0, value = -42;
184cbd8acf3SDaniel P. Berrange     Error *err = NULL;
185cbd8acf3SDaniel P. Berrange     Visitor *v;
186cbd8acf3SDaniel P. Berrange 
187cbd8acf3SDaniel P. Berrange     v = visitor_input_test_init_full(data, true, "%" PRId64, value);
188cbd8acf3SDaniel P. Berrange     visit_type_int(v, NULL, &res, &err);
189cbd8acf3SDaniel P. Berrange     error_free_or_abort(&err);
190cbd8acf3SDaniel P. Berrange }
191cbd8acf3SDaniel P. Berrange 
192cbd8acf3SDaniel P. Berrange static void test_visitor_in_int_str_keyval(TestInputVisitorData *data,
193cbd8acf3SDaniel P. Berrange                                            const void *unused)
194cbd8acf3SDaniel P. Berrange {
195cbd8acf3SDaniel P. Berrange     int64_t res = 0, value = -42;
196cbd8acf3SDaniel P. Berrange     Visitor *v;
197cbd8acf3SDaniel P. Berrange 
198cbd8acf3SDaniel P. Berrange     v = visitor_input_test_init_full(data, true, "\"-42\"");
199cbd8acf3SDaniel P. Berrange 
200cbd8acf3SDaniel P. Berrange     visit_type_int(v, NULL, &res, &error_abort);
201cbd8acf3SDaniel P. Berrange     g_assert_cmpint(res, ==, value);
202cbd8acf3SDaniel P. Berrange }
203cbd8acf3SDaniel P. Berrange 
204cbd8acf3SDaniel P. Berrange static void test_visitor_in_int_str_fail(TestInputVisitorData *data,
205cbd8acf3SDaniel P. Berrange                                          const void *unused)
206cbd8acf3SDaniel P. Berrange {
207cbd8acf3SDaniel P. Berrange     int64_t res = 0;
208cbd8acf3SDaniel P. Berrange     Visitor *v;
209cbd8acf3SDaniel P. Berrange     Error *err = NULL;
210cbd8acf3SDaniel P. Berrange 
211cbd8acf3SDaniel P. Berrange     v = visitor_input_test_init(data, "\"-42\"");
212cbd8acf3SDaniel P. Berrange 
213cbd8acf3SDaniel P. Berrange     visit_type_int(v, NULL, &res, &err);
214cbd8acf3SDaniel P. Berrange     error_free_or_abort(&err);
215cbd8acf3SDaniel P. Berrange }
216cbd8acf3SDaniel P. Berrange 
217d88f5fd1SLuiz Capitulino static void test_visitor_in_bool(TestInputVisitorData *data,
218d88f5fd1SLuiz Capitulino                                  const void *unused)
219d88f5fd1SLuiz Capitulino {
220d88f5fd1SLuiz Capitulino     bool res = false;
221d88f5fd1SLuiz Capitulino     Visitor *v;
222d88f5fd1SLuiz Capitulino 
223d88f5fd1SLuiz Capitulino     v = visitor_input_test_init(data, "true");
224d88f5fd1SLuiz Capitulino 
22551e72bc1SEric Blake     visit_type_bool(v, NULL, &res, &error_abort);
226d88f5fd1SLuiz Capitulino     g_assert_cmpint(res, ==, true);
227d88f5fd1SLuiz Capitulino }
228d88f5fd1SLuiz Capitulino 
229cbd8acf3SDaniel P. Berrange static void test_visitor_in_bool_keyval(TestInputVisitorData *data,
230cbd8acf3SDaniel P. Berrange                                         const void *unused)
231cbd8acf3SDaniel P. Berrange {
232cbd8acf3SDaniel P. Berrange     bool res = false;
233cbd8acf3SDaniel P. Berrange     Error *err = NULL;
234cbd8acf3SDaniel P. Berrange     Visitor *v;
235cbd8acf3SDaniel P. Berrange 
236cbd8acf3SDaniel P. Berrange     v = visitor_input_test_init_full(data, true, "true");
237cbd8acf3SDaniel P. Berrange 
238cbd8acf3SDaniel P. Berrange     visit_type_bool(v, NULL, &res, &err);
239cbd8acf3SDaniel P. Berrange     error_free_or_abort(&err);
240cbd8acf3SDaniel P. Berrange }
241cbd8acf3SDaniel P. Berrange 
242cbd8acf3SDaniel P. Berrange static void test_visitor_in_bool_str_keyval(TestInputVisitorData *data,
243cbd8acf3SDaniel P. Berrange                                             const void *unused)
244cbd8acf3SDaniel P. Berrange {
245cbd8acf3SDaniel P. Berrange     bool res = false;
246cbd8acf3SDaniel P. Berrange     Visitor *v;
247cbd8acf3SDaniel P. Berrange 
248cbd8acf3SDaniel P. Berrange     v = visitor_input_test_init_full(data, true, "\"on\"");
249cbd8acf3SDaniel P. Berrange 
250cbd8acf3SDaniel P. Berrange     visit_type_bool(v, NULL, &res, &error_abort);
251cbd8acf3SDaniel P. Berrange     g_assert_cmpint(res, ==, true);
252cbd8acf3SDaniel P. Berrange }
253cbd8acf3SDaniel P. Berrange 
254cbd8acf3SDaniel P. Berrange static void test_visitor_in_bool_str_fail(TestInputVisitorData *data,
255cbd8acf3SDaniel P. Berrange                                           const void *unused)
256cbd8acf3SDaniel P. Berrange {
257cbd8acf3SDaniel P. Berrange     bool res = false;
258cbd8acf3SDaniel P. Berrange     Visitor *v;
259cbd8acf3SDaniel P. Berrange     Error *err = NULL;
260cbd8acf3SDaniel P. Berrange 
261cbd8acf3SDaniel P. Berrange     v = visitor_input_test_init(data, "\"true\"");
262cbd8acf3SDaniel P. Berrange 
263cbd8acf3SDaniel P. Berrange     visit_type_bool(v, NULL, &res, &err);
264cbd8acf3SDaniel P. Berrange     error_free_or_abort(&err);
265cbd8acf3SDaniel P. Berrange }
266cbd8acf3SDaniel P. Berrange 
267d88f5fd1SLuiz Capitulino static void test_visitor_in_number(TestInputVisitorData *data,
268d88f5fd1SLuiz Capitulino                                    const void *unused)
269d88f5fd1SLuiz Capitulino {
270d88f5fd1SLuiz Capitulino     double res = 0, value = 3.14;
271d88f5fd1SLuiz Capitulino     Visitor *v;
272d88f5fd1SLuiz Capitulino 
273d88f5fd1SLuiz Capitulino     v = visitor_input_test_init(data, "%f", value);
274d88f5fd1SLuiz Capitulino 
27551e72bc1SEric Blake     visit_type_number(v, NULL, &res, &error_abort);
276d88f5fd1SLuiz Capitulino     g_assert_cmpfloat(res, ==, value);
277d88f5fd1SLuiz Capitulino }
278d88f5fd1SLuiz Capitulino 
279c1214ad3SMarc-André Lureau static void test_visitor_in_large_number(TestInputVisitorData *data,
280c1214ad3SMarc-André Lureau                                          const void *unused)
281c1214ad3SMarc-André Lureau {
282c1214ad3SMarc-André Lureau     Error *err = NULL;
283c1214ad3SMarc-André Lureau     double res = 0;
284c1214ad3SMarc-André Lureau     int64_t i64;
285c1214ad3SMarc-André Lureau     uint64_t u64;
286c1214ad3SMarc-André Lureau     Visitor *v;
287c1214ad3SMarc-André Lureau 
288c1214ad3SMarc-André Lureau     v = visitor_input_test_init(data, "-18446744073709551616"); /* -2^64 */
289c1214ad3SMarc-André Lureau 
290c1214ad3SMarc-André Lureau     visit_type_number(v, NULL, &res, &error_abort);
291c1214ad3SMarc-André Lureau     g_assert_cmpfloat(res, ==, -18446744073709552e3);
292c1214ad3SMarc-André Lureau 
293c1214ad3SMarc-André Lureau     visit_type_int(v, NULL, &i64, &err);
294c1214ad3SMarc-André Lureau     error_free_or_abort(&err);
295c1214ad3SMarc-André Lureau 
296c1214ad3SMarc-André Lureau     visit_type_uint64(v, NULL, &u64, &err);
297c1214ad3SMarc-André Lureau     error_free_or_abort(&err);
298c1214ad3SMarc-André Lureau }
299c1214ad3SMarc-André Lureau 
300cbd8acf3SDaniel P. Berrange static void test_visitor_in_number_keyval(TestInputVisitorData *data,
301cbd8acf3SDaniel P. Berrange                                           const void *unused)
302cbd8acf3SDaniel P. Berrange {
303cbd8acf3SDaniel P. Berrange     double res = 0, value = 3.14;
304cbd8acf3SDaniel P. Berrange     Error *err = NULL;
305cbd8acf3SDaniel P. Berrange     Visitor *v;
306cbd8acf3SDaniel P. Berrange 
307cbd8acf3SDaniel P. Berrange     v = visitor_input_test_init_full(data, true, "%f", value);
308cbd8acf3SDaniel P. Berrange 
309cbd8acf3SDaniel P. Berrange     visit_type_number(v, NULL, &res, &err);
310cbd8acf3SDaniel P. Berrange     error_free_or_abort(&err);
311cbd8acf3SDaniel P. Berrange }
312cbd8acf3SDaniel P. Berrange 
313cbd8acf3SDaniel P. Berrange static void test_visitor_in_number_str_keyval(TestInputVisitorData *data,
314cbd8acf3SDaniel P. Berrange                                               const void *unused)
315cbd8acf3SDaniel P. Berrange {
316cbd8acf3SDaniel P. Berrange     double res = 0, value = 3.14;
317cbd8acf3SDaniel P. Berrange     Visitor *v;
3185891c388SMarkus Armbruster     Error *err = NULL;
319cbd8acf3SDaniel P. Berrange 
320cbd8acf3SDaniel P. Berrange     v = visitor_input_test_init_full(data, true, "\"3.14\"");
321cbd8acf3SDaniel P. Berrange 
322cbd8acf3SDaniel P. Berrange     visit_type_number(v, NULL, &res, &error_abort);
323cbd8acf3SDaniel P. Berrange     g_assert_cmpfloat(res, ==, value);
3245891c388SMarkus Armbruster 
3255891c388SMarkus Armbruster     v = visitor_input_test_init_full(data, true, "\"inf\"");
3265891c388SMarkus Armbruster 
3275891c388SMarkus Armbruster     visit_type_number(v, NULL, &res, &err);
3285891c388SMarkus Armbruster     error_free_or_abort(&err);
329cbd8acf3SDaniel P. Berrange }
330cbd8acf3SDaniel P. Berrange 
331cbd8acf3SDaniel P. Berrange static void test_visitor_in_number_str_fail(TestInputVisitorData *data,
332cbd8acf3SDaniel P. Berrange                                             const void *unused)
333cbd8acf3SDaniel P. Berrange {
334cbd8acf3SDaniel P. Berrange     double res = 0;
335cbd8acf3SDaniel P. Berrange     Visitor *v;
336cbd8acf3SDaniel P. Berrange     Error *err = NULL;
337cbd8acf3SDaniel P. Berrange 
338cbd8acf3SDaniel P. Berrange     v = visitor_input_test_init(data, "\"3.14\"");
339cbd8acf3SDaniel P. Berrange 
340cbd8acf3SDaniel P. Berrange     visit_type_number(v, NULL, &res, &err);
341cbd8acf3SDaniel P. Berrange     error_free_or_abort(&err);
342cbd8acf3SDaniel P. Berrange }
343cbd8acf3SDaniel P. Berrange 
344cbd8acf3SDaniel P. Berrange static void test_visitor_in_size_str_keyval(TestInputVisitorData *data,
345cbd8acf3SDaniel P. Berrange                                             const void *unused)
346cbd8acf3SDaniel P. Berrange {
347cbd8acf3SDaniel P. Berrange     uint64_t res, value = 500 * 1024 * 1024;
348cbd8acf3SDaniel P. Berrange     Visitor *v;
349cbd8acf3SDaniel P. Berrange 
350cbd8acf3SDaniel P. Berrange     v = visitor_input_test_init_full(data, true, "\"500M\"");
351cbd8acf3SDaniel P. Berrange 
352cbd8acf3SDaniel P. Berrange     visit_type_size(v, NULL, &res, &error_abort);
353cbd8acf3SDaniel P. Berrange     g_assert_cmpfloat(res, ==, value);
354cbd8acf3SDaniel P. Berrange }
355cbd8acf3SDaniel P. Berrange 
356cbd8acf3SDaniel P. Berrange static void test_visitor_in_size_str_fail(TestInputVisitorData *data,
357cbd8acf3SDaniel P. Berrange                                           const void *unused)
358cbd8acf3SDaniel P. Berrange {
359cbd8acf3SDaniel P. Berrange     uint64_t res = 0;
360cbd8acf3SDaniel P. Berrange     Visitor *v;
361cbd8acf3SDaniel P. Berrange     Error *err = NULL;
362cbd8acf3SDaniel P. Berrange 
363cbd8acf3SDaniel P. Berrange     v = visitor_input_test_init(data, "\"500M\"");
364cbd8acf3SDaniel P. Berrange 
365cbd8acf3SDaniel P. Berrange     visit_type_size(v, NULL, &res, &err);
366cbd8acf3SDaniel P. Berrange     error_free_or_abort(&err);
367cbd8acf3SDaniel P. Berrange }
368cbd8acf3SDaniel P. Berrange 
369d88f5fd1SLuiz Capitulino static void test_visitor_in_string(TestInputVisitorData *data,
370d88f5fd1SLuiz Capitulino                                    const void *unused)
371d88f5fd1SLuiz Capitulino {
372d88f5fd1SLuiz Capitulino     char *res = NULL, *value = (char *) "Q E M U";
373d88f5fd1SLuiz Capitulino     Visitor *v;
374d88f5fd1SLuiz Capitulino 
375d88f5fd1SLuiz Capitulino     v = visitor_input_test_init(data, "%s", value);
376d88f5fd1SLuiz Capitulino 
37751e72bc1SEric Blake     visit_type_str(v, NULL, &res, &error_abort);
378d88f5fd1SLuiz Capitulino     g_assert_cmpstr(res, ==, value);
379d88f5fd1SLuiz Capitulino 
380d88f5fd1SLuiz Capitulino     g_free(res);
381d88f5fd1SLuiz Capitulino }
382d88f5fd1SLuiz Capitulino 
383d88f5fd1SLuiz Capitulino static void test_visitor_in_enum(TestInputVisitorData *data,
384d88f5fd1SLuiz Capitulino                                  const void *unused)
385d88f5fd1SLuiz Capitulino {
386d88f5fd1SLuiz Capitulino     Visitor *v;
387d88f5fd1SLuiz Capitulino     EnumOne i;
388d88f5fd1SLuiz Capitulino 
3891c236ba5SMarkus Armbruster     for (i = 0; i < ENUM_ONE__MAX; i++) {
390d88f5fd1SLuiz Capitulino         EnumOne res = -1;
391d88f5fd1SLuiz Capitulino 
392977c736fSMarkus Armbruster         v = visitor_input_test_init(data, "%s", EnumOne_str(i));
393d88f5fd1SLuiz Capitulino 
39451e72bc1SEric Blake         visit_type_EnumOne(v, NULL, &res, &error_abort);
395d88f5fd1SLuiz Capitulino         g_assert_cmpint(i, ==, res);
396d88f5fd1SLuiz Capitulino     }
397d88f5fd1SLuiz Capitulino }
398d88f5fd1SLuiz Capitulino 
399d88f5fd1SLuiz Capitulino 
400d88f5fd1SLuiz Capitulino static void test_visitor_in_struct(TestInputVisitorData *data,
401d88f5fd1SLuiz Capitulino                                    const void *unused)
402d88f5fd1SLuiz Capitulino {
403d88f5fd1SLuiz Capitulino     TestStruct *p = NULL;
404d88f5fd1SLuiz Capitulino     Visitor *v;
405d88f5fd1SLuiz Capitulino 
406d88f5fd1SLuiz Capitulino     v = visitor_input_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo' }");
407d88f5fd1SLuiz Capitulino 
40851e72bc1SEric Blake     visit_type_TestStruct(v, NULL, &p, &error_abort);
409d88f5fd1SLuiz Capitulino     g_assert_cmpint(p->integer, ==, -42);
410d88f5fd1SLuiz Capitulino     g_assert(p->boolean == true);
411d88f5fd1SLuiz Capitulino     g_assert_cmpstr(p->string, ==, "foo");
412d88f5fd1SLuiz Capitulino 
413d88f5fd1SLuiz Capitulino     g_free(p->string);
414d88f5fd1SLuiz Capitulino     g_free(p);
415d88f5fd1SLuiz Capitulino }
416d88f5fd1SLuiz Capitulino 
417d88f5fd1SLuiz Capitulino static void test_visitor_in_struct_nested(TestInputVisitorData *data,
418d88f5fd1SLuiz Capitulino                                           const void *unused)
419d88f5fd1SLuiz Capitulino {
420221db5daSDaniel P. Berrangé     g_autoptr(UserDefTwo) udp = NULL;
421d88f5fd1SLuiz Capitulino     Visitor *v;
422d88f5fd1SLuiz Capitulino 
423b6fcf32dSEric Blake     v = visitor_input_test_init(data, "{ 'string0': 'string0', "
424b6fcf32dSEric Blake                                 "'dict1': { 'string1': 'string1', "
425b6fcf32dSEric Blake                                 "'dict2': { 'userdef': { 'integer': 42, "
426b6fcf32dSEric Blake                                 "'string': 'string' }, 'string': 'string2'}}}");
427d88f5fd1SLuiz Capitulino 
42851e72bc1SEric Blake     visit_type_UserDefTwo(v, NULL, &udp, &error_abort);
429d88f5fd1SLuiz Capitulino 
430b18f1141SEric Blake     g_assert_cmpstr(udp->string0, ==, "string0");
431b18f1141SEric Blake     g_assert_cmpstr(udp->dict1->string1, ==, "string1");
432ddf21908SEric Blake     g_assert_cmpint(udp->dict1->dict2->userdef->integer, ==, 42);
433b18f1141SEric Blake     g_assert_cmpstr(udp->dict1->dict2->userdef->string, ==, "string");
434b18f1141SEric Blake     g_assert_cmpstr(udp->dict1->dict2->string, ==, "string2");
4356446a592SEric Blake     g_assert(udp->dict1->has_dict3 == false);
436d88f5fd1SLuiz Capitulino }
437d88f5fd1SLuiz Capitulino 
438d88f5fd1SLuiz Capitulino static void test_visitor_in_list(TestInputVisitorData *data,
439d88f5fd1SLuiz Capitulino                                  const void *unused)
440d88f5fd1SLuiz Capitulino {
441d88f5fd1SLuiz Capitulino     UserDefOneList *item, *head = NULL;
442d88f5fd1SLuiz Capitulino     Visitor *v;
443d88f5fd1SLuiz Capitulino     int i;
444d88f5fd1SLuiz Capitulino 
445d88f5fd1SLuiz Capitulino     v = visitor_input_test_init(data, "[ { 'string': 'string0', 'integer': 42 }, { 'string': 'string1', 'integer': 43 }, { 'string': 'string2', 'integer': 44 } ]");
446d88f5fd1SLuiz Capitulino 
44751e72bc1SEric Blake     visit_type_UserDefOneList(v, NULL, &head, &error_abort);
448d88f5fd1SLuiz Capitulino     g_assert(head != NULL);
449d88f5fd1SLuiz Capitulino 
450d88f5fd1SLuiz Capitulino     for (i = 0, item = head; item; item = item->next, i++) {
451d88f5fd1SLuiz Capitulino         char string[12];
452d88f5fd1SLuiz Capitulino 
453d88f5fd1SLuiz Capitulino         snprintf(string, sizeof(string), "string%d", i);
454d88f5fd1SLuiz Capitulino         g_assert_cmpstr(item->value->string, ==, string);
455ddf21908SEric Blake         g_assert_cmpint(item->value->integer, ==, 42 + i);
456d88f5fd1SLuiz Capitulino     }
457d88f5fd1SLuiz Capitulino 
458d88f5fd1SLuiz Capitulino     qapi_free_UserDefOneList(head);
4592533377cSEric Blake     head = NULL;
4602533377cSEric Blake 
4612533377cSEric Blake     /* An empty list is valid */
4622533377cSEric Blake     v = visitor_input_test_init(data, "[]");
46351e72bc1SEric Blake     visit_type_UserDefOneList(v, NULL, &head, &error_abort);
4642533377cSEric Blake     g_assert(!head);
465d88f5fd1SLuiz Capitulino }
466d88f5fd1SLuiz Capitulino 
467*e7a76fe2SMarkus Armbruster static void test_visitor_in_list_struct(TestInputVisitorData *data,
468*e7a76fe2SMarkus Armbruster                                         const void *unused)
469*e7a76fe2SMarkus Armbruster {
470*e7a76fe2SMarkus Armbruster     const char *int_member[] = {
471*e7a76fe2SMarkus Armbruster         "integer", "s8", "s16", "s32", "s64", "u8", "u16", "u32", "u64" };
472*e7a76fe2SMarkus Armbruster     g_autoptr(GString) json = g_string_new("");
473*e7a76fe2SMarkus Armbruster     int i, j;
474*e7a76fe2SMarkus Armbruster     const char *sep;
475*e7a76fe2SMarkus Armbruster     g_autoptr(ArrayStruct) arrs = NULL;
476*e7a76fe2SMarkus Armbruster     Visitor *v;
477*e7a76fe2SMarkus Armbruster     intList *int_list;
478*e7a76fe2SMarkus Armbruster     int8List *s8_list;
479*e7a76fe2SMarkus Armbruster     int16List *s16_list;
480*e7a76fe2SMarkus Armbruster     int32List *s32_list;
481*e7a76fe2SMarkus Armbruster     int64List *s64_list;
482*e7a76fe2SMarkus Armbruster     uint8List *u8_list;
483*e7a76fe2SMarkus Armbruster     uint16List *u16_list;
484*e7a76fe2SMarkus Armbruster     uint32List *u32_list;
485*e7a76fe2SMarkus Armbruster     uint64List *u64_list;
486*e7a76fe2SMarkus Armbruster     numberList *num_list;
487*e7a76fe2SMarkus Armbruster     boolList *bool_list;
488*e7a76fe2SMarkus Armbruster     strList *str_list;
489*e7a76fe2SMarkus Armbruster 
490*e7a76fe2SMarkus Armbruster     g_string_append_printf(json, "{");
491*e7a76fe2SMarkus Armbruster 
492*e7a76fe2SMarkus Armbruster     for (i = 0; i < G_N_ELEMENTS(int_member); i++) {
493*e7a76fe2SMarkus Armbruster         g_string_append_printf(json, "'%s': [", int_member[i]);
494*e7a76fe2SMarkus Armbruster         sep = "";
495*e7a76fe2SMarkus Armbruster         for (j = 0; j < 32; j++) {
496*e7a76fe2SMarkus Armbruster             g_string_append_printf(json, "%s%d", sep, j);
497*e7a76fe2SMarkus Armbruster             sep = ", ";
498*e7a76fe2SMarkus Armbruster         }
499*e7a76fe2SMarkus Armbruster         g_string_append_printf(json, "], ");
500*e7a76fe2SMarkus Armbruster     }
501*e7a76fe2SMarkus Armbruster 
502*e7a76fe2SMarkus Armbruster     g_string_append_printf(json, "'number': [");
503*e7a76fe2SMarkus Armbruster     sep = "";
504*e7a76fe2SMarkus Armbruster     for (i = 0; i < 32; i++) {
505*e7a76fe2SMarkus Armbruster         g_string_append_printf(json, "%s%f", sep, (double)i / 3);
506*e7a76fe2SMarkus Armbruster         sep = ", ";
507*e7a76fe2SMarkus Armbruster     }
508*e7a76fe2SMarkus Armbruster     g_string_append_printf(json, "], ");
509*e7a76fe2SMarkus Armbruster 
510*e7a76fe2SMarkus Armbruster     g_string_append_printf(json, "'boolean': [");
511*e7a76fe2SMarkus Armbruster     sep = "";
512*e7a76fe2SMarkus Armbruster     for (i = 0; i < 32; i++) {
513*e7a76fe2SMarkus Armbruster         g_string_append_printf(json, "%s%s",
514*e7a76fe2SMarkus Armbruster                                sep, i % 3 == 0 ? "true" : "false");
515*e7a76fe2SMarkus Armbruster         sep = ", ";
516*e7a76fe2SMarkus Armbruster     }
517*e7a76fe2SMarkus Armbruster     g_string_append_printf(json, "], ");
518*e7a76fe2SMarkus Armbruster 
519*e7a76fe2SMarkus Armbruster     g_string_append_printf(json, "'string': [");
520*e7a76fe2SMarkus Armbruster     sep = "";
521*e7a76fe2SMarkus Armbruster     for (i = 0; i < 32; i++) {
522*e7a76fe2SMarkus Armbruster         g_string_append_printf(json, "%s'%d'", sep, i);
523*e7a76fe2SMarkus Armbruster         sep = ", ";
524*e7a76fe2SMarkus Armbruster     }
525*e7a76fe2SMarkus Armbruster     g_string_append_printf(json, "]");
526*e7a76fe2SMarkus Armbruster 
527*e7a76fe2SMarkus Armbruster     g_string_append_printf(json, "}");
528*e7a76fe2SMarkus Armbruster 
529*e7a76fe2SMarkus Armbruster     v = visitor_input_test_init_raw(data, json->str);
530*e7a76fe2SMarkus Armbruster     visit_type_ArrayStruct(v, NULL, &arrs, &error_abort);
531*e7a76fe2SMarkus Armbruster 
532*e7a76fe2SMarkus Armbruster     i = 0;
533*e7a76fe2SMarkus Armbruster     for (int_list = arrs->integer; int_list; int_list = int_list->next) {
534*e7a76fe2SMarkus Armbruster         g_assert_cmpint(int_list->value, ==, i);
535*e7a76fe2SMarkus Armbruster         i++;
536*e7a76fe2SMarkus Armbruster     }
537*e7a76fe2SMarkus Armbruster 
538*e7a76fe2SMarkus Armbruster     i = 0;
539*e7a76fe2SMarkus Armbruster     for (s8_list = arrs->s8; s8_list; s8_list = s8_list->next) {
540*e7a76fe2SMarkus Armbruster         g_assert_cmpint(s8_list->value, ==, i);
541*e7a76fe2SMarkus Armbruster         i++;
542*e7a76fe2SMarkus Armbruster     }
543*e7a76fe2SMarkus Armbruster 
544*e7a76fe2SMarkus Armbruster     i = 0;
545*e7a76fe2SMarkus Armbruster     for (s16_list = arrs->s16; s16_list; s16_list = s16_list->next) {
546*e7a76fe2SMarkus Armbruster         g_assert_cmpint(s16_list->value, ==, i);
547*e7a76fe2SMarkus Armbruster         i++;
548*e7a76fe2SMarkus Armbruster     }
549*e7a76fe2SMarkus Armbruster 
550*e7a76fe2SMarkus Armbruster     i = 0;
551*e7a76fe2SMarkus Armbruster     for (s32_list = arrs->s32; s32_list; s32_list = s32_list->next) {
552*e7a76fe2SMarkus Armbruster         g_assert_cmpint(s32_list->value, ==, i);
553*e7a76fe2SMarkus Armbruster         i++;
554*e7a76fe2SMarkus Armbruster     }
555*e7a76fe2SMarkus Armbruster 
556*e7a76fe2SMarkus Armbruster     i = 0;
557*e7a76fe2SMarkus Armbruster     for (s64_list = arrs->s64; s64_list; s64_list = s64_list->next) {
558*e7a76fe2SMarkus Armbruster         g_assert_cmpint(s64_list->value, ==, i);
559*e7a76fe2SMarkus Armbruster         i++;
560*e7a76fe2SMarkus Armbruster     }
561*e7a76fe2SMarkus Armbruster 
562*e7a76fe2SMarkus Armbruster     i = 0;
563*e7a76fe2SMarkus Armbruster     for (u8_list = arrs->u8; u8_list; u8_list = u8_list->next) {
564*e7a76fe2SMarkus Armbruster         g_assert_cmpint(u8_list->value, ==, i);
565*e7a76fe2SMarkus Armbruster         i++;
566*e7a76fe2SMarkus Armbruster     }
567*e7a76fe2SMarkus Armbruster 
568*e7a76fe2SMarkus Armbruster     i = 0;
569*e7a76fe2SMarkus Armbruster     for (u16_list = arrs->u16; u16_list; u16_list = u16_list->next) {
570*e7a76fe2SMarkus Armbruster         g_assert_cmpint(u16_list->value, ==, i);
571*e7a76fe2SMarkus Armbruster         i++;
572*e7a76fe2SMarkus Armbruster     }
573*e7a76fe2SMarkus Armbruster 
574*e7a76fe2SMarkus Armbruster     i = 0;
575*e7a76fe2SMarkus Armbruster     for (u32_list = arrs->u32; u32_list; u32_list = u32_list->next) {
576*e7a76fe2SMarkus Armbruster         g_assert_cmpint(u32_list->value, ==, i);
577*e7a76fe2SMarkus Armbruster         i++;
578*e7a76fe2SMarkus Armbruster     }
579*e7a76fe2SMarkus Armbruster 
580*e7a76fe2SMarkus Armbruster     i = 0;
581*e7a76fe2SMarkus Armbruster     for (u64_list = arrs->u64; u64_list; u64_list = u64_list->next) {
582*e7a76fe2SMarkus Armbruster         g_assert_cmpint(u64_list->value, ==, i);
583*e7a76fe2SMarkus Armbruster         i++;
584*e7a76fe2SMarkus Armbruster     }
585*e7a76fe2SMarkus Armbruster 
586*e7a76fe2SMarkus Armbruster     i = 0;
587*e7a76fe2SMarkus Armbruster     for (num_list = arrs->number; num_list; num_list = num_list->next) {
588*e7a76fe2SMarkus Armbruster         char expected[32], actual[32];
589*e7a76fe2SMarkus Armbruster 
590*e7a76fe2SMarkus Armbruster         sprintf(expected, "%.6f", (double)i / 3);
591*e7a76fe2SMarkus Armbruster         sprintf(actual, "%.6f", num_list->value);
592*e7a76fe2SMarkus Armbruster         g_assert_cmpstr(expected, ==, actual);
593*e7a76fe2SMarkus Armbruster         i++;
594*e7a76fe2SMarkus Armbruster     }
595*e7a76fe2SMarkus Armbruster 
596*e7a76fe2SMarkus Armbruster     i = 0;
597*e7a76fe2SMarkus Armbruster     for (bool_list = arrs->boolean; bool_list; bool_list = bool_list->next) {
598*e7a76fe2SMarkus Armbruster         g_assert_cmpint(bool_list->value, ==, i % 3 == 0);
599*e7a76fe2SMarkus Armbruster         i++;
600*e7a76fe2SMarkus Armbruster     }
601*e7a76fe2SMarkus Armbruster 
602*e7a76fe2SMarkus Armbruster     i = 0;
603*e7a76fe2SMarkus Armbruster     for (str_list = arrs->string; str_list; str_list = str_list->next) {
604*e7a76fe2SMarkus Armbruster         char expected[32];
605*e7a76fe2SMarkus Armbruster 
606*e7a76fe2SMarkus Armbruster         sprintf(expected, "%d", i);
607*e7a76fe2SMarkus Armbruster         g_assert_cmpstr(str_list->value, ==, expected);
608*e7a76fe2SMarkus Armbruster         i++;
609*e7a76fe2SMarkus Armbruster     }
610*e7a76fe2SMarkus Armbruster }
611*e7a76fe2SMarkus Armbruster 
61228770e05SMarkus Armbruster static void test_visitor_in_any(TestInputVisitorData *data,
61328770e05SMarkus Armbruster                                 const void *unused)
61428770e05SMarkus Armbruster {
61528770e05SMarkus Armbruster     QObject *res = NULL;
61628770e05SMarkus Armbruster     Visitor *v;
61701b2ffceSMarc-André Lureau     QNum *qnum;
61828770e05SMarkus Armbruster     QBool *qbool;
61928770e05SMarkus Armbruster     QString *qstring;
62028770e05SMarkus Armbruster     QDict *qdict;
62128770e05SMarkus Armbruster     QObject *qobj;
62201b2ffceSMarc-André Lureau     int64_t val;
62328770e05SMarkus Armbruster 
62428770e05SMarkus Armbruster     v = visitor_input_test_init(data, "-42");
62551e72bc1SEric Blake     visit_type_any(v, NULL, &res, &error_abort);
6267dc847ebSMax Reitz     qnum = qobject_to(QNum, res);
62701b2ffceSMarc-André Lureau     g_assert(qnum);
62801b2ffceSMarc-André Lureau     g_assert(qnum_get_try_int(qnum, &val));
62901b2ffceSMarc-André Lureau     g_assert_cmpint(val, ==, -42);
630cb3e7f08SMarc-André Lureau     qobject_unref(res);
63128770e05SMarkus Armbruster 
63228770e05SMarkus Armbruster     v = visitor_input_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo' }");
63351e72bc1SEric Blake     visit_type_any(v, NULL, &res, &error_abort);
6347dc847ebSMax Reitz     qdict = qobject_to(QDict, res);
63528770e05SMarkus Armbruster     g_assert(qdict && qdict_size(qdict) == 3);
63628770e05SMarkus Armbruster     qobj = qdict_get(qdict, "integer");
63728770e05SMarkus Armbruster     g_assert(qobj);
6387dc847ebSMax Reitz     qnum = qobject_to(QNum, qobj);
63901b2ffceSMarc-André Lureau     g_assert(qnum);
64001b2ffceSMarc-André Lureau     g_assert(qnum_get_try_int(qnum, &val));
64101b2ffceSMarc-André Lureau     g_assert_cmpint(val, ==, -42);
64228770e05SMarkus Armbruster     qobj = qdict_get(qdict, "boolean");
64328770e05SMarkus Armbruster     g_assert(qobj);
6447dc847ebSMax Reitz     qbool = qobject_to(QBool, qobj);
64528770e05SMarkus Armbruster     g_assert(qbool);
64628770e05SMarkus Armbruster     g_assert(qbool_get_bool(qbool) == true);
64728770e05SMarkus Armbruster     qobj = qdict_get(qdict, "string");
64828770e05SMarkus Armbruster     g_assert(qobj);
6497dc847ebSMax Reitz     qstring = qobject_to(QString, qobj);
65028770e05SMarkus Armbruster     g_assert(qstring);
65128770e05SMarkus Armbruster     g_assert_cmpstr(qstring_get_str(qstring), ==, "foo");
652cb3e7f08SMarc-André Lureau     qobject_unref(res);
65328770e05SMarkus Armbruster }
65428770e05SMarkus Armbruster 
6553df016f1SEric Blake static void test_visitor_in_null(TestInputVisitorData *data,
6563df016f1SEric Blake                                  const void *unused)
6573df016f1SEric Blake {
6583df016f1SEric Blake     Visitor *v;
6593df016f1SEric Blake     Error *err = NULL;
660d2f95f4dSMarkus Armbruster     QNull *null;
6613df016f1SEric Blake     char *tmp;
6623df016f1SEric Blake 
6633df016f1SEric Blake     /*
6643df016f1SEric Blake      * FIXME: Since QAPI doesn't know the 'null' type yet, we can't
6653df016f1SEric Blake      * test visit_type_null() by reading into a QAPI struct then
6663df016f1SEric Blake      * checking that it was populated correctly.  The best we can do
6673df016f1SEric Blake      * for now is ensure that we consumed null from the input, proven
6683df016f1SEric Blake      * by the fact that we can't re-read the key; and that we detect
6693df016f1SEric Blake      * when input is not null.
6703df016f1SEric Blake      */
6713df016f1SEric Blake 
672cbd8acf3SDaniel P. Berrange     v = visitor_input_test_init_full(data, false,
673cbd8acf3SDaniel P. Berrange                                      "{ 'a': null, 'b': '' }");
6743df016f1SEric Blake     visit_start_struct(v, NULL, NULL, 0, &error_abort);
675d2f95f4dSMarkus Armbruster     visit_type_null(v, "a", &null, &error_abort);
676d2f95f4dSMarkus Armbruster     g_assert(qobject_type(QOBJECT(null)) == QTYPE_QNULL);
677cb3e7f08SMarc-André Lureau     qobject_unref(null);
678d2f95f4dSMarkus Armbruster     visit_type_null(v, "b", &null, &err);
6793df016f1SEric Blake     error_free_or_abort(&err);
680d2f95f4dSMarkus Armbruster     g_assert(!null);
681ec95f614SMarkus Armbruster     visit_type_str(v, "c", &tmp, &err);
682ec95f614SMarkus Armbruster     error_free_or_abort(&err);
683d2f95f4dSMarkus Armbruster     g_assert(!tmp);
68415c2f669SEric Blake     visit_check_struct(v, &error_abort);
6851158bb2aSEric Blake     visit_end_struct(v, NULL);
6863df016f1SEric Blake }
6873df016f1SEric Blake 
6882fc00432SMarkus Armbruster static void test_visitor_in_union_flat(TestInputVisitorData *data,
6892fc00432SMarkus Armbruster                                        const void *unused)
6902fc00432SMarkus Armbruster {
6912fc00432SMarkus Armbruster     Visitor *v;
692221db5daSDaniel P. Berrangé     g_autoptr(UserDefFlatUnion) tmp = NULL;
69330594fe1SEric Blake     UserDefUnionBase *base;
6942fc00432SMarkus Armbruster 
6955223070cSWenchao Xia     v = visitor_input_test_init(data,
6965223070cSWenchao Xia                                 "{ 'enum1': 'value1', "
697441cbac0SMarkus Armbruster                                 "'integer': 41, "
6985223070cSWenchao Xia                                 "'string': 'str', "
6995223070cSWenchao Xia                                 "'boolean': true }");
7002fc00432SMarkus Armbruster 
70151e72bc1SEric Blake     visit_type_UserDefFlatUnion(v, NULL, &tmp, &error_abort);
7020f61af3eSMarkus Armbruster     g_assert_cmpint(tmp->enum1, ==, ENUM_ONE_VALUE1);
7035223070cSWenchao Xia     g_assert_cmpstr(tmp->string, ==, "str");
704441cbac0SMarkus Armbruster     g_assert_cmpint(tmp->integer, ==, 41);
705544a3731SEric Blake     g_assert_cmpint(tmp->u.value1.boolean, ==, true);
70630594fe1SEric Blake 
70730594fe1SEric Blake     base = qapi_UserDefFlatUnion_base(tmp);
70830594fe1SEric Blake     g_assert(&base->enum1 == &tmp->enum1);
7092fc00432SMarkus Armbruster }
7102fc00432SMarkus Armbruster 
711ab045267SEric Blake static void test_visitor_in_alternate(TestInputVisitorData *data,
7122c38b600SMarkus Armbruster                                       const void *unused)
7132c38b600SMarkus Armbruster {
7142c38b600SMarkus Armbruster     Visitor *v;
715ab045267SEric Blake     UserDefAlternate *tmp;
71668d07839SEric Blake     WrapAlternate *wrap;
7172c38b600SMarkus Armbruster 
7182c38b600SMarkus Armbruster     v = visitor_input_test_init(data, "42");
71951e72bc1SEric Blake     visit_type_UserDefAlternate(v, NULL, &tmp, &error_abort);
72001b2ffceSMarc-André Lureau     g_assert_cmpint(tmp->type, ==, QTYPE_QNUM);
721c363acefSEric Blake     g_assert_cmpint(tmp->u.i, ==, 42);
722ab045267SEric Blake     qapi_free_UserDefAlternate(tmp);
7239c51b441SEric Blake 
7248168ca8eSMarkus Armbruster     v = visitor_input_test_init(data, "'value1'");
72551e72bc1SEric Blake     visit_type_UserDefAlternate(v, NULL, &tmp, &error_abort);
7260426d53cSEric Blake     g_assert_cmpint(tmp->type, ==, QTYPE_QSTRING);
7278168ca8eSMarkus Armbruster     g_assert_cmpint(tmp->u.e, ==, ENUM_ONE_VALUE1);
7289c51b441SEric Blake     qapi_free_UserDefAlternate(tmp);
7299c51b441SEric Blake 
7304d2d5c41SMarkus Armbruster     v = visitor_input_test_init(data, "null");
7314d2d5c41SMarkus Armbruster     visit_type_UserDefAlternate(v, NULL, &tmp, &error_abort);
7324d2d5c41SMarkus Armbruster     g_assert_cmpint(tmp->type, ==, QTYPE_QNULL);
7334d2d5c41SMarkus Armbruster     qapi_free_UserDefAlternate(tmp);
7344d2d5c41SMarkus Armbruster 
73568d07839SEric Blake     v = visitor_input_test_init(data, "{'integer':1, 'string':'str', "
73668d07839SEric Blake                                 "'enum1':'value1', 'boolean':true}");
73768d07839SEric Blake     visit_type_UserDefAlternate(v, NULL, &tmp, &error_abort);
73868d07839SEric Blake     g_assert_cmpint(tmp->type, ==, QTYPE_QDICT);
739becceedcSEric Blake     g_assert_cmpint(tmp->u.udfu.integer, ==, 1);
740becceedcSEric Blake     g_assert_cmpstr(tmp->u.udfu.string, ==, "str");
741becceedcSEric Blake     g_assert_cmpint(tmp->u.udfu.enum1, ==, ENUM_ONE_VALUE1);
742544a3731SEric Blake     g_assert_cmpint(tmp->u.udfu.u.value1.boolean, ==, true);
743544a3731SEric Blake     g_assert_cmpint(tmp->u.udfu.u.value1.has_a_b, ==, false);
74468d07839SEric Blake     qapi_free_UserDefAlternate(tmp);
74568d07839SEric Blake 
74668d07839SEric Blake     v = visitor_input_test_init(data, "{ 'alt': 42 }");
74768d07839SEric Blake     visit_type_WrapAlternate(v, NULL, &wrap, &error_abort);
74801b2ffceSMarc-André Lureau     g_assert_cmpint(wrap->alt->type, ==, QTYPE_QNUM);
74968d07839SEric Blake     g_assert_cmpint(wrap->alt->u.i, ==, 42);
75068d07839SEric Blake     qapi_free_WrapAlternate(wrap);
75168d07839SEric Blake 
7528168ca8eSMarkus Armbruster     v = visitor_input_test_init(data, "{ 'alt': 'value1' }");
75368d07839SEric Blake     visit_type_WrapAlternate(v, NULL, &wrap, &error_abort);
75468d07839SEric Blake     g_assert_cmpint(wrap->alt->type, ==, QTYPE_QSTRING);
7558168ca8eSMarkus Armbruster     g_assert_cmpint(wrap->alt->u.e, ==, ENUM_ONE_VALUE1);
75668d07839SEric Blake     qapi_free_WrapAlternate(wrap);
75768d07839SEric Blake 
75868d07839SEric Blake     v = visitor_input_test_init(data, "{ 'alt': {'integer':1, 'string':'str', "
75968d07839SEric Blake                                 "'enum1':'value1', 'boolean':true} }");
76068d07839SEric Blake     visit_type_WrapAlternate(v, NULL, &wrap, &error_abort);
76168d07839SEric Blake     g_assert_cmpint(wrap->alt->type, ==, QTYPE_QDICT);
762becceedcSEric Blake     g_assert_cmpint(wrap->alt->u.udfu.integer, ==, 1);
763becceedcSEric Blake     g_assert_cmpstr(wrap->alt->u.udfu.string, ==, "str");
764becceedcSEric Blake     g_assert_cmpint(wrap->alt->u.udfu.enum1, ==, ENUM_ONE_VALUE1);
765544a3731SEric Blake     g_assert_cmpint(wrap->alt->u.udfu.u.value1.boolean, ==, true);
766544a3731SEric Blake     g_assert_cmpint(wrap->alt->u.udfu.u.value1.has_a_b, ==, false);
76768d07839SEric Blake     qapi_free_WrapAlternate(wrap);
7689c51b441SEric Blake }
7699c51b441SEric Blake 
7709c51b441SEric Blake static void test_visitor_in_alternate_number(TestInputVisitorData *data,
7719c51b441SEric Blake                                              const void *unused)
7729c51b441SEric Blake {
7739c51b441SEric Blake     Visitor *v;
7749c51b441SEric Blake     Error *err = NULL;
7758168ca8eSMarkus Armbruster     AltEnumBool *aeb;
7768168ca8eSMarkus Armbruster     AltEnumNum *aen;
7778168ca8eSMarkus Armbruster     AltNumEnum *ans;
7788168ca8eSMarkus Armbruster     AltEnumInt *asi;
7799c51b441SEric Blake 
7809c51b441SEric Blake     /* Parsing an int */
7819c51b441SEric Blake 
7829c51b441SEric Blake     v = visitor_input_test_init(data, "42");
7838168ca8eSMarkus Armbruster     visit_type_AltEnumBool(v, NULL, &aeb, &err);
784a12a5a1aSEric Blake     error_free_or_abort(&err);
7858168ca8eSMarkus Armbruster     qapi_free_AltEnumBool(aeb);
7869c51b441SEric Blake 
7879c51b441SEric Blake     v = visitor_input_test_init(data, "42");
7888168ca8eSMarkus Armbruster     visit_type_AltEnumNum(v, NULL, &aen, &error_abort);
78901b2ffceSMarc-André Lureau     g_assert_cmpint(aen->type, ==, QTYPE_QNUM);
7908168ca8eSMarkus Armbruster     g_assert_cmpfloat(aen->u.n, ==, 42);
7918168ca8eSMarkus Armbruster     qapi_free_AltEnumNum(aen);
7929c51b441SEric Blake 
7939c51b441SEric Blake     v = visitor_input_test_init(data, "42");
7948168ca8eSMarkus Armbruster     visit_type_AltNumEnum(v, NULL, &ans, &error_abort);
79501b2ffceSMarc-André Lureau     g_assert_cmpint(ans->type, ==, QTYPE_QNUM);
796d00341afSEric Blake     g_assert_cmpfloat(ans->u.n, ==, 42);
7978168ca8eSMarkus Armbruster     qapi_free_AltNumEnum(ans);
7989c51b441SEric Blake 
7999c51b441SEric Blake     v = visitor_input_test_init(data, "42");
8008168ca8eSMarkus Armbruster     visit_type_AltEnumInt(v, NULL, &asi, &error_abort);
80101b2ffceSMarc-André Lureau     g_assert_cmpint(asi->type, ==, QTYPE_QNUM);
802c363acefSEric Blake     g_assert_cmpint(asi->u.i, ==, 42);
8038168ca8eSMarkus Armbruster     qapi_free_AltEnumInt(asi);
8049c51b441SEric Blake 
8059c51b441SEric Blake     /* Parsing a double */
8069c51b441SEric Blake 
8079c51b441SEric Blake     v = visitor_input_test_init(data, "42.5");
8088168ca8eSMarkus Armbruster     visit_type_AltEnumBool(v, NULL, &aeb, &err);
809a12a5a1aSEric Blake     error_free_or_abort(&err);
8108168ca8eSMarkus Armbruster     qapi_free_AltEnumBool(aeb);
8119c51b441SEric Blake 
8129c51b441SEric Blake     v = visitor_input_test_init(data, "42.5");
8138168ca8eSMarkus Armbruster     visit_type_AltEnumNum(v, NULL, &aen, &error_abort);
81401b2ffceSMarc-André Lureau     g_assert_cmpint(aen->type, ==, QTYPE_QNUM);
8158168ca8eSMarkus Armbruster     g_assert_cmpfloat(aen->u.n, ==, 42.5);
8168168ca8eSMarkus Armbruster     qapi_free_AltEnumNum(aen);
8179c51b441SEric Blake 
8189c51b441SEric Blake     v = visitor_input_test_init(data, "42.5");
8198168ca8eSMarkus Armbruster     visit_type_AltNumEnum(v, NULL, &ans, &error_abort);
82001b2ffceSMarc-André Lureau     g_assert_cmpint(ans->type, ==, QTYPE_QNUM);
821c363acefSEric Blake     g_assert_cmpfloat(ans->u.n, ==, 42.5);
8228168ca8eSMarkus Armbruster     qapi_free_AltNumEnum(ans);
8239c51b441SEric Blake 
8249c51b441SEric Blake     v = visitor_input_test_init(data, "42.5");
8258168ca8eSMarkus Armbruster     visit_type_AltEnumInt(v, NULL, &asi, &err);
826a12a5a1aSEric Blake     error_free_or_abort(&err);
8278168ca8eSMarkus Armbruster     qapi_free_AltEnumInt(asi);
8282c38b600SMarkus Armbruster }
8292c38b600SMarkus Armbruster 
830d88f5fd1SLuiz Capitulino static void input_visitor_test_add(const char *testpath,
831b1d2e5f1SDaniel P. Berrange                                    const void *user_data,
832b1d2e5f1SDaniel P. Berrange                                    void (*test_func)(TestInputVisitorData *data,
833b1d2e5f1SDaniel P. Berrange                                                      const void *user_data))
834d88f5fd1SLuiz Capitulino {
835b1d2e5f1SDaniel P. Berrange     g_test_add(testpath, TestInputVisitorData, user_data, NULL, test_func,
836d88f5fd1SLuiz Capitulino                visitor_input_teardown);
837d88f5fd1SLuiz Capitulino }
838d88f5fd1SLuiz Capitulino 
8393dcf71f6SPaolo Bonzini static void test_visitor_in_errors(TestInputVisitorData *data,
8403dcf71f6SPaolo Bonzini                                    const void *unused)
8413dcf71f6SPaolo Bonzini {
8423dcf71f6SPaolo Bonzini     TestStruct *p = NULL;
843e940f543SMarkus Armbruster     Error *err = NULL;
8443dcf71f6SPaolo Bonzini     Visitor *v;
845dd5ee2c2SEric Blake     strList *q = NULL;
8469b4e38feSEric Blake     UserDefTwo *r = NULL;
8479b4e38feSEric Blake     WrapAlternate *s = NULL;
8483dcf71f6SPaolo Bonzini 
849dd5ee2c2SEric Blake     v = visitor_input_test_init(data, "{ 'integer': false, 'boolean': 'foo', "
850dd5ee2c2SEric Blake                                 "'string': -42 }");
8513dcf71f6SPaolo Bonzini 
85251e72bc1SEric Blake     visit_type_TestStruct(v, NULL, &p, &err);
853a12a5a1aSEric Blake     error_free_or_abort(&err);
85468ab47e4SEric Blake     g_assert(!p);
855dd5ee2c2SEric Blake 
856dd5ee2c2SEric Blake     v = visitor_input_test_init(data, "[ '1', '2', false, '3' ]");
85751e72bc1SEric Blake     visit_type_strList(v, NULL, &q, &err);
858dd5ee2c2SEric Blake     error_free_or_abort(&err);
85968ab47e4SEric Blake     assert(!q);
8609b4e38feSEric Blake 
8619b4e38feSEric Blake     v = visitor_input_test_init(data, "{ 'str':'hi' }");
8629b4e38feSEric Blake     visit_type_UserDefTwo(v, NULL, &r, &err);
8639b4e38feSEric Blake     error_free_or_abort(&err);
8649b4e38feSEric Blake     assert(!r);
8659b4e38feSEric Blake 
8669b4e38feSEric Blake     v = visitor_input_test_init(data, "{ }");
8679b4e38feSEric Blake     visit_type_WrapAlternate(v, NULL, &s, &err);
8689b4e38feSEric Blake     error_free_or_abort(&err);
8699b4e38feSEric Blake     assert(!s);
8703dcf71f6SPaolo Bonzini }
8713dcf71f6SPaolo Bonzini 
8722533377cSEric Blake static void test_visitor_in_wrong_type(TestInputVisitorData *data,
8732533377cSEric Blake                                        const void *unused)
8742533377cSEric Blake {
8752533377cSEric Blake     TestStruct *p = NULL;
8762533377cSEric Blake     Visitor *v;
8772533377cSEric Blake     strList *q = NULL;
8782533377cSEric Blake     int64_t i;
8792533377cSEric Blake     Error *err = NULL;
8802533377cSEric Blake 
8812533377cSEric Blake     /* Make sure arrays and structs cannot be confused */
8822533377cSEric Blake 
8832533377cSEric Blake     v = visitor_input_test_init(data, "[]");
88451e72bc1SEric Blake     visit_type_TestStruct(v, NULL, &p, &err);
8852533377cSEric Blake     error_free_or_abort(&err);
8862533377cSEric Blake     g_assert(!p);
8872533377cSEric Blake 
8882533377cSEric Blake     v = visitor_input_test_init(data, "{}");
88951e72bc1SEric Blake     visit_type_strList(v, NULL, &q, &err);
8902533377cSEric Blake     error_free_or_abort(&err);
8912533377cSEric Blake     assert(!q);
8922533377cSEric Blake 
8932533377cSEric Blake     /* Make sure primitives and struct cannot be confused */
8942533377cSEric Blake 
8952533377cSEric Blake     v = visitor_input_test_init(data, "1");
89651e72bc1SEric Blake     visit_type_TestStruct(v, NULL, &p, &err);
8972533377cSEric Blake     error_free_or_abort(&err);
8982533377cSEric Blake     g_assert(!p);
8992533377cSEric Blake 
9002533377cSEric Blake     v = visitor_input_test_init(data, "{}");
90151e72bc1SEric Blake     visit_type_int(v, NULL, &i, &err);
9022533377cSEric Blake     error_free_or_abort(&err);
9032533377cSEric Blake 
9042533377cSEric Blake     /* Make sure primitives and arrays cannot be confused */
9052533377cSEric Blake 
9062533377cSEric Blake     v = visitor_input_test_init(data, "1");
90751e72bc1SEric Blake     visit_type_strList(v, NULL, &q, &err);
9082533377cSEric Blake     error_free_or_abort(&err);
9092533377cSEric Blake     assert(!q);
9102533377cSEric Blake 
9112533377cSEric Blake     v = visitor_input_test_init(data, "[]");
91251e72bc1SEric Blake     visit_type_int(v, NULL, &i, &err);
9132533377cSEric Blake     error_free_or_abort(&err);
9142533377cSEric Blake }
9152533377cSEric Blake 
91677c47de2SMarkus Armbruster static void test_visitor_in_fail_struct(TestInputVisitorData *data,
91777c47de2SMarkus Armbruster                                         const void *unused)
91877c47de2SMarkus Armbruster {
91977c47de2SMarkus Armbruster     TestStruct *p = NULL;
92077c47de2SMarkus Armbruster     Error *err = NULL;
92177c47de2SMarkus Armbruster     Visitor *v;
92277c47de2SMarkus Armbruster 
92377c47de2SMarkus Armbruster     v = visitor_input_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo', 'extra': 42 }");
92477c47de2SMarkus Armbruster 
92577c47de2SMarkus Armbruster     visit_type_TestStruct(v, NULL, &p, &err);
92677c47de2SMarkus Armbruster     error_free_or_abort(&err);
92777c47de2SMarkus Armbruster     g_assert(!p);
92877c47de2SMarkus Armbruster }
92977c47de2SMarkus Armbruster 
93077c47de2SMarkus Armbruster static void test_visitor_in_fail_struct_nested(TestInputVisitorData *data,
93177c47de2SMarkus Armbruster                                                const void *unused)
93277c47de2SMarkus Armbruster {
93377c47de2SMarkus Armbruster     UserDefTwo *udp = NULL;
93477c47de2SMarkus Armbruster     Error *err = NULL;
93577c47de2SMarkus Armbruster     Visitor *v;
93677c47de2SMarkus Armbruster 
93777c47de2SMarkus Armbruster     v = visitor_input_test_init(data, "{ 'string0': 'string0', 'dict1': { 'string1': 'string1', 'dict2': { 'userdef1': { 'integer': 42, 'string': 'string', 'extra': [42, 23, {'foo':'bar'}] }, 'string2': 'string2'}}}");
93877c47de2SMarkus Armbruster 
93977c47de2SMarkus Armbruster     visit_type_UserDefTwo(v, NULL, &udp, &err);
94077c47de2SMarkus Armbruster     error_free_or_abort(&err);
94177c47de2SMarkus Armbruster     g_assert(!udp);
94277c47de2SMarkus Armbruster }
94377c47de2SMarkus Armbruster 
94477c47de2SMarkus Armbruster static void test_visitor_in_fail_struct_in_list(TestInputVisitorData *data,
94577c47de2SMarkus Armbruster                                                 const void *unused)
94677c47de2SMarkus Armbruster {
94777c47de2SMarkus Armbruster     UserDefOneList *head = NULL;
94877c47de2SMarkus Armbruster     Error *err = NULL;
94977c47de2SMarkus Armbruster     Visitor *v;
95077c47de2SMarkus Armbruster 
95177c47de2SMarkus Armbruster     v = visitor_input_test_init(data, "[ { 'string': 'string0', 'integer': 42 }, { 'string': 'string1', 'integer': 43 }, { 'string': 'string2', 'integer': 44, 'extra': 'ggg' } ]");
95277c47de2SMarkus Armbruster 
95377c47de2SMarkus Armbruster     visit_type_UserDefOneList(v, NULL, &head, &err);
95477c47de2SMarkus Armbruster     error_free_or_abort(&err);
95577c47de2SMarkus Armbruster     g_assert(!head);
95677c47de2SMarkus Armbruster }
95777c47de2SMarkus Armbruster 
95877c47de2SMarkus Armbruster static void test_visitor_in_fail_struct_missing(TestInputVisitorData *data,
95977c47de2SMarkus Armbruster                                                 const void *unused)
96077c47de2SMarkus Armbruster {
96177c47de2SMarkus Armbruster     Error *err = NULL;
96277c47de2SMarkus Armbruster     Visitor *v;
96377c47de2SMarkus Armbruster     QObject *any;
964d2f95f4dSMarkus Armbruster     QNull *null;
96577c47de2SMarkus Armbruster     GenericAlternate *alt;
96677c47de2SMarkus Armbruster     bool present;
96777c47de2SMarkus Armbruster     int en;
96877c47de2SMarkus Armbruster     int64_t i64;
96977c47de2SMarkus Armbruster     uint32_t u32;
97077c47de2SMarkus Armbruster     int8_t i8;
97177c47de2SMarkus Armbruster     char *str;
97277c47de2SMarkus Armbruster     double dbl;
97377c47de2SMarkus Armbruster 
97486ca0dbeSMarkus Armbruster     v = visitor_input_test_init(data, "{ 'sub': [ {} ] }");
97577c47de2SMarkus Armbruster     visit_start_struct(v, NULL, NULL, 0, &error_abort);
97677c47de2SMarkus Armbruster     visit_start_struct(v, "struct", NULL, 0, &err);
97777c47de2SMarkus Armbruster     error_free_or_abort(&err);
97877c47de2SMarkus Armbruster     visit_start_list(v, "list", NULL, 0, &err);
97977c47de2SMarkus Armbruster     error_free_or_abort(&err);
98060390d2dSMarc-André Lureau     visit_start_alternate(v, "alternate", &alt, sizeof(*alt), &err);
98177c47de2SMarkus Armbruster     error_free_or_abort(&err);
98277c47de2SMarkus Armbruster     visit_optional(v, "optional", &present);
98377c47de2SMarkus Armbruster     g_assert(!present);
984f7abe0ecSMarc-André Lureau     visit_type_enum(v, "enum", &en, &EnumOne_lookup, &err);
98577c47de2SMarkus Armbruster     error_free_or_abort(&err);
98677c47de2SMarkus Armbruster     visit_type_int(v, "i64", &i64, &err);
98777c47de2SMarkus Armbruster     error_free_or_abort(&err);
98877c47de2SMarkus Armbruster     visit_type_uint32(v, "u32", &u32, &err);
98977c47de2SMarkus Armbruster     error_free_or_abort(&err);
99077c47de2SMarkus Armbruster     visit_type_int8(v, "i8", &i8, &err);
99177c47de2SMarkus Armbruster     error_free_or_abort(&err);
99277c47de2SMarkus Armbruster     visit_type_str(v, "i8", &str, &err);
99377c47de2SMarkus Armbruster     error_free_or_abort(&err);
99477c47de2SMarkus Armbruster     visit_type_number(v, "dbl", &dbl, &err);
99577c47de2SMarkus Armbruster     error_free_or_abort(&err);
99677c47de2SMarkus Armbruster     visit_type_any(v, "any", &any, &err);
99777c47de2SMarkus Armbruster     error_free_or_abort(&err);
998d2f95f4dSMarkus Armbruster     visit_type_null(v, "null", &null, &err);
99977c47de2SMarkus Armbruster     error_free_or_abort(&err);
100086ca0dbeSMarkus Armbruster     visit_start_list(v, "sub", NULL, 0, &error_abort);
100186ca0dbeSMarkus Armbruster     visit_start_struct(v, NULL, NULL, 0, &error_abort);
100286ca0dbeSMarkus Armbruster     visit_type_int(v, "i64", &i64, &err);
100386ca0dbeSMarkus Armbruster     error_free_or_abort(&err);
100486ca0dbeSMarkus Armbruster     visit_end_struct(v, NULL);
100586ca0dbeSMarkus Armbruster     visit_end_list(v, NULL);
100677c47de2SMarkus Armbruster     visit_end_struct(v, NULL);
100777c47de2SMarkus Armbruster }
100877c47de2SMarkus Armbruster 
10099cb8ef36SMarkus Armbruster static void test_visitor_in_fail_list(TestInputVisitorData *data,
10109cb8ef36SMarkus Armbruster                                       const void *unused)
10119cb8ef36SMarkus Armbruster {
10129cb8ef36SMarkus Armbruster     int64_t i64 = -1;
1013a4a1c70dSMarkus Armbruster     Error *err = NULL;
10149cb8ef36SMarkus Armbruster     Visitor *v;
10159cb8ef36SMarkus Armbruster 
10169cb8ef36SMarkus Armbruster     /* Unvisited list tail */
10179cb8ef36SMarkus Armbruster 
10189cb8ef36SMarkus Armbruster     v = visitor_input_test_init(data, "[ 1, 2, 3 ]");
10199cb8ef36SMarkus Armbruster 
10209cb8ef36SMarkus Armbruster     visit_start_list(v, NULL, NULL, 0, &error_abort);
10219cb8ef36SMarkus Armbruster     visit_type_int(v, NULL, &i64, &error_abort);
10229cb8ef36SMarkus Armbruster     g_assert_cmpint(i64, ==, 1);
10239cb8ef36SMarkus Armbruster     visit_type_int(v, NULL, &i64, &error_abort);
10249cb8ef36SMarkus Armbruster     g_assert_cmpint(i64, ==, 2);
1025a4a1c70dSMarkus Armbruster     visit_check_list(v, &err);
1026a4a1c70dSMarkus Armbruster     error_free_or_abort(&err);
10279cb8ef36SMarkus Armbruster     visit_end_list(v, NULL);
1028a9416dc6SMarkus Armbruster 
1029a9416dc6SMarkus Armbruster     /* Visit beyond end of list */
1030a9416dc6SMarkus Armbruster     v = visitor_input_test_init(data, "[]");
1031a9416dc6SMarkus Armbruster 
1032a9416dc6SMarkus Armbruster     visit_start_list(v, NULL, NULL, 0, &error_abort);
1033a9416dc6SMarkus Armbruster     visit_type_int(v, NULL, &i64, &err);
1034a9416dc6SMarkus Armbruster     error_free_or_abort(&err);
1035a9416dc6SMarkus Armbruster     visit_end_list(v, NULL);
10369cb8ef36SMarkus Armbruster }
10379cb8ef36SMarkus Armbruster 
10389cb8ef36SMarkus Armbruster static void test_visitor_in_fail_list_nested(TestInputVisitorData *data,
10399cb8ef36SMarkus Armbruster                                              const void *unused)
10409cb8ef36SMarkus Armbruster {
10419cb8ef36SMarkus Armbruster     int64_t i64 = -1;
1042a4a1c70dSMarkus Armbruster     Error *err = NULL;
10439cb8ef36SMarkus Armbruster     Visitor *v;
10449cb8ef36SMarkus Armbruster 
10459cb8ef36SMarkus Armbruster     /* Unvisited nested list tail */
10469cb8ef36SMarkus Armbruster 
10479cb8ef36SMarkus Armbruster     v = visitor_input_test_init(data, "[ 0, [ 1, 2, 3 ] ]");
10489cb8ef36SMarkus Armbruster 
10499cb8ef36SMarkus Armbruster     visit_start_list(v, NULL, NULL, 0, &error_abort);
10509cb8ef36SMarkus Armbruster     visit_type_int(v, NULL, &i64, &error_abort);
10519cb8ef36SMarkus Armbruster     g_assert_cmpint(i64, ==, 0);
10529cb8ef36SMarkus Armbruster     visit_start_list(v, NULL, NULL, 0, &error_abort);
10539cb8ef36SMarkus Armbruster     visit_type_int(v, NULL, &i64, &error_abort);
10549cb8ef36SMarkus Armbruster     g_assert_cmpint(i64, ==, 1);
1055a4a1c70dSMarkus Armbruster     visit_check_list(v, &err);
1056a4a1c70dSMarkus Armbruster     error_free_or_abort(&err);
10579cb8ef36SMarkus Armbruster     visit_end_list(v, NULL);
1058a4a1c70dSMarkus Armbruster     visit_check_list(v, &error_abort);
10599cb8ef36SMarkus Armbruster     visit_end_list(v, NULL);
10609cb8ef36SMarkus Armbruster }
10619cb8ef36SMarkus Armbruster 
106277c47de2SMarkus Armbruster static void test_visitor_in_fail_union_flat(TestInputVisitorData *data,
106377c47de2SMarkus Armbruster                                             const void *unused)
106477c47de2SMarkus Armbruster {
106577c47de2SMarkus Armbruster     UserDefFlatUnion *tmp = NULL;
106677c47de2SMarkus Armbruster     Error *err = NULL;
106777c47de2SMarkus Armbruster     Visitor *v;
106877c47de2SMarkus Armbruster 
1069*e7a76fe2SMarkus Armbruster     v = visitor_input_test_init(data, "{ 'enum1': 'value2', 'string': 'c', 'integer': 41, 'boolean': true }");
107077c47de2SMarkus Armbruster 
107177c47de2SMarkus Armbruster     visit_type_UserDefFlatUnion(v, NULL, &tmp, &err);
107277c47de2SMarkus Armbruster     error_free_or_abort(&err);
107377c47de2SMarkus Armbruster     g_assert(!tmp);
107477c47de2SMarkus Armbruster }
107577c47de2SMarkus Armbruster 
107677c47de2SMarkus Armbruster static void test_visitor_in_fail_union_flat_no_discrim(TestInputVisitorData *data,
107777c47de2SMarkus Armbruster                                                        const void *unused)
107877c47de2SMarkus Armbruster {
107977c47de2SMarkus Armbruster     UserDefFlatUnion2 *tmp = NULL;
108077c47de2SMarkus Armbruster     Error *err = NULL;
108177c47de2SMarkus Armbruster     Visitor *v;
108277c47de2SMarkus Armbruster 
108377c47de2SMarkus Armbruster     /* test situation where discriminator field ('enum1' here) is missing */
108477c47de2SMarkus Armbruster     v = visitor_input_test_init(data, "{ 'integer': 42, 'string': 'c', 'string1': 'd', 'string2': 'e' }");
108577c47de2SMarkus Armbruster 
108677c47de2SMarkus Armbruster     visit_type_UserDefFlatUnion2(v, NULL, &tmp, &err);
108777c47de2SMarkus Armbruster     error_free_or_abort(&err);
108877c47de2SMarkus Armbruster     g_assert(!tmp);
108977c47de2SMarkus Armbruster }
109077c47de2SMarkus Armbruster 
109177c47de2SMarkus Armbruster static void test_visitor_in_fail_alternate(TestInputVisitorData *data,
109277c47de2SMarkus Armbruster                                            const void *unused)
109377c47de2SMarkus Armbruster {
109477c47de2SMarkus Armbruster     UserDefAlternate *tmp;
109577c47de2SMarkus Armbruster     Visitor *v;
109677c47de2SMarkus Armbruster     Error *err = NULL;
109777c47de2SMarkus Armbruster 
109877c47de2SMarkus Armbruster     v = visitor_input_test_init(data, "3.14");
109977c47de2SMarkus Armbruster 
110077c47de2SMarkus Armbruster     visit_type_UserDefAlternate(v, NULL, &tmp, &err);
110177c47de2SMarkus Armbruster     error_free_or_abort(&err);
110277c47de2SMarkus Armbruster     g_assert(!tmp);
110377c47de2SMarkus Armbruster }
110477c47de2SMarkus Armbruster 
110577c47de2SMarkus Armbruster static void do_test_visitor_in_qmp_introspect(TestInputVisitorData *data,
11067d0f982bSMarc-André Lureau                                               const QLitObject *qlit)
110777c47de2SMarkus Armbruster {
1108221db5daSDaniel P. Berrangé     g_autoptr(SchemaInfoList) schema = NULL;
11097d0f982bSMarc-André Lureau     QObject *obj = qobject_from_qlit(qlit);
111077c47de2SMarkus Armbruster     Visitor *v;
111177c47de2SMarkus Armbruster 
11127d0f982bSMarc-André Lureau     v = qobject_input_visitor_new(obj);
111377c47de2SMarkus Armbruster 
111477c47de2SMarkus Armbruster     visit_type_SchemaInfoList(v, NULL, &schema, &error_abort);
111577c47de2SMarkus Armbruster     g_assert(schema);
111677c47de2SMarkus Armbruster 
1117cb3e7f08SMarc-André Lureau     qobject_unref(obj);
11187d0f982bSMarc-André Lureau     visit_free(v);
111977c47de2SMarkus Armbruster }
112077c47de2SMarkus Armbruster 
112177c47de2SMarkus Armbruster static void test_visitor_in_qmp_introspect(TestInputVisitorData *data,
112277c47de2SMarkus Armbruster                                            const void *unused)
112377c47de2SMarkus Armbruster {
11247d0f982bSMarc-André Lureau     do_test_visitor_in_qmp_introspect(data, &test_qmp_schema_qlit);
112577c47de2SMarkus Armbruster }
112677c47de2SMarkus Armbruster 
1127d88f5fd1SLuiz Capitulino int main(int argc, char **argv)
1128d88f5fd1SLuiz Capitulino {
1129d88f5fd1SLuiz Capitulino     g_test_init(&argc, &argv, NULL);
1130d88f5fd1SLuiz Capitulino 
1131d88f5fd1SLuiz Capitulino     input_visitor_test_add("/visitor/input/int",
1132b1d2e5f1SDaniel P. Berrange                            NULL, test_visitor_in_int);
11334bc0c94dSMarkus Armbruster     input_visitor_test_add("/visitor/input/uint",
11344bc0c94dSMarkus Armbruster                            NULL, test_visitor_in_uint);
1135e92cfa0dSMichael Roth     input_visitor_test_add("/visitor/input/int_overflow",
1136b1d2e5f1SDaniel P. Berrange                            NULL, test_visitor_in_int_overflow);
1137cbd8acf3SDaniel P. Berrange     input_visitor_test_add("/visitor/input/int_keyval",
1138cbd8acf3SDaniel P. Berrange                            NULL, test_visitor_in_int_keyval);
1139cbd8acf3SDaniel P. Berrange     input_visitor_test_add("/visitor/input/int_str_keyval",
1140cbd8acf3SDaniel P. Berrange                            NULL, test_visitor_in_int_str_keyval);
1141cbd8acf3SDaniel P. Berrange     input_visitor_test_add("/visitor/input/int_str_fail",
1142cbd8acf3SDaniel P. Berrange                            NULL, test_visitor_in_int_str_fail);
1143d88f5fd1SLuiz Capitulino     input_visitor_test_add("/visitor/input/bool",
1144b1d2e5f1SDaniel P. Berrange                            NULL, test_visitor_in_bool);
1145cbd8acf3SDaniel P. Berrange     input_visitor_test_add("/visitor/input/bool_keyval",
1146cbd8acf3SDaniel P. Berrange                            NULL, test_visitor_in_bool_keyval);
1147cbd8acf3SDaniel P. Berrange     input_visitor_test_add("/visitor/input/bool_str_keyval",
1148cbd8acf3SDaniel P. Berrange                            NULL, test_visitor_in_bool_str_keyval);
1149cbd8acf3SDaniel P. Berrange     input_visitor_test_add("/visitor/input/bool_str_fail",
1150cbd8acf3SDaniel P. Berrange                            NULL, test_visitor_in_bool_str_fail);
1151d88f5fd1SLuiz Capitulino     input_visitor_test_add("/visitor/input/number",
1152b1d2e5f1SDaniel P. Berrange                            NULL, test_visitor_in_number);
1153c1214ad3SMarc-André Lureau     input_visitor_test_add("/visitor/input/large_number",
1154c1214ad3SMarc-André Lureau                            NULL, test_visitor_in_large_number);
1155cbd8acf3SDaniel P. Berrange     input_visitor_test_add("/visitor/input/number_keyval",
1156cbd8acf3SDaniel P. Berrange                            NULL, test_visitor_in_number_keyval);
1157cbd8acf3SDaniel P. Berrange     input_visitor_test_add("/visitor/input/number_str_keyval",
1158cbd8acf3SDaniel P. Berrange                            NULL, test_visitor_in_number_str_keyval);
1159cbd8acf3SDaniel P. Berrange     input_visitor_test_add("/visitor/input/number_str_fail",
1160cbd8acf3SDaniel P. Berrange                            NULL, test_visitor_in_number_str_fail);
1161cbd8acf3SDaniel P. Berrange     input_visitor_test_add("/visitor/input/size_str_keyval",
1162cbd8acf3SDaniel P. Berrange                            NULL, test_visitor_in_size_str_keyval);
1163cbd8acf3SDaniel P. Berrange     input_visitor_test_add("/visitor/input/size_str_fail",
1164cbd8acf3SDaniel P. Berrange                            NULL, test_visitor_in_size_str_fail);
1165d88f5fd1SLuiz Capitulino     input_visitor_test_add("/visitor/input/string",
1166b1d2e5f1SDaniel P. Berrange                            NULL, test_visitor_in_string);
1167d88f5fd1SLuiz Capitulino     input_visitor_test_add("/visitor/input/enum",
1168b1d2e5f1SDaniel P. Berrange                            NULL, test_visitor_in_enum);
1169d88f5fd1SLuiz Capitulino     input_visitor_test_add("/visitor/input/struct",
1170b1d2e5f1SDaniel P. Berrange                            NULL, test_visitor_in_struct);
1171d88f5fd1SLuiz Capitulino     input_visitor_test_add("/visitor/input/struct-nested",
1172b1d2e5f1SDaniel P. Berrange                            NULL, test_visitor_in_struct_nested);
1173*e7a76fe2SMarkus Armbruster     input_visitor_test_add("/visitor/input/list2",
1174*e7a76fe2SMarkus Armbruster                            NULL, test_visitor_in_list_struct);
1175d88f5fd1SLuiz Capitulino     input_visitor_test_add("/visitor/input/list",
1176b1d2e5f1SDaniel P. Berrange                            NULL, test_visitor_in_list);
117728770e05SMarkus Armbruster     input_visitor_test_add("/visitor/input/any",
1178b1d2e5f1SDaniel P. Berrange                            NULL, test_visitor_in_any);
11793df016f1SEric Blake     input_visitor_test_add("/visitor/input/null",
1180b1d2e5f1SDaniel P. Berrange                            NULL, test_visitor_in_null);
11812fc00432SMarkus Armbruster     input_visitor_test_add("/visitor/input/union-flat",
1182b1d2e5f1SDaniel P. Berrange                            NULL, test_visitor_in_union_flat);
1183ab045267SEric Blake     input_visitor_test_add("/visitor/input/alternate",
1184b1d2e5f1SDaniel P. Berrange                            NULL, test_visitor_in_alternate);
11853dcf71f6SPaolo Bonzini     input_visitor_test_add("/visitor/input/errors",
1186b1d2e5f1SDaniel P. Berrange                            NULL, test_visitor_in_errors);
11872533377cSEric Blake     input_visitor_test_add("/visitor/input/wrong-type",
1188b1d2e5f1SDaniel P. Berrange                            NULL, test_visitor_in_wrong_type);
11899c51b441SEric Blake     input_visitor_test_add("/visitor/input/alternate-number",
1190b1d2e5f1SDaniel P. Berrange                            NULL, test_visitor_in_alternate_number);
119177c47de2SMarkus Armbruster     input_visitor_test_add("/visitor/input/fail/struct",
119277c47de2SMarkus Armbruster                            NULL, test_visitor_in_fail_struct);
119377c47de2SMarkus Armbruster     input_visitor_test_add("/visitor/input/fail/struct-nested",
119477c47de2SMarkus Armbruster                            NULL, test_visitor_in_fail_struct_nested);
119577c47de2SMarkus Armbruster     input_visitor_test_add("/visitor/input/fail/struct-in-list",
119677c47de2SMarkus Armbruster                            NULL, test_visitor_in_fail_struct_in_list);
119777c47de2SMarkus Armbruster     input_visitor_test_add("/visitor/input/fail/struct-missing",
119877c47de2SMarkus Armbruster                            NULL, test_visitor_in_fail_struct_missing);
11999cb8ef36SMarkus Armbruster     input_visitor_test_add("/visitor/input/fail/list",
12009cb8ef36SMarkus Armbruster                            NULL, test_visitor_in_fail_list);
12019cb8ef36SMarkus Armbruster     input_visitor_test_add("/visitor/input/fail/list-nested",
12029cb8ef36SMarkus Armbruster                            NULL, test_visitor_in_fail_list_nested);
120377c47de2SMarkus Armbruster     input_visitor_test_add("/visitor/input/fail/union-flat",
120477c47de2SMarkus Armbruster                            NULL, test_visitor_in_fail_union_flat);
120577c47de2SMarkus Armbruster     input_visitor_test_add("/visitor/input/fail/union-flat-no-discriminator",
120677c47de2SMarkus Armbruster                            NULL, test_visitor_in_fail_union_flat_no_discrim);
120777c47de2SMarkus Armbruster     input_visitor_test_add("/visitor/input/fail/alternate",
120877c47de2SMarkus Armbruster                            NULL, test_visitor_in_fail_alternate);
1209eb815e24SMarkus Armbruster     input_visitor_test_add("/visitor/input/qapi-introspect",
121077c47de2SMarkus Armbruster                            NULL, test_visitor_in_qmp_introspect);
1211d88f5fd1SLuiz Capitulino 
1212d88f5fd1SLuiz Capitulino     g_test_run();
1213d88f5fd1SLuiz Capitulino 
1214d88f5fd1SLuiz Capitulino     return 0;
1215d88f5fd1SLuiz Capitulino }
1216