]> git.proxmox.com Git - mirror_qemu.git/blame - tests/test-qobject-input-visitor.c
Typedef the subtypes of QObject in qemu/typedefs.h, too
[mirror_qemu.git] / tests / test-qobject-input-visitor.c
CommitLineData
d88f5fd1 1/*
b3db211f 2 * QObject Input Visitor unit-tests.
d88f5fd1 3 *
68d07839 4 * Copyright (C) 2011-2016 Red Hat Inc.
d88f5fd1
LC
5 *
6 * Authors:
7 * Luiz Capitulino <lcapitulino@redhat.com>
77c47de2 8 * Paolo Bonzini <pbonzini@redhat.com>
d88f5fd1
LC
9 *
10 * This work is licensed under the terms of the GNU GPL, version 2 or later.
11 * See the COPYING file in the top-level directory.
12 */
13
681c28a3 14#include "qemu/osdep.h"
d88f5fd1 15
79ee7df8 16#include "qemu-common.h"
da34e65c 17#include "qapi/error.h"
b3db211f 18#include "qapi/qobject-input-visitor.h"
d88f5fd1 19#include "test-qapi-visit.h"
7b1b5d19 20#include "qapi/qmp/types.h"
c7eb39cb 21#include "qapi/qmp/qjson.h"
77c47de2
MA
22#include "test-qmp-introspect.h"
23#include "qmp-introspect.h"
24#include "qapi-visit.h"
d88f5fd1
LC
25
26typedef struct TestInputVisitorData {
27 QObject *obj;
b70ce101 28 Visitor *qiv;
d88f5fd1
LC
29} TestInputVisitorData;
30
31static void visitor_input_teardown(TestInputVisitorData *data,
32 const void *unused)
33{
34 qobject_decref(data->obj);
35 data->obj = NULL;
36
37 if (data->qiv) {
b70ce101 38 visit_free(data->qiv);
d88f5fd1
LC
39 data->qiv = NULL;
40 }
41}
42
0920a171
EB
43/* The various test_init functions are provided instead of a test setup
44 function so that the JSON string used by the tests are kept in the test
45 functions (and not in main()). */
46static Visitor *visitor_input_test_init_internal(TestInputVisitorData *data,
cbd8acf3 47 bool keyval,
0920a171
EB
48 const char *json_string,
49 va_list *ap)
50{
b18f1141
EB
51 visitor_input_teardown(data, NULL);
52
bff17e84 53 data->obj = qobject_from_jsonv(json_string, ap, &error_abort);
0920a171
EB
54 g_assert(data->obj);
55
cbd8acf3
DB
56 if (keyval) {
57 data->qiv = qobject_input_visitor_new_keyval(data->obj);
58 } else {
59 data->qiv = qobject_input_visitor_new(data->obj);
60 }
0920a171 61 g_assert(data->qiv);
b70ce101 62 return data->qiv;
0920a171
EB
63}
64
cbd8acf3
DB
65static GCC_FMT_ATTR(3, 4)
66Visitor *visitor_input_test_init_full(TestInputVisitorData *data,
67 bool keyval,
68 const char *json_string, ...)
69{
70 Visitor *v;
71 va_list ap;
72
73 va_start(ap, json_string);
74 v = visitor_input_test_init_internal(data, keyval, json_string, &ap);
75 va_end(ap);
76 return v;
77}
78
aba2107a
SW
79static GCC_FMT_ATTR(2, 3)
80Visitor *visitor_input_test_init(TestInputVisitorData *data,
81 const char *json_string, ...)
d88f5fd1
LC
82{
83 Visitor *v;
84 va_list ap;
85
86 va_start(ap, json_string);
cbd8acf3 87 v = visitor_input_test_init_internal(data, false, json_string, &ap);
d88f5fd1 88 va_end(ap);
d88f5fd1
LC
89 return v;
90}
91
199e0f17
MR
92/* similar to visitor_input_test_init(), but does not expect a string
93 * literal/format json_string argument and so can be used for
94 * programatically generated strings (and we can't pass in programatically
95 * generated strings via %s format parameters since qobject_from_jsonv()
96 * will wrap those in double-quotes and treat the entire object as a
97 * string)
98 */
99static Visitor *visitor_input_test_init_raw(TestInputVisitorData *data,
100 const char *json_string)
101{
cbd8acf3 102 return visitor_input_test_init_internal(data, false, json_string, NULL);
199e0f17
MR
103}
104
d88f5fd1
LC
105static void test_visitor_in_int(TestInputVisitorData *data,
106 const void *unused)
107{
29a6731a 108 int64_t res = 0;
c1214ad3 109 double dbl;
29a6731a 110 int value = -42;
d88f5fd1
LC
111 Visitor *v;
112
29a6731a 113 v = visitor_input_test_init(data, "%d", value);
d88f5fd1 114
51e72bc1 115 visit_type_int(v, NULL, &res, &error_abort);
d88f5fd1 116 g_assert_cmpint(res, ==, value);
c1214ad3
MAL
117
118 visit_type_number(v, NULL, &dbl, &error_abort);
119 g_assert_cmpfloat(dbl, ==, -42.0);
d88f5fd1
LC
120}
121
4bc0c94d
MA
122static void test_visitor_in_uint(TestInputVisitorData *data,
123 const void *unused)
124{
4bc0c94d 125 uint64_t res = 0;
c1214ad3
MAL
126 int64_t i64;
127 double dbl;
4bc0c94d
MA
128 int value = 42;
129 Visitor *v;
130
131 v = visitor_input_test_init(data, "%d", value);
132
133 visit_type_uint64(v, NULL, &res, &error_abort);
134 g_assert_cmpuint(res, ==, (uint64_t)value);
135
c1214ad3
MAL
136 visit_type_int(v, NULL, &i64, &error_abort);
137 g_assert_cmpint(i64, ==, value);
138
139 visit_type_number(v, NULL, &dbl, &error_abort);
140 g_assert_cmpfloat(dbl, ==, value);
4bc0c94d 141
c1214ad3 142 /* BUG: value between INT64_MIN and -1 accepted modulo 2^64 */
4bc0c94d
MA
143 v = visitor_input_test_init(data, "%d", -value);
144
145 visit_type_uint64(v, NULL, &res, &error_abort);
146 g_assert_cmpuint(res, ==, (uint64_t)-value);
147
4bc0c94d
MA
148 v = visitor_input_test_init(data, "18446744073709551574");
149
5923f85f
MAL
150 visit_type_uint64(v, NULL, &res, &error_abort);
151 g_assert_cmpuint(res, ==, 18446744073709551574U);
c1214ad3
MAL
152
153 visit_type_number(v, NULL, &dbl, &error_abort);
154 g_assert_cmpfloat(dbl, ==, 18446744073709552000.0);
4bc0c94d
MA
155}
156
e92cfa0d
MR
157static void test_visitor_in_int_overflow(TestInputVisitorData *data,
158 const void *unused)
159{
160 int64_t res = 0;
e940f543 161 Error *err = NULL;
e92cfa0d
MR
162 Visitor *v;
163
01b2ffce
MAL
164 /*
165 * This will overflow a QNUM_I64, so should be deserialized into a
166 * QNUM_DOUBLE field instead, leading to an error if we pass it to
167 * visit_type_int(). Confirm this.
e92cfa0d
MR
168 */
169 v = visitor_input_test_init(data, "%f", DBL_MAX);
170
51e72bc1 171 visit_type_int(v, NULL, &res, &err);
a12a5a1a 172 error_free_or_abort(&err);
e92cfa0d
MR
173}
174
cbd8acf3
DB
175static void test_visitor_in_int_keyval(TestInputVisitorData *data,
176 const void *unused)
177{
178 int64_t res = 0, value = -42;
179 Error *err = NULL;
180 Visitor *v;
181
182 v = visitor_input_test_init_full(data, true, "%" PRId64, value);
183 visit_type_int(v, NULL, &res, &err);
184 error_free_or_abort(&err);
185}
186
187static void test_visitor_in_int_str_keyval(TestInputVisitorData *data,
188 const void *unused)
189{
190 int64_t res = 0, value = -42;
191 Visitor *v;
192
193 v = visitor_input_test_init_full(data, true, "\"-42\"");
194
195 visit_type_int(v, NULL, &res, &error_abort);
196 g_assert_cmpint(res, ==, value);
197}
198
199static void test_visitor_in_int_str_fail(TestInputVisitorData *data,
200 const void *unused)
201{
202 int64_t res = 0;
203 Visitor *v;
204 Error *err = NULL;
205
206 v = visitor_input_test_init(data, "\"-42\"");
207
208 visit_type_int(v, NULL, &res, &err);
209 error_free_or_abort(&err);
210}
211
d88f5fd1
LC
212static void test_visitor_in_bool(TestInputVisitorData *data,
213 const void *unused)
214{
d88f5fd1
LC
215 bool res = false;
216 Visitor *v;
217
218 v = visitor_input_test_init(data, "true");
219
51e72bc1 220 visit_type_bool(v, NULL, &res, &error_abort);
d88f5fd1
LC
221 g_assert_cmpint(res, ==, true);
222}
223
cbd8acf3
DB
224static void test_visitor_in_bool_keyval(TestInputVisitorData *data,
225 const void *unused)
226{
227 bool res = false;
228 Error *err = NULL;
229 Visitor *v;
230
231 v = visitor_input_test_init_full(data, true, "true");
232
233 visit_type_bool(v, NULL, &res, &err);
234 error_free_or_abort(&err);
235}
236
237static void test_visitor_in_bool_str_keyval(TestInputVisitorData *data,
238 const void *unused)
239{
240 bool res = false;
241 Visitor *v;
242
243 v = visitor_input_test_init_full(data, true, "\"on\"");
244
245 visit_type_bool(v, NULL, &res, &error_abort);
246 g_assert_cmpint(res, ==, true);
247}
248
249static void test_visitor_in_bool_str_fail(TestInputVisitorData *data,
250 const void *unused)
251{
252 bool res = false;
253 Visitor *v;
254 Error *err = NULL;
255
256 v = visitor_input_test_init(data, "\"true\"");
257
258 visit_type_bool(v, NULL, &res, &err);
259 error_free_or_abort(&err);
260}
261
d88f5fd1
LC
262static void test_visitor_in_number(TestInputVisitorData *data,
263 const void *unused)
264{
265 double res = 0, value = 3.14;
d88f5fd1
LC
266 Visitor *v;
267
268 v = visitor_input_test_init(data, "%f", value);
269
51e72bc1 270 visit_type_number(v, NULL, &res, &error_abort);
d88f5fd1
LC
271 g_assert_cmpfloat(res, ==, value);
272}
273
c1214ad3
MAL
274static void test_visitor_in_large_number(TestInputVisitorData *data,
275 const void *unused)
276{
277 Error *err = NULL;
278 double res = 0;
279 int64_t i64;
280 uint64_t u64;
281 Visitor *v;
282
283 v = visitor_input_test_init(data, "-18446744073709551616"); /* -2^64 */
284
285 visit_type_number(v, NULL, &res, &error_abort);
286 g_assert_cmpfloat(res, ==, -18446744073709552e3);
287
288 visit_type_int(v, NULL, &i64, &err);
289 error_free_or_abort(&err);
290
291 visit_type_uint64(v, NULL, &u64, &err);
292 error_free_or_abort(&err);
293}
294
cbd8acf3
DB
295static void test_visitor_in_number_keyval(TestInputVisitorData *data,
296 const void *unused)
297{
298 double res = 0, value = 3.14;
299 Error *err = NULL;
300 Visitor *v;
301
302 v = visitor_input_test_init_full(data, true, "%f", value);
303
304 visit_type_number(v, NULL, &res, &err);
305 error_free_or_abort(&err);
306}
307
308static void test_visitor_in_number_str_keyval(TestInputVisitorData *data,
309 const void *unused)
310{
311 double res = 0, value = 3.14;
312 Visitor *v;
5891c388 313 Error *err = NULL;
cbd8acf3
DB
314
315 v = visitor_input_test_init_full(data, true, "\"3.14\"");
316
317 visit_type_number(v, NULL, &res, &error_abort);
318 g_assert_cmpfloat(res, ==, value);
5891c388
MA
319
320 v = visitor_input_test_init_full(data, true, "\"inf\"");
321
322 visit_type_number(v, NULL, &res, &err);
323 error_free_or_abort(&err);
cbd8acf3
DB
324}
325
326static void test_visitor_in_number_str_fail(TestInputVisitorData *data,
327 const void *unused)
328{
329 double res = 0;
330 Visitor *v;
331 Error *err = NULL;
332
333 v = visitor_input_test_init(data, "\"3.14\"");
334
335 visit_type_number(v, NULL, &res, &err);
336 error_free_or_abort(&err);
337}
338
339static void test_visitor_in_size_str_keyval(TestInputVisitorData *data,
340 const void *unused)
341{
342 uint64_t res, value = 500 * 1024 * 1024;
343 Visitor *v;
344
345 v = visitor_input_test_init_full(data, true, "\"500M\"");
346
347 visit_type_size(v, NULL, &res, &error_abort);
348 g_assert_cmpfloat(res, ==, value);
349}
350
351static void test_visitor_in_size_str_fail(TestInputVisitorData *data,
352 const void *unused)
353{
354 uint64_t res = 0;
355 Visitor *v;
356 Error *err = NULL;
357
358 v = visitor_input_test_init(data, "\"500M\"");
359
360 visit_type_size(v, NULL, &res, &err);
361 error_free_or_abort(&err);
362}
363
d88f5fd1
LC
364static void test_visitor_in_string(TestInputVisitorData *data,
365 const void *unused)
366{
367 char *res = NULL, *value = (char *) "Q E M U";
d88f5fd1
LC
368 Visitor *v;
369
370 v = visitor_input_test_init(data, "%s", value);
371
51e72bc1 372 visit_type_str(v, NULL, &res, &error_abort);
d88f5fd1
LC
373 g_assert_cmpstr(res, ==, value);
374
375 g_free(res);
376}
377
378static void test_visitor_in_enum(TestInputVisitorData *data,
379 const void *unused)
380{
d88f5fd1
LC
381 Visitor *v;
382 EnumOne i;
383
1c236ba5 384 for (i = 0; i < ENUM_ONE__MAX; i++) {
d88f5fd1
LC
385 EnumOne res = -1;
386
977c736f 387 v = visitor_input_test_init(data, "%s", EnumOne_str(i));
d88f5fd1 388
51e72bc1 389 visit_type_EnumOne(v, NULL, &res, &error_abort);
d88f5fd1 390 g_assert_cmpint(i, ==, res);
d88f5fd1 391 }
d88f5fd1
LC
392}
393
d88f5fd1
LC
394
395static void test_visitor_in_struct(TestInputVisitorData *data,
396 const void *unused)
397{
398 TestStruct *p = NULL;
d88f5fd1
LC
399 Visitor *v;
400
401 v = visitor_input_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo' }");
402
51e72bc1 403 visit_type_TestStruct(v, NULL, &p, &error_abort);
d88f5fd1
LC
404 g_assert_cmpint(p->integer, ==, -42);
405 g_assert(p->boolean == true);
406 g_assert_cmpstr(p->string, ==, "foo");
407
408 g_free(p->string);
409 g_free(p);
410}
411
d88f5fd1
LC
412static void test_visitor_in_struct_nested(TestInputVisitorData *data,
413 const void *unused)
414{
b6fcf32d 415 UserDefTwo *udp = NULL;
d88f5fd1
LC
416 Visitor *v;
417
b6fcf32d
EB
418 v = visitor_input_test_init(data, "{ 'string0': 'string0', "
419 "'dict1': { 'string1': 'string1', "
420 "'dict2': { 'userdef': { 'integer': 42, "
421 "'string': 'string' }, 'string': 'string2'}}}");
d88f5fd1 422
51e72bc1 423 visit_type_UserDefTwo(v, NULL, &udp, &error_abort);
d88f5fd1 424
b18f1141
EB
425 g_assert_cmpstr(udp->string0, ==, "string0");
426 g_assert_cmpstr(udp->dict1->string1, ==, "string1");
ddf21908 427 g_assert_cmpint(udp->dict1->dict2->userdef->integer, ==, 42);
b18f1141
EB
428 g_assert_cmpstr(udp->dict1->dict2->userdef->string, ==, "string");
429 g_assert_cmpstr(udp->dict1->dict2->string, ==, "string2");
6446a592
EB
430 g_assert(udp->dict1->has_dict3 == false);
431
b18f1141 432 qapi_free_UserDefTwo(udp);
d88f5fd1
LC
433}
434
435static void test_visitor_in_list(TestInputVisitorData *data,
436 const void *unused)
437{
438 UserDefOneList *item, *head = NULL;
d88f5fd1
LC
439 Visitor *v;
440 int i;
441
442 v = visitor_input_test_init(data, "[ { 'string': 'string0', 'integer': 42 }, { 'string': 'string1', 'integer': 43 }, { 'string': 'string2', 'integer': 44 } ]");
443
51e72bc1 444 visit_type_UserDefOneList(v, NULL, &head, &error_abort);
d88f5fd1
LC
445 g_assert(head != NULL);
446
447 for (i = 0, item = head; item; item = item->next, i++) {
448 char string[12];
449
450 snprintf(string, sizeof(string), "string%d", i);
451 g_assert_cmpstr(item->value->string, ==, string);
ddf21908 452 g_assert_cmpint(item->value->integer, ==, 42 + i);
d88f5fd1
LC
453 }
454
455 qapi_free_UserDefOneList(head);
2533377c
EB
456 head = NULL;
457
458 /* An empty list is valid */
459 v = visitor_input_test_init(data, "[]");
51e72bc1 460 visit_type_UserDefOneList(v, NULL, &head, &error_abort);
2533377c 461 g_assert(!head);
d88f5fd1
LC
462}
463
28770e05
MA
464static void test_visitor_in_any(TestInputVisitorData *data,
465 const void *unused)
466{
467 QObject *res = NULL;
28770e05 468 Visitor *v;
01b2ffce 469 QNum *qnum;
28770e05
MA
470 QBool *qbool;
471 QString *qstring;
472 QDict *qdict;
473 QObject *qobj;
01b2ffce 474 int64_t val;
28770e05
MA
475
476 v = visitor_input_test_init(data, "-42");
51e72bc1 477 visit_type_any(v, NULL, &res, &error_abort);
01b2ffce
MAL
478 qnum = qobject_to_qnum(res);
479 g_assert(qnum);
480 g_assert(qnum_get_try_int(qnum, &val));
481 g_assert_cmpint(val, ==, -42);
28770e05
MA
482 qobject_decref(res);
483
484 v = visitor_input_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo' }");
51e72bc1 485 visit_type_any(v, NULL, &res, &error_abort);
28770e05
MA
486 qdict = qobject_to_qdict(res);
487 g_assert(qdict && qdict_size(qdict) == 3);
488 qobj = qdict_get(qdict, "integer");
489 g_assert(qobj);
01b2ffce
MAL
490 qnum = qobject_to_qnum(qobj);
491 g_assert(qnum);
492 g_assert(qnum_get_try_int(qnum, &val));
493 g_assert_cmpint(val, ==, -42);
28770e05
MA
494 qobj = qdict_get(qdict, "boolean");
495 g_assert(qobj);
496 qbool = qobject_to_qbool(qobj);
497 g_assert(qbool);
498 g_assert(qbool_get_bool(qbool) == true);
499 qobj = qdict_get(qdict, "string");
500 g_assert(qobj);
501 qstring = qobject_to_qstring(qobj);
502 g_assert(qstring);
503 g_assert_cmpstr(qstring_get_str(qstring), ==, "foo");
504 qobject_decref(res);
505}
506
3df016f1
EB
507static void test_visitor_in_null(TestInputVisitorData *data,
508 const void *unused)
509{
510 Visitor *v;
511 Error *err = NULL;
d2f95f4d 512 QNull *null;
3df016f1
EB
513 char *tmp;
514
515 /*
516 * FIXME: Since QAPI doesn't know the 'null' type yet, we can't
517 * test visit_type_null() by reading into a QAPI struct then
518 * checking that it was populated correctly. The best we can do
519 * for now is ensure that we consumed null from the input, proven
520 * by the fact that we can't re-read the key; and that we detect
521 * when input is not null.
522 */
523
cbd8acf3
DB
524 v = visitor_input_test_init_full(data, false,
525 "{ 'a': null, 'b': '' }");
3df016f1 526 visit_start_struct(v, NULL, NULL, 0, &error_abort);
d2f95f4d
MA
527 visit_type_null(v, "a", &null, &error_abort);
528 g_assert(qobject_type(QOBJECT(null)) == QTYPE_QNULL);
529 QDECREF(null);
530 visit_type_null(v, "b", &null, &err);
3df016f1 531 error_free_or_abort(&err);
d2f95f4d 532 g_assert(!null);
ec95f614 533 visit_type_str(v, "c", &tmp, &err);
ec95f614 534 error_free_or_abort(&err);
d2f95f4d 535 g_assert(!tmp);
15c2f669 536 visit_check_struct(v, &error_abort);
1158bb2a 537 visit_end_struct(v, NULL);
3df016f1
EB
538}
539
2fc00432
MA
540static void test_visitor_in_union_flat(TestInputVisitorData *data,
541 const void *unused)
542{
543 Visitor *v;
2fc00432 544 UserDefFlatUnion *tmp;
30594fe1 545 UserDefUnionBase *base;
2fc00432 546
5223070c
WX
547 v = visitor_input_test_init(data,
548 "{ 'enum1': 'value1', "
441cbac0 549 "'integer': 41, "
5223070c
WX
550 "'string': 'str', "
551 "'boolean': true }");
2fc00432 552
51e72bc1 553 visit_type_UserDefFlatUnion(v, NULL, &tmp, &error_abort);
0f61af3e 554 g_assert_cmpint(tmp->enum1, ==, ENUM_ONE_VALUE1);
5223070c 555 g_assert_cmpstr(tmp->string, ==, "str");
441cbac0 556 g_assert_cmpint(tmp->integer, ==, 41);
544a3731 557 g_assert_cmpint(tmp->u.value1.boolean, ==, true);
30594fe1
EB
558
559 base = qapi_UserDefFlatUnion_base(tmp);
560 g_assert(&base->enum1 == &tmp->enum1);
561
2fc00432
MA
562 qapi_free_UserDefFlatUnion(tmp);
563}
564
ab045267
EB
565static void test_visitor_in_alternate(TestInputVisitorData *data,
566 const void *unused)
2c38b600
MA
567{
568 Visitor *v;
ab045267 569 UserDefAlternate *tmp;
68d07839 570 WrapAlternate *wrap;
2c38b600
MA
571
572 v = visitor_input_test_init(data, "42");
51e72bc1 573 visit_type_UserDefAlternate(v, NULL, &tmp, &error_abort);
01b2ffce 574 g_assert_cmpint(tmp->type, ==, QTYPE_QNUM);
c363acef 575 g_assert_cmpint(tmp->u.i, ==, 42);
ab045267 576 qapi_free_UserDefAlternate(tmp);
9c51b441 577
8168ca8e 578 v = visitor_input_test_init(data, "'value1'");
51e72bc1 579 visit_type_UserDefAlternate(v, NULL, &tmp, &error_abort);
0426d53c 580 g_assert_cmpint(tmp->type, ==, QTYPE_QSTRING);
8168ca8e 581 g_assert_cmpint(tmp->u.e, ==, ENUM_ONE_VALUE1);
9c51b441 582 qapi_free_UserDefAlternate(tmp);
9c51b441 583
4d2d5c41
MA
584 v = visitor_input_test_init(data, "null");
585 visit_type_UserDefAlternate(v, NULL, &tmp, &error_abort);
586 g_assert_cmpint(tmp->type, ==, QTYPE_QNULL);
587 qapi_free_UserDefAlternate(tmp);
588
68d07839
EB
589 v = visitor_input_test_init(data, "{'integer':1, 'string':'str', "
590 "'enum1':'value1', 'boolean':true}");
591 visit_type_UserDefAlternate(v, NULL, &tmp, &error_abort);
592 g_assert_cmpint(tmp->type, ==, QTYPE_QDICT);
becceedc
EB
593 g_assert_cmpint(tmp->u.udfu.integer, ==, 1);
594 g_assert_cmpstr(tmp->u.udfu.string, ==, "str");
595 g_assert_cmpint(tmp->u.udfu.enum1, ==, ENUM_ONE_VALUE1);
544a3731
EB
596 g_assert_cmpint(tmp->u.udfu.u.value1.boolean, ==, true);
597 g_assert_cmpint(tmp->u.udfu.u.value1.has_a_b, ==, false);
68d07839
EB
598 qapi_free_UserDefAlternate(tmp);
599
68d07839
EB
600 v = visitor_input_test_init(data, "{ 'alt': 42 }");
601 visit_type_WrapAlternate(v, NULL, &wrap, &error_abort);
01b2ffce 602 g_assert_cmpint(wrap->alt->type, ==, QTYPE_QNUM);
68d07839
EB
603 g_assert_cmpint(wrap->alt->u.i, ==, 42);
604 qapi_free_WrapAlternate(wrap);
605
8168ca8e 606 v = visitor_input_test_init(data, "{ 'alt': 'value1' }");
68d07839
EB
607 visit_type_WrapAlternate(v, NULL, &wrap, &error_abort);
608 g_assert_cmpint(wrap->alt->type, ==, QTYPE_QSTRING);
8168ca8e 609 g_assert_cmpint(wrap->alt->u.e, ==, ENUM_ONE_VALUE1);
68d07839
EB
610 qapi_free_WrapAlternate(wrap);
611
612 v = visitor_input_test_init(data, "{ 'alt': {'integer':1, 'string':'str', "
613 "'enum1':'value1', 'boolean':true} }");
614 visit_type_WrapAlternate(v, NULL, &wrap, &error_abort);
615 g_assert_cmpint(wrap->alt->type, ==, QTYPE_QDICT);
becceedc
EB
616 g_assert_cmpint(wrap->alt->u.udfu.integer, ==, 1);
617 g_assert_cmpstr(wrap->alt->u.udfu.string, ==, "str");
618 g_assert_cmpint(wrap->alt->u.udfu.enum1, ==, ENUM_ONE_VALUE1);
544a3731
EB
619 g_assert_cmpint(wrap->alt->u.udfu.u.value1.boolean, ==, true);
620 g_assert_cmpint(wrap->alt->u.udfu.u.value1.has_a_b, ==, false);
68d07839 621 qapi_free_WrapAlternate(wrap);
9c51b441
EB
622}
623
624static void test_visitor_in_alternate_number(TestInputVisitorData *data,
625 const void *unused)
626{
627 Visitor *v;
628 Error *err = NULL;
8168ca8e
MA
629 AltEnumBool *aeb;
630 AltEnumNum *aen;
631 AltNumEnum *ans;
632 AltEnumInt *asi;
9c51b441
EB
633
634 /* Parsing an int */
635
636 v = visitor_input_test_init(data, "42");
8168ca8e 637 visit_type_AltEnumBool(v, NULL, &aeb, &err);
a12a5a1a 638 error_free_or_abort(&err);
8168ca8e 639 qapi_free_AltEnumBool(aeb);
9c51b441 640
9c51b441 641 v = visitor_input_test_init(data, "42");
8168ca8e 642 visit_type_AltEnumNum(v, NULL, &aen, &error_abort);
01b2ffce 643 g_assert_cmpint(aen->type, ==, QTYPE_QNUM);
8168ca8e
MA
644 g_assert_cmpfloat(aen->u.n, ==, 42);
645 qapi_free_AltEnumNum(aen);
9c51b441
EB
646
647 v = visitor_input_test_init(data, "42");
8168ca8e 648 visit_type_AltNumEnum(v, NULL, &ans, &error_abort);
01b2ffce 649 g_assert_cmpint(ans->type, ==, QTYPE_QNUM);
d00341af 650 g_assert_cmpfloat(ans->u.n, ==, 42);
8168ca8e 651 qapi_free_AltNumEnum(ans);
9c51b441
EB
652
653 v = visitor_input_test_init(data, "42");
8168ca8e 654 visit_type_AltEnumInt(v, NULL, &asi, &error_abort);
01b2ffce 655 g_assert_cmpint(asi->type, ==, QTYPE_QNUM);
c363acef 656 g_assert_cmpint(asi->u.i, ==, 42);
8168ca8e 657 qapi_free_AltEnumInt(asi);
9c51b441 658
9c51b441
EB
659 /* Parsing a double */
660
661 v = visitor_input_test_init(data, "42.5");
8168ca8e 662 visit_type_AltEnumBool(v, NULL, &aeb, &err);
a12a5a1a 663 error_free_or_abort(&err);
8168ca8e 664 qapi_free_AltEnumBool(aeb);
9c51b441
EB
665
666 v = visitor_input_test_init(data, "42.5");
8168ca8e 667 visit_type_AltEnumNum(v, NULL, &aen, &error_abort);
01b2ffce 668 g_assert_cmpint(aen->type, ==, QTYPE_QNUM);
8168ca8e
MA
669 g_assert_cmpfloat(aen->u.n, ==, 42.5);
670 qapi_free_AltEnumNum(aen);
9c51b441
EB
671
672 v = visitor_input_test_init(data, "42.5");
8168ca8e 673 visit_type_AltNumEnum(v, NULL, &ans, &error_abort);
01b2ffce 674 g_assert_cmpint(ans->type, ==, QTYPE_QNUM);
c363acef 675 g_assert_cmpfloat(ans->u.n, ==, 42.5);
8168ca8e 676 qapi_free_AltNumEnum(ans);
9c51b441
EB
677
678 v = visitor_input_test_init(data, "42.5");
8168ca8e 679 visit_type_AltEnumInt(v, NULL, &asi, &err);
a12a5a1a 680 error_free_or_abort(&err);
8168ca8e 681 qapi_free_AltEnumInt(asi);
2c38b600
MA
682}
683
199e0f17
MR
684static void test_native_list_integer_helper(TestInputVisitorData *data,
685 const void *unused,
686 UserDefNativeListUnionKind kind)
687{
688 UserDefNativeListUnion *cvalue = NULL;
199e0f17
MR
689 Visitor *v;
690 GString *gstr_list = g_string_new("");
691 GString *gstr_union = g_string_new("");
692 int i;
693
694 for (i = 0; i < 32; i++) {
695 g_string_append_printf(gstr_list, "%d", i);
696 if (i != 31) {
697 g_string_append(gstr_list, ", ");
698 }
699 }
700 g_string_append_printf(gstr_union, "{ 'type': '%s', 'data': [ %s ] }",
977c736f 701 UserDefNativeListUnionKind_str(kind),
199e0f17
MR
702 gstr_list->str);
703 v = visitor_input_test_init_raw(data, gstr_union->str);
704
51e72bc1 705 visit_type_UserDefNativeListUnion(v, NULL, &cvalue, &error_abort);
199e0f17 706 g_assert(cvalue != NULL);
c363acef 707 g_assert_cmpint(cvalue->type, ==, kind);
199e0f17
MR
708
709 switch (kind) {
710 case USER_DEF_NATIVE_LIST_UNION_KIND_INTEGER: {
711 intList *elem = NULL;
32bafa8f
EB
712 for (i = 0, elem = cvalue->u.integer.data;
713 elem; elem = elem->next, i++) {
199e0f17
MR
714 g_assert_cmpint(elem->value, ==, i);
715 }
716 break;
717 }
718 case USER_DEF_NATIVE_LIST_UNION_KIND_S8: {
719 int8List *elem = NULL;
32bafa8f 720 for (i = 0, elem = cvalue->u.s8.data; elem; elem = elem->next, i++) {
199e0f17
MR
721 g_assert_cmpint(elem->value, ==, i);
722 }
723 break;
724 }
725 case USER_DEF_NATIVE_LIST_UNION_KIND_S16: {
726 int16List *elem = NULL;
32bafa8f 727 for (i = 0, elem = cvalue->u.s16.data; elem; elem = elem->next, i++) {
199e0f17
MR
728 g_assert_cmpint(elem->value, ==, i);
729 }
730 break;
731 }
732 case USER_DEF_NATIVE_LIST_UNION_KIND_S32: {
733 int32List *elem = NULL;
32bafa8f 734 for (i = 0, elem = cvalue->u.s32.data; elem; elem = elem->next, i++) {
199e0f17
MR
735 g_assert_cmpint(elem->value, ==, i);
736 }
737 break;
738 }
739 case USER_DEF_NATIVE_LIST_UNION_KIND_S64: {
740 int64List *elem = NULL;
32bafa8f 741 for (i = 0, elem = cvalue->u.s64.data; elem; elem = elem->next, i++) {
199e0f17
MR
742 g_assert_cmpint(elem->value, ==, i);
743 }
744 break;
745 }
746 case USER_DEF_NATIVE_LIST_UNION_KIND_U8: {
747 uint8List *elem = NULL;
32bafa8f 748 for (i = 0, elem = cvalue->u.u8.data; elem; elem = elem->next, i++) {
199e0f17
MR
749 g_assert_cmpint(elem->value, ==, i);
750 }
751 break;
752 }
753 case USER_DEF_NATIVE_LIST_UNION_KIND_U16: {
754 uint16List *elem = NULL;
32bafa8f 755 for (i = 0, elem = cvalue->u.u16.data; elem; elem = elem->next, i++) {
199e0f17
MR
756 g_assert_cmpint(elem->value, ==, i);
757 }
758 break;
759 }
760 case USER_DEF_NATIVE_LIST_UNION_KIND_U32: {
761 uint32List *elem = NULL;
32bafa8f 762 for (i = 0, elem = cvalue->u.u32.data; elem; elem = elem->next, i++) {
199e0f17
MR
763 g_assert_cmpint(elem->value, ==, i);
764 }
765 break;
766 }
767 case USER_DEF_NATIVE_LIST_UNION_KIND_U64: {
768 uint64List *elem = NULL;
32bafa8f 769 for (i = 0, elem = cvalue->u.u64.data; elem; elem = elem->next, i++) {
199e0f17
MR
770 g_assert_cmpint(elem->value, ==, i);
771 }
772 break;
773 }
774 default:
dfc6f865 775 g_assert_not_reached();
199e0f17
MR
776 }
777
778 g_string_free(gstr_union, true);
779 g_string_free(gstr_list, true);
780 qapi_free_UserDefNativeListUnion(cvalue);
781}
782
783static void test_visitor_in_native_list_int(TestInputVisitorData *data,
784 const void *unused)
785{
786 test_native_list_integer_helper(data, unused,
787 USER_DEF_NATIVE_LIST_UNION_KIND_INTEGER);
788}
789
790static void test_visitor_in_native_list_int8(TestInputVisitorData *data,
791 const void *unused)
792{
793 test_native_list_integer_helper(data, unused,
794 USER_DEF_NATIVE_LIST_UNION_KIND_S8);
795}
796
797static void test_visitor_in_native_list_int16(TestInputVisitorData *data,
798 const void *unused)
799{
800 test_native_list_integer_helper(data, unused,
801 USER_DEF_NATIVE_LIST_UNION_KIND_S16);
802}
803
804static void test_visitor_in_native_list_int32(TestInputVisitorData *data,
805 const void *unused)
806{
807 test_native_list_integer_helper(data, unused,
808 USER_DEF_NATIVE_LIST_UNION_KIND_S32);
809}
810
811static void test_visitor_in_native_list_int64(TestInputVisitorData *data,
812 const void *unused)
813{
814 test_native_list_integer_helper(data, unused,
815 USER_DEF_NATIVE_LIST_UNION_KIND_S64);
816}
817
818static void test_visitor_in_native_list_uint8(TestInputVisitorData *data,
819 const void *unused)
820{
821 test_native_list_integer_helper(data, unused,
822 USER_DEF_NATIVE_LIST_UNION_KIND_U8);
823}
824
825static void test_visitor_in_native_list_uint16(TestInputVisitorData *data,
826 const void *unused)
827{
828 test_native_list_integer_helper(data, unused,
829 USER_DEF_NATIVE_LIST_UNION_KIND_U16);
830}
831
832static void test_visitor_in_native_list_uint32(TestInputVisitorData *data,
833 const void *unused)
834{
835 test_native_list_integer_helper(data, unused,
836 USER_DEF_NATIVE_LIST_UNION_KIND_U32);
837}
838
839static void test_visitor_in_native_list_uint64(TestInputVisitorData *data,
840 const void *unused)
841{
842 test_native_list_integer_helper(data, unused,
843 USER_DEF_NATIVE_LIST_UNION_KIND_U64);
844}
845
846static void test_visitor_in_native_list_bool(TestInputVisitorData *data,
847 const void *unused)
848{
849 UserDefNativeListUnion *cvalue = NULL;
850 boolList *elem = NULL;
199e0f17
MR
851 Visitor *v;
852 GString *gstr_list = g_string_new("");
853 GString *gstr_union = g_string_new("");
854 int i;
855
856 for (i = 0; i < 32; i++) {
857 g_string_append_printf(gstr_list, "%s",
858 (i % 3 == 0) ? "true" : "false");
859 if (i != 31) {
860 g_string_append(gstr_list, ", ");
861 }
862 }
863 g_string_append_printf(gstr_union, "{ 'type': 'boolean', 'data': [ %s ] }",
864 gstr_list->str);
865 v = visitor_input_test_init_raw(data, gstr_union->str);
866
51e72bc1 867 visit_type_UserDefNativeListUnion(v, NULL, &cvalue, &error_abort);
199e0f17 868 g_assert(cvalue != NULL);
c363acef 869 g_assert_cmpint(cvalue->type, ==, USER_DEF_NATIVE_LIST_UNION_KIND_BOOLEAN);
199e0f17 870
32bafa8f 871 for (i = 0, elem = cvalue->u.boolean.data; elem; elem = elem->next, i++) {
199e0f17
MR
872 g_assert_cmpint(elem->value, ==, (i % 3 == 0) ? 1 : 0);
873 }
874
875 g_string_free(gstr_union, true);
876 g_string_free(gstr_list, true);
877 qapi_free_UserDefNativeListUnion(cvalue);
878}
879
880static void test_visitor_in_native_list_string(TestInputVisitorData *data,
881 const void *unused)
882{
883 UserDefNativeListUnion *cvalue = NULL;
884 strList *elem = NULL;
199e0f17
MR
885 Visitor *v;
886 GString *gstr_list = g_string_new("");
887 GString *gstr_union = g_string_new("");
888 int i;
889
890 for (i = 0; i < 32; i++) {
891 g_string_append_printf(gstr_list, "'%d'", i);
892 if (i != 31) {
893 g_string_append(gstr_list, ", ");
894 }
895 }
896 g_string_append_printf(gstr_union, "{ 'type': 'string', 'data': [ %s ] }",
897 gstr_list->str);
898 v = visitor_input_test_init_raw(data, gstr_union->str);
899
51e72bc1 900 visit_type_UserDefNativeListUnion(v, NULL, &cvalue, &error_abort);
199e0f17 901 g_assert(cvalue != NULL);
c363acef 902 g_assert_cmpint(cvalue->type, ==, USER_DEF_NATIVE_LIST_UNION_KIND_STRING);
199e0f17 903
32bafa8f 904 for (i = 0, elem = cvalue->u.string.data; elem; elem = elem->next, i++) {
199e0f17
MR
905 gchar str[8];
906 sprintf(str, "%d", i);
907 g_assert_cmpstr(elem->value, ==, str);
908 }
909
910 g_string_free(gstr_union, true);
911 g_string_free(gstr_list, true);
912 qapi_free_UserDefNativeListUnion(cvalue);
913}
914
915#define DOUBLE_STR_MAX 16
916
917static void test_visitor_in_native_list_number(TestInputVisitorData *data,
918 const void *unused)
919{
920 UserDefNativeListUnion *cvalue = NULL;
921 numberList *elem = NULL;
199e0f17
MR
922 Visitor *v;
923 GString *gstr_list = g_string_new("");
924 GString *gstr_union = g_string_new("");
925 int i;
926
927 for (i = 0; i < 32; i++) {
928 g_string_append_printf(gstr_list, "%f", (double)i / 3);
929 if (i != 31) {
930 g_string_append(gstr_list, ", ");
931 }
932 }
933 g_string_append_printf(gstr_union, "{ 'type': 'number', 'data': [ %s ] }",
934 gstr_list->str);
935 v = visitor_input_test_init_raw(data, gstr_union->str);
936
51e72bc1 937 visit_type_UserDefNativeListUnion(v, NULL, &cvalue, &error_abort);
199e0f17 938 g_assert(cvalue != NULL);
c363acef 939 g_assert_cmpint(cvalue->type, ==, USER_DEF_NATIVE_LIST_UNION_KIND_NUMBER);
199e0f17 940
32bafa8f 941 for (i = 0, elem = cvalue->u.number.data; elem; elem = elem->next, i++) {
199e0f17
MR
942 GString *double_expected = g_string_new("");
943 GString *double_actual = g_string_new("");
944
945 g_string_printf(double_expected, "%.6f", (double)i / 3);
946 g_string_printf(double_actual, "%.6f", elem->value);
947 g_assert_cmpstr(double_expected->str, ==, double_actual->str);
948
949 g_string_free(double_expected, true);
950 g_string_free(double_actual, true);
951 }
952
953 g_string_free(gstr_union, true);
954 g_string_free(gstr_list, true);
955 qapi_free_UserDefNativeListUnion(cvalue);
956}
957
d88f5fd1 958static void input_visitor_test_add(const char *testpath,
b1d2e5f1
DB
959 const void *user_data,
960 void (*test_func)(TestInputVisitorData *data,
961 const void *user_data))
d88f5fd1 962{
b1d2e5f1 963 g_test_add(testpath, TestInputVisitorData, user_data, NULL, test_func,
d88f5fd1
LC
964 visitor_input_teardown);
965}
966
3dcf71f6
PB
967static void test_visitor_in_errors(TestInputVisitorData *data,
968 const void *unused)
969{
970 TestStruct *p = NULL;
e940f543 971 Error *err = NULL;
3dcf71f6 972 Visitor *v;
dd5ee2c2 973 strList *q = NULL;
9b4e38fe
EB
974 UserDefTwo *r = NULL;
975 WrapAlternate *s = NULL;
3dcf71f6 976
dd5ee2c2
EB
977 v = visitor_input_test_init(data, "{ 'integer': false, 'boolean': 'foo', "
978 "'string': -42 }");
3dcf71f6 979
51e72bc1 980 visit_type_TestStruct(v, NULL, &p, &err);
a12a5a1a 981 error_free_or_abort(&err);
68ab47e4 982 g_assert(!p);
dd5ee2c2
EB
983
984 v = visitor_input_test_init(data, "[ '1', '2', false, '3' ]");
51e72bc1 985 visit_type_strList(v, NULL, &q, &err);
dd5ee2c2 986 error_free_or_abort(&err);
68ab47e4 987 assert(!q);
9b4e38fe
EB
988
989 v = visitor_input_test_init(data, "{ 'str':'hi' }");
990 visit_type_UserDefTwo(v, NULL, &r, &err);
991 error_free_or_abort(&err);
992 assert(!r);
993
994 v = visitor_input_test_init(data, "{ }");
995 visit_type_WrapAlternate(v, NULL, &s, &err);
996 error_free_or_abort(&err);
997 assert(!s);
3dcf71f6
PB
998}
999
2533377c
EB
1000static void test_visitor_in_wrong_type(TestInputVisitorData *data,
1001 const void *unused)
1002{
1003 TestStruct *p = NULL;
1004 Visitor *v;
1005 strList *q = NULL;
1006 int64_t i;
1007 Error *err = NULL;
1008
1009 /* Make sure arrays and structs cannot be confused */
1010
1011 v = visitor_input_test_init(data, "[]");
51e72bc1 1012 visit_type_TestStruct(v, NULL, &p, &err);
2533377c
EB
1013 error_free_or_abort(&err);
1014 g_assert(!p);
1015
1016 v = visitor_input_test_init(data, "{}");
51e72bc1 1017 visit_type_strList(v, NULL, &q, &err);
2533377c
EB
1018 error_free_or_abort(&err);
1019 assert(!q);
1020
1021 /* Make sure primitives and struct cannot be confused */
1022
1023 v = visitor_input_test_init(data, "1");
51e72bc1 1024 visit_type_TestStruct(v, NULL, &p, &err);
2533377c
EB
1025 error_free_or_abort(&err);
1026 g_assert(!p);
1027
1028 v = visitor_input_test_init(data, "{}");
51e72bc1 1029 visit_type_int(v, NULL, &i, &err);
2533377c
EB
1030 error_free_or_abort(&err);
1031
1032 /* Make sure primitives and arrays cannot be confused */
1033
1034 v = visitor_input_test_init(data, "1");
51e72bc1 1035 visit_type_strList(v, NULL, &q, &err);
2533377c
EB
1036 error_free_or_abort(&err);
1037 assert(!q);
1038
1039 v = visitor_input_test_init(data, "[]");
51e72bc1 1040 visit_type_int(v, NULL, &i, &err);
2533377c
EB
1041 error_free_or_abort(&err);
1042}
1043
77c47de2
MA
1044static void test_visitor_in_fail_struct(TestInputVisitorData *data,
1045 const void *unused)
1046{
1047 TestStruct *p = NULL;
1048 Error *err = NULL;
1049 Visitor *v;
1050
1051 v = visitor_input_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo', 'extra': 42 }");
1052
1053 visit_type_TestStruct(v, NULL, &p, &err);
1054 error_free_or_abort(&err);
1055 g_assert(!p);
1056}
1057
1058static void test_visitor_in_fail_struct_nested(TestInputVisitorData *data,
1059 const void *unused)
1060{
1061 UserDefTwo *udp = NULL;
1062 Error *err = NULL;
1063 Visitor *v;
1064
1065 v = visitor_input_test_init(data, "{ 'string0': 'string0', 'dict1': { 'string1': 'string1', 'dict2': { 'userdef1': { 'integer': 42, 'string': 'string', 'extra': [42, 23, {'foo':'bar'}] }, 'string2': 'string2'}}}");
1066
1067 visit_type_UserDefTwo(v, NULL, &udp, &err);
1068 error_free_or_abort(&err);
1069 g_assert(!udp);
1070}
1071
1072static void test_visitor_in_fail_struct_in_list(TestInputVisitorData *data,
1073 const void *unused)
1074{
1075 UserDefOneList *head = NULL;
1076 Error *err = NULL;
1077 Visitor *v;
1078
1079 v = visitor_input_test_init(data, "[ { 'string': 'string0', 'integer': 42 }, { 'string': 'string1', 'integer': 43 }, { 'string': 'string2', 'integer': 44, 'extra': 'ggg' } ]");
1080
1081 visit_type_UserDefOneList(v, NULL, &head, &err);
1082 error_free_or_abort(&err);
1083 g_assert(!head);
1084}
1085
1086static void test_visitor_in_fail_struct_missing(TestInputVisitorData *data,
1087 const void *unused)
1088{
1089 Error *err = NULL;
1090 Visitor *v;
1091 QObject *any;
d2f95f4d 1092 QNull *null;
77c47de2
MA
1093 GenericAlternate *alt;
1094 bool present;
1095 int en;
1096 int64_t i64;
1097 uint32_t u32;
1098 int8_t i8;
1099 char *str;
1100 double dbl;
1101
86ca0dbe 1102 v = visitor_input_test_init(data, "{ 'sub': [ {} ] }");
77c47de2
MA
1103 visit_start_struct(v, NULL, NULL, 0, &error_abort);
1104 visit_start_struct(v, "struct", NULL, 0, &err);
1105 error_free_or_abort(&err);
1106 visit_start_list(v, "list", NULL, 0, &err);
1107 error_free_or_abort(&err);
60390d2d 1108 visit_start_alternate(v, "alternate", &alt, sizeof(*alt), &err);
77c47de2
MA
1109 error_free_or_abort(&err);
1110 visit_optional(v, "optional", &present);
1111 g_assert(!present);
f7abe0ec 1112 visit_type_enum(v, "enum", &en, &EnumOne_lookup, &err);
77c47de2
MA
1113 error_free_or_abort(&err);
1114 visit_type_int(v, "i64", &i64, &err);
1115 error_free_or_abort(&err);
1116 visit_type_uint32(v, "u32", &u32, &err);
1117 error_free_or_abort(&err);
1118 visit_type_int8(v, "i8", &i8, &err);
1119 error_free_or_abort(&err);
1120 visit_type_str(v, "i8", &str, &err);
1121 error_free_or_abort(&err);
1122 visit_type_number(v, "dbl", &dbl, &err);
1123 error_free_or_abort(&err);
1124 visit_type_any(v, "any", &any, &err);
1125 error_free_or_abort(&err);
d2f95f4d 1126 visit_type_null(v, "null", &null, &err);
77c47de2 1127 error_free_or_abort(&err);
86ca0dbe
MA
1128 visit_start_list(v, "sub", NULL, 0, &error_abort);
1129 visit_start_struct(v, NULL, NULL, 0, &error_abort);
1130 visit_type_int(v, "i64", &i64, &err);
1131 error_free_or_abort(&err);
1132 visit_end_struct(v, NULL);
1133 visit_end_list(v, NULL);
77c47de2
MA
1134 visit_end_struct(v, NULL);
1135}
1136
9cb8ef36
MA
1137static void test_visitor_in_fail_list(TestInputVisitorData *data,
1138 const void *unused)
1139{
1140 int64_t i64 = -1;
a4a1c70d 1141 Error *err = NULL;
9cb8ef36
MA
1142 Visitor *v;
1143
1144 /* Unvisited list tail */
1145
1146 v = visitor_input_test_init(data, "[ 1, 2, 3 ]");
1147
1148 visit_start_list(v, NULL, NULL, 0, &error_abort);
1149 visit_type_int(v, NULL, &i64, &error_abort);
1150 g_assert_cmpint(i64, ==, 1);
1151 visit_type_int(v, NULL, &i64, &error_abort);
1152 g_assert_cmpint(i64, ==, 2);
a4a1c70d
MA
1153 visit_check_list(v, &err);
1154 error_free_or_abort(&err);
9cb8ef36 1155 visit_end_list(v, NULL);
a9416dc6
MA
1156
1157 /* Visit beyond end of list */
1158 v = visitor_input_test_init(data, "[]");
1159
1160 visit_start_list(v, NULL, NULL, 0, &error_abort);
a9416dc6
MA
1161 visit_type_int(v, NULL, &i64, &err);
1162 error_free_or_abort(&err);
a9416dc6 1163 visit_end_list(v, NULL);
9cb8ef36
MA
1164}
1165
1166static void test_visitor_in_fail_list_nested(TestInputVisitorData *data,
1167 const void *unused)
1168{
1169 int64_t i64 = -1;
a4a1c70d 1170 Error *err = NULL;
9cb8ef36
MA
1171 Visitor *v;
1172
1173 /* Unvisited nested list tail */
1174
1175 v = visitor_input_test_init(data, "[ 0, [ 1, 2, 3 ] ]");
1176
1177 visit_start_list(v, NULL, NULL, 0, &error_abort);
1178 visit_type_int(v, NULL, &i64, &error_abort);
1179 g_assert_cmpint(i64, ==, 0);
1180 visit_start_list(v, NULL, NULL, 0, &error_abort);
1181 visit_type_int(v, NULL, &i64, &error_abort);
1182 g_assert_cmpint(i64, ==, 1);
a4a1c70d
MA
1183 visit_check_list(v, &err);
1184 error_free_or_abort(&err);
9cb8ef36 1185 visit_end_list(v, NULL);
a4a1c70d 1186 visit_check_list(v, &error_abort);
9cb8ef36
MA
1187 visit_end_list(v, NULL);
1188}
1189
77c47de2
MA
1190static void test_visitor_in_fail_union_native_list(TestInputVisitorData *data,
1191 const void *unused)
1192{
1193 UserDefNativeListUnion *tmp = NULL;
1194 Error *err = NULL;
1195 Visitor *v;
1196
1197 v = visitor_input_test_init(data,
1198 "{ 'type': 'integer', 'data' : [ 'string' ] }");
1199
1200 visit_type_UserDefNativeListUnion(v, NULL, &tmp, &err);
1201 error_free_or_abort(&err);
1202 g_assert(!tmp);
1203}
1204
1205static void test_visitor_in_fail_union_flat(TestInputVisitorData *data,
1206 const void *unused)
1207{
1208 UserDefFlatUnion *tmp = NULL;
1209 Error *err = NULL;
1210 Visitor *v;
1211
1212 v = visitor_input_test_init(data, "{ 'string': 'c', 'integer': 41, 'boolean': true }");
1213
1214 visit_type_UserDefFlatUnion(v, NULL, &tmp, &err);
1215 error_free_or_abort(&err);
1216 g_assert(!tmp);
1217}
1218
1219static void test_visitor_in_fail_union_flat_no_discrim(TestInputVisitorData *data,
1220 const void *unused)
1221{
1222 UserDefFlatUnion2 *tmp = NULL;
1223 Error *err = NULL;
1224 Visitor *v;
1225
1226 /* test situation where discriminator field ('enum1' here) is missing */
1227 v = visitor_input_test_init(data, "{ 'integer': 42, 'string': 'c', 'string1': 'd', 'string2': 'e' }");
1228
1229 visit_type_UserDefFlatUnion2(v, NULL, &tmp, &err);
1230 error_free_or_abort(&err);
1231 g_assert(!tmp);
1232}
1233
1234static void test_visitor_in_fail_alternate(TestInputVisitorData *data,
1235 const void *unused)
1236{
1237 UserDefAlternate *tmp;
1238 Visitor *v;
1239 Error *err = NULL;
1240
1241 v = visitor_input_test_init(data, "3.14");
1242
1243 visit_type_UserDefAlternate(v, NULL, &tmp, &err);
1244 error_free_or_abort(&err);
1245 g_assert(!tmp);
1246}
1247
1248static void do_test_visitor_in_qmp_introspect(TestInputVisitorData *data,
1249 const char *schema_json)
1250{
1251 SchemaInfoList *schema = NULL;
1252 Visitor *v;
1253
1254 v = visitor_input_test_init_raw(data, schema_json);
1255
1256 visit_type_SchemaInfoList(v, NULL, &schema, &error_abort);
1257 g_assert(schema);
1258
1259 qapi_free_SchemaInfoList(schema);
1260}
1261
1262static void test_visitor_in_qmp_introspect(TestInputVisitorData *data,
1263 const void *unused)
1264{
1265 do_test_visitor_in_qmp_introspect(data, test_qmp_schema_json);
1266 do_test_visitor_in_qmp_introspect(data, qmp_schema_json);
1267}
1268
d88f5fd1
LC
1269int main(int argc, char **argv)
1270{
d88f5fd1
LC
1271 g_test_init(&argc, &argv, NULL);
1272
1273 input_visitor_test_add("/visitor/input/int",
b1d2e5f1 1274 NULL, test_visitor_in_int);
4bc0c94d
MA
1275 input_visitor_test_add("/visitor/input/uint",
1276 NULL, test_visitor_in_uint);
e92cfa0d 1277 input_visitor_test_add("/visitor/input/int_overflow",
b1d2e5f1 1278 NULL, test_visitor_in_int_overflow);
cbd8acf3
DB
1279 input_visitor_test_add("/visitor/input/int_keyval",
1280 NULL, test_visitor_in_int_keyval);
1281 input_visitor_test_add("/visitor/input/int_str_keyval",
1282 NULL, test_visitor_in_int_str_keyval);
1283 input_visitor_test_add("/visitor/input/int_str_fail",
1284 NULL, test_visitor_in_int_str_fail);
d88f5fd1 1285 input_visitor_test_add("/visitor/input/bool",
b1d2e5f1 1286 NULL, test_visitor_in_bool);
cbd8acf3
DB
1287 input_visitor_test_add("/visitor/input/bool_keyval",
1288 NULL, test_visitor_in_bool_keyval);
1289 input_visitor_test_add("/visitor/input/bool_str_keyval",
1290 NULL, test_visitor_in_bool_str_keyval);
1291 input_visitor_test_add("/visitor/input/bool_str_fail",
1292 NULL, test_visitor_in_bool_str_fail);
d88f5fd1 1293 input_visitor_test_add("/visitor/input/number",
b1d2e5f1 1294 NULL, test_visitor_in_number);
c1214ad3
MAL
1295 input_visitor_test_add("/visitor/input/large_number",
1296 NULL, test_visitor_in_large_number);
cbd8acf3
DB
1297 input_visitor_test_add("/visitor/input/number_keyval",
1298 NULL, test_visitor_in_number_keyval);
1299 input_visitor_test_add("/visitor/input/number_str_keyval",
1300 NULL, test_visitor_in_number_str_keyval);
1301 input_visitor_test_add("/visitor/input/number_str_fail",
1302 NULL, test_visitor_in_number_str_fail);
1303 input_visitor_test_add("/visitor/input/size_str_keyval",
1304 NULL, test_visitor_in_size_str_keyval);
1305 input_visitor_test_add("/visitor/input/size_str_fail",
1306 NULL, test_visitor_in_size_str_fail);
d88f5fd1 1307 input_visitor_test_add("/visitor/input/string",
b1d2e5f1 1308 NULL, test_visitor_in_string);
d88f5fd1 1309 input_visitor_test_add("/visitor/input/enum",
b1d2e5f1 1310 NULL, test_visitor_in_enum);
d88f5fd1 1311 input_visitor_test_add("/visitor/input/struct",
b1d2e5f1 1312 NULL, test_visitor_in_struct);
d88f5fd1 1313 input_visitor_test_add("/visitor/input/struct-nested",
b1d2e5f1 1314 NULL, test_visitor_in_struct_nested);
d88f5fd1 1315 input_visitor_test_add("/visitor/input/list",
b1d2e5f1 1316 NULL, test_visitor_in_list);
28770e05 1317 input_visitor_test_add("/visitor/input/any",
b1d2e5f1 1318 NULL, test_visitor_in_any);
3df016f1 1319 input_visitor_test_add("/visitor/input/null",
b1d2e5f1 1320 NULL, test_visitor_in_null);
2fc00432 1321 input_visitor_test_add("/visitor/input/union-flat",
b1d2e5f1 1322 NULL, test_visitor_in_union_flat);
ab045267 1323 input_visitor_test_add("/visitor/input/alternate",
b1d2e5f1 1324 NULL, test_visitor_in_alternate);
3dcf71f6 1325 input_visitor_test_add("/visitor/input/errors",
b1d2e5f1 1326 NULL, test_visitor_in_errors);
2533377c 1327 input_visitor_test_add("/visitor/input/wrong-type",
b1d2e5f1 1328 NULL, test_visitor_in_wrong_type);
9c51b441 1329 input_visitor_test_add("/visitor/input/alternate-number",
b1d2e5f1 1330 NULL, test_visitor_in_alternate_number);
199e0f17 1331 input_visitor_test_add("/visitor/input/native_list/int",
b1d2e5f1 1332 NULL, test_visitor_in_native_list_int);
199e0f17 1333 input_visitor_test_add("/visitor/input/native_list/int8",
b1d2e5f1 1334 NULL, test_visitor_in_native_list_int8);
199e0f17 1335 input_visitor_test_add("/visitor/input/native_list/int16",
b1d2e5f1 1336 NULL, test_visitor_in_native_list_int16);
199e0f17 1337 input_visitor_test_add("/visitor/input/native_list/int32",
b1d2e5f1 1338 NULL, test_visitor_in_native_list_int32);
199e0f17 1339 input_visitor_test_add("/visitor/input/native_list/int64",
b1d2e5f1 1340 NULL, test_visitor_in_native_list_int64);
199e0f17 1341 input_visitor_test_add("/visitor/input/native_list/uint8",
b1d2e5f1 1342 NULL, test_visitor_in_native_list_uint8);
199e0f17 1343 input_visitor_test_add("/visitor/input/native_list/uint16",
b1d2e5f1 1344 NULL, test_visitor_in_native_list_uint16);
199e0f17 1345 input_visitor_test_add("/visitor/input/native_list/uint32",
b1d2e5f1 1346 NULL, test_visitor_in_native_list_uint32);
199e0f17 1347 input_visitor_test_add("/visitor/input/native_list/uint64",
b1d2e5f1 1348 NULL, test_visitor_in_native_list_uint64);
199e0f17 1349 input_visitor_test_add("/visitor/input/native_list/bool",
b1d2e5f1 1350 NULL, test_visitor_in_native_list_bool);
199e0f17 1351 input_visitor_test_add("/visitor/input/native_list/str",
b1d2e5f1 1352 NULL, test_visitor_in_native_list_string);
199e0f17 1353 input_visitor_test_add("/visitor/input/native_list/number",
b1d2e5f1 1354 NULL, test_visitor_in_native_list_number);
77c47de2
MA
1355 input_visitor_test_add("/visitor/input/fail/struct",
1356 NULL, test_visitor_in_fail_struct);
1357 input_visitor_test_add("/visitor/input/fail/struct-nested",
1358 NULL, test_visitor_in_fail_struct_nested);
1359 input_visitor_test_add("/visitor/input/fail/struct-in-list",
1360 NULL, test_visitor_in_fail_struct_in_list);
1361 input_visitor_test_add("/visitor/input/fail/struct-missing",
1362 NULL, test_visitor_in_fail_struct_missing);
9cb8ef36
MA
1363 input_visitor_test_add("/visitor/input/fail/list",
1364 NULL, test_visitor_in_fail_list);
1365 input_visitor_test_add("/visitor/input/fail/list-nested",
1366 NULL, test_visitor_in_fail_list_nested);
77c47de2
MA
1367 input_visitor_test_add("/visitor/input/fail/union-flat",
1368 NULL, test_visitor_in_fail_union_flat);
1369 input_visitor_test_add("/visitor/input/fail/union-flat-no-discriminator",
1370 NULL, test_visitor_in_fail_union_flat_no_discrim);
1371 input_visitor_test_add("/visitor/input/fail/alternate",
1372 NULL, test_visitor_in_fail_alternate);
1373 input_visitor_test_add("/visitor/input/fail/union-native-list",
1374 NULL, test_visitor_in_fail_union_native_list);
1375 input_visitor_test_add("/visitor/input/qmp-introspect",
1376 NULL, test_visitor_in_qmp_introspect);
d88f5fd1
LC
1377
1378 g_test_run();
1379
1380 return 0;
1381}