Merge remote-tracking branch 'qemu/master'
[qemu/ar7.git] / tests / test-qobject-input-visitor.c
bloba62b5adaa685e91b71ffe5d3e9d8398778f5355c
1 /*
2 * QObject 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/qobject-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 = qobject_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 GCC_FMT_ATTR(2, 0)
78 Visitor *visitor_input_test_init_raw(TestInputVisitorData *data,
79 const char *json_string)
81 return visitor_input_test_init_internal(data, json_string, NULL);
84 static void test_visitor_in_int(TestInputVisitorData *data,
85 const void *unused)
87 int64_t res = 0;
88 int value = -42;
89 Visitor *v;
91 v = visitor_input_test_init(data, "%d", value);
93 visit_type_int(v, NULL, &res, &error_abort);
94 g_assert_cmpint(res, ==, value);
97 static void test_visitor_in_int_overflow(TestInputVisitorData *data,
98 const void *unused)
100 int64_t res = 0;
101 Error *err = NULL;
102 Visitor *v;
104 /* this will overflow a Qint/int64, so should be deserialized into
105 * a QFloat/double field instead, leading to an error if we pass it
106 * to visit_type_int. confirm this.
108 v = visitor_input_test_init(data, "%f", DBL_MAX);
110 visit_type_int(v, NULL, &res, &err);
111 error_free_or_abort(&err);
114 static void test_visitor_in_bool(TestInputVisitorData *data,
115 const void *unused)
117 bool res = false;
118 Visitor *v;
120 v = visitor_input_test_init(data, "true");
122 visit_type_bool(v, NULL, &res, &error_abort);
123 g_assert_cmpint(res, ==, true);
126 static void test_visitor_in_number(TestInputVisitorData *data,
127 const void *unused)
129 double res = 0, value = 3.14;
130 Visitor *v;
132 v = visitor_input_test_init(data, "%f", value);
134 visit_type_number(v, NULL, &res, &error_abort);
135 g_assert_cmpfloat(res, ==, value);
138 static void test_visitor_in_string(TestInputVisitorData *data,
139 const void *unused)
141 char *res = NULL, *value = (char *) "Q E M U";
142 Visitor *v;
144 v = visitor_input_test_init(data, "%s", value);
146 visit_type_str(v, NULL, &res, &error_abort);
147 g_assert_cmpstr(res, ==, value);
149 g_free(res);
152 static void test_visitor_in_enum(TestInputVisitorData *data,
153 const void *unused)
155 Visitor *v;
156 EnumOne i;
158 for (i = 0; EnumOne_lookup[i]; i++) {
159 EnumOne res = -1;
161 v = visitor_input_test_init(data, "%s", EnumOne_lookup[i]);
163 visit_type_EnumOne(v, NULL, &res, &error_abort);
164 g_assert_cmpint(i, ==, res);
169 static void test_visitor_in_struct(TestInputVisitorData *data,
170 const void *unused)
172 TestStruct *p = NULL;
173 Visitor *v;
175 v = visitor_input_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo' }");
177 visit_type_TestStruct(v, NULL, &p, &error_abort);
178 g_assert_cmpint(p->integer, ==, -42);
179 g_assert(p->boolean == true);
180 g_assert_cmpstr(p->string, ==, "foo");
182 g_free(p->string);
183 g_free(p);
186 static void test_visitor_in_struct_nested(TestInputVisitorData *data,
187 const void *unused)
189 UserDefTwo *udp = NULL;
190 Visitor *v;
192 v = visitor_input_test_init(data, "{ 'string0': 'string0', "
193 "'dict1': { 'string1': 'string1', "
194 "'dict2': { 'userdef': { 'integer': 42, "
195 "'string': 'string' }, 'string': 'string2'}}}");
197 visit_type_UserDefTwo(v, NULL, &udp, &error_abort);
199 g_assert_cmpstr(udp->string0, ==, "string0");
200 g_assert_cmpstr(udp->dict1->string1, ==, "string1");
201 g_assert_cmpint(udp->dict1->dict2->userdef->integer, ==, 42);
202 g_assert_cmpstr(udp->dict1->dict2->userdef->string, ==, "string");
203 g_assert_cmpstr(udp->dict1->dict2->string, ==, "string2");
204 g_assert(udp->dict1->has_dict3 == false);
206 qapi_free_UserDefTwo(udp);
209 static void test_visitor_in_list(TestInputVisitorData *data,
210 const void *unused)
212 UserDefOneList *item, *head = NULL;
213 Visitor *v;
214 int i;
216 v = visitor_input_test_init(data, "[ { 'string': 'string0', 'integer': 42 }, { 'string': 'string1', 'integer': 43 }, { 'string': 'string2', 'integer': 44 } ]");
218 visit_type_UserDefOneList(v, NULL, &head, &error_abort);
219 g_assert(head != NULL);
221 for (i = 0, item = head; item; item = item->next, i++) {
222 char string[12];
224 snprintf(string, sizeof(string), "string%d", i);
225 g_assert_cmpstr(item->value->string, ==, string);
226 g_assert_cmpint(item->value->integer, ==, 42 + i);
229 qapi_free_UserDefOneList(head);
230 head = NULL;
232 /* An empty list is valid */
233 v = visitor_input_test_init(data, "[]");
234 visit_type_UserDefOneList(v, NULL, &head, &error_abort);
235 g_assert(!head);
238 static void test_visitor_in_any(TestInputVisitorData *data,
239 const void *unused)
241 QObject *res = NULL;
242 Visitor *v;
243 QInt *qint;
244 QBool *qbool;
245 QString *qstring;
246 QDict *qdict;
247 QObject *qobj;
249 v = visitor_input_test_init(data, "-42");
250 visit_type_any(v, NULL, &res, &error_abort);
251 qint = qobject_to_qint(res);
252 g_assert(qint);
253 g_assert_cmpint(qint_get_int(qint), ==, -42);
254 qobject_decref(res);
256 v = visitor_input_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo' }");
257 visit_type_any(v, NULL, &res, &error_abort);
258 qdict = qobject_to_qdict(res);
259 g_assert(qdict && qdict_size(qdict) == 3);
260 qobj = qdict_get(qdict, "integer");
261 g_assert(qobj);
262 qint = qobject_to_qint(qobj);
263 g_assert(qint);
264 g_assert_cmpint(qint_get_int(qint), ==, -42);
265 qobj = qdict_get(qdict, "boolean");
266 g_assert(qobj);
267 qbool = qobject_to_qbool(qobj);
268 g_assert(qbool);
269 g_assert(qbool_get_bool(qbool) == true);
270 qobj = qdict_get(qdict, "string");
271 g_assert(qobj);
272 qstring = qobject_to_qstring(qobj);
273 g_assert(qstring);
274 g_assert_cmpstr(qstring_get_str(qstring), ==, "foo");
275 qobject_decref(res);
278 static void test_visitor_in_null(TestInputVisitorData *data,
279 const void *unused)
281 Visitor *v;
282 Error *err = NULL;
283 char *tmp;
286 * FIXME: Since QAPI doesn't know the 'null' type yet, we can't
287 * test visit_type_null() by reading into a QAPI struct then
288 * checking that it was populated correctly. The best we can do
289 * for now is ensure that we consumed null from the input, proven
290 * by the fact that we can't re-read the key; and that we detect
291 * when input is not null.
294 v = visitor_input_test_init(data, "{ 'a': null, 'b': '' }");
295 visit_start_struct(v, NULL, NULL, 0, &error_abort);
296 visit_type_null(v, "a", &error_abort);
297 visit_type_str(v, "a", &tmp, &err);
298 g_assert(!tmp);
299 error_free_or_abort(&err);
300 visit_type_null(v, "b", &err);
301 error_free_or_abort(&err);
302 visit_check_struct(v, &error_abort);
303 visit_end_struct(v, NULL);
306 static void test_visitor_in_union_flat(TestInputVisitorData *data,
307 const void *unused)
309 Visitor *v;
310 UserDefFlatUnion *tmp;
311 UserDefUnionBase *base;
313 v = visitor_input_test_init(data,
314 "{ 'enum1': 'value1', "
315 "'integer': 41, "
316 "'string': 'str', "
317 "'boolean': true }");
319 visit_type_UserDefFlatUnion(v, NULL, &tmp, &error_abort);
320 g_assert_cmpint(tmp->enum1, ==, ENUM_ONE_VALUE1);
321 g_assert_cmpstr(tmp->string, ==, "str");
322 g_assert_cmpint(tmp->integer, ==, 41);
323 g_assert_cmpint(tmp->u.value1.boolean, ==, true);
325 base = qapi_UserDefFlatUnion_base(tmp);
326 g_assert(&base->enum1 == &tmp->enum1);
328 qapi_free_UserDefFlatUnion(tmp);
331 static void test_visitor_in_alternate(TestInputVisitorData *data,
332 const void *unused)
334 Visitor *v;
335 Error *err = NULL;
336 UserDefAlternate *tmp;
337 WrapAlternate *wrap;
339 v = visitor_input_test_init(data, "42");
340 visit_type_UserDefAlternate(v, NULL, &tmp, &error_abort);
341 g_assert_cmpint(tmp->type, ==, QTYPE_QINT);
342 g_assert_cmpint(tmp->u.i, ==, 42);
343 qapi_free_UserDefAlternate(tmp);
345 v = visitor_input_test_init(data, "'string'");
346 visit_type_UserDefAlternate(v, NULL, &tmp, &error_abort);
347 g_assert_cmpint(tmp->type, ==, QTYPE_QSTRING);
348 g_assert_cmpstr(tmp->u.s, ==, "string");
349 qapi_free_UserDefAlternate(tmp);
351 v = visitor_input_test_init(data, "{'integer':1, 'string':'str', "
352 "'enum1':'value1', 'boolean':true}");
353 visit_type_UserDefAlternate(v, NULL, &tmp, &error_abort);
354 g_assert_cmpint(tmp->type, ==, QTYPE_QDICT);
355 g_assert_cmpint(tmp->u.udfu.integer, ==, 1);
356 g_assert_cmpstr(tmp->u.udfu.string, ==, "str");
357 g_assert_cmpint(tmp->u.udfu.enum1, ==, ENUM_ONE_VALUE1);
358 g_assert_cmpint(tmp->u.udfu.u.value1.boolean, ==, true);
359 g_assert_cmpint(tmp->u.udfu.u.value1.has_a_b, ==, false);
360 qapi_free_UserDefAlternate(tmp);
362 v = visitor_input_test_init(data, "false");
363 visit_type_UserDefAlternate(v, NULL, &tmp, &err);
364 error_free_or_abort(&err);
365 qapi_free_UserDefAlternate(tmp);
367 v = visitor_input_test_init(data, "{ 'alt': 42 }");
368 visit_type_WrapAlternate(v, NULL, &wrap, &error_abort);
369 g_assert_cmpint(wrap->alt->type, ==, QTYPE_QINT);
370 g_assert_cmpint(wrap->alt->u.i, ==, 42);
371 qapi_free_WrapAlternate(wrap);
373 v = visitor_input_test_init(data, "{ 'alt': 'string' }");
374 visit_type_WrapAlternate(v, NULL, &wrap, &error_abort);
375 g_assert_cmpint(wrap->alt->type, ==, QTYPE_QSTRING);
376 g_assert_cmpstr(wrap->alt->u.s, ==, "string");
377 qapi_free_WrapAlternate(wrap);
379 v = visitor_input_test_init(data, "{ 'alt': {'integer':1, 'string':'str', "
380 "'enum1':'value1', 'boolean':true} }");
381 visit_type_WrapAlternate(v, NULL, &wrap, &error_abort);
382 g_assert_cmpint(wrap->alt->type, ==, QTYPE_QDICT);
383 g_assert_cmpint(wrap->alt->u.udfu.integer, ==, 1);
384 g_assert_cmpstr(wrap->alt->u.udfu.string, ==, "str");
385 g_assert_cmpint(wrap->alt->u.udfu.enum1, ==, ENUM_ONE_VALUE1);
386 g_assert_cmpint(wrap->alt->u.udfu.u.value1.boolean, ==, true);
387 g_assert_cmpint(wrap->alt->u.udfu.u.value1.has_a_b, ==, false);
388 qapi_free_WrapAlternate(wrap);
391 static void test_visitor_in_alternate_number(TestInputVisitorData *data,
392 const void *unused)
394 Visitor *v;
395 Error *err = NULL;
396 AltStrBool *asb;
397 AltStrNum *asn;
398 AltNumStr *ans;
399 AltStrInt *asi;
400 AltIntNum *ain;
401 AltNumInt *ani;
403 /* Parsing an int */
405 v = visitor_input_test_init(data, "42");
406 visit_type_AltStrBool(v, NULL, &asb, &err);
407 error_free_or_abort(&err);
408 qapi_free_AltStrBool(asb);
410 v = visitor_input_test_init(data, "42");
411 visit_type_AltStrNum(v, NULL, &asn, &error_abort);
412 g_assert_cmpint(asn->type, ==, QTYPE_QFLOAT);
413 g_assert_cmpfloat(asn->u.n, ==, 42);
414 qapi_free_AltStrNum(asn);
416 v = visitor_input_test_init(data, "42");
417 visit_type_AltNumStr(v, NULL, &ans, &error_abort);
418 g_assert_cmpint(ans->type, ==, QTYPE_QFLOAT);
419 g_assert_cmpfloat(ans->u.n, ==, 42);
420 qapi_free_AltNumStr(ans);
422 v = visitor_input_test_init(data, "42");
423 visit_type_AltStrInt(v, NULL, &asi, &error_abort);
424 g_assert_cmpint(asi->type, ==, QTYPE_QINT);
425 g_assert_cmpint(asi->u.i, ==, 42);
426 qapi_free_AltStrInt(asi);
428 v = visitor_input_test_init(data, "42");
429 visit_type_AltIntNum(v, NULL, &ain, &error_abort);
430 g_assert_cmpint(ain->type, ==, QTYPE_QINT);
431 g_assert_cmpint(ain->u.i, ==, 42);
432 qapi_free_AltIntNum(ain);
434 v = visitor_input_test_init(data, "42");
435 visit_type_AltNumInt(v, NULL, &ani, &error_abort);
436 g_assert_cmpint(ani->type, ==, QTYPE_QINT);
437 g_assert_cmpint(ani->u.i, ==, 42);
438 qapi_free_AltNumInt(ani);
440 /* Parsing a double */
442 v = visitor_input_test_init(data, "42.5");
443 visit_type_AltStrBool(v, NULL, &asb, &err);
444 error_free_or_abort(&err);
445 qapi_free_AltStrBool(asb);
447 v = visitor_input_test_init(data, "42.5");
448 visit_type_AltStrNum(v, NULL, &asn, &error_abort);
449 g_assert_cmpint(asn->type, ==, QTYPE_QFLOAT);
450 g_assert_cmpfloat(asn->u.n, ==, 42.5);
451 qapi_free_AltStrNum(asn);
453 v = visitor_input_test_init(data, "42.5");
454 visit_type_AltNumStr(v, NULL, &ans, &error_abort);
455 g_assert_cmpint(ans->type, ==, QTYPE_QFLOAT);
456 g_assert_cmpfloat(ans->u.n, ==, 42.5);
457 qapi_free_AltNumStr(ans);
459 v = visitor_input_test_init(data, "42.5");
460 visit_type_AltStrInt(v, NULL, &asi, &err);
461 error_free_or_abort(&err);
462 qapi_free_AltStrInt(asi);
464 v = visitor_input_test_init(data, "42.5");
465 visit_type_AltIntNum(v, NULL, &ain, &error_abort);
466 g_assert_cmpint(ain->type, ==, QTYPE_QFLOAT);
467 g_assert_cmpfloat(ain->u.n, ==, 42.5);
468 qapi_free_AltIntNum(ain);
470 v = visitor_input_test_init(data, "42.5");
471 visit_type_AltNumInt(v, NULL, &ani, &error_abort);
472 g_assert_cmpint(ani->type, ==, QTYPE_QFLOAT);
473 g_assert_cmpfloat(ani->u.n, ==, 42.5);
474 qapi_free_AltNumInt(ani);
477 static void test_native_list_integer_helper(TestInputVisitorData *data,
478 const void *unused,
479 UserDefNativeListUnionKind kind)
481 UserDefNativeListUnion *cvalue = NULL;
482 Visitor *v;
483 GString *gstr_list = g_string_new("");
484 GString *gstr_union = g_string_new("");
485 int i;
487 for (i = 0; i < 32; i++) {
488 g_string_append_printf(gstr_list, "%d", i);
489 if (i != 31) {
490 g_string_append(gstr_list, ", ");
493 g_string_append_printf(gstr_union, "{ 'type': '%s', 'data': [ %s ] }",
494 UserDefNativeListUnionKind_lookup[kind],
495 gstr_list->str);
496 v = visitor_input_test_init_raw(data, gstr_union->str);
498 visit_type_UserDefNativeListUnion(v, NULL, &cvalue, &error_abort);
499 g_assert(cvalue != NULL);
500 g_assert_cmpint(cvalue->type, ==, kind);
502 switch (kind) {
503 case USER_DEF_NATIVE_LIST_UNION_KIND_INTEGER: {
504 intList *elem = NULL;
505 for (i = 0, elem = cvalue->u.integer.data;
506 elem; elem = elem->next, i++) {
507 g_assert_cmpint(elem->value, ==, i);
509 break;
511 case USER_DEF_NATIVE_LIST_UNION_KIND_S8: {
512 int8List *elem = NULL;
513 for (i = 0, elem = cvalue->u.s8.data; elem; elem = elem->next, i++) {
514 g_assert_cmpint(elem->value, ==, i);
516 break;
518 case USER_DEF_NATIVE_LIST_UNION_KIND_S16: {
519 int16List *elem = NULL;
520 for (i = 0, elem = cvalue->u.s16.data; elem; elem = elem->next, i++) {
521 g_assert_cmpint(elem->value, ==, i);
523 break;
525 case USER_DEF_NATIVE_LIST_UNION_KIND_S32: {
526 int32List *elem = NULL;
527 for (i = 0, elem = cvalue->u.s32.data; elem; elem = elem->next, i++) {
528 g_assert_cmpint(elem->value, ==, i);
530 break;
532 case USER_DEF_NATIVE_LIST_UNION_KIND_S64: {
533 int64List *elem = NULL;
534 for (i = 0, elem = cvalue->u.s64.data; elem; elem = elem->next, i++) {
535 g_assert_cmpint(elem->value, ==, i);
537 break;
539 case USER_DEF_NATIVE_LIST_UNION_KIND_U8: {
540 uint8List *elem = NULL;
541 for (i = 0, elem = cvalue->u.u8.data; elem; elem = elem->next, i++) {
542 g_assert_cmpint(elem->value, ==, i);
544 break;
546 case USER_DEF_NATIVE_LIST_UNION_KIND_U16: {
547 uint16List *elem = NULL;
548 for (i = 0, elem = cvalue->u.u16.data; elem; elem = elem->next, i++) {
549 g_assert_cmpint(elem->value, ==, i);
551 break;
553 case USER_DEF_NATIVE_LIST_UNION_KIND_U32: {
554 uint32List *elem = NULL;
555 for (i = 0, elem = cvalue->u.u32.data; elem; elem = elem->next, i++) {
556 g_assert_cmpint(elem->value, ==, i);
558 break;
560 case USER_DEF_NATIVE_LIST_UNION_KIND_U64: {
561 uint64List *elem = NULL;
562 for (i = 0, elem = cvalue->u.u64.data; elem; elem = elem->next, i++) {
563 g_assert_cmpint(elem->value, ==, i);
565 break;
567 default:
568 g_assert_not_reached();
571 g_string_free(gstr_union, true);
572 g_string_free(gstr_list, true);
573 qapi_free_UserDefNativeListUnion(cvalue);
576 static void test_visitor_in_native_list_int(TestInputVisitorData *data,
577 const void *unused)
579 test_native_list_integer_helper(data, unused,
580 USER_DEF_NATIVE_LIST_UNION_KIND_INTEGER);
583 static void test_visitor_in_native_list_int8(TestInputVisitorData *data,
584 const void *unused)
586 test_native_list_integer_helper(data, unused,
587 USER_DEF_NATIVE_LIST_UNION_KIND_S8);
590 static void test_visitor_in_native_list_int16(TestInputVisitorData *data,
591 const void *unused)
593 test_native_list_integer_helper(data, unused,
594 USER_DEF_NATIVE_LIST_UNION_KIND_S16);
597 static void test_visitor_in_native_list_int32(TestInputVisitorData *data,
598 const void *unused)
600 test_native_list_integer_helper(data, unused,
601 USER_DEF_NATIVE_LIST_UNION_KIND_S32);
604 static void test_visitor_in_native_list_int64(TestInputVisitorData *data,
605 const void *unused)
607 test_native_list_integer_helper(data, unused,
608 USER_DEF_NATIVE_LIST_UNION_KIND_S64);
611 static void test_visitor_in_native_list_uint8(TestInputVisitorData *data,
612 const void *unused)
614 test_native_list_integer_helper(data, unused,
615 USER_DEF_NATIVE_LIST_UNION_KIND_U8);
618 static void test_visitor_in_native_list_uint16(TestInputVisitorData *data,
619 const void *unused)
621 test_native_list_integer_helper(data, unused,
622 USER_DEF_NATIVE_LIST_UNION_KIND_U16);
625 static void test_visitor_in_native_list_uint32(TestInputVisitorData *data,
626 const void *unused)
628 test_native_list_integer_helper(data, unused,
629 USER_DEF_NATIVE_LIST_UNION_KIND_U32);
632 static void test_visitor_in_native_list_uint64(TestInputVisitorData *data,
633 const void *unused)
635 test_native_list_integer_helper(data, unused,
636 USER_DEF_NATIVE_LIST_UNION_KIND_U64);
639 static void test_visitor_in_native_list_bool(TestInputVisitorData *data,
640 const void *unused)
642 UserDefNativeListUnion *cvalue = NULL;
643 boolList *elem = NULL;
644 Visitor *v;
645 GString *gstr_list = g_string_new("");
646 GString *gstr_union = g_string_new("");
647 int i;
649 for (i = 0; i < 32; i++) {
650 g_string_append_printf(gstr_list, "%s",
651 (i % 3 == 0) ? "true" : "false");
652 if (i != 31) {
653 g_string_append(gstr_list, ", ");
656 g_string_append_printf(gstr_union, "{ 'type': 'boolean', 'data': [ %s ] }",
657 gstr_list->str);
658 v = visitor_input_test_init_raw(data, gstr_union->str);
660 visit_type_UserDefNativeListUnion(v, NULL, &cvalue, &error_abort);
661 g_assert(cvalue != NULL);
662 g_assert_cmpint(cvalue->type, ==, USER_DEF_NATIVE_LIST_UNION_KIND_BOOLEAN);
664 for (i = 0, elem = cvalue->u.boolean.data; elem; elem = elem->next, i++) {
665 g_assert_cmpint(elem->value, ==, (i % 3 == 0) ? 1 : 0);
668 g_string_free(gstr_union, true);
669 g_string_free(gstr_list, true);
670 qapi_free_UserDefNativeListUnion(cvalue);
673 static void test_visitor_in_native_list_string(TestInputVisitorData *data,
674 const void *unused)
676 UserDefNativeListUnion *cvalue = NULL;
677 strList *elem = NULL;
678 Visitor *v;
679 GString *gstr_list = g_string_new("");
680 GString *gstr_union = g_string_new("");
681 int i;
683 for (i = 0; i < 32; i++) {
684 g_string_append_printf(gstr_list, "'%d'", i);
685 if (i != 31) {
686 g_string_append(gstr_list, ", ");
689 g_string_append_printf(gstr_union, "{ 'type': 'string', 'data': [ %s ] }",
690 gstr_list->str);
691 v = visitor_input_test_init_raw(data, gstr_union->str);
693 visit_type_UserDefNativeListUnion(v, NULL, &cvalue, &error_abort);
694 g_assert(cvalue != NULL);
695 g_assert_cmpint(cvalue->type, ==, USER_DEF_NATIVE_LIST_UNION_KIND_STRING);
697 for (i = 0, elem = cvalue->u.string.data; elem; elem = elem->next, i++) {
698 gchar str[8];
699 sprintf(str, "%d", i);
700 g_assert_cmpstr(elem->value, ==, str);
703 g_string_free(gstr_union, true);
704 g_string_free(gstr_list, true);
705 qapi_free_UserDefNativeListUnion(cvalue);
708 #define DOUBLE_STR_MAX 16
710 static void test_visitor_in_native_list_number(TestInputVisitorData *data,
711 const void *unused)
713 UserDefNativeListUnion *cvalue = NULL;
714 numberList *elem = NULL;
715 Visitor *v;
716 GString *gstr_list = g_string_new("");
717 GString *gstr_union = g_string_new("");
718 int i;
720 for (i = 0; i < 32; i++) {
721 g_string_append_printf(gstr_list, "%f", (double)i / 3);
722 if (i != 31) {
723 g_string_append(gstr_list, ", ");
726 g_string_append_printf(gstr_union, "{ 'type': 'number', 'data': [ %s ] }",
727 gstr_list->str);
728 v = visitor_input_test_init_raw(data, gstr_union->str);
730 visit_type_UserDefNativeListUnion(v, NULL, &cvalue, &error_abort);
731 g_assert(cvalue != NULL);
732 g_assert_cmpint(cvalue->type, ==, USER_DEF_NATIVE_LIST_UNION_KIND_NUMBER);
734 for (i = 0, elem = cvalue->u.number.data; elem; elem = elem->next, i++) {
735 GString *double_expected = g_string_new("");
736 GString *double_actual = g_string_new("");
738 g_string_printf(double_expected, "%.6f", (double)i / 3);
739 g_string_printf(double_actual, "%.6f", elem->value);
740 g_assert_cmpstr(double_expected->str, ==, double_actual->str);
742 g_string_free(double_expected, true);
743 g_string_free(double_actual, true);
746 g_string_free(gstr_union, true);
747 g_string_free(gstr_list, true);
748 qapi_free_UserDefNativeListUnion(cvalue);
751 static void input_visitor_test_add(const char *testpath,
752 const void *user_data,
753 void (*test_func)(TestInputVisitorData *data,
754 const void *user_data))
756 g_test_add(testpath, TestInputVisitorData, user_data, NULL, test_func,
757 visitor_input_teardown);
760 static void test_visitor_in_errors(TestInputVisitorData *data,
761 const void *unused)
763 TestStruct *p = NULL;
764 Error *err = NULL;
765 Visitor *v;
766 strList *q = NULL;
767 UserDefTwo *r = NULL;
768 WrapAlternate *s = NULL;
770 v = visitor_input_test_init(data, "{ 'integer': false, 'boolean': 'foo', "
771 "'string': -42 }");
773 visit_type_TestStruct(v, NULL, &p, &err);
774 error_free_or_abort(&err);
775 g_assert(!p);
777 v = visitor_input_test_init(data, "[ '1', '2', false, '3' ]");
778 visit_type_strList(v, NULL, &q, &err);
779 error_free_or_abort(&err);
780 assert(!q);
782 v = visitor_input_test_init(data, "{ 'str':'hi' }");
783 visit_type_UserDefTwo(v, NULL, &r, &err);
784 error_free_or_abort(&err);
785 assert(!r);
787 v = visitor_input_test_init(data, "{ }");
788 visit_type_WrapAlternate(v, NULL, &s, &err);
789 error_free_or_abort(&err);
790 assert(!s);
793 static void test_visitor_in_wrong_type(TestInputVisitorData *data,
794 const void *unused)
796 TestStruct *p = NULL;
797 Visitor *v;
798 strList *q = NULL;
799 int64_t i;
800 Error *err = NULL;
802 /* Make sure arrays and structs cannot be confused */
804 v = visitor_input_test_init(data, "[]");
805 visit_type_TestStruct(v, NULL, &p, &err);
806 error_free_or_abort(&err);
807 g_assert(!p);
809 v = visitor_input_test_init(data, "{}");
810 visit_type_strList(v, NULL, &q, &err);
811 error_free_or_abort(&err);
812 assert(!q);
814 /* Make sure primitives and struct cannot be confused */
816 v = visitor_input_test_init(data, "1");
817 visit_type_TestStruct(v, NULL, &p, &err);
818 error_free_or_abort(&err);
819 g_assert(!p);
821 v = visitor_input_test_init(data, "{}");
822 visit_type_int(v, NULL, &i, &err);
823 error_free_or_abort(&err);
825 /* Make sure primitives and arrays cannot be confused */
827 v = visitor_input_test_init(data, "1");
828 visit_type_strList(v, NULL, &q, &err);
829 error_free_or_abort(&err);
830 assert(!q);
832 v = visitor_input_test_init(data, "[]");
833 visit_type_int(v, NULL, &i, &err);
834 error_free_or_abort(&err);
837 int main(int argc, char **argv)
839 g_test_init(&argc, &argv, NULL);
841 input_visitor_test_add("/visitor/input/int",
842 NULL, test_visitor_in_int);
843 input_visitor_test_add("/visitor/input/int_overflow",
844 NULL, test_visitor_in_int_overflow);
845 input_visitor_test_add("/visitor/input/bool",
846 NULL, test_visitor_in_bool);
847 input_visitor_test_add("/visitor/input/number",
848 NULL, test_visitor_in_number);
849 input_visitor_test_add("/visitor/input/string",
850 NULL, test_visitor_in_string);
851 input_visitor_test_add("/visitor/input/enum",
852 NULL, test_visitor_in_enum);
853 input_visitor_test_add("/visitor/input/struct",
854 NULL, test_visitor_in_struct);
855 input_visitor_test_add("/visitor/input/struct-nested",
856 NULL, test_visitor_in_struct_nested);
857 input_visitor_test_add("/visitor/input/list",
858 NULL, test_visitor_in_list);
859 input_visitor_test_add("/visitor/input/any",
860 NULL, test_visitor_in_any);
861 input_visitor_test_add("/visitor/input/null",
862 NULL, test_visitor_in_null);
863 input_visitor_test_add("/visitor/input/union-flat",
864 NULL, test_visitor_in_union_flat);
865 input_visitor_test_add("/visitor/input/alternate",
866 NULL, test_visitor_in_alternate);
867 input_visitor_test_add("/visitor/input/errors",
868 NULL, test_visitor_in_errors);
869 input_visitor_test_add("/visitor/input/wrong-type",
870 NULL, test_visitor_in_wrong_type);
871 input_visitor_test_add("/visitor/input/alternate-number",
872 NULL, test_visitor_in_alternate_number);
873 input_visitor_test_add("/visitor/input/native_list/int",
874 NULL, test_visitor_in_native_list_int);
875 input_visitor_test_add("/visitor/input/native_list/int8",
876 NULL, test_visitor_in_native_list_int8);
877 input_visitor_test_add("/visitor/input/native_list/int16",
878 NULL, test_visitor_in_native_list_int16);
879 input_visitor_test_add("/visitor/input/native_list/int32",
880 NULL, test_visitor_in_native_list_int32);
881 input_visitor_test_add("/visitor/input/native_list/int64",
882 NULL, test_visitor_in_native_list_int64);
883 input_visitor_test_add("/visitor/input/native_list/uint8",
884 NULL, test_visitor_in_native_list_uint8);
885 input_visitor_test_add("/visitor/input/native_list/uint16",
886 NULL, test_visitor_in_native_list_uint16);
887 input_visitor_test_add("/visitor/input/native_list/uint32",
888 NULL, test_visitor_in_native_list_uint32);
889 input_visitor_test_add("/visitor/input/native_list/uint64",
890 NULL, test_visitor_in_native_list_uint64);
891 input_visitor_test_add("/visitor/input/native_list/bool",
892 NULL, test_visitor_in_native_list_bool);
893 input_visitor_test_add("/visitor/input/native_list/str",
894 NULL, test_visitor_in_native_list_string);
895 input_visitor_test_add("/visitor/input/native_list/number",
896 NULL, test_visitor_in_native_list_number);
898 g_test_run();
900 return 0;