Merge remote-tracking branch 'remotes/mdroth/tags/qga-pull-2016-07-25-tag' into staging
[qemu/kevin.git] / tests / test-qmp-input-visitor.c
blobf583dce3ed2f0e89fed19444672a17de35d8236d
1 /*
2 * QMP Input Visitor unit-tests.
4 * Copyright (C) 2011-2016 Red Hat Inc.
6 * Authors:
7 * Luiz Capitulino <lcapitulino@redhat.com>
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.
13 #include "qemu/osdep.h"
15 #include "qemu-common.h"
16 #include "qapi/error.h"
17 #include "qapi/qmp-input-visitor.h"
18 #include "test-qapi-types.h"
19 #include "test-qapi-visit.h"
20 #include "qapi/qmp/types.h"
21 #include "qapi/qmp/qjson.h"
23 typedef struct TestInputVisitorData {
24 QObject *obj;
25 Visitor *qiv;
26 } TestInputVisitorData;
28 static void visitor_input_teardown(TestInputVisitorData *data,
29 const void *unused)
31 qobject_decref(data->obj);
32 data->obj = NULL;
34 if (data->qiv) {
35 visit_free(data->qiv);
36 data->qiv = NULL;
40 /* The various test_init functions are provided instead of a test setup
41 function so that the JSON string used by the tests are kept in the test
42 functions (and not in main()). */
43 static Visitor *visitor_input_test_init_internal(TestInputVisitorData *data,
44 const char *json_string,
45 va_list *ap)
47 visitor_input_teardown(data, NULL);
49 data->obj = qobject_from_jsonv(json_string, ap);
50 g_assert(data->obj);
52 data->qiv = qmp_input_visitor_new(data->obj, false);
53 g_assert(data->qiv);
54 return data->qiv;
57 static GCC_FMT_ATTR(2, 3)
58 Visitor *visitor_input_test_init(TestInputVisitorData *data,
59 const char *json_string, ...)
61 Visitor *v;
62 va_list ap;
64 va_start(ap, json_string);
65 v = visitor_input_test_init_internal(data, json_string, &ap);
66 va_end(ap);
67 return v;
70 /* similar to visitor_input_test_init(), but does not expect a string
71 * literal/format json_string argument and so can be used for
72 * programatically generated strings (and we can't pass in programatically
73 * generated strings via %s format parameters since qobject_from_jsonv()
74 * will wrap those in double-quotes and treat the entire object as a
75 * string)
77 static Visitor *visitor_input_test_init_raw(TestInputVisitorData *data,
78 const char *json_string)
80 return visitor_input_test_init_internal(data, json_string, NULL);
83 static void test_visitor_in_int(TestInputVisitorData *data,
84 const void *unused)
86 int64_t res = 0, value = -42;
87 Visitor *v;
89 v = visitor_input_test_init(data, "%" PRId64, value);
91 visit_type_int(v, NULL, &res, &error_abort);
92 g_assert_cmpint(res, ==, value);
95 static void test_visitor_in_int_overflow(TestInputVisitorData *data,
96 const void *unused)
98 int64_t res = 0;
99 Error *err = NULL;
100 Visitor *v;
102 /* this will overflow a Qint/int64, so should be deserialized into
103 * a QFloat/double field instead, leading to an error if we pass it
104 * to visit_type_int. confirm this.
106 v = visitor_input_test_init(data, "%f", DBL_MAX);
108 visit_type_int(v, NULL, &res, &err);
109 error_free_or_abort(&err);
112 static void test_visitor_in_bool(TestInputVisitorData *data,
113 const void *unused)
115 bool res = false;
116 Visitor *v;
118 v = visitor_input_test_init(data, "true");
120 visit_type_bool(v, NULL, &res, &error_abort);
121 g_assert_cmpint(res, ==, true);
124 static void test_visitor_in_number(TestInputVisitorData *data,
125 const void *unused)
127 double res = 0, value = 3.14;
128 Visitor *v;
130 v = visitor_input_test_init(data, "%f", value);
132 visit_type_number(v, NULL, &res, &error_abort);
133 g_assert_cmpfloat(res, ==, value);
136 static void test_visitor_in_string(TestInputVisitorData *data,
137 const void *unused)
139 char *res = NULL, *value = (char *) "Q E M U";
140 Visitor *v;
142 v = visitor_input_test_init(data, "%s", value);
144 visit_type_str(v, NULL, &res, &error_abort);
145 g_assert_cmpstr(res, ==, value);
147 g_free(res);
150 static void test_visitor_in_enum(TestInputVisitorData *data,
151 const void *unused)
153 Visitor *v;
154 EnumOne i;
156 for (i = 0; EnumOne_lookup[i]; i++) {
157 EnumOne res = -1;
159 v = visitor_input_test_init(data, "%s", EnumOne_lookup[i]);
161 visit_type_EnumOne(v, NULL, &res, &error_abort);
162 g_assert_cmpint(i, ==, res);
167 static void test_visitor_in_struct(TestInputVisitorData *data,
168 const void *unused)
170 TestStruct *p = NULL;
171 Visitor *v;
173 v = visitor_input_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo' }");
175 visit_type_TestStruct(v, NULL, &p, &error_abort);
176 g_assert_cmpint(p->integer, ==, -42);
177 g_assert(p->boolean == true);
178 g_assert_cmpstr(p->string, ==, "foo");
180 g_free(p->string);
181 g_free(p);
184 static void test_visitor_in_struct_nested(TestInputVisitorData *data,
185 const void *unused)
187 UserDefTwo *udp = NULL;
188 Visitor *v;
190 v = visitor_input_test_init(data, "{ 'string0': 'string0', "
191 "'dict1': { 'string1': 'string1', "
192 "'dict2': { 'userdef': { 'integer': 42, "
193 "'string': 'string' }, 'string': 'string2'}}}");
195 visit_type_UserDefTwo(v, NULL, &udp, &error_abort);
197 g_assert_cmpstr(udp->string0, ==, "string0");
198 g_assert_cmpstr(udp->dict1->string1, ==, "string1");
199 g_assert_cmpint(udp->dict1->dict2->userdef->integer, ==, 42);
200 g_assert_cmpstr(udp->dict1->dict2->userdef->string, ==, "string");
201 g_assert_cmpstr(udp->dict1->dict2->string, ==, "string2");
202 g_assert(udp->dict1->has_dict3 == false);
204 qapi_free_UserDefTwo(udp);
207 static void test_visitor_in_list(TestInputVisitorData *data,
208 const void *unused)
210 UserDefOneList *item, *head = NULL;
211 Visitor *v;
212 int i;
214 v = visitor_input_test_init(data, "[ { 'string': 'string0', 'integer': 42 }, { 'string': 'string1', 'integer': 43 }, { 'string': 'string2', 'integer': 44 } ]");
216 visit_type_UserDefOneList(v, NULL, &head, &error_abort);
217 g_assert(head != NULL);
219 for (i = 0, item = head; item; item = item->next, i++) {
220 char string[12];
222 snprintf(string, sizeof(string), "string%d", i);
223 g_assert_cmpstr(item->value->string, ==, string);
224 g_assert_cmpint(item->value->integer, ==, 42 + i);
227 qapi_free_UserDefOneList(head);
228 head = NULL;
230 /* An empty list is valid */
231 v = visitor_input_test_init(data, "[]");
232 visit_type_UserDefOneList(v, NULL, &head, &error_abort);
233 g_assert(!head);
236 static void test_visitor_in_any(TestInputVisitorData *data,
237 const void *unused)
239 QObject *res = NULL;
240 Visitor *v;
241 QInt *qint;
242 QBool *qbool;
243 QString *qstring;
244 QDict *qdict;
245 QObject *qobj;
247 v = visitor_input_test_init(data, "-42");
248 visit_type_any(v, NULL, &res, &error_abort);
249 qint = qobject_to_qint(res);
250 g_assert(qint);
251 g_assert_cmpint(qint_get_int(qint), ==, -42);
252 qobject_decref(res);
254 v = visitor_input_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo' }");
255 visit_type_any(v, NULL, &res, &error_abort);
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);
276 static void test_visitor_in_null(TestInputVisitorData *data,
277 const void *unused)
279 Visitor *v;
280 Error *err = NULL;
281 char *tmp;
284 * FIXME: Since QAPI doesn't know the 'null' type yet, we can't
285 * test visit_type_null() by reading into a QAPI struct then
286 * checking that it was populated correctly. The best we can do
287 * for now is ensure that we consumed null from the input, proven
288 * by the fact that we can't re-read the key; and that we detect
289 * when input is not null.
292 v = visitor_input_test_init(data, "{ 'a': null, 'b': '' }");
293 visit_start_struct(v, NULL, NULL, 0, &error_abort);
294 visit_type_null(v, "a", &error_abort);
295 visit_type_str(v, "a", &tmp, &err);
296 g_assert(!tmp);
297 error_free_or_abort(&err);
298 visit_type_null(v, "b", &err);
299 error_free_or_abort(&err);
300 visit_check_struct(v, &error_abort);
301 visit_end_struct(v, NULL);
304 static void test_visitor_in_union_flat(TestInputVisitorData *data,
305 const void *unused)
307 Visitor *v;
308 UserDefFlatUnion *tmp;
309 UserDefUnionBase *base;
311 v = visitor_input_test_init(data,
312 "{ 'enum1': 'value1', "
313 "'integer': 41, "
314 "'string': 'str', "
315 "'boolean': true }");
317 visit_type_UserDefFlatUnion(v, NULL, &tmp, &error_abort);
318 g_assert_cmpint(tmp->enum1, ==, ENUM_ONE_VALUE1);
319 g_assert_cmpstr(tmp->string, ==, "str");
320 g_assert_cmpint(tmp->integer, ==, 41);
321 g_assert_cmpint(tmp->u.value1.boolean, ==, true);
323 base = qapi_UserDefFlatUnion_base(tmp);
324 g_assert(&base->enum1 == &tmp->enum1);
326 qapi_free_UserDefFlatUnion(tmp);
329 static void test_visitor_in_alternate(TestInputVisitorData *data,
330 const void *unused)
332 Visitor *v;
333 Error *err = NULL;
334 UserDefAlternate *tmp;
335 WrapAlternate *wrap;
337 v = visitor_input_test_init(data, "42");
338 visit_type_UserDefAlternate(v, NULL, &tmp, &error_abort);
339 g_assert_cmpint(tmp->type, ==, QTYPE_QINT);
340 g_assert_cmpint(tmp->u.i, ==, 42);
341 qapi_free_UserDefAlternate(tmp);
343 v = visitor_input_test_init(data, "'string'");
344 visit_type_UserDefAlternate(v, NULL, &tmp, &error_abort);
345 g_assert_cmpint(tmp->type, ==, QTYPE_QSTRING);
346 g_assert_cmpstr(tmp->u.s, ==, "string");
347 qapi_free_UserDefAlternate(tmp);
349 v = visitor_input_test_init(data, "{'integer':1, 'string':'str', "
350 "'enum1':'value1', 'boolean':true}");
351 visit_type_UserDefAlternate(v, NULL, &tmp, &error_abort);
352 g_assert_cmpint(tmp->type, ==, QTYPE_QDICT);
353 g_assert_cmpint(tmp->u.udfu.integer, ==, 1);
354 g_assert_cmpstr(tmp->u.udfu.string, ==, "str");
355 g_assert_cmpint(tmp->u.udfu.enum1, ==, ENUM_ONE_VALUE1);
356 g_assert_cmpint(tmp->u.udfu.u.value1.boolean, ==, true);
357 g_assert_cmpint(tmp->u.udfu.u.value1.has_a_b, ==, false);
358 qapi_free_UserDefAlternate(tmp);
360 v = visitor_input_test_init(data, "false");
361 visit_type_UserDefAlternate(v, NULL, &tmp, &err);
362 error_free_or_abort(&err);
363 qapi_free_UserDefAlternate(tmp);
365 v = visitor_input_test_init(data, "{ 'alt': 42 }");
366 visit_type_WrapAlternate(v, NULL, &wrap, &error_abort);
367 g_assert_cmpint(wrap->alt->type, ==, QTYPE_QINT);
368 g_assert_cmpint(wrap->alt->u.i, ==, 42);
369 qapi_free_WrapAlternate(wrap);
371 v = visitor_input_test_init(data, "{ 'alt': 'string' }");
372 visit_type_WrapAlternate(v, NULL, &wrap, &error_abort);
373 g_assert_cmpint(wrap->alt->type, ==, QTYPE_QSTRING);
374 g_assert_cmpstr(wrap->alt->u.s, ==, "string");
375 qapi_free_WrapAlternate(wrap);
377 v = visitor_input_test_init(data, "{ 'alt': {'integer':1, 'string':'str', "
378 "'enum1':'value1', 'boolean':true} }");
379 visit_type_WrapAlternate(v, NULL, &wrap, &error_abort);
380 g_assert_cmpint(wrap->alt->type, ==, QTYPE_QDICT);
381 g_assert_cmpint(wrap->alt->u.udfu.integer, ==, 1);
382 g_assert_cmpstr(wrap->alt->u.udfu.string, ==, "str");
383 g_assert_cmpint(wrap->alt->u.udfu.enum1, ==, ENUM_ONE_VALUE1);
384 g_assert_cmpint(wrap->alt->u.udfu.u.value1.boolean, ==, true);
385 g_assert_cmpint(wrap->alt->u.udfu.u.value1.has_a_b, ==, false);
386 qapi_free_WrapAlternate(wrap);
389 static void test_visitor_in_alternate_number(TestInputVisitorData *data,
390 const void *unused)
392 Visitor *v;
393 Error *err = NULL;
394 AltStrBool *asb;
395 AltStrNum *asn;
396 AltNumStr *ans;
397 AltStrInt *asi;
398 AltIntNum *ain;
399 AltNumInt *ani;
401 /* Parsing an int */
403 v = visitor_input_test_init(data, "42");
404 visit_type_AltStrBool(v, NULL, &asb, &err);
405 error_free_or_abort(&err);
406 qapi_free_AltStrBool(asb);
408 v = visitor_input_test_init(data, "42");
409 visit_type_AltStrNum(v, NULL, &asn, &error_abort);
410 g_assert_cmpint(asn->type, ==, QTYPE_QFLOAT);
411 g_assert_cmpfloat(asn->u.n, ==, 42);
412 qapi_free_AltStrNum(asn);
414 v = visitor_input_test_init(data, "42");
415 visit_type_AltNumStr(v, NULL, &ans, &error_abort);
416 g_assert_cmpint(ans->type, ==, QTYPE_QFLOAT);
417 g_assert_cmpfloat(ans->u.n, ==, 42);
418 qapi_free_AltNumStr(ans);
420 v = visitor_input_test_init(data, "42");
421 visit_type_AltStrInt(v, NULL, &asi, &error_abort);
422 g_assert_cmpint(asi->type, ==, QTYPE_QINT);
423 g_assert_cmpint(asi->u.i, ==, 42);
424 qapi_free_AltStrInt(asi);
426 v = visitor_input_test_init(data, "42");
427 visit_type_AltIntNum(v, NULL, &ain, &error_abort);
428 g_assert_cmpint(ain->type, ==, QTYPE_QINT);
429 g_assert_cmpint(ain->u.i, ==, 42);
430 qapi_free_AltIntNum(ain);
432 v = visitor_input_test_init(data, "42");
433 visit_type_AltNumInt(v, NULL, &ani, &error_abort);
434 g_assert_cmpint(ani->type, ==, QTYPE_QINT);
435 g_assert_cmpint(ani->u.i, ==, 42);
436 qapi_free_AltNumInt(ani);
438 /* Parsing a double */
440 v = visitor_input_test_init(data, "42.5");
441 visit_type_AltStrBool(v, NULL, &asb, &err);
442 error_free_or_abort(&err);
443 qapi_free_AltStrBool(asb);
445 v = visitor_input_test_init(data, "42.5");
446 visit_type_AltStrNum(v, NULL, &asn, &error_abort);
447 g_assert_cmpint(asn->type, ==, QTYPE_QFLOAT);
448 g_assert_cmpfloat(asn->u.n, ==, 42.5);
449 qapi_free_AltStrNum(asn);
451 v = visitor_input_test_init(data, "42.5");
452 visit_type_AltNumStr(v, NULL, &ans, &error_abort);
453 g_assert_cmpint(ans->type, ==, QTYPE_QFLOAT);
454 g_assert_cmpfloat(ans->u.n, ==, 42.5);
455 qapi_free_AltNumStr(ans);
457 v = visitor_input_test_init(data, "42.5");
458 visit_type_AltStrInt(v, NULL, &asi, &err);
459 error_free_or_abort(&err);
460 qapi_free_AltStrInt(asi);
462 v = visitor_input_test_init(data, "42.5");
463 visit_type_AltIntNum(v, NULL, &ain, &error_abort);
464 g_assert_cmpint(ain->type, ==, QTYPE_QFLOAT);
465 g_assert_cmpfloat(ain->u.n, ==, 42.5);
466 qapi_free_AltIntNum(ain);
468 v = visitor_input_test_init(data, "42.5");
469 visit_type_AltNumInt(v, NULL, &ani, &error_abort);
470 g_assert_cmpint(ani->type, ==, QTYPE_QFLOAT);
471 g_assert_cmpfloat(ani->u.n, ==, 42.5);
472 qapi_free_AltNumInt(ani);
475 static void test_native_list_integer_helper(TestInputVisitorData *data,
476 const void *unused,
477 UserDefNativeListUnionKind kind)
479 UserDefNativeListUnion *cvalue = NULL;
480 Visitor *v;
481 GString *gstr_list = g_string_new("");
482 GString *gstr_union = g_string_new("");
483 int i;
485 for (i = 0; i < 32; i++) {
486 g_string_append_printf(gstr_list, "%d", i);
487 if (i != 31) {
488 g_string_append(gstr_list, ", ");
491 g_string_append_printf(gstr_union, "{ 'type': '%s', 'data': [ %s ] }",
492 UserDefNativeListUnionKind_lookup[kind],
493 gstr_list->str);
494 v = visitor_input_test_init_raw(data, gstr_union->str);
496 visit_type_UserDefNativeListUnion(v, NULL, &cvalue, &error_abort);
497 g_assert(cvalue != NULL);
498 g_assert_cmpint(cvalue->type, ==, kind);
500 switch (kind) {
501 case USER_DEF_NATIVE_LIST_UNION_KIND_INTEGER: {
502 intList *elem = NULL;
503 for (i = 0, elem = cvalue->u.integer.data;
504 elem; elem = elem->next, i++) {
505 g_assert_cmpint(elem->value, ==, i);
507 break;
509 case USER_DEF_NATIVE_LIST_UNION_KIND_S8: {
510 int8List *elem = NULL;
511 for (i = 0, elem = cvalue->u.s8.data; elem; elem = elem->next, i++) {
512 g_assert_cmpint(elem->value, ==, i);
514 break;
516 case USER_DEF_NATIVE_LIST_UNION_KIND_S16: {
517 int16List *elem = NULL;
518 for (i = 0, elem = cvalue->u.s16.data; elem; elem = elem->next, i++) {
519 g_assert_cmpint(elem->value, ==, i);
521 break;
523 case USER_DEF_NATIVE_LIST_UNION_KIND_S32: {
524 int32List *elem = NULL;
525 for (i = 0, elem = cvalue->u.s32.data; elem; elem = elem->next, i++) {
526 g_assert_cmpint(elem->value, ==, i);
528 break;
530 case USER_DEF_NATIVE_LIST_UNION_KIND_S64: {
531 int64List *elem = NULL;
532 for (i = 0, elem = cvalue->u.s64.data; elem; elem = elem->next, i++) {
533 g_assert_cmpint(elem->value, ==, i);
535 break;
537 case USER_DEF_NATIVE_LIST_UNION_KIND_U8: {
538 uint8List *elem = NULL;
539 for (i = 0, elem = cvalue->u.u8.data; elem; elem = elem->next, i++) {
540 g_assert_cmpint(elem->value, ==, i);
542 break;
544 case USER_DEF_NATIVE_LIST_UNION_KIND_U16: {
545 uint16List *elem = NULL;
546 for (i = 0, elem = cvalue->u.u16.data; elem; elem = elem->next, i++) {
547 g_assert_cmpint(elem->value, ==, i);
549 break;
551 case USER_DEF_NATIVE_LIST_UNION_KIND_U32: {
552 uint32List *elem = NULL;
553 for (i = 0, elem = cvalue->u.u32.data; elem; elem = elem->next, i++) {
554 g_assert_cmpint(elem->value, ==, i);
556 break;
558 case USER_DEF_NATIVE_LIST_UNION_KIND_U64: {
559 uint64List *elem = NULL;
560 for (i = 0, elem = cvalue->u.u64.data; elem; elem = elem->next, i++) {
561 g_assert_cmpint(elem->value, ==, i);
563 break;
565 default:
566 g_assert_not_reached();
569 g_string_free(gstr_union, true);
570 g_string_free(gstr_list, true);
571 qapi_free_UserDefNativeListUnion(cvalue);
574 static void test_visitor_in_native_list_int(TestInputVisitorData *data,
575 const void *unused)
577 test_native_list_integer_helper(data, unused,
578 USER_DEF_NATIVE_LIST_UNION_KIND_INTEGER);
581 static void test_visitor_in_native_list_int8(TestInputVisitorData *data,
582 const void *unused)
584 test_native_list_integer_helper(data, unused,
585 USER_DEF_NATIVE_LIST_UNION_KIND_S8);
588 static void test_visitor_in_native_list_int16(TestInputVisitorData *data,
589 const void *unused)
591 test_native_list_integer_helper(data, unused,
592 USER_DEF_NATIVE_LIST_UNION_KIND_S16);
595 static void test_visitor_in_native_list_int32(TestInputVisitorData *data,
596 const void *unused)
598 test_native_list_integer_helper(data, unused,
599 USER_DEF_NATIVE_LIST_UNION_KIND_S32);
602 static void test_visitor_in_native_list_int64(TestInputVisitorData *data,
603 const void *unused)
605 test_native_list_integer_helper(data, unused,
606 USER_DEF_NATIVE_LIST_UNION_KIND_S64);
609 static void test_visitor_in_native_list_uint8(TestInputVisitorData *data,
610 const void *unused)
612 test_native_list_integer_helper(data, unused,
613 USER_DEF_NATIVE_LIST_UNION_KIND_U8);
616 static void test_visitor_in_native_list_uint16(TestInputVisitorData *data,
617 const void *unused)
619 test_native_list_integer_helper(data, unused,
620 USER_DEF_NATIVE_LIST_UNION_KIND_U16);
623 static void test_visitor_in_native_list_uint32(TestInputVisitorData *data,
624 const void *unused)
626 test_native_list_integer_helper(data, unused,
627 USER_DEF_NATIVE_LIST_UNION_KIND_U32);
630 static void test_visitor_in_native_list_uint64(TestInputVisitorData *data,
631 const void *unused)
633 test_native_list_integer_helper(data, unused,
634 USER_DEF_NATIVE_LIST_UNION_KIND_U64);
637 static void test_visitor_in_native_list_bool(TestInputVisitorData *data,
638 const void *unused)
640 UserDefNativeListUnion *cvalue = NULL;
641 boolList *elem = NULL;
642 Visitor *v;
643 GString *gstr_list = g_string_new("");
644 GString *gstr_union = g_string_new("");
645 int i;
647 for (i = 0; i < 32; i++) {
648 g_string_append_printf(gstr_list, "%s",
649 (i % 3 == 0) ? "true" : "false");
650 if (i != 31) {
651 g_string_append(gstr_list, ", ");
654 g_string_append_printf(gstr_union, "{ 'type': 'boolean', 'data': [ %s ] }",
655 gstr_list->str);
656 v = visitor_input_test_init_raw(data, gstr_union->str);
658 visit_type_UserDefNativeListUnion(v, NULL, &cvalue, &error_abort);
659 g_assert(cvalue != NULL);
660 g_assert_cmpint(cvalue->type, ==, USER_DEF_NATIVE_LIST_UNION_KIND_BOOLEAN);
662 for (i = 0, elem = cvalue->u.boolean.data; elem; elem = elem->next, i++) {
663 g_assert_cmpint(elem->value, ==, (i % 3 == 0) ? 1 : 0);
666 g_string_free(gstr_union, true);
667 g_string_free(gstr_list, true);
668 qapi_free_UserDefNativeListUnion(cvalue);
671 static void test_visitor_in_native_list_string(TestInputVisitorData *data,
672 const void *unused)
674 UserDefNativeListUnion *cvalue = NULL;
675 strList *elem = NULL;
676 Visitor *v;
677 GString *gstr_list = g_string_new("");
678 GString *gstr_union = g_string_new("");
679 int i;
681 for (i = 0; i < 32; i++) {
682 g_string_append_printf(gstr_list, "'%d'", i);
683 if (i != 31) {
684 g_string_append(gstr_list, ", ");
687 g_string_append_printf(gstr_union, "{ 'type': 'string', 'data': [ %s ] }",
688 gstr_list->str);
689 v = visitor_input_test_init_raw(data, gstr_union->str);
691 visit_type_UserDefNativeListUnion(v, NULL, &cvalue, &error_abort);
692 g_assert(cvalue != NULL);
693 g_assert_cmpint(cvalue->type, ==, USER_DEF_NATIVE_LIST_UNION_KIND_STRING);
695 for (i = 0, elem = cvalue->u.string.data; elem; elem = elem->next, i++) {
696 gchar str[8];
697 sprintf(str, "%d", i);
698 g_assert_cmpstr(elem->value, ==, str);
701 g_string_free(gstr_union, true);
702 g_string_free(gstr_list, true);
703 qapi_free_UserDefNativeListUnion(cvalue);
706 #define DOUBLE_STR_MAX 16
708 static void test_visitor_in_native_list_number(TestInputVisitorData *data,
709 const void *unused)
711 UserDefNativeListUnion *cvalue = NULL;
712 numberList *elem = NULL;
713 Visitor *v;
714 GString *gstr_list = g_string_new("");
715 GString *gstr_union = g_string_new("");
716 int i;
718 for (i = 0; i < 32; i++) {
719 g_string_append_printf(gstr_list, "%f", (double)i / 3);
720 if (i != 31) {
721 g_string_append(gstr_list, ", ");
724 g_string_append_printf(gstr_union, "{ 'type': 'number', 'data': [ %s ] }",
725 gstr_list->str);
726 v = visitor_input_test_init_raw(data, gstr_union->str);
728 visit_type_UserDefNativeListUnion(v, NULL, &cvalue, &error_abort);
729 g_assert(cvalue != NULL);
730 g_assert_cmpint(cvalue->type, ==, USER_DEF_NATIVE_LIST_UNION_KIND_NUMBER);
732 for (i = 0, elem = cvalue->u.number.data; elem; elem = elem->next, i++) {
733 GString *double_expected = g_string_new("");
734 GString *double_actual = g_string_new("");
736 g_string_printf(double_expected, "%.6f", (double)i / 3);
737 g_string_printf(double_actual, "%.6f", elem->value);
738 g_assert_cmpstr(double_expected->str, ==, double_actual->str);
740 g_string_free(double_expected, true);
741 g_string_free(double_actual, true);
744 g_string_free(gstr_union, true);
745 g_string_free(gstr_list, true);
746 qapi_free_UserDefNativeListUnion(cvalue);
749 static void input_visitor_test_add(const char *testpath,
750 TestInputVisitorData *data,
751 void (*test_func)(TestInputVisitorData *data, const void *user_data))
753 g_test_add(testpath, TestInputVisitorData, data, NULL, test_func,
754 visitor_input_teardown);
757 static void test_visitor_in_errors(TestInputVisitorData *data,
758 const void *unused)
760 TestStruct *p = NULL;
761 Error *err = NULL;
762 Visitor *v;
763 strList *q = NULL;
764 UserDefTwo *r = NULL;
765 WrapAlternate *s = NULL;
767 v = visitor_input_test_init(data, "{ 'integer': false, 'boolean': 'foo', "
768 "'string': -42 }");
770 visit_type_TestStruct(v, NULL, &p, &err);
771 error_free_or_abort(&err);
772 g_assert(!p);
774 v = visitor_input_test_init(data, "[ '1', '2', false, '3' ]");
775 visit_type_strList(v, NULL, &q, &err);
776 error_free_or_abort(&err);
777 assert(!q);
779 v = visitor_input_test_init(data, "{ 'str':'hi' }");
780 visit_type_UserDefTwo(v, NULL, &r, &err);
781 error_free_or_abort(&err);
782 assert(!r);
784 v = visitor_input_test_init(data, "{ }");
785 visit_type_WrapAlternate(v, NULL, &s, &err);
786 error_free_or_abort(&err);
787 assert(!s);
790 static void test_visitor_in_wrong_type(TestInputVisitorData *data,
791 const void *unused)
793 TestStruct *p = NULL;
794 Visitor *v;
795 strList *q = NULL;
796 int64_t i;
797 Error *err = NULL;
799 /* Make sure arrays and structs cannot be confused */
801 v = visitor_input_test_init(data, "[]");
802 visit_type_TestStruct(v, NULL, &p, &err);
803 error_free_or_abort(&err);
804 g_assert(!p);
806 v = visitor_input_test_init(data, "{}");
807 visit_type_strList(v, NULL, &q, &err);
808 error_free_or_abort(&err);
809 assert(!q);
811 /* Make sure primitives and struct cannot be confused */
813 v = visitor_input_test_init(data, "1");
814 visit_type_TestStruct(v, NULL, &p, &err);
815 error_free_or_abort(&err);
816 g_assert(!p);
818 v = visitor_input_test_init(data, "{}");
819 visit_type_int(v, NULL, &i, &err);
820 error_free_or_abort(&err);
822 /* Make sure primitives and arrays cannot be confused */
824 v = visitor_input_test_init(data, "1");
825 visit_type_strList(v, NULL, &q, &err);
826 error_free_or_abort(&err);
827 assert(!q);
829 v = visitor_input_test_init(data, "[]");
830 visit_type_int(v, NULL, &i, &err);
831 error_free_or_abort(&err);
834 int main(int argc, char **argv)
836 TestInputVisitorData in_visitor_data;
838 g_test_init(&argc, &argv, NULL);
840 input_visitor_test_add("/visitor/input/int",
841 &in_visitor_data, test_visitor_in_int);
842 input_visitor_test_add("/visitor/input/int_overflow",
843 &in_visitor_data, test_visitor_in_int_overflow);
844 input_visitor_test_add("/visitor/input/bool",
845 &in_visitor_data, test_visitor_in_bool);
846 input_visitor_test_add("/visitor/input/number",
847 &in_visitor_data, test_visitor_in_number);
848 input_visitor_test_add("/visitor/input/string",
849 &in_visitor_data, test_visitor_in_string);
850 input_visitor_test_add("/visitor/input/enum",
851 &in_visitor_data, test_visitor_in_enum);
852 input_visitor_test_add("/visitor/input/struct",
853 &in_visitor_data, test_visitor_in_struct);
854 input_visitor_test_add("/visitor/input/struct-nested",
855 &in_visitor_data, test_visitor_in_struct_nested);
856 input_visitor_test_add("/visitor/input/list",
857 &in_visitor_data, test_visitor_in_list);
858 input_visitor_test_add("/visitor/input/any",
859 &in_visitor_data, test_visitor_in_any);
860 input_visitor_test_add("/visitor/input/null",
861 &in_visitor_data, test_visitor_in_null);
862 input_visitor_test_add("/visitor/input/union-flat",
863 &in_visitor_data, test_visitor_in_union_flat);
864 input_visitor_test_add("/visitor/input/alternate",
865 &in_visitor_data, test_visitor_in_alternate);
866 input_visitor_test_add("/visitor/input/errors",
867 &in_visitor_data, test_visitor_in_errors);
868 input_visitor_test_add("/visitor/input/wrong-type",
869 &in_visitor_data, test_visitor_in_wrong_type);
870 input_visitor_test_add("/visitor/input/alternate-number",
871 &in_visitor_data, test_visitor_in_alternate_number);
872 input_visitor_test_add("/visitor/input/native_list/int",
873 &in_visitor_data,
874 test_visitor_in_native_list_int);
875 input_visitor_test_add("/visitor/input/native_list/int8",
876 &in_visitor_data,
877 test_visitor_in_native_list_int8);
878 input_visitor_test_add("/visitor/input/native_list/int16",
879 &in_visitor_data,
880 test_visitor_in_native_list_int16);
881 input_visitor_test_add("/visitor/input/native_list/int32",
882 &in_visitor_data,
883 test_visitor_in_native_list_int32);
884 input_visitor_test_add("/visitor/input/native_list/int64",
885 &in_visitor_data,
886 test_visitor_in_native_list_int64);
887 input_visitor_test_add("/visitor/input/native_list/uint8",
888 &in_visitor_data,
889 test_visitor_in_native_list_uint8);
890 input_visitor_test_add("/visitor/input/native_list/uint16",
891 &in_visitor_data,
892 test_visitor_in_native_list_uint16);
893 input_visitor_test_add("/visitor/input/native_list/uint32",
894 &in_visitor_data,
895 test_visitor_in_native_list_uint32);
896 input_visitor_test_add("/visitor/input/native_list/uint64",
897 &in_visitor_data,
898 test_visitor_in_native_list_uint64);
899 input_visitor_test_add("/visitor/input/native_list/bool",
900 &in_visitor_data, test_visitor_in_native_list_bool);
901 input_visitor_test_add("/visitor/input/native_list/str",
902 &in_visitor_data,
903 test_visitor_in_native_list_string);
904 input_visitor_test_add("/visitor/input/native_list/number",
905 &in_visitor_data,
906 test_visitor_in_native_list_number);
908 g_test_run();
910 return 0;