1d88f5fd1SLuiz Capitulino /* 2d88f5fd1SLuiz Capitulino * QMP 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" 17d88f5fd1SLuiz Capitulino #include "qapi/qmp-input-visitor.h" 18d88f5fd1SLuiz Capitulino #include "test-qapi-types.h" 19d88f5fd1SLuiz Capitulino #include "test-qapi-visit.h" 207b1b5d19SPaolo Bonzini #include "qapi/qmp/types.h" 21d88f5fd1SLuiz Capitulino 22d88f5fd1SLuiz Capitulino typedef struct TestInputVisitorData { 23d88f5fd1SLuiz Capitulino QObject *obj; 24d88f5fd1SLuiz Capitulino QmpInputVisitor *qiv; 25d88f5fd1SLuiz Capitulino } TestInputVisitorData; 26d88f5fd1SLuiz Capitulino 27d88f5fd1SLuiz Capitulino static void visitor_input_teardown(TestInputVisitorData *data, 28d88f5fd1SLuiz Capitulino const void *unused) 29d88f5fd1SLuiz Capitulino { 30d88f5fd1SLuiz Capitulino qobject_decref(data->obj); 31d88f5fd1SLuiz Capitulino data->obj = NULL; 32d88f5fd1SLuiz Capitulino 33d88f5fd1SLuiz Capitulino if (data->qiv) { 34d88f5fd1SLuiz Capitulino qmp_input_visitor_cleanup(data->qiv); 35d88f5fd1SLuiz Capitulino data->qiv = NULL; 36d88f5fd1SLuiz Capitulino } 37d88f5fd1SLuiz Capitulino } 38d88f5fd1SLuiz Capitulino 390920a171SEric Blake /* The various test_init functions are provided instead of a test setup 400920a171SEric Blake function so that the JSON string used by the tests are kept in the test 410920a171SEric Blake functions (and not in main()). */ 420920a171SEric Blake static Visitor *visitor_input_test_init_internal(TestInputVisitorData *data, 430920a171SEric Blake const char *json_string, 440920a171SEric Blake va_list *ap) 450920a171SEric Blake { 460920a171SEric Blake Visitor *v; 470920a171SEric Blake 48b18f1141SEric Blake visitor_input_teardown(data, NULL); 49b18f1141SEric Blake 500920a171SEric Blake data->obj = qobject_from_jsonv(json_string, ap); 510920a171SEric Blake g_assert(data->obj); 520920a171SEric Blake 53fc471c18SEric Blake data->qiv = qmp_input_visitor_new(data->obj, false); 540920a171SEric Blake g_assert(data->qiv); 550920a171SEric Blake 560920a171SEric Blake v = qmp_input_get_visitor(data->qiv); 570920a171SEric Blake g_assert(v); 580920a171SEric Blake 590920a171SEric Blake return v; 600920a171SEric Blake } 610920a171SEric Blake 62aba2107aSStefan Weil static GCC_FMT_ATTR(2, 3) 63aba2107aSStefan Weil Visitor *visitor_input_test_init(TestInputVisitorData *data, 64d88f5fd1SLuiz Capitulino const char *json_string, ...) 65d88f5fd1SLuiz Capitulino { 66d88f5fd1SLuiz Capitulino Visitor *v; 67d88f5fd1SLuiz Capitulino va_list ap; 68d88f5fd1SLuiz Capitulino 69d88f5fd1SLuiz Capitulino va_start(ap, json_string); 700920a171SEric Blake v = visitor_input_test_init_internal(data, json_string, &ap); 71d88f5fd1SLuiz Capitulino va_end(ap); 72d88f5fd1SLuiz Capitulino return v; 73d88f5fd1SLuiz Capitulino } 74d88f5fd1SLuiz Capitulino 75199e0f17SMichael Roth /* similar to visitor_input_test_init(), but does not expect a string 76199e0f17SMichael Roth * literal/format json_string argument and so can be used for 77199e0f17SMichael Roth * programatically generated strings (and we can't pass in programatically 78199e0f17SMichael Roth * generated strings via %s format parameters since qobject_from_jsonv() 79199e0f17SMichael Roth * will wrap those in double-quotes and treat the entire object as a 80199e0f17SMichael Roth * string) 81199e0f17SMichael Roth */ 82199e0f17SMichael Roth static Visitor *visitor_input_test_init_raw(TestInputVisitorData *data, 83199e0f17SMichael Roth const char *json_string) 84199e0f17SMichael Roth { 850920a171SEric Blake return visitor_input_test_init_internal(data, json_string, NULL); 86199e0f17SMichael Roth } 87199e0f17SMichael Roth 88d88f5fd1SLuiz Capitulino static void test_visitor_in_int(TestInputVisitorData *data, 89d88f5fd1SLuiz Capitulino const void *unused) 90d88f5fd1SLuiz Capitulino { 91d88f5fd1SLuiz Capitulino int64_t res = 0, value = -42; 92d88f5fd1SLuiz Capitulino Visitor *v; 93d88f5fd1SLuiz Capitulino 94aba2107aSStefan Weil v = visitor_input_test_init(data, "%" PRId64, value); 95d88f5fd1SLuiz Capitulino 9651e72bc1SEric Blake visit_type_int(v, NULL, &res, &error_abort); 97d88f5fd1SLuiz Capitulino g_assert_cmpint(res, ==, value); 98d88f5fd1SLuiz Capitulino } 99d88f5fd1SLuiz Capitulino 100e92cfa0dSMichael Roth static void test_visitor_in_int_overflow(TestInputVisitorData *data, 101e92cfa0dSMichael Roth const void *unused) 102e92cfa0dSMichael Roth { 103e92cfa0dSMichael Roth int64_t res = 0; 104e940f543SMarkus Armbruster Error *err = NULL; 105e92cfa0dSMichael Roth Visitor *v; 106e92cfa0dSMichael Roth 107e92cfa0dSMichael Roth /* this will overflow a Qint/int64, so should be deserialized into 108e92cfa0dSMichael Roth * a QFloat/double field instead, leading to an error if we pass it 109e92cfa0dSMichael Roth * to visit_type_int. confirm this. 110e92cfa0dSMichael Roth */ 111e92cfa0dSMichael Roth v = visitor_input_test_init(data, "%f", DBL_MAX); 112e92cfa0dSMichael Roth 11351e72bc1SEric Blake visit_type_int(v, NULL, &res, &err); 114a12a5a1aSEric Blake error_free_or_abort(&err); 115e92cfa0dSMichael Roth } 116e92cfa0dSMichael Roth 117d88f5fd1SLuiz Capitulino static void test_visitor_in_bool(TestInputVisitorData *data, 118d88f5fd1SLuiz Capitulino const void *unused) 119d88f5fd1SLuiz Capitulino { 120d88f5fd1SLuiz Capitulino bool res = false; 121d88f5fd1SLuiz Capitulino Visitor *v; 122d88f5fd1SLuiz Capitulino 123d88f5fd1SLuiz Capitulino v = visitor_input_test_init(data, "true"); 124d88f5fd1SLuiz Capitulino 12551e72bc1SEric Blake visit_type_bool(v, NULL, &res, &error_abort); 126d88f5fd1SLuiz Capitulino g_assert_cmpint(res, ==, true); 127d88f5fd1SLuiz Capitulino } 128d88f5fd1SLuiz Capitulino 129d88f5fd1SLuiz Capitulino static void test_visitor_in_number(TestInputVisitorData *data, 130d88f5fd1SLuiz Capitulino const void *unused) 131d88f5fd1SLuiz Capitulino { 132d88f5fd1SLuiz Capitulino double res = 0, value = 3.14; 133d88f5fd1SLuiz Capitulino Visitor *v; 134d88f5fd1SLuiz Capitulino 135d88f5fd1SLuiz Capitulino v = visitor_input_test_init(data, "%f", value); 136d88f5fd1SLuiz Capitulino 13751e72bc1SEric Blake visit_type_number(v, NULL, &res, &error_abort); 138d88f5fd1SLuiz Capitulino g_assert_cmpfloat(res, ==, value); 139d88f5fd1SLuiz Capitulino } 140d88f5fd1SLuiz Capitulino 141d88f5fd1SLuiz Capitulino static void test_visitor_in_string(TestInputVisitorData *data, 142d88f5fd1SLuiz Capitulino const void *unused) 143d88f5fd1SLuiz Capitulino { 144d88f5fd1SLuiz Capitulino char *res = NULL, *value = (char *) "Q E M U"; 145d88f5fd1SLuiz Capitulino Visitor *v; 146d88f5fd1SLuiz Capitulino 147d88f5fd1SLuiz Capitulino v = visitor_input_test_init(data, "%s", value); 148d88f5fd1SLuiz Capitulino 14951e72bc1SEric Blake visit_type_str(v, NULL, &res, &error_abort); 150d88f5fd1SLuiz Capitulino g_assert_cmpstr(res, ==, value); 151d88f5fd1SLuiz Capitulino 152d88f5fd1SLuiz Capitulino g_free(res); 153d88f5fd1SLuiz Capitulino } 154d88f5fd1SLuiz Capitulino 155d88f5fd1SLuiz Capitulino static void test_visitor_in_enum(TestInputVisitorData *data, 156d88f5fd1SLuiz Capitulino const void *unused) 157d88f5fd1SLuiz Capitulino { 158d88f5fd1SLuiz Capitulino Visitor *v; 159d88f5fd1SLuiz Capitulino EnumOne i; 160d88f5fd1SLuiz Capitulino 161d88f5fd1SLuiz Capitulino for (i = 0; EnumOne_lookup[i]; i++) { 162d88f5fd1SLuiz Capitulino EnumOne res = -1; 163d88f5fd1SLuiz Capitulino 164d88f5fd1SLuiz Capitulino v = visitor_input_test_init(data, "%s", EnumOne_lookup[i]); 165d88f5fd1SLuiz Capitulino 16651e72bc1SEric Blake visit_type_EnumOne(v, NULL, &res, &error_abort); 167d88f5fd1SLuiz Capitulino g_assert_cmpint(i, ==, res); 168d88f5fd1SLuiz Capitulino } 169d88f5fd1SLuiz Capitulino } 170d88f5fd1SLuiz Capitulino 171d88f5fd1SLuiz Capitulino 172d88f5fd1SLuiz Capitulino static void test_visitor_in_struct(TestInputVisitorData *data, 173d88f5fd1SLuiz Capitulino const void *unused) 174d88f5fd1SLuiz Capitulino { 175d88f5fd1SLuiz Capitulino TestStruct *p = NULL; 176d88f5fd1SLuiz Capitulino Visitor *v; 177d88f5fd1SLuiz Capitulino 178d88f5fd1SLuiz Capitulino v = visitor_input_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo' }"); 179d88f5fd1SLuiz Capitulino 18051e72bc1SEric Blake visit_type_TestStruct(v, NULL, &p, &error_abort); 181d88f5fd1SLuiz Capitulino g_assert_cmpint(p->integer, ==, -42); 182d88f5fd1SLuiz Capitulino g_assert(p->boolean == true); 183d88f5fd1SLuiz Capitulino g_assert_cmpstr(p->string, ==, "foo"); 184d88f5fd1SLuiz Capitulino 185d88f5fd1SLuiz Capitulino g_free(p->string); 186d88f5fd1SLuiz Capitulino g_free(p); 187d88f5fd1SLuiz Capitulino } 188d88f5fd1SLuiz Capitulino 189d88f5fd1SLuiz Capitulino static void test_visitor_in_struct_nested(TestInputVisitorData *data, 190d88f5fd1SLuiz Capitulino const void *unused) 191d88f5fd1SLuiz Capitulino { 192b6fcf32dSEric Blake UserDefTwo *udp = NULL; 193d88f5fd1SLuiz Capitulino Visitor *v; 194d88f5fd1SLuiz Capitulino 195b6fcf32dSEric Blake v = visitor_input_test_init(data, "{ 'string0': 'string0', " 196b6fcf32dSEric Blake "'dict1': { 'string1': 'string1', " 197b6fcf32dSEric Blake "'dict2': { 'userdef': { 'integer': 42, " 198b6fcf32dSEric Blake "'string': 'string' }, 'string': 'string2'}}}"); 199d88f5fd1SLuiz Capitulino 20051e72bc1SEric Blake visit_type_UserDefTwo(v, NULL, &udp, &error_abort); 201d88f5fd1SLuiz Capitulino 202b18f1141SEric Blake g_assert_cmpstr(udp->string0, ==, "string0"); 203b18f1141SEric Blake g_assert_cmpstr(udp->dict1->string1, ==, "string1"); 204ddf21908SEric Blake g_assert_cmpint(udp->dict1->dict2->userdef->integer, ==, 42); 205b18f1141SEric Blake g_assert_cmpstr(udp->dict1->dict2->userdef->string, ==, "string"); 206b18f1141SEric Blake g_assert_cmpstr(udp->dict1->dict2->string, ==, "string2"); 2076446a592SEric Blake g_assert(udp->dict1->has_dict3 == false); 208d88f5fd1SLuiz Capitulino 209b18f1141SEric Blake qapi_free_UserDefTwo(udp); 210d88f5fd1SLuiz Capitulino } 211d88f5fd1SLuiz Capitulino 212d88f5fd1SLuiz Capitulino static void test_visitor_in_list(TestInputVisitorData *data, 213d88f5fd1SLuiz Capitulino const void *unused) 214d88f5fd1SLuiz Capitulino { 215d88f5fd1SLuiz Capitulino UserDefOneList *item, *head = NULL; 216d88f5fd1SLuiz Capitulino Visitor *v; 217d88f5fd1SLuiz Capitulino int i; 218d88f5fd1SLuiz Capitulino 219d88f5fd1SLuiz Capitulino v = visitor_input_test_init(data, "[ { 'string': 'string0', 'integer': 42 }, { 'string': 'string1', 'integer': 43 }, { 'string': 'string2', 'integer': 44 } ]"); 220d88f5fd1SLuiz Capitulino 22151e72bc1SEric Blake visit_type_UserDefOneList(v, NULL, &head, &error_abort); 222d88f5fd1SLuiz Capitulino g_assert(head != NULL); 223d88f5fd1SLuiz Capitulino 224d88f5fd1SLuiz Capitulino for (i = 0, item = head; item; item = item->next, i++) { 225d88f5fd1SLuiz Capitulino char string[12]; 226d88f5fd1SLuiz Capitulino 227d88f5fd1SLuiz Capitulino snprintf(string, sizeof(string), "string%d", i); 228d88f5fd1SLuiz Capitulino g_assert_cmpstr(item->value->string, ==, string); 229ddf21908SEric Blake g_assert_cmpint(item->value->integer, ==, 42 + i); 230d88f5fd1SLuiz Capitulino } 231d88f5fd1SLuiz Capitulino 232d88f5fd1SLuiz Capitulino qapi_free_UserDefOneList(head); 2332533377cSEric Blake head = NULL; 2342533377cSEric Blake 2352533377cSEric Blake /* An empty list is valid */ 2362533377cSEric Blake v = visitor_input_test_init(data, "[]"); 23751e72bc1SEric Blake visit_type_UserDefOneList(v, NULL, &head, &error_abort); 2382533377cSEric Blake g_assert(!head); 239d88f5fd1SLuiz Capitulino } 240d88f5fd1SLuiz Capitulino 24128770e05SMarkus Armbruster static void test_visitor_in_any(TestInputVisitorData *data, 24228770e05SMarkus Armbruster const void *unused) 24328770e05SMarkus Armbruster { 24428770e05SMarkus Armbruster QObject *res = NULL; 24528770e05SMarkus Armbruster Visitor *v; 24628770e05SMarkus Armbruster QInt *qint; 24728770e05SMarkus Armbruster QBool *qbool; 24828770e05SMarkus Armbruster QString *qstring; 24928770e05SMarkus Armbruster QDict *qdict; 25028770e05SMarkus Armbruster QObject *qobj; 25128770e05SMarkus Armbruster 25228770e05SMarkus Armbruster v = visitor_input_test_init(data, "-42"); 25351e72bc1SEric Blake visit_type_any(v, NULL, &res, &error_abort); 25428770e05SMarkus Armbruster qint = qobject_to_qint(res); 25528770e05SMarkus Armbruster g_assert(qint); 25628770e05SMarkus Armbruster g_assert_cmpint(qint_get_int(qint), ==, -42); 25728770e05SMarkus Armbruster qobject_decref(res); 25828770e05SMarkus Armbruster 25928770e05SMarkus Armbruster v = visitor_input_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo' }"); 26051e72bc1SEric Blake visit_type_any(v, NULL, &res, &error_abort); 26128770e05SMarkus Armbruster qdict = qobject_to_qdict(res); 26228770e05SMarkus Armbruster g_assert(qdict && qdict_size(qdict) == 3); 26328770e05SMarkus Armbruster qobj = qdict_get(qdict, "integer"); 26428770e05SMarkus Armbruster g_assert(qobj); 26528770e05SMarkus Armbruster qint = qobject_to_qint(qobj); 26628770e05SMarkus Armbruster g_assert(qint); 26728770e05SMarkus Armbruster g_assert_cmpint(qint_get_int(qint), ==, -42); 26828770e05SMarkus Armbruster qobj = qdict_get(qdict, "boolean"); 26928770e05SMarkus Armbruster g_assert(qobj); 27028770e05SMarkus Armbruster qbool = qobject_to_qbool(qobj); 27128770e05SMarkus Armbruster g_assert(qbool); 27228770e05SMarkus Armbruster g_assert(qbool_get_bool(qbool) == true); 27328770e05SMarkus Armbruster qobj = qdict_get(qdict, "string"); 27428770e05SMarkus Armbruster g_assert(qobj); 27528770e05SMarkus Armbruster qstring = qobject_to_qstring(qobj); 27628770e05SMarkus Armbruster g_assert(qstring); 27728770e05SMarkus Armbruster g_assert_cmpstr(qstring_get_str(qstring), ==, "foo"); 27828770e05SMarkus Armbruster qobject_decref(res); 27928770e05SMarkus Armbruster } 28028770e05SMarkus Armbruster 2813df016f1SEric Blake static void test_visitor_in_null(TestInputVisitorData *data, 2823df016f1SEric Blake const void *unused) 2833df016f1SEric Blake { 2843df016f1SEric Blake Visitor *v; 2853df016f1SEric Blake Error *err = NULL; 2863df016f1SEric Blake char *tmp; 2873df016f1SEric Blake 2883df016f1SEric Blake /* 2893df016f1SEric Blake * FIXME: Since QAPI doesn't know the 'null' type yet, we can't 2903df016f1SEric Blake * test visit_type_null() by reading into a QAPI struct then 2913df016f1SEric Blake * checking that it was populated correctly. The best we can do 2923df016f1SEric Blake * for now is ensure that we consumed null from the input, proven 2933df016f1SEric Blake * by the fact that we can't re-read the key; and that we detect 2943df016f1SEric Blake * when input is not null. 2953df016f1SEric Blake */ 2963df016f1SEric Blake 2973df016f1SEric Blake v = visitor_input_test_init(data, "{ 'a': null, 'b': '' }"); 2983df016f1SEric Blake visit_start_struct(v, NULL, NULL, 0, &error_abort); 2993df016f1SEric Blake visit_type_null(v, "a", &error_abort); 3003df016f1SEric Blake visit_type_str(v, "a", &tmp, &err); 3013df016f1SEric Blake g_assert(!tmp); 3023df016f1SEric Blake error_free_or_abort(&err); 3033df016f1SEric Blake visit_type_null(v, "b", &err); 3043df016f1SEric Blake error_free_or_abort(&err); 30515c2f669SEric Blake visit_check_struct(v, &error_abort); 30615c2f669SEric Blake visit_end_struct(v); 3073df016f1SEric Blake } 3083df016f1SEric Blake 3092fc00432SMarkus Armbruster static void test_visitor_in_union_flat(TestInputVisitorData *data, 3102fc00432SMarkus Armbruster const void *unused) 3112fc00432SMarkus Armbruster { 3122fc00432SMarkus Armbruster Visitor *v; 3132fc00432SMarkus Armbruster UserDefFlatUnion *tmp; 31430594fe1SEric Blake UserDefUnionBase *base; 3152fc00432SMarkus Armbruster 3165223070cSWenchao Xia v = visitor_input_test_init(data, 3175223070cSWenchao Xia "{ 'enum1': 'value1', " 318441cbac0SMarkus Armbruster "'integer': 41, " 3195223070cSWenchao Xia "'string': 'str', " 3205223070cSWenchao Xia "'boolean': true }"); 3212fc00432SMarkus Armbruster 32251e72bc1SEric Blake visit_type_UserDefFlatUnion(v, NULL, &tmp, &error_abort); 3230f61af3eSMarkus Armbruster g_assert_cmpint(tmp->enum1, ==, ENUM_ONE_VALUE1); 3245223070cSWenchao Xia g_assert_cmpstr(tmp->string, ==, "str"); 325441cbac0SMarkus Armbruster g_assert_cmpint(tmp->integer, ==, 41); 326544a3731SEric Blake g_assert_cmpint(tmp->u.value1.boolean, ==, true); 32730594fe1SEric Blake 32830594fe1SEric Blake base = qapi_UserDefFlatUnion_base(tmp); 32930594fe1SEric Blake g_assert(&base->enum1 == &tmp->enum1); 33030594fe1SEric Blake 3312fc00432SMarkus Armbruster qapi_free_UserDefFlatUnion(tmp); 3322fc00432SMarkus Armbruster } 3332fc00432SMarkus Armbruster 334ab045267SEric Blake static void test_visitor_in_alternate(TestInputVisitorData *data, 3352c38b600SMarkus Armbruster const void *unused) 3362c38b600SMarkus Armbruster { 3372c38b600SMarkus Armbruster Visitor *v; 3382c38b600SMarkus Armbruster Error *err = NULL; 339ab045267SEric Blake UserDefAlternate *tmp; 34068d07839SEric Blake WrapAlternate *wrap; 3412c38b600SMarkus Armbruster 3422c38b600SMarkus Armbruster v = visitor_input_test_init(data, "42"); 34351e72bc1SEric Blake visit_type_UserDefAlternate(v, NULL, &tmp, &error_abort); 3440426d53cSEric Blake g_assert_cmpint(tmp->type, ==, QTYPE_QINT); 345c363acefSEric Blake g_assert_cmpint(tmp->u.i, ==, 42); 346ab045267SEric Blake qapi_free_UserDefAlternate(tmp); 3479c51b441SEric Blake 3489c51b441SEric Blake v = visitor_input_test_init(data, "'string'"); 34951e72bc1SEric Blake visit_type_UserDefAlternate(v, NULL, &tmp, &error_abort); 3500426d53cSEric Blake g_assert_cmpint(tmp->type, ==, QTYPE_QSTRING); 351c363acefSEric Blake g_assert_cmpstr(tmp->u.s, ==, "string"); 3529c51b441SEric Blake qapi_free_UserDefAlternate(tmp); 3539c51b441SEric Blake 35468d07839SEric Blake v = visitor_input_test_init(data, "{'integer':1, 'string':'str', " 35568d07839SEric Blake "'enum1':'value1', 'boolean':true}"); 35668d07839SEric Blake visit_type_UserDefAlternate(v, NULL, &tmp, &error_abort); 35768d07839SEric Blake g_assert_cmpint(tmp->type, ==, QTYPE_QDICT); 358becceedcSEric Blake g_assert_cmpint(tmp->u.udfu.integer, ==, 1); 359becceedcSEric Blake g_assert_cmpstr(tmp->u.udfu.string, ==, "str"); 360becceedcSEric Blake g_assert_cmpint(tmp->u.udfu.enum1, ==, ENUM_ONE_VALUE1); 361544a3731SEric Blake g_assert_cmpint(tmp->u.udfu.u.value1.boolean, ==, true); 362544a3731SEric Blake g_assert_cmpint(tmp->u.udfu.u.value1.has_a_b, ==, false); 36368d07839SEric Blake qapi_free_UserDefAlternate(tmp); 36468d07839SEric Blake 3659c51b441SEric Blake v = visitor_input_test_init(data, "false"); 36651e72bc1SEric Blake visit_type_UserDefAlternate(v, NULL, &tmp, &err); 367a12a5a1aSEric Blake error_free_or_abort(&err); 3689c51b441SEric Blake qapi_free_UserDefAlternate(tmp); 36968d07839SEric Blake 37068d07839SEric Blake v = visitor_input_test_init(data, "{ 'alt': 42 }"); 37168d07839SEric Blake visit_type_WrapAlternate(v, NULL, &wrap, &error_abort); 37268d07839SEric Blake g_assert_cmpint(wrap->alt->type, ==, QTYPE_QINT); 37368d07839SEric Blake g_assert_cmpint(wrap->alt->u.i, ==, 42); 37468d07839SEric Blake qapi_free_WrapAlternate(wrap); 37568d07839SEric Blake 37668d07839SEric Blake v = visitor_input_test_init(data, "{ 'alt': 'string' }"); 37768d07839SEric Blake visit_type_WrapAlternate(v, NULL, &wrap, &error_abort); 37868d07839SEric Blake g_assert_cmpint(wrap->alt->type, ==, QTYPE_QSTRING); 37968d07839SEric Blake g_assert_cmpstr(wrap->alt->u.s, ==, "string"); 38068d07839SEric Blake qapi_free_WrapAlternate(wrap); 38168d07839SEric Blake 38268d07839SEric Blake v = visitor_input_test_init(data, "{ 'alt': {'integer':1, 'string':'str', " 38368d07839SEric Blake "'enum1':'value1', 'boolean':true} }"); 38468d07839SEric Blake visit_type_WrapAlternate(v, NULL, &wrap, &error_abort); 38568d07839SEric Blake g_assert_cmpint(wrap->alt->type, ==, QTYPE_QDICT); 386becceedcSEric Blake g_assert_cmpint(wrap->alt->u.udfu.integer, ==, 1); 387becceedcSEric Blake g_assert_cmpstr(wrap->alt->u.udfu.string, ==, "str"); 388becceedcSEric Blake g_assert_cmpint(wrap->alt->u.udfu.enum1, ==, ENUM_ONE_VALUE1); 389544a3731SEric Blake g_assert_cmpint(wrap->alt->u.udfu.u.value1.boolean, ==, true); 390544a3731SEric Blake g_assert_cmpint(wrap->alt->u.udfu.u.value1.has_a_b, ==, false); 39168d07839SEric Blake qapi_free_WrapAlternate(wrap); 3929c51b441SEric Blake } 3939c51b441SEric Blake 3949c51b441SEric Blake static void test_visitor_in_alternate_number(TestInputVisitorData *data, 3959c51b441SEric Blake const void *unused) 3969c51b441SEric Blake { 3979c51b441SEric Blake Visitor *v; 3989c51b441SEric Blake Error *err = NULL; 3999c51b441SEric Blake AltStrBool *asb; 4009c51b441SEric Blake AltStrNum *asn; 4019c51b441SEric Blake AltNumStr *ans; 4029c51b441SEric Blake AltStrInt *asi; 4039c51b441SEric Blake AltIntNum *ain; 4049c51b441SEric Blake AltNumInt *ani; 4059c51b441SEric Blake 4069c51b441SEric Blake /* Parsing an int */ 4079c51b441SEric Blake 4089c51b441SEric Blake v = visitor_input_test_init(data, "42"); 40951e72bc1SEric Blake visit_type_AltStrBool(v, NULL, &asb, &err); 410a12a5a1aSEric Blake error_free_or_abort(&err); 4119c51b441SEric Blake qapi_free_AltStrBool(asb); 4129c51b441SEric Blake 4139c51b441SEric Blake v = visitor_input_test_init(data, "42"); 41451e72bc1SEric Blake visit_type_AltStrNum(v, NULL, &asn, &error_abort); 415d00341afSEric Blake g_assert_cmpint(asn->type, ==, QTYPE_QFLOAT); 416d00341afSEric Blake g_assert_cmpfloat(asn->u.n, ==, 42); 4179c51b441SEric Blake qapi_free_AltStrNum(asn); 4189c51b441SEric Blake 4199c51b441SEric Blake v = visitor_input_test_init(data, "42"); 42051e72bc1SEric Blake visit_type_AltNumStr(v, NULL, &ans, &error_abort); 421d00341afSEric Blake g_assert_cmpint(ans->type, ==, QTYPE_QFLOAT); 422d00341afSEric Blake g_assert_cmpfloat(ans->u.n, ==, 42); 4239c51b441SEric Blake qapi_free_AltNumStr(ans); 4249c51b441SEric Blake 4259c51b441SEric Blake v = visitor_input_test_init(data, "42"); 42651e72bc1SEric Blake visit_type_AltStrInt(v, NULL, &asi, &error_abort); 4270426d53cSEric Blake g_assert_cmpint(asi->type, ==, QTYPE_QINT); 428c363acefSEric Blake g_assert_cmpint(asi->u.i, ==, 42); 4299c51b441SEric Blake qapi_free_AltStrInt(asi); 4309c51b441SEric Blake 4319c51b441SEric Blake v = visitor_input_test_init(data, "42"); 43251e72bc1SEric Blake visit_type_AltIntNum(v, NULL, &ain, &error_abort); 4330426d53cSEric Blake g_assert_cmpint(ain->type, ==, QTYPE_QINT); 434c363acefSEric Blake g_assert_cmpint(ain->u.i, ==, 42); 4359c51b441SEric Blake qapi_free_AltIntNum(ain); 4369c51b441SEric Blake 4379c51b441SEric Blake v = visitor_input_test_init(data, "42"); 43851e72bc1SEric Blake visit_type_AltNumInt(v, NULL, &ani, &error_abort); 4390426d53cSEric Blake g_assert_cmpint(ani->type, ==, QTYPE_QINT); 440c363acefSEric Blake g_assert_cmpint(ani->u.i, ==, 42); 4419c51b441SEric Blake qapi_free_AltNumInt(ani); 4429c51b441SEric Blake 4439c51b441SEric Blake /* Parsing a double */ 4449c51b441SEric Blake 4459c51b441SEric Blake v = visitor_input_test_init(data, "42.5"); 44651e72bc1SEric Blake visit_type_AltStrBool(v, NULL, &asb, &err); 447a12a5a1aSEric Blake error_free_or_abort(&err); 4489c51b441SEric Blake qapi_free_AltStrBool(asb); 4499c51b441SEric Blake 4509c51b441SEric Blake v = visitor_input_test_init(data, "42.5"); 45151e72bc1SEric Blake visit_type_AltStrNum(v, NULL, &asn, &error_abort); 4520426d53cSEric Blake g_assert_cmpint(asn->type, ==, QTYPE_QFLOAT); 453c363acefSEric Blake g_assert_cmpfloat(asn->u.n, ==, 42.5); 4549c51b441SEric Blake qapi_free_AltStrNum(asn); 4559c51b441SEric Blake 4569c51b441SEric Blake v = visitor_input_test_init(data, "42.5"); 45751e72bc1SEric Blake visit_type_AltNumStr(v, NULL, &ans, &error_abort); 4580426d53cSEric Blake g_assert_cmpint(ans->type, ==, QTYPE_QFLOAT); 459c363acefSEric Blake g_assert_cmpfloat(ans->u.n, ==, 42.5); 4609c51b441SEric Blake qapi_free_AltNumStr(ans); 4619c51b441SEric Blake 4629c51b441SEric Blake v = visitor_input_test_init(data, "42.5"); 46351e72bc1SEric Blake visit_type_AltStrInt(v, NULL, &asi, &err); 464a12a5a1aSEric Blake error_free_or_abort(&err); 4659c51b441SEric Blake qapi_free_AltStrInt(asi); 4669c51b441SEric Blake 4679c51b441SEric Blake v = visitor_input_test_init(data, "42.5"); 46851e72bc1SEric Blake visit_type_AltIntNum(v, NULL, &ain, &error_abort); 4690426d53cSEric Blake g_assert_cmpint(ain->type, ==, QTYPE_QFLOAT); 470c363acefSEric Blake g_assert_cmpfloat(ain->u.n, ==, 42.5); 4719c51b441SEric Blake qapi_free_AltIntNum(ain); 4729c51b441SEric Blake 4739c51b441SEric Blake v = visitor_input_test_init(data, "42.5"); 47451e72bc1SEric Blake visit_type_AltNumInt(v, NULL, &ani, &error_abort); 4750426d53cSEric Blake g_assert_cmpint(ani->type, ==, QTYPE_QFLOAT); 476c363acefSEric Blake g_assert_cmpfloat(ani->u.n, ==, 42.5); 4779c51b441SEric Blake qapi_free_AltNumInt(ani); 4782c38b600SMarkus Armbruster } 4792c38b600SMarkus Armbruster 480199e0f17SMichael Roth static void test_native_list_integer_helper(TestInputVisitorData *data, 481199e0f17SMichael Roth const void *unused, 482199e0f17SMichael Roth UserDefNativeListUnionKind kind) 483199e0f17SMichael Roth { 484199e0f17SMichael Roth UserDefNativeListUnion *cvalue = NULL; 485199e0f17SMichael Roth Visitor *v; 486199e0f17SMichael Roth GString *gstr_list = g_string_new(""); 487199e0f17SMichael Roth GString *gstr_union = g_string_new(""); 488199e0f17SMichael Roth int i; 489199e0f17SMichael Roth 490199e0f17SMichael Roth for (i = 0; i < 32; i++) { 491199e0f17SMichael Roth g_string_append_printf(gstr_list, "%d", i); 492199e0f17SMichael Roth if (i != 31) { 493199e0f17SMichael Roth g_string_append(gstr_list, ", "); 494199e0f17SMichael Roth } 495199e0f17SMichael Roth } 496199e0f17SMichael Roth g_string_append_printf(gstr_union, "{ 'type': '%s', 'data': [ %s ] }", 497199e0f17SMichael Roth UserDefNativeListUnionKind_lookup[kind], 498199e0f17SMichael Roth gstr_list->str); 499199e0f17SMichael Roth v = visitor_input_test_init_raw(data, gstr_union->str); 500199e0f17SMichael Roth 50151e72bc1SEric Blake visit_type_UserDefNativeListUnion(v, NULL, &cvalue, &error_abort); 502199e0f17SMichael Roth g_assert(cvalue != NULL); 503c363acefSEric Blake g_assert_cmpint(cvalue->type, ==, kind); 504199e0f17SMichael Roth 505199e0f17SMichael Roth switch (kind) { 506199e0f17SMichael Roth case USER_DEF_NATIVE_LIST_UNION_KIND_INTEGER: { 507199e0f17SMichael Roth intList *elem = NULL; 50832bafa8fSEric Blake for (i = 0, elem = cvalue->u.integer.data; 50932bafa8fSEric Blake elem; elem = elem->next, i++) { 510199e0f17SMichael Roth g_assert_cmpint(elem->value, ==, i); 511199e0f17SMichael Roth } 512199e0f17SMichael Roth break; 513199e0f17SMichael Roth } 514199e0f17SMichael Roth case USER_DEF_NATIVE_LIST_UNION_KIND_S8: { 515199e0f17SMichael Roth int8List *elem = NULL; 51632bafa8fSEric Blake for (i = 0, elem = cvalue->u.s8.data; elem; elem = elem->next, i++) { 517199e0f17SMichael Roth g_assert_cmpint(elem->value, ==, i); 518199e0f17SMichael Roth } 519199e0f17SMichael Roth break; 520199e0f17SMichael Roth } 521199e0f17SMichael Roth case USER_DEF_NATIVE_LIST_UNION_KIND_S16: { 522199e0f17SMichael Roth int16List *elem = NULL; 52332bafa8fSEric Blake for (i = 0, elem = cvalue->u.s16.data; elem; elem = elem->next, i++) { 524199e0f17SMichael Roth g_assert_cmpint(elem->value, ==, i); 525199e0f17SMichael Roth } 526199e0f17SMichael Roth break; 527199e0f17SMichael Roth } 528199e0f17SMichael Roth case USER_DEF_NATIVE_LIST_UNION_KIND_S32: { 529199e0f17SMichael Roth int32List *elem = NULL; 53032bafa8fSEric Blake for (i = 0, elem = cvalue->u.s32.data; elem; elem = elem->next, i++) { 531199e0f17SMichael Roth g_assert_cmpint(elem->value, ==, i); 532199e0f17SMichael Roth } 533199e0f17SMichael Roth break; 534199e0f17SMichael Roth } 535199e0f17SMichael Roth case USER_DEF_NATIVE_LIST_UNION_KIND_S64: { 536199e0f17SMichael Roth int64List *elem = NULL; 53732bafa8fSEric Blake for (i = 0, elem = cvalue->u.s64.data; elem; elem = elem->next, i++) { 538199e0f17SMichael Roth g_assert_cmpint(elem->value, ==, i); 539199e0f17SMichael Roth } 540199e0f17SMichael Roth break; 541199e0f17SMichael Roth } 542199e0f17SMichael Roth case USER_DEF_NATIVE_LIST_UNION_KIND_U8: { 543199e0f17SMichael Roth uint8List *elem = NULL; 54432bafa8fSEric Blake for (i = 0, elem = cvalue->u.u8.data; elem; elem = elem->next, i++) { 545199e0f17SMichael Roth g_assert_cmpint(elem->value, ==, i); 546199e0f17SMichael Roth } 547199e0f17SMichael Roth break; 548199e0f17SMichael Roth } 549199e0f17SMichael Roth case USER_DEF_NATIVE_LIST_UNION_KIND_U16: { 550199e0f17SMichael Roth uint16List *elem = NULL; 55132bafa8fSEric Blake for (i = 0, elem = cvalue->u.u16.data; elem; elem = elem->next, i++) { 552199e0f17SMichael Roth g_assert_cmpint(elem->value, ==, i); 553199e0f17SMichael Roth } 554199e0f17SMichael Roth break; 555199e0f17SMichael Roth } 556199e0f17SMichael Roth case USER_DEF_NATIVE_LIST_UNION_KIND_U32: { 557199e0f17SMichael Roth uint32List *elem = NULL; 55832bafa8fSEric Blake for (i = 0, elem = cvalue->u.u32.data; elem; elem = elem->next, i++) { 559199e0f17SMichael Roth g_assert_cmpint(elem->value, ==, i); 560199e0f17SMichael Roth } 561199e0f17SMichael Roth break; 562199e0f17SMichael Roth } 563199e0f17SMichael Roth case USER_DEF_NATIVE_LIST_UNION_KIND_U64: { 564199e0f17SMichael Roth uint64List *elem = NULL; 56532bafa8fSEric Blake for (i = 0, elem = cvalue->u.u64.data; elem; elem = elem->next, i++) { 566199e0f17SMichael Roth g_assert_cmpint(elem->value, ==, i); 567199e0f17SMichael Roth } 568199e0f17SMichael Roth break; 569199e0f17SMichael Roth } 570199e0f17SMichael Roth default: 571dfc6f865SStefan Weil g_assert_not_reached(); 572199e0f17SMichael Roth } 573199e0f17SMichael Roth 574199e0f17SMichael Roth g_string_free(gstr_union, true); 575199e0f17SMichael Roth g_string_free(gstr_list, true); 576199e0f17SMichael Roth qapi_free_UserDefNativeListUnion(cvalue); 577199e0f17SMichael Roth } 578199e0f17SMichael Roth 579199e0f17SMichael Roth static void test_visitor_in_native_list_int(TestInputVisitorData *data, 580199e0f17SMichael Roth const void *unused) 581199e0f17SMichael Roth { 582199e0f17SMichael Roth test_native_list_integer_helper(data, unused, 583199e0f17SMichael Roth USER_DEF_NATIVE_LIST_UNION_KIND_INTEGER); 584199e0f17SMichael Roth } 585199e0f17SMichael Roth 586199e0f17SMichael Roth static void test_visitor_in_native_list_int8(TestInputVisitorData *data, 587199e0f17SMichael Roth const void *unused) 588199e0f17SMichael Roth { 589199e0f17SMichael Roth test_native_list_integer_helper(data, unused, 590199e0f17SMichael Roth USER_DEF_NATIVE_LIST_UNION_KIND_S8); 591199e0f17SMichael Roth } 592199e0f17SMichael Roth 593199e0f17SMichael Roth static void test_visitor_in_native_list_int16(TestInputVisitorData *data, 594199e0f17SMichael Roth const void *unused) 595199e0f17SMichael Roth { 596199e0f17SMichael Roth test_native_list_integer_helper(data, unused, 597199e0f17SMichael Roth USER_DEF_NATIVE_LIST_UNION_KIND_S16); 598199e0f17SMichael Roth } 599199e0f17SMichael Roth 600199e0f17SMichael Roth static void test_visitor_in_native_list_int32(TestInputVisitorData *data, 601199e0f17SMichael Roth const void *unused) 602199e0f17SMichael Roth { 603199e0f17SMichael Roth test_native_list_integer_helper(data, unused, 604199e0f17SMichael Roth USER_DEF_NATIVE_LIST_UNION_KIND_S32); 605199e0f17SMichael Roth } 606199e0f17SMichael Roth 607199e0f17SMichael Roth static void test_visitor_in_native_list_int64(TestInputVisitorData *data, 608199e0f17SMichael Roth const void *unused) 609199e0f17SMichael Roth { 610199e0f17SMichael Roth test_native_list_integer_helper(data, unused, 611199e0f17SMichael Roth USER_DEF_NATIVE_LIST_UNION_KIND_S64); 612199e0f17SMichael Roth } 613199e0f17SMichael Roth 614199e0f17SMichael Roth static void test_visitor_in_native_list_uint8(TestInputVisitorData *data, 615199e0f17SMichael Roth const void *unused) 616199e0f17SMichael Roth { 617199e0f17SMichael Roth test_native_list_integer_helper(data, unused, 618199e0f17SMichael Roth USER_DEF_NATIVE_LIST_UNION_KIND_U8); 619199e0f17SMichael Roth } 620199e0f17SMichael Roth 621199e0f17SMichael Roth static void test_visitor_in_native_list_uint16(TestInputVisitorData *data, 622199e0f17SMichael Roth const void *unused) 623199e0f17SMichael Roth { 624199e0f17SMichael Roth test_native_list_integer_helper(data, unused, 625199e0f17SMichael Roth USER_DEF_NATIVE_LIST_UNION_KIND_U16); 626199e0f17SMichael Roth } 627199e0f17SMichael Roth 628199e0f17SMichael Roth static void test_visitor_in_native_list_uint32(TestInputVisitorData *data, 629199e0f17SMichael Roth const void *unused) 630199e0f17SMichael Roth { 631199e0f17SMichael Roth test_native_list_integer_helper(data, unused, 632199e0f17SMichael Roth USER_DEF_NATIVE_LIST_UNION_KIND_U32); 633199e0f17SMichael Roth } 634199e0f17SMichael Roth 635199e0f17SMichael Roth static void test_visitor_in_native_list_uint64(TestInputVisitorData *data, 636199e0f17SMichael Roth const void *unused) 637199e0f17SMichael Roth { 638199e0f17SMichael Roth test_native_list_integer_helper(data, unused, 639199e0f17SMichael Roth USER_DEF_NATIVE_LIST_UNION_KIND_U64); 640199e0f17SMichael Roth } 641199e0f17SMichael Roth 642199e0f17SMichael Roth static void test_visitor_in_native_list_bool(TestInputVisitorData *data, 643199e0f17SMichael Roth const void *unused) 644199e0f17SMichael Roth { 645199e0f17SMichael Roth UserDefNativeListUnion *cvalue = NULL; 646199e0f17SMichael Roth boolList *elem = NULL; 647199e0f17SMichael Roth Visitor *v; 648199e0f17SMichael Roth GString *gstr_list = g_string_new(""); 649199e0f17SMichael Roth GString *gstr_union = g_string_new(""); 650199e0f17SMichael Roth int i; 651199e0f17SMichael Roth 652199e0f17SMichael Roth for (i = 0; i < 32; i++) { 653199e0f17SMichael Roth g_string_append_printf(gstr_list, "%s", 654199e0f17SMichael Roth (i % 3 == 0) ? "true" : "false"); 655199e0f17SMichael Roth if (i != 31) { 656199e0f17SMichael Roth g_string_append(gstr_list, ", "); 657199e0f17SMichael Roth } 658199e0f17SMichael Roth } 659199e0f17SMichael Roth g_string_append_printf(gstr_union, "{ 'type': 'boolean', 'data': [ %s ] }", 660199e0f17SMichael Roth gstr_list->str); 661199e0f17SMichael Roth v = visitor_input_test_init_raw(data, gstr_union->str); 662199e0f17SMichael Roth 66351e72bc1SEric Blake visit_type_UserDefNativeListUnion(v, NULL, &cvalue, &error_abort); 664199e0f17SMichael Roth g_assert(cvalue != NULL); 665c363acefSEric Blake g_assert_cmpint(cvalue->type, ==, USER_DEF_NATIVE_LIST_UNION_KIND_BOOLEAN); 666199e0f17SMichael Roth 66732bafa8fSEric Blake for (i = 0, elem = cvalue->u.boolean.data; elem; elem = elem->next, i++) { 668199e0f17SMichael Roth g_assert_cmpint(elem->value, ==, (i % 3 == 0) ? 1 : 0); 669199e0f17SMichael Roth } 670199e0f17SMichael Roth 671199e0f17SMichael Roth g_string_free(gstr_union, true); 672199e0f17SMichael Roth g_string_free(gstr_list, true); 673199e0f17SMichael Roth qapi_free_UserDefNativeListUnion(cvalue); 674199e0f17SMichael Roth } 675199e0f17SMichael Roth 676199e0f17SMichael Roth static void test_visitor_in_native_list_string(TestInputVisitorData *data, 677199e0f17SMichael Roth const void *unused) 678199e0f17SMichael Roth { 679199e0f17SMichael Roth UserDefNativeListUnion *cvalue = NULL; 680199e0f17SMichael Roth strList *elem = NULL; 681199e0f17SMichael Roth Visitor *v; 682199e0f17SMichael Roth GString *gstr_list = g_string_new(""); 683199e0f17SMichael Roth GString *gstr_union = g_string_new(""); 684199e0f17SMichael Roth int i; 685199e0f17SMichael Roth 686199e0f17SMichael Roth for (i = 0; i < 32; i++) { 687199e0f17SMichael Roth g_string_append_printf(gstr_list, "'%d'", i); 688199e0f17SMichael Roth if (i != 31) { 689199e0f17SMichael Roth g_string_append(gstr_list, ", "); 690199e0f17SMichael Roth } 691199e0f17SMichael Roth } 692199e0f17SMichael Roth g_string_append_printf(gstr_union, "{ 'type': 'string', 'data': [ %s ] }", 693199e0f17SMichael Roth gstr_list->str); 694199e0f17SMichael Roth v = visitor_input_test_init_raw(data, gstr_union->str); 695199e0f17SMichael Roth 69651e72bc1SEric Blake visit_type_UserDefNativeListUnion(v, NULL, &cvalue, &error_abort); 697199e0f17SMichael Roth g_assert(cvalue != NULL); 698c363acefSEric Blake g_assert_cmpint(cvalue->type, ==, USER_DEF_NATIVE_LIST_UNION_KIND_STRING); 699199e0f17SMichael Roth 70032bafa8fSEric Blake for (i = 0, elem = cvalue->u.string.data; elem; elem = elem->next, i++) { 701199e0f17SMichael Roth gchar str[8]; 702199e0f17SMichael Roth sprintf(str, "%d", i); 703199e0f17SMichael Roth g_assert_cmpstr(elem->value, ==, str); 704199e0f17SMichael Roth } 705199e0f17SMichael Roth 706199e0f17SMichael Roth g_string_free(gstr_union, true); 707199e0f17SMichael Roth g_string_free(gstr_list, true); 708199e0f17SMichael Roth qapi_free_UserDefNativeListUnion(cvalue); 709199e0f17SMichael Roth } 710199e0f17SMichael Roth 711199e0f17SMichael Roth #define DOUBLE_STR_MAX 16 712199e0f17SMichael Roth 713199e0f17SMichael Roth static void test_visitor_in_native_list_number(TestInputVisitorData *data, 714199e0f17SMichael Roth const void *unused) 715199e0f17SMichael Roth { 716199e0f17SMichael Roth UserDefNativeListUnion *cvalue = NULL; 717199e0f17SMichael Roth numberList *elem = NULL; 718199e0f17SMichael Roth Visitor *v; 719199e0f17SMichael Roth GString *gstr_list = g_string_new(""); 720199e0f17SMichael Roth GString *gstr_union = g_string_new(""); 721199e0f17SMichael Roth int i; 722199e0f17SMichael Roth 723199e0f17SMichael Roth for (i = 0; i < 32; i++) { 724199e0f17SMichael Roth g_string_append_printf(gstr_list, "%f", (double)i / 3); 725199e0f17SMichael Roth if (i != 31) { 726199e0f17SMichael Roth g_string_append(gstr_list, ", "); 727199e0f17SMichael Roth } 728199e0f17SMichael Roth } 729199e0f17SMichael Roth g_string_append_printf(gstr_union, "{ 'type': 'number', 'data': [ %s ] }", 730199e0f17SMichael Roth gstr_list->str); 731199e0f17SMichael Roth v = visitor_input_test_init_raw(data, gstr_union->str); 732199e0f17SMichael Roth 73351e72bc1SEric Blake visit_type_UserDefNativeListUnion(v, NULL, &cvalue, &error_abort); 734199e0f17SMichael Roth g_assert(cvalue != NULL); 735c363acefSEric Blake g_assert_cmpint(cvalue->type, ==, USER_DEF_NATIVE_LIST_UNION_KIND_NUMBER); 736199e0f17SMichael Roth 73732bafa8fSEric Blake for (i = 0, elem = cvalue->u.number.data; elem; elem = elem->next, i++) { 738199e0f17SMichael Roth GString *double_expected = g_string_new(""); 739199e0f17SMichael Roth GString *double_actual = g_string_new(""); 740199e0f17SMichael Roth 741199e0f17SMichael Roth g_string_printf(double_expected, "%.6f", (double)i / 3); 742199e0f17SMichael Roth g_string_printf(double_actual, "%.6f", elem->value); 743199e0f17SMichael Roth g_assert_cmpstr(double_expected->str, ==, double_actual->str); 744199e0f17SMichael Roth 745199e0f17SMichael Roth g_string_free(double_expected, true); 746199e0f17SMichael Roth g_string_free(double_actual, true); 747199e0f17SMichael Roth } 748199e0f17SMichael Roth 749199e0f17SMichael Roth g_string_free(gstr_union, true); 750199e0f17SMichael Roth g_string_free(gstr_list, true); 751199e0f17SMichael Roth qapi_free_UserDefNativeListUnion(cvalue); 752199e0f17SMichael Roth } 753199e0f17SMichael Roth 754d88f5fd1SLuiz Capitulino static void input_visitor_test_add(const char *testpath, 755d88f5fd1SLuiz Capitulino TestInputVisitorData *data, 756d88f5fd1SLuiz Capitulino void (*test_func)(TestInputVisitorData *data, const void *user_data)) 757d88f5fd1SLuiz Capitulino { 758d88f5fd1SLuiz Capitulino g_test_add(testpath, TestInputVisitorData, data, NULL, test_func, 759d88f5fd1SLuiz Capitulino visitor_input_teardown); 760d88f5fd1SLuiz Capitulino } 761d88f5fd1SLuiz Capitulino 7623dcf71f6SPaolo Bonzini static void test_visitor_in_errors(TestInputVisitorData *data, 7633dcf71f6SPaolo Bonzini const void *unused) 7643dcf71f6SPaolo Bonzini { 7653dcf71f6SPaolo Bonzini TestStruct *p = NULL; 766e940f543SMarkus Armbruster Error *err = NULL; 7673dcf71f6SPaolo Bonzini Visitor *v; 768dd5ee2c2SEric Blake strList *q = NULL; 7699b4e38feSEric Blake UserDefTwo *r = NULL; 7709b4e38feSEric Blake WrapAlternate *s = NULL; 7713dcf71f6SPaolo Bonzini 772dd5ee2c2SEric Blake v = visitor_input_test_init(data, "{ 'integer': false, 'boolean': 'foo', " 773dd5ee2c2SEric Blake "'string': -42 }"); 7743dcf71f6SPaolo Bonzini 77551e72bc1SEric Blake visit_type_TestStruct(v, NULL, &p, &err); 776a12a5a1aSEric Blake error_free_or_abort(&err); 77768ab47e4SEric Blake g_assert(!p); 778dd5ee2c2SEric Blake 779dd5ee2c2SEric Blake v = visitor_input_test_init(data, "[ '1', '2', false, '3' ]"); 78051e72bc1SEric Blake visit_type_strList(v, NULL, &q, &err); 781dd5ee2c2SEric Blake error_free_or_abort(&err); 78268ab47e4SEric Blake assert(!q); 7839b4e38feSEric Blake 7849b4e38feSEric Blake v = visitor_input_test_init(data, "{ 'str':'hi' }"); 7859b4e38feSEric Blake visit_type_UserDefTwo(v, NULL, &r, &err); 7869b4e38feSEric Blake error_free_or_abort(&err); 7879b4e38feSEric Blake assert(!r); 7889b4e38feSEric Blake 7899b4e38feSEric Blake v = visitor_input_test_init(data, "{ }"); 7909b4e38feSEric Blake visit_type_WrapAlternate(v, NULL, &s, &err); 7919b4e38feSEric Blake error_free_or_abort(&err); 7929b4e38feSEric Blake assert(!s); 7933dcf71f6SPaolo Bonzini } 7943dcf71f6SPaolo Bonzini 7952533377cSEric Blake static void test_visitor_in_wrong_type(TestInputVisitorData *data, 7962533377cSEric Blake const void *unused) 7972533377cSEric Blake { 7982533377cSEric Blake TestStruct *p = NULL; 7992533377cSEric Blake Visitor *v; 8002533377cSEric Blake strList *q = NULL; 8012533377cSEric Blake int64_t i; 8022533377cSEric Blake Error *err = NULL; 8032533377cSEric Blake 8042533377cSEric Blake /* Make sure arrays and structs cannot be confused */ 8052533377cSEric Blake 8062533377cSEric Blake v = visitor_input_test_init(data, "[]"); 80751e72bc1SEric Blake visit_type_TestStruct(v, NULL, &p, &err); 8082533377cSEric Blake error_free_or_abort(&err); 8092533377cSEric Blake g_assert(!p); 8102533377cSEric Blake 8112533377cSEric Blake v = visitor_input_test_init(data, "{}"); 81251e72bc1SEric Blake visit_type_strList(v, NULL, &q, &err); 8132533377cSEric Blake error_free_or_abort(&err); 8142533377cSEric Blake assert(!q); 8152533377cSEric Blake 8162533377cSEric Blake /* Make sure primitives and struct cannot be confused */ 8172533377cSEric Blake 8182533377cSEric Blake v = visitor_input_test_init(data, "1"); 81951e72bc1SEric Blake visit_type_TestStruct(v, NULL, &p, &err); 8202533377cSEric Blake error_free_or_abort(&err); 8212533377cSEric Blake g_assert(!p); 8222533377cSEric Blake 8232533377cSEric Blake v = visitor_input_test_init(data, "{}"); 82451e72bc1SEric Blake visit_type_int(v, NULL, &i, &err); 8252533377cSEric Blake error_free_or_abort(&err); 8262533377cSEric Blake 8272533377cSEric Blake /* Make sure primitives and arrays cannot be confused */ 8282533377cSEric Blake 8292533377cSEric Blake v = visitor_input_test_init(data, "1"); 83051e72bc1SEric Blake visit_type_strList(v, NULL, &q, &err); 8312533377cSEric Blake error_free_or_abort(&err); 8322533377cSEric Blake assert(!q); 8332533377cSEric Blake 8342533377cSEric Blake v = visitor_input_test_init(data, "[]"); 83551e72bc1SEric Blake visit_type_int(v, NULL, &i, &err); 8362533377cSEric Blake error_free_or_abort(&err); 8372533377cSEric Blake } 8382533377cSEric Blake 839d88f5fd1SLuiz Capitulino int main(int argc, char **argv) 840d88f5fd1SLuiz Capitulino { 841d88f5fd1SLuiz Capitulino TestInputVisitorData in_visitor_data; 842d88f5fd1SLuiz Capitulino 843d88f5fd1SLuiz Capitulino g_test_init(&argc, &argv, NULL); 844d88f5fd1SLuiz Capitulino 845d88f5fd1SLuiz Capitulino input_visitor_test_add("/visitor/input/int", 846d88f5fd1SLuiz Capitulino &in_visitor_data, test_visitor_in_int); 847e92cfa0dSMichael Roth input_visitor_test_add("/visitor/input/int_overflow", 848e92cfa0dSMichael Roth &in_visitor_data, test_visitor_in_int_overflow); 849d88f5fd1SLuiz Capitulino input_visitor_test_add("/visitor/input/bool", 850d88f5fd1SLuiz Capitulino &in_visitor_data, test_visitor_in_bool); 851d88f5fd1SLuiz Capitulino input_visitor_test_add("/visitor/input/number", 852d88f5fd1SLuiz Capitulino &in_visitor_data, test_visitor_in_number); 853d88f5fd1SLuiz Capitulino input_visitor_test_add("/visitor/input/string", 854d88f5fd1SLuiz Capitulino &in_visitor_data, test_visitor_in_string); 855d88f5fd1SLuiz Capitulino input_visitor_test_add("/visitor/input/enum", 856d88f5fd1SLuiz Capitulino &in_visitor_data, test_visitor_in_enum); 857d88f5fd1SLuiz Capitulino input_visitor_test_add("/visitor/input/struct", 858d88f5fd1SLuiz Capitulino &in_visitor_data, test_visitor_in_struct); 859d88f5fd1SLuiz Capitulino input_visitor_test_add("/visitor/input/struct-nested", 860d88f5fd1SLuiz Capitulino &in_visitor_data, test_visitor_in_struct_nested); 861d88f5fd1SLuiz Capitulino input_visitor_test_add("/visitor/input/list", 862d88f5fd1SLuiz Capitulino &in_visitor_data, test_visitor_in_list); 86328770e05SMarkus Armbruster input_visitor_test_add("/visitor/input/any", 86428770e05SMarkus Armbruster &in_visitor_data, test_visitor_in_any); 8653df016f1SEric Blake input_visitor_test_add("/visitor/input/null", 8663df016f1SEric Blake &in_visitor_data, test_visitor_in_null); 8672fc00432SMarkus Armbruster input_visitor_test_add("/visitor/input/union-flat", 8682fc00432SMarkus Armbruster &in_visitor_data, test_visitor_in_union_flat); 869ab045267SEric Blake input_visitor_test_add("/visitor/input/alternate", 870ab045267SEric Blake &in_visitor_data, test_visitor_in_alternate); 8713dcf71f6SPaolo Bonzini input_visitor_test_add("/visitor/input/errors", 8723dcf71f6SPaolo Bonzini &in_visitor_data, test_visitor_in_errors); 8732533377cSEric Blake input_visitor_test_add("/visitor/input/wrong-type", 8742533377cSEric Blake &in_visitor_data, test_visitor_in_wrong_type); 8759c51b441SEric Blake input_visitor_test_add("/visitor/input/alternate-number", 8769c51b441SEric Blake &in_visitor_data, test_visitor_in_alternate_number); 877199e0f17SMichael Roth input_visitor_test_add("/visitor/input/native_list/int", 878199e0f17SMichael Roth &in_visitor_data, 879199e0f17SMichael Roth test_visitor_in_native_list_int); 880199e0f17SMichael Roth input_visitor_test_add("/visitor/input/native_list/int8", 881199e0f17SMichael Roth &in_visitor_data, 882199e0f17SMichael Roth test_visitor_in_native_list_int8); 883199e0f17SMichael Roth input_visitor_test_add("/visitor/input/native_list/int16", 884199e0f17SMichael Roth &in_visitor_data, 885199e0f17SMichael Roth test_visitor_in_native_list_int16); 886199e0f17SMichael Roth input_visitor_test_add("/visitor/input/native_list/int32", 887199e0f17SMichael Roth &in_visitor_data, 888199e0f17SMichael Roth test_visitor_in_native_list_int32); 889199e0f17SMichael Roth input_visitor_test_add("/visitor/input/native_list/int64", 890199e0f17SMichael Roth &in_visitor_data, 891199e0f17SMichael Roth test_visitor_in_native_list_int64); 892199e0f17SMichael Roth input_visitor_test_add("/visitor/input/native_list/uint8", 893199e0f17SMichael Roth &in_visitor_data, 894199e0f17SMichael Roth test_visitor_in_native_list_uint8); 895199e0f17SMichael Roth input_visitor_test_add("/visitor/input/native_list/uint16", 896199e0f17SMichael Roth &in_visitor_data, 897199e0f17SMichael Roth test_visitor_in_native_list_uint16); 898199e0f17SMichael Roth input_visitor_test_add("/visitor/input/native_list/uint32", 899199e0f17SMichael Roth &in_visitor_data, 900199e0f17SMichael Roth test_visitor_in_native_list_uint32); 901199e0f17SMichael Roth input_visitor_test_add("/visitor/input/native_list/uint64", 902805017b7SEric Blake &in_visitor_data, 903805017b7SEric Blake test_visitor_in_native_list_uint64); 904199e0f17SMichael Roth input_visitor_test_add("/visitor/input/native_list/bool", 905199e0f17SMichael Roth &in_visitor_data, test_visitor_in_native_list_bool); 906199e0f17SMichael Roth input_visitor_test_add("/visitor/input/native_list/str", 907805017b7SEric Blake &in_visitor_data, 908805017b7SEric Blake test_visitor_in_native_list_string); 909199e0f17SMichael Roth input_visitor_test_add("/visitor/input/native_list/number", 910805017b7SEric Blake &in_visitor_data, 911805017b7SEric Blake test_visitor_in_native_list_number); 912d88f5fd1SLuiz Capitulino 913d88f5fd1SLuiz Capitulino g_test_run(); 914d88f5fd1SLuiz Capitulino 915d88f5fd1SLuiz Capitulino return 0; 916d88f5fd1SLuiz Capitulino } 917