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 9796420a30SMichael Tokarev * programmatically generated strings (and we can't pass in programmatically 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"); 4344b2fc7dbSMarkus Armbruster g_assert(!udp->dict1->dict3); 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++) { 4506a54ac2aSMarc-André Lureau g_autofree char *string = g_strdup_printf("string%d", i); 451d88f5fd1SLuiz Capitulino 452d88f5fd1SLuiz Capitulino g_assert_cmpstr(item->value->string, ==, string); 453ddf21908SEric Blake g_assert_cmpint(item->value->integer, ==, 42 + i); 454d88f5fd1SLuiz Capitulino } 455d88f5fd1SLuiz Capitulino 456d88f5fd1SLuiz Capitulino qapi_free_UserDefOneList(head); 4572533377cSEric Blake head = NULL; 4582533377cSEric Blake 4592533377cSEric Blake /* An empty list is valid */ 4602533377cSEric Blake v = visitor_input_test_init(data, "[]"); 46151e72bc1SEric Blake visit_type_UserDefOneList(v, NULL, &head, &error_abort); 4622533377cSEric Blake g_assert(!head); 463d88f5fd1SLuiz Capitulino } 464d88f5fd1SLuiz Capitulino 465e7a76fe2SMarkus Armbruster static void test_visitor_in_list_struct(TestInputVisitorData *data, 466e7a76fe2SMarkus Armbruster const void *unused) 467e7a76fe2SMarkus Armbruster { 468e7a76fe2SMarkus Armbruster const char *int_member[] = { 469e7a76fe2SMarkus Armbruster "integer", "s8", "s16", "s32", "s64", "u8", "u16", "u32", "u64" }; 470e7a76fe2SMarkus Armbruster g_autoptr(GString) json = g_string_new(""); 471e7a76fe2SMarkus Armbruster int i, j; 472e7a76fe2SMarkus Armbruster const char *sep; 473e7a76fe2SMarkus Armbruster g_autoptr(ArrayStruct) arrs = NULL; 474e7a76fe2SMarkus Armbruster Visitor *v; 475e7a76fe2SMarkus Armbruster intList *int_list; 476e7a76fe2SMarkus Armbruster int8List *s8_list; 477e7a76fe2SMarkus Armbruster int16List *s16_list; 478e7a76fe2SMarkus Armbruster int32List *s32_list; 479e7a76fe2SMarkus Armbruster int64List *s64_list; 480e7a76fe2SMarkus Armbruster uint8List *u8_list; 481e7a76fe2SMarkus Armbruster uint16List *u16_list; 482e7a76fe2SMarkus Armbruster uint32List *u32_list; 483e7a76fe2SMarkus Armbruster uint64List *u64_list; 484e7a76fe2SMarkus Armbruster numberList *num_list; 485e7a76fe2SMarkus Armbruster boolList *bool_list; 486e7a76fe2SMarkus Armbruster strList *str_list; 487e7a76fe2SMarkus Armbruster 488e7a76fe2SMarkus Armbruster g_string_append_printf(json, "{"); 489e7a76fe2SMarkus Armbruster 490e7a76fe2SMarkus Armbruster for (i = 0; i < G_N_ELEMENTS(int_member); i++) { 491e7a76fe2SMarkus Armbruster g_string_append_printf(json, "'%s': [", int_member[i]); 492e7a76fe2SMarkus Armbruster sep = ""; 493e7a76fe2SMarkus Armbruster for (j = 0; j < 32; j++) { 494e7a76fe2SMarkus Armbruster g_string_append_printf(json, "%s%d", sep, j); 495e7a76fe2SMarkus Armbruster sep = ", "; 496e7a76fe2SMarkus Armbruster } 497e7a76fe2SMarkus Armbruster g_string_append_printf(json, "], "); 498e7a76fe2SMarkus Armbruster } 499e7a76fe2SMarkus Armbruster 500e7a76fe2SMarkus Armbruster g_string_append_printf(json, "'number': ["); 501e7a76fe2SMarkus Armbruster sep = ""; 502e7a76fe2SMarkus Armbruster for (i = 0; i < 32; i++) { 503e7a76fe2SMarkus Armbruster g_string_append_printf(json, "%s%f", sep, (double)i / 3); 504e7a76fe2SMarkus Armbruster sep = ", "; 505e7a76fe2SMarkus Armbruster } 506e7a76fe2SMarkus Armbruster g_string_append_printf(json, "], "); 507e7a76fe2SMarkus Armbruster 508e7a76fe2SMarkus Armbruster g_string_append_printf(json, "'boolean': ["); 509e7a76fe2SMarkus Armbruster sep = ""; 510e7a76fe2SMarkus Armbruster for (i = 0; i < 32; i++) { 511e7a76fe2SMarkus Armbruster g_string_append_printf(json, "%s%s", 512e7a76fe2SMarkus Armbruster sep, i % 3 == 0 ? "true" : "false"); 513e7a76fe2SMarkus Armbruster sep = ", "; 514e7a76fe2SMarkus Armbruster } 515e7a76fe2SMarkus Armbruster g_string_append_printf(json, "], "); 516e7a76fe2SMarkus Armbruster 517e7a76fe2SMarkus Armbruster g_string_append_printf(json, "'string': ["); 518e7a76fe2SMarkus Armbruster sep = ""; 519e7a76fe2SMarkus Armbruster for (i = 0; i < 32; i++) { 520e7a76fe2SMarkus Armbruster g_string_append_printf(json, "%s'%d'", sep, i); 521e7a76fe2SMarkus Armbruster sep = ", "; 522e7a76fe2SMarkus Armbruster } 523e7a76fe2SMarkus Armbruster g_string_append_printf(json, "]"); 524e7a76fe2SMarkus Armbruster 525e7a76fe2SMarkus Armbruster g_string_append_printf(json, "}"); 526e7a76fe2SMarkus Armbruster 527e7a76fe2SMarkus Armbruster v = visitor_input_test_init_raw(data, json->str); 528e7a76fe2SMarkus Armbruster visit_type_ArrayStruct(v, NULL, &arrs, &error_abort); 529e7a76fe2SMarkus Armbruster 530e7a76fe2SMarkus Armbruster i = 0; 531e7a76fe2SMarkus Armbruster for (int_list = arrs->integer; int_list; int_list = int_list->next) { 532e7a76fe2SMarkus Armbruster g_assert_cmpint(int_list->value, ==, i); 533e7a76fe2SMarkus Armbruster i++; 534e7a76fe2SMarkus Armbruster } 535e7a76fe2SMarkus Armbruster 536e7a76fe2SMarkus Armbruster i = 0; 537e7a76fe2SMarkus Armbruster for (s8_list = arrs->s8; s8_list; s8_list = s8_list->next) { 538e7a76fe2SMarkus Armbruster g_assert_cmpint(s8_list->value, ==, i); 539e7a76fe2SMarkus Armbruster i++; 540e7a76fe2SMarkus Armbruster } 541e7a76fe2SMarkus Armbruster 542e7a76fe2SMarkus Armbruster i = 0; 543e7a76fe2SMarkus Armbruster for (s16_list = arrs->s16; s16_list; s16_list = s16_list->next) { 544e7a76fe2SMarkus Armbruster g_assert_cmpint(s16_list->value, ==, i); 545e7a76fe2SMarkus Armbruster i++; 546e7a76fe2SMarkus Armbruster } 547e7a76fe2SMarkus Armbruster 548e7a76fe2SMarkus Armbruster i = 0; 549e7a76fe2SMarkus Armbruster for (s32_list = arrs->s32; s32_list; s32_list = s32_list->next) { 550e7a76fe2SMarkus Armbruster g_assert_cmpint(s32_list->value, ==, i); 551e7a76fe2SMarkus Armbruster i++; 552e7a76fe2SMarkus Armbruster } 553e7a76fe2SMarkus Armbruster 554e7a76fe2SMarkus Armbruster i = 0; 555e7a76fe2SMarkus Armbruster for (s64_list = arrs->s64; s64_list; s64_list = s64_list->next) { 556e7a76fe2SMarkus Armbruster g_assert_cmpint(s64_list->value, ==, i); 557e7a76fe2SMarkus Armbruster i++; 558e7a76fe2SMarkus Armbruster } 559e7a76fe2SMarkus Armbruster 560e7a76fe2SMarkus Armbruster i = 0; 561e7a76fe2SMarkus Armbruster for (u8_list = arrs->u8; u8_list; u8_list = u8_list->next) { 562e7a76fe2SMarkus Armbruster g_assert_cmpint(u8_list->value, ==, i); 563e7a76fe2SMarkus Armbruster i++; 564e7a76fe2SMarkus Armbruster } 565e7a76fe2SMarkus Armbruster 566e7a76fe2SMarkus Armbruster i = 0; 567e7a76fe2SMarkus Armbruster for (u16_list = arrs->u16; u16_list; u16_list = u16_list->next) { 568e7a76fe2SMarkus Armbruster g_assert_cmpint(u16_list->value, ==, i); 569e7a76fe2SMarkus Armbruster i++; 570e7a76fe2SMarkus Armbruster } 571e7a76fe2SMarkus Armbruster 572e7a76fe2SMarkus Armbruster i = 0; 573e7a76fe2SMarkus Armbruster for (u32_list = arrs->u32; u32_list; u32_list = u32_list->next) { 574e7a76fe2SMarkus Armbruster g_assert_cmpint(u32_list->value, ==, i); 575e7a76fe2SMarkus Armbruster i++; 576e7a76fe2SMarkus Armbruster } 577e7a76fe2SMarkus Armbruster 578e7a76fe2SMarkus Armbruster i = 0; 579e7a76fe2SMarkus Armbruster for (u64_list = arrs->u64; u64_list; u64_list = u64_list->next) { 580e7a76fe2SMarkus Armbruster g_assert_cmpint(u64_list->value, ==, i); 581e7a76fe2SMarkus Armbruster i++; 582e7a76fe2SMarkus Armbruster } 583e7a76fe2SMarkus Armbruster 584e7a76fe2SMarkus Armbruster i = 0; 585e7a76fe2SMarkus Armbruster for (num_list = arrs->number; num_list; num_list = num_list->next) { 586e7a76fe2SMarkus Armbruster char expected[32], actual[32]; 587e7a76fe2SMarkus Armbruster 588e7a76fe2SMarkus Armbruster sprintf(expected, "%.6f", (double)i / 3); 589e7a76fe2SMarkus Armbruster sprintf(actual, "%.6f", num_list->value); 590e7a76fe2SMarkus Armbruster g_assert_cmpstr(expected, ==, actual); 591e7a76fe2SMarkus Armbruster i++; 592e7a76fe2SMarkus Armbruster } 593e7a76fe2SMarkus Armbruster 594e7a76fe2SMarkus Armbruster i = 0; 595e7a76fe2SMarkus Armbruster for (bool_list = arrs->boolean; bool_list; bool_list = bool_list->next) { 596e7a76fe2SMarkus Armbruster g_assert_cmpint(bool_list->value, ==, i % 3 == 0); 597e7a76fe2SMarkus Armbruster i++; 598e7a76fe2SMarkus Armbruster } 599e7a76fe2SMarkus Armbruster 600e7a76fe2SMarkus Armbruster i = 0; 601e7a76fe2SMarkus Armbruster for (str_list = arrs->string; str_list; str_list = str_list->next) { 602e7a76fe2SMarkus Armbruster char expected[32]; 603e7a76fe2SMarkus Armbruster 604e7a76fe2SMarkus Armbruster sprintf(expected, "%d", i); 605e7a76fe2SMarkus Armbruster g_assert_cmpstr(str_list->value, ==, expected); 606e7a76fe2SMarkus Armbruster i++; 607e7a76fe2SMarkus Armbruster } 608e7a76fe2SMarkus Armbruster } 609e7a76fe2SMarkus Armbruster 61028770e05SMarkus Armbruster static void test_visitor_in_any(TestInputVisitorData *data, 61128770e05SMarkus Armbruster const void *unused) 61228770e05SMarkus Armbruster { 61328770e05SMarkus Armbruster QObject *res = NULL; 61428770e05SMarkus Armbruster Visitor *v; 61501b2ffceSMarc-André Lureau QNum *qnum; 61628770e05SMarkus Armbruster QBool *qbool; 61728770e05SMarkus Armbruster QString *qstring; 61828770e05SMarkus Armbruster QDict *qdict; 61928770e05SMarkus Armbruster QObject *qobj; 62001b2ffceSMarc-André Lureau int64_t val; 62128770e05SMarkus Armbruster 62228770e05SMarkus Armbruster v = visitor_input_test_init(data, "-42"); 62351e72bc1SEric Blake visit_type_any(v, NULL, &res, &error_abort); 6247dc847ebSMax Reitz qnum = qobject_to(QNum, res); 62501b2ffceSMarc-André Lureau g_assert(qnum); 62601b2ffceSMarc-André Lureau g_assert(qnum_get_try_int(qnum, &val)); 62701b2ffceSMarc-André Lureau g_assert_cmpint(val, ==, -42); 628cb3e7f08SMarc-André Lureau qobject_unref(res); 62928770e05SMarkus Armbruster 63028770e05SMarkus Armbruster v = visitor_input_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo' }"); 63151e72bc1SEric Blake visit_type_any(v, NULL, &res, &error_abort); 6327dc847ebSMax Reitz qdict = qobject_to(QDict, res); 63328770e05SMarkus Armbruster g_assert(qdict && qdict_size(qdict) == 3); 63428770e05SMarkus Armbruster qobj = qdict_get(qdict, "integer"); 63528770e05SMarkus Armbruster g_assert(qobj); 6367dc847ebSMax Reitz qnum = qobject_to(QNum, qobj); 63701b2ffceSMarc-André Lureau g_assert(qnum); 63801b2ffceSMarc-André Lureau g_assert(qnum_get_try_int(qnum, &val)); 63901b2ffceSMarc-André Lureau g_assert_cmpint(val, ==, -42); 64028770e05SMarkus Armbruster qobj = qdict_get(qdict, "boolean"); 64128770e05SMarkus Armbruster g_assert(qobj); 6427dc847ebSMax Reitz qbool = qobject_to(QBool, qobj); 64328770e05SMarkus Armbruster g_assert(qbool); 64428770e05SMarkus Armbruster g_assert(qbool_get_bool(qbool) == true); 64528770e05SMarkus Armbruster qobj = qdict_get(qdict, "string"); 64628770e05SMarkus Armbruster g_assert(qobj); 6477dc847ebSMax Reitz qstring = qobject_to(QString, qobj); 64828770e05SMarkus Armbruster g_assert(qstring); 64928770e05SMarkus Armbruster g_assert_cmpstr(qstring_get_str(qstring), ==, "foo"); 650cb3e7f08SMarc-André Lureau qobject_unref(res); 65128770e05SMarkus Armbruster } 65228770e05SMarkus Armbruster 6533df016f1SEric Blake static void test_visitor_in_null(TestInputVisitorData *data, 6543df016f1SEric Blake const void *unused) 6553df016f1SEric Blake { 6563df016f1SEric Blake Visitor *v; 6573df016f1SEric Blake Error *err = NULL; 658d2f95f4dSMarkus Armbruster QNull *null; 6593df016f1SEric Blake char *tmp; 6603df016f1SEric Blake 6613df016f1SEric Blake /* 6623df016f1SEric Blake * FIXME: Since QAPI doesn't know the 'null' type yet, we can't 6633df016f1SEric Blake * test visit_type_null() by reading into a QAPI struct then 6643df016f1SEric Blake * checking that it was populated correctly. The best we can do 6653df016f1SEric Blake * for now is ensure that we consumed null from the input, proven 6663df016f1SEric Blake * by the fact that we can't re-read the key; and that we detect 6673df016f1SEric Blake * when input is not null. 6683df016f1SEric Blake */ 6693df016f1SEric Blake 670cbd8acf3SDaniel P. Berrange v = visitor_input_test_init_full(data, false, 671cbd8acf3SDaniel P. Berrange "{ 'a': null, 'b': '' }"); 6723df016f1SEric Blake visit_start_struct(v, NULL, NULL, 0, &error_abort); 673d2f95f4dSMarkus Armbruster visit_type_null(v, "a", &null, &error_abort); 674d2f95f4dSMarkus Armbruster g_assert(qobject_type(QOBJECT(null)) == QTYPE_QNULL); 675cb3e7f08SMarc-André Lureau qobject_unref(null); 676d2f95f4dSMarkus Armbruster visit_type_null(v, "b", &null, &err); 6773df016f1SEric Blake error_free_or_abort(&err); 678d2f95f4dSMarkus Armbruster g_assert(!null); 679ec95f614SMarkus Armbruster visit_type_str(v, "c", &tmp, &err); 680ec95f614SMarkus Armbruster error_free_or_abort(&err); 681d2f95f4dSMarkus Armbruster g_assert(!tmp); 68215c2f669SEric Blake visit_check_struct(v, &error_abort); 6831158bb2aSEric Blake visit_end_struct(v, NULL); 6843df016f1SEric Blake } 6853df016f1SEric Blake 6862fc00432SMarkus Armbruster static void test_visitor_in_union_flat(TestInputVisitorData *data, 6872fc00432SMarkus Armbruster const void *unused) 6882fc00432SMarkus Armbruster { 6892fc00432SMarkus Armbruster Visitor *v; 690221db5daSDaniel P. Berrangé g_autoptr(UserDefFlatUnion) tmp = NULL; 69130594fe1SEric Blake UserDefUnionBase *base; 6922fc00432SMarkus Armbruster 6935223070cSWenchao Xia v = visitor_input_test_init(data, 6945223070cSWenchao Xia "{ 'enum1': 'value1', " 695441cbac0SMarkus Armbruster "'integer': 41, " 6965223070cSWenchao Xia "'string': 'str', " 6975223070cSWenchao Xia "'boolean': true }"); 6982fc00432SMarkus Armbruster 69951e72bc1SEric Blake visit_type_UserDefFlatUnion(v, NULL, &tmp, &error_abort); 7000f61af3eSMarkus Armbruster g_assert_cmpint(tmp->enum1, ==, ENUM_ONE_VALUE1); 7015223070cSWenchao Xia g_assert_cmpstr(tmp->string, ==, "str"); 702441cbac0SMarkus Armbruster g_assert_cmpint(tmp->integer, ==, 41); 703544a3731SEric Blake g_assert_cmpint(tmp->u.value1.boolean, ==, true); 70430594fe1SEric Blake 70530594fe1SEric Blake base = qapi_UserDefFlatUnion_base(tmp); 70630594fe1SEric Blake g_assert(&base->enum1 == &tmp->enum1); 7072fc00432SMarkus Armbruster } 7082fc00432SMarkus Armbruster 709a17dbc4bSDaniel P. Berrangé static void test_visitor_in_union_in_union(TestInputVisitorData *data, 710a17dbc4bSDaniel P. Berrangé const void *unused) 711a17dbc4bSDaniel P. Berrangé { 712a17dbc4bSDaniel P. Berrangé Visitor *v; 713a17dbc4bSDaniel P. Berrangé g_autoptr(TestUnionInUnion) tmp = NULL; 714a17dbc4bSDaniel P. Berrangé 715a17dbc4bSDaniel P. Berrangé v = visitor_input_test_init(data, 716a17dbc4bSDaniel P. Berrangé "{ 'type': 'value-a', " 717a17dbc4bSDaniel P. Berrangé " 'type-a': 'value-a1', " 718a17dbc4bSDaniel P. Berrangé " 'integer': 2, " 719a17dbc4bSDaniel P. Berrangé " 'name': 'fish' }"); 720a17dbc4bSDaniel P. Berrangé 721a17dbc4bSDaniel P. Berrangé visit_type_TestUnionInUnion(v, NULL, &tmp, &error_abort); 722a17dbc4bSDaniel P. Berrangé g_assert_cmpint(tmp->type, ==, TEST_UNION_ENUM_VALUE_A); 723*a25b2312SMarkus Armbruster g_assert_cmpint(tmp->u.value_a.type_a, ==, TEST_UNION_ENUM_A_VALUE_A1); 724a17dbc4bSDaniel P. Berrangé g_assert_cmpint(tmp->u.value_a.u.value_a1.integer, ==, 2); 725a17dbc4bSDaniel P. Berrangé g_assert_cmpint(strcmp(tmp->u.value_a.u.value_a1.name, "fish"), ==, 0); 726a17dbc4bSDaniel P. Berrangé 727a17dbc4bSDaniel P. Berrangé qapi_free_TestUnionInUnion(tmp); 728a17dbc4bSDaniel P. Berrangé 729a17dbc4bSDaniel P. Berrangé v = visitor_input_test_init(data, 730a17dbc4bSDaniel P. Berrangé "{ 'type': 'value-a', " 731a17dbc4bSDaniel P. Berrangé " 'type-a': 'value-a2', " 732a17dbc4bSDaniel P. Berrangé " 'integer': 1729, " 733a17dbc4bSDaniel P. Berrangé " 'size': 87539319 }"); 734a17dbc4bSDaniel P. Berrangé 735a17dbc4bSDaniel P. Berrangé visit_type_TestUnionInUnion(v, NULL, &tmp, &error_abort); 736a17dbc4bSDaniel P. Berrangé g_assert_cmpint(tmp->type, ==, TEST_UNION_ENUM_VALUE_A); 737*a25b2312SMarkus Armbruster g_assert_cmpint(tmp->u.value_a.type_a, ==, TEST_UNION_ENUM_A_VALUE_A2); 738a17dbc4bSDaniel P. Berrangé g_assert_cmpint(tmp->u.value_a.u.value_a2.integer, ==, 1729); 739a17dbc4bSDaniel P. Berrangé g_assert_cmpint(tmp->u.value_a.u.value_a2.size, ==, 87539319); 740a17dbc4bSDaniel P. Berrangé 741a17dbc4bSDaniel P. Berrangé qapi_free_TestUnionInUnion(tmp); 742a17dbc4bSDaniel P. Berrangé 743a17dbc4bSDaniel P. Berrangé v = visitor_input_test_init(data, 744a17dbc4bSDaniel P. Berrangé "{ 'type': 'value-b', " 745a17dbc4bSDaniel P. Berrangé " 'integer': 1729, " 746a17dbc4bSDaniel P. Berrangé " 'onoff': true }"); 747a17dbc4bSDaniel P. Berrangé 748a17dbc4bSDaniel P. Berrangé visit_type_TestUnionInUnion(v, NULL, &tmp, &error_abort); 749a17dbc4bSDaniel P. Berrangé g_assert_cmpint(tmp->type, ==, TEST_UNION_ENUM_VALUE_B); 750a17dbc4bSDaniel P. Berrangé g_assert_cmpint(tmp->u.value_b.integer, ==, 1729); 751a17dbc4bSDaniel P. Berrangé g_assert_cmpint(tmp->u.value_b.onoff, ==, true); 752a17dbc4bSDaniel P. Berrangé } 753a17dbc4bSDaniel P. Berrangé 754ab045267SEric Blake static void test_visitor_in_alternate(TestInputVisitorData *data, 7552c38b600SMarkus Armbruster const void *unused) 7562c38b600SMarkus Armbruster { 7572c38b600SMarkus Armbruster Visitor *v; 758ab045267SEric Blake UserDefAlternate *tmp; 75968d07839SEric Blake WrapAlternate *wrap; 7602c38b600SMarkus Armbruster 7612c38b600SMarkus Armbruster v = visitor_input_test_init(data, "42"); 76251e72bc1SEric Blake visit_type_UserDefAlternate(v, NULL, &tmp, &error_abort); 76301b2ffceSMarc-André Lureau g_assert_cmpint(tmp->type, ==, QTYPE_QNUM); 764c363acefSEric Blake g_assert_cmpint(tmp->u.i, ==, 42); 765ab045267SEric Blake qapi_free_UserDefAlternate(tmp); 7669c51b441SEric Blake 7678168ca8eSMarkus Armbruster v = visitor_input_test_init(data, "'value1'"); 76851e72bc1SEric Blake visit_type_UserDefAlternate(v, NULL, &tmp, &error_abort); 7690426d53cSEric Blake g_assert_cmpint(tmp->type, ==, QTYPE_QSTRING); 7708168ca8eSMarkus Armbruster g_assert_cmpint(tmp->u.e, ==, ENUM_ONE_VALUE1); 7719c51b441SEric Blake qapi_free_UserDefAlternate(tmp); 7729c51b441SEric Blake 7734d2d5c41SMarkus Armbruster v = visitor_input_test_init(data, "null"); 7744d2d5c41SMarkus Armbruster visit_type_UserDefAlternate(v, NULL, &tmp, &error_abort); 7754d2d5c41SMarkus Armbruster g_assert_cmpint(tmp->type, ==, QTYPE_QNULL); 7764d2d5c41SMarkus Armbruster qapi_free_UserDefAlternate(tmp); 7774d2d5c41SMarkus Armbruster 77868d07839SEric Blake v = visitor_input_test_init(data, "{'integer':1, 'string':'str', " 77968d07839SEric Blake "'enum1':'value1', 'boolean':true}"); 78068d07839SEric Blake visit_type_UserDefAlternate(v, NULL, &tmp, &error_abort); 78168d07839SEric Blake g_assert_cmpint(tmp->type, ==, QTYPE_QDICT); 782becceedcSEric Blake g_assert_cmpint(tmp->u.udfu.integer, ==, 1); 783becceedcSEric Blake g_assert_cmpstr(tmp->u.udfu.string, ==, "str"); 784becceedcSEric Blake g_assert_cmpint(tmp->u.udfu.enum1, ==, ENUM_ONE_VALUE1); 785544a3731SEric Blake g_assert_cmpint(tmp->u.udfu.u.value1.boolean, ==, true); 786544a3731SEric Blake g_assert_cmpint(tmp->u.udfu.u.value1.has_a_b, ==, false); 78768d07839SEric Blake qapi_free_UserDefAlternate(tmp); 78868d07839SEric Blake 78968d07839SEric Blake v = visitor_input_test_init(data, "{ 'alt': 42 }"); 79068d07839SEric Blake visit_type_WrapAlternate(v, NULL, &wrap, &error_abort); 79101b2ffceSMarc-André Lureau g_assert_cmpint(wrap->alt->type, ==, QTYPE_QNUM); 79268d07839SEric Blake g_assert_cmpint(wrap->alt->u.i, ==, 42); 79368d07839SEric Blake qapi_free_WrapAlternate(wrap); 79468d07839SEric Blake 7958168ca8eSMarkus Armbruster v = visitor_input_test_init(data, "{ 'alt': 'value1' }"); 79668d07839SEric Blake visit_type_WrapAlternate(v, NULL, &wrap, &error_abort); 79768d07839SEric Blake g_assert_cmpint(wrap->alt->type, ==, QTYPE_QSTRING); 7988168ca8eSMarkus Armbruster g_assert_cmpint(wrap->alt->u.e, ==, ENUM_ONE_VALUE1); 79968d07839SEric Blake qapi_free_WrapAlternate(wrap); 80068d07839SEric Blake 80168d07839SEric Blake v = visitor_input_test_init(data, "{ 'alt': {'integer':1, 'string':'str', " 80268d07839SEric Blake "'enum1':'value1', 'boolean':true} }"); 80368d07839SEric Blake visit_type_WrapAlternate(v, NULL, &wrap, &error_abort); 80468d07839SEric Blake g_assert_cmpint(wrap->alt->type, ==, QTYPE_QDICT); 805becceedcSEric Blake g_assert_cmpint(wrap->alt->u.udfu.integer, ==, 1); 806becceedcSEric Blake g_assert_cmpstr(wrap->alt->u.udfu.string, ==, "str"); 807becceedcSEric Blake g_assert_cmpint(wrap->alt->u.udfu.enum1, ==, ENUM_ONE_VALUE1); 808544a3731SEric Blake g_assert_cmpint(wrap->alt->u.udfu.u.value1.boolean, ==, true); 809544a3731SEric Blake g_assert_cmpint(wrap->alt->u.udfu.u.value1.has_a_b, ==, false); 81068d07839SEric Blake qapi_free_WrapAlternate(wrap); 8119c51b441SEric Blake } 8129c51b441SEric Blake 8139c51b441SEric Blake static void test_visitor_in_alternate_number(TestInputVisitorData *data, 8149c51b441SEric Blake const void *unused) 8159c51b441SEric Blake { 8169c51b441SEric Blake Visitor *v; 8179c51b441SEric Blake Error *err = NULL; 8188168ca8eSMarkus Armbruster AltEnumBool *aeb; 8198168ca8eSMarkus Armbruster AltEnumNum *aen; 8208168ca8eSMarkus Armbruster AltNumEnum *ans; 8218168ca8eSMarkus Armbruster AltEnumInt *asi; 82279db9948SPaolo Bonzini AltListInt *ali; 8239c51b441SEric Blake 8249c51b441SEric Blake /* Parsing an int */ 8259c51b441SEric Blake 8269c51b441SEric Blake v = visitor_input_test_init(data, "42"); 8278168ca8eSMarkus Armbruster visit_type_AltEnumBool(v, NULL, &aeb, &err); 828a12a5a1aSEric Blake error_free_or_abort(&err); 8298168ca8eSMarkus Armbruster qapi_free_AltEnumBool(aeb); 8309c51b441SEric Blake 8319c51b441SEric Blake v = visitor_input_test_init(data, "42"); 8328168ca8eSMarkus Armbruster visit_type_AltEnumNum(v, NULL, &aen, &error_abort); 83301b2ffceSMarc-André Lureau g_assert_cmpint(aen->type, ==, QTYPE_QNUM); 8348168ca8eSMarkus Armbruster g_assert_cmpfloat(aen->u.n, ==, 42); 8358168ca8eSMarkus Armbruster qapi_free_AltEnumNum(aen); 8369c51b441SEric Blake 8379c51b441SEric Blake v = visitor_input_test_init(data, "42"); 8388168ca8eSMarkus Armbruster visit_type_AltNumEnum(v, NULL, &ans, &error_abort); 83901b2ffceSMarc-André Lureau g_assert_cmpint(ans->type, ==, QTYPE_QNUM); 840d00341afSEric Blake g_assert_cmpfloat(ans->u.n, ==, 42); 8418168ca8eSMarkus Armbruster qapi_free_AltNumEnum(ans); 8429c51b441SEric Blake 8439c51b441SEric Blake v = visitor_input_test_init(data, "42"); 8448168ca8eSMarkus Armbruster visit_type_AltEnumInt(v, NULL, &asi, &error_abort); 84501b2ffceSMarc-André Lureau g_assert_cmpint(asi->type, ==, QTYPE_QNUM); 846c363acefSEric Blake g_assert_cmpint(asi->u.i, ==, 42); 8478168ca8eSMarkus Armbruster qapi_free_AltEnumInt(asi); 8489c51b441SEric Blake 84979db9948SPaolo Bonzini v = visitor_input_test_init(data, "42"); 85079db9948SPaolo Bonzini visit_type_AltListInt(v, NULL, &ali, &error_abort); 85179db9948SPaolo Bonzini g_assert_cmpint(ali->type, ==, QTYPE_QNUM); 85279db9948SPaolo Bonzini g_assert_cmpint(ali->u.i, ==, 42); 85379db9948SPaolo Bonzini qapi_free_AltListInt(ali); 85479db9948SPaolo Bonzini 8559c51b441SEric Blake /* Parsing a double */ 8569c51b441SEric Blake 8579c51b441SEric Blake v = visitor_input_test_init(data, "42.5"); 8588168ca8eSMarkus Armbruster visit_type_AltEnumBool(v, NULL, &aeb, &err); 859a12a5a1aSEric Blake error_free_or_abort(&err); 8608168ca8eSMarkus Armbruster qapi_free_AltEnumBool(aeb); 8619c51b441SEric Blake 8629c51b441SEric Blake v = visitor_input_test_init(data, "42.5"); 8638168ca8eSMarkus Armbruster visit_type_AltEnumNum(v, NULL, &aen, &error_abort); 86401b2ffceSMarc-André Lureau g_assert_cmpint(aen->type, ==, QTYPE_QNUM); 8658168ca8eSMarkus Armbruster g_assert_cmpfloat(aen->u.n, ==, 42.5); 8668168ca8eSMarkus Armbruster qapi_free_AltEnumNum(aen); 8679c51b441SEric Blake 8689c51b441SEric Blake v = visitor_input_test_init(data, "42.5"); 8698168ca8eSMarkus Armbruster visit_type_AltNumEnum(v, NULL, &ans, &error_abort); 87001b2ffceSMarc-André Lureau g_assert_cmpint(ans->type, ==, QTYPE_QNUM); 871c363acefSEric Blake g_assert_cmpfloat(ans->u.n, ==, 42.5); 8728168ca8eSMarkus Armbruster qapi_free_AltNumEnum(ans); 8739c51b441SEric Blake 8749c51b441SEric Blake v = visitor_input_test_init(data, "42.5"); 8758168ca8eSMarkus Armbruster visit_type_AltEnumInt(v, NULL, &asi, &err); 876a12a5a1aSEric Blake error_free_or_abort(&err); 8778168ca8eSMarkus Armbruster qapi_free_AltEnumInt(asi); 8782c38b600SMarkus Armbruster } 8792c38b600SMarkus Armbruster 88079db9948SPaolo Bonzini static void test_visitor_in_alternate_list(TestInputVisitorData *data, 88179db9948SPaolo Bonzini const void *unused) 88279db9948SPaolo Bonzini { 88379db9948SPaolo Bonzini intList *item; 88479db9948SPaolo Bonzini Visitor *v; 88579db9948SPaolo Bonzini AltListInt *ali; 88679db9948SPaolo Bonzini int i; 88779db9948SPaolo Bonzini 88879db9948SPaolo Bonzini v = visitor_input_test_init(data, "[ 42, 43, 44 ]"); 88979db9948SPaolo Bonzini visit_type_AltListInt(v, NULL, &ali, &error_abort); 89079db9948SPaolo Bonzini g_assert(ali != NULL); 89179db9948SPaolo Bonzini 89279db9948SPaolo Bonzini g_assert_cmpint(ali->type, ==, QTYPE_QLIST); 89379db9948SPaolo Bonzini for (i = 0, item = ali->u.l; item; item = item->next, i++) { 89479db9948SPaolo Bonzini g_assert_cmpint(item->value, ==, 42 + i); 89579db9948SPaolo Bonzini } 89679db9948SPaolo Bonzini 89779db9948SPaolo Bonzini qapi_free_AltListInt(ali); 89879db9948SPaolo Bonzini ali = NULL; 89979db9948SPaolo Bonzini 90079db9948SPaolo Bonzini /* An empty list is valid */ 90179db9948SPaolo Bonzini v = visitor_input_test_init(data, "[]"); 90279db9948SPaolo Bonzini visit_type_AltListInt(v, NULL, &ali, &error_abort); 90379db9948SPaolo Bonzini g_assert(ali != NULL); 90479db9948SPaolo Bonzini 90579db9948SPaolo Bonzini g_assert_cmpint(ali->type, ==, QTYPE_QLIST); 90679db9948SPaolo Bonzini g_assert(!ali->u.l); 90779db9948SPaolo Bonzini qapi_free_AltListInt(ali); 90879db9948SPaolo Bonzini ali = NULL; 90979db9948SPaolo Bonzini } 91079db9948SPaolo Bonzini 911d88f5fd1SLuiz Capitulino static void input_visitor_test_add(const char *testpath, 912b1d2e5f1SDaniel P. Berrange const void *user_data, 913b1d2e5f1SDaniel P. Berrange void (*test_func)(TestInputVisitorData *data, 914b1d2e5f1SDaniel P. Berrange const void *user_data)) 915d88f5fd1SLuiz Capitulino { 916b1d2e5f1SDaniel P. Berrange g_test_add(testpath, TestInputVisitorData, user_data, NULL, test_func, 917d88f5fd1SLuiz Capitulino visitor_input_teardown); 918d88f5fd1SLuiz Capitulino } 919d88f5fd1SLuiz Capitulino 9203dcf71f6SPaolo Bonzini static void test_visitor_in_errors(TestInputVisitorData *data, 9213dcf71f6SPaolo Bonzini const void *unused) 9223dcf71f6SPaolo Bonzini { 9233dcf71f6SPaolo Bonzini TestStruct *p = NULL; 924e940f543SMarkus Armbruster Error *err = NULL; 9253dcf71f6SPaolo Bonzini Visitor *v; 926dd5ee2c2SEric Blake strList *q = NULL; 9279b4e38feSEric Blake UserDefTwo *r = NULL; 9289b4e38feSEric Blake WrapAlternate *s = NULL; 9293dcf71f6SPaolo Bonzini 930dd5ee2c2SEric Blake v = visitor_input_test_init(data, "{ 'integer': false, 'boolean': 'foo', " 931dd5ee2c2SEric Blake "'string': -42 }"); 9323dcf71f6SPaolo Bonzini 93351e72bc1SEric Blake visit_type_TestStruct(v, NULL, &p, &err); 934a12a5a1aSEric Blake error_free_or_abort(&err); 93568ab47e4SEric Blake g_assert(!p); 936dd5ee2c2SEric Blake 937dd5ee2c2SEric Blake v = visitor_input_test_init(data, "[ '1', '2', false, '3' ]"); 93851e72bc1SEric Blake visit_type_strList(v, NULL, &q, &err); 939dd5ee2c2SEric Blake error_free_or_abort(&err); 94068ab47e4SEric Blake assert(!q); 9419b4e38feSEric Blake 9429b4e38feSEric Blake v = visitor_input_test_init(data, "{ 'str':'hi' }"); 9439b4e38feSEric Blake visit_type_UserDefTwo(v, NULL, &r, &err); 9449b4e38feSEric Blake error_free_or_abort(&err); 9459b4e38feSEric Blake assert(!r); 9469b4e38feSEric Blake 9479b4e38feSEric Blake v = visitor_input_test_init(data, "{ }"); 9489b4e38feSEric Blake visit_type_WrapAlternate(v, NULL, &s, &err); 9499b4e38feSEric Blake error_free_or_abort(&err); 9509b4e38feSEric Blake assert(!s); 9513dcf71f6SPaolo Bonzini } 9523dcf71f6SPaolo Bonzini 9532533377cSEric Blake static void test_visitor_in_wrong_type(TestInputVisitorData *data, 9542533377cSEric Blake const void *unused) 9552533377cSEric Blake { 9562533377cSEric Blake TestStruct *p = NULL; 9572533377cSEric Blake Visitor *v; 9582533377cSEric Blake strList *q = NULL; 9592533377cSEric Blake int64_t i; 9602533377cSEric Blake Error *err = NULL; 9612533377cSEric Blake 9622533377cSEric Blake /* Make sure arrays and structs cannot be confused */ 9632533377cSEric Blake 9642533377cSEric Blake v = visitor_input_test_init(data, "[]"); 96551e72bc1SEric Blake visit_type_TestStruct(v, NULL, &p, &err); 9662533377cSEric Blake error_free_or_abort(&err); 9672533377cSEric Blake g_assert(!p); 9682533377cSEric Blake 9692533377cSEric Blake v = visitor_input_test_init(data, "{}"); 97051e72bc1SEric Blake visit_type_strList(v, NULL, &q, &err); 9712533377cSEric Blake error_free_or_abort(&err); 9722533377cSEric Blake assert(!q); 9732533377cSEric Blake 9742533377cSEric Blake /* Make sure primitives and struct cannot be confused */ 9752533377cSEric Blake 9762533377cSEric Blake v = visitor_input_test_init(data, "1"); 97751e72bc1SEric Blake visit_type_TestStruct(v, NULL, &p, &err); 9782533377cSEric Blake error_free_or_abort(&err); 9792533377cSEric Blake g_assert(!p); 9802533377cSEric Blake 9812533377cSEric Blake v = visitor_input_test_init(data, "{}"); 98251e72bc1SEric Blake visit_type_int(v, NULL, &i, &err); 9832533377cSEric Blake error_free_or_abort(&err); 9842533377cSEric Blake 9852533377cSEric Blake /* Make sure primitives and arrays cannot be confused */ 9862533377cSEric Blake 9872533377cSEric Blake v = visitor_input_test_init(data, "1"); 98851e72bc1SEric Blake visit_type_strList(v, NULL, &q, &err); 9892533377cSEric Blake error_free_or_abort(&err); 9902533377cSEric Blake assert(!q); 9912533377cSEric Blake 9922533377cSEric Blake v = visitor_input_test_init(data, "[]"); 99351e72bc1SEric Blake visit_type_int(v, NULL, &i, &err); 9942533377cSEric Blake error_free_or_abort(&err); 9952533377cSEric Blake } 9962533377cSEric Blake 99777c47de2SMarkus Armbruster static void test_visitor_in_fail_struct(TestInputVisitorData *data, 99877c47de2SMarkus Armbruster const void *unused) 99977c47de2SMarkus Armbruster { 100077c47de2SMarkus Armbruster TestStruct *p = NULL; 100177c47de2SMarkus Armbruster Error *err = NULL; 100277c47de2SMarkus Armbruster Visitor *v; 100377c47de2SMarkus Armbruster 100477c47de2SMarkus Armbruster v = visitor_input_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo', 'extra': 42 }"); 100577c47de2SMarkus Armbruster 100677c47de2SMarkus Armbruster visit_type_TestStruct(v, NULL, &p, &err); 100777c47de2SMarkus Armbruster error_free_or_abort(&err); 100877c47de2SMarkus Armbruster g_assert(!p); 100977c47de2SMarkus Armbruster } 101077c47de2SMarkus Armbruster 101177c47de2SMarkus Armbruster static void test_visitor_in_fail_struct_nested(TestInputVisitorData *data, 101277c47de2SMarkus Armbruster const void *unused) 101377c47de2SMarkus Armbruster { 101477c47de2SMarkus Armbruster UserDefTwo *udp = NULL; 101577c47de2SMarkus Armbruster Error *err = NULL; 101677c47de2SMarkus Armbruster Visitor *v; 101777c47de2SMarkus Armbruster 101877c47de2SMarkus 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'}}}"); 101977c47de2SMarkus Armbruster 102077c47de2SMarkus Armbruster visit_type_UserDefTwo(v, NULL, &udp, &err); 102177c47de2SMarkus Armbruster error_free_or_abort(&err); 102277c47de2SMarkus Armbruster g_assert(!udp); 102377c47de2SMarkus Armbruster } 102477c47de2SMarkus Armbruster 102577c47de2SMarkus Armbruster static void test_visitor_in_fail_struct_in_list(TestInputVisitorData *data, 102677c47de2SMarkus Armbruster const void *unused) 102777c47de2SMarkus Armbruster { 102877c47de2SMarkus Armbruster UserDefOneList *head = NULL; 102977c47de2SMarkus Armbruster Error *err = NULL; 103077c47de2SMarkus Armbruster Visitor *v; 103177c47de2SMarkus Armbruster 103277c47de2SMarkus Armbruster v = visitor_input_test_init(data, "[ { 'string': 'string0', 'integer': 42 }, { 'string': 'string1', 'integer': 43 }, { 'string': 'string2', 'integer': 44, 'extra': 'ggg' } ]"); 103377c47de2SMarkus Armbruster 103477c47de2SMarkus Armbruster visit_type_UserDefOneList(v, NULL, &head, &err); 103577c47de2SMarkus Armbruster error_free_or_abort(&err); 103677c47de2SMarkus Armbruster g_assert(!head); 103777c47de2SMarkus Armbruster } 103877c47de2SMarkus Armbruster 103977c47de2SMarkus Armbruster static void test_visitor_in_fail_struct_missing(TestInputVisitorData *data, 104077c47de2SMarkus Armbruster const void *unused) 104177c47de2SMarkus Armbruster { 104277c47de2SMarkus Armbruster Error *err = NULL; 104377c47de2SMarkus Armbruster Visitor *v; 104477c47de2SMarkus Armbruster QObject *any; 1045d2f95f4dSMarkus Armbruster QNull *null; 104677c47de2SMarkus Armbruster GenericAlternate *alt; 104777c47de2SMarkus Armbruster bool present; 104877c47de2SMarkus Armbruster int en; 104977c47de2SMarkus Armbruster int64_t i64; 105077c47de2SMarkus Armbruster uint32_t u32; 105177c47de2SMarkus Armbruster int8_t i8; 105277c47de2SMarkus Armbruster char *str; 105377c47de2SMarkus Armbruster double dbl; 105477c47de2SMarkus Armbruster 105586ca0dbeSMarkus Armbruster v = visitor_input_test_init(data, "{ 'sub': [ {} ] }"); 105677c47de2SMarkus Armbruster visit_start_struct(v, NULL, NULL, 0, &error_abort); 105777c47de2SMarkus Armbruster visit_start_struct(v, "struct", NULL, 0, &err); 105877c47de2SMarkus Armbruster error_free_or_abort(&err); 105977c47de2SMarkus Armbruster visit_start_list(v, "list", NULL, 0, &err); 106077c47de2SMarkus Armbruster error_free_or_abort(&err); 106160390d2dSMarc-André Lureau visit_start_alternate(v, "alternate", &alt, sizeof(*alt), &err); 106277c47de2SMarkus Armbruster error_free_or_abort(&err); 106377c47de2SMarkus Armbruster visit_optional(v, "optional", &present); 106477c47de2SMarkus Armbruster g_assert(!present); 1065f7abe0ecSMarc-André Lureau visit_type_enum(v, "enum", &en, &EnumOne_lookup, &err); 106677c47de2SMarkus Armbruster error_free_or_abort(&err); 106777c47de2SMarkus Armbruster visit_type_int(v, "i64", &i64, &err); 106877c47de2SMarkus Armbruster error_free_or_abort(&err); 106977c47de2SMarkus Armbruster visit_type_uint32(v, "u32", &u32, &err); 107077c47de2SMarkus Armbruster error_free_or_abort(&err); 107177c47de2SMarkus Armbruster visit_type_int8(v, "i8", &i8, &err); 107277c47de2SMarkus Armbruster error_free_or_abort(&err); 107377c47de2SMarkus Armbruster visit_type_str(v, "i8", &str, &err); 107477c47de2SMarkus Armbruster error_free_or_abort(&err); 107577c47de2SMarkus Armbruster visit_type_number(v, "dbl", &dbl, &err); 107677c47de2SMarkus Armbruster error_free_or_abort(&err); 107777c47de2SMarkus Armbruster visit_type_any(v, "any", &any, &err); 107877c47de2SMarkus Armbruster error_free_or_abort(&err); 1079d2f95f4dSMarkus Armbruster visit_type_null(v, "null", &null, &err); 108077c47de2SMarkus Armbruster error_free_or_abort(&err); 108186ca0dbeSMarkus Armbruster visit_start_list(v, "sub", NULL, 0, &error_abort); 108286ca0dbeSMarkus Armbruster visit_start_struct(v, NULL, NULL, 0, &error_abort); 108386ca0dbeSMarkus Armbruster visit_type_int(v, "i64", &i64, &err); 108486ca0dbeSMarkus Armbruster error_free_or_abort(&err); 108586ca0dbeSMarkus Armbruster visit_end_struct(v, NULL); 108686ca0dbeSMarkus Armbruster visit_end_list(v, NULL); 108777c47de2SMarkus Armbruster visit_end_struct(v, NULL); 108877c47de2SMarkus Armbruster } 108977c47de2SMarkus Armbruster 10909cb8ef36SMarkus Armbruster static void test_visitor_in_fail_list(TestInputVisitorData *data, 10919cb8ef36SMarkus Armbruster const void *unused) 10929cb8ef36SMarkus Armbruster { 10939cb8ef36SMarkus Armbruster int64_t i64 = -1; 1094a4a1c70dSMarkus Armbruster Error *err = NULL; 10959cb8ef36SMarkus Armbruster Visitor *v; 10969cb8ef36SMarkus Armbruster 10979cb8ef36SMarkus Armbruster /* Unvisited list tail */ 10989cb8ef36SMarkus Armbruster 10999cb8ef36SMarkus Armbruster v = visitor_input_test_init(data, "[ 1, 2, 3 ]"); 11009cb8ef36SMarkus Armbruster 11019cb8ef36SMarkus Armbruster visit_start_list(v, NULL, NULL, 0, &error_abort); 11029cb8ef36SMarkus Armbruster visit_type_int(v, NULL, &i64, &error_abort); 11039cb8ef36SMarkus Armbruster g_assert_cmpint(i64, ==, 1); 11049cb8ef36SMarkus Armbruster visit_type_int(v, NULL, &i64, &error_abort); 11059cb8ef36SMarkus Armbruster g_assert_cmpint(i64, ==, 2); 1106a4a1c70dSMarkus Armbruster visit_check_list(v, &err); 1107a4a1c70dSMarkus Armbruster error_free_or_abort(&err); 11089cb8ef36SMarkus Armbruster visit_end_list(v, NULL); 1109a9416dc6SMarkus Armbruster 1110a9416dc6SMarkus Armbruster /* Visit beyond end of list */ 1111a9416dc6SMarkus Armbruster v = visitor_input_test_init(data, "[]"); 1112a9416dc6SMarkus Armbruster 1113a9416dc6SMarkus Armbruster visit_start_list(v, NULL, NULL, 0, &error_abort); 1114a9416dc6SMarkus Armbruster visit_type_int(v, NULL, &i64, &err); 1115a9416dc6SMarkus Armbruster error_free_or_abort(&err); 1116a9416dc6SMarkus Armbruster visit_end_list(v, NULL); 11179cb8ef36SMarkus Armbruster } 11189cb8ef36SMarkus Armbruster 11199cb8ef36SMarkus Armbruster static void test_visitor_in_fail_list_nested(TestInputVisitorData *data, 11209cb8ef36SMarkus Armbruster const void *unused) 11219cb8ef36SMarkus Armbruster { 11229cb8ef36SMarkus Armbruster int64_t i64 = -1; 1123a4a1c70dSMarkus Armbruster Error *err = NULL; 11249cb8ef36SMarkus Armbruster Visitor *v; 11259cb8ef36SMarkus Armbruster 11269cb8ef36SMarkus Armbruster /* Unvisited nested list tail */ 11279cb8ef36SMarkus Armbruster 11289cb8ef36SMarkus Armbruster v = visitor_input_test_init(data, "[ 0, [ 1, 2, 3 ] ]"); 11299cb8ef36SMarkus Armbruster 11309cb8ef36SMarkus Armbruster visit_start_list(v, NULL, NULL, 0, &error_abort); 11319cb8ef36SMarkus Armbruster visit_type_int(v, NULL, &i64, &error_abort); 11329cb8ef36SMarkus Armbruster g_assert_cmpint(i64, ==, 0); 11339cb8ef36SMarkus Armbruster visit_start_list(v, NULL, NULL, 0, &error_abort); 11349cb8ef36SMarkus Armbruster visit_type_int(v, NULL, &i64, &error_abort); 11359cb8ef36SMarkus Armbruster g_assert_cmpint(i64, ==, 1); 1136a4a1c70dSMarkus Armbruster visit_check_list(v, &err); 1137a4a1c70dSMarkus Armbruster error_free_or_abort(&err); 11389cb8ef36SMarkus Armbruster visit_end_list(v, NULL); 1139a4a1c70dSMarkus Armbruster visit_check_list(v, &error_abort); 11409cb8ef36SMarkus Armbruster visit_end_list(v, NULL); 11419cb8ef36SMarkus Armbruster } 11429cb8ef36SMarkus Armbruster 114377c47de2SMarkus Armbruster static void test_visitor_in_fail_union_flat(TestInputVisitorData *data, 114477c47de2SMarkus Armbruster const void *unused) 114577c47de2SMarkus Armbruster { 114677c47de2SMarkus Armbruster UserDefFlatUnion *tmp = NULL; 114777c47de2SMarkus Armbruster Error *err = NULL; 114877c47de2SMarkus Armbruster Visitor *v; 114977c47de2SMarkus Armbruster 1150e7a76fe2SMarkus Armbruster v = visitor_input_test_init(data, "{ 'enum1': 'value2', 'string': 'c', 'integer': 41, 'boolean': true }"); 115177c47de2SMarkus Armbruster 115277c47de2SMarkus Armbruster visit_type_UserDefFlatUnion(v, NULL, &tmp, &err); 115377c47de2SMarkus Armbruster error_free_or_abort(&err); 115477c47de2SMarkus Armbruster g_assert(!tmp); 115577c47de2SMarkus Armbruster } 115677c47de2SMarkus Armbruster 115777c47de2SMarkus Armbruster static void test_visitor_in_fail_union_flat_no_discrim(TestInputVisitorData *data, 115877c47de2SMarkus Armbruster const void *unused) 115977c47de2SMarkus Armbruster { 116077c47de2SMarkus Armbruster UserDefFlatUnion2 *tmp = NULL; 116177c47de2SMarkus Armbruster Error *err = NULL; 116277c47de2SMarkus Armbruster Visitor *v; 116377c47de2SMarkus Armbruster 116477c47de2SMarkus Armbruster /* test situation where discriminator field ('enum1' here) is missing */ 116577c47de2SMarkus Armbruster v = visitor_input_test_init(data, "{ 'integer': 42, 'string': 'c', 'string1': 'd', 'string2': 'e' }"); 116677c47de2SMarkus Armbruster 116777c47de2SMarkus Armbruster visit_type_UserDefFlatUnion2(v, NULL, &tmp, &err); 116877c47de2SMarkus Armbruster error_free_or_abort(&err); 116977c47de2SMarkus Armbruster g_assert(!tmp); 117077c47de2SMarkus Armbruster } 117177c47de2SMarkus Armbruster 117277c47de2SMarkus Armbruster static void test_visitor_in_fail_alternate(TestInputVisitorData *data, 117377c47de2SMarkus Armbruster const void *unused) 117477c47de2SMarkus Armbruster { 117577c47de2SMarkus Armbruster UserDefAlternate *tmp; 117677c47de2SMarkus Armbruster Visitor *v; 117777c47de2SMarkus Armbruster Error *err = NULL; 117877c47de2SMarkus Armbruster 117977c47de2SMarkus Armbruster v = visitor_input_test_init(data, "3.14"); 118077c47de2SMarkus Armbruster 118177c47de2SMarkus Armbruster visit_type_UserDefAlternate(v, NULL, &tmp, &err); 118277c47de2SMarkus Armbruster error_free_or_abort(&err); 118377c47de2SMarkus Armbruster g_assert(!tmp); 118477c47de2SMarkus Armbruster } 118577c47de2SMarkus Armbruster 118677c47de2SMarkus Armbruster static void do_test_visitor_in_qmp_introspect(TestInputVisitorData *data, 11877d0f982bSMarc-André Lureau const QLitObject *qlit) 118877c47de2SMarkus Armbruster { 1189221db5daSDaniel P. Berrangé g_autoptr(SchemaInfoList) schema = NULL; 11907d0f982bSMarc-André Lureau QObject *obj = qobject_from_qlit(qlit); 119177c47de2SMarkus Armbruster Visitor *v; 119277c47de2SMarkus Armbruster 11937d0f982bSMarc-André Lureau v = qobject_input_visitor_new(obj); 119477c47de2SMarkus Armbruster 119577c47de2SMarkus Armbruster visit_type_SchemaInfoList(v, NULL, &schema, &error_abort); 119677c47de2SMarkus Armbruster g_assert(schema); 119777c47de2SMarkus Armbruster 1198cb3e7f08SMarc-André Lureau qobject_unref(obj); 11997d0f982bSMarc-André Lureau visit_free(v); 120077c47de2SMarkus Armbruster } 120177c47de2SMarkus Armbruster 120277c47de2SMarkus Armbruster static void test_visitor_in_qmp_introspect(TestInputVisitorData *data, 120377c47de2SMarkus Armbruster const void *unused) 120477c47de2SMarkus Armbruster { 12057d0f982bSMarc-André Lureau do_test_visitor_in_qmp_introspect(data, &test_qmp_schema_qlit); 120677c47de2SMarkus Armbruster } 120777c47de2SMarkus Armbruster 1208d88f5fd1SLuiz Capitulino int main(int argc, char **argv) 1209d88f5fd1SLuiz Capitulino { 1210d88f5fd1SLuiz Capitulino g_test_init(&argc, &argv, NULL); 1211d88f5fd1SLuiz Capitulino 1212d88f5fd1SLuiz Capitulino input_visitor_test_add("/visitor/input/int", 1213b1d2e5f1SDaniel P. Berrange NULL, test_visitor_in_int); 12144bc0c94dSMarkus Armbruster input_visitor_test_add("/visitor/input/uint", 12154bc0c94dSMarkus Armbruster NULL, test_visitor_in_uint); 1216e92cfa0dSMichael Roth input_visitor_test_add("/visitor/input/int_overflow", 1217b1d2e5f1SDaniel P. Berrange NULL, test_visitor_in_int_overflow); 1218cbd8acf3SDaniel P. Berrange input_visitor_test_add("/visitor/input/int_keyval", 1219cbd8acf3SDaniel P. Berrange NULL, test_visitor_in_int_keyval); 1220cbd8acf3SDaniel P. Berrange input_visitor_test_add("/visitor/input/int_str_keyval", 1221cbd8acf3SDaniel P. Berrange NULL, test_visitor_in_int_str_keyval); 1222cbd8acf3SDaniel P. Berrange input_visitor_test_add("/visitor/input/int_str_fail", 1223cbd8acf3SDaniel P. Berrange NULL, test_visitor_in_int_str_fail); 1224d88f5fd1SLuiz Capitulino input_visitor_test_add("/visitor/input/bool", 1225b1d2e5f1SDaniel P. Berrange NULL, test_visitor_in_bool); 1226cbd8acf3SDaniel P. Berrange input_visitor_test_add("/visitor/input/bool_keyval", 1227cbd8acf3SDaniel P. Berrange NULL, test_visitor_in_bool_keyval); 1228cbd8acf3SDaniel P. Berrange input_visitor_test_add("/visitor/input/bool_str_keyval", 1229cbd8acf3SDaniel P. Berrange NULL, test_visitor_in_bool_str_keyval); 1230cbd8acf3SDaniel P. Berrange input_visitor_test_add("/visitor/input/bool_str_fail", 1231cbd8acf3SDaniel P. Berrange NULL, test_visitor_in_bool_str_fail); 1232d88f5fd1SLuiz Capitulino input_visitor_test_add("/visitor/input/number", 1233b1d2e5f1SDaniel P. Berrange NULL, test_visitor_in_number); 1234c1214ad3SMarc-André Lureau input_visitor_test_add("/visitor/input/large_number", 1235c1214ad3SMarc-André Lureau NULL, test_visitor_in_large_number); 1236cbd8acf3SDaniel P. Berrange input_visitor_test_add("/visitor/input/number_keyval", 1237cbd8acf3SDaniel P. Berrange NULL, test_visitor_in_number_keyval); 1238cbd8acf3SDaniel P. Berrange input_visitor_test_add("/visitor/input/number_str_keyval", 1239cbd8acf3SDaniel P. Berrange NULL, test_visitor_in_number_str_keyval); 1240cbd8acf3SDaniel P. Berrange input_visitor_test_add("/visitor/input/number_str_fail", 1241cbd8acf3SDaniel P. Berrange NULL, test_visitor_in_number_str_fail); 1242cbd8acf3SDaniel P. Berrange input_visitor_test_add("/visitor/input/size_str_keyval", 1243cbd8acf3SDaniel P. Berrange NULL, test_visitor_in_size_str_keyval); 1244cbd8acf3SDaniel P. Berrange input_visitor_test_add("/visitor/input/size_str_fail", 1245cbd8acf3SDaniel P. Berrange NULL, test_visitor_in_size_str_fail); 1246d88f5fd1SLuiz Capitulino input_visitor_test_add("/visitor/input/string", 1247b1d2e5f1SDaniel P. Berrange NULL, test_visitor_in_string); 1248d88f5fd1SLuiz Capitulino input_visitor_test_add("/visitor/input/enum", 1249b1d2e5f1SDaniel P. Berrange NULL, test_visitor_in_enum); 1250d88f5fd1SLuiz Capitulino input_visitor_test_add("/visitor/input/struct", 1251b1d2e5f1SDaniel P. Berrange NULL, test_visitor_in_struct); 1252d88f5fd1SLuiz Capitulino input_visitor_test_add("/visitor/input/struct-nested", 1253b1d2e5f1SDaniel P. Berrange NULL, test_visitor_in_struct_nested); 1254e7a76fe2SMarkus Armbruster input_visitor_test_add("/visitor/input/list2", 1255e7a76fe2SMarkus Armbruster NULL, test_visitor_in_list_struct); 1256d88f5fd1SLuiz Capitulino input_visitor_test_add("/visitor/input/list", 1257b1d2e5f1SDaniel P. Berrange NULL, test_visitor_in_list); 125828770e05SMarkus Armbruster input_visitor_test_add("/visitor/input/any", 1259b1d2e5f1SDaniel P. Berrange NULL, test_visitor_in_any); 12603df016f1SEric Blake input_visitor_test_add("/visitor/input/null", 1261b1d2e5f1SDaniel P. Berrange NULL, test_visitor_in_null); 12622fc00432SMarkus Armbruster input_visitor_test_add("/visitor/input/union-flat", 1263b1d2e5f1SDaniel P. Berrange NULL, test_visitor_in_union_flat); 1264a17dbc4bSDaniel P. Berrangé input_visitor_test_add("/visitor/input/union-in-union", 1265a17dbc4bSDaniel P. Berrangé NULL, test_visitor_in_union_in_union); 1266ab045267SEric Blake input_visitor_test_add("/visitor/input/alternate", 1267b1d2e5f1SDaniel P. Berrange NULL, test_visitor_in_alternate); 12683dcf71f6SPaolo Bonzini input_visitor_test_add("/visitor/input/errors", 1269b1d2e5f1SDaniel P. Berrange NULL, test_visitor_in_errors); 12702533377cSEric Blake input_visitor_test_add("/visitor/input/wrong-type", 1271b1d2e5f1SDaniel P. Berrange NULL, test_visitor_in_wrong_type); 12729c51b441SEric Blake input_visitor_test_add("/visitor/input/alternate-number", 1273b1d2e5f1SDaniel P. Berrange NULL, test_visitor_in_alternate_number); 127479db9948SPaolo Bonzini input_visitor_test_add("/visitor/input/alternate-list", 127579db9948SPaolo Bonzini NULL, test_visitor_in_alternate_list); 127677c47de2SMarkus Armbruster input_visitor_test_add("/visitor/input/fail/struct", 127777c47de2SMarkus Armbruster NULL, test_visitor_in_fail_struct); 127877c47de2SMarkus Armbruster input_visitor_test_add("/visitor/input/fail/struct-nested", 127977c47de2SMarkus Armbruster NULL, test_visitor_in_fail_struct_nested); 128077c47de2SMarkus Armbruster input_visitor_test_add("/visitor/input/fail/struct-in-list", 128177c47de2SMarkus Armbruster NULL, test_visitor_in_fail_struct_in_list); 128277c47de2SMarkus Armbruster input_visitor_test_add("/visitor/input/fail/struct-missing", 128377c47de2SMarkus Armbruster NULL, test_visitor_in_fail_struct_missing); 12849cb8ef36SMarkus Armbruster input_visitor_test_add("/visitor/input/fail/list", 12859cb8ef36SMarkus Armbruster NULL, test_visitor_in_fail_list); 12869cb8ef36SMarkus Armbruster input_visitor_test_add("/visitor/input/fail/list-nested", 12879cb8ef36SMarkus Armbruster NULL, test_visitor_in_fail_list_nested); 128877c47de2SMarkus Armbruster input_visitor_test_add("/visitor/input/fail/union-flat", 128977c47de2SMarkus Armbruster NULL, test_visitor_in_fail_union_flat); 129077c47de2SMarkus Armbruster input_visitor_test_add("/visitor/input/fail/union-flat-no-discriminator", 129177c47de2SMarkus Armbruster NULL, test_visitor_in_fail_union_flat_no_discrim); 129277c47de2SMarkus Armbruster input_visitor_test_add("/visitor/input/fail/alternate", 129377c47de2SMarkus Armbruster NULL, test_visitor_in_fail_alternate); 1294eb815e24SMarkus Armbruster input_visitor_test_add("/visitor/input/qapi-introspect", 129577c47de2SMarkus Armbruster NULL, test_visitor_in_qmp_introspect); 1296d88f5fd1SLuiz Capitulino 1297d88f5fd1SLuiz Capitulino g_test_run(); 1298d88f5fd1SLuiz Capitulino 1299d88f5fd1SLuiz Capitulino return 0; 1300d88f5fd1SLuiz Capitulino } 1301