1d88f5fd1SLuiz Capitulino /* 2b3db211fSDaniel 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> 877c47de2SMarkus Armbruster * Paolo Bonzini <pbonzini@redhat.com> 9d88f5fd1SLuiz Capitulino * 10d88f5fd1SLuiz Capitulino * This work is licensed under the terms of the GNU GPL, version 2 or later. 11d88f5fd1SLuiz Capitulino * See the COPYING file in the top-level directory. 12d88f5fd1SLuiz Capitulino */ 13d88f5fd1SLuiz Capitulino 14681c28a3SPeter Maydell #include "qemu/osdep.h" 15d88f5fd1SLuiz Capitulino 1679ee7df8SPaolo Bonzini #include "qemu-common.h" 17da34e65cSMarkus Armbruster #include "qapi/error.h" 18112ed241SMarkus Armbruster #include "qapi/qapi-visit-introspect.h" 19b3db211fSDaniel P. Berrange #include "qapi/qobject-input-visitor.h" 20d88f5fd1SLuiz Capitulino #include "test-qapi-visit.h" 216b673957SMarkus Armbruster #include "qapi/qmp/qbool.h" 22452fcdbcSMarkus Armbruster #include "qapi/qmp/qdict.h" 2315280c36SMarkus Armbruster #include "qapi/qmp/qnull.h" 2415280c36SMarkus Armbruster #include "qapi/qmp/qnum.h" 25fc81fa1eSMarkus Armbruster #include "qapi/qmp/qstring.h" 26c7eb39cbSEric Blake #include "qapi/qmp/qjson.h" 27eb815e24SMarkus Armbruster #include "test-qapi-introspect.h" 28eb815e24SMarkus Armbruster #include "qapi/qapi-introspect.h" 29d88f5fd1SLuiz Capitulino 30d88f5fd1SLuiz Capitulino typedef struct TestInputVisitorData { 31d88f5fd1SLuiz Capitulino QObject *obj; 32b70ce101SEric Blake Visitor *qiv; 33d88f5fd1SLuiz Capitulino } TestInputVisitorData; 34d88f5fd1SLuiz Capitulino 35d88f5fd1SLuiz Capitulino static void visitor_input_teardown(TestInputVisitorData *data, 36d88f5fd1SLuiz Capitulino const void *unused) 37d88f5fd1SLuiz Capitulino { 38cb3e7f08SMarc-André Lureau qobject_unref(data->obj); 39d88f5fd1SLuiz Capitulino data->obj = NULL; 40d88f5fd1SLuiz Capitulino 41d88f5fd1SLuiz Capitulino if (data->qiv) { 42b70ce101SEric Blake visit_free(data->qiv); 43d88f5fd1SLuiz Capitulino data->qiv = NULL; 44d88f5fd1SLuiz Capitulino } 45d88f5fd1SLuiz Capitulino } 46d88f5fd1SLuiz Capitulino 470920a171SEric Blake /* The various test_init functions are provided instead of a test setup 480920a171SEric Blake function so that the JSON string used by the tests are kept in the test 490920a171SEric Blake functions (and not in main()). */ 50eac78bd4SMarkus Armbruster 51eac78bd4SMarkus Armbruster static Visitor *test_init_internal(TestInputVisitorData *data, bool keyval, 52eac78bd4SMarkus Armbruster QObject *obj) 530920a171SEric Blake { 54b18f1141SEric Blake visitor_input_teardown(data, NULL); 55b18f1141SEric Blake 56eac78bd4SMarkus Armbruster data->obj = obj; 570920a171SEric Blake 58cbd8acf3SDaniel P. Berrange if (keyval) { 59cbd8acf3SDaniel P. Berrange data->qiv = qobject_input_visitor_new_keyval(data->obj); 60cbd8acf3SDaniel P. Berrange } else { 61048abb7bSMarkus Armbruster data->qiv = qobject_input_visitor_new(data->obj); 62cbd8acf3SDaniel P. Berrange } 630920a171SEric Blake g_assert(data->qiv); 64b70ce101SEric Blake return data->qiv; 650920a171SEric Blake } 660920a171SEric Blake 67cbd8acf3SDaniel P. Berrange static GCC_FMT_ATTR(3, 4) 68cbd8acf3SDaniel P. Berrange Visitor *visitor_input_test_init_full(TestInputVisitorData *data, 69cbd8acf3SDaniel P. Berrange bool keyval, 70cbd8acf3SDaniel P. Berrange const char *json_string, ...) 71cbd8acf3SDaniel P. Berrange { 72cbd8acf3SDaniel P. Berrange Visitor *v; 73cbd8acf3SDaniel P. Berrange va_list ap; 74cbd8acf3SDaniel P. Berrange 75cbd8acf3SDaniel P. Berrange va_start(ap, json_string); 76eac78bd4SMarkus Armbruster v = test_init_internal(data, keyval, 77eac78bd4SMarkus Armbruster qobject_from_vjsonf_nofail(json_string, ap)); 78cbd8acf3SDaniel P. Berrange va_end(ap); 79cbd8acf3SDaniel P. Berrange return v; 80cbd8acf3SDaniel P. Berrange } 81cbd8acf3SDaniel P. Berrange 82aba2107aSStefan Weil static GCC_FMT_ATTR(2, 3) 83aba2107aSStefan Weil Visitor *visitor_input_test_init(TestInputVisitorData *data, 84d88f5fd1SLuiz Capitulino const char *json_string, ...) 85d88f5fd1SLuiz Capitulino { 86d88f5fd1SLuiz Capitulino Visitor *v; 87d88f5fd1SLuiz Capitulino va_list ap; 88d88f5fd1SLuiz Capitulino 89d88f5fd1SLuiz Capitulino va_start(ap, json_string); 90eac78bd4SMarkus Armbruster v = test_init_internal(data, false, 91eac78bd4SMarkus Armbruster qobject_from_vjsonf_nofail(json_string, ap)); 92d88f5fd1SLuiz Capitulino va_end(ap); 93d88f5fd1SLuiz Capitulino return v; 94d88f5fd1SLuiz Capitulino } 95d88f5fd1SLuiz Capitulino 96199e0f17SMichael Roth /* similar to visitor_input_test_init(), but does not expect a string 97199e0f17SMichael Roth * literal/format json_string argument and so can be used for 98199e0f17SMichael Roth * programatically generated strings (and we can't pass in programatically 99199e0f17SMichael Roth * generated strings via %s format parameters since qobject_from_jsonv() 100199e0f17SMichael Roth * will wrap those in double-quotes and treat the entire object as a 101199e0f17SMichael Roth * string) 102199e0f17SMichael Roth */ 103199e0f17SMichael Roth static Visitor *visitor_input_test_init_raw(TestInputVisitorData *data, 104199e0f17SMichael Roth const char *json_string) 105199e0f17SMichael Roth { 106eac78bd4SMarkus Armbruster return test_init_internal(data, false, 107eac78bd4SMarkus Armbruster qobject_from_json(json_string, &error_abort)); 108199e0f17SMichael Roth } 109199e0f17SMichael Roth 110d88f5fd1SLuiz Capitulino static void test_visitor_in_int(TestInputVisitorData *data, 111d88f5fd1SLuiz Capitulino const void *unused) 112d88f5fd1SLuiz Capitulino { 11329a6731aSEric Blake int64_t res = 0; 114c1214ad3SMarc-André Lureau double dbl; 11529a6731aSEric Blake int value = -42; 116d88f5fd1SLuiz Capitulino Visitor *v; 117d88f5fd1SLuiz Capitulino 11829a6731aSEric Blake v = visitor_input_test_init(data, "%d", value); 119d88f5fd1SLuiz Capitulino 12051e72bc1SEric Blake visit_type_int(v, NULL, &res, &error_abort); 121d88f5fd1SLuiz Capitulino g_assert_cmpint(res, ==, value); 122c1214ad3SMarc-André Lureau 123c1214ad3SMarc-André Lureau visit_type_number(v, NULL, &dbl, &error_abort); 124c1214ad3SMarc-André Lureau g_assert_cmpfloat(dbl, ==, -42.0); 125d88f5fd1SLuiz Capitulino } 126d88f5fd1SLuiz Capitulino 1274bc0c94dSMarkus Armbruster static void test_visitor_in_uint(TestInputVisitorData *data, 1284bc0c94dSMarkus Armbruster const void *unused) 1294bc0c94dSMarkus Armbruster { 1304bc0c94dSMarkus Armbruster uint64_t res = 0; 131c1214ad3SMarc-André Lureau int64_t i64; 132c1214ad3SMarc-André Lureau double dbl; 1334bc0c94dSMarkus Armbruster int value = 42; 1344bc0c94dSMarkus Armbruster Visitor *v; 1354bc0c94dSMarkus Armbruster 1364bc0c94dSMarkus Armbruster v = visitor_input_test_init(data, "%d", value); 1374bc0c94dSMarkus Armbruster 1384bc0c94dSMarkus Armbruster visit_type_uint64(v, NULL, &res, &error_abort); 1394bc0c94dSMarkus Armbruster g_assert_cmpuint(res, ==, (uint64_t)value); 1404bc0c94dSMarkus Armbruster 141c1214ad3SMarc-André Lureau visit_type_int(v, NULL, &i64, &error_abort); 142c1214ad3SMarc-André Lureau g_assert_cmpint(i64, ==, value); 1434bc0c94dSMarkus Armbruster 144c1214ad3SMarc-André Lureau visit_type_number(v, NULL, &dbl, &error_abort); 145c1214ad3SMarc-André Lureau g_assert_cmpfloat(dbl, ==, value); 146c1214ad3SMarc-André Lureau 147c1214ad3SMarc-André Lureau /* BUG: value between INT64_MIN and -1 accepted modulo 2^64 */ 1484bc0c94dSMarkus Armbruster v = visitor_input_test_init(data, "%d", -value); 1494bc0c94dSMarkus Armbruster 1504bc0c94dSMarkus Armbruster visit_type_uint64(v, NULL, &res, &error_abort); 1514bc0c94dSMarkus Armbruster g_assert_cmpuint(res, ==, (uint64_t)-value); 1524bc0c94dSMarkus Armbruster 1534bc0c94dSMarkus Armbruster v = visitor_input_test_init(data, "18446744073709551574"); 1544bc0c94dSMarkus Armbruster 1555923f85fSMarc-André Lureau visit_type_uint64(v, NULL, &res, &error_abort); 1565923f85fSMarc-André Lureau g_assert_cmpuint(res, ==, 18446744073709551574U); 157c1214ad3SMarc-André Lureau 158c1214ad3SMarc-André Lureau visit_type_number(v, NULL, &dbl, &error_abort); 159c1214ad3SMarc-André Lureau g_assert_cmpfloat(dbl, ==, 18446744073709552000.0); 1604bc0c94dSMarkus Armbruster } 1614bc0c94dSMarkus Armbruster 162e92cfa0dSMichael Roth static void test_visitor_in_int_overflow(TestInputVisitorData *data, 163e92cfa0dSMichael Roth const void *unused) 164e92cfa0dSMichael Roth { 165e92cfa0dSMichael Roth int64_t res = 0; 166e940f543SMarkus Armbruster Error *err = NULL; 167e92cfa0dSMichael Roth Visitor *v; 168e92cfa0dSMichael Roth 16901b2ffceSMarc-André Lureau /* 17001b2ffceSMarc-André Lureau * This will overflow a QNUM_I64, so should be deserialized into a 17101b2ffceSMarc-André Lureau * QNUM_DOUBLE field instead, leading to an error if we pass it to 17201b2ffceSMarc-André Lureau * visit_type_int(). Confirm this. 173e92cfa0dSMichael Roth */ 174e92cfa0dSMichael Roth v = visitor_input_test_init(data, "%f", DBL_MAX); 175e92cfa0dSMichael Roth 17651e72bc1SEric Blake visit_type_int(v, NULL, &res, &err); 177a12a5a1aSEric Blake error_free_or_abort(&err); 178e92cfa0dSMichael Roth } 179e92cfa0dSMichael Roth 180cbd8acf3SDaniel P. Berrange static void test_visitor_in_int_keyval(TestInputVisitorData *data, 181cbd8acf3SDaniel P. Berrange const void *unused) 182cbd8acf3SDaniel P. Berrange { 183cbd8acf3SDaniel P. Berrange int64_t res = 0, value = -42; 184cbd8acf3SDaniel P. Berrange Error *err = NULL; 185cbd8acf3SDaniel P. Berrange Visitor *v; 186cbd8acf3SDaniel P. Berrange 187cbd8acf3SDaniel P. Berrange v = visitor_input_test_init_full(data, true, "%" PRId64, value); 188cbd8acf3SDaniel P. Berrange visit_type_int(v, NULL, &res, &err); 189cbd8acf3SDaniel P. Berrange error_free_or_abort(&err); 190cbd8acf3SDaniel P. Berrange } 191cbd8acf3SDaniel P. Berrange 192cbd8acf3SDaniel P. Berrange static void test_visitor_in_int_str_keyval(TestInputVisitorData *data, 193cbd8acf3SDaniel P. Berrange const void *unused) 194cbd8acf3SDaniel P. Berrange { 195cbd8acf3SDaniel P. Berrange int64_t res = 0, value = -42; 196cbd8acf3SDaniel P. Berrange Visitor *v; 197cbd8acf3SDaniel P. Berrange 198cbd8acf3SDaniel P. Berrange v = visitor_input_test_init_full(data, true, "\"-42\""); 199cbd8acf3SDaniel P. Berrange 200cbd8acf3SDaniel P. Berrange visit_type_int(v, NULL, &res, &error_abort); 201cbd8acf3SDaniel P. Berrange g_assert_cmpint(res, ==, value); 202cbd8acf3SDaniel P. Berrange } 203cbd8acf3SDaniel P. Berrange 204cbd8acf3SDaniel P. Berrange static void test_visitor_in_int_str_fail(TestInputVisitorData *data, 205cbd8acf3SDaniel P. Berrange const void *unused) 206cbd8acf3SDaniel P. Berrange { 207cbd8acf3SDaniel P. Berrange int64_t res = 0; 208cbd8acf3SDaniel P. Berrange Visitor *v; 209cbd8acf3SDaniel P. Berrange Error *err = NULL; 210cbd8acf3SDaniel P. Berrange 211cbd8acf3SDaniel P. Berrange v = visitor_input_test_init(data, "\"-42\""); 212cbd8acf3SDaniel P. Berrange 213cbd8acf3SDaniel P. Berrange visit_type_int(v, NULL, &res, &err); 214cbd8acf3SDaniel P. Berrange error_free_or_abort(&err); 215cbd8acf3SDaniel P. Berrange } 216cbd8acf3SDaniel P. Berrange 217d88f5fd1SLuiz Capitulino static void test_visitor_in_bool(TestInputVisitorData *data, 218d88f5fd1SLuiz Capitulino const void *unused) 219d88f5fd1SLuiz Capitulino { 220d88f5fd1SLuiz Capitulino bool res = false; 221d88f5fd1SLuiz Capitulino Visitor *v; 222d88f5fd1SLuiz Capitulino 223d88f5fd1SLuiz Capitulino v = visitor_input_test_init(data, "true"); 224d88f5fd1SLuiz Capitulino 22551e72bc1SEric Blake visit_type_bool(v, NULL, &res, &error_abort); 226d88f5fd1SLuiz Capitulino g_assert_cmpint(res, ==, true); 227d88f5fd1SLuiz Capitulino } 228d88f5fd1SLuiz Capitulino 229cbd8acf3SDaniel P. Berrange static void test_visitor_in_bool_keyval(TestInputVisitorData *data, 230cbd8acf3SDaniel P. Berrange const void *unused) 231cbd8acf3SDaniel P. Berrange { 232cbd8acf3SDaniel P. Berrange bool res = false; 233cbd8acf3SDaniel P. Berrange Error *err = NULL; 234cbd8acf3SDaniel P. Berrange Visitor *v; 235cbd8acf3SDaniel P. Berrange 236cbd8acf3SDaniel P. Berrange v = visitor_input_test_init_full(data, true, "true"); 237cbd8acf3SDaniel P. Berrange 238cbd8acf3SDaniel P. Berrange visit_type_bool(v, NULL, &res, &err); 239cbd8acf3SDaniel P. Berrange error_free_or_abort(&err); 240cbd8acf3SDaniel P. Berrange } 241cbd8acf3SDaniel P. Berrange 242cbd8acf3SDaniel P. Berrange static void test_visitor_in_bool_str_keyval(TestInputVisitorData *data, 243cbd8acf3SDaniel P. Berrange const void *unused) 244cbd8acf3SDaniel P. Berrange { 245cbd8acf3SDaniel P. Berrange bool res = false; 246cbd8acf3SDaniel P. Berrange Visitor *v; 247cbd8acf3SDaniel P. Berrange 248cbd8acf3SDaniel P. Berrange v = visitor_input_test_init_full(data, true, "\"on\""); 249cbd8acf3SDaniel P. Berrange 250cbd8acf3SDaniel P. Berrange visit_type_bool(v, NULL, &res, &error_abort); 251cbd8acf3SDaniel P. Berrange g_assert_cmpint(res, ==, true); 252cbd8acf3SDaniel P. Berrange } 253cbd8acf3SDaniel P. Berrange 254cbd8acf3SDaniel P. Berrange static void test_visitor_in_bool_str_fail(TestInputVisitorData *data, 255cbd8acf3SDaniel P. Berrange const void *unused) 256cbd8acf3SDaniel P. Berrange { 257cbd8acf3SDaniel P. Berrange bool res = false; 258cbd8acf3SDaniel P. Berrange Visitor *v; 259cbd8acf3SDaniel P. Berrange Error *err = NULL; 260cbd8acf3SDaniel P. Berrange 261cbd8acf3SDaniel P. Berrange v = visitor_input_test_init(data, "\"true\""); 262cbd8acf3SDaniel P. Berrange 263cbd8acf3SDaniel P. Berrange visit_type_bool(v, NULL, &res, &err); 264cbd8acf3SDaniel P. Berrange error_free_or_abort(&err); 265cbd8acf3SDaniel P. Berrange } 266cbd8acf3SDaniel P. Berrange 267d88f5fd1SLuiz Capitulino static void test_visitor_in_number(TestInputVisitorData *data, 268d88f5fd1SLuiz Capitulino const void *unused) 269d88f5fd1SLuiz Capitulino { 270d88f5fd1SLuiz Capitulino double res = 0, value = 3.14; 271d88f5fd1SLuiz Capitulino Visitor *v; 272d88f5fd1SLuiz Capitulino 273d88f5fd1SLuiz Capitulino v = visitor_input_test_init(data, "%f", value); 274d88f5fd1SLuiz Capitulino 27551e72bc1SEric Blake visit_type_number(v, NULL, &res, &error_abort); 276d88f5fd1SLuiz Capitulino g_assert_cmpfloat(res, ==, value); 277d88f5fd1SLuiz Capitulino } 278d88f5fd1SLuiz Capitulino 279c1214ad3SMarc-André Lureau static void test_visitor_in_large_number(TestInputVisitorData *data, 280c1214ad3SMarc-André Lureau const void *unused) 281c1214ad3SMarc-André Lureau { 282c1214ad3SMarc-André Lureau Error *err = NULL; 283c1214ad3SMarc-André Lureau double res = 0; 284c1214ad3SMarc-André Lureau int64_t i64; 285c1214ad3SMarc-André Lureau uint64_t u64; 286c1214ad3SMarc-André Lureau Visitor *v; 287c1214ad3SMarc-André Lureau 288c1214ad3SMarc-André Lureau v = visitor_input_test_init(data, "-18446744073709551616"); /* -2^64 */ 289c1214ad3SMarc-André Lureau 290c1214ad3SMarc-André Lureau visit_type_number(v, NULL, &res, &error_abort); 291c1214ad3SMarc-André Lureau g_assert_cmpfloat(res, ==, -18446744073709552e3); 292c1214ad3SMarc-André Lureau 293c1214ad3SMarc-André Lureau visit_type_int(v, NULL, &i64, &err); 294c1214ad3SMarc-André Lureau error_free_or_abort(&err); 295c1214ad3SMarc-André Lureau 296c1214ad3SMarc-André Lureau visit_type_uint64(v, NULL, &u64, &err); 297c1214ad3SMarc-André Lureau error_free_or_abort(&err); 298c1214ad3SMarc-André Lureau } 299c1214ad3SMarc-André Lureau 300cbd8acf3SDaniel P. Berrange static void test_visitor_in_number_keyval(TestInputVisitorData *data, 301cbd8acf3SDaniel P. Berrange const void *unused) 302cbd8acf3SDaniel P. Berrange { 303cbd8acf3SDaniel P. Berrange double res = 0, value = 3.14; 304cbd8acf3SDaniel P. Berrange Error *err = NULL; 305cbd8acf3SDaniel P. Berrange Visitor *v; 306cbd8acf3SDaniel P. Berrange 307cbd8acf3SDaniel P. Berrange v = visitor_input_test_init_full(data, true, "%f", value); 308cbd8acf3SDaniel P. Berrange 309cbd8acf3SDaniel P. Berrange visit_type_number(v, NULL, &res, &err); 310cbd8acf3SDaniel P. Berrange error_free_or_abort(&err); 311cbd8acf3SDaniel P. Berrange } 312cbd8acf3SDaniel P. Berrange 313cbd8acf3SDaniel P. Berrange static void test_visitor_in_number_str_keyval(TestInputVisitorData *data, 314cbd8acf3SDaniel P. Berrange const void *unused) 315cbd8acf3SDaniel P. Berrange { 316cbd8acf3SDaniel P. Berrange double res = 0, value = 3.14; 317cbd8acf3SDaniel P. Berrange Visitor *v; 3185891c388SMarkus Armbruster Error *err = NULL; 319cbd8acf3SDaniel P. Berrange 320cbd8acf3SDaniel P. Berrange v = visitor_input_test_init_full(data, true, "\"3.14\""); 321cbd8acf3SDaniel P. Berrange 322cbd8acf3SDaniel P. Berrange visit_type_number(v, NULL, &res, &error_abort); 323cbd8acf3SDaniel P. Berrange g_assert_cmpfloat(res, ==, value); 3245891c388SMarkus Armbruster 3255891c388SMarkus Armbruster v = visitor_input_test_init_full(data, true, "\"inf\""); 3265891c388SMarkus Armbruster 3275891c388SMarkus Armbruster visit_type_number(v, NULL, &res, &err); 3285891c388SMarkus Armbruster error_free_or_abort(&err); 329cbd8acf3SDaniel P. Berrange } 330cbd8acf3SDaniel P. Berrange 331cbd8acf3SDaniel P. Berrange static void test_visitor_in_number_str_fail(TestInputVisitorData *data, 332cbd8acf3SDaniel P. Berrange const void *unused) 333cbd8acf3SDaniel P. Berrange { 334cbd8acf3SDaniel P. Berrange double res = 0; 335cbd8acf3SDaniel P. Berrange Visitor *v; 336cbd8acf3SDaniel P. Berrange Error *err = NULL; 337cbd8acf3SDaniel P. Berrange 338cbd8acf3SDaniel P. Berrange v = visitor_input_test_init(data, "\"3.14\""); 339cbd8acf3SDaniel P. Berrange 340cbd8acf3SDaniel P. Berrange visit_type_number(v, NULL, &res, &err); 341cbd8acf3SDaniel P. Berrange error_free_or_abort(&err); 342cbd8acf3SDaniel P. Berrange } 343cbd8acf3SDaniel P. Berrange 344cbd8acf3SDaniel P. Berrange static void test_visitor_in_size_str_keyval(TestInputVisitorData *data, 345cbd8acf3SDaniel P. Berrange const void *unused) 346cbd8acf3SDaniel P. Berrange { 347cbd8acf3SDaniel P. Berrange uint64_t res, value = 500 * 1024 * 1024; 348cbd8acf3SDaniel P. Berrange Visitor *v; 349cbd8acf3SDaniel P. Berrange 350cbd8acf3SDaniel P. Berrange v = visitor_input_test_init_full(data, true, "\"500M\""); 351cbd8acf3SDaniel P. Berrange 352cbd8acf3SDaniel P. Berrange visit_type_size(v, NULL, &res, &error_abort); 353cbd8acf3SDaniel P. Berrange g_assert_cmpfloat(res, ==, value); 354cbd8acf3SDaniel P. Berrange } 355cbd8acf3SDaniel P. Berrange 356cbd8acf3SDaniel P. Berrange static void test_visitor_in_size_str_fail(TestInputVisitorData *data, 357cbd8acf3SDaniel P. Berrange const void *unused) 358cbd8acf3SDaniel P. Berrange { 359cbd8acf3SDaniel P. Berrange uint64_t res = 0; 360cbd8acf3SDaniel P. Berrange Visitor *v; 361cbd8acf3SDaniel P. Berrange Error *err = NULL; 362cbd8acf3SDaniel P. Berrange 363cbd8acf3SDaniel P. Berrange v = visitor_input_test_init(data, "\"500M\""); 364cbd8acf3SDaniel P. Berrange 365cbd8acf3SDaniel P. Berrange visit_type_size(v, NULL, &res, &err); 366cbd8acf3SDaniel P. Berrange error_free_or_abort(&err); 367cbd8acf3SDaniel P. Berrange } 368cbd8acf3SDaniel P. Berrange 369d88f5fd1SLuiz Capitulino static void test_visitor_in_string(TestInputVisitorData *data, 370d88f5fd1SLuiz Capitulino const void *unused) 371d88f5fd1SLuiz Capitulino { 372d88f5fd1SLuiz Capitulino char *res = NULL, *value = (char *) "Q E M U"; 373d88f5fd1SLuiz Capitulino Visitor *v; 374d88f5fd1SLuiz Capitulino 375d88f5fd1SLuiz Capitulino v = visitor_input_test_init(data, "%s", value); 376d88f5fd1SLuiz Capitulino 37751e72bc1SEric Blake visit_type_str(v, NULL, &res, &error_abort); 378d88f5fd1SLuiz Capitulino g_assert_cmpstr(res, ==, value); 379d88f5fd1SLuiz Capitulino 380d88f5fd1SLuiz Capitulino g_free(res); 381d88f5fd1SLuiz Capitulino } 382d88f5fd1SLuiz Capitulino 383d88f5fd1SLuiz Capitulino static void test_visitor_in_enum(TestInputVisitorData *data, 384d88f5fd1SLuiz Capitulino const void *unused) 385d88f5fd1SLuiz Capitulino { 386d88f5fd1SLuiz Capitulino Visitor *v; 387d88f5fd1SLuiz Capitulino EnumOne i; 388d88f5fd1SLuiz Capitulino 3891c236ba5SMarkus Armbruster for (i = 0; i < ENUM_ONE__MAX; i++) { 390d88f5fd1SLuiz Capitulino EnumOne res = -1; 391d88f5fd1SLuiz Capitulino 392977c736fSMarkus Armbruster v = visitor_input_test_init(data, "%s", EnumOne_str(i)); 393d88f5fd1SLuiz Capitulino 39451e72bc1SEric Blake visit_type_EnumOne(v, NULL, &res, &error_abort); 395d88f5fd1SLuiz Capitulino g_assert_cmpint(i, ==, res); 396d88f5fd1SLuiz Capitulino } 397d88f5fd1SLuiz Capitulino } 398d88f5fd1SLuiz Capitulino 399d88f5fd1SLuiz Capitulino 400d88f5fd1SLuiz Capitulino static void test_visitor_in_struct(TestInputVisitorData *data, 401d88f5fd1SLuiz Capitulino const void *unused) 402d88f5fd1SLuiz Capitulino { 403d88f5fd1SLuiz Capitulino TestStruct *p = NULL; 404d88f5fd1SLuiz Capitulino Visitor *v; 405d88f5fd1SLuiz Capitulino 406d88f5fd1SLuiz Capitulino v = visitor_input_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo' }"); 407d88f5fd1SLuiz Capitulino 40851e72bc1SEric Blake visit_type_TestStruct(v, NULL, &p, &error_abort); 409d88f5fd1SLuiz Capitulino g_assert_cmpint(p->integer, ==, -42); 410d88f5fd1SLuiz Capitulino g_assert(p->boolean == true); 411d88f5fd1SLuiz Capitulino g_assert_cmpstr(p->string, ==, "foo"); 412d88f5fd1SLuiz Capitulino 413d88f5fd1SLuiz Capitulino g_free(p->string); 414d88f5fd1SLuiz Capitulino g_free(p); 415d88f5fd1SLuiz Capitulino } 416d88f5fd1SLuiz Capitulino 417d88f5fd1SLuiz Capitulino static void test_visitor_in_struct_nested(TestInputVisitorData *data, 418d88f5fd1SLuiz Capitulino const void *unused) 419d88f5fd1SLuiz Capitulino { 420221db5daSDaniel P. Berrangé g_autoptr(UserDefTwo) udp = NULL; 421d88f5fd1SLuiz Capitulino Visitor *v; 422d88f5fd1SLuiz Capitulino 423b6fcf32dSEric Blake v = visitor_input_test_init(data, "{ 'string0': 'string0', " 424b6fcf32dSEric Blake "'dict1': { 'string1': 'string1', " 425b6fcf32dSEric Blake "'dict2': { 'userdef': { 'integer': 42, " 426b6fcf32dSEric Blake "'string': 'string' }, 'string': 'string2'}}}"); 427d88f5fd1SLuiz Capitulino 42851e72bc1SEric Blake visit_type_UserDefTwo(v, NULL, &udp, &error_abort); 429d88f5fd1SLuiz Capitulino 430b18f1141SEric Blake g_assert_cmpstr(udp->string0, ==, "string0"); 431b18f1141SEric Blake g_assert_cmpstr(udp->dict1->string1, ==, "string1"); 432ddf21908SEric Blake g_assert_cmpint(udp->dict1->dict2->userdef->integer, ==, 42); 433b18f1141SEric Blake g_assert_cmpstr(udp->dict1->dict2->userdef->string, ==, "string"); 434b18f1141SEric Blake g_assert_cmpstr(udp->dict1->dict2->string, ==, "string2"); 4356446a592SEric Blake g_assert(udp->dict1->has_dict3 == false); 436d88f5fd1SLuiz Capitulino } 437d88f5fd1SLuiz Capitulino 438d88f5fd1SLuiz Capitulino static void test_visitor_in_list(TestInputVisitorData *data, 439d88f5fd1SLuiz Capitulino const void *unused) 440d88f5fd1SLuiz Capitulino { 441d88f5fd1SLuiz Capitulino UserDefOneList *item, *head = NULL; 442d88f5fd1SLuiz Capitulino Visitor *v; 443d88f5fd1SLuiz Capitulino int i; 444d88f5fd1SLuiz Capitulino 445d88f5fd1SLuiz Capitulino v = visitor_input_test_init(data, "[ { 'string': 'string0', 'integer': 42 }, { 'string': 'string1', 'integer': 43 }, { 'string': 'string2', 'integer': 44 } ]"); 446d88f5fd1SLuiz Capitulino 44751e72bc1SEric Blake visit_type_UserDefOneList(v, NULL, &head, &error_abort); 448d88f5fd1SLuiz Capitulino g_assert(head != NULL); 449d88f5fd1SLuiz Capitulino 450d88f5fd1SLuiz Capitulino for (i = 0, item = head; item; item = item->next, i++) { 451d88f5fd1SLuiz Capitulino char string[12]; 452d88f5fd1SLuiz Capitulino 453d88f5fd1SLuiz Capitulino snprintf(string, sizeof(string), "string%d", i); 454d88f5fd1SLuiz Capitulino g_assert_cmpstr(item->value->string, ==, string); 455ddf21908SEric Blake g_assert_cmpint(item->value->integer, ==, 42 + i); 456d88f5fd1SLuiz Capitulino } 457d88f5fd1SLuiz Capitulino 458d88f5fd1SLuiz Capitulino qapi_free_UserDefOneList(head); 4592533377cSEric Blake head = NULL; 4602533377cSEric Blake 4612533377cSEric Blake /* An empty list is valid */ 4622533377cSEric Blake v = visitor_input_test_init(data, "[]"); 46351e72bc1SEric Blake visit_type_UserDefOneList(v, NULL, &head, &error_abort); 4642533377cSEric Blake g_assert(!head); 465d88f5fd1SLuiz Capitulino } 466d88f5fd1SLuiz Capitulino 467*e7a76fe2SMarkus Armbruster static void test_visitor_in_list_struct(TestInputVisitorData *data, 468*e7a76fe2SMarkus Armbruster const void *unused) 469*e7a76fe2SMarkus Armbruster { 470*e7a76fe2SMarkus Armbruster const char *int_member[] = { 471*e7a76fe2SMarkus Armbruster "integer", "s8", "s16", "s32", "s64", "u8", "u16", "u32", "u64" }; 472*e7a76fe2SMarkus Armbruster g_autoptr(GString) json = g_string_new(""); 473*e7a76fe2SMarkus Armbruster int i, j; 474*e7a76fe2SMarkus Armbruster const char *sep; 475*e7a76fe2SMarkus Armbruster g_autoptr(ArrayStruct) arrs = NULL; 476*e7a76fe2SMarkus Armbruster Visitor *v; 477*e7a76fe2SMarkus Armbruster intList *int_list; 478*e7a76fe2SMarkus Armbruster int8List *s8_list; 479*e7a76fe2SMarkus Armbruster int16List *s16_list; 480*e7a76fe2SMarkus Armbruster int32List *s32_list; 481*e7a76fe2SMarkus Armbruster int64List *s64_list; 482*e7a76fe2SMarkus Armbruster uint8List *u8_list; 483*e7a76fe2SMarkus Armbruster uint16List *u16_list; 484*e7a76fe2SMarkus Armbruster uint32List *u32_list; 485*e7a76fe2SMarkus Armbruster uint64List *u64_list; 486*e7a76fe2SMarkus Armbruster numberList *num_list; 487*e7a76fe2SMarkus Armbruster boolList *bool_list; 488*e7a76fe2SMarkus Armbruster strList *str_list; 489*e7a76fe2SMarkus Armbruster 490*e7a76fe2SMarkus Armbruster g_string_append_printf(json, "{"); 491*e7a76fe2SMarkus Armbruster 492*e7a76fe2SMarkus Armbruster for (i = 0; i < G_N_ELEMENTS(int_member); i++) { 493*e7a76fe2SMarkus Armbruster g_string_append_printf(json, "'%s': [", int_member[i]); 494*e7a76fe2SMarkus Armbruster sep = ""; 495*e7a76fe2SMarkus Armbruster for (j = 0; j < 32; j++) { 496*e7a76fe2SMarkus Armbruster g_string_append_printf(json, "%s%d", sep, j); 497*e7a76fe2SMarkus Armbruster sep = ", "; 498*e7a76fe2SMarkus Armbruster } 499*e7a76fe2SMarkus Armbruster g_string_append_printf(json, "], "); 500*e7a76fe2SMarkus Armbruster } 501*e7a76fe2SMarkus Armbruster 502*e7a76fe2SMarkus Armbruster g_string_append_printf(json, "'number': ["); 503*e7a76fe2SMarkus Armbruster sep = ""; 504*e7a76fe2SMarkus Armbruster for (i = 0; i < 32; i++) { 505*e7a76fe2SMarkus Armbruster g_string_append_printf(json, "%s%f", sep, (double)i / 3); 506*e7a76fe2SMarkus Armbruster sep = ", "; 507*e7a76fe2SMarkus Armbruster } 508*e7a76fe2SMarkus Armbruster g_string_append_printf(json, "], "); 509*e7a76fe2SMarkus Armbruster 510*e7a76fe2SMarkus Armbruster g_string_append_printf(json, "'boolean': ["); 511*e7a76fe2SMarkus Armbruster sep = ""; 512*e7a76fe2SMarkus Armbruster for (i = 0; i < 32; i++) { 513*e7a76fe2SMarkus Armbruster g_string_append_printf(json, "%s%s", 514*e7a76fe2SMarkus Armbruster sep, i % 3 == 0 ? "true" : "false"); 515*e7a76fe2SMarkus Armbruster sep = ", "; 516*e7a76fe2SMarkus Armbruster } 517*e7a76fe2SMarkus Armbruster g_string_append_printf(json, "], "); 518*e7a76fe2SMarkus Armbruster 519*e7a76fe2SMarkus Armbruster g_string_append_printf(json, "'string': ["); 520*e7a76fe2SMarkus Armbruster sep = ""; 521*e7a76fe2SMarkus Armbruster for (i = 0; i < 32; i++) { 522*e7a76fe2SMarkus Armbruster g_string_append_printf(json, "%s'%d'", sep, i); 523*e7a76fe2SMarkus Armbruster sep = ", "; 524*e7a76fe2SMarkus Armbruster } 525*e7a76fe2SMarkus Armbruster g_string_append_printf(json, "]"); 526*e7a76fe2SMarkus Armbruster 527*e7a76fe2SMarkus Armbruster g_string_append_printf(json, "}"); 528*e7a76fe2SMarkus Armbruster 529*e7a76fe2SMarkus Armbruster v = visitor_input_test_init_raw(data, json->str); 530*e7a76fe2SMarkus Armbruster visit_type_ArrayStruct(v, NULL, &arrs, &error_abort); 531*e7a76fe2SMarkus Armbruster 532*e7a76fe2SMarkus Armbruster i = 0; 533*e7a76fe2SMarkus Armbruster for (int_list = arrs->integer; int_list; int_list = int_list->next) { 534*e7a76fe2SMarkus Armbruster g_assert_cmpint(int_list->value, ==, i); 535*e7a76fe2SMarkus Armbruster i++; 536*e7a76fe2SMarkus Armbruster } 537*e7a76fe2SMarkus Armbruster 538*e7a76fe2SMarkus Armbruster i = 0; 539*e7a76fe2SMarkus Armbruster for (s8_list = arrs->s8; s8_list; s8_list = s8_list->next) { 540*e7a76fe2SMarkus Armbruster g_assert_cmpint(s8_list->value, ==, i); 541*e7a76fe2SMarkus Armbruster i++; 542*e7a76fe2SMarkus Armbruster } 543*e7a76fe2SMarkus Armbruster 544*e7a76fe2SMarkus Armbruster i = 0; 545*e7a76fe2SMarkus Armbruster for (s16_list = arrs->s16; s16_list; s16_list = s16_list->next) { 546*e7a76fe2SMarkus Armbruster g_assert_cmpint(s16_list->value, ==, i); 547*e7a76fe2SMarkus Armbruster i++; 548*e7a76fe2SMarkus Armbruster } 549*e7a76fe2SMarkus Armbruster 550*e7a76fe2SMarkus Armbruster i = 0; 551*e7a76fe2SMarkus Armbruster for (s32_list = arrs->s32; s32_list; s32_list = s32_list->next) { 552*e7a76fe2SMarkus Armbruster g_assert_cmpint(s32_list->value, ==, i); 553*e7a76fe2SMarkus Armbruster i++; 554*e7a76fe2SMarkus Armbruster } 555*e7a76fe2SMarkus Armbruster 556*e7a76fe2SMarkus Armbruster i = 0; 557*e7a76fe2SMarkus Armbruster for (s64_list = arrs->s64; s64_list; s64_list = s64_list->next) { 558*e7a76fe2SMarkus Armbruster g_assert_cmpint(s64_list->value, ==, i); 559*e7a76fe2SMarkus Armbruster i++; 560*e7a76fe2SMarkus Armbruster } 561*e7a76fe2SMarkus Armbruster 562*e7a76fe2SMarkus Armbruster i = 0; 563*e7a76fe2SMarkus Armbruster for (u8_list = arrs->u8; u8_list; u8_list = u8_list->next) { 564*e7a76fe2SMarkus Armbruster g_assert_cmpint(u8_list->value, ==, i); 565*e7a76fe2SMarkus Armbruster i++; 566*e7a76fe2SMarkus Armbruster } 567*e7a76fe2SMarkus Armbruster 568*e7a76fe2SMarkus Armbruster i = 0; 569*e7a76fe2SMarkus Armbruster for (u16_list = arrs->u16; u16_list; u16_list = u16_list->next) { 570*e7a76fe2SMarkus Armbruster g_assert_cmpint(u16_list->value, ==, i); 571*e7a76fe2SMarkus Armbruster i++; 572*e7a76fe2SMarkus Armbruster } 573*e7a76fe2SMarkus Armbruster 574*e7a76fe2SMarkus Armbruster i = 0; 575*e7a76fe2SMarkus Armbruster for (u32_list = arrs->u32; u32_list; u32_list = u32_list->next) { 576*e7a76fe2SMarkus Armbruster g_assert_cmpint(u32_list->value, ==, i); 577*e7a76fe2SMarkus Armbruster i++; 578*e7a76fe2SMarkus Armbruster } 579*e7a76fe2SMarkus Armbruster 580*e7a76fe2SMarkus Armbruster i = 0; 581*e7a76fe2SMarkus Armbruster for (u64_list = arrs->u64; u64_list; u64_list = u64_list->next) { 582*e7a76fe2SMarkus Armbruster g_assert_cmpint(u64_list->value, ==, i); 583*e7a76fe2SMarkus Armbruster i++; 584*e7a76fe2SMarkus Armbruster } 585*e7a76fe2SMarkus Armbruster 586*e7a76fe2SMarkus Armbruster i = 0; 587*e7a76fe2SMarkus Armbruster for (num_list = arrs->number; num_list; num_list = num_list->next) { 588*e7a76fe2SMarkus Armbruster char expected[32], actual[32]; 589*e7a76fe2SMarkus Armbruster 590*e7a76fe2SMarkus Armbruster sprintf(expected, "%.6f", (double)i / 3); 591*e7a76fe2SMarkus Armbruster sprintf(actual, "%.6f", num_list->value); 592*e7a76fe2SMarkus Armbruster g_assert_cmpstr(expected, ==, actual); 593*e7a76fe2SMarkus Armbruster i++; 594*e7a76fe2SMarkus Armbruster } 595*e7a76fe2SMarkus Armbruster 596*e7a76fe2SMarkus Armbruster i = 0; 597*e7a76fe2SMarkus Armbruster for (bool_list = arrs->boolean; bool_list; bool_list = bool_list->next) { 598*e7a76fe2SMarkus Armbruster g_assert_cmpint(bool_list->value, ==, i % 3 == 0); 599*e7a76fe2SMarkus Armbruster i++; 600*e7a76fe2SMarkus Armbruster } 601*e7a76fe2SMarkus Armbruster 602*e7a76fe2SMarkus Armbruster i = 0; 603*e7a76fe2SMarkus Armbruster for (str_list = arrs->string; str_list; str_list = str_list->next) { 604*e7a76fe2SMarkus Armbruster char expected[32]; 605*e7a76fe2SMarkus Armbruster 606*e7a76fe2SMarkus Armbruster sprintf(expected, "%d", i); 607*e7a76fe2SMarkus Armbruster g_assert_cmpstr(str_list->value, ==, expected); 608*e7a76fe2SMarkus Armbruster i++; 609*e7a76fe2SMarkus Armbruster } 610*e7a76fe2SMarkus Armbruster } 611*e7a76fe2SMarkus Armbruster 61228770e05SMarkus Armbruster static void test_visitor_in_any(TestInputVisitorData *data, 61328770e05SMarkus Armbruster const void *unused) 61428770e05SMarkus Armbruster { 61528770e05SMarkus Armbruster QObject *res = NULL; 61628770e05SMarkus Armbruster Visitor *v; 61701b2ffceSMarc-André Lureau QNum *qnum; 61828770e05SMarkus Armbruster QBool *qbool; 61928770e05SMarkus Armbruster QString *qstring; 62028770e05SMarkus Armbruster QDict *qdict; 62128770e05SMarkus Armbruster QObject *qobj; 62201b2ffceSMarc-André Lureau int64_t val; 62328770e05SMarkus Armbruster 62428770e05SMarkus Armbruster v = visitor_input_test_init(data, "-42"); 62551e72bc1SEric Blake visit_type_any(v, NULL, &res, &error_abort); 6267dc847ebSMax Reitz qnum = qobject_to(QNum, res); 62701b2ffceSMarc-André Lureau g_assert(qnum); 62801b2ffceSMarc-André Lureau g_assert(qnum_get_try_int(qnum, &val)); 62901b2ffceSMarc-André Lureau g_assert_cmpint(val, ==, -42); 630cb3e7f08SMarc-André Lureau qobject_unref(res); 63128770e05SMarkus Armbruster 63228770e05SMarkus Armbruster v = visitor_input_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo' }"); 63351e72bc1SEric Blake visit_type_any(v, NULL, &res, &error_abort); 6347dc847ebSMax Reitz qdict = qobject_to(QDict, res); 63528770e05SMarkus Armbruster g_assert(qdict && qdict_size(qdict) == 3); 63628770e05SMarkus Armbruster qobj = qdict_get(qdict, "integer"); 63728770e05SMarkus Armbruster g_assert(qobj); 6387dc847ebSMax Reitz qnum = qobject_to(QNum, qobj); 63901b2ffceSMarc-André Lureau g_assert(qnum); 64001b2ffceSMarc-André Lureau g_assert(qnum_get_try_int(qnum, &val)); 64101b2ffceSMarc-André Lureau g_assert_cmpint(val, ==, -42); 64228770e05SMarkus Armbruster qobj = qdict_get(qdict, "boolean"); 64328770e05SMarkus Armbruster g_assert(qobj); 6447dc847ebSMax Reitz qbool = qobject_to(QBool, qobj); 64528770e05SMarkus Armbruster g_assert(qbool); 64628770e05SMarkus Armbruster g_assert(qbool_get_bool(qbool) == true); 64728770e05SMarkus Armbruster qobj = qdict_get(qdict, "string"); 64828770e05SMarkus Armbruster g_assert(qobj); 6497dc847ebSMax Reitz qstring = qobject_to(QString, qobj); 65028770e05SMarkus Armbruster g_assert(qstring); 65128770e05SMarkus Armbruster g_assert_cmpstr(qstring_get_str(qstring), ==, "foo"); 652cb3e7f08SMarc-André Lureau qobject_unref(res); 65328770e05SMarkus Armbruster } 65428770e05SMarkus Armbruster 6553df016f1SEric Blake static void test_visitor_in_null(TestInputVisitorData *data, 6563df016f1SEric Blake const void *unused) 6573df016f1SEric Blake { 6583df016f1SEric Blake Visitor *v; 6593df016f1SEric Blake Error *err = NULL; 660d2f95f4dSMarkus Armbruster QNull *null; 6613df016f1SEric Blake char *tmp; 6623df016f1SEric Blake 6633df016f1SEric Blake /* 6643df016f1SEric Blake * FIXME: Since QAPI doesn't know the 'null' type yet, we can't 6653df016f1SEric Blake * test visit_type_null() by reading into a QAPI struct then 6663df016f1SEric Blake * checking that it was populated correctly. The best we can do 6673df016f1SEric Blake * for now is ensure that we consumed null from the input, proven 6683df016f1SEric Blake * by the fact that we can't re-read the key; and that we detect 6693df016f1SEric Blake * when input is not null. 6703df016f1SEric Blake */ 6713df016f1SEric Blake 672cbd8acf3SDaniel P. Berrange v = visitor_input_test_init_full(data, false, 673cbd8acf3SDaniel P. Berrange "{ 'a': null, 'b': '' }"); 6743df016f1SEric Blake visit_start_struct(v, NULL, NULL, 0, &error_abort); 675d2f95f4dSMarkus Armbruster visit_type_null(v, "a", &null, &error_abort); 676d2f95f4dSMarkus Armbruster g_assert(qobject_type(QOBJECT(null)) == QTYPE_QNULL); 677cb3e7f08SMarc-André Lureau qobject_unref(null); 678d2f95f4dSMarkus Armbruster visit_type_null(v, "b", &null, &err); 6793df016f1SEric Blake error_free_or_abort(&err); 680d2f95f4dSMarkus Armbruster g_assert(!null); 681ec95f614SMarkus Armbruster visit_type_str(v, "c", &tmp, &err); 682ec95f614SMarkus Armbruster error_free_or_abort(&err); 683d2f95f4dSMarkus Armbruster g_assert(!tmp); 68415c2f669SEric Blake visit_check_struct(v, &error_abort); 6851158bb2aSEric Blake visit_end_struct(v, NULL); 6863df016f1SEric Blake } 6873df016f1SEric Blake 6882fc00432SMarkus Armbruster static void test_visitor_in_union_flat(TestInputVisitorData *data, 6892fc00432SMarkus Armbruster const void *unused) 6902fc00432SMarkus Armbruster { 6912fc00432SMarkus Armbruster Visitor *v; 692221db5daSDaniel P. Berrangé g_autoptr(UserDefFlatUnion) tmp = NULL; 69330594fe1SEric Blake UserDefUnionBase *base; 6942fc00432SMarkus Armbruster 6955223070cSWenchao Xia v = visitor_input_test_init(data, 6965223070cSWenchao Xia "{ 'enum1': 'value1', " 697441cbac0SMarkus Armbruster "'integer': 41, " 6985223070cSWenchao Xia "'string': 'str', " 6995223070cSWenchao Xia "'boolean': true }"); 7002fc00432SMarkus Armbruster 70151e72bc1SEric Blake visit_type_UserDefFlatUnion(v, NULL, &tmp, &error_abort); 7020f61af3eSMarkus Armbruster g_assert_cmpint(tmp->enum1, ==, ENUM_ONE_VALUE1); 7035223070cSWenchao Xia g_assert_cmpstr(tmp->string, ==, "str"); 704441cbac0SMarkus Armbruster g_assert_cmpint(tmp->integer, ==, 41); 705544a3731SEric Blake g_assert_cmpint(tmp->u.value1.boolean, ==, true); 70630594fe1SEric Blake 70730594fe1SEric Blake base = qapi_UserDefFlatUnion_base(tmp); 70830594fe1SEric Blake g_assert(&base->enum1 == &tmp->enum1); 7092fc00432SMarkus Armbruster } 7102fc00432SMarkus Armbruster 711ab045267SEric Blake static void test_visitor_in_alternate(TestInputVisitorData *data, 7122c38b600SMarkus Armbruster const void *unused) 7132c38b600SMarkus Armbruster { 7142c38b600SMarkus Armbruster Visitor *v; 715ab045267SEric Blake UserDefAlternate *tmp; 71668d07839SEric Blake WrapAlternate *wrap; 7172c38b600SMarkus Armbruster 7182c38b600SMarkus Armbruster v = visitor_input_test_init(data, "42"); 71951e72bc1SEric Blake visit_type_UserDefAlternate(v, NULL, &tmp, &error_abort); 72001b2ffceSMarc-André Lureau g_assert_cmpint(tmp->type, ==, QTYPE_QNUM); 721c363acefSEric Blake g_assert_cmpint(tmp->u.i, ==, 42); 722ab045267SEric Blake qapi_free_UserDefAlternate(tmp); 7239c51b441SEric Blake 7248168ca8eSMarkus Armbruster v = visitor_input_test_init(data, "'value1'"); 72551e72bc1SEric Blake visit_type_UserDefAlternate(v, NULL, &tmp, &error_abort); 7260426d53cSEric Blake g_assert_cmpint(tmp->type, ==, QTYPE_QSTRING); 7278168ca8eSMarkus Armbruster g_assert_cmpint(tmp->u.e, ==, ENUM_ONE_VALUE1); 7289c51b441SEric Blake qapi_free_UserDefAlternate(tmp); 7299c51b441SEric Blake 7304d2d5c41SMarkus Armbruster v = visitor_input_test_init(data, "null"); 7314d2d5c41SMarkus Armbruster visit_type_UserDefAlternate(v, NULL, &tmp, &error_abort); 7324d2d5c41SMarkus Armbruster g_assert_cmpint(tmp->type, ==, QTYPE_QNULL); 7334d2d5c41SMarkus Armbruster qapi_free_UserDefAlternate(tmp); 7344d2d5c41SMarkus Armbruster 73568d07839SEric Blake v = visitor_input_test_init(data, "{'integer':1, 'string':'str', " 73668d07839SEric Blake "'enum1':'value1', 'boolean':true}"); 73768d07839SEric Blake visit_type_UserDefAlternate(v, NULL, &tmp, &error_abort); 73868d07839SEric Blake g_assert_cmpint(tmp->type, ==, QTYPE_QDICT); 739becceedcSEric Blake g_assert_cmpint(tmp->u.udfu.integer, ==, 1); 740becceedcSEric Blake g_assert_cmpstr(tmp->u.udfu.string, ==, "str"); 741becceedcSEric Blake g_assert_cmpint(tmp->u.udfu.enum1, ==, ENUM_ONE_VALUE1); 742544a3731SEric Blake g_assert_cmpint(tmp->u.udfu.u.value1.boolean, ==, true); 743544a3731SEric Blake g_assert_cmpint(tmp->u.udfu.u.value1.has_a_b, ==, false); 74468d07839SEric Blake qapi_free_UserDefAlternate(tmp); 74568d07839SEric Blake 74668d07839SEric Blake v = visitor_input_test_init(data, "{ 'alt': 42 }"); 74768d07839SEric Blake visit_type_WrapAlternate(v, NULL, &wrap, &error_abort); 74801b2ffceSMarc-André Lureau g_assert_cmpint(wrap->alt->type, ==, QTYPE_QNUM); 74968d07839SEric Blake g_assert_cmpint(wrap->alt->u.i, ==, 42); 75068d07839SEric Blake qapi_free_WrapAlternate(wrap); 75168d07839SEric Blake 7528168ca8eSMarkus Armbruster v = visitor_input_test_init(data, "{ 'alt': 'value1' }"); 75368d07839SEric Blake visit_type_WrapAlternate(v, NULL, &wrap, &error_abort); 75468d07839SEric Blake g_assert_cmpint(wrap->alt->type, ==, QTYPE_QSTRING); 7558168ca8eSMarkus Armbruster g_assert_cmpint(wrap->alt->u.e, ==, ENUM_ONE_VALUE1); 75668d07839SEric Blake qapi_free_WrapAlternate(wrap); 75768d07839SEric Blake 75868d07839SEric Blake v = visitor_input_test_init(data, "{ 'alt': {'integer':1, 'string':'str', " 75968d07839SEric Blake "'enum1':'value1', 'boolean':true} }"); 76068d07839SEric Blake visit_type_WrapAlternate(v, NULL, &wrap, &error_abort); 76168d07839SEric Blake g_assert_cmpint(wrap->alt->type, ==, QTYPE_QDICT); 762becceedcSEric Blake g_assert_cmpint(wrap->alt->u.udfu.integer, ==, 1); 763becceedcSEric Blake g_assert_cmpstr(wrap->alt->u.udfu.string, ==, "str"); 764becceedcSEric Blake g_assert_cmpint(wrap->alt->u.udfu.enum1, ==, ENUM_ONE_VALUE1); 765544a3731SEric Blake g_assert_cmpint(wrap->alt->u.udfu.u.value1.boolean, ==, true); 766544a3731SEric Blake g_assert_cmpint(wrap->alt->u.udfu.u.value1.has_a_b, ==, false); 76768d07839SEric Blake qapi_free_WrapAlternate(wrap); 7689c51b441SEric Blake } 7699c51b441SEric Blake 7709c51b441SEric Blake static void test_visitor_in_alternate_number(TestInputVisitorData *data, 7719c51b441SEric Blake const void *unused) 7729c51b441SEric Blake { 7739c51b441SEric Blake Visitor *v; 7749c51b441SEric Blake Error *err = NULL; 7758168ca8eSMarkus Armbruster AltEnumBool *aeb; 7768168ca8eSMarkus Armbruster AltEnumNum *aen; 7778168ca8eSMarkus Armbruster AltNumEnum *ans; 7788168ca8eSMarkus Armbruster AltEnumInt *asi; 7799c51b441SEric Blake 7809c51b441SEric Blake /* Parsing an int */ 7819c51b441SEric Blake 7829c51b441SEric Blake v = visitor_input_test_init(data, "42"); 7838168ca8eSMarkus Armbruster visit_type_AltEnumBool(v, NULL, &aeb, &err); 784a12a5a1aSEric Blake error_free_or_abort(&err); 7858168ca8eSMarkus Armbruster qapi_free_AltEnumBool(aeb); 7869c51b441SEric Blake 7879c51b441SEric Blake v = visitor_input_test_init(data, "42"); 7888168ca8eSMarkus Armbruster visit_type_AltEnumNum(v, NULL, &aen, &error_abort); 78901b2ffceSMarc-André Lureau g_assert_cmpint(aen->type, ==, QTYPE_QNUM); 7908168ca8eSMarkus Armbruster g_assert_cmpfloat(aen->u.n, ==, 42); 7918168ca8eSMarkus Armbruster qapi_free_AltEnumNum(aen); 7929c51b441SEric Blake 7939c51b441SEric Blake v = visitor_input_test_init(data, "42"); 7948168ca8eSMarkus Armbruster visit_type_AltNumEnum(v, NULL, &ans, &error_abort); 79501b2ffceSMarc-André Lureau g_assert_cmpint(ans->type, ==, QTYPE_QNUM); 796d00341afSEric Blake g_assert_cmpfloat(ans->u.n, ==, 42); 7978168ca8eSMarkus Armbruster qapi_free_AltNumEnum(ans); 7989c51b441SEric Blake 7999c51b441SEric Blake v = visitor_input_test_init(data, "42"); 8008168ca8eSMarkus Armbruster visit_type_AltEnumInt(v, NULL, &asi, &error_abort); 80101b2ffceSMarc-André Lureau g_assert_cmpint(asi->type, ==, QTYPE_QNUM); 802c363acefSEric Blake g_assert_cmpint(asi->u.i, ==, 42); 8038168ca8eSMarkus Armbruster qapi_free_AltEnumInt(asi); 8049c51b441SEric Blake 8059c51b441SEric Blake /* Parsing a double */ 8069c51b441SEric Blake 8079c51b441SEric Blake v = visitor_input_test_init(data, "42.5"); 8088168ca8eSMarkus Armbruster visit_type_AltEnumBool(v, NULL, &aeb, &err); 809a12a5a1aSEric Blake error_free_or_abort(&err); 8108168ca8eSMarkus Armbruster qapi_free_AltEnumBool(aeb); 8119c51b441SEric Blake 8129c51b441SEric Blake v = visitor_input_test_init(data, "42.5"); 8138168ca8eSMarkus Armbruster visit_type_AltEnumNum(v, NULL, &aen, &error_abort); 81401b2ffceSMarc-André Lureau g_assert_cmpint(aen->type, ==, QTYPE_QNUM); 8158168ca8eSMarkus Armbruster g_assert_cmpfloat(aen->u.n, ==, 42.5); 8168168ca8eSMarkus Armbruster qapi_free_AltEnumNum(aen); 8179c51b441SEric Blake 8189c51b441SEric Blake v = visitor_input_test_init(data, "42.5"); 8198168ca8eSMarkus Armbruster visit_type_AltNumEnum(v, NULL, &ans, &error_abort); 82001b2ffceSMarc-André Lureau g_assert_cmpint(ans->type, ==, QTYPE_QNUM); 821c363acefSEric Blake g_assert_cmpfloat(ans->u.n, ==, 42.5); 8228168ca8eSMarkus Armbruster qapi_free_AltNumEnum(ans); 8239c51b441SEric Blake 8249c51b441SEric Blake v = visitor_input_test_init(data, "42.5"); 8258168ca8eSMarkus Armbruster visit_type_AltEnumInt(v, NULL, &asi, &err); 826a12a5a1aSEric Blake error_free_or_abort(&err); 8278168ca8eSMarkus Armbruster qapi_free_AltEnumInt(asi); 8282c38b600SMarkus Armbruster } 8292c38b600SMarkus Armbruster 830d88f5fd1SLuiz Capitulino static void input_visitor_test_add(const char *testpath, 831b1d2e5f1SDaniel P. Berrange const void *user_data, 832b1d2e5f1SDaniel P. Berrange void (*test_func)(TestInputVisitorData *data, 833b1d2e5f1SDaniel P. Berrange const void *user_data)) 834d88f5fd1SLuiz Capitulino { 835b1d2e5f1SDaniel P. Berrange g_test_add(testpath, TestInputVisitorData, user_data, NULL, test_func, 836d88f5fd1SLuiz Capitulino visitor_input_teardown); 837d88f5fd1SLuiz Capitulino } 838d88f5fd1SLuiz Capitulino 8393dcf71f6SPaolo Bonzini static void test_visitor_in_errors(TestInputVisitorData *data, 8403dcf71f6SPaolo Bonzini const void *unused) 8413dcf71f6SPaolo Bonzini { 8423dcf71f6SPaolo Bonzini TestStruct *p = NULL; 843e940f543SMarkus Armbruster Error *err = NULL; 8443dcf71f6SPaolo Bonzini Visitor *v; 845dd5ee2c2SEric Blake strList *q = NULL; 8469b4e38feSEric Blake UserDefTwo *r = NULL; 8479b4e38feSEric Blake WrapAlternate *s = NULL; 8483dcf71f6SPaolo Bonzini 849dd5ee2c2SEric Blake v = visitor_input_test_init(data, "{ 'integer': false, 'boolean': 'foo', " 850dd5ee2c2SEric Blake "'string': -42 }"); 8513dcf71f6SPaolo Bonzini 85251e72bc1SEric Blake visit_type_TestStruct(v, NULL, &p, &err); 853a12a5a1aSEric Blake error_free_or_abort(&err); 85468ab47e4SEric Blake g_assert(!p); 855dd5ee2c2SEric Blake 856dd5ee2c2SEric Blake v = visitor_input_test_init(data, "[ '1', '2', false, '3' ]"); 85751e72bc1SEric Blake visit_type_strList(v, NULL, &q, &err); 858dd5ee2c2SEric Blake error_free_or_abort(&err); 85968ab47e4SEric Blake assert(!q); 8609b4e38feSEric Blake 8619b4e38feSEric Blake v = visitor_input_test_init(data, "{ 'str':'hi' }"); 8629b4e38feSEric Blake visit_type_UserDefTwo(v, NULL, &r, &err); 8639b4e38feSEric Blake error_free_or_abort(&err); 8649b4e38feSEric Blake assert(!r); 8659b4e38feSEric Blake 8669b4e38feSEric Blake v = visitor_input_test_init(data, "{ }"); 8679b4e38feSEric Blake visit_type_WrapAlternate(v, NULL, &s, &err); 8689b4e38feSEric Blake error_free_or_abort(&err); 8699b4e38feSEric Blake assert(!s); 8703dcf71f6SPaolo Bonzini } 8713dcf71f6SPaolo Bonzini 8722533377cSEric Blake static void test_visitor_in_wrong_type(TestInputVisitorData *data, 8732533377cSEric Blake const void *unused) 8742533377cSEric Blake { 8752533377cSEric Blake TestStruct *p = NULL; 8762533377cSEric Blake Visitor *v; 8772533377cSEric Blake strList *q = NULL; 8782533377cSEric Blake int64_t i; 8792533377cSEric Blake Error *err = NULL; 8802533377cSEric Blake 8812533377cSEric Blake /* Make sure arrays and structs cannot be confused */ 8822533377cSEric Blake 8832533377cSEric Blake v = visitor_input_test_init(data, "[]"); 88451e72bc1SEric Blake visit_type_TestStruct(v, NULL, &p, &err); 8852533377cSEric Blake error_free_or_abort(&err); 8862533377cSEric Blake g_assert(!p); 8872533377cSEric Blake 8882533377cSEric Blake v = visitor_input_test_init(data, "{}"); 88951e72bc1SEric Blake visit_type_strList(v, NULL, &q, &err); 8902533377cSEric Blake error_free_or_abort(&err); 8912533377cSEric Blake assert(!q); 8922533377cSEric Blake 8932533377cSEric Blake /* Make sure primitives and struct cannot be confused */ 8942533377cSEric Blake 8952533377cSEric Blake v = visitor_input_test_init(data, "1"); 89651e72bc1SEric Blake visit_type_TestStruct(v, NULL, &p, &err); 8972533377cSEric Blake error_free_or_abort(&err); 8982533377cSEric Blake g_assert(!p); 8992533377cSEric Blake 9002533377cSEric Blake v = visitor_input_test_init(data, "{}"); 90151e72bc1SEric Blake visit_type_int(v, NULL, &i, &err); 9022533377cSEric Blake error_free_or_abort(&err); 9032533377cSEric Blake 9042533377cSEric Blake /* Make sure primitives and arrays cannot be confused */ 9052533377cSEric Blake 9062533377cSEric Blake v = visitor_input_test_init(data, "1"); 90751e72bc1SEric Blake visit_type_strList(v, NULL, &q, &err); 9082533377cSEric Blake error_free_or_abort(&err); 9092533377cSEric Blake assert(!q); 9102533377cSEric Blake 9112533377cSEric Blake v = visitor_input_test_init(data, "[]"); 91251e72bc1SEric Blake visit_type_int(v, NULL, &i, &err); 9132533377cSEric Blake error_free_or_abort(&err); 9142533377cSEric Blake } 9152533377cSEric Blake 91677c47de2SMarkus Armbruster static void test_visitor_in_fail_struct(TestInputVisitorData *data, 91777c47de2SMarkus Armbruster const void *unused) 91877c47de2SMarkus Armbruster { 91977c47de2SMarkus Armbruster TestStruct *p = NULL; 92077c47de2SMarkus Armbruster Error *err = NULL; 92177c47de2SMarkus Armbruster Visitor *v; 92277c47de2SMarkus Armbruster 92377c47de2SMarkus Armbruster v = visitor_input_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo', 'extra': 42 }"); 92477c47de2SMarkus Armbruster 92577c47de2SMarkus Armbruster visit_type_TestStruct(v, NULL, &p, &err); 92677c47de2SMarkus Armbruster error_free_or_abort(&err); 92777c47de2SMarkus Armbruster g_assert(!p); 92877c47de2SMarkus Armbruster } 92977c47de2SMarkus Armbruster 93077c47de2SMarkus Armbruster static void test_visitor_in_fail_struct_nested(TestInputVisitorData *data, 93177c47de2SMarkus Armbruster const void *unused) 93277c47de2SMarkus Armbruster { 93377c47de2SMarkus Armbruster UserDefTwo *udp = NULL; 93477c47de2SMarkus Armbruster Error *err = NULL; 93577c47de2SMarkus Armbruster Visitor *v; 93677c47de2SMarkus Armbruster 93777c47de2SMarkus Armbruster v = visitor_input_test_init(data, "{ 'string0': 'string0', 'dict1': { 'string1': 'string1', 'dict2': { 'userdef1': { 'integer': 42, 'string': 'string', 'extra': [42, 23, {'foo':'bar'}] }, 'string2': 'string2'}}}"); 93877c47de2SMarkus Armbruster 93977c47de2SMarkus Armbruster visit_type_UserDefTwo(v, NULL, &udp, &err); 94077c47de2SMarkus Armbruster error_free_or_abort(&err); 94177c47de2SMarkus Armbruster g_assert(!udp); 94277c47de2SMarkus Armbruster } 94377c47de2SMarkus Armbruster 94477c47de2SMarkus Armbruster static void test_visitor_in_fail_struct_in_list(TestInputVisitorData *data, 94577c47de2SMarkus Armbruster const void *unused) 94677c47de2SMarkus Armbruster { 94777c47de2SMarkus Armbruster UserDefOneList *head = NULL; 94877c47de2SMarkus Armbruster Error *err = NULL; 94977c47de2SMarkus Armbruster Visitor *v; 95077c47de2SMarkus Armbruster 95177c47de2SMarkus Armbruster v = visitor_input_test_init(data, "[ { 'string': 'string0', 'integer': 42 }, { 'string': 'string1', 'integer': 43 }, { 'string': 'string2', 'integer': 44, 'extra': 'ggg' } ]"); 95277c47de2SMarkus Armbruster 95377c47de2SMarkus Armbruster visit_type_UserDefOneList(v, NULL, &head, &err); 95477c47de2SMarkus Armbruster error_free_or_abort(&err); 95577c47de2SMarkus Armbruster g_assert(!head); 95677c47de2SMarkus Armbruster } 95777c47de2SMarkus Armbruster 95877c47de2SMarkus Armbruster static void test_visitor_in_fail_struct_missing(TestInputVisitorData *data, 95977c47de2SMarkus Armbruster const void *unused) 96077c47de2SMarkus Armbruster { 96177c47de2SMarkus Armbruster Error *err = NULL; 96277c47de2SMarkus Armbruster Visitor *v; 96377c47de2SMarkus Armbruster QObject *any; 964d2f95f4dSMarkus Armbruster QNull *null; 96577c47de2SMarkus Armbruster GenericAlternate *alt; 96677c47de2SMarkus Armbruster bool present; 96777c47de2SMarkus Armbruster int en; 96877c47de2SMarkus Armbruster int64_t i64; 96977c47de2SMarkus Armbruster uint32_t u32; 97077c47de2SMarkus Armbruster int8_t i8; 97177c47de2SMarkus Armbruster char *str; 97277c47de2SMarkus Armbruster double dbl; 97377c47de2SMarkus Armbruster 97486ca0dbeSMarkus Armbruster v = visitor_input_test_init(data, "{ 'sub': [ {} ] }"); 97577c47de2SMarkus Armbruster visit_start_struct(v, NULL, NULL, 0, &error_abort); 97677c47de2SMarkus Armbruster visit_start_struct(v, "struct", NULL, 0, &err); 97777c47de2SMarkus Armbruster error_free_or_abort(&err); 97877c47de2SMarkus Armbruster visit_start_list(v, "list", NULL, 0, &err); 97977c47de2SMarkus Armbruster error_free_or_abort(&err); 98060390d2dSMarc-André Lureau visit_start_alternate(v, "alternate", &alt, sizeof(*alt), &err); 98177c47de2SMarkus Armbruster error_free_or_abort(&err); 98277c47de2SMarkus Armbruster visit_optional(v, "optional", &present); 98377c47de2SMarkus Armbruster g_assert(!present); 984f7abe0ecSMarc-André Lureau visit_type_enum(v, "enum", &en, &EnumOne_lookup, &err); 98577c47de2SMarkus Armbruster error_free_or_abort(&err); 98677c47de2SMarkus Armbruster visit_type_int(v, "i64", &i64, &err); 98777c47de2SMarkus Armbruster error_free_or_abort(&err); 98877c47de2SMarkus Armbruster visit_type_uint32(v, "u32", &u32, &err); 98977c47de2SMarkus Armbruster error_free_or_abort(&err); 99077c47de2SMarkus Armbruster visit_type_int8(v, "i8", &i8, &err); 99177c47de2SMarkus Armbruster error_free_or_abort(&err); 99277c47de2SMarkus Armbruster visit_type_str(v, "i8", &str, &err); 99377c47de2SMarkus Armbruster error_free_or_abort(&err); 99477c47de2SMarkus Armbruster visit_type_number(v, "dbl", &dbl, &err); 99577c47de2SMarkus Armbruster error_free_or_abort(&err); 99677c47de2SMarkus Armbruster visit_type_any(v, "any", &any, &err); 99777c47de2SMarkus Armbruster error_free_or_abort(&err); 998d2f95f4dSMarkus Armbruster visit_type_null(v, "null", &null, &err); 99977c47de2SMarkus Armbruster error_free_or_abort(&err); 100086ca0dbeSMarkus Armbruster visit_start_list(v, "sub", NULL, 0, &error_abort); 100186ca0dbeSMarkus Armbruster visit_start_struct(v, NULL, NULL, 0, &error_abort); 100286ca0dbeSMarkus Armbruster visit_type_int(v, "i64", &i64, &err); 100386ca0dbeSMarkus Armbruster error_free_or_abort(&err); 100486ca0dbeSMarkus Armbruster visit_end_struct(v, NULL); 100586ca0dbeSMarkus Armbruster visit_end_list(v, NULL); 100677c47de2SMarkus Armbruster visit_end_struct(v, NULL); 100777c47de2SMarkus Armbruster } 100877c47de2SMarkus Armbruster 10099cb8ef36SMarkus Armbruster static void test_visitor_in_fail_list(TestInputVisitorData *data, 10109cb8ef36SMarkus Armbruster const void *unused) 10119cb8ef36SMarkus Armbruster { 10129cb8ef36SMarkus Armbruster int64_t i64 = -1; 1013a4a1c70dSMarkus Armbruster Error *err = NULL; 10149cb8ef36SMarkus Armbruster Visitor *v; 10159cb8ef36SMarkus Armbruster 10169cb8ef36SMarkus Armbruster /* Unvisited list tail */ 10179cb8ef36SMarkus Armbruster 10189cb8ef36SMarkus Armbruster v = visitor_input_test_init(data, "[ 1, 2, 3 ]"); 10199cb8ef36SMarkus Armbruster 10209cb8ef36SMarkus Armbruster visit_start_list(v, NULL, NULL, 0, &error_abort); 10219cb8ef36SMarkus Armbruster visit_type_int(v, NULL, &i64, &error_abort); 10229cb8ef36SMarkus Armbruster g_assert_cmpint(i64, ==, 1); 10239cb8ef36SMarkus Armbruster visit_type_int(v, NULL, &i64, &error_abort); 10249cb8ef36SMarkus Armbruster g_assert_cmpint(i64, ==, 2); 1025a4a1c70dSMarkus Armbruster visit_check_list(v, &err); 1026a4a1c70dSMarkus Armbruster error_free_or_abort(&err); 10279cb8ef36SMarkus Armbruster visit_end_list(v, NULL); 1028a9416dc6SMarkus Armbruster 1029a9416dc6SMarkus Armbruster /* Visit beyond end of list */ 1030a9416dc6SMarkus Armbruster v = visitor_input_test_init(data, "[]"); 1031a9416dc6SMarkus Armbruster 1032a9416dc6SMarkus Armbruster visit_start_list(v, NULL, NULL, 0, &error_abort); 1033a9416dc6SMarkus Armbruster visit_type_int(v, NULL, &i64, &err); 1034a9416dc6SMarkus Armbruster error_free_or_abort(&err); 1035a9416dc6SMarkus Armbruster visit_end_list(v, NULL); 10369cb8ef36SMarkus Armbruster } 10379cb8ef36SMarkus Armbruster 10389cb8ef36SMarkus Armbruster static void test_visitor_in_fail_list_nested(TestInputVisitorData *data, 10399cb8ef36SMarkus Armbruster const void *unused) 10409cb8ef36SMarkus Armbruster { 10419cb8ef36SMarkus Armbruster int64_t i64 = -1; 1042a4a1c70dSMarkus Armbruster Error *err = NULL; 10439cb8ef36SMarkus Armbruster Visitor *v; 10449cb8ef36SMarkus Armbruster 10459cb8ef36SMarkus Armbruster /* Unvisited nested list tail */ 10469cb8ef36SMarkus Armbruster 10479cb8ef36SMarkus Armbruster v = visitor_input_test_init(data, "[ 0, [ 1, 2, 3 ] ]"); 10489cb8ef36SMarkus Armbruster 10499cb8ef36SMarkus Armbruster visit_start_list(v, NULL, NULL, 0, &error_abort); 10509cb8ef36SMarkus Armbruster visit_type_int(v, NULL, &i64, &error_abort); 10519cb8ef36SMarkus Armbruster g_assert_cmpint(i64, ==, 0); 10529cb8ef36SMarkus Armbruster visit_start_list(v, NULL, NULL, 0, &error_abort); 10539cb8ef36SMarkus Armbruster visit_type_int(v, NULL, &i64, &error_abort); 10549cb8ef36SMarkus Armbruster g_assert_cmpint(i64, ==, 1); 1055a4a1c70dSMarkus Armbruster visit_check_list(v, &err); 1056a4a1c70dSMarkus Armbruster error_free_or_abort(&err); 10579cb8ef36SMarkus Armbruster visit_end_list(v, NULL); 1058a4a1c70dSMarkus Armbruster visit_check_list(v, &error_abort); 10599cb8ef36SMarkus Armbruster visit_end_list(v, NULL); 10609cb8ef36SMarkus Armbruster } 10619cb8ef36SMarkus Armbruster 106277c47de2SMarkus Armbruster static void test_visitor_in_fail_union_flat(TestInputVisitorData *data, 106377c47de2SMarkus Armbruster const void *unused) 106477c47de2SMarkus Armbruster { 106577c47de2SMarkus Armbruster UserDefFlatUnion *tmp = NULL; 106677c47de2SMarkus Armbruster Error *err = NULL; 106777c47de2SMarkus Armbruster Visitor *v; 106877c47de2SMarkus Armbruster 1069*e7a76fe2SMarkus Armbruster v = visitor_input_test_init(data, "{ 'enum1': 'value2', 'string': 'c', 'integer': 41, 'boolean': true }"); 107077c47de2SMarkus Armbruster 107177c47de2SMarkus Armbruster visit_type_UserDefFlatUnion(v, NULL, &tmp, &err); 107277c47de2SMarkus Armbruster error_free_or_abort(&err); 107377c47de2SMarkus Armbruster g_assert(!tmp); 107477c47de2SMarkus Armbruster } 107577c47de2SMarkus Armbruster 107677c47de2SMarkus Armbruster static void test_visitor_in_fail_union_flat_no_discrim(TestInputVisitorData *data, 107777c47de2SMarkus Armbruster const void *unused) 107877c47de2SMarkus Armbruster { 107977c47de2SMarkus Armbruster UserDefFlatUnion2 *tmp = NULL; 108077c47de2SMarkus Armbruster Error *err = NULL; 108177c47de2SMarkus Armbruster Visitor *v; 108277c47de2SMarkus Armbruster 108377c47de2SMarkus Armbruster /* test situation where discriminator field ('enum1' here) is missing */ 108477c47de2SMarkus Armbruster v = visitor_input_test_init(data, "{ 'integer': 42, 'string': 'c', 'string1': 'd', 'string2': 'e' }"); 108577c47de2SMarkus Armbruster 108677c47de2SMarkus Armbruster visit_type_UserDefFlatUnion2(v, NULL, &tmp, &err); 108777c47de2SMarkus Armbruster error_free_or_abort(&err); 108877c47de2SMarkus Armbruster g_assert(!tmp); 108977c47de2SMarkus Armbruster } 109077c47de2SMarkus Armbruster 109177c47de2SMarkus Armbruster static void test_visitor_in_fail_alternate(TestInputVisitorData *data, 109277c47de2SMarkus Armbruster const void *unused) 109377c47de2SMarkus Armbruster { 109477c47de2SMarkus Armbruster UserDefAlternate *tmp; 109577c47de2SMarkus Armbruster Visitor *v; 109677c47de2SMarkus Armbruster Error *err = NULL; 109777c47de2SMarkus Armbruster 109877c47de2SMarkus Armbruster v = visitor_input_test_init(data, "3.14"); 109977c47de2SMarkus Armbruster 110077c47de2SMarkus Armbruster visit_type_UserDefAlternate(v, NULL, &tmp, &err); 110177c47de2SMarkus Armbruster error_free_or_abort(&err); 110277c47de2SMarkus Armbruster g_assert(!tmp); 110377c47de2SMarkus Armbruster } 110477c47de2SMarkus Armbruster 110577c47de2SMarkus Armbruster static void do_test_visitor_in_qmp_introspect(TestInputVisitorData *data, 11067d0f982bSMarc-André Lureau const QLitObject *qlit) 110777c47de2SMarkus Armbruster { 1108221db5daSDaniel P. Berrangé g_autoptr(SchemaInfoList) schema = NULL; 11097d0f982bSMarc-André Lureau QObject *obj = qobject_from_qlit(qlit); 111077c47de2SMarkus Armbruster Visitor *v; 111177c47de2SMarkus Armbruster 11127d0f982bSMarc-André Lureau v = qobject_input_visitor_new(obj); 111377c47de2SMarkus Armbruster 111477c47de2SMarkus Armbruster visit_type_SchemaInfoList(v, NULL, &schema, &error_abort); 111577c47de2SMarkus Armbruster g_assert(schema); 111677c47de2SMarkus Armbruster 1117cb3e7f08SMarc-André Lureau qobject_unref(obj); 11187d0f982bSMarc-André Lureau visit_free(v); 111977c47de2SMarkus Armbruster } 112077c47de2SMarkus Armbruster 112177c47de2SMarkus Armbruster static void test_visitor_in_qmp_introspect(TestInputVisitorData *data, 112277c47de2SMarkus Armbruster const void *unused) 112377c47de2SMarkus Armbruster { 11247d0f982bSMarc-André Lureau do_test_visitor_in_qmp_introspect(data, &test_qmp_schema_qlit); 112577c47de2SMarkus Armbruster } 112677c47de2SMarkus Armbruster 1127d88f5fd1SLuiz Capitulino int main(int argc, char **argv) 1128d88f5fd1SLuiz Capitulino { 1129d88f5fd1SLuiz Capitulino g_test_init(&argc, &argv, NULL); 1130d88f5fd1SLuiz Capitulino 1131d88f5fd1SLuiz Capitulino input_visitor_test_add("/visitor/input/int", 1132b1d2e5f1SDaniel P. Berrange NULL, test_visitor_in_int); 11334bc0c94dSMarkus Armbruster input_visitor_test_add("/visitor/input/uint", 11344bc0c94dSMarkus Armbruster NULL, test_visitor_in_uint); 1135e92cfa0dSMichael Roth input_visitor_test_add("/visitor/input/int_overflow", 1136b1d2e5f1SDaniel P. Berrange NULL, test_visitor_in_int_overflow); 1137cbd8acf3SDaniel P. Berrange input_visitor_test_add("/visitor/input/int_keyval", 1138cbd8acf3SDaniel P. Berrange NULL, test_visitor_in_int_keyval); 1139cbd8acf3SDaniel P. Berrange input_visitor_test_add("/visitor/input/int_str_keyval", 1140cbd8acf3SDaniel P. Berrange NULL, test_visitor_in_int_str_keyval); 1141cbd8acf3SDaniel P. Berrange input_visitor_test_add("/visitor/input/int_str_fail", 1142cbd8acf3SDaniel P. Berrange NULL, test_visitor_in_int_str_fail); 1143d88f5fd1SLuiz Capitulino input_visitor_test_add("/visitor/input/bool", 1144b1d2e5f1SDaniel P. Berrange NULL, test_visitor_in_bool); 1145cbd8acf3SDaniel P. Berrange input_visitor_test_add("/visitor/input/bool_keyval", 1146cbd8acf3SDaniel P. Berrange NULL, test_visitor_in_bool_keyval); 1147cbd8acf3SDaniel P. Berrange input_visitor_test_add("/visitor/input/bool_str_keyval", 1148cbd8acf3SDaniel P. Berrange NULL, test_visitor_in_bool_str_keyval); 1149cbd8acf3SDaniel P. Berrange input_visitor_test_add("/visitor/input/bool_str_fail", 1150cbd8acf3SDaniel P. Berrange NULL, test_visitor_in_bool_str_fail); 1151d88f5fd1SLuiz Capitulino input_visitor_test_add("/visitor/input/number", 1152b1d2e5f1SDaniel P. Berrange NULL, test_visitor_in_number); 1153c1214ad3SMarc-André Lureau input_visitor_test_add("/visitor/input/large_number", 1154c1214ad3SMarc-André Lureau NULL, test_visitor_in_large_number); 1155cbd8acf3SDaniel P. Berrange input_visitor_test_add("/visitor/input/number_keyval", 1156cbd8acf3SDaniel P. Berrange NULL, test_visitor_in_number_keyval); 1157cbd8acf3SDaniel P. Berrange input_visitor_test_add("/visitor/input/number_str_keyval", 1158cbd8acf3SDaniel P. Berrange NULL, test_visitor_in_number_str_keyval); 1159cbd8acf3SDaniel P. Berrange input_visitor_test_add("/visitor/input/number_str_fail", 1160cbd8acf3SDaniel P. Berrange NULL, test_visitor_in_number_str_fail); 1161cbd8acf3SDaniel P. Berrange input_visitor_test_add("/visitor/input/size_str_keyval", 1162cbd8acf3SDaniel P. Berrange NULL, test_visitor_in_size_str_keyval); 1163cbd8acf3SDaniel P. Berrange input_visitor_test_add("/visitor/input/size_str_fail", 1164cbd8acf3SDaniel P. Berrange NULL, test_visitor_in_size_str_fail); 1165d88f5fd1SLuiz Capitulino input_visitor_test_add("/visitor/input/string", 1166b1d2e5f1SDaniel P. Berrange NULL, test_visitor_in_string); 1167d88f5fd1SLuiz Capitulino input_visitor_test_add("/visitor/input/enum", 1168b1d2e5f1SDaniel P. Berrange NULL, test_visitor_in_enum); 1169d88f5fd1SLuiz Capitulino input_visitor_test_add("/visitor/input/struct", 1170b1d2e5f1SDaniel P. Berrange NULL, test_visitor_in_struct); 1171d88f5fd1SLuiz Capitulino input_visitor_test_add("/visitor/input/struct-nested", 1172b1d2e5f1SDaniel P. Berrange NULL, test_visitor_in_struct_nested); 1173*e7a76fe2SMarkus Armbruster input_visitor_test_add("/visitor/input/list2", 1174*e7a76fe2SMarkus Armbruster NULL, test_visitor_in_list_struct); 1175d88f5fd1SLuiz Capitulino input_visitor_test_add("/visitor/input/list", 1176b1d2e5f1SDaniel P. Berrange NULL, test_visitor_in_list); 117728770e05SMarkus Armbruster input_visitor_test_add("/visitor/input/any", 1178b1d2e5f1SDaniel P. Berrange NULL, test_visitor_in_any); 11793df016f1SEric Blake input_visitor_test_add("/visitor/input/null", 1180b1d2e5f1SDaniel P. Berrange NULL, test_visitor_in_null); 11812fc00432SMarkus Armbruster input_visitor_test_add("/visitor/input/union-flat", 1182b1d2e5f1SDaniel P. Berrange NULL, test_visitor_in_union_flat); 1183ab045267SEric Blake input_visitor_test_add("/visitor/input/alternate", 1184b1d2e5f1SDaniel P. Berrange NULL, test_visitor_in_alternate); 11853dcf71f6SPaolo Bonzini input_visitor_test_add("/visitor/input/errors", 1186b1d2e5f1SDaniel P. Berrange NULL, test_visitor_in_errors); 11872533377cSEric Blake input_visitor_test_add("/visitor/input/wrong-type", 1188b1d2e5f1SDaniel P. Berrange NULL, test_visitor_in_wrong_type); 11899c51b441SEric Blake input_visitor_test_add("/visitor/input/alternate-number", 1190b1d2e5f1SDaniel P. Berrange NULL, test_visitor_in_alternate_number); 119177c47de2SMarkus Armbruster input_visitor_test_add("/visitor/input/fail/struct", 119277c47de2SMarkus Armbruster NULL, test_visitor_in_fail_struct); 119377c47de2SMarkus Armbruster input_visitor_test_add("/visitor/input/fail/struct-nested", 119477c47de2SMarkus Armbruster NULL, test_visitor_in_fail_struct_nested); 119577c47de2SMarkus Armbruster input_visitor_test_add("/visitor/input/fail/struct-in-list", 119677c47de2SMarkus Armbruster NULL, test_visitor_in_fail_struct_in_list); 119777c47de2SMarkus Armbruster input_visitor_test_add("/visitor/input/fail/struct-missing", 119877c47de2SMarkus Armbruster NULL, test_visitor_in_fail_struct_missing); 11999cb8ef36SMarkus Armbruster input_visitor_test_add("/visitor/input/fail/list", 12009cb8ef36SMarkus Armbruster NULL, test_visitor_in_fail_list); 12019cb8ef36SMarkus Armbruster input_visitor_test_add("/visitor/input/fail/list-nested", 12029cb8ef36SMarkus Armbruster NULL, test_visitor_in_fail_list_nested); 120377c47de2SMarkus Armbruster input_visitor_test_add("/visitor/input/fail/union-flat", 120477c47de2SMarkus Armbruster NULL, test_visitor_in_fail_union_flat); 120577c47de2SMarkus Armbruster input_visitor_test_add("/visitor/input/fail/union-flat-no-discriminator", 120677c47de2SMarkus Armbruster NULL, test_visitor_in_fail_union_flat_no_discrim); 120777c47de2SMarkus Armbruster input_visitor_test_add("/visitor/input/fail/alternate", 120877c47de2SMarkus Armbruster NULL, test_visitor_in_fail_alternate); 1209eb815e24SMarkus Armbruster input_visitor_test_add("/visitor/input/qapi-introspect", 121077c47de2SMarkus Armbruster NULL, test_visitor_in_qmp_introspect); 1211d88f5fd1SLuiz Capitulino 1212d88f5fd1SLuiz Capitulino g_test_run(); 1213d88f5fd1SLuiz Capitulino 1214d88f5fd1SLuiz Capitulino return 0; 1215d88f5fd1SLuiz Capitulino } 1216