]> git.proxmox.com Git - mirror_qemu.git/blame - tests/test-qmp-input-visitor.c
qapi: More tests of alternate output
[mirror_qemu.git] / tests / test-qmp-input-visitor.c
CommitLineData
d88f5fd1
LC
1/*
2 * QMP Input Visitor unit-tests.
3 *
805017b7 4 * Copyright (C) 2011, 2015 Red Hat Inc.
d88f5fd1
LC
5 *
6 * Authors:
7 * Luiz Capitulino <lcapitulino@redhat.com>
8 *
9 * This work is licensed under the terms of the GNU GPL, version 2 or later.
10 * See the COPYING file in the top-level directory.
11 */
12
13#include <glib.h>
14#include <stdarg.h>
15
79ee7df8 16#include "qemu-common.h"
d88f5fd1
LC
17#include "qapi/qmp-input-visitor.h"
18#include "test-qapi-types.h"
19#include "test-qapi-visit.h"
7b1b5d19 20#include "qapi/qmp/types.h"
d88f5fd1
LC
21
22typedef struct TestInputVisitorData {
23 QObject *obj;
24 QmpInputVisitor *qiv;
25} TestInputVisitorData;
26
27static void visitor_input_teardown(TestInputVisitorData *data,
28 const void *unused)
29{
30 qobject_decref(data->obj);
31 data->obj = NULL;
32
33 if (data->qiv) {
34 qmp_input_visitor_cleanup(data->qiv);
35 data->qiv = NULL;
36 }
37}
38
0920a171
EB
39/* The various test_init functions are provided instead of a test setup
40 function so that the JSON string used by the tests are kept in the test
41 functions (and not in main()). */
42static Visitor *visitor_input_test_init_internal(TestInputVisitorData *data,
43 const char *json_string,
44 va_list *ap)
45{
46 Visitor *v;
47
b18f1141
EB
48 visitor_input_teardown(data, NULL);
49
0920a171
EB
50 data->obj = qobject_from_jsonv(json_string, ap);
51 g_assert(data->obj);
52
53 data->qiv = qmp_input_visitor_new(data->obj);
54 g_assert(data->qiv);
55
56 v = qmp_input_get_visitor(data->qiv);
57 g_assert(v);
58
59 return v;
60}
61
aba2107a
SW
62static GCC_FMT_ATTR(2, 3)
63Visitor *visitor_input_test_init(TestInputVisitorData *data,
64 const char *json_string, ...)
d88f5fd1
LC
65{
66 Visitor *v;
67 va_list ap;
68
69 va_start(ap, json_string);
0920a171 70 v = visitor_input_test_init_internal(data, json_string, &ap);
d88f5fd1 71 va_end(ap);
d88f5fd1
LC
72 return v;
73}
74
199e0f17
MR
75/* similar to visitor_input_test_init(), but does not expect a string
76 * literal/format json_string argument and so can be used for
77 * programatically generated strings (and we can't pass in programatically
78 * generated strings via %s format parameters since qobject_from_jsonv()
79 * will wrap those in double-quotes and treat the entire object as a
80 * string)
81 */
82static Visitor *visitor_input_test_init_raw(TestInputVisitorData *data,
83 const char *json_string)
84{
0920a171 85 return visitor_input_test_init_internal(data, json_string, NULL);
199e0f17
MR
86}
87
d88f5fd1
LC
88static void test_visitor_in_int(TestInputVisitorData *data,
89 const void *unused)
90{
91 int64_t res = 0, value = -42;
d88f5fd1
LC
92 Visitor *v;
93
aba2107a 94 v = visitor_input_test_init(data, "%" PRId64, value);
d88f5fd1 95
3f66f764 96 visit_type_int(v, &res, NULL, &error_abort);
d88f5fd1
LC
97 g_assert_cmpint(res, ==, value);
98}
99
e92cfa0d
MR
100static void test_visitor_in_int_overflow(TestInputVisitorData *data,
101 const void *unused)
102{
103 int64_t res = 0;
e940f543 104 Error *err = NULL;
e92cfa0d
MR
105 Visitor *v;
106
107 /* this will overflow a Qint/int64, so should be deserialized into
108 * a QFloat/double field instead, leading to an error if we pass it
109 * to visit_type_int. confirm this.
110 */
111 v = visitor_input_test_init(data, "%f", DBL_MAX);
112
e940f543 113 visit_type_int(v, &res, NULL, &err);
a12a5a1a 114 error_free_or_abort(&err);
e92cfa0d
MR
115}
116
d88f5fd1
LC
117static void test_visitor_in_bool(TestInputVisitorData *data,
118 const void *unused)
119{
d88f5fd1
LC
120 bool res = false;
121 Visitor *v;
122
123 v = visitor_input_test_init(data, "true");
124
3f66f764 125 visit_type_bool(v, &res, NULL, &error_abort);
d88f5fd1
LC
126 g_assert_cmpint(res, ==, true);
127}
128
129static void test_visitor_in_number(TestInputVisitorData *data,
130 const void *unused)
131{
132 double res = 0, value = 3.14;
d88f5fd1
LC
133 Visitor *v;
134
135 v = visitor_input_test_init(data, "%f", value);
136
3f66f764 137 visit_type_number(v, &res, NULL, &error_abort);
d88f5fd1
LC
138 g_assert_cmpfloat(res, ==, value);
139}
140
141static void test_visitor_in_string(TestInputVisitorData *data,
142 const void *unused)
143{
144 char *res = NULL, *value = (char *) "Q E M U";
d88f5fd1
LC
145 Visitor *v;
146
147 v = visitor_input_test_init(data, "%s", value);
148
3f66f764 149 visit_type_str(v, &res, NULL, &error_abort);
d88f5fd1
LC
150 g_assert_cmpstr(res, ==, value);
151
152 g_free(res);
153}
154
155static void test_visitor_in_enum(TestInputVisitorData *data,
156 const void *unused)
157{
d88f5fd1
LC
158 Visitor *v;
159 EnumOne i;
160
161 for (i = 0; EnumOne_lookup[i]; i++) {
162 EnumOne res = -1;
163
164 v = visitor_input_test_init(data, "%s", EnumOne_lookup[i]);
165
3f66f764 166 visit_type_EnumOne(v, &res, NULL, &error_abort);
d88f5fd1 167 g_assert_cmpint(i, ==, res);
d88f5fd1 168 }
d88f5fd1
LC
169}
170
d88f5fd1
LC
171
172static void test_visitor_in_struct(TestInputVisitorData *data,
173 const void *unused)
174{
175 TestStruct *p = NULL;
d88f5fd1
LC
176 Visitor *v;
177
178 v = visitor_input_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo' }");
179
3f66f764 180 visit_type_TestStruct(v, &p, NULL, &error_abort);
d88f5fd1
LC
181 g_assert_cmpint(p->integer, ==, -42);
182 g_assert(p->boolean == true);
183 g_assert_cmpstr(p->string, ==, "foo");
184
185 g_free(p->string);
186 g_free(p);
187}
188
d88f5fd1
LC
189static void test_visitor_in_struct_nested(TestInputVisitorData *data,
190 const void *unused)
191{
b6fcf32d 192 UserDefTwo *udp = NULL;
d88f5fd1
LC
193 Visitor *v;
194
b6fcf32d
EB
195 v = visitor_input_test_init(data, "{ 'string0': 'string0', "
196 "'dict1': { 'string1': 'string1', "
197 "'dict2': { 'userdef': { 'integer': 42, "
198 "'string': 'string' }, 'string': 'string2'}}}");
d88f5fd1 199
3f66f764 200 visit_type_UserDefTwo(v, &udp, NULL, &error_abort);
d88f5fd1 201
b18f1141
EB
202 g_assert_cmpstr(udp->string0, ==, "string0");
203 g_assert_cmpstr(udp->dict1->string1, ==, "string1");
ddf21908 204 g_assert_cmpint(udp->dict1->dict2->userdef->integer, ==, 42);
b18f1141
EB
205 g_assert_cmpstr(udp->dict1->dict2->userdef->string, ==, "string");
206 g_assert_cmpstr(udp->dict1->dict2->string, ==, "string2");
6446a592
EB
207 g_assert(udp->dict1->has_dict3 == false);
208
b18f1141 209 qapi_free_UserDefTwo(udp);
d88f5fd1
LC
210}
211
212static void test_visitor_in_list(TestInputVisitorData *data,
213 const void *unused)
214{
215 UserDefOneList *item, *head = NULL;
d88f5fd1
LC
216 Visitor *v;
217 int i;
218
219 v = visitor_input_test_init(data, "[ { 'string': 'string0', 'integer': 42 }, { 'string': 'string1', 'integer': 43 }, { 'string': 'string2', 'integer': 44 } ]");
220
3f66f764 221 visit_type_UserDefOneList(v, &head, NULL, &error_abort);
d88f5fd1
LC
222 g_assert(head != NULL);
223
224 for (i = 0, item = head; item; item = item->next, i++) {
225 char string[12];
226
227 snprintf(string, sizeof(string), "string%d", i);
228 g_assert_cmpstr(item->value->string, ==, string);
ddf21908 229 g_assert_cmpint(item->value->integer, ==, 42 + i);
d88f5fd1
LC
230 }
231
232 qapi_free_UserDefOneList(head);
233}
234
28770e05
MA
235static void test_visitor_in_any(TestInputVisitorData *data,
236 const void *unused)
237{
238 QObject *res = NULL;
28770e05
MA
239 Visitor *v;
240 QInt *qint;
241 QBool *qbool;
242 QString *qstring;
243 QDict *qdict;
244 QObject *qobj;
245
246 v = visitor_input_test_init(data, "-42");
3f66f764 247 visit_type_any(v, &res, NULL, &error_abort);
28770e05
MA
248 qint = qobject_to_qint(res);
249 g_assert(qint);
250 g_assert_cmpint(qint_get_int(qint), ==, -42);
251 qobject_decref(res);
252
253 v = visitor_input_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo' }");
3f66f764 254 visit_type_any(v, &res, NULL, &error_abort);
28770e05
MA
255 qdict = qobject_to_qdict(res);
256 g_assert(qdict && qdict_size(qdict) == 3);
257 qobj = qdict_get(qdict, "integer");
258 g_assert(qobj);
259 qint = qobject_to_qint(qobj);
260 g_assert(qint);
261 g_assert_cmpint(qint_get_int(qint), ==, -42);
262 qobj = qdict_get(qdict, "boolean");
263 g_assert(qobj);
264 qbool = qobject_to_qbool(qobj);
265 g_assert(qbool);
266 g_assert(qbool_get_bool(qbool) == true);
267 qobj = qdict_get(qdict, "string");
268 g_assert(qobj);
269 qstring = qobject_to_qstring(qobj);
270 g_assert(qstring);
271 g_assert_cmpstr(qstring_get_str(qstring), ==, "foo");
272 qobject_decref(res);
273}
274
2fc00432
MA
275static void test_visitor_in_union_flat(TestInputVisitorData *data,
276 const void *unused)
277{
278 Visitor *v;
2fc00432 279 UserDefFlatUnion *tmp;
30594fe1 280 UserDefUnionBase *base;
2fc00432 281
5223070c
WX
282 v = visitor_input_test_init(data,
283 "{ 'enum1': 'value1', "
441cbac0 284 "'integer': 41, "
5223070c
WX
285 "'string': 'str', "
286 "'boolean': true }");
2fc00432 287
3f66f764 288 visit_type_UserDefFlatUnion(v, &tmp, NULL, &error_abort);
0f61af3e 289 g_assert_cmpint(tmp->enum1, ==, ENUM_ONE_VALUE1);
5223070c 290 g_assert_cmpstr(tmp->string, ==, "str");
441cbac0 291 g_assert_cmpint(tmp->integer, ==, 41);
c363acef 292 g_assert_cmpint(tmp->u.value1->boolean, ==, true);
30594fe1
EB
293
294 base = qapi_UserDefFlatUnion_base(tmp);
295 g_assert(&base->enum1 == &tmp->enum1);
296
2fc00432
MA
297 qapi_free_UserDefFlatUnion(tmp);
298}
299
ab045267
EB
300static void test_visitor_in_alternate(TestInputVisitorData *data,
301 const void *unused)
2c38b600
MA
302{
303 Visitor *v;
304 Error *err = NULL;
ab045267 305 UserDefAlternate *tmp;
2c38b600
MA
306
307 v = visitor_input_test_init(data, "42");
9c51b441 308 visit_type_UserDefAlternate(v, &tmp, NULL, &error_abort);
c363acef
EB
309 g_assert_cmpint(tmp->type, ==, USER_DEF_ALTERNATE_KIND_I);
310 g_assert_cmpint(tmp->u.i, ==, 42);
ab045267 311 qapi_free_UserDefAlternate(tmp);
9c51b441
EB
312
313 v = visitor_input_test_init(data, "'string'");
314 visit_type_UserDefAlternate(v, &tmp, NULL, &error_abort);
c363acef
EB
315 g_assert_cmpint(tmp->type, ==, USER_DEF_ALTERNATE_KIND_S);
316 g_assert_cmpstr(tmp->u.s, ==, "string");
9c51b441 317 qapi_free_UserDefAlternate(tmp);
9c51b441
EB
318
319 v = visitor_input_test_init(data, "false");
320 visit_type_UserDefAlternate(v, &tmp, NULL, &err);
a12a5a1a 321 error_free_or_abort(&err);
9c51b441 322 qapi_free_UserDefAlternate(tmp);
9c51b441
EB
323}
324
325static void test_visitor_in_alternate_number(TestInputVisitorData *data,
326 const void *unused)
327{
328 Visitor *v;
329 Error *err = NULL;
330 AltStrBool *asb;
331 AltStrNum *asn;
332 AltNumStr *ans;
333 AltStrInt *asi;
334 AltIntNum *ain;
335 AltNumInt *ani;
336
337 /* Parsing an int */
338
339 v = visitor_input_test_init(data, "42");
340 visit_type_AltStrBool(v, &asb, NULL, &err);
a12a5a1a 341 error_free_or_abort(&err);
9c51b441 342 qapi_free_AltStrBool(asb);
9c51b441
EB
343
344 /* FIXME: Order of alternate should not affect semantics; asn should
345 * parse the same as ans */
346 v = visitor_input_test_init(data, "42");
347 visit_type_AltStrNum(v, &asn, NULL, &err);
c363acef
EB
348 /* FIXME g_assert_cmpint(asn->type, == ALT_STR_NUM_KIND_N); */
349 /* FIXME g_assert_cmpfloat(asn->u.n, ==, 42); */
a12a5a1a 350 error_free_or_abort(&err);
9c51b441 351 qapi_free_AltStrNum(asn);
9c51b441
EB
352
353 v = visitor_input_test_init(data, "42");
354 visit_type_AltNumStr(v, &ans, NULL, &error_abort);
c363acef
EB
355 g_assert_cmpint(ans->type, ==, ALT_NUM_STR_KIND_N);
356 g_assert_cmpfloat(ans->u.n, ==, 42);
9c51b441 357 qapi_free_AltNumStr(ans);
9c51b441
EB
358
359 v = visitor_input_test_init(data, "42");
360 visit_type_AltStrInt(v, &asi, NULL, &error_abort);
c363acef
EB
361 g_assert_cmpint(asi->type, ==, ALT_STR_INT_KIND_I);
362 g_assert_cmpint(asi->u.i, ==, 42);
9c51b441 363 qapi_free_AltStrInt(asi);
9c51b441
EB
364
365 v = visitor_input_test_init(data, "42");
366 visit_type_AltIntNum(v, &ain, NULL, &error_abort);
c363acef
EB
367 g_assert_cmpint(ain->type, ==, ALT_INT_NUM_KIND_I);
368 g_assert_cmpint(ain->u.i, ==, 42);
9c51b441 369 qapi_free_AltIntNum(ain);
9c51b441
EB
370
371 v = visitor_input_test_init(data, "42");
372 visit_type_AltNumInt(v, &ani, NULL, &error_abort);
c363acef
EB
373 g_assert_cmpint(ani->type, ==, ALT_NUM_INT_KIND_I);
374 g_assert_cmpint(ani->u.i, ==, 42);
9c51b441 375 qapi_free_AltNumInt(ani);
9c51b441
EB
376
377 /* Parsing a double */
378
379 v = visitor_input_test_init(data, "42.5");
380 visit_type_AltStrBool(v, &asb, NULL, &err);
a12a5a1a 381 error_free_or_abort(&err);
9c51b441 382 qapi_free_AltStrBool(asb);
9c51b441
EB
383
384 v = visitor_input_test_init(data, "42.5");
385 visit_type_AltStrNum(v, &asn, NULL, &error_abort);
c363acef
EB
386 g_assert_cmpint(asn->type, ==, ALT_STR_NUM_KIND_N);
387 g_assert_cmpfloat(asn->u.n, ==, 42.5);
9c51b441 388 qapi_free_AltStrNum(asn);
9c51b441
EB
389
390 v = visitor_input_test_init(data, "42.5");
391 visit_type_AltNumStr(v, &ans, NULL, &error_abort);
c363acef
EB
392 g_assert_cmpint(ans->type, ==, ALT_NUM_STR_KIND_N);
393 g_assert_cmpfloat(ans->u.n, ==, 42.5);
9c51b441 394 qapi_free_AltNumStr(ans);
9c51b441
EB
395
396 v = visitor_input_test_init(data, "42.5");
397 visit_type_AltStrInt(v, &asi, NULL, &err);
a12a5a1a 398 error_free_or_abort(&err);
9c51b441 399 qapi_free_AltStrInt(asi);
9c51b441
EB
400
401 v = visitor_input_test_init(data, "42.5");
402 visit_type_AltIntNum(v, &ain, NULL, &error_abort);
c363acef
EB
403 g_assert_cmpint(ain->type, ==, ALT_INT_NUM_KIND_N);
404 g_assert_cmpfloat(ain->u.n, ==, 42.5);
9c51b441 405 qapi_free_AltIntNum(ain);
9c51b441
EB
406
407 v = visitor_input_test_init(data, "42.5");
408 visit_type_AltNumInt(v, &ani, NULL, &error_abort);
c363acef
EB
409 g_assert_cmpint(ani->type, ==, ALT_NUM_INT_KIND_N);
410 g_assert_cmpfloat(ani->u.n, ==, 42.5);
9c51b441 411 qapi_free_AltNumInt(ani);
2c38b600
MA
412}
413
199e0f17
MR
414static void test_native_list_integer_helper(TestInputVisitorData *data,
415 const void *unused,
416 UserDefNativeListUnionKind kind)
417{
418 UserDefNativeListUnion *cvalue = NULL;
199e0f17
MR
419 Visitor *v;
420 GString *gstr_list = g_string_new("");
421 GString *gstr_union = g_string_new("");
422 int i;
423
424 for (i = 0; i < 32; i++) {
425 g_string_append_printf(gstr_list, "%d", i);
426 if (i != 31) {
427 g_string_append(gstr_list, ", ");
428 }
429 }
430 g_string_append_printf(gstr_union, "{ 'type': '%s', 'data': [ %s ] }",
431 UserDefNativeListUnionKind_lookup[kind],
432 gstr_list->str);
433 v = visitor_input_test_init_raw(data, gstr_union->str);
434
3f66f764 435 visit_type_UserDefNativeListUnion(v, &cvalue, NULL, &error_abort);
199e0f17 436 g_assert(cvalue != NULL);
c363acef 437 g_assert_cmpint(cvalue->type, ==, kind);
199e0f17
MR
438
439 switch (kind) {
440 case USER_DEF_NATIVE_LIST_UNION_KIND_INTEGER: {
441 intList *elem = NULL;
c363acef 442 for (i = 0, elem = cvalue->u.integer; elem; elem = elem->next, i++) {
199e0f17
MR
443 g_assert_cmpint(elem->value, ==, i);
444 }
445 break;
446 }
447 case USER_DEF_NATIVE_LIST_UNION_KIND_S8: {
448 int8List *elem = NULL;
c363acef 449 for (i = 0, elem = cvalue->u.s8; elem; elem = elem->next, i++) {
199e0f17
MR
450 g_assert_cmpint(elem->value, ==, i);
451 }
452 break;
453 }
454 case USER_DEF_NATIVE_LIST_UNION_KIND_S16: {
455 int16List *elem = NULL;
c363acef 456 for (i = 0, elem = cvalue->u.s16; elem; elem = elem->next, i++) {
199e0f17
MR
457 g_assert_cmpint(elem->value, ==, i);
458 }
459 break;
460 }
461 case USER_DEF_NATIVE_LIST_UNION_KIND_S32: {
462 int32List *elem = NULL;
c363acef 463 for (i = 0, elem = cvalue->u.s32; elem; elem = elem->next, i++) {
199e0f17
MR
464 g_assert_cmpint(elem->value, ==, i);
465 }
466 break;
467 }
468 case USER_DEF_NATIVE_LIST_UNION_KIND_S64: {
469 int64List *elem = NULL;
c363acef 470 for (i = 0, elem = cvalue->u.s64; elem; elem = elem->next, i++) {
199e0f17
MR
471 g_assert_cmpint(elem->value, ==, i);
472 }
473 break;
474 }
475 case USER_DEF_NATIVE_LIST_UNION_KIND_U8: {
476 uint8List *elem = NULL;
c363acef 477 for (i = 0, elem = cvalue->u.u8; elem; elem = elem->next, i++) {
199e0f17
MR
478 g_assert_cmpint(elem->value, ==, i);
479 }
480 break;
481 }
482 case USER_DEF_NATIVE_LIST_UNION_KIND_U16: {
483 uint16List *elem = NULL;
c363acef 484 for (i = 0, elem = cvalue->u.u16; elem; elem = elem->next, i++) {
199e0f17
MR
485 g_assert_cmpint(elem->value, ==, i);
486 }
487 break;
488 }
489 case USER_DEF_NATIVE_LIST_UNION_KIND_U32: {
490 uint32List *elem = NULL;
c363acef 491 for (i = 0, elem = cvalue->u.u32; elem; elem = elem->next, i++) {
199e0f17
MR
492 g_assert_cmpint(elem->value, ==, i);
493 }
494 break;
495 }
496 case USER_DEF_NATIVE_LIST_UNION_KIND_U64: {
497 uint64List *elem = NULL;
c363acef 498 for (i = 0, elem = cvalue->u.u64; elem; elem = elem->next, i++) {
199e0f17
MR
499 g_assert_cmpint(elem->value, ==, i);
500 }
501 break;
502 }
503 default:
dfc6f865 504 g_assert_not_reached();
199e0f17
MR
505 }
506
507 g_string_free(gstr_union, true);
508 g_string_free(gstr_list, true);
509 qapi_free_UserDefNativeListUnion(cvalue);
510}
511
512static void test_visitor_in_native_list_int(TestInputVisitorData *data,
513 const void *unused)
514{
515 test_native_list_integer_helper(data, unused,
516 USER_DEF_NATIVE_LIST_UNION_KIND_INTEGER);
517}
518
519static void test_visitor_in_native_list_int8(TestInputVisitorData *data,
520 const void *unused)
521{
522 test_native_list_integer_helper(data, unused,
523 USER_DEF_NATIVE_LIST_UNION_KIND_S8);
524}
525
526static void test_visitor_in_native_list_int16(TestInputVisitorData *data,
527 const void *unused)
528{
529 test_native_list_integer_helper(data, unused,
530 USER_DEF_NATIVE_LIST_UNION_KIND_S16);
531}
532
533static void test_visitor_in_native_list_int32(TestInputVisitorData *data,
534 const void *unused)
535{
536 test_native_list_integer_helper(data, unused,
537 USER_DEF_NATIVE_LIST_UNION_KIND_S32);
538}
539
540static void test_visitor_in_native_list_int64(TestInputVisitorData *data,
541 const void *unused)
542{
543 test_native_list_integer_helper(data, unused,
544 USER_DEF_NATIVE_LIST_UNION_KIND_S64);
545}
546
547static void test_visitor_in_native_list_uint8(TestInputVisitorData *data,
548 const void *unused)
549{
550 test_native_list_integer_helper(data, unused,
551 USER_DEF_NATIVE_LIST_UNION_KIND_U8);
552}
553
554static void test_visitor_in_native_list_uint16(TestInputVisitorData *data,
555 const void *unused)
556{
557 test_native_list_integer_helper(data, unused,
558 USER_DEF_NATIVE_LIST_UNION_KIND_U16);
559}
560
561static void test_visitor_in_native_list_uint32(TestInputVisitorData *data,
562 const void *unused)
563{
564 test_native_list_integer_helper(data, unused,
565 USER_DEF_NATIVE_LIST_UNION_KIND_U32);
566}
567
568static void test_visitor_in_native_list_uint64(TestInputVisitorData *data,
569 const void *unused)
570{
571 test_native_list_integer_helper(data, unused,
572 USER_DEF_NATIVE_LIST_UNION_KIND_U64);
573}
574
575static void test_visitor_in_native_list_bool(TestInputVisitorData *data,
576 const void *unused)
577{
578 UserDefNativeListUnion *cvalue = NULL;
579 boolList *elem = NULL;
199e0f17
MR
580 Visitor *v;
581 GString *gstr_list = g_string_new("");
582 GString *gstr_union = g_string_new("");
583 int i;
584
585 for (i = 0; i < 32; i++) {
586 g_string_append_printf(gstr_list, "%s",
587 (i % 3 == 0) ? "true" : "false");
588 if (i != 31) {
589 g_string_append(gstr_list, ", ");
590 }
591 }
592 g_string_append_printf(gstr_union, "{ 'type': 'boolean', 'data': [ %s ] }",
593 gstr_list->str);
594 v = visitor_input_test_init_raw(data, gstr_union->str);
595
3f66f764 596 visit_type_UserDefNativeListUnion(v, &cvalue, NULL, &error_abort);
199e0f17 597 g_assert(cvalue != NULL);
c363acef 598 g_assert_cmpint(cvalue->type, ==, USER_DEF_NATIVE_LIST_UNION_KIND_BOOLEAN);
199e0f17 599
c363acef 600 for (i = 0, elem = cvalue->u.boolean; elem; elem = elem->next, i++) {
199e0f17
MR
601 g_assert_cmpint(elem->value, ==, (i % 3 == 0) ? 1 : 0);
602 }
603
604 g_string_free(gstr_union, true);
605 g_string_free(gstr_list, true);
606 qapi_free_UserDefNativeListUnion(cvalue);
607}
608
609static void test_visitor_in_native_list_string(TestInputVisitorData *data,
610 const void *unused)
611{
612 UserDefNativeListUnion *cvalue = NULL;
613 strList *elem = NULL;
199e0f17
MR
614 Visitor *v;
615 GString *gstr_list = g_string_new("");
616 GString *gstr_union = g_string_new("");
617 int i;
618
619 for (i = 0; i < 32; i++) {
620 g_string_append_printf(gstr_list, "'%d'", i);
621 if (i != 31) {
622 g_string_append(gstr_list, ", ");
623 }
624 }
625 g_string_append_printf(gstr_union, "{ 'type': 'string', 'data': [ %s ] }",
626 gstr_list->str);
627 v = visitor_input_test_init_raw(data, gstr_union->str);
628
3f66f764 629 visit_type_UserDefNativeListUnion(v, &cvalue, NULL, &error_abort);
199e0f17 630 g_assert(cvalue != NULL);
c363acef 631 g_assert_cmpint(cvalue->type, ==, USER_DEF_NATIVE_LIST_UNION_KIND_STRING);
199e0f17 632
c363acef 633 for (i = 0, elem = cvalue->u.string; elem; elem = elem->next, i++) {
199e0f17
MR
634 gchar str[8];
635 sprintf(str, "%d", i);
636 g_assert_cmpstr(elem->value, ==, str);
637 }
638
639 g_string_free(gstr_union, true);
640 g_string_free(gstr_list, true);
641 qapi_free_UserDefNativeListUnion(cvalue);
642}
643
644#define DOUBLE_STR_MAX 16
645
646static void test_visitor_in_native_list_number(TestInputVisitorData *data,
647 const void *unused)
648{
649 UserDefNativeListUnion *cvalue = NULL;
650 numberList *elem = NULL;
199e0f17
MR
651 Visitor *v;
652 GString *gstr_list = g_string_new("");
653 GString *gstr_union = g_string_new("");
654 int i;
655
656 for (i = 0; i < 32; i++) {
657 g_string_append_printf(gstr_list, "%f", (double)i / 3);
658 if (i != 31) {
659 g_string_append(gstr_list, ", ");
660 }
661 }
662 g_string_append_printf(gstr_union, "{ 'type': 'number', 'data': [ %s ] }",
663 gstr_list->str);
664 v = visitor_input_test_init_raw(data, gstr_union->str);
665
3f66f764 666 visit_type_UserDefNativeListUnion(v, &cvalue, NULL, &error_abort);
199e0f17 667 g_assert(cvalue != NULL);
c363acef 668 g_assert_cmpint(cvalue->type, ==, USER_DEF_NATIVE_LIST_UNION_KIND_NUMBER);
199e0f17 669
c363acef 670 for (i = 0, elem = cvalue->u.number; elem; elem = elem->next, i++) {
199e0f17
MR
671 GString *double_expected = g_string_new("");
672 GString *double_actual = g_string_new("");
673
674 g_string_printf(double_expected, "%.6f", (double)i / 3);
675 g_string_printf(double_actual, "%.6f", elem->value);
676 g_assert_cmpstr(double_expected->str, ==, double_actual->str);
677
678 g_string_free(double_expected, true);
679 g_string_free(double_actual, true);
680 }
681
682 g_string_free(gstr_union, true);
683 g_string_free(gstr_list, true);
684 qapi_free_UserDefNativeListUnion(cvalue);
685}
686
d88f5fd1
LC
687static void input_visitor_test_add(const char *testpath,
688 TestInputVisitorData *data,
689 void (*test_func)(TestInputVisitorData *data, const void *user_data))
690{
691 g_test_add(testpath, TestInputVisitorData, data, NULL, test_func,
692 visitor_input_teardown);
693}
694
3dcf71f6
PB
695static void test_visitor_in_errors(TestInputVisitorData *data,
696 const void *unused)
697{
698 TestStruct *p = NULL;
e940f543 699 Error *err = NULL;
3dcf71f6
PB
700 Visitor *v;
701
702 v = visitor_input_test_init(data, "{ 'integer': false, 'boolean': 'foo', 'string': -42 }");
703
e940f543 704 visit_type_TestStruct(v, &p, NULL, &err);
a12a5a1a 705 error_free_or_abort(&err);
2f52e205
EB
706 /* FIXME - a failed parse should not leave a partially-allocated p
707 * for us to clean up; this could cause callers to leak memory. */
3dcf71f6
PB
708 g_assert(p->string == NULL);
709
710 g_free(p->string);
711 g_free(p);
712}
713
d88f5fd1
LC
714int main(int argc, char **argv)
715{
716 TestInputVisitorData in_visitor_data;
717
718 g_test_init(&argc, &argv, NULL);
719
720 input_visitor_test_add("/visitor/input/int",
721 &in_visitor_data, test_visitor_in_int);
e92cfa0d
MR
722 input_visitor_test_add("/visitor/input/int_overflow",
723 &in_visitor_data, test_visitor_in_int_overflow);
d88f5fd1
LC
724 input_visitor_test_add("/visitor/input/bool",
725 &in_visitor_data, test_visitor_in_bool);
726 input_visitor_test_add("/visitor/input/number",
727 &in_visitor_data, test_visitor_in_number);
728 input_visitor_test_add("/visitor/input/string",
805017b7 729 &in_visitor_data, test_visitor_in_string);
d88f5fd1 730 input_visitor_test_add("/visitor/input/enum",
805017b7 731 &in_visitor_data, test_visitor_in_enum);
d88f5fd1 732 input_visitor_test_add("/visitor/input/struct",
805017b7 733 &in_visitor_data, test_visitor_in_struct);
d88f5fd1 734 input_visitor_test_add("/visitor/input/struct-nested",
805017b7 735 &in_visitor_data, test_visitor_in_struct_nested);
d88f5fd1 736 input_visitor_test_add("/visitor/input/list",
805017b7 737 &in_visitor_data, test_visitor_in_list);
28770e05
MA
738 input_visitor_test_add("/visitor/input/any",
739 &in_visitor_data, test_visitor_in_any);
2fc00432 740 input_visitor_test_add("/visitor/input/union-flat",
805017b7 741 &in_visitor_data, test_visitor_in_union_flat);
ab045267
EB
742 input_visitor_test_add("/visitor/input/alternate",
743 &in_visitor_data, test_visitor_in_alternate);
3dcf71f6 744 input_visitor_test_add("/visitor/input/errors",
805017b7 745 &in_visitor_data, test_visitor_in_errors);
9c51b441
EB
746 input_visitor_test_add("/visitor/input/alternate-number",
747 &in_visitor_data, test_visitor_in_alternate_number);
199e0f17 748 input_visitor_test_add("/visitor/input/native_list/int",
805017b7
EB
749 &in_visitor_data,
750 test_visitor_in_native_list_int);
199e0f17 751 input_visitor_test_add("/visitor/input/native_list/int8",
805017b7
EB
752 &in_visitor_data,
753 test_visitor_in_native_list_int8);
199e0f17 754 input_visitor_test_add("/visitor/input/native_list/int16",
805017b7
EB
755 &in_visitor_data,
756 test_visitor_in_native_list_int16);
199e0f17 757 input_visitor_test_add("/visitor/input/native_list/int32",
805017b7
EB
758 &in_visitor_data,
759 test_visitor_in_native_list_int32);
199e0f17 760 input_visitor_test_add("/visitor/input/native_list/int64",
805017b7
EB
761 &in_visitor_data,
762 test_visitor_in_native_list_int64);
199e0f17 763 input_visitor_test_add("/visitor/input/native_list/uint8",
805017b7
EB
764 &in_visitor_data,
765 test_visitor_in_native_list_uint8);
199e0f17 766 input_visitor_test_add("/visitor/input/native_list/uint16",
805017b7
EB
767 &in_visitor_data,
768 test_visitor_in_native_list_uint16);
199e0f17 769 input_visitor_test_add("/visitor/input/native_list/uint32",
805017b7
EB
770 &in_visitor_data,
771 test_visitor_in_native_list_uint32);
199e0f17 772 input_visitor_test_add("/visitor/input/native_list/uint64",
805017b7
EB
773 &in_visitor_data,
774 test_visitor_in_native_list_uint64);
199e0f17 775 input_visitor_test_add("/visitor/input/native_list/bool",
805017b7 776 &in_visitor_data, test_visitor_in_native_list_bool);
199e0f17 777 input_visitor_test_add("/visitor/input/native_list/str",
805017b7
EB
778 &in_visitor_data,
779 test_visitor_in_native_list_string);
199e0f17 780 input_visitor_test_add("/visitor/input/native_list/number",
805017b7
EB
781 &in_visitor_data,
782 test_visitor_in_native_list_number);
d88f5fd1
LC
783
784 g_test_run();
785
786 return 0;
787}