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