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 16da34e65cSMarkus Armbruster #include "qapi/error.h" 17112ed241SMarkus Armbruster #include "qapi/qapi-visit-introspect.h" 18b3db211fSDaniel P. Berrange #include "qapi/qobject-input-visitor.h" 19d88f5fd1SLuiz Capitulino #include "test-qapi-visit.h" 206b673957SMarkus Armbruster #include "qapi/qmp/qbool.h" 21452fcdbcSMarkus Armbruster #include "qapi/qmp/qdict.h" 2215280c36SMarkus Armbruster #include "qapi/qmp/qnull.h" 2315280c36SMarkus Armbruster #include "qapi/qmp/qnum.h" 24fc81fa1eSMarkus Armbruster #include "qapi/qmp/qstring.h" 25c7eb39cbSEric Blake #include "qapi/qmp/qjson.h" 26eb815e24SMarkus Armbruster #include "test-qapi-introspect.h" 27eb815e24SMarkus Armbruster #include "qapi/qapi-introspect.h" 28d88f5fd1SLuiz Capitulino 29d88f5fd1SLuiz Capitulino typedef struct TestInputVisitorData { 30d88f5fd1SLuiz Capitulino QObject *obj; 31b70ce101SEric Blake Visitor *qiv; 32d88f5fd1SLuiz Capitulino } TestInputVisitorData; 33d88f5fd1SLuiz Capitulino 34d88f5fd1SLuiz Capitulino static void visitor_input_teardown(TestInputVisitorData *data, 35d88f5fd1SLuiz Capitulino const void *unused) 36d88f5fd1SLuiz Capitulino { 37cb3e7f08SMarc-André Lureau qobject_unref(data->obj); 38d88f5fd1SLuiz Capitulino data->obj = NULL; 39d88f5fd1SLuiz Capitulino 40d88f5fd1SLuiz Capitulino if (data->qiv) { 41b70ce101SEric Blake visit_free(data->qiv); 42d88f5fd1SLuiz Capitulino data->qiv = NULL; 43d88f5fd1SLuiz Capitulino } 44d88f5fd1SLuiz Capitulino } 45d88f5fd1SLuiz Capitulino 460920a171SEric Blake /* The various test_init functions are provided instead of a test setup 470920a171SEric Blake function so that the JSON string used by the tests are kept in the test 480920a171SEric Blake functions (and not in main()). */ 49eac78bd4SMarkus Armbruster 50eac78bd4SMarkus Armbruster static Visitor *test_init_internal(TestInputVisitorData *data, bool keyval, 51eac78bd4SMarkus Armbruster QObject *obj) 520920a171SEric Blake { 53b18f1141SEric Blake visitor_input_teardown(data, NULL); 54b18f1141SEric Blake 55eac78bd4SMarkus Armbruster data->obj = obj; 560920a171SEric Blake 57cbd8acf3SDaniel P. Berrange if (keyval) { 58cbd8acf3SDaniel P. Berrange data->qiv = qobject_input_visitor_new_keyval(data->obj); 59cbd8acf3SDaniel P. Berrange } else { 60048abb7bSMarkus Armbruster data->qiv = qobject_input_visitor_new(data->obj); 61cbd8acf3SDaniel P. Berrange } 620920a171SEric Blake g_assert(data->qiv); 63b70ce101SEric Blake return data->qiv; 640920a171SEric Blake } 650920a171SEric Blake 669edc6313SMarc-André Lureau static G_GNUC_PRINTF(3, 4) 67cbd8acf3SDaniel P. Berrange Visitor *visitor_input_test_init_full(TestInputVisitorData *data, 68cbd8acf3SDaniel P. Berrange bool keyval, 69cbd8acf3SDaniel P. Berrange const char *json_string, ...) 70cbd8acf3SDaniel P. Berrange { 71cbd8acf3SDaniel P. Berrange Visitor *v; 72cbd8acf3SDaniel P. Berrange va_list ap; 73cbd8acf3SDaniel P. Berrange 74cbd8acf3SDaniel P. Berrange va_start(ap, json_string); 75eac78bd4SMarkus Armbruster v = test_init_internal(data, keyval, 76eac78bd4SMarkus Armbruster qobject_from_vjsonf_nofail(json_string, ap)); 77cbd8acf3SDaniel P. Berrange va_end(ap); 78cbd8acf3SDaniel P. Berrange return v; 79cbd8acf3SDaniel P. Berrange } 80cbd8acf3SDaniel P. Berrange 819edc6313SMarc-André Lureau static G_GNUC_PRINTF(2, 3) 82aba2107aSStefan Weil Visitor *visitor_input_test_init(TestInputVisitorData *data, 83d88f5fd1SLuiz Capitulino const char *json_string, ...) 84d88f5fd1SLuiz Capitulino { 85d88f5fd1SLuiz Capitulino Visitor *v; 86d88f5fd1SLuiz Capitulino va_list ap; 87d88f5fd1SLuiz Capitulino 88d88f5fd1SLuiz Capitulino va_start(ap, json_string); 89eac78bd4SMarkus Armbruster v = test_init_internal(data, false, 90eac78bd4SMarkus Armbruster qobject_from_vjsonf_nofail(json_string, ap)); 91d88f5fd1SLuiz Capitulino va_end(ap); 92d88f5fd1SLuiz Capitulino return v; 93d88f5fd1SLuiz Capitulino } 94d88f5fd1SLuiz Capitulino 95199e0f17SMichael Roth /* similar to visitor_input_test_init(), but does not expect a string 96199e0f17SMichael Roth * literal/format json_string argument and so can be used for 97199e0f17SMichael Roth * programatically generated strings (and we can't pass in programatically 98199e0f17SMichael Roth * generated strings via %s format parameters since qobject_from_jsonv() 99199e0f17SMichael Roth * will wrap those in double-quotes and treat the entire object as a 100199e0f17SMichael Roth * string) 101199e0f17SMichael Roth */ 102199e0f17SMichael Roth static Visitor *visitor_input_test_init_raw(TestInputVisitorData *data, 103199e0f17SMichael Roth const char *json_string) 104199e0f17SMichael Roth { 105eac78bd4SMarkus Armbruster return test_init_internal(data, false, 106eac78bd4SMarkus Armbruster qobject_from_json(json_string, &error_abort)); 107199e0f17SMichael Roth } 108199e0f17SMichael Roth 109d88f5fd1SLuiz Capitulino static void test_visitor_in_int(TestInputVisitorData *data, 110d88f5fd1SLuiz Capitulino const void *unused) 111d88f5fd1SLuiz Capitulino { 11229a6731aSEric Blake int64_t res = 0; 113c1214ad3SMarc-André Lureau double dbl; 11429a6731aSEric Blake int value = -42; 115d88f5fd1SLuiz Capitulino Visitor *v; 116d88f5fd1SLuiz Capitulino 11729a6731aSEric Blake v = visitor_input_test_init(data, "%d", value); 118d88f5fd1SLuiz Capitulino 11951e72bc1SEric Blake visit_type_int(v, NULL, &res, &error_abort); 120d88f5fd1SLuiz Capitulino g_assert_cmpint(res, ==, value); 121c1214ad3SMarc-André Lureau 122c1214ad3SMarc-André Lureau visit_type_number(v, NULL, &dbl, &error_abort); 123c1214ad3SMarc-André Lureau g_assert_cmpfloat(dbl, ==, -42.0); 124d88f5fd1SLuiz Capitulino } 125d88f5fd1SLuiz Capitulino 1264bc0c94dSMarkus Armbruster static void test_visitor_in_uint(TestInputVisitorData *data, 1274bc0c94dSMarkus Armbruster const void *unused) 1284bc0c94dSMarkus Armbruster { 1294bc0c94dSMarkus Armbruster uint64_t res = 0; 130c1214ad3SMarc-André Lureau int64_t i64; 131c1214ad3SMarc-André Lureau double dbl; 1324bc0c94dSMarkus Armbruster int value = 42; 1334bc0c94dSMarkus Armbruster Visitor *v; 1344bc0c94dSMarkus Armbruster 1354bc0c94dSMarkus Armbruster v = visitor_input_test_init(data, "%d", value); 1364bc0c94dSMarkus Armbruster 1374bc0c94dSMarkus Armbruster visit_type_uint64(v, NULL, &res, &error_abort); 1384bc0c94dSMarkus Armbruster g_assert_cmpuint(res, ==, (uint64_t)value); 1394bc0c94dSMarkus Armbruster 140c1214ad3SMarc-André Lureau visit_type_int(v, NULL, &i64, &error_abort); 141c1214ad3SMarc-André Lureau g_assert_cmpint(i64, ==, value); 1424bc0c94dSMarkus Armbruster 143c1214ad3SMarc-André Lureau visit_type_number(v, NULL, &dbl, &error_abort); 144c1214ad3SMarc-André Lureau g_assert_cmpfloat(dbl, ==, value); 145c1214ad3SMarc-André Lureau 146c1214ad3SMarc-André Lureau /* BUG: value between INT64_MIN and -1 accepted modulo 2^64 */ 1474bc0c94dSMarkus Armbruster v = visitor_input_test_init(data, "%d", -value); 1484bc0c94dSMarkus Armbruster 1494bc0c94dSMarkus Armbruster visit_type_uint64(v, NULL, &res, &error_abort); 1504bc0c94dSMarkus Armbruster g_assert_cmpuint(res, ==, (uint64_t)-value); 1514bc0c94dSMarkus Armbruster 1524bc0c94dSMarkus Armbruster v = visitor_input_test_init(data, "18446744073709551574"); 1534bc0c94dSMarkus Armbruster 1545923f85fSMarc-André Lureau visit_type_uint64(v, NULL, &res, &error_abort); 1555923f85fSMarc-André Lureau g_assert_cmpuint(res, ==, 18446744073709551574U); 156c1214ad3SMarc-André Lureau 157c1214ad3SMarc-André Lureau visit_type_number(v, NULL, &dbl, &error_abort); 158c1214ad3SMarc-André Lureau g_assert_cmpfloat(dbl, ==, 18446744073709552000.0); 1594bc0c94dSMarkus Armbruster } 1604bc0c94dSMarkus Armbruster 161e92cfa0dSMichael Roth static void test_visitor_in_int_overflow(TestInputVisitorData *data, 162e92cfa0dSMichael Roth const void *unused) 163e92cfa0dSMichael Roth { 164e92cfa0dSMichael Roth int64_t res = 0; 165e940f543SMarkus Armbruster Error *err = NULL; 166e92cfa0dSMichael Roth Visitor *v; 167e92cfa0dSMichael Roth 16801b2ffceSMarc-André Lureau /* 16901b2ffceSMarc-André Lureau * This will overflow a QNUM_I64, so should be deserialized into a 17001b2ffceSMarc-André Lureau * QNUM_DOUBLE field instead, leading to an error if we pass it to 17101b2ffceSMarc-André Lureau * visit_type_int(). Confirm this. 172e92cfa0dSMichael Roth */ 173e92cfa0dSMichael Roth v = visitor_input_test_init(data, "%f", DBL_MAX); 174e92cfa0dSMichael Roth 17551e72bc1SEric Blake visit_type_int(v, NULL, &res, &err); 176a12a5a1aSEric Blake error_free_or_abort(&err); 177e92cfa0dSMichael Roth } 178e92cfa0dSMichael Roth 179cbd8acf3SDaniel P. Berrange static void test_visitor_in_int_keyval(TestInputVisitorData *data, 180cbd8acf3SDaniel P. Berrange const void *unused) 181cbd8acf3SDaniel P. Berrange { 182cbd8acf3SDaniel P. Berrange int64_t res = 0, value = -42; 183cbd8acf3SDaniel P. Berrange Error *err = NULL; 184cbd8acf3SDaniel P. Berrange Visitor *v; 185cbd8acf3SDaniel P. Berrange 186cbd8acf3SDaniel P. Berrange v = visitor_input_test_init_full(data, true, "%" PRId64, value); 187cbd8acf3SDaniel P. Berrange visit_type_int(v, NULL, &res, &err); 188cbd8acf3SDaniel P. Berrange error_free_or_abort(&err); 189cbd8acf3SDaniel P. Berrange } 190cbd8acf3SDaniel P. Berrange 191cbd8acf3SDaniel P. Berrange static void test_visitor_in_int_str_keyval(TestInputVisitorData *data, 192cbd8acf3SDaniel P. Berrange const void *unused) 193cbd8acf3SDaniel P. Berrange { 194cbd8acf3SDaniel P. Berrange int64_t res = 0, value = -42; 195cbd8acf3SDaniel P. Berrange Visitor *v; 196cbd8acf3SDaniel P. Berrange 197cbd8acf3SDaniel P. Berrange v = visitor_input_test_init_full(data, true, "\"-42\""); 198cbd8acf3SDaniel P. Berrange 199cbd8acf3SDaniel P. Berrange visit_type_int(v, NULL, &res, &error_abort); 200cbd8acf3SDaniel P. Berrange g_assert_cmpint(res, ==, value); 201cbd8acf3SDaniel P. Berrange } 202cbd8acf3SDaniel P. Berrange 203cbd8acf3SDaniel P. Berrange static void test_visitor_in_int_str_fail(TestInputVisitorData *data, 204cbd8acf3SDaniel P. Berrange const void *unused) 205cbd8acf3SDaniel P. Berrange { 206cbd8acf3SDaniel P. Berrange int64_t res = 0; 207cbd8acf3SDaniel P. Berrange Visitor *v; 208cbd8acf3SDaniel P. Berrange Error *err = NULL; 209cbd8acf3SDaniel P. Berrange 210cbd8acf3SDaniel P. Berrange v = visitor_input_test_init(data, "\"-42\""); 211cbd8acf3SDaniel P. Berrange 212cbd8acf3SDaniel P. Berrange visit_type_int(v, NULL, &res, &err); 213cbd8acf3SDaniel P. Berrange error_free_or_abort(&err); 214cbd8acf3SDaniel P. Berrange } 215cbd8acf3SDaniel P. Berrange 216d88f5fd1SLuiz Capitulino static void test_visitor_in_bool(TestInputVisitorData *data, 217d88f5fd1SLuiz Capitulino const void *unused) 218d88f5fd1SLuiz Capitulino { 219d88f5fd1SLuiz Capitulino bool res = false; 220d88f5fd1SLuiz Capitulino Visitor *v; 221d88f5fd1SLuiz Capitulino 222d88f5fd1SLuiz Capitulino v = visitor_input_test_init(data, "true"); 223d88f5fd1SLuiz Capitulino 22451e72bc1SEric Blake visit_type_bool(v, NULL, &res, &error_abort); 225d88f5fd1SLuiz Capitulino g_assert_cmpint(res, ==, true); 226d88f5fd1SLuiz Capitulino } 227d88f5fd1SLuiz Capitulino 228cbd8acf3SDaniel P. Berrange static void test_visitor_in_bool_keyval(TestInputVisitorData *data, 229cbd8acf3SDaniel P. Berrange const void *unused) 230cbd8acf3SDaniel P. Berrange { 231cbd8acf3SDaniel P. Berrange bool res = false; 232cbd8acf3SDaniel P. Berrange Error *err = NULL; 233cbd8acf3SDaniel P. Berrange Visitor *v; 234cbd8acf3SDaniel P. Berrange 235cbd8acf3SDaniel P. Berrange v = visitor_input_test_init_full(data, true, "true"); 236cbd8acf3SDaniel P. Berrange 237cbd8acf3SDaniel P. Berrange visit_type_bool(v, NULL, &res, &err); 238cbd8acf3SDaniel P. Berrange error_free_or_abort(&err); 239cbd8acf3SDaniel P. Berrange } 240cbd8acf3SDaniel P. Berrange 241cbd8acf3SDaniel P. Berrange static void test_visitor_in_bool_str_keyval(TestInputVisitorData *data, 242cbd8acf3SDaniel P. Berrange const void *unused) 243cbd8acf3SDaniel P. Berrange { 244cbd8acf3SDaniel P. Berrange bool res = false; 245cbd8acf3SDaniel P. Berrange Visitor *v; 246cbd8acf3SDaniel P. Berrange 247cbd8acf3SDaniel P. Berrange v = visitor_input_test_init_full(data, true, "\"on\""); 248cbd8acf3SDaniel P. Berrange 249cbd8acf3SDaniel P. Berrange visit_type_bool(v, NULL, &res, &error_abort); 250cbd8acf3SDaniel P. Berrange g_assert_cmpint(res, ==, true); 251cbd8acf3SDaniel P. Berrange } 252cbd8acf3SDaniel P. Berrange 253cbd8acf3SDaniel P. Berrange static void test_visitor_in_bool_str_fail(TestInputVisitorData *data, 254cbd8acf3SDaniel P. Berrange const void *unused) 255cbd8acf3SDaniel P. Berrange { 256cbd8acf3SDaniel P. Berrange bool res = false; 257cbd8acf3SDaniel P. Berrange Visitor *v; 258cbd8acf3SDaniel P. Berrange Error *err = NULL; 259cbd8acf3SDaniel P. Berrange 260cbd8acf3SDaniel P. Berrange v = visitor_input_test_init(data, "\"true\""); 261cbd8acf3SDaniel P. Berrange 262cbd8acf3SDaniel P. Berrange visit_type_bool(v, NULL, &res, &err); 263cbd8acf3SDaniel P. Berrange error_free_or_abort(&err); 264cbd8acf3SDaniel P. Berrange } 265cbd8acf3SDaniel P. Berrange 266d88f5fd1SLuiz Capitulino static void test_visitor_in_number(TestInputVisitorData *data, 267d88f5fd1SLuiz Capitulino const void *unused) 268d88f5fd1SLuiz Capitulino { 269d88f5fd1SLuiz Capitulino double res = 0, value = 3.14; 270d88f5fd1SLuiz Capitulino Visitor *v; 271d88f5fd1SLuiz Capitulino 272d88f5fd1SLuiz Capitulino v = visitor_input_test_init(data, "%f", value); 273d88f5fd1SLuiz Capitulino 27451e72bc1SEric Blake visit_type_number(v, NULL, &res, &error_abort); 275d88f5fd1SLuiz Capitulino g_assert_cmpfloat(res, ==, value); 276d88f5fd1SLuiz Capitulino } 277d88f5fd1SLuiz Capitulino 278c1214ad3SMarc-André Lureau static void test_visitor_in_large_number(TestInputVisitorData *data, 279c1214ad3SMarc-André Lureau const void *unused) 280c1214ad3SMarc-André Lureau { 281c1214ad3SMarc-André Lureau Error *err = NULL; 282c1214ad3SMarc-André Lureau double res = 0; 283c1214ad3SMarc-André Lureau int64_t i64; 284c1214ad3SMarc-André Lureau uint64_t u64; 285c1214ad3SMarc-André Lureau Visitor *v; 286c1214ad3SMarc-André Lureau 287c1214ad3SMarc-André Lureau v = visitor_input_test_init(data, "-18446744073709551616"); /* -2^64 */ 288c1214ad3SMarc-André Lureau 289c1214ad3SMarc-André Lureau visit_type_number(v, NULL, &res, &error_abort); 290c1214ad3SMarc-André Lureau g_assert_cmpfloat(res, ==, -18446744073709552e3); 291c1214ad3SMarc-André Lureau 292c1214ad3SMarc-André Lureau visit_type_int(v, NULL, &i64, &err); 293c1214ad3SMarc-André Lureau error_free_or_abort(&err); 294c1214ad3SMarc-André Lureau 295c1214ad3SMarc-André Lureau visit_type_uint64(v, NULL, &u64, &err); 296c1214ad3SMarc-André Lureau error_free_or_abort(&err); 297c1214ad3SMarc-André Lureau } 298c1214ad3SMarc-André Lureau 299cbd8acf3SDaniel P. Berrange static void test_visitor_in_number_keyval(TestInputVisitorData *data, 300cbd8acf3SDaniel P. Berrange const void *unused) 301cbd8acf3SDaniel P. Berrange { 302cbd8acf3SDaniel P. Berrange double res = 0, value = 3.14; 303cbd8acf3SDaniel P. Berrange Error *err = NULL; 304cbd8acf3SDaniel P. Berrange Visitor *v; 305cbd8acf3SDaniel P. Berrange 306cbd8acf3SDaniel P. Berrange v = visitor_input_test_init_full(data, true, "%f", value); 307cbd8acf3SDaniel P. Berrange 308cbd8acf3SDaniel P. Berrange visit_type_number(v, NULL, &res, &err); 309cbd8acf3SDaniel P. Berrange error_free_or_abort(&err); 310cbd8acf3SDaniel P. Berrange } 311cbd8acf3SDaniel P. Berrange 312cbd8acf3SDaniel P. Berrange static void test_visitor_in_number_str_keyval(TestInputVisitorData *data, 313cbd8acf3SDaniel P. Berrange const void *unused) 314cbd8acf3SDaniel P. Berrange { 315cbd8acf3SDaniel P. Berrange double res = 0, value = 3.14; 316cbd8acf3SDaniel P. Berrange Visitor *v; 3175891c388SMarkus Armbruster Error *err = NULL; 318cbd8acf3SDaniel P. Berrange 319cbd8acf3SDaniel P. Berrange v = visitor_input_test_init_full(data, true, "\"3.14\""); 320cbd8acf3SDaniel P. Berrange 321cbd8acf3SDaniel P. Berrange visit_type_number(v, NULL, &res, &error_abort); 322cbd8acf3SDaniel P. Berrange g_assert_cmpfloat(res, ==, value); 3235891c388SMarkus Armbruster 3245891c388SMarkus Armbruster v = visitor_input_test_init_full(data, true, "\"inf\""); 3255891c388SMarkus Armbruster 3265891c388SMarkus Armbruster visit_type_number(v, NULL, &res, &err); 3275891c388SMarkus Armbruster error_free_or_abort(&err); 328cbd8acf3SDaniel P. Berrange } 329cbd8acf3SDaniel P. Berrange 330cbd8acf3SDaniel P. Berrange static void test_visitor_in_number_str_fail(TestInputVisitorData *data, 331cbd8acf3SDaniel P. Berrange const void *unused) 332cbd8acf3SDaniel P. Berrange { 333cbd8acf3SDaniel P. Berrange double res = 0; 334cbd8acf3SDaniel P. Berrange Visitor *v; 335cbd8acf3SDaniel P. Berrange Error *err = NULL; 336cbd8acf3SDaniel P. Berrange 337cbd8acf3SDaniel P. Berrange v = visitor_input_test_init(data, "\"3.14\""); 338cbd8acf3SDaniel P. Berrange 339cbd8acf3SDaniel P. Berrange visit_type_number(v, NULL, &res, &err); 340cbd8acf3SDaniel P. Berrange error_free_or_abort(&err); 341cbd8acf3SDaniel P. Berrange } 342cbd8acf3SDaniel P. Berrange 343cbd8acf3SDaniel P. Berrange static void test_visitor_in_size_str_keyval(TestInputVisitorData *data, 344cbd8acf3SDaniel P. Berrange const void *unused) 345cbd8acf3SDaniel P. Berrange { 346cbd8acf3SDaniel P. Berrange uint64_t res, value = 500 * 1024 * 1024; 347cbd8acf3SDaniel P. Berrange Visitor *v; 348cbd8acf3SDaniel P. Berrange 349cbd8acf3SDaniel P. Berrange v = visitor_input_test_init_full(data, true, "\"500M\""); 350cbd8acf3SDaniel P. Berrange 351cbd8acf3SDaniel P. Berrange visit_type_size(v, NULL, &res, &error_abort); 352cbd8acf3SDaniel P. Berrange g_assert_cmpfloat(res, ==, value); 353cbd8acf3SDaniel P. Berrange } 354cbd8acf3SDaniel P. Berrange 355cbd8acf3SDaniel P. Berrange static void test_visitor_in_size_str_fail(TestInputVisitorData *data, 356cbd8acf3SDaniel P. Berrange const void *unused) 357cbd8acf3SDaniel P. Berrange { 358cbd8acf3SDaniel P. Berrange uint64_t res = 0; 359cbd8acf3SDaniel P. Berrange Visitor *v; 360cbd8acf3SDaniel P. Berrange Error *err = NULL; 361cbd8acf3SDaniel P. Berrange 362cbd8acf3SDaniel P. Berrange v = visitor_input_test_init(data, "\"500M\""); 363cbd8acf3SDaniel P. Berrange 364cbd8acf3SDaniel P. Berrange visit_type_size(v, NULL, &res, &err); 365cbd8acf3SDaniel P. Berrange error_free_or_abort(&err); 366cbd8acf3SDaniel P. Berrange } 367cbd8acf3SDaniel P. Berrange 368d88f5fd1SLuiz Capitulino static void test_visitor_in_string(TestInputVisitorData *data, 369d88f5fd1SLuiz Capitulino const void *unused) 370d88f5fd1SLuiz Capitulino { 371d88f5fd1SLuiz Capitulino char *res = NULL, *value = (char *) "Q E M U"; 372d88f5fd1SLuiz Capitulino Visitor *v; 373d88f5fd1SLuiz Capitulino 374d88f5fd1SLuiz Capitulino v = visitor_input_test_init(data, "%s", value); 375d88f5fd1SLuiz Capitulino 37651e72bc1SEric Blake visit_type_str(v, NULL, &res, &error_abort); 377d88f5fd1SLuiz Capitulino g_assert_cmpstr(res, ==, value); 378d88f5fd1SLuiz Capitulino 379d88f5fd1SLuiz Capitulino g_free(res); 380d88f5fd1SLuiz Capitulino } 381d88f5fd1SLuiz Capitulino 382d88f5fd1SLuiz Capitulino static void test_visitor_in_enum(TestInputVisitorData *data, 383d88f5fd1SLuiz Capitulino const void *unused) 384d88f5fd1SLuiz Capitulino { 385d88f5fd1SLuiz Capitulino Visitor *v; 386d88f5fd1SLuiz Capitulino EnumOne i; 387d88f5fd1SLuiz Capitulino 3881c236ba5SMarkus Armbruster for (i = 0; i < ENUM_ONE__MAX; i++) { 389d88f5fd1SLuiz Capitulino EnumOne res = -1; 390d88f5fd1SLuiz Capitulino 391977c736fSMarkus Armbruster v = visitor_input_test_init(data, "%s", EnumOne_str(i)); 392d88f5fd1SLuiz Capitulino 39351e72bc1SEric Blake visit_type_EnumOne(v, NULL, &res, &error_abort); 394d88f5fd1SLuiz Capitulino g_assert_cmpint(i, ==, res); 395d88f5fd1SLuiz Capitulino } 396d88f5fd1SLuiz Capitulino } 397d88f5fd1SLuiz Capitulino 398d88f5fd1SLuiz Capitulino 399d88f5fd1SLuiz Capitulino static void test_visitor_in_struct(TestInputVisitorData *data, 400d88f5fd1SLuiz Capitulino const void *unused) 401d88f5fd1SLuiz Capitulino { 402d88f5fd1SLuiz Capitulino TestStruct *p = NULL; 403d88f5fd1SLuiz Capitulino Visitor *v; 404d88f5fd1SLuiz Capitulino 405d88f5fd1SLuiz Capitulino v = visitor_input_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo' }"); 406d88f5fd1SLuiz Capitulino 40751e72bc1SEric Blake visit_type_TestStruct(v, NULL, &p, &error_abort); 408d88f5fd1SLuiz Capitulino g_assert_cmpint(p->integer, ==, -42); 409d88f5fd1SLuiz Capitulino g_assert(p->boolean == true); 410d88f5fd1SLuiz Capitulino g_assert_cmpstr(p->string, ==, "foo"); 411d88f5fd1SLuiz Capitulino 412d88f5fd1SLuiz Capitulino g_free(p->string); 413d88f5fd1SLuiz Capitulino g_free(p); 414d88f5fd1SLuiz Capitulino } 415d88f5fd1SLuiz Capitulino 416d88f5fd1SLuiz Capitulino static void test_visitor_in_struct_nested(TestInputVisitorData *data, 417d88f5fd1SLuiz Capitulino const void *unused) 418d88f5fd1SLuiz Capitulino { 419221db5daSDaniel P. Berrangé g_autoptr(UserDefTwo) udp = NULL; 420d88f5fd1SLuiz Capitulino Visitor *v; 421d88f5fd1SLuiz Capitulino 422b6fcf32dSEric Blake v = visitor_input_test_init(data, "{ 'string0': 'string0', " 423b6fcf32dSEric Blake "'dict1': { 'string1': 'string1', " 424b6fcf32dSEric Blake "'dict2': { 'userdef': { 'integer': 42, " 425b6fcf32dSEric Blake "'string': 'string' }, 'string': 'string2'}}}"); 426d88f5fd1SLuiz Capitulino 42751e72bc1SEric Blake visit_type_UserDefTwo(v, NULL, &udp, &error_abort); 428d88f5fd1SLuiz Capitulino 429b18f1141SEric Blake g_assert_cmpstr(udp->string0, ==, "string0"); 430b18f1141SEric Blake g_assert_cmpstr(udp->dict1->string1, ==, "string1"); 431ddf21908SEric Blake g_assert_cmpint(udp->dict1->dict2->userdef->integer, ==, 42); 432b18f1141SEric Blake g_assert_cmpstr(udp->dict1->dict2->userdef->string, ==, "string"); 433b18f1141SEric Blake g_assert_cmpstr(udp->dict1->dict2->string, ==, "string2"); 4346446a592SEric Blake g_assert(udp->dict1->has_dict3 == false); 435d88f5fd1SLuiz Capitulino } 436d88f5fd1SLuiz Capitulino 437d88f5fd1SLuiz Capitulino static void test_visitor_in_list(TestInputVisitorData *data, 438d88f5fd1SLuiz Capitulino const void *unused) 439d88f5fd1SLuiz Capitulino { 440d88f5fd1SLuiz Capitulino UserDefOneList *item, *head = NULL; 441d88f5fd1SLuiz Capitulino Visitor *v; 442d88f5fd1SLuiz Capitulino int i; 443d88f5fd1SLuiz Capitulino 444d88f5fd1SLuiz Capitulino v = visitor_input_test_init(data, "[ { 'string': 'string0', 'integer': 42 }, { 'string': 'string1', 'integer': 43 }, { 'string': 'string2', 'integer': 44 } ]"); 445d88f5fd1SLuiz Capitulino 44651e72bc1SEric Blake visit_type_UserDefOneList(v, NULL, &head, &error_abort); 447d88f5fd1SLuiz Capitulino g_assert(head != NULL); 448d88f5fd1SLuiz Capitulino 449d88f5fd1SLuiz Capitulino for (i = 0, item = head; item; item = item->next, i++) { 450d88f5fd1SLuiz Capitulino char string[12]; 451d88f5fd1SLuiz Capitulino 452d88f5fd1SLuiz Capitulino snprintf(string, sizeof(string), "string%d", i); 453d88f5fd1SLuiz Capitulino g_assert_cmpstr(item->value->string, ==, string); 454ddf21908SEric Blake g_assert_cmpint(item->value->integer, ==, 42 + i); 455d88f5fd1SLuiz Capitulino } 456d88f5fd1SLuiz Capitulino 457d88f5fd1SLuiz Capitulino qapi_free_UserDefOneList(head); 4582533377cSEric Blake head = NULL; 4592533377cSEric Blake 4602533377cSEric Blake /* An empty list is valid */ 4612533377cSEric Blake v = visitor_input_test_init(data, "[]"); 46251e72bc1SEric Blake visit_type_UserDefOneList(v, NULL, &head, &error_abort); 4632533377cSEric Blake g_assert(!head); 464d88f5fd1SLuiz Capitulino } 465d88f5fd1SLuiz Capitulino 466e7a76fe2SMarkus Armbruster static void test_visitor_in_list_struct(TestInputVisitorData *data, 467e7a76fe2SMarkus Armbruster const void *unused) 468e7a76fe2SMarkus Armbruster { 469e7a76fe2SMarkus Armbruster const char *int_member[] = { 470e7a76fe2SMarkus Armbruster "integer", "s8", "s16", "s32", "s64", "u8", "u16", "u32", "u64" }; 471e7a76fe2SMarkus Armbruster g_autoptr(GString) json = g_string_new(""); 472e7a76fe2SMarkus Armbruster int i, j; 473e7a76fe2SMarkus Armbruster const char *sep; 474e7a76fe2SMarkus Armbruster g_autoptr(ArrayStruct) arrs = NULL; 475e7a76fe2SMarkus Armbruster Visitor *v; 476e7a76fe2SMarkus Armbruster intList *int_list; 477e7a76fe2SMarkus Armbruster int8List *s8_list; 478e7a76fe2SMarkus Armbruster int16List *s16_list; 479e7a76fe2SMarkus Armbruster int32List *s32_list; 480e7a76fe2SMarkus Armbruster int64List *s64_list; 481e7a76fe2SMarkus Armbruster uint8List *u8_list; 482e7a76fe2SMarkus Armbruster uint16List *u16_list; 483e7a76fe2SMarkus Armbruster uint32List *u32_list; 484e7a76fe2SMarkus Armbruster uint64List *u64_list; 485e7a76fe2SMarkus Armbruster numberList *num_list; 486e7a76fe2SMarkus Armbruster boolList *bool_list; 487e7a76fe2SMarkus Armbruster strList *str_list; 488e7a76fe2SMarkus Armbruster 489e7a76fe2SMarkus Armbruster g_string_append_printf(json, "{"); 490e7a76fe2SMarkus Armbruster 491e7a76fe2SMarkus Armbruster for (i = 0; i < G_N_ELEMENTS(int_member); i++) { 492e7a76fe2SMarkus Armbruster g_string_append_printf(json, "'%s': [", int_member[i]); 493e7a76fe2SMarkus Armbruster sep = ""; 494e7a76fe2SMarkus Armbruster for (j = 0; j < 32; j++) { 495e7a76fe2SMarkus Armbruster g_string_append_printf(json, "%s%d", sep, j); 496e7a76fe2SMarkus Armbruster sep = ", "; 497e7a76fe2SMarkus Armbruster } 498e7a76fe2SMarkus Armbruster g_string_append_printf(json, "], "); 499e7a76fe2SMarkus Armbruster } 500e7a76fe2SMarkus Armbruster 501e7a76fe2SMarkus Armbruster g_string_append_printf(json, "'number': ["); 502e7a76fe2SMarkus Armbruster sep = ""; 503e7a76fe2SMarkus Armbruster for (i = 0; i < 32; i++) { 504e7a76fe2SMarkus Armbruster g_string_append_printf(json, "%s%f", sep, (double)i / 3); 505e7a76fe2SMarkus Armbruster sep = ", "; 506e7a76fe2SMarkus Armbruster } 507e7a76fe2SMarkus Armbruster g_string_append_printf(json, "], "); 508e7a76fe2SMarkus Armbruster 509e7a76fe2SMarkus Armbruster g_string_append_printf(json, "'boolean': ["); 510e7a76fe2SMarkus Armbruster sep = ""; 511e7a76fe2SMarkus Armbruster for (i = 0; i < 32; i++) { 512e7a76fe2SMarkus Armbruster g_string_append_printf(json, "%s%s", 513e7a76fe2SMarkus Armbruster sep, i % 3 == 0 ? "true" : "false"); 514e7a76fe2SMarkus Armbruster sep = ", "; 515e7a76fe2SMarkus Armbruster } 516e7a76fe2SMarkus Armbruster g_string_append_printf(json, "], "); 517e7a76fe2SMarkus Armbruster 518e7a76fe2SMarkus Armbruster g_string_append_printf(json, "'string': ["); 519e7a76fe2SMarkus Armbruster sep = ""; 520e7a76fe2SMarkus Armbruster for (i = 0; i < 32; i++) { 521e7a76fe2SMarkus Armbruster g_string_append_printf(json, "%s'%d'", sep, i); 522e7a76fe2SMarkus Armbruster sep = ", "; 523e7a76fe2SMarkus Armbruster } 524e7a76fe2SMarkus Armbruster g_string_append_printf(json, "]"); 525e7a76fe2SMarkus Armbruster 526e7a76fe2SMarkus Armbruster g_string_append_printf(json, "}"); 527e7a76fe2SMarkus Armbruster 528e7a76fe2SMarkus Armbruster v = visitor_input_test_init_raw(data, json->str); 529e7a76fe2SMarkus Armbruster visit_type_ArrayStruct(v, NULL, &arrs, &error_abort); 530e7a76fe2SMarkus Armbruster 531e7a76fe2SMarkus Armbruster i = 0; 532e7a76fe2SMarkus Armbruster for (int_list = arrs->integer; int_list; int_list = int_list->next) { 533e7a76fe2SMarkus Armbruster g_assert_cmpint(int_list->value, ==, i); 534e7a76fe2SMarkus Armbruster i++; 535e7a76fe2SMarkus Armbruster } 536e7a76fe2SMarkus Armbruster 537e7a76fe2SMarkus Armbruster i = 0; 538e7a76fe2SMarkus Armbruster for (s8_list = arrs->s8; s8_list; s8_list = s8_list->next) { 539e7a76fe2SMarkus Armbruster g_assert_cmpint(s8_list->value, ==, i); 540e7a76fe2SMarkus Armbruster i++; 541e7a76fe2SMarkus Armbruster } 542e7a76fe2SMarkus Armbruster 543e7a76fe2SMarkus Armbruster i = 0; 544e7a76fe2SMarkus Armbruster for (s16_list = arrs->s16; s16_list; s16_list = s16_list->next) { 545e7a76fe2SMarkus Armbruster g_assert_cmpint(s16_list->value, ==, i); 546e7a76fe2SMarkus Armbruster i++; 547e7a76fe2SMarkus Armbruster } 548e7a76fe2SMarkus Armbruster 549e7a76fe2SMarkus Armbruster i = 0; 550e7a76fe2SMarkus Armbruster for (s32_list = arrs->s32; s32_list; s32_list = s32_list->next) { 551e7a76fe2SMarkus Armbruster g_assert_cmpint(s32_list->value, ==, i); 552e7a76fe2SMarkus Armbruster i++; 553e7a76fe2SMarkus Armbruster } 554e7a76fe2SMarkus Armbruster 555e7a76fe2SMarkus Armbruster i = 0; 556e7a76fe2SMarkus Armbruster for (s64_list = arrs->s64; s64_list; s64_list = s64_list->next) { 557e7a76fe2SMarkus Armbruster g_assert_cmpint(s64_list->value, ==, i); 558e7a76fe2SMarkus Armbruster i++; 559e7a76fe2SMarkus Armbruster } 560e7a76fe2SMarkus Armbruster 561e7a76fe2SMarkus Armbruster i = 0; 562e7a76fe2SMarkus Armbruster for (u8_list = arrs->u8; u8_list; u8_list = u8_list->next) { 563e7a76fe2SMarkus Armbruster g_assert_cmpint(u8_list->value, ==, i); 564e7a76fe2SMarkus Armbruster i++; 565e7a76fe2SMarkus Armbruster } 566e7a76fe2SMarkus Armbruster 567e7a76fe2SMarkus Armbruster i = 0; 568e7a76fe2SMarkus Armbruster for (u16_list = arrs->u16; u16_list; u16_list = u16_list->next) { 569e7a76fe2SMarkus Armbruster g_assert_cmpint(u16_list->value, ==, i); 570e7a76fe2SMarkus Armbruster i++; 571e7a76fe2SMarkus Armbruster } 572e7a76fe2SMarkus Armbruster 573e7a76fe2SMarkus Armbruster i = 0; 574e7a76fe2SMarkus Armbruster for (u32_list = arrs->u32; u32_list; u32_list = u32_list->next) { 575e7a76fe2SMarkus Armbruster g_assert_cmpint(u32_list->value, ==, i); 576e7a76fe2SMarkus Armbruster i++; 577e7a76fe2SMarkus Armbruster } 578e7a76fe2SMarkus Armbruster 579e7a76fe2SMarkus Armbruster i = 0; 580e7a76fe2SMarkus Armbruster for (u64_list = arrs->u64; u64_list; u64_list = u64_list->next) { 581e7a76fe2SMarkus Armbruster g_assert_cmpint(u64_list->value, ==, i); 582e7a76fe2SMarkus Armbruster i++; 583e7a76fe2SMarkus Armbruster } 584e7a76fe2SMarkus Armbruster 585e7a76fe2SMarkus Armbruster i = 0; 586e7a76fe2SMarkus Armbruster for (num_list = arrs->number; num_list; num_list = num_list->next) { 587e7a76fe2SMarkus Armbruster char expected[32], actual[32]; 588e7a76fe2SMarkus Armbruster 589e7a76fe2SMarkus Armbruster sprintf(expected, "%.6f", (double)i / 3); 590e7a76fe2SMarkus Armbruster sprintf(actual, "%.6f", num_list->value); 591e7a76fe2SMarkus Armbruster g_assert_cmpstr(expected, ==, actual); 592e7a76fe2SMarkus Armbruster i++; 593e7a76fe2SMarkus Armbruster } 594e7a76fe2SMarkus Armbruster 595e7a76fe2SMarkus Armbruster i = 0; 596e7a76fe2SMarkus Armbruster for (bool_list = arrs->boolean; bool_list; bool_list = bool_list->next) { 597e7a76fe2SMarkus Armbruster g_assert_cmpint(bool_list->value, ==, i % 3 == 0); 598e7a76fe2SMarkus Armbruster i++; 599e7a76fe2SMarkus Armbruster } 600e7a76fe2SMarkus Armbruster 601e7a76fe2SMarkus Armbruster i = 0; 602e7a76fe2SMarkus Armbruster for (str_list = arrs->string; str_list; str_list = str_list->next) { 603e7a76fe2SMarkus Armbruster char expected[32]; 604e7a76fe2SMarkus Armbruster 605e7a76fe2SMarkus Armbruster sprintf(expected, "%d", i); 606e7a76fe2SMarkus Armbruster g_assert_cmpstr(str_list->value, ==, expected); 607e7a76fe2SMarkus Armbruster i++; 608e7a76fe2SMarkus Armbruster } 609e7a76fe2SMarkus Armbruster } 610e7a76fe2SMarkus Armbruster 61128770e05SMarkus Armbruster static void test_visitor_in_any(TestInputVisitorData *data, 61228770e05SMarkus Armbruster const void *unused) 61328770e05SMarkus Armbruster { 61428770e05SMarkus Armbruster QObject *res = NULL; 61528770e05SMarkus Armbruster Visitor *v; 61601b2ffceSMarc-André Lureau QNum *qnum; 61728770e05SMarkus Armbruster QBool *qbool; 61828770e05SMarkus Armbruster QString *qstring; 61928770e05SMarkus Armbruster QDict *qdict; 62028770e05SMarkus Armbruster QObject *qobj; 62101b2ffceSMarc-André Lureau int64_t val; 62228770e05SMarkus Armbruster 62328770e05SMarkus Armbruster v = visitor_input_test_init(data, "-42"); 62451e72bc1SEric Blake visit_type_any(v, NULL, &res, &error_abort); 6257dc847ebSMax Reitz qnum = qobject_to(QNum, res); 62601b2ffceSMarc-André Lureau g_assert(qnum); 62701b2ffceSMarc-André Lureau g_assert(qnum_get_try_int(qnum, &val)); 62801b2ffceSMarc-André Lureau g_assert_cmpint(val, ==, -42); 629cb3e7f08SMarc-André Lureau qobject_unref(res); 63028770e05SMarkus Armbruster 63128770e05SMarkus Armbruster v = visitor_input_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo' }"); 63251e72bc1SEric Blake visit_type_any(v, NULL, &res, &error_abort); 6337dc847ebSMax Reitz qdict = qobject_to(QDict, res); 63428770e05SMarkus Armbruster g_assert(qdict && qdict_size(qdict) == 3); 63528770e05SMarkus Armbruster qobj = qdict_get(qdict, "integer"); 63628770e05SMarkus Armbruster g_assert(qobj); 6377dc847ebSMax Reitz qnum = qobject_to(QNum, qobj); 63801b2ffceSMarc-André Lureau g_assert(qnum); 63901b2ffceSMarc-André Lureau g_assert(qnum_get_try_int(qnum, &val)); 64001b2ffceSMarc-André Lureau g_assert_cmpint(val, ==, -42); 64128770e05SMarkus Armbruster qobj = qdict_get(qdict, "boolean"); 64228770e05SMarkus Armbruster g_assert(qobj); 6437dc847ebSMax Reitz qbool = qobject_to(QBool, qobj); 64428770e05SMarkus Armbruster g_assert(qbool); 64528770e05SMarkus Armbruster g_assert(qbool_get_bool(qbool) == true); 64628770e05SMarkus Armbruster qobj = qdict_get(qdict, "string"); 64728770e05SMarkus Armbruster g_assert(qobj); 6487dc847ebSMax Reitz qstring = qobject_to(QString, qobj); 64928770e05SMarkus Armbruster g_assert(qstring); 65028770e05SMarkus Armbruster g_assert_cmpstr(qstring_get_str(qstring), ==, "foo"); 651cb3e7f08SMarc-André Lureau qobject_unref(res); 65228770e05SMarkus Armbruster } 65328770e05SMarkus Armbruster 6543df016f1SEric Blake static void test_visitor_in_null(TestInputVisitorData *data, 6553df016f1SEric Blake const void *unused) 6563df016f1SEric Blake { 6573df016f1SEric Blake Visitor *v; 6583df016f1SEric Blake Error *err = NULL; 659d2f95f4dSMarkus Armbruster QNull *null; 6603df016f1SEric Blake char *tmp; 6613df016f1SEric Blake 6623df016f1SEric Blake /* 6633df016f1SEric Blake * FIXME: Since QAPI doesn't know the 'null' type yet, we can't 6643df016f1SEric Blake * test visit_type_null() by reading into a QAPI struct then 6653df016f1SEric Blake * checking that it was populated correctly. The best we can do 6663df016f1SEric Blake * for now is ensure that we consumed null from the input, proven 6673df016f1SEric Blake * by the fact that we can't re-read the key; and that we detect 6683df016f1SEric Blake * when input is not null. 6693df016f1SEric Blake */ 6703df016f1SEric Blake 671cbd8acf3SDaniel P. Berrange v = visitor_input_test_init_full(data, false, 672cbd8acf3SDaniel P. Berrange "{ 'a': null, 'b': '' }"); 6733df016f1SEric Blake visit_start_struct(v, NULL, NULL, 0, &error_abort); 674d2f95f4dSMarkus Armbruster visit_type_null(v, "a", &null, &error_abort); 675d2f95f4dSMarkus Armbruster g_assert(qobject_type(QOBJECT(null)) == QTYPE_QNULL); 676cb3e7f08SMarc-André Lureau qobject_unref(null); 677d2f95f4dSMarkus Armbruster visit_type_null(v, "b", &null, &err); 6783df016f1SEric Blake error_free_or_abort(&err); 679d2f95f4dSMarkus Armbruster g_assert(!null); 680ec95f614SMarkus Armbruster visit_type_str(v, "c", &tmp, &err); 681ec95f614SMarkus Armbruster error_free_or_abort(&err); 682d2f95f4dSMarkus Armbruster g_assert(!tmp); 68315c2f669SEric Blake visit_check_struct(v, &error_abort); 6841158bb2aSEric Blake visit_end_struct(v, NULL); 6853df016f1SEric Blake } 6863df016f1SEric Blake 6872fc00432SMarkus Armbruster static void test_visitor_in_union_flat(TestInputVisitorData *data, 6882fc00432SMarkus Armbruster const void *unused) 6892fc00432SMarkus Armbruster { 6902fc00432SMarkus Armbruster Visitor *v; 691221db5daSDaniel P. Berrangé g_autoptr(UserDefFlatUnion) tmp = NULL; 69230594fe1SEric Blake UserDefUnionBase *base; 6932fc00432SMarkus Armbruster 6945223070cSWenchao Xia v = visitor_input_test_init(data, 6955223070cSWenchao Xia "{ 'enum1': 'value1', " 696441cbac0SMarkus Armbruster "'integer': 41, " 6975223070cSWenchao Xia "'string': 'str', " 6985223070cSWenchao Xia "'boolean': true }"); 6992fc00432SMarkus Armbruster 70051e72bc1SEric Blake visit_type_UserDefFlatUnion(v, NULL, &tmp, &error_abort); 7010f61af3eSMarkus Armbruster g_assert_cmpint(tmp->enum1, ==, ENUM_ONE_VALUE1); 7025223070cSWenchao Xia g_assert_cmpstr(tmp->string, ==, "str"); 703441cbac0SMarkus Armbruster g_assert_cmpint(tmp->integer, ==, 41); 704544a3731SEric Blake g_assert_cmpint(tmp->u.value1.boolean, ==, true); 70530594fe1SEric Blake 70630594fe1SEric Blake base = qapi_UserDefFlatUnion_base(tmp); 70730594fe1SEric Blake g_assert(&base->enum1 == &tmp->enum1); 7082fc00432SMarkus Armbruster } 7092fc00432SMarkus Armbruster 710ab045267SEric Blake static void test_visitor_in_alternate(TestInputVisitorData *data, 7112c38b600SMarkus Armbruster const void *unused) 7122c38b600SMarkus Armbruster { 7132c38b600SMarkus Armbruster Visitor *v; 714ab045267SEric Blake UserDefAlternate *tmp; 71568d07839SEric Blake WrapAlternate *wrap; 7162c38b600SMarkus Armbruster 7172c38b600SMarkus Armbruster v = visitor_input_test_init(data, "42"); 71851e72bc1SEric Blake visit_type_UserDefAlternate(v, NULL, &tmp, &error_abort); 71901b2ffceSMarc-André Lureau g_assert_cmpint(tmp->type, ==, QTYPE_QNUM); 720c363acefSEric Blake g_assert_cmpint(tmp->u.i, ==, 42); 721ab045267SEric Blake qapi_free_UserDefAlternate(tmp); 7229c51b441SEric Blake 7238168ca8eSMarkus Armbruster v = visitor_input_test_init(data, "'value1'"); 72451e72bc1SEric Blake visit_type_UserDefAlternate(v, NULL, &tmp, &error_abort); 7250426d53cSEric Blake g_assert_cmpint(tmp->type, ==, QTYPE_QSTRING); 7268168ca8eSMarkus Armbruster g_assert_cmpint(tmp->u.e, ==, ENUM_ONE_VALUE1); 7279c51b441SEric Blake qapi_free_UserDefAlternate(tmp); 7289c51b441SEric Blake 7294d2d5c41SMarkus Armbruster v = visitor_input_test_init(data, "null"); 7304d2d5c41SMarkus Armbruster visit_type_UserDefAlternate(v, NULL, &tmp, &error_abort); 7314d2d5c41SMarkus Armbruster g_assert_cmpint(tmp->type, ==, QTYPE_QNULL); 7324d2d5c41SMarkus Armbruster qapi_free_UserDefAlternate(tmp); 7334d2d5c41SMarkus Armbruster 73468d07839SEric Blake v = visitor_input_test_init(data, "{'integer':1, 'string':'str', " 73568d07839SEric Blake "'enum1':'value1', 'boolean':true}"); 73668d07839SEric Blake visit_type_UserDefAlternate(v, NULL, &tmp, &error_abort); 73768d07839SEric Blake g_assert_cmpint(tmp->type, ==, QTYPE_QDICT); 738becceedcSEric Blake g_assert_cmpint(tmp->u.udfu.integer, ==, 1); 739becceedcSEric Blake g_assert_cmpstr(tmp->u.udfu.string, ==, "str"); 740becceedcSEric Blake g_assert_cmpint(tmp->u.udfu.enum1, ==, ENUM_ONE_VALUE1); 741544a3731SEric Blake g_assert_cmpint(tmp->u.udfu.u.value1.boolean, ==, true); 742544a3731SEric Blake g_assert_cmpint(tmp->u.udfu.u.value1.has_a_b, ==, false); 74368d07839SEric Blake qapi_free_UserDefAlternate(tmp); 74468d07839SEric Blake 74568d07839SEric Blake v = visitor_input_test_init(data, "{ 'alt': 42 }"); 74668d07839SEric Blake visit_type_WrapAlternate(v, NULL, &wrap, &error_abort); 74701b2ffceSMarc-André Lureau g_assert_cmpint(wrap->alt->type, ==, QTYPE_QNUM); 74868d07839SEric Blake g_assert_cmpint(wrap->alt->u.i, ==, 42); 74968d07839SEric Blake qapi_free_WrapAlternate(wrap); 75068d07839SEric Blake 7518168ca8eSMarkus Armbruster v = visitor_input_test_init(data, "{ 'alt': 'value1' }"); 75268d07839SEric Blake visit_type_WrapAlternate(v, NULL, &wrap, &error_abort); 75368d07839SEric Blake g_assert_cmpint(wrap->alt->type, ==, QTYPE_QSTRING); 7548168ca8eSMarkus Armbruster g_assert_cmpint(wrap->alt->u.e, ==, ENUM_ONE_VALUE1); 75568d07839SEric Blake qapi_free_WrapAlternate(wrap); 75668d07839SEric Blake 75768d07839SEric Blake v = visitor_input_test_init(data, "{ 'alt': {'integer':1, 'string':'str', " 75868d07839SEric Blake "'enum1':'value1', 'boolean':true} }"); 75968d07839SEric Blake visit_type_WrapAlternate(v, NULL, &wrap, &error_abort); 76068d07839SEric Blake g_assert_cmpint(wrap->alt->type, ==, QTYPE_QDICT); 761becceedcSEric Blake g_assert_cmpint(wrap->alt->u.udfu.integer, ==, 1); 762becceedcSEric Blake g_assert_cmpstr(wrap->alt->u.udfu.string, ==, "str"); 763becceedcSEric Blake g_assert_cmpint(wrap->alt->u.udfu.enum1, ==, ENUM_ONE_VALUE1); 764544a3731SEric Blake g_assert_cmpint(wrap->alt->u.udfu.u.value1.boolean, ==, true); 765544a3731SEric Blake g_assert_cmpint(wrap->alt->u.udfu.u.value1.has_a_b, ==, false); 76668d07839SEric Blake qapi_free_WrapAlternate(wrap); 7679c51b441SEric Blake } 7689c51b441SEric Blake 7699c51b441SEric Blake static void test_visitor_in_alternate_number(TestInputVisitorData *data, 7709c51b441SEric Blake const void *unused) 7719c51b441SEric Blake { 7729c51b441SEric Blake Visitor *v; 7739c51b441SEric Blake Error *err = NULL; 7748168ca8eSMarkus Armbruster AltEnumBool *aeb; 7758168ca8eSMarkus Armbruster AltEnumNum *aen; 7768168ca8eSMarkus Armbruster AltNumEnum *ans; 7778168ca8eSMarkus Armbruster AltEnumInt *asi; 778*79db9948SPaolo Bonzini AltListInt *ali; 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 805*79db9948SPaolo Bonzini v = visitor_input_test_init(data, "42"); 806*79db9948SPaolo Bonzini visit_type_AltListInt(v, NULL, &ali, &error_abort); 807*79db9948SPaolo Bonzini g_assert_cmpint(ali->type, ==, QTYPE_QNUM); 808*79db9948SPaolo Bonzini g_assert_cmpint(ali->u.i, ==, 42); 809*79db9948SPaolo Bonzini qapi_free_AltListInt(ali); 810*79db9948SPaolo Bonzini 8119c51b441SEric Blake /* Parsing a double */ 8129c51b441SEric Blake 8139c51b441SEric Blake v = visitor_input_test_init(data, "42.5"); 8148168ca8eSMarkus Armbruster visit_type_AltEnumBool(v, NULL, &aeb, &err); 815a12a5a1aSEric Blake error_free_or_abort(&err); 8168168ca8eSMarkus Armbruster qapi_free_AltEnumBool(aeb); 8179c51b441SEric Blake 8189c51b441SEric Blake v = visitor_input_test_init(data, "42.5"); 8198168ca8eSMarkus Armbruster visit_type_AltEnumNum(v, NULL, &aen, &error_abort); 82001b2ffceSMarc-André Lureau g_assert_cmpint(aen->type, ==, QTYPE_QNUM); 8218168ca8eSMarkus Armbruster g_assert_cmpfloat(aen->u.n, ==, 42.5); 8228168ca8eSMarkus Armbruster qapi_free_AltEnumNum(aen); 8239c51b441SEric Blake 8249c51b441SEric Blake v = visitor_input_test_init(data, "42.5"); 8258168ca8eSMarkus Armbruster visit_type_AltNumEnum(v, NULL, &ans, &error_abort); 82601b2ffceSMarc-André Lureau g_assert_cmpint(ans->type, ==, QTYPE_QNUM); 827c363acefSEric Blake g_assert_cmpfloat(ans->u.n, ==, 42.5); 8288168ca8eSMarkus Armbruster qapi_free_AltNumEnum(ans); 8299c51b441SEric Blake 8309c51b441SEric Blake v = visitor_input_test_init(data, "42.5"); 8318168ca8eSMarkus Armbruster visit_type_AltEnumInt(v, NULL, &asi, &err); 832a12a5a1aSEric Blake error_free_or_abort(&err); 8338168ca8eSMarkus Armbruster qapi_free_AltEnumInt(asi); 8342c38b600SMarkus Armbruster } 8352c38b600SMarkus Armbruster 836*79db9948SPaolo Bonzini static void test_visitor_in_alternate_list(TestInputVisitorData *data, 837*79db9948SPaolo Bonzini const void *unused) 838*79db9948SPaolo Bonzini { 839*79db9948SPaolo Bonzini intList *item; 840*79db9948SPaolo Bonzini Visitor *v; 841*79db9948SPaolo Bonzini AltListInt *ali; 842*79db9948SPaolo Bonzini int i; 843*79db9948SPaolo Bonzini 844*79db9948SPaolo Bonzini v = visitor_input_test_init(data, "[ 42, 43, 44 ]"); 845*79db9948SPaolo Bonzini visit_type_AltListInt(v, NULL, &ali, &error_abort); 846*79db9948SPaolo Bonzini g_assert(ali != NULL); 847*79db9948SPaolo Bonzini 848*79db9948SPaolo Bonzini g_assert_cmpint(ali->type, ==, QTYPE_QLIST); 849*79db9948SPaolo Bonzini for (i = 0, item = ali->u.l; item; item = item->next, i++) { 850*79db9948SPaolo Bonzini g_assert_cmpint(item->value, ==, 42 + i); 851*79db9948SPaolo Bonzini } 852*79db9948SPaolo Bonzini 853*79db9948SPaolo Bonzini qapi_free_AltListInt(ali); 854*79db9948SPaolo Bonzini ali = NULL; 855*79db9948SPaolo Bonzini 856*79db9948SPaolo Bonzini /* An empty list is valid */ 857*79db9948SPaolo Bonzini v = visitor_input_test_init(data, "[]"); 858*79db9948SPaolo Bonzini visit_type_AltListInt(v, NULL, &ali, &error_abort); 859*79db9948SPaolo Bonzini g_assert(ali != NULL); 860*79db9948SPaolo Bonzini 861*79db9948SPaolo Bonzini g_assert_cmpint(ali->type, ==, QTYPE_QLIST); 862*79db9948SPaolo Bonzini g_assert(!ali->u.l); 863*79db9948SPaolo Bonzini qapi_free_AltListInt(ali); 864*79db9948SPaolo Bonzini ali = NULL; 865*79db9948SPaolo Bonzini } 866*79db9948SPaolo Bonzini 867d88f5fd1SLuiz Capitulino static void input_visitor_test_add(const char *testpath, 868b1d2e5f1SDaniel P. Berrange const void *user_data, 869b1d2e5f1SDaniel P. Berrange void (*test_func)(TestInputVisitorData *data, 870b1d2e5f1SDaniel P. Berrange const void *user_data)) 871d88f5fd1SLuiz Capitulino { 872b1d2e5f1SDaniel P. Berrange g_test_add(testpath, TestInputVisitorData, user_data, NULL, test_func, 873d88f5fd1SLuiz Capitulino visitor_input_teardown); 874d88f5fd1SLuiz Capitulino } 875d88f5fd1SLuiz Capitulino 8763dcf71f6SPaolo Bonzini static void test_visitor_in_errors(TestInputVisitorData *data, 8773dcf71f6SPaolo Bonzini const void *unused) 8783dcf71f6SPaolo Bonzini { 8793dcf71f6SPaolo Bonzini TestStruct *p = NULL; 880e940f543SMarkus Armbruster Error *err = NULL; 8813dcf71f6SPaolo Bonzini Visitor *v; 882dd5ee2c2SEric Blake strList *q = NULL; 8839b4e38feSEric Blake UserDefTwo *r = NULL; 8849b4e38feSEric Blake WrapAlternate *s = NULL; 8853dcf71f6SPaolo Bonzini 886dd5ee2c2SEric Blake v = visitor_input_test_init(data, "{ 'integer': false, 'boolean': 'foo', " 887dd5ee2c2SEric Blake "'string': -42 }"); 8883dcf71f6SPaolo Bonzini 88951e72bc1SEric Blake visit_type_TestStruct(v, NULL, &p, &err); 890a12a5a1aSEric Blake error_free_or_abort(&err); 89168ab47e4SEric Blake g_assert(!p); 892dd5ee2c2SEric Blake 893dd5ee2c2SEric Blake v = visitor_input_test_init(data, "[ '1', '2', false, '3' ]"); 89451e72bc1SEric Blake visit_type_strList(v, NULL, &q, &err); 895dd5ee2c2SEric Blake error_free_or_abort(&err); 89668ab47e4SEric Blake assert(!q); 8979b4e38feSEric Blake 8989b4e38feSEric Blake v = visitor_input_test_init(data, "{ 'str':'hi' }"); 8999b4e38feSEric Blake visit_type_UserDefTwo(v, NULL, &r, &err); 9009b4e38feSEric Blake error_free_or_abort(&err); 9019b4e38feSEric Blake assert(!r); 9029b4e38feSEric Blake 9039b4e38feSEric Blake v = visitor_input_test_init(data, "{ }"); 9049b4e38feSEric Blake visit_type_WrapAlternate(v, NULL, &s, &err); 9059b4e38feSEric Blake error_free_or_abort(&err); 9069b4e38feSEric Blake assert(!s); 9073dcf71f6SPaolo Bonzini } 9083dcf71f6SPaolo Bonzini 9092533377cSEric Blake static void test_visitor_in_wrong_type(TestInputVisitorData *data, 9102533377cSEric Blake const void *unused) 9112533377cSEric Blake { 9122533377cSEric Blake TestStruct *p = NULL; 9132533377cSEric Blake Visitor *v; 9142533377cSEric Blake strList *q = NULL; 9152533377cSEric Blake int64_t i; 9162533377cSEric Blake Error *err = NULL; 9172533377cSEric Blake 9182533377cSEric Blake /* Make sure arrays and structs cannot be confused */ 9192533377cSEric Blake 9202533377cSEric Blake v = visitor_input_test_init(data, "[]"); 92151e72bc1SEric Blake visit_type_TestStruct(v, NULL, &p, &err); 9222533377cSEric Blake error_free_or_abort(&err); 9232533377cSEric Blake g_assert(!p); 9242533377cSEric Blake 9252533377cSEric Blake v = visitor_input_test_init(data, "{}"); 92651e72bc1SEric Blake visit_type_strList(v, NULL, &q, &err); 9272533377cSEric Blake error_free_or_abort(&err); 9282533377cSEric Blake assert(!q); 9292533377cSEric Blake 9302533377cSEric Blake /* Make sure primitives and struct cannot be confused */ 9312533377cSEric Blake 9322533377cSEric Blake v = visitor_input_test_init(data, "1"); 93351e72bc1SEric Blake visit_type_TestStruct(v, NULL, &p, &err); 9342533377cSEric Blake error_free_or_abort(&err); 9352533377cSEric Blake g_assert(!p); 9362533377cSEric Blake 9372533377cSEric Blake v = visitor_input_test_init(data, "{}"); 93851e72bc1SEric Blake visit_type_int(v, NULL, &i, &err); 9392533377cSEric Blake error_free_or_abort(&err); 9402533377cSEric Blake 9412533377cSEric Blake /* Make sure primitives and arrays cannot be confused */ 9422533377cSEric Blake 9432533377cSEric Blake v = visitor_input_test_init(data, "1"); 94451e72bc1SEric Blake visit_type_strList(v, NULL, &q, &err); 9452533377cSEric Blake error_free_or_abort(&err); 9462533377cSEric Blake assert(!q); 9472533377cSEric Blake 9482533377cSEric Blake v = visitor_input_test_init(data, "[]"); 94951e72bc1SEric Blake visit_type_int(v, NULL, &i, &err); 9502533377cSEric Blake error_free_or_abort(&err); 9512533377cSEric Blake } 9522533377cSEric Blake 95377c47de2SMarkus Armbruster static void test_visitor_in_fail_struct(TestInputVisitorData *data, 95477c47de2SMarkus Armbruster const void *unused) 95577c47de2SMarkus Armbruster { 95677c47de2SMarkus Armbruster TestStruct *p = NULL; 95777c47de2SMarkus Armbruster Error *err = NULL; 95877c47de2SMarkus Armbruster Visitor *v; 95977c47de2SMarkus Armbruster 96077c47de2SMarkus Armbruster v = visitor_input_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo', 'extra': 42 }"); 96177c47de2SMarkus Armbruster 96277c47de2SMarkus Armbruster visit_type_TestStruct(v, NULL, &p, &err); 96377c47de2SMarkus Armbruster error_free_or_abort(&err); 96477c47de2SMarkus Armbruster g_assert(!p); 96577c47de2SMarkus Armbruster } 96677c47de2SMarkus Armbruster 96777c47de2SMarkus Armbruster static void test_visitor_in_fail_struct_nested(TestInputVisitorData *data, 96877c47de2SMarkus Armbruster const void *unused) 96977c47de2SMarkus Armbruster { 97077c47de2SMarkus Armbruster UserDefTwo *udp = NULL; 97177c47de2SMarkus Armbruster Error *err = NULL; 97277c47de2SMarkus Armbruster Visitor *v; 97377c47de2SMarkus Armbruster 97477c47de2SMarkus 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'}}}"); 97577c47de2SMarkus Armbruster 97677c47de2SMarkus Armbruster visit_type_UserDefTwo(v, NULL, &udp, &err); 97777c47de2SMarkus Armbruster error_free_or_abort(&err); 97877c47de2SMarkus Armbruster g_assert(!udp); 97977c47de2SMarkus Armbruster } 98077c47de2SMarkus Armbruster 98177c47de2SMarkus Armbruster static void test_visitor_in_fail_struct_in_list(TestInputVisitorData *data, 98277c47de2SMarkus Armbruster const void *unused) 98377c47de2SMarkus Armbruster { 98477c47de2SMarkus Armbruster UserDefOneList *head = NULL; 98577c47de2SMarkus Armbruster Error *err = NULL; 98677c47de2SMarkus Armbruster Visitor *v; 98777c47de2SMarkus Armbruster 98877c47de2SMarkus Armbruster v = visitor_input_test_init(data, "[ { 'string': 'string0', 'integer': 42 }, { 'string': 'string1', 'integer': 43 }, { 'string': 'string2', 'integer': 44, 'extra': 'ggg' } ]"); 98977c47de2SMarkus Armbruster 99077c47de2SMarkus Armbruster visit_type_UserDefOneList(v, NULL, &head, &err); 99177c47de2SMarkus Armbruster error_free_or_abort(&err); 99277c47de2SMarkus Armbruster g_assert(!head); 99377c47de2SMarkus Armbruster } 99477c47de2SMarkus Armbruster 99577c47de2SMarkus Armbruster static void test_visitor_in_fail_struct_missing(TestInputVisitorData *data, 99677c47de2SMarkus Armbruster const void *unused) 99777c47de2SMarkus Armbruster { 99877c47de2SMarkus Armbruster Error *err = NULL; 99977c47de2SMarkus Armbruster Visitor *v; 100077c47de2SMarkus Armbruster QObject *any; 1001d2f95f4dSMarkus Armbruster QNull *null; 100277c47de2SMarkus Armbruster GenericAlternate *alt; 100377c47de2SMarkus Armbruster bool present; 100477c47de2SMarkus Armbruster int en; 100577c47de2SMarkus Armbruster int64_t i64; 100677c47de2SMarkus Armbruster uint32_t u32; 100777c47de2SMarkus Armbruster int8_t i8; 100877c47de2SMarkus Armbruster char *str; 100977c47de2SMarkus Armbruster double dbl; 101077c47de2SMarkus Armbruster 101186ca0dbeSMarkus Armbruster v = visitor_input_test_init(data, "{ 'sub': [ {} ] }"); 101277c47de2SMarkus Armbruster visit_start_struct(v, NULL, NULL, 0, &error_abort); 101377c47de2SMarkus Armbruster visit_start_struct(v, "struct", NULL, 0, &err); 101477c47de2SMarkus Armbruster error_free_or_abort(&err); 101577c47de2SMarkus Armbruster visit_start_list(v, "list", NULL, 0, &err); 101677c47de2SMarkus Armbruster error_free_or_abort(&err); 101760390d2dSMarc-André Lureau visit_start_alternate(v, "alternate", &alt, sizeof(*alt), &err); 101877c47de2SMarkus Armbruster error_free_or_abort(&err); 101977c47de2SMarkus Armbruster visit_optional(v, "optional", &present); 102077c47de2SMarkus Armbruster g_assert(!present); 1021f7abe0ecSMarc-André Lureau visit_type_enum(v, "enum", &en, &EnumOne_lookup, &err); 102277c47de2SMarkus Armbruster error_free_or_abort(&err); 102377c47de2SMarkus Armbruster visit_type_int(v, "i64", &i64, &err); 102477c47de2SMarkus Armbruster error_free_or_abort(&err); 102577c47de2SMarkus Armbruster visit_type_uint32(v, "u32", &u32, &err); 102677c47de2SMarkus Armbruster error_free_or_abort(&err); 102777c47de2SMarkus Armbruster visit_type_int8(v, "i8", &i8, &err); 102877c47de2SMarkus Armbruster error_free_or_abort(&err); 102977c47de2SMarkus Armbruster visit_type_str(v, "i8", &str, &err); 103077c47de2SMarkus Armbruster error_free_or_abort(&err); 103177c47de2SMarkus Armbruster visit_type_number(v, "dbl", &dbl, &err); 103277c47de2SMarkus Armbruster error_free_or_abort(&err); 103377c47de2SMarkus Armbruster visit_type_any(v, "any", &any, &err); 103477c47de2SMarkus Armbruster error_free_or_abort(&err); 1035d2f95f4dSMarkus Armbruster visit_type_null(v, "null", &null, &err); 103677c47de2SMarkus Armbruster error_free_or_abort(&err); 103786ca0dbeSMarkus Armbruster visit_start_list(v, "sub", NULL, 0, &error_abort); 103886ca0dbeSMarkus Armbruster visit_start_struct(v, NULL, NULL, 0, &error_abort); 103986ca0dbeSMarkus Armbruster visit_type_int(v, "i64", &i64, &err); 104086ca0dbeSMarkus Armbruster error_free_or_abort(&err); 104186ca0dbeSMarkus Armbruster visit_end_struct(v, NULL); 104286ca0dbeSMarkus Armbruster visit_end_list(v, NULL); 104377c47de2SMarkus Armbruster visit_end_struct(v, NULL); 104477c47de2SMarkus Armbruster } 104577c47de2SMarkus Armbruster 10469cb8ef36SMarkus Armbruster static void test_visitor_in_fail_list(TestInputVisitorData *data, 10479cb8ef36SMarkus Armbruster const void *unused) 10489cb8ef36SMarkus Armbruster { 10499cb8ef36SMarkus Armbruster int64_t i64 = -1; 1050a4a1c70dSMarkus Armbruster Error *err = NULL; 10519cb8ef36SMarkus Armbruster Visitor *v; 10529cb8ef36SMarkus Armbruster 10539cb8ef36SMarkus Armbruster /* Unvisited list tail */ 10549cb8ef36SMarkus Armbruster 10559cb8ef36SMarkus Armbruster v = visitor_input_test_init(data, "[ 1, 2, 3 ]"); 10569cb8ef36SMarkus Armbruster 10579cb8ef36SMarkus Armbruster visit_start_list(v, NULL, NULL, 0, &error_abort); 10589cb8ef36SMarkus Armbruster visit_type_int(v, NULL, &i64, &error_abort); 10599cb8ef36SMarkus Armbruster g_assert_cmpint(i64, ==, 1); 10609cb8ef36SMarkus Armbruster visit_type_int(v, NULL, &i64, &error_abort); 10619cb8ef36SMarkus Armbruster g_assert_cmpint(i64, ==, 2); 1062a4a1c70dSMarkus Armbruster visit_check_list(v, &err); 1063a4a1c70dSMarkus Armbruster error_free_or_abort(&err); 10649cb8ef36SMarkus Armbruster visit_end_list(v, NULL); 1065a9416dc6SMarkus Armbruster 1066a9416dc6SMarkus Armbruster /* Visit beyond end of list */ 1067a9416dc6SMarkus Armbruster v = visitor_input_test_init(data, "[]"); 1068a9416dc6SMarkus Armbruster 1069a9416dc6SMarkus Armbruster visit_start_list(v, NULL, NULL, 0, &error_abort); 1070a9416dc6SMarkus Armbruster visit_type_int(v, NULL, &i64, &err); 1071a9416dc6SMarkus Armbruster error_free_or_abort(&err); 1072a9416dc6SMarkus Armbruster visit_end_list(v, NULL); 10739cb8ef36SMarkus Armbruster } 10749cb8ef36SMarkus Armbruster 10759cb8ef36SMarkus Armbruster static void test_visitor_in_fail_list_nested(TestInputVisitorData *data, 10769cb8ef36SMarkus Armbruster const void *unused) 10779cb8ef36SMarkus Armbruster { 10789cb8ef36SMarkus Armbruster int64_t i64 = -1; 1079a4a1c70dSMarkus Armbruster Error *err = NULL; 10809cb8ef36SMarkus Armbruster Visitor *v; 10819cb8ef36SMarkus Armbruster 10829cb8ef36SMarkus Armbruster /* Unvisited nested list tail */ 10839cb8ef36SMarkus Armbruster 10849cb8ef36SMarkus Armbruster v = visitor_input_test_init(data, "[ 0, [ 1, 2, 3 ] ]"); 10859cb8ef36SMarkus Armbruster 10869cb8ef36SMarkus Armbruster visit_start_list(v, NULL, NULL, 0, &error_abort); 10879cb8ef36SMarkus Armbruster visit_type_int(v, NULL, &i64, &error_abort); 10889cb8ef36SMarkus Armbruster g_assert_cmpint(i64, ==, 0); 10899cb8ef36SMarkus Armbruster visit_start_list(v, NULL, NULL, 0, &error_abort); 10909cb8ef36SMarkus Armbruster visit_type_int(v, NULL, &i64, &error_abort); 10919cb8ef36SMarkus Armbruster g_assert_cmpint(i64, ==, 1); 1092a4a1c70dSMarkus Armbruster visit_check_list(v, &err); 1093a4a1c70dSMarkus Armbruster error_free_or_abort(&err); 10949cb8ef36SMarkus Armbruster visit_end_list(v, NULL); 1095a4a1c70dSMarkus Armbruster visit_check_list(v, &error_abort); 10969cb8ef36SMarkus Armbruster visit_end_list(v, NULL); 10979cb8ef36SMarkus Armbruster } 10989cb8ef36SMarkus Armbruster 109977c47de2SMarkus Armbruster static void test_visitor_in_fail_union_flat(TestInputVisitorData *data, 110077c47de2SMarkus Armbruster const void *unused) 110177c47de2SMarkus Armbruster { 110277c47de2SMarkus Armbruster UserDefFlatUnion *tmp = NULL; 110377c47de2SMarkus Armbruster Error *err = NULL; 110477c47de2SMarkus Armbruster Visitor *v; 110577c47de2SMarkus Armbruster 1106e7a76fe2SMarkus Armbruster v = visitor_input_test_init(data, "{ 'enum1': 'value2', 'string': 'c', 'integer': 41, 'boolean': true }"); 110777c47de2SMarkus Armbruster 110877c47de2SMarkus Armbruster visit_type_UserDefFlatUnion(v, NULL, &tmp, &err); 110977c47de2SMarkus Armbruster error_free_or_abort(&err); 111077c47de2SMarkus Armbruster g_assert(!tmp); 111177c47de2SMarkus Armbruster } 111277c47de2SMarkus Armbruster 111377c47de2SMarkus Armbruster static void test_visitor_in_fail_union_flat_no_discrim(TestInputVisitorData *data, 111477c47de2SMarkus Armbruster const void *unused) 111577c47de2SMarkus Armbruster { 111677c47de2SMarkus Armbruster UserDefFlatUnion2 *tmp = NULL; 111777c47de2SMarkus Armbruster Error *err = NULL; 111877c47de2SMarkus Armbruster Visitor *v; 111977c47de2SMarkus Armbruster 112077c47de2SMarkus Armbruster /* test situation where discriminator field ('enum1' here) is missing */ 112177c47de2SMarkus Armbruster v = visitor_input_test_init(data, "{ 'integer': 42, 'string': 'c', 'string1': 'd', 'string2': 'e' }"); 112277c47de2SMarkus Armbruster 112377c47de2SMarkus Armbruster visit_type_UserDefFlatUnion2(v, NULL, &tmp, &err); 112477c47de2SMarkus Armbruster error_free_or_abort(&err); 112577c47de2SMarkus Armbruster g_assert(!tmp); 112677c47de2SMarkus Armbruster } 112777c47de2SMarkus Armbruster 112877c47de2SMarkus Armbruster static void test_visitor_in_fail_alternate(TestInputVisitorData *data, 112977c47de2SMarkus Armbruster const void *unused) 113077c47de2SMarkus Armbruster { 113177c47de2SMarkus Armbruster UserDefAlternate *tmp; 113277c47de2SMarkus Armbruster Visitor *v; 113377c47de2SMarkus Armbruster Error *err = NULL; 113477c47de2SMarkus Armbruster 113577c47de2SMarkus Armbruster v = visitor_input_test_init(data, "3.14"); 113677c47de2SMarkus Armbruster 113777c47de2SMarkus Armbruster visit_type_UserDefAlternate(v, NULL, &tmp, &err); 113877c47de2SMarkus Armbruster error_free_or_abort(&err); 113977c47de2SMarkus Armbruster g_assert(!tmp); 114077c47de2SMarkus Armbruster } 114177c47de2SMarkus Armbruster 114277c47de2SMarkus Armbruster static void do_test_visitor_in_qmp_introspect(TestInputVisitorData *data, 11437d0f982bSMarc-André Lureau const QLitObject *qlit) 114477c47de2SMarkus Armbruster { 1145221db5daSDaniel P. Berrangé g_autoptr(SchemaInfoList) schema = NULL; 11467d0f982bSMarc-André Lureau QObject *obj = qobject_from_qlit(qlit); 114777c47de2SMarkus Armbruster Visitor *v; 114877c47de2SMarkus Armbruster 11497d0f982bSMarc-André Lureau v = qobject_input_visitor_new(obj); 115077c47de2SMarkus Armbruster 115177c47de2SMarkus Armbruster visit_type_SchemaInfoList(v, NULL, &schema, &error_abort); 115277c47de2SMarkus Armbruster g_assert(schema); 115377c47de2SMarkus Armbruster 1154cb3e7f08SMarc-André Lureau qobject_unref(obj); 11557d0f982bSMarc-André Lureau visit_free(v); 115677c47de2SMarkus Armbruster } 115777c47de2SMarkus Armbruster 115877c47de2SMarkus Armbruster static void test_visitor_in_qmp_introspect(TestInputVisitorData *data, 115977c47de2SMarkus Armbruster const void *unused) 116077c47de2SMarkus Armbruster { 11617d0f982bSMarc-André Lureau do_test_visitor_in_qmp_introspect(data, &test_qmp_schema_qlit); 116277c47de2SMarkus Armbruster } 116377c47de2SMarkus Armbruster 1164d88f5fd1SLuiz Capitulino int main(int argc, char **argv) 1165d88f5fd1SLuiz Capitulino { 1166d88f5fd1SLuiz Capitulino g_test_init(&argc, &argv, NULL); 1167d88f5fd1SLuiz Capitulino 1168d88f5fd1SLuiz Capitulino input_visitor_test_add("/visitor/input/int", 1169b1d2e5f1SDaniel P. Berrange NULL, test_visitor_in_int); 11704bc0c94dSMarkus Armbruster input_visitor_test_add("/visitor/input/uint", 11714bc0c94dSMarkus Armbruster NULL, test_visitor_in_uint); 1172e92cfa0dSMichael Roth input_visitor_test_add("/visitor/input/int_overflow", 1173b1d2e5f1SDaniel P. Berrange NULL, test_visitor_in_int_overflow); 1174cbd8acf3SDaniel P. Berrange input_visitor_test_add("/visitor/input/int_keyval", 1175cbd8acf3SDaniel P. Berrange NULL, test_visitor_in_int_keyval); 1176cbd8acf3SDaniel P. Berrange input_visitor_test_add("/visitor/input/int_str_keyval", 1177cbd8acf3SDaniel P. Berrange NULL, test_visitor_in_int_str_keyval); 1178cbd8acf3SDaniel P. Berrange input_visitor_test_add("/visitor/input/int_str_fail", 1179cbd8acf3SDaniel P. Berrange NULL, test_visitor_in_int_str_fail); 1180d88f5fd1SLuiz Capitulino input_visitor_test_add("/visitor/input/bool", 1181b1d2e5f1SDaniel P. Berrange NULL, test_visitor_in_bool); 1182cbd8acf3SDaniel P. Berrange input_visitor_test_add("/visitor/input/bool_keyval", 1183cbd8acf3SDaniel P. Berrange NULL, test_visitor_in_bool_keyval); 1184cbd8acf3SDaniel P. Berrange input_visitor_test_add("/visitor/input/bool_str_keyval", 1185cbd8acf3SDaniel P. Berrange NULL, test_visitor_in_bool_str_keyval); 1186cbd8acf3SDaniel P. Berrange input_visitor_test_add("/visitor/input/bool_str_fail", 1187cbd8acf3SDaniel P. Berrange NULL, test_visitor_in_bool_str_fail); 1188d88f5fd1SLuiz Capitulino input_visitor_test_add("/visitor/input/number", 1189b1d2e5f1SDaniel P. Berrange NULL, test_visitor_in_number); 1190c1214ad3SMarc-André Lureau input_visitor_test_add("/visitor/input/large_number", 1191c1214ad3SMarc-André Lureau NULL, test_visitor_in_large_number); 1192cbd8acf3SDaniel P. Berrange input_visitor_test_add("/visitor/input/number_keyval", 1193cbd8acf3SDaniel P. Berrange NULL, test_visitor_in_number_keyval); 1194cbd8acf3SDaniel P. Berrange input_visitor_test_add("/visitor/input/number_str_keyval", 1195cbd8acf3SDaniel P. Berrange NULL, test_visitor_in_number_str_keyval); 1196cbd8acf3SDaniel P. Berrange input_visitor_test_add("/visitor/input/number_str_fail", 1197cbd8acf3SDaniel P. Berrange NULL, test_visitor_in_number_str_fail); 1198cbd8acf3SDaniel P. Berrange input_visitor_test_add("/visitor/input/size_str_keyval", 1199cbd8acf3SDaniel P. Berrange NULL, test_visitor_in_size_str_keyval); 1200cbd8acf3SDaniel P. Berrange input_visitor_test_add("/visitor/input/size_str_fail", 1201cbd8acf3SDaniel P. Berrange NULL, test_visitor_in_size_str_fail); 1202d88f5fd1SLuiz Capitulino input_visitor_test_add("/visitor/input/string", 1203b1d2e5f1SDaniel P. Berrange NULL, test_visitor_in_string); 1204d88f5fd1SLuiz Capitulino input_visitor_test_add("/visitor/input/enum", 1205b1d2e5f1SDaniel P. Berrange NULL, test_visitor_in_enum); 1206d88f5fd1SLuiz Capitulino input_visitor_test_add("/visitor/input/struct", 1207b1d2e5f1SDaniel P. Berrange NULL, test_visitor_in_struct); 1208d88f5fd1SLuiz Capitulino input_visitor_test_add("/visitor/input/struct-nested", 1209b1d2e5f1SDaniel P. Berrange NULL, test_visitor_in_struct_nested); 1210e7a76fe2SMarkus Armbruster input_visitor_test_add("/visitor/input/list2", 1211e7a76fe2SMarkus Armbruster NULL, test_visitor_in_list_struct); 1212d88f5fd1SLuiz Capitulino input_visitor_test_add("/visitor/input/list", 1213b1d2e5f1SDaniel P. Berrange NULL, test_visitor_in_list); 121428770e05SMarkus Armbruster input_visitor_test_add("/visitor/input/any", 1215b1d2e5f1SDaniel P. Berrange NULL, test_visitor_in_any); 12163df016f1SEric Blake input_visitor_test_add("/visitor/input/null", 1217b1d2e5f1SDaniel P. Berrange NULL, test_visitor_in_null); 12182fc00432SMarkus Armbruster input_visitor_test_add("/visitor/input/union-flat", 1219b1d2e5f1SDaniel P. Berrange NULL, test_visitor_in_union_flat); 1220ab045267SEric Blake input_visitor_test_add("/visitor/input/alternate", 1221b1d2e5f1SDaniel P. Berrange NULL, test_visitor_in_alternate); 12223dcf71f6SPaolo Bonzini input_visitor_test_add("/visitor/input/errors", 1223b1d2e5f1SDaniel P. Berrange NULL, test_visitor_in_errors); 12242533377cSEric Blake input_visitor_test_add("/visitor/input/wrong-type", 1225b1d2e5f1SDaniel P. Berrange NULL, test_visitor_in_wrong_type); 12269c51b441SEric Blake input_visitor_test_add("/visitor/input/alternate-number", 1227b1d2e5f1SDaniel P. Berrange NULL, test_visitor_in_alternate_number); 1228*79db9948SPaolo Bonzini input_visitor_test_add("/visitor/input/alternate-list", 1229*79db9948SPaolo Bonzini NULL, test_visitor_in_alternate_list); 123077c47de2SMarkus Armbruster input_visitor_test_add("/visitor/input/fail/struct", 123177c47de2SMarkus Armbruster NULL, test_visitor_in_fail_struct); 123277c47de2SMarkus Armbruster input_visitor_test_add("/visitor/input/fail/struct-nested", 123377c47de2SMarkus Armbruster NULL, test_visitor_in_fail_struct_nested); 123477c47de2SMarkus Armbruster input_visitor_test_add("/visitor/input/fail/struct-in-list", 123577c47de2SMarkus Armbruster NULL, test_visitor_in_fail_struct_in_list); 123677c47de2SMarkus Armbruster input_visitor_test_add("/visitor/input/fail/struct-missing", 123777c47de2SMarkus Armbruster NULL, test_visitor_in_fail_struct_missing); 12389cb8ef36SMarkus Armbruster input_visitor_test_add("/visitor/input/fail/list", 12399cb8ef36SMarkus Armbruster NULL, test_visitor_in_fail_list); 12409cb8ef36SMarkus Armbruster input_visitor_test_add("/visitor/input/fail/list-nested", 12419cb8ef36SMarkus Armbruster NULL, test_visitor_in_fail_list_nested); 124277c47de2SMarkus Armbruster input_visitor_test_add("/visitor/input/fail/union-flat", 124377c47de2SMarkus Armbruster NULL, test_visitor_in_fail_union_flat); 124477c47de2SMarkus Armbruster input_visitor_test_add("/visitor/input/fail/union-flat-no-discriminator", 124577c47de2SMarkus Armbruster NULL, test_visitor_in_fail_union_flat_no_discrim); 124677c47de2SMarkus Armbruster input_visitor_test_add("/visitor/input/fail/alternate", 124777c47de2SMarkus Armbruster NULL, test_visitor_in_fail_alternate); 1248eb815e24SMarkus Armbruster input_visitor_test_add("/visitor/input/qapi-introspect", 124977c47de2SMarkus Armbruster NULL, test_visitor_in_qmp_introspect); 1250d88f5fd1SLuiz Capitulino 1251d88f5fd1SLuiz Capitulino g_test_run(); 1252d88f5fd1SLuiz Capitulino 1253d88f5fd1SLuiz Capitulino return 0; 1254d88f5fd1SLuiz Capitulino } 1255