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