1d88f5fd1SLuiz Capitulino /* 2*b3db211fSDaniel P. Berrange * QObject Input Visitor unit-tests. 3d88f5fd1SLuiz Capitulino * 468d07839SEric Blake * Copyright (C) 2011-2016 Red Hat Inc. 5d88f5fd1SLuiz Capitulino * 6d88f5fd1SLuiz Capitulino * Authors: 7d88f5fd1SLuiz Capitulino * Luiz Capitulino <lcapitulino@redhat.com> 8d88f5fd1SLuiz Capitulino * 9d88f5fd1SLuiz Capitulino * This work is licensed under the terms of the GNU GPL, version 2 or later. 10d88f5fd1SLuiz Capitulino * See the COPYING file in the top-level directory. 11d88f5fd1SLuiz Capitulino */ 12d88f5fd1SLuiz Capitulino 13681c28a3SPeter Maydell #include "qemu/osdep.h" 14d88f5fd1SLuiz Capitulino 1579ee7df8SPaolo Bonzini #include "qemu-common.h" 16da34e65cSMarkus Armbruster #include "qapi/error.h" 17*b3db211fSDaniel P. Berrange #include "qapi/qobject-input-visitor.h" 18d88f5fd1SLuiz Capitulino #include "test-qapi-types.h" 19d88f5fd1SLuiz Capitulino #include "test-qapi-visit.h" 207b1b5d19SPaolo Bonzini #include "qapi/qmp/types.h" 21c7eb39cbSEric Blake #include "qapi/qmp/qjson.h" 22d88f5fd1SLuiz Capitulino 23d88f5fd1SLuiz Capitulino typedef struct TestInputVisitorData { 24d88f5fd1SLuiz Capitulino QObject *obj; 25b70ce101SEric Blake Visitor *qiv; 26d88f5fd1SLuiz Capitulino } TestInputVisitorData; 27d88f5fd1SLuiz Capitulino 28d88f5fd1SLuiz Capitulino static void visitor_input_teardown(TestInputVisitorData *data, 29d88f5fd1SLuiz Capitulino const void *unused) 30d88f5fd1SLuiz Capitulino { 31d88f5fd1SLuiz Capitulino qobject_decref(data->obj); 32d88f5fd1SLuiz Capitulino data->obj = NULL; 33d88f5fd1SLuiz Capitulino 34d88f5fd1SLuiz Capitulino if (data->qiv) { 35b70ce101SEric Blake visit_free(data->qiv); 36d88f5fd1SLuiz Capitulino data->qiv = NULL; 37d88f5fd1SLuiz Capitulino } 38d88f5fd1SLuiz Capitulino } 39d88f5fd1SLuiz Capitulino 400920a171SEric Blake /* The various test_init functions are provided instead of a test setup 410920a171SEric Blake function so that the JSON string used by the tests are kept in the test 420920a171SEric Blake functions (and not in main()). */ 430920a171SEric Blake static Visitor *visitor_input_test_init_internal(TestInputVisitorData *data, 440920a171SEric Blake const char *json_string, 450920a171SEric Blake va_list *ap) 460920a171SEric Blake { 47b18f1141SEric Blake visitor_input_teardown(data, NULL); 48b18f1141SEric Blake 490920a171SEric Blake data->obj = qobject_from_jsonv(json_string, ap); 500920a171SEric Blake g_assert(data->obj); 510920a171SEric Blake 52fc471c18SEric Blake data->qiv = qmp_input_visitor_new(data->obj, false); 530920a171SEric Blake g_assert(data->qiv); 54b70ce101SEric Blake return data->qiv; 550920a171SEric Blake } 560920a171SEric Blake 57aba2107aSStefan Weil static GCC_FMT_ATTR(2, 3) 58aba2107aSStefan Weil Visitor *visitor_input_test_init(TestInputVisitorData *data, 59d88f5fd1SLuiz Capitulino const char *json_string, ...) 60d88f5fd1SLuiz Capitulino { 61d88f5fd1SLuiz Capitulino Visitor *v; 62d88f5fd1SLuiz Capitulino va_list ap; 63d88f5fd1SLuiz Capitulino 64d88f5fd1SLuiz Capitulino va_start(ap, json_string); 650920a171SEric Blake v = visitor_input_test_init_internal(data, json_string, &ap); 66d88f5fd1SLuiz Capitulino va_end(ap); 67d88f5fd1SLuiz Capitulino return v; 68d88f5fd1SLuiz Capitulino } 69d88f5fd1SLuiz Capitulino 70199e0f17SMichael Roth /* similar to visitor_input_test_init(), but does not expect a string 71199e0f17SMichael Roth * literal/format json_string argument and so can be used for 72199e0f17SMichael Roth * programatically generated strings (and we can't pass in programatically 73199e0f17SMichael Roth * generated strings via %s format parameters since qobject_from_jsonv() 74199e0f17SMichael Roth * will wrap those in double-quotes and treat the entire object as a 75199e0f17SMichael Roth * string) 76199e0f17SMichael Roth */ 77199e0f17SMichael Roth static Visitor *visitor_input_test_init_raw(TestInputVisitorData *data, 78199e0f17SMichael Roth const char *json_string) 79199e0f17SMichael Roth { 800920a171SEric Blake return visitor_input_test_init_internal(data, json_string, NULL); 81199e0f17SMichael Roth } 82199e0f17SMichael Roth 83d88f5fd1SLuiz Capitulino static void test_visitor_in_int(TestInputVisitorData *data, 84d88f5fd1SLuiz Capitulino const void *unused) 85d88f5fd1SLuiz Capitulino { 86d88f5fd1SLuiz Capitulino int64_t res = 0, value = -42; 87d88f5fd1SLuiz Capitulino Visitor *v; 88d88f5fd1SLuiz Capitulino 89aba2107aSStefan Weil v = visitor_input_test_init(data, "%" PRId64, value); 90d88f5fd1SLuiz Capitulino 9151e72bc1SEric Blake visit_type_int(v, NULL, &res, &error_abort); 92d88f5fd1SLuiz Capitulino g_assert_cmpint(res, ==, value); 93d88f5fd1SLuiz Capitulino } 94d88f5fd1SLuiz Capitulino 95e92cfa0dSMichael Roth static void test_visitor_in_int_overflow(TestInputVisitorData *data, 96e92cfa0dSMichael Roth const void *unused) 97e92cfa0dSMichael Roth { 98e92cfa0dSMichael Roth int64_t res = 0; 99e940f543SMarkus Armbruster Error *err = NULL; 100e92cfa0dSMichael Roth Visitor *v; 101e92cfa0dSMichael Roth 102e92cfa0dSMichael Roth /* this will overflow a Qint/int64, so should be deserialized into 103e92cfa0dSMichael Roth * a QFloat/double field instead, leading to an error if we pass it 104e92cfa0dSMichael Roth * to visit_type_int. confirm this. 105e92cfa0dSMichael Roth */ 106e92cfa0dSMichael Roth v = visitor_input_test_init(data, "%f", DBL_MAX); 107e92cfa0dSMichael Roth 10851e72bc1SEric Blake visit_type_int(v, NULL, &res, &err); 109a12a5a1aSEric Blake error_free_or_abort(&err); 110e92cfa0dSMichael Roth } 111e92cfa0dSMichael Roth 112d88f5fd1SLuiz Capitulino static void test_visitor_in_bool(TestInputVisitorData *data, 113d88f5fd1SLuiz Capitulino const void *unused) 114d88f5fd1SLuiz Capitulino { 115d88f5fd1SLuiz Capitulino bool res = false; 116d88f5fd1SLuiz Capitulino Visitor *v; 117d88f5fd1SLuiz Capitulino 118d88f5fd1SLuiz Capitulino v = visitor_input_test_init(data, "true"); 119d88f5fd1SLuiz Capitulino 12051e72bc1SEric Blake visit_type_bool(v, NULL, &res, &error_abort); 121d88f5fd1SLuiz Capitulino g_assert_cmpint(res, ==, true); 122d88f5fd1SLuiz Capitulino } 123d88f5fd1SLuiz Capitulino 124d88f5fd1SLuiz Capitulino static void test_visitor_in_number(TestInputVisitorData *data, 125d88f5fd1SLuiz Capitulino const void *unused) 126d88f5fd1SLuiz Capitulino { 127d88f5fd1SLuiz Capitulino double res = 0, value = 3.14; 128d88f5fd1SLuiz Capitulino Visitor *v; 129d88f5fd1SLuiz Capitulino 130d88f5fd1SLuiz Capitulino v = visitor_input_test_init(data, "%f", value); 131d88f5fd1SLuiz Capitulino 13251e72bc1SEric Blake visit_type_number(v, NULL, &res, &error_abort); 133d88f5fd1SLuiz Capitulino g_assert_cmpfloat(res, ==, value); 134d88f5fd1SLuiz Capitulino } 135d88f5fd1SLuiz Capitulino 136d88f5fd1SLuiz Capitulino static void test_visitor_in_string(TestInputVisitorData *data, 137d88f5fd1SLuiz Capitulino const void *unused) 138d88f5fd1SLuiz Capitulino { 139d88f5fd1SLuiz Capitulino char *res = NULL, *value = (char *) "Q E M U"; 140d88f5fd1SLuiz Capitulino Visitor *v; 141d88f5fd1SLuiz Capitulino 142d88f5fd1SLuiz Capitulino v = visitor_input_test_init(data, "%s", value); 143d88f5fd1SLuiz Capitulino 14451e72bc1SEric Blake visit_type_str(v, NULL, &res, &error_abort); 145d88f5fd1SLuiz Capitulino g_assert_cmpstr(res, ==, value); 146d88f5fd1SLuiz Capitulino 147d88f5fd1SLuiz Capitulino g_free(res); 148d88f5fd1SLuiz Capitulino } 149d88f5fd1SLuiz Capitulino 150d88f5fd1SLuiz Capitulino static void test_visitor_in_enum(TestInputVisitorData *data, 151d88f5fd1SLuiz Capitulino const void *unused) 152d88f5fd1SLuiz Capitulino { 153d88f5fd1SLuiz Capitulino Visitor *v; 154d88f5fd1SLuiz Capitulino EnumOne i; 155d88f5fd1SLuiz Capitulino 156d88f5fd1SLuiz Capitulino for (i = 0; EnumOne_lookup[i]; i++) { 157d88f5fd1SLuiz Capitulino EnumOne res = -1; 158d88f5fd1SLuiz Capitulino 159d88f5fd1SLuiz Capitulino v = visitor_input_test_init(data, "%s", EnumOne_lookup[i]); 160d88f5fd1SLuiz Capitulino 16151e72bc1SEric Blake visit_type_EnumOne(v, NULL, &res, &error_abort); 162d88f5fd1SLuiz Capitulino g_assert_cmpint(i, ==, res); 163d88f5fd1SLuiz Capitulino } 164d88f5fd1SLuiz Capitulino } 165d88f5fd1SLuiz Capitulino 166d88f5fd1SLuiz Capitulino 167d88f5fd1SLuiz Capitulino static void test_visitor_in_struct(TestInputVisitorData *data, 168d88f5fd1SLuiz Capitulino const void *unused) 169d88f5fd1SLuiz Capitulino { 170d88f5fd1SLuiz Capitulino TestStruct *p = NULL; 171d88f5fd1SLuiz Capitulino Visitor *v; 172d88f5fd1SLuiz Capitulino 173d88f5fd1SLuiz Capitulino v = visitor_input_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo' }"); 174d88f5fd1SLuiz Capitulino 17551e72bc1SEric Blake visit_type_TestStruct(v, NULL, &p, &error_abort); 176d88f5fd1SLuiz Capitulino g_assert_cmpint(p->integer, ==, -42); 177d88f5fd1SLuiz Capitulino g_assert(p->boolean == true); 178d88f5fd1SLuiz Capitulino g_assert_cmpstr(p->string, ==, "foo"); 179d88f5fd1SLuiz Capitulino 180d88f5fd1SLuiz Capitulino g_free(p->string); 181d88f5fd1SLuiz Capitulino g_free(p); 182d88f5fd1SLuiz Capitulino } 183d88f5fd1SLuiz Capitulino 184d88f5fd1SLuiz Capitulino static void test_visitor_in_struct_nested(TestInputVisitorData *data, 185d88f5fd1SLuiz Capitulino const void *unused) 186d88f5fd1SLuiz Capitulino { 187b6fcf32dSEric Blake UserDefTwo *udp = NULL; 188d88f5fd1SLuiz Capitulino Visitor *v; 189d88f5fd1SLuiz Capitulino 190b6fcf32dSEric Blake v = visitor_input_test_init(data, "{ 'string0': 'string0', " 191b6fcf32dSEric Blake "'dict1': { 'string1': 'string1', " 192b6fcf32dSEric Blake "'dict2': { 'userdef': { 'integer': 42, " 193b6fcf32dSEric Blake "'string': 'string' }, 'string': 'string2'}}}"); 194d88f5fd1SLuiz Capitulino 19551e72bc1SEric Blake visit_type_UserDefTwo(v, NULL, &udp, &error_abort); 196d88f5fd1SLuiz Capitulino 197b18f1141SEric Blake g_assert_cmpstr(udp->string0, ==, "string0"); 198b18f1141SEric Blake g_assert_cmpstr(udp->dict1->string1, ==, "string1"); 199ddf21908SEric Blake g_assert_cmpint(udp->dict1->dict2->userdef->integer, ==, 42); 200b18f1141SEric Blake g_assert_cmpstr(udp->dict1->dict2->userdef->string, ==, "string"); 201b18f1141SEric Blake g_assert_cmpstr(udp->dict1->dict2->string, ==, "string2"); 2026446a592SEric Blake g_assert(udp->dict1->has_dict3 == false); 203d88f5fd1SLuiz Capitulino 204b18f1141SEric Blake qapi_free_UserDefTwo(udp); 205d88f5fd1SLuiz Capitulino } 206d88f5fd1SLuiz Capitulino 207d88f5fd1SLuiz Capitulino static void test_visitor_in_list(TestInputVisitorData *data, 208d88f5fd1SLuiz Capitulino const void *unused) 209d88f5fd1SLuiz Capitulino { 210d88f5fd1SLuiz Capitulino UserDefOneList *item, *head = NULL; 211d88f5fd1SLuiz Capitulino Visitor *v; 212d88f5fd1SLuiz Capitulino int i; 213d88f5fd1SLuiz Capitulino 214d88f5fd1SLuiz Capitulino v = visitor_input_test_init(data, "[ { 'string': 'string0', 'integer': 42 }, { 'string': 'string1', 'integer': 43 }, { 'string': 'string2', 'integer': 44 } ]"); 215d88f5fd1SLuiz Capitulino 21651e72bc1SEric Blake visit_type_UserDefOneList(v, NULL, &head, &error_abort); 217d88f5fd1SLuiz Capitulino g_assert(head != NULL); 218d88f5fd1SLuiz Capitulino 219d88f5fd1SLuiz Capitulino for (i = 0, item = head; item; item = item->next, i++) { 220d88f5fd1SLuiz Capitulino char string[12]; 221d88f5fd1SLuiz Capitulino 222d88f5fd1SLuiz Capitulino snprintf(string, sizeof(string), "string%d", i); 223d88f5fd1SLuiz Capitulino g_assert_cmpstr(item->value->string, ==, string); 224ddf21908SEric Blake g_assert_cmpint(item->value->integer, ==, 42 + i); 225d88f5fd1SLuiz Capitulino } 226d88f5fd1SLuiz Capitulino 227d88f5fd1SLuiz Capitulino qapi_free_UserDefOneList(head); 2282533377cSEric Blake head = NULL; 2292533377cSEric Blake 2302533377cSEric Blake /* An empty list is valid */ 2312533377cSEric Blake v = visitor_input_test_init(data, "[]"); 23251e72bc1SEric Blake visit_type_UserDefOneList(v, NULL, &head, &error_abort); 2332533377cSEric Blake g_assert(!head); 234d88f5fd1SLuiz Capitulino } 235d88f5fd1SLuiz Capitulino 23628770e05SMarkus Armbruster static void test_visitor_in_any(TestInputVisitorData *data, 23728770e05SMarkus Armbruster const void *unused) 23828770e05SMarkus Armbruster { 23928770e05SMarkus Armbruster QObject *res = NULL; 24028770e05SMarkus Armbruster Visitor *v; 24128770e05SMarkus Armbruster QInt *qint; 24228770e05SMarkus Armbruster QBool *qbool; 24328770e05SMarkus Armbruster QString *qstring; 24428770e05SMarkus Armbruster QDict *qdict; 24528770e05SMarkus Armbruster QObject *qobj; 24628770e05SMarkus Armbruster 24728770e05SMarkus Armbruster v = visitor_input_test_init(data, "-42"); 24851e72bc1SEric Blake visit_type_any(v, NULL, &res, &error_abort); 24928770e05SMarkus Armbruster qint = qobject_to_qint(res); 25028770e05SMarkus Armbruster g_assert(qint); 25128770e05SMarkus Armbruster g_assert_cmpint(qint_get_int(qint), ==, -42); 25228770e05SMarkus Armbruster qobject_decref(res); 25328770e05SMarkus Armbruster 25428770e05SMarkus Armbruster v = visitor_input_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo' }"); 25551e72bc1SEric Blake visit_type_any(v, NULL, &res, &error_abort); 25628770e05SMarkus Armbruster qdict = qobject_to_qdict(res); 25728770e05SMarkus Armbruster g_assert(qdict && qdict_size(qdict) == 3); 25828770e05SMarkus Armbruster qobj = qdict_get(qdict, "integer"); 25928770e05SMarkus Armbruster g_assert(qobj); 26028770e05SMarkus Armbruster qint = qobject_to_qint(qobj); 26128770e05SMarkus Armbruster g_assert(qint); 26228770e05SMarkus Armbruster g_assert_cmpint(qint_get_int(qint), ==, -42); 26328770e05SMarkus Armbruster qobj = qdict_get(qdict, "boolean"); 26428770e05SMarkus Armbruster g_assert(qobj); 26528770e05SMarkus Armbruster qbool = qobject_to_qbool(qobj); 26628770e05SMarkus Armbruster g_assert(qbool); 26728770e05SMarkus Armbruster g_assert(qbool_get_bool(qbool) == true); 26828770e05SMarkus Armbruster qobj = qdict_get(qdict, "string"); 26928770e05SMarkus Armbruster g_assert(qobj); 27028770e05SMarkus Armbruster qstring = qobject_to_qstring(qobj); 27128770e05SMarkus Armbruster g_assert(qstring); 27228770e05SMarkus Armbruster g_assert_cmpstr(qstring_get_str(qstring), ==, "foo"); 27328770e05SMarkus Armbruster qobject_decref(res); 27428770e05SMarkus Armbruster } 27528770e05SMarkus Armbruster 2763df016f1SEric Blake static void test_visitor_in_null(TestInputVisitorData *data, 2773df016f1SEric Blake const void *unused) 2783df016f1SEric Blake { 2793df016f1SEric Blake Visitor *v; 2803df016f1SEric Blake Error *err = NULL; 2813df016f1SEric Blake char *tmp; 2823df016f1SEric Blake 2833df016f1SEric Blake /* 2843df016f1SEric Blake * FIXME: Since QAPI doesn't know the 'null' type yet, we can't 2853df016f1SEric Blake * test visit_type_null() by reading into a QAPI struct then 2863df016f1SEric Blake * checking that it was populated correctly. The best we can do 2873df016f1SEric Blake * for now is ensure that we consumed null from the input, proven 2883df016f1SEric Blake * by the fact that we can't re-read the key; and that we detect 2893df016f1SEric Blake * when input is not null. 2903df016f1SEric Blake */ 2913df016f1SEric Blake 2923df016f1SEric Blake v = visitor_input_test_init(data, "{ 'a': null, 'b': '' }"); 2933df016f1SEric Blake visit_start_struct(v, NULL, NULL, 0, &error_abort); 2943df016f1SEric Blake visit_type_null(v, "a", &error_abort); 2953df016f1SEric Blake visit_type_str(v, "a", &tmp, &err); 2963df016f1SEric Blake g_assert(!tmp); 2973df016f1SEric Blake error_free_or_abort(&err); 2983df016f1SEric Blake visit_type_null(v, "b", &err); 2993df016f1SEric Blake error_free_or_abort(&err); 30015c2f669SEric Blake visit_check_struct(v, &error_abort); 3011158bb2aSEric Blake visit_end_struct(v, NULL); 3023df016f1SEric Blake } 3033df016f1SEric Blake 3042fc00432SMarkus Armbruster static void test_visitor_in_union_flat(TestInputVisitorData *data, 3052fc00432SMarkus Armbruster const void *unused) 3062fc00432SMarkus Armbruster { 3072fc00432SMarkus Armbruster Visitor *v; 3082fc00432SMarkus Armbruster UserDefFlatUnion *tmp; 30930594fe1SEric Blake UserDefUnionBase *base; 3102fc00432SMarkus Armbruster 3115223070cSWenchao Xia v = visitor_input_test_init(data, 3125223070cSWenchao Xia "{ 'enum1': 'value1', " 313441cbac0SMarkus Armbruster "'integer': 41, " 3145223070cSWenchao Xia "'string': 'str', " 3155223070cSWenchao Xia "'boolean': true }"); 3162fc00432SMarkus Armbruster 31751e72bc1SEric Blake visit_type_UserDefFlatUnion(v, NULL, &tmp, &error_abort); 3180f61af3eSMarkus Armbruster g_assert_cmpint(tmp->enum1, ==, ENUM_ONE_VALUE1); 3195223070cSWenchao Xia g_assert_cmpstr(tmp->string, ==, "str"); 320441cbac0SMarkus Armbruster g_assert_cmpint(tmp->integer, ==, 41); 321544a3731SEric Blake g_assert_cmpint(tmp->u.value1.boolean, ==, true); 32230594fe1SEric Blake 32330594fe1SEric Blake base = qapi_UserDefFlatUnion_base(tmp); 32430594fe1SEric Blake g_assert(&base->enum1 == &tmp->enum1); 32530594fe1SEric Blake 3262fc00432SMarkus Armbruster qapi_free_UserDefFlatUnion(tmp); 3272fc00432SMarkus Armbruster } 3282fc00432SMarkus Armbruster 329ab045267SEric Blake static void test_visitor_in_alternate(TestInputVisitorData *data, 3302c38b600SMarkus Armbruster const void *unused) 3312c38b600SMarkus Armbruster { 3322c38b600SMarkus Armbruster Visitor *v; 3332c38b600SMarkus Armbruster Error *err = NULL; 334ab045267SEric Blake UserDefAlternate *tmp; 33568d07839SEric Blake WrapAlternate *wrap; 3362c38b600SMarkus Armbruster 3372c38b600SMarkus Armbruster v = visitor_input_test_init(data, "42"); 33851e72bc1SEric Blake visit_type_UserDefAlternate(v, NULL, &tmp, &error_abort); 3390426d53cSEric Blake g_assert_cmpint(tmp->type, ==, QTYPE_QINT); 340c363acefSEric Blake g_assert_cmpint(tmp->u.i, ==, 42); 341ab045267SEric Blake qapi_free_UserDefAlternate(tmp); 3429c51b441SEric Blake 3439c51b441SEric Blake v = visitor_input_test_init(data, "'string'"); 34451e72bc1SEric Blake visit_type_UserDefAlternate(v, NULL, &tmp, &error_abort); 3450426d53cSEric Blake g_assert_cmpint(tmp->type, ==, QTYPE_QSTRING); 346c363acefSEric Blake g_assert_cmpstr(tmp->u.s, ==, "string"); 3479c51b441SEric Blake qapi_free_UserDefAlternate(tmp); 3489c51b441SEric Blake 34968d07839SEric Blake v = visitor_input_test_init(data, "{'integer':1, 'string':'str', " 35068d07839SEric Blake "'enum1':'value1', 'boolean':true}"); 35168d07839SEric Blake visit_type_UserDefAlternate(v, NULL, &tmp, &error_abort); 35268d07839SEric Blake g_assert_cmpint(tmp->type, ==, QTYPE_QDICT); 353becceedcSEric Blake g_assert_cmpint(tmp->u.udfu.integer, ==, 1); 354becceedcSEric Blake g_assert_cmpstr(tmp->u.udfu.string, ==, "str"); 355becceedcSEric Blake g_assert_cmpint(tmp->u.udfu.enum1, ==, ENUM_ONE_VALUE1); 356544a3731SEric Blake g_assert_cmpint(tmp->u.udfu.u.value1.boolean, ==, true); 357544a3731SEric Blake g_assert_cmpint(tmp->u.udfu.u.value1.has_a_b, ==, false); 35868d07839SEric Blake qapi_free_UserDefAlternate(tmp); 35968d07839SEric Blake 3609c51b441SEric Blake v = visitor_input_test_init(data, "false"); 36151e72bc1SEric Blake visit_type_UserDefAlternate(v, NULL, &tmp, &err); 362a12a5a1aSEric Blake error_free_or_abort(&err); 3639c51b441SEric Blake qapi_free_UserDefAlternate(tmp); 36468d07839SEric Blake 36568d07839SEric Blake v = visitor_input_test_init(data, "{ 'alt': 42 }"); 36668d07839SEric Blake visit_type_WrapAlternate(v, NULL, &wrap, &error_abort); 36768d07839SEric Blake g_assert_cmpint(wrap->alt->type, ==, QTYPE_QINT); 36868d07839SEric Blake g_assert_cmpint(wrap->alt->u.i, ==, 42); 36968d07839SEric Blake qapi_free_WrapAlternate(wrap); 37068d07839SEric Blake 37168d07839SEric Blake v = visitor_input_test_init(data, "{ 'alt': 'string' }"); 37268d07839SEric Blake visit_type_WrapAlternate(v, NULL, &wrap, &error_abort); 37368d07839SEric Blake g_assert_cmpint(wrap->alt->type, ==, QTYPE_QSTRING); 37468d07839SEric Blake g_assert_cmpstr(wrap->alt->u.s, ==, "string"); 37568d07839SEric Blake qapi_free_WrapAlternate(wrap); 37668d07839SEric Blake 37768d07839SEric Blake v = visitor_input_test_init(data, "{ 'alt': {'integer':1, 'string':'str', " 37868d07839SEric Blake "'enum1':'value1', 'boolean':true} }"); 37968d07839SEric Blake visit_type_WrapAlternate(v, NULL, &wrap, &error_abort); 38068d07839SEric Blake g_assert_cmpint(wrap->alt->type, ==, QTYPE_QDICT); 381becceedcSEric Blake g_assert_cmpint(wrap->alt->u.udfu.integer, ==, 1); 382becceedcSEric Blake g_assert_cmpstr(wrap->alt->u.udfu.string, ==, "str"); 383becceedcSEric Blake g_assert_cmpint(wrap->alt->u.udfu.enum1, ==, ENUM_ONE_VALUE1); 384544a3731SEric Blake g_assert_cmpint(wrap->alt->u.udfu.u.value1.boolean, ==, true); 385544a3731SEric Blake g_assert_cmpint(wrap->alt->u.udfu.u.value1.has_a_b, ==, false); 38668d07839SEric Blake qapi_free_WrapAlternate(wrap); 3879c51b441SEric Blake } 3889c51b441SEric Blake 3899c51b441SEric Blake static void test_visitor_in_alternate_number(TestInputVisitorData *data, 3909c51b441SEric Blake const void *unused) 3919c51b441SEric Blake { 3929c51b441SEric Blake Visitor *v; 3939c51b441SEric Blake Error *err = NULL; 3949c51b441SEric Blake AltStrBool *asb; 3959c51b441SEric Blake AltStrNum *asn; 3969c51b441SEric Blake AltNumStr *ans; 3979c51b441SEric Blake AltStrInt *asi; 3989c51b441SEric Blake AltIntNum *ain; 3999c51b441SEric Blake AltNumInt *ani; 4009c51b441SEric Blake 4019c51b441SEric Blake /* Parsing an int */ 4029c51b441SEric Blake 4039c51b441SEric Blake v = visitor_input_test_init(data, "42"); 40451e72bc1SEric Blake visit_type_AltStrBool(v, NULL, &asb, &err); 405a12a5a1aSEric Blake error_free_or_abort(&err); 4069c51b441SEric Blake qapi_free_AltStrBool(asb); 4079c51b441SEric Blake 4089c51b441SEric Blake v = visitor_input_test_init(data, "42"); 40951e72bc1SEric Blake visit_type_AltStrNum(v, NULL, &asn, &error_abort); 410d00341afSEric Blake g_assert_cmpint(asn->type, ==, QTYPE_QFLOAT); 411d00341afSEric Blake g_assert_cmpfloat(asn->u.n, ==, 42); 4129c51b441SEric Blake qapi_free_AltStrNum(asn); 4139c51b441SEric Blake 4149c51b441SEric Blake v = visitor_input_test_init(data, "42"); 41551e72bc1SEric Blake visit_type_AltNumStr(v, NULL, &ans, &error_abort); 416d00341afSEric Blake g_assert_cmpint(ans->type, ==, QTYPE_QFLOAT); 417d00341afSEric Blake g_assert_cmpfloat(ans->u.n, ==, 42); 4189c51b441SEric Blake qapi_free_AltNumStr(ans); 4199c51b441SEric Blake 4209c51b441SEric Blake v = visitor_input_test_init(data, "42"); 42151e72bc1SEric Blake visit_type_AltStrInt(v, NULL, &asi, &error_abort); 4220426d53cSEric Blake g_assert_cmpint(asi->type, ==, QTYPE_QINT); 423c363acefSEric Blake g_assert_cmpint(asi->u.i, ==, 42); 4249c51b441SEric Blake qapi_free_AltStrInt(asi); 4259c51b441SEric Blake 4269c51b441SEric Blake v = visitor_input_test_init(data, "42"); 42751e72bc1SEric Blake visit_type_AltIntNum(v, NULL, &ain, &error_abort); 4280426d53cSEric Blake g_assert_cmpint(ain->type, ==, QTYPE_QINT); 429c363acefSEric Blake g_assert_cmpint(ain->u.i, ==, 42); 4309c51b441SEric Blake qapi_free_AltIntNum(ain); 4319c51b441SEric Blake 4329c51b441SEric Blake v = visitor_input_test_init(data, "42"); 43351e72bc1SEric Blake visit_type_AltNumInt(v, NULL, &ani, &error_abort); 4340426d53cSEric Blake g_assert_cmpint(ani->type, ==, QTYPE_QINT); 435c363acefSEric Blake g_assert_cmpint(ani->u.i, ==, 42); 4369c51b441SEric Blake qapi_free_AltNumInt(ani); 4379c51b441SEric Blake 4389c51b441SEric Blake /* Parsing a double */ 4399c51b441SEric Blake 4409c51b441SEric Blake v = visitor_input_test_init(data, "42.5"); 44151e72bc1SEric Blake visit_type_AltStrBool(v, NULL, &asb, &err); 442a12a5a1aSEric Blake error_free_or_abort(&err); 4439c51b441SEric Blake qapi_free_AltStrBool(asb); 4449c51b441SEric Blake 4459c51b441SEric Blake v = visitor_input_test_init(data, "42.5"); 44651e72bc1SEric Blake visit_type_AltStrNum(v, NULL, &asn, &error_abort); 4470426d53cSEric Blake g_assert_cmpint(asn->type, ==, QTYPE_QFLOAT); 448c363acefSEric Blake g_assert_cmpfloat(asn->u.n, ==, 42.5); 4499c51b441SEric Blake qapi_free_AltStrNum(asn); 4509c51b441SEric Blake 4519c51b441SEric Blake v = visitor_input_test_init(data, "42.5"); 45251e72bc1SEric Blake visit_type_AltNumStr(v, NULL, &ans, &error_abort); 4530426d53cSEric Blake g_assert_cmpint(ans->type, ==, QTYPE_QFLOAT); 454c363acefSEric Blake g_assert_cmpfloat(ans->u.n, ==, 42.5); 4559c51b441SEric Blake qapi_free_AltNumStr(ans); 4569c51b441SEric Blake 4579c51b441SEric Blake v = visitor_input_test_init(data, "42.5"); 45851e72bc1SEric Blake visit_type_AltStrInt(v, NULL, &asi, &err); 459a12a5a1aSEric Blake error_free_or_abort(&err); 4609c51b441SEric Blake qapi_free_AltStrInt(asi); 4619c51b441SEric Blake 4629c51b441SEric Blake v = visitor_input_test_init(data, "42.5"); 46351e72bc1SEric Blake visit_type_AltIntNum(v, NULL, &ain, &error_abort); 4640426d53cSEric Blake g_assert_cmpint(ain->type, ==, QTYPE_QFLOAT); 465c363acefSEric Blake g_assert_cmpfloat(ain->u.n, ==, 42.5); 4669c51b441SEric Blake qapi_free_AltIntNum(ain); 4679c51b441SEric Blake 4689c51b441SEric Blake v = visitor_input_test_init(data, "42.5"); 46951e72bc1SEric Blake visit_type_AltNumInt(v, NULL, &ani, &error_abort); 4700426d53cSEric Blake g_assert_cmpint(ani->type, ==, QTYPE_QFLOAT); 471c363acefSEric Blake g_assert_cmpfloat(ani->u.n, ==, 42.5); 4729c51b441SEric Blake qapi_free_AltNumInt(ani); 4732c38b600SMarkus Armbruster } 4742c38b600SMarkus Armbruster 475199e0f17SMichael Roth static void test_native_list_integer_helper(TestInputVisitorData *data, 476199e0f17SMichael Roth const void *unused, 477199e0f17SMichael Roth UserDefNativeListUnionKind kind) 478199e0f17SMichael Roth { 479199e0f17SMichael Roth UserDefNativeListUnion *cvalue = NULL; 480199e0f17SMichael Roth Visitor *v; 481199e0f17SMichael Roth GString *gstr_list = g_string_new(""); 482199e0f17SMichael Roth GString *gstr_union = g_string_new(""); 483199e0f17SMichael Roth int i; 484199e0f17SMichael Roth 485199e0f17SMichael Roth for (i = 0; i < 32; i++) { 486199e0f17SMichael Roth g_string_append_printf(gstr_list, "%d", i); 487199e0f17SMichael Roth if (i != 31) { 488199e0f17SMichael Roth g_string_append(gstr_list, ", "); 489199e0f17SMichael Roth } 490199e0f17SMichael Roth } 491199e0f17SMichael Roth g_string_append_printf(gstr_union, "{ 'type': '%s', 'data': [ %s ] }", 492199e0f17SMichael Roth UserDefNativeListUnionKind_lookup[kind], 493199e0f17SMichael Roth gstr_list->str); 494199e0f17SMichael Roth v = visitor_input_test_init_raw(data, gstr_union->str); 495199e0f17SMichael Roth 49651e72bc1SEric Blake visit_type_UserDefNativeListUnion(v, NULL, &cvalue, &error_abort); 497199e0f17SMichael Roth g_assert(cvalue != NULL); 498c363acefSEric Blake g_assert_cmpint(cvalue->type, ==, kind); 499199e0f17SMichael Roth 500199e0f17SMichael Roth switch (kind) { 501199e0f17SMichael Roth case USER_DEF_NATIVE_LIST_UNION_KIND_INTEGER: { 502199e0f17SMichael Roth intList *elem = NULL; 50332bafa8fSEric Blake for (i = 0, elem = cvalue->u.integer.data; 50432bafa8fSEric Blake elem; elem = elem->next, i++) { 505199e0f17SMichael Roth g_assert_cmpint(elem->value, ==, i); 506199e0f17SMichael Roth } 507199e0f17SMichael Roth break; 508199e0f17SMichael Roth } 509199e0f17SMichael Roth case USER_DEF_NATIVE_LIST_UNION_KIND_S8: { 510199e0f17SMichael Roth int8List *elem = NULL; 51132bafa8fSEric Blake for (i = 0, elem = cvalue->u.s8.data; elem; elem = elem->next, i++) { 512199e0f17SMichael Roth g_assert_cmpint(elem->value, ==, i); 513199e0f17SMichael Roth } 514199e0f17SMichael Roth break; 515199e0f17SMichael Roth } 516199e0f17SMichael Roth case USER_DEF_NATIVE_LIST_UNION_KIND_S16: { 517199e0f17SMichael Roth int16List *elem = NULL; 51832bafa8fSEric Blake for (i = 0, elem = cvalue->u.s16.data; elem; elem = elem->next, i++) { 519199e0f17SMichael Roth g_assert_cmpint(elem->value, ==, i); 520199e0f17SMichael Roth } 521199e0f17SMichael Roth break; 522199e0f17SMichael Roth } 523199e0f17SMichael Roth case USER_DEF_NATIVE_LIST_UNION_KIND_S32: { 524199e0f17SMichael Roth int32List *elem = NULL; 52532bafa8fSEric Blake for (i = 0, elem = cvalue->u.s32.data; elem; elem = elem->next, i++) { 526199e0f17SMichael Roth g_assert_cmpint(elem->value, ==, i); 527199e0f17SMichael Roth } 528199e0f17SMichael Roth break; 529199e0f17SMichael Roth } 530199e0f17SMichael Roth case USER_DEF_NATIVE_LIST_UNION_KIND_S64: { 531199e0f17SMichael Roth int64List *elem = NULL; 53232bafa8fSEric Blake for (i = 0, elem = cvalue->u.s64.data; elem; elem = elem->next, i++) { 533199e0f17SMichael Roth g_assert_cmpint(elem->value, ==, i); 534199e0f17SMichael Roth } 535199e0f17SMichael Roth break; 536199e0f17SMichael Roth } 537199e0f17SMichael Roth case USER_DEF_NATIVE_LIST_UNION_KIND_U8: { 538199e0f17SMichael Roth uint8List *elem = NULL; 53932bafa8fSEric Blake for (i = 0, elem = cvalue->u.u8.data; elem; elem = elem->next, i++) { 540199e0f17SMichael Roth g_assert_cmpint(elem->value, ==, i); 541199e0f17SMichael Roth } 542199e0f17SMichael Roth break; 543199e0f17SMichael Roth } 544199e0f17SMichael Roth case USER_DEF_NATIVE_LIST_UNION_KIND_U16: { 545199e0f17SMichael Roth uint16List *elem = NULL; 54632bafa8fSEric Blake for (i = 0, elem = cvalue->u.u16.data; elem; elem = elem->next, i++) { 547199e0f17SMichael Roth g_assert_cmpint(elem->value, ==, i); 548199e0f17SMichael Roth } 549199e0f17SMichael Roth break; 550199e0f17SMichael Roth } 551199e0f17SMichael Roth case USER_DEF_NATIVE_LIST_UNION_KIND_U32: { 552199e0f17SMichael Roth uint32List *elem = NULL; 55332bafa8fSEric Blake for (i = 0, elem = cvalue->u.u32.data; elem; elem = elem->next, i++) { 554199e0f17SMichael Roth g_assert_cmpint(elem->value, ==, i); 555199e0f17SMichael Roth } 556199e0f17SMichael Roth break; 557199e0f17SMichael Roth } 558199e0f17SMichael Roth case USER_DEF_NATIVE_LIST_UNION_KIND_U64: { 559199e0f17SMichael Roth uint64List *elem = NULL; 56032bafa8fSEric Blake for (i = 0, elem = cvalue->u.u64.data; elem; elem = elem->next, i++) { 561199e0f17SMichael Roth g_assert_cmpint(elem->value, ==, i); 562199e0f17SMichael Roth } 563199e0f17SMichael Roth break; 564199e0f17SMichael Roth } 565199e0f17SMichael Roth default: 566dfc6f865SStefan Weil g_assert_not_reached(); 567199e0f17SMichael Roth } 568199e0f17SMichael Roth 569199e0f17SMichael Roth g_string_free(gstr_union, true); 570199e0f17SMichael Roth g_string_free(gstr_list, true); 571199e0f17SMichael Roth qapi_free_UserDefNativeListUnion(cvalue); 572199e0f17SMichael Roth } 573199e0f17SMichael Roth 574199e0f17SMichael Roth static void test_visitor_in_native_list_int(TestInputVisitorData *data, 575199e0f17SMichael Roth const void *unused) 576199e0f17SMichael Roth { 577199e0f17SMichael Roth test_native_list_integer_helper(data, unused, 578199e0f17SMichael Roth USER_DEF_NATIVE_LIST_UNION_KIND_INTEGER); 579199e0f17SMichael Roth } 580199e0f17SMichael Roth 581199e0f17SMichael Roth static void test_visitor_in_native_list_int8(TestInputVisitorData *data, 582199e0f17SMichael Roth const void *unused) 583199e0f17SMichael Roth { 584199e0f17SMichael Roth test_native_list_integer_helper(data, unused, 585199e0f17SMichael Roth USER_DEF_NATIVE_LIST_UNION_KIND_S8); 586199e0f17SMichael Roth } 587199e0f17SMichael Roth 588199e0f17SMichael Roth static void test_visitor_in_native_list_int16(TestInputVisitorData *data, 589199e0f17SMichael Roth const void *unused) 590199e0f17SMichael Roth { 591199e0f17SMichael Roth test_native_list_integer_helper(data, unused, 592199e0f17SMichael Roth USER_DEF_NATIVE_LIST_UNION_KIND_S16); 593199e0f17SMichael Roth } 594199e0f17SMichael Roth 595199e0f17SMichael Roth static void test_visitor_in_native_list_int32(TestInputVisitorData *data, 596199e0f17SMichael Roth const void *unused) 597199e0f17SMichael Roth { 598199e0f17SMichael Roth test_native_list_integer_helper(data, unused, 599199e0f17SMichael Roth USER_DEF_NATIVE_LIST_UNION_KIND_S32); 600199e0f17SMichael Roth } 601199e0f17SMichael Roth 602199e0f17SMichael Roth static void test_visitor_in_native_list_int64(TestInputVisitorData *data, 603199e0f17SMichael Roth const void *unused) 604199e0f17SMichael Roth { 605199e0f17SMichael Roth test_native_list_integer_helper(data, unused, 606199e0f17SMichael Roth USER_DEF_NATIVE_LIST_UNION_KIND_S64); 607199e0f17SMichael Roth } 608199e0f17SMichael Roth 609199e0f17SMichael Roth static void test_visitor_in_native_list_uint8(TestInputVisitorData *data, 610199e0f17SMichael Roth const void *unused) 611199e0f17SMichael Roth { 612199e0f17SMichael Roth test_native_list_integer_helper(data, unused, 613199e0f17SMichael Roth USER_DEF_NATIVE_LIST_UNION_KIND_U8); 614199e0f17SMichael Roth } 615199e0f17SMichael Roth 616199e0f17SMichael Roth static void test_visitor_in_native_list_uint16(TestInputVisitorData *data, 617199e0f17SMichael Roth const void *unused) 618199e0f17SMichael Roth { 619199e0f17SMichael Roth test_native_list_integer_helper(data, unused, 620199e0f17SMichael Roth USER_DEF_NATIVE_LIST_UNION_KIND_U16); 621199e0f17SMichael Roth } 622199e0f17SMichael Roth 623199e0f17SMichael Roth static void test_visitor_in_native_list_uint32(TestInputVisitorData *data, 624199e0f17SMichael Roth const void *unused) 625199e0f17SMichael Roth { 626199e0f17SMichael Roth test_native_list_integer_helper(data, unused, 627199e0f17SMichael Roth USER_DEF_NATIVE_LIST_UNION_KIND_U32); 628199e0f17SMichael Roth } 629199e0f17SMichael Roth 630199e0f17SMichael Roth static void test_visitor_in_native_list_uint64(TestInputVisitorData *data, 631199e0f17SMichael Roth const void *unused) 632199e0f17SMichael Roth { 633199e0f17SMichael Roth test_native_list_integer_helper(data, unused, 634199e0f17SMichael Roth USER_DEF_NATIVE_LIST_UNION_KIND_U64); 635199e0f17SMichael Roth } 636199e0f17SMichael Roth 637199e0f17SMichael Roth static void test_visitor_in_native_list_bool(TestInputVisitorData *data, 638199e0f17SMichael Roth const void *unused) 639199e0f17SMichael Roth { 640199e0f17SMichael Roth UserDefNativeListUnion *cvalue = NULL; 641199e0f17SMichael Roth boolList *elem = NULL; 642199e0f17SMichael Roth Visitor *v; 643199e0f17SMichael Roth GString *gstr_list = g_string_new(""); 644199e0f17SMichael Roth GString *gstr_union = g_string_new(""); 645199e0f17SMichael Roth int i; 646199e0f17SMichael Roth 647199e0f17SMichael Roth for (i = 0; i < 32; i++) { 648199e0f17SMichael Roth g_string_append_printf(gstr_list, "%s", 649199e0f17SMichael Roth (i % 3 == 0) ? "true" : "false"); 650199e0f17SMichael Roth if (i != 31) { 651199e0f17SMichael Roth g_string_append(gstr_list, ", "); 652199e0f17SMichael Roth } 653199e0f17SMichael Roth } 654199e0f17SMichael Roth g_string_append_printf(gstr_union, "{ 'type': 'boolean', 'data': [ %s ] }", 655199e0f17SMichael Roth gstr_list->str); 656199e0f17SMichael Roth v = visitor_input_test_init_raw(data, gstr_union->str); 657199e0f17SMichael Roth 65851e72bc1SEric Blake visit_type_UserDefNativeListUnion(v, NULL, &cvalue, &error_abort); 659199e0f17SMichael Roth g_assert(cvalue != NULL); 660c363acefSEric Blake g_assert_cmpint(cvalue->type, ==, USER_DEF_NATIVE_LIST_UNION_KIND_BOOLEAN); 661199e0f17SMichael Roth 66232bafa8fSEric Blake for (i = 0, elem = cvalue->u.boolean.data; elem; elem = elem->next, i++) { 663199e0f17SMichael Roth g_assert_cmpint(elem->value, ==, (i % 3 == 0) ? 1 : 0); 664199e0f17SMichael Roth } 665199e0f17SMichael Roth 666199e0f17SMichael Roth g_string_free(gstr_union, true); 667199e0f17SMichael Roth g_string_free(gstr_list, true); 668199e0f17SMichael Roth qapi_free_UserDefNativeListUnion(cvalue); 669199e0f17SMichael Roth } 670199e0f17SMichael Roth 671199e0f17SMichael Roth static void test_visitor_in_native_list_string(TestInputVisitorData *data, 672199e0f17SMichael Roth const void *unused) 673199e0f17SMichael Roth { 674199e0f17SMichael Roth UserDefNativeListUnion *cvalue = NULL; 675199e0f17SMichael Roth strList *elem = NULL; 676199e0f17SMichael Roth Visitor *v; 677199e0f17SMichael Roth GString *gstr_list = g_string_new(""); 678199e0f17SMichael Roth GString *gstr_union = g_string_new(""); 679199e0f17SMichael Roth int i; 680199e0f17SMichael Roth 681199e0f17SMichael Roth for (i = 0; i < 32; i++) { 682199e0f17SMichael Roth g_string_append_printf(gstr_list, "'%d'", i); 683199e0f17SMichael Roth if (i != 31) { 684199e0f17SMichael Roth g_string_append(gstr_list, ", "); 685199e0f17SMichael Roth } 686199e0f17SMichael Roth } 687199e0f17SMichael Roth g_string_append_printf(gstr_union, "{ 'type': 'string', 'data': [ %s ] }", 688199e0f17SMichael Roth gstr_list->str); 689199e0f17SMichael Roth v = visitor_input_test_init_raw(data, gstr_union->str); 690199e0f17SMichael Roth 69151e72bc1SEric Blake visit_type_UserDefNativeListUnion(v, NULL, &cvalue, &error_abort); 692199e0f17SMichael Roth g_assert(cvalue != NULL); 693c363acefSEric Blake g_assert_cmpint(cvalue->type, ==, USER_DEF_NATIVE_LIST_UNION_KIND_STRING); 694199e0f17SMichael Roth 69532bafa8fSEric Blake for (i = 0, elem = cvalue->u.string.data; elem; elem = elem->next, i++) { 696199e0f17SMichael Roth gchar str[8]; 697199e0f17SMichael Roth sprintf(str, "%d", i); 698199e0f17SMichael Roth g_assert_cmpstr(elem->value, ==, str); 699199e0f17SMichael Roth } 700199e0f17SMichael Roth 701199e0f17SMichael Roth g_string_free(gstr_union, true); 702199e0f17SMichael Roth g_string_free(gstr_list, true); 703199e0f17SMichael Roth qapi_free_UserDefNativeListUnion(cvalue); 704199e0f17SMichael Roth } 705199e0f17SMichael Roth 706199e0f17SMichael Roth #define DOUBLE_STR_MAX 16 707199e0f17SMichael Roth 708199e0f17SMichael Roth static void test_visitor_in_native_list_number(TestInputVisitorData *data, 709199e0f17SMichael Roth const void *unused) 710199e0f17SMichael Roth { 711199e0f17SMichael Roth UserDefNativeListUnion *cvalue = NULL; 712199e0f17SMichael Roth numberList *elem = NULL; 713199e0f17SMichael Roth Visitor *v; 714199e0f17SMichael Roth GString *gstr_list = g_string_new(""); 715199e0f17SMichael Roth GString *gstr_union = g_string_new(""); 716199e0f17SMichael Roth int i; 717199e0f17SMichael Roth 718199e0f17SMichael Roth for (i = 0; i < 32; i++) { 719199e0f17SMichael Roth g_string_append_printf(gstr_list, "%f", (double)i / 3); 720199e0f17SMichael Roth if (i != 31) { 721199e0f17SMichael Roth g_string_append(gstr_list, ", "); 722199e0f17SMichael Roth } 723199e0f17SMichael Roth } 724199e0f17SMichael Roth g_string_append_printf(gstr_union, "{ 'type': 'number', 'data': [ %s ] }", 725199e0f17SMichael Roth gstr_list->str); 726199e0f17SMichael Roth v = visitor_input_test_init_raw(data, gstr_union->str); 727199e0f17SMichael Roth 72851e72bc1SEric Blake visit_type_UserDefNativeListUnion(v, NULL, &cvalue, &error_abort); 729199e0f17SMichael Roth g_assert(cvalue != NULL); 730c363acefSEric Blake g_assert_cmpint(cvalue->type, ==, USER_DEF_NATIVE_LIST_UNION_KIND_NUMBER); 731199e0f17SMichael Roth 73232bafa8fSEric Blake for (i = 0, elem = cvalue->u.number.data; elem; elem = elem->next, i++) { 733199e0f17SMichael Roth GString *double_expected = g_string_new(""); 734199e0f17SMichael Roth GString *double_actual = g_string_new(""); 735199e0f17SMichael Roth 736199e0f17SMichael Roth g_string_printf(double_expected, "%.6f", (double)i / 3); 737199e0f17SMichael Roth g_string_printf(double_actual, "%.6f", elem->value); 738199e0f17SMichael Roth g_assert_cmpstr(double_expected->str, ==, double_actual->str); 739199e0f17SMichael Roth 740199e0f17SMichael Roth g_string_free(double_expected, true); 741199e0f17SMichael Roth g_string_free(double_actual, true); 742199e0f17SMichael Roth } 743199e0f17SMichael Roth 744199e0f17SMichael Roth g_string_free(gstr_union, true); 745199e0f17SMichael Roth g_string_free(gstr_list, true); 746199e0f17SMichael Roth qapi_free_UserDefNativeListUnion(cvalue); 747199e0f17SMichael Roth } 748199e0f17SMichael Roth 749d88f5fd1SLuiz Capitulino static void input_visitor_test_add(const char *testpath, 750d88f5fd1SLuiz Capitulino TestInputVisitorData *data, 751d88f5fd1SLuiz Capitulino void (*test_func)(TestInputVisitorData *data, const void *user_data)) 752d88f5fd1SLuiz Capitulino { 753d88f5fd1SLuiz Capitulino g_test_add(testpath, TestInputVisitorData, data, NULL, test_func, 754d88f5fd1SLuiz Capitulino visitor_input_teardown); 755d88f5fd1SLuiz Capitulino } 756d88f5fd1SLuiz Capitulino 7573dcf71f6SPaolo Bonzini static void test_visitor_in_errors(TestInputVisitorData *data, 7583dcf71f6SPaolo Bonzini const void *unused) 7593dcf71f6SPaolo Bonzini { 7603dcf71f6SPaolo Bonzini TestStruct *p = NULL; 761e940f543SMarkus Armbruster Error *err = NULL; 7623dcf71f6SPaolo Bonzini Visitor *v; 763dd5ee2c2SEric Blake strList *q = NULL; 7649b4e38feSEric Blake UserDefTwo *r = NULL; 7659b4e38feSEric Blake WrapAlternate *s = NULL; 7663dcf71f6SPaolo Bonzini 767dd5ee2c2SEric Blake v = visitor_input_test_init(data, "{ 'integer': false, 'boolean': 'foo', " 768dd5ee2c2SEric Blake "'string': -42 }"); 7693dcf71f6SPaolo Bonzini 77051e72bc1SEric Blake visit_type_TestStruct(v, NULL, &p, &err); 771a12a5a1aSEric Blake error_free_or_abort(&err); 77268ab47e4SEric Blake g_assert(!p); 773dd5ee2c2SEric Blake 774dd5ee2c2SEric Blake v = visitor_input_test_init(data, "[ '1', '2', false, '3' ]"); 77551e72bc1SEric Blake visit_type_strList(v, NULL, &q, &err); 776dd5ee2c2SEric Blake error_free_or_abort(&err); 77768ab47e4SEric Blake assert(!q); 7789b4e38feSEric Blake 7799b4e38feSEric Blake v = visitor_input_test_init(data, "{ 'str':'hi' }"); 7809b4e38feSEric Blake visit_type_UserDefTwo(v, NULL, &r, &err); 7819b4e38feSEric Blake error_free_or_abort(&err); 7829b4e38feSEric Blake assert(!r); 7839b4e38feSEric Blake 7849b4e38feSEric Blake v = visitor_input_test_init(data, "{ }"); 7859b4e38feSEric Blake visit_type_WrapAlternate(v, NULL, &s, &err); 7869b4e38feSEric Blake error_free_or_abort(&err); 7879b4e38feSEric Blake assert(!s); 7883dcf71f6SPaolo Bonzini } 7893dcf71f6SPaolo Bonzini 7902533377cSEric Blake static void test_visitor_in_wrong_type(TestInputVisitorData *data, 7912533377cSEric Blake const void *unused) 7922533377cSEric Blake { 7932533377cSEric Blake TestStruct *p = NULL; 7942533377cSEric Blake Visitor *v; 7952533377cSEric Blake strList *q = NULL; 7962533377cSEric Blake int64_t i; 7972533377cSEric Blake Error *err = NULL; 7982533377cSEric Blake 7992533377cSEric Blake /* Make sure arrays and structs cannot be confused */ 8002533377cSEric Blake 8012533377cSEric Blake v = visitor_input_test_init(data, "[]"); 80251e72bc1SEric Blake visit_type_TestStruct(v, NULL, &p, &err); 8032533377cSEric Blake error_free_or_abort(&err); 8042533377cSEric Blake g_assert(!p); 8052533377cSEric Blake 8062533377cSEric Blake v = visitor_input_test_init(data, "{}"); 80751e72bc1SEric Blake visit_type_strList(v, NULL, &q, &err); 8082533377cSEric Blake error_free_or_abort(&err); 8092533377cSEric Blake assert(!q); 8102533377cSEric Blake 8112533377cSEric Blake /* Make sure primitives and struct cannot be confused */ 8122533377cSEric Blake 8132533377cSEric Blake v = visitor_input_test_init(data, "1"); 81451e72bc1SEric Blake visit_type_TestStruct(v, NULL, &p, &err); 8152533377cSEric Blake error_free_or_abort(&err); 8162533377cSEric Blake g_assert(!p); 8172533377cSEric Blake 8182533377cSEric Blake v = visitor_input_test_init(data, "{}"); 81951e72bc1SEric Blake visit_type_int(v, NULL, &i, &err); 8202533377cSEric Blake error_free_or_abort(&err); 8212533377cSEric Blake 8222533377cSEric Blake /* Make sure primitives and arrays cannot be confused */ 8232533377cSEric Blake 8242533377cSEric Blake v = visitor_input_test_init(data, "1"); 82551e72bc1SEric Blake visit_type_strList(v, NULL, &q, &err); 8262533377cSEric Blake error_free_or_abort(&err); 8272533377cSEric Blake assert(!q); 8282533377cSEric Blake 8292533377cSEric Blake v = visitor_input_test_init(data, "[]"); 83051e72bc1SEric Blake visit_type_int(v, NULL, &i, &err); 8312533377cSEric Blake error_free_or_abort(&err); 8322533377cSEric Blake } 8332533377cSEric Blake 834d88f5fd1SLuiz Capitulino int main(int argc, char **argv) 835d88f5fd1SLuiz Capitulino { 836d88f5fd1SLuiz Capitulino TestInputVisitorData in_visitor_data; 837d88f5fd1SLuiz Capitulino 838d88f5fd1SLuiz Capitulino g_test_init(&argc, &argv, NULL); 839d88f5fd1SLuiz Capitulino 840d88f5fd1SLuiz Capitulino input_visitor_test_add("/visitor/input/int", 841d88f5fd1SLuiz Capitulino &in_visitor_data, test_visitor_in_int); 842e92cfa0dSMichael Roth input_visitor_test_add("/visitor/input/int_overflow", 843e92cfa0dSMichael Roth &in_visitor_data, test_visitor_in_int_overflow); 844d88f5fd1SLuiz Capitulino input_visitor_test_add("/visitor/input/bool", 845d88f5fd1SLuiz Capitulino &in_visitor_data, test_visitor_in_bool); 846d88f5fd1SLuiz Capitulino input_visitor_test_add("/visitor/input/number", 847d88f5fd1SLuiz Capitulino &in_visitor_data, test_visitor_in_number); 848d88f5fd1SLuiz Capitulino input_visitor_test_add("/visitor/input/string", 849d88f5fd1SLuiz Capitulino &in_visitor_data, test_visitor_in_string); 850d88f5fd1SLuiz Capitulino input_visitor_test_add("/visitor/input/enum", 851d88f5fd1SLuiz Capitulino &in_visitor_data, test_visitor_in_enum); 852d88f5fd1SLuiz Capitulino input_visitor_test_add("/visitor/input/struct", 853d88f5fd1SLuiz Capitulino &in_visitor_data, test_visitor_in_struct); 854d88f5fd1SLuiz Capitulino input_visitor_test_add("/visitor/input/struct-nested", 855d88f5fd1SLuiz Capitulino &in_visitor_data, test_visitor_in_struct_nested); 856d88f5fd1SLuiz Capitulino input_visitor_test_add("/visitor/input/list", 857d88f5fd1SLuiz Capitulino &in_visitor_data, test_visitor_in_list); 85828770e05SMarkus Armbruster input_visitor_test_add("/visitor/input/any", 85928770e05SMarkus Armbruster &in_visitor_data, test_visitor_in_any); 8603df016f1SEric Blake input_visitor_test_add("/visitor/input/null", 8613df016f1SEric Blake &in_visitor_data, test_visitor_in_null); 8622fc00432SMarkus Armbruster input_visitor_test_add("/visitor/input/union-flat", 8632fc00432SMarkus Armbruster &in_visitor_data, test_visitor_in_union_flat); 864ab045267SEric Blake input_visitor_test_add("/visitor/input/alternate", 865ab045267SEric Blake &in_visitor_data, test_visitor_in_alternate); 8663dcf71f6SPaolo Bonzini input_visitor_test_add("/visitor/input/errors", 8673dcf71f6SPaolo Bonzini &in_visitor_data, test_visitor_in_errors); 8682533377cSEric Blake input_visitor_test_add("/visitor/input/wrong-type", 8692533377cSEric Blake &in_visitor_data, test_visitor_in_wrong_type); 8709c51b441SEric Blake input_visitor_test_add("/visitor/input/alternate-number", 8719c51b441SEric Blake &in_visitor_data, test_visitor_in_alternate_number); 872199e0f17SMichael Roth input_visitor_test_add("/visitor/input/native_list/int", 873199e0f17SMichael Roth &in_visitor_data, 874199e0f17SMichael Roth test_visitor_in_native_list_int); 875199e0f17SMichael Roth input_visitor_test_add("/visitor/input/native_list/int8", 876199e0f17SMichael Roth &in_visitor_data, 877199e0f17SMichael Roth test_visitor_in_native_list_int8); 878199e0f17SMichael Roth input_visitor_test_add("/visitor/input/native_list/int16", 879199e0f17SMichael Roth &in_visitor_data, 880199e0f17SMichael Roth test_visitor_in_native_list_int16); 881199e0f17SMichael Roth input_visitor_test_add("/visitor/input/native_list/int32", 882199e0f17SMichael Roth &in_visitor_data, 883199e0f17SMichael Roth test_visitor_in_native_list_int32); 884199e0f17SMichael Roth input_visitor_test_add("/visitor/input/native_list/int64", 885199e0f17SMichael Roth &in_visitor_data, 886199e0f17SMichael Roth test_visitor_in_native_list_int64); 887199e0f17SMichael Roth input_visitor_test_add("/visitor/input/native_list/uint8", 888199e0f17SMichael Roth &in_visitor_data, 889199e0f17SMichael Roth test_visitor_in_native_list_uint8); 890199e0f17SMichael Roth input_visitor_test_add("/visitor/input/native_list/uint16", 891199e0f17SMichael Roth &in_visitor_data, 892199e0f17SMichael Roth test_visitor_in_native_list_uint16); 893199e0f17SMichael Roth input_visitor_test_add("/visitor/input/native_list/uint32", 894199e0f17SMichael Roth &in_visitor_data, 895199e0f17SMichael Roth test_visitor_in_native_list_uint32); 896199e0f17SMichael Roth input_visitor_test_add("/visitor/input/native_list/uint64", 897805017b7SEric Blake &in_visitor_data, 898805017b7SEric Blake test_visitor_in_native_list_uint64); 899199e0f17SMichael Roth input_visitor_test_add("/visitor/input/native_list/bool", 900199e0f17SMichael Roth &in_visitor_data, test_visitor_in_native_list_bool); 901199e0f17SMichael Roth input_visitor_test_add("/visitor/input/native_list/str", 902805017b7SEric Blake &in_visitor_data, 903805017b7SEric Blake test_visitor_in_native_list_string); 904199e0f17SMichael Roth input_visitor_test_add("/visitor/input/native_list/number", 905805017b7SEric Blake &in_visitor_data, 906805017b7SEric Blake test_visitor_in_native_list_number); 907d88f5fd1SLuiz Capitulino 908d88f5fd1SLuiz Capitulino g_test_run(); 909d88f5fd1SLuiz Capitulino 910d88f5fd1SLuiz Capitulino return 0; 911d88f5fd1SLuiz Capitulino } 912