qemu/tests/unit/test-qobject-input-visitor.c
<<
>>
Prefs
   1/*
   2 * QObject Input Visitor unit-tests.
   3 *
   4 * Copyright (C) 2011-2016 Red Hat Inc.
   5 *
   6 * Authors:
   7 *  Luiz Capitulino <lcapitulino@redhat.com>
   8 *  Paolo Bonzini <pbonzini@redhat.com>
   9 *
  10 * This work is licensed under the terms of the GNU GPL, version 2 or later.
  11 * See the COPYING file in the top-level directory.
  12 */
  13
  14#include "qemu/osdep.h"
  15
  16#include "qemu-common.h"
  17#include "qapi/error.h"
  18#include "qapi/qapi-visit-introspect.h"
  19#include "qapi/qobject-input-visitor.h"
  20#include "test-qapi-visit.h"
  21#include "qapi/qmp/qbool.h"
  22#include "qapi/qmp/qdict.h"
  23#include "qapi/qmp/qnull.h"
  24#include "qapi/qmp/qnum.h"
  25#include "qapi/qmp/qstring.h"
  26#include "qapi/qmp/qjson.h"
  27#include "test-qapi-introspect.h"
  28#include "qapi/qapi-introspect.h"
  29
  30typedef struct TestInputVisitorData {
  31    QObject *obj;
  32    Visitor *qiv;
  33} TestInputVisitorData;
  34
  35static void visitor_input_teardown(TestInputVisitorData *data,
  36                                   const void *unused)
  37{
  38    qobject_unref(data->obj);
  39    data->obj = NULL;
  40
  41    if (data->qiv) {
  42        visit_free(data->qiv);
  43        data->qiv = NULL;
  44    }
  45}
  46
  47/* The various test_init functions are provided instead of a test setup
  48   function so that the JSON string used by the tests are kept in the test
  49   functions (and not in main()). */
  50
  51static Visitor *test_init_internal(TestInputVisitorData *data, bool keyval,
  52                                   QObject *obj)
  53{
  54    visitor_input_teardown(data, NULL);
  55
  56    data->obj = obj;
  57
  58    if (keyval) {
  59        data->qiv = qobject_input_visitor_new_keyval(data->obj);
  60    } else {
  61        data->qiv = qobject_input_visitor_new(data->obj);
  62    }
  63    g_assert(data->qiv);
  64    return data->qiv;
  65}
  66
  67static GCC_FMT_ATTR(3, 4)
  68Visitor *visitor_input_test_init_full(TestInputVisitorData *data,
  69                                      bool keyval,
  70                                      const char *json_string, ...)
  71{
  72    Visitor *v;
  73    va_list ap;
  74
  75    va_start(ap, json_string);
  76    v = test_init_internal(data, keyval,
  77                           qobject_from_vjsonf_nofail(json_string, ap));
  78    va_end(ap);
  79    return v;
  80}
  81
  82static GCC_FMT_ATTR(2, 3)
  83Visitor *visitor_input_test_init(TestInputVisitorData *data,
  84                                 const char *json_string, ...)
  85{
  86    Visitor *v;
  87    va_list ap;
  88
  89    va_start(ap, json_string);
  90    v = test_init_internal(data, false,
  91                           qobject_from_vjsonf_nofail(json_string, ap));
  92    va_end(ap);
  93    return v;
  94}
  95
  96/* similar to visitor_input_test_init(), but does not expect a string
  97 * literal/format json_string argument and so can be used for
  98 * programatically generated strings (and we can't pass in programatically
  99 * generated strings via %s format parameters since qobject_from_jsonv()
 100 * will wrap those in double-quotes and treat the entire object as a
 101 * string)
 102 */
 103static Visitor *visitor_input_test_init_raw(TestInputVisitorData *data,
 104                                            const char *json_string)
 105{
 106    return test_init_internal(data, false,
 107                              qobject_from_json(json_string, &error_abort));
 108}
 109
 110static void test_visitor_in_int(TestInputVisitorData *data,
 111                                const void *unused)
 112{
 113    int64_t res = 0;
 114    double dbl;
 115    int value = -42;
 116    Visitor *v;
 117
 118    v = visitor_input_test_init(data, "%d", value);
 119
 120    visit_type_int(v, NULL, &res, &error_abort);
 121    g_assert_cmpint(res, ==, value);
 122
 123    visit_type_number(v, NULL, &dbl, &error_abort);
 124    g_assert_cmpfloat(dbl, ==, -42.0);
 125}
 126
 127static void test_visitor_in_uint(TestInputVisitorData *data,
 128                                const void *unused)
 129{
 130    uint64_t res = 0;
 131    int64_t i64;
 132    double dbl;
 133    int value = 42;
 134    Visitor *v;
 135
 136    v = visitor_input_test_init(data, "%d", value);
 137
 138    visit_type_uint64(v, NULL, &res, &error_abort);
 139    g_assert_cmpuint(res, ==, (uint64_t)value);
 140
 141    visit_type_int(v, NULL, &i64, &error_abort);
 142    g_assert_cmpint(i64, ==, value);
 143
 144    visit_type_number(v, NULL, &dbl, &error_abort);
 145    g_assert_cmpfloat(dbl, ==, value);
 146
 147    /* BUG: value between INT64_MIN and -1 accepted modulo 2^64 */
 148    v = visitor_input_test_init(data, "%d", -value);
 149
 150    visit_type_uint64(v, NULL, &res, &error_abort);
 151    g_assert_cmpuint(res, ==, (uint64_t)-value);
 152
 153    v = visitor_input_test_init(data, "18446744073709551574");
 154
 155    visit_type_uint64(v, NULL, &res, &error_abort);
 156    g_assert_cmpuint(res, ==, 18446744073709551574U);
 157
 158    visit_type_number(v, NULL, &dbl, &error_abort);
 159    g_assert_cmpfloat(dbl, ==, 18446744073709552000.0);
 160}
 161
 162static void test_visitor_in_int_overflow(TestInputVisitorData *data,
 163                                         const void *unused)
 164{
 165    int64_t res = 0;
 166    Error *err = NULL;
 167    Visitor *v;
 168
 169    /*
 170     * This will overflow a QNUM_I64, so should be deserialized into a
 171     * QNUM_DOUBLE field instead, leading to an error if we pass it to
 172     * visit_type_int().  Confirm this.
 173     */
 174    v = visitor_input_test_init(data, "%f", DBL_MAX);
 175
 176    visit_type_int(v, NULL, &res, &err);
 177    error_free_or_abort(&err);
 178}
 179
 180static void test_visitor_in_int_keyval(TestInputVisitorData *data,
 181                                       const void *unused)
 182{
 183    int64_t res = 0, value = -42;
 184    Error *err = NULL;
 185    Visitor *v;
 186
 187    v = visitor_input_test_init_full(data, true, "%" PRId64, value);
 188    visit_type_int(v, NULL, &res, &err);
 189    error_free_or_abort(&err);
 190}
 191
 192static void test_visitor_in_int_str_keyval(TestInputVisitorData *data,
 193                                           const void *unused)
 194{
 195    int64_t res = 0, value = -42;
 196    Visitor *v;
 197
 198    v = visitor_input_test_init_full(data, true, "\"-42\"");
 199
 200    visit_type_int(v, NULL, &res, &error_abort);
 201    g_assert_cmpint(res, ==, value);
 202}
 203
 204static void test_visitor_in_int_str_fail(TestInputVisitorData *data,
 205                                         const void *unused)
 206{
 207    int64_t res = 0;
 208    Visitor *v;
 209    Error *err = NULL;
 210
 211    v = visitor_input_test_init(data, "\"-42\"");
 212
 213    visit_type_int(v, NULL, &res, &err);
 214    error_free_or_abort(&err);
 215}
 216
 217static void test_visitor_in_bool(TestInputVisitorData *data,
 218                                 const void *unused)
 219{
 220    bool res = false;
 221    Visitor *v;
 222
 223    v = visitor_input_test_init(data, "true");
 224
 225    visit_type_bool(v, NULL, &res, &error_abort);
 226    g_assert_cmpint(res, ==, true);
 227}
 228
 229static void test_visitor_in_bool_keyval(TestInputVisitorData *data,
 230                                        const void *unused)
 231{
 232    bool res = false;
 233    Error *err = NULL;
 234    Visitor *v;
 235
 236    v = visitor_input_test_init_full(data, true, "true");
 237
 238    visit_type_bool(v, NULL, &res, &err);
 239    error_free_or_abort(&err);
 240}
 241
 242static void test_visitor_in_bool_str_keyval(TestInputVisitorData *data,
 243                                            const void *unused)
 244{
 245    bool res = false;
 246    Visitor *v;
 247
 248    v = visitor_input_test_init_full(data, true, "\"on\"");
 249
 250    visit_type_bool(v, NULL, &res, &error_abort);
 251    g_assert_cmpint(res, ==, true);
 252}
 253
 254static void test_visitor_in_bool_str_fail(TestInputVisitorData *data,
 255                                          const void *unused)
 256{
 257    bool res = false;
 258    Visitor *v;
 259    Error *err = NULL;
 260
 261    v = visitor_input_test_init(data, "\"true\"");
 262
 263    visit_type_bool(v, NULL, &res, &err);
 264    error_free_or_abort(&err);
 265}
 266
 267static void test_visitor_in_number(TestInputVisitorData *data,
 268                                   const void *unused)
 269{
 270    double res = 0, value = 3.14;
 271    Visitor *v;
 272
 273    v = visitor_input_test_init(data, "%f", value);
 274
 275    visit_type_number(v, NULL, &res, &error_abort);
 276    g_assert_cmpfloat(res, ==, value);
 277}
 278
 279static void test_visitor_in_large_number(TestInputVisitorData *data,
 280                                         const void *unused)
 281{
 282    Error *err = NULL;
 283    double res = 0;
 284    int64_t i64;
 285    uint64_t u64;
 286    Visitor *v;
 287
 288    v = visitor_input_test_init(data, "-18446744073709551616"); /* -2^64 */
 289
 290    visit_type_number(v, NULL, &res, &error_abort);
 291    g_assert_cmpfloat(res, ==, -18446744073709552e3);
 292
 293    visit_type_int(v, NULL, &i64, &err);
 294    error_free_or_abort(&err);
 295
 296    visit_type_uint64(v, NULL, &u64, &err);
 297    error_free_or_abort(&err);
 298}
 299
 300static void test_visitor_in_number_keyval(TestInputVisitorData *data,
 301                                          const void *unused)
 302{
 303    double res = 0, value = 3.14;
 304    Error *err = NULL;
 305    Visitor *v;
 306
 307    v = visitor_input_test_init_full(data, true, "%f", value);
 308
 309    visit_type_number(v, NULL, &res, &err);
 310    error_free_or_abort(&err);
 311}
 312
 313static void test_visitor_in_number_str_keyval(TestInputVisitorData *data,
 314                                              const void *unused)
 315{
 316    double res = 0, value = 3.14;
 317    Visitor *v;
 318    Error *err = NULL;
 319
 320    v = visitor_input_test_init_full(data, true, "\"3.14\"");
 321
 322    visit_type_number(v, NULL, &res, &error_abort);
 323    g_assert_cmpfloat(res, ==, value);
 324
 325    v = visitor_input_test_init_full(data, true, "\"inf\"");
 326
 327    visit_type_number(v, NULL, &res, &err);
 328    error_free_or_abort(&err);
 329}
 330
 331static void test_visitor_in_number_str_fail(TestInputVisitorData *data,
 332                                            const void *unused)
 333{
 334    double res = 0;
 335    Visitor *v;
 336    Error *err = NULL;
 337
 338    v = visitor_input_test_init(data, "\"3.14\"");
 339
 340    visit_type_number(v, NULL, &res, &err);
 341    error_free_or_abort(&err);
 342}
 343
 344static void test_visitor_in_size_str_keyval(TestInputVisitorData *data,
 345                                            const void *unused)
 346{
 347    uint64_t res, value = 500 * 1024 * 1024;
 348    Visitor *v;
 349
 350    v = visitor_input_test_init_full(data, true, "\"500M\"");
 351
 352    visit_type_size(v, NULL, &res, &error_abort);
 353    g_assert_cmpfloat(res, ==, value);
 354}
 355
 356static void test_visitor_in_size_str_fail(TestInputVisitorData *data,
 357                                          const void *unused)
 358{
 359    uint64_t res = 0;
 360    Visitor *v;
 361    Error *err = NULL;
 362
 363    v = visitor_input_test_init(data, "\"500M\"");
 364
 365    visit_type_size(v, NULL, &res, &err);
 366    error_free_or_abort(&err);
 367}
 368
 369static void test_visitor_in_string(TestInputVisitorData *data,
 370                                   const void *unused)
 371{
 372    char *res = NULL, *value = (char *) "Q E M U";
 373    Visitor *v;
 374
 375    v = visitor_input_test_init(data, "%s", value);
 376
 377    visit_type_str(v, NULL, &res, &error_abort);
 378    g_assert_cmpstr(res, ==, value);
 379
 380    g_free(res);
 381}
 382
 383static void test_visitor_in_enum(TestInputVisitorData *data,
 384                                 const void *unused)
 385{
 386    Visitor *v;
 387    EnumOne i;
 388
 389    for (i = 0; i < ENUM_ONE__MAX; i++) {
 390        EnumOne res = -1;
 391
 392        v = visitor_input_test_init(data, "%s", EnumOne_str(i));
 393
 394        visit_type_EnumOne(v, NULL, &res, &error_abort);
 395        g_assert_cmpint(i, ==, res);
 396    }
 397}
 398
 399
 400static void test_visitor_in_struct(TestInputVisitorData *data,
 401                                   const void *unused)
 402{
 403    TestStruct *p = NULL;
 404    Visitor *v;
 405
 406    v = visitor_input_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo' }");
 407
 408    visit_type_TestStruct(v, NULL, &p, &error_abort);
 409    g_assert_cmpint(p->integer, ==, -42);
 410    g_assert(p->boolean == true);
 411    g_assert_cmpstr(p->string, ==, "foo");
 412
 413    g_free(p->string);
 414    g_free(p);
 415}
 416
 417static void test_visitor_in_struct_nested(TestInputVisitorData *data,
 418                                          const void *unused)
 419{
 420    g_autoptr(UserDefTwo) udp = NULL;
 421    Visitor *v;
 422
 423    v = visitor_input_test_init(data, "{ 'string0': 'string0', "
 424                                "'dict1': { 'string1': 'string1', "
 425                                "'dict2': { 'userdef': { 'integer': 42, "
 426                                "'string': 'string' }, 'string': 'string2'}}}");
 427
 428    visit_type_UserDefTwo(v, NULL, &udp, &error_abort);
 429
 430    g_assert_cmpstr(udp->string0, ==, "string0");
 431    g_assert_cmpstr(udp->dict1->string1, ==, "string1");
 432    g_assert_cmpint(udp->dict1->dict2->userdef->integer, ==, 42);
 433    g_assert_cmpstr(udp->dict1->dict2->userdef->string, ==, "string");
 434    g_assert_cmpstr(udp->dict1->dict2->string, ==, "string2");
 435    g_assert(udp->dict1->has_dict3 == false);
 436}
 437
 438static void test_visitor_in_list(TestInputVisitorData *data,
 439                                 const void *unused)
 440{
 441    UserDefOneList *item, *head = NULL;
 442    Visitor *v;
 443    int i;
 444
 445    v = visitor_input_test_init(data, "[ { 'string': 'string0', 'integer': 42 }, { 'string': 'string1', 'integer': 43 }, { 'string': 'string2', 'integer': 44 } ]");
 446
 447    visit_type_UserDefOneList(v, NULL, &head, &error_abort);
 448    g_assert(head != NULL);
 449
 450    for (i = 0, item = head; item; item = item->next, i++) {
 451        char string[12];
 452
 453        snprintf(string, sizeof(string), "string%d", i);
 454        g_assert_cmpstr(item->value->string, ==, string);
 455        g_assert_cmpint(item->value->integer, ==, 42 + i);
 456    }
 457
 458    qapi_free_UserDefOneList(head);
 459    head = NULL;
 460
 461    /* An empty list is valid */
 462    v = visitor_input_test_init(data, "[]");
 463    visit_type_UserDefOneList(v, NULL, &head, &error_abort);
 464    g_assert(!head);
 465}
 466
 467static void test_visitor_in_any(TestInputVisitorData *data,
 468                                const void *unused)
 469{
 470    QObject *res = NULL;
 471    Visitor *v;
 472    QNum *qnum;
 473    QBool *qbool;
 474    QString *qstring;
 475    QDict *qdict;
 476    QObject *qobj;
 477    int64_t val;
 478
 479    v = visitor_input_test_init(data, "-42");
 480    visit_type_any(v, NULL, &res, &error_abort);
 481    qnum = qobject_to(QNum, res);
 482    g_assert(qnum);
 483    g_assert(qnum_get_try_int(qnum, &val));
 484    g_assert_cmpint(val, ==, -42);
 485    qobject_unref(res);
 486
 487    v = visitor_input_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo' }");
 488    visit_type_any(v, NULL, &res, &error_abort);
 489    qdict = qobject_to(QDict, res);
 490    g_assert(qdict && qdict_size(qdict) == 3);
 491    qobj = qdict_get(qdict, "integer");
 492    g_assert(qobj);
 493    qnum = qobject_to(QNum, qobj);
 494    g_assert(qnum);
 495    g_assert(qnum_get_try_int(qnum, &val));
 496    g_assert_cmpint(val, ==, -42);
 497    qobj = qdict_get(qdict, "boolean");
 498    g_assert(qobj);
 499    qbool = qobject_to(QBool, qobj);
 500    g_assert(qbool);
 501    g_assert(qbool_get_bool(qbool) == true);
 502    qobj = qdict_get(qdict, "string");
 503    g_assert(qobj);
 504    qstring = qobject_to(QString, qobj);
 505    g_assert(qstring);
 506    g_assert_cmpstr(qstring_get_str(qstring), ==, "foo");
 507    qobject_unref(res);
 508}
 509
 510static void test_visitor_in_null(TestInputVisitorData *data,
 511                                 const void *unused)
 512{
 513    Visitor *v;
 514    Error *err = NULL;
 515    QNull *null;
 516    char *tmp;
 517
 518    /*
 519     * FIXME: Since QAPI doesn't know the 'null' type yet, we can't
 520     * test visit_type_null() by reading into a QAPI struct then
 521     * checking that it was populated correctly.  The best we can do
 522     * for now is ensure that we consumed null from the input, proven
 523     * by the fact that we can't re-read the key; and that we detect
 524     * when input is not null.
 525     */
 526
 527    v = visitor_input_test_init_full(data, false,
 528                                     "{ 'a': null, 'b': '' }");
 529    visit_start_struct(v, NULL, NULL, 0, &error_abort);
 530    visit_type_null(v, "a", &null, &error_abort);
 531    g_assert(qobject_type(QOBJECT(null)) == QTYPE_QNULL);
 532    qobject_unref(null);
 533    visit_type_null(v, "b", &null, &err);
 534    error_free_or_abort(&err);
 535    g_assert(!null);
 536    visit_type_str(v, "c", &tmp, &err);
 537    error_free_or_abort(&err);
 538    g_assert(!tmp);
 539    visit_check_struct(v, &error_abort);
 540    visit_end_struct(v, NULL);
 541}
 542
 543static void test_visitor_in_union_flat(TestInputVisitorData *data,
 544                                       const void *unused)
 545{
 546    Visitor *v;
 547    g_autoptr(UserDefFlatUnion) tmp = NULL;
 548    UserDefUnionBase *base;
 549
 550    v = visitor_input_test_init(data,
 551                                "{ 'enum1': 'value1', "
 552                                "'integer': 41, "
 553                                "'string': 'str', "
 554                                "'boolean': true }");
 555
 556    visit_type_UserDefFlatUnion(v, NULL, &tmp, &error_abort);
 557    g_assert_cmpint(tmp->enum1, ==, ENUM_ONE_VALUE1);
 558    g_assert_cmpstr(tmp->string, ==, "str");
 559    g_assert_cmpint(tmp->integer, ==, 41);
 560    g_assert_cmpint(tmp->u.value1.boolean, ==, true);
 561
 562    base = qapi_UserDefFlatUnion_base(tmp);
 563    g_assert(&base->enum1 == &tmp->enum1);
 564}
 565
 566static void test_visitor_in_alternate(TestInputVisitorData *data,
 567                                      const void *unused)
 568{
 569    Visitor *v;
 570    UserDefAlternate *tmp;
 571    WrapAlternate *wrap;
 572
 573    v = visitor_input_test_init(data, "42");
 574    visit_type_UserDefAlternate(v, NULL, &tmp, &error_abort);
 575    g_assert_cmpint(tmp->type, ==, QTYPE_QNUM);
 576    g_assert_cmpint(tmp->u.i, ==, 42);
 577    qapi_free_UserDefAlternate(tmp);
 578
 579    v = visitor_input_test_init(data, "'value1'");
 580    visit_type_UserDefAlternate(v, NULL, &tmp, &error_abort);
 581    g_assert_cmpint(tmp->type, ==, QTYPE_QSTRING);
 582    g_assert_cmpint(tmp->u.e, ==, ENUM_ONE_VALUE1);
 583    qapi_free_UserDefAlternate(tmp);
 584
 585    v = visitor_input_test_init(data, "null");
 586    visit_type_UserDefAlternate(v, NULL, &tmp, &error_abort);
 587    g_assert_cmpint(tmp->type, ==, QTYPE_QNULL);
 588    qapi_free_UserDefAlternate(tmp);
 589
 590    v = visitor_input_test_init(data, "{'integer':1, 'string':'str', "
 591                                "'enum1':'value1', 'boolean':true}");
 592    visit_type_UserDefAlternate(v, NULL, &tmp, &error_abort);
 593    g_assert_cmpint(tmp->type, ==, QTYPE_QDICT);
 594    g_assert_cmpint(tmp->u.udfu.integer, ==, 1);
 595    g_assert_cmpstr(tmp->u.udfu.string, ==, "str");
 596    g_assert_cmpint(tmp->u.udfu.enum1, ==, ENUM_ONE_VALUE1);
 597    g_assert_cmpint(tmp->u.udfu.u.value1.boolean, ==, true);
 598    g_assert_cmpint(tmp->u.udfu.u.value1.has_a_b, ==, false);
 599    qapi_free_UserDefAlternate(tmp);
 600
 601    v = visitor_input_test_init(data, "{ 'alt': 42 }");
 602    visit_type_WrapAlternate(v, NULL, &wrap, &error_abort);
 603    g_assert_cmpint(wrap->alt->type, ==, QTYPE_QNUM);
 604    g_assert_cmpint(wrap->alt->u.i, ==, 42);
 605    qapi_free_WrapAlternate(wrap);
 606
 607    v = visitor_input_test_init(data, "{ 'alt': 'value1' }");
 608    visit_type_WrapAlternate(v, NULL, &wrap, &error_abort);
 609    g_assert_cmpint(wrap->alt->type, ==, QTYPE_QSTRING);
 610    g_assert_cmpint(wrap->alt->u.e, ==, ENUM_ONE_VALUE1);
 611    qapi_free_WrapAlternate(wrap);
 612
 613    v = visitor_input_test_init(data, "{ 'alt': {'integer':1, 'string':'str', "
 614                                "'enum1':'value1', 'boolean':true} }");
 615    visit_type_WrapAlternate(v, NULL, &wrap, &error_abort);
 616    g_assert_cmpint(wrap->alt->type, ==, QTYPE_QDICT);
 617    g_assert_cmpint(wrap->alt->u.udfu.integer, ==, 1);
 618    g_assert_cmpstr(wrap->alt->u.udfu.string, ==, "str");
 619    g_assert_cmpint(wrap->alt->u.udfu.enum1, ==, ENUM_ONE_VALUE1);
 620    g_assert_cmpint(wrap->alt->u.udfu.u.value1.boolean, ==, true);
 621    g_assert_cmpint(wrap->alt->u.udfu.u.value1.has_a_b, ==, false);
 622    qapi_free_WrapAlternate(wrap);
 623}
 624
 625static void test_visitor_in_alternate_number(TestInputVisitorData *data,
 626                                             const void *unused)
 627{
 628    Visitor *v;
 629    Error *err = NULL;
 630    AltEnumBool *aeb;
 631    AltEnumNum *aen;
 632    AltNumEnum *ans;
 633    AltEnumInt *asi;
 634
 635    /* Parsing an int */
 636
 637    v = visitor_input_test_init(data, "42");
 638    visit_type_AltEnumBool(v, NULL, &aeb, &err);
 639    error_free_or_abort(&err);
 640    qapi_free_AltEnumBool(aeb);
 641
 642    v = visitor_input_test_init(data, "42");
 643    visit_type_AltEnumNum(v, NULL, &aen, &error_abort);
 644    g_assert_cmpint(aen->type, ==, QTYPE_QNUM);
 645    g_assert_cmpfloat(aen->u.n, ==, 42);
 646    qapi_free_AltEnumNum(aen);
 647
 648    v = visitor_input_test_init(data, "42");
 649    visit_type_AltNumEnum(v, NULL, &ans, &error_abort);
 650    g_assert_cmpint(ans->type, ==, QTYPE_QNUM);
 651    g_assert_cmpfloat(ans->u.n, ==, 42);
 652    qapi_free_AltNumEnum(ans);
 653
 654    v = visitor_input_test_init(data, "42");
 655    visit_type_AltEnumInt(v, NULL, &asi, &error_abort);
 656    g_assert_cmpint(asi->type, ==, QTYPE_QNUM);
 657    g_assert_cmpint(asi->u.i, ==, 42);
 658    qapi_free_AltEnumInt(asi);
 659
 660    /* Parsing a double */
 661
 662    v = visitor_input_test_init(data, "42.5");
 663    visit_type_AltEnumBool(v, NULL, &aeb, &err);
 664    error_free_or_abort(&err);
 665    qapi_free_AltEnumBool(aeb);
 666
 667    v = visitor_input_test_init(data, "42.5");
 668    visit_type_AltEnumNum(v, NULL, &aen, &error_abort);
 669    g_assert_cmpint(aen->type, ==, QTYPE_QNUM);
 670    g_assert_cmpfloat(aen->u.n, ==, 42.5);
 671    qapi_free_AltEnumNum(aen);
 672
 673    v = visitor_input_test_init(data, "42.5");
 674    visit_type_AltNumEnum(v, NULL, &ans, &error_abort);
 675    g_assert_cmpint(ans->type, ==, QTYPE_QNUM);
 676    g_assert_cmpfloat(ans->u.n, ==, 42.5);
 677    qapi_free_AltNumEnum(ans);
 678
 679    v = visitor_input_test_init(data, "42.5");
 680    visit_type_AltEnumInt(v, NULL, &asi, &err);
 681    error_free_or_abort(&err);
 682    qapi_free_AltEnumInt(asi);
 683}
 684
 685static void test_list_union_integer_helper(TestInputVisitorData *data,
 686                                           const void *unused,
 687                                           UserDefListUnionKind kind)
 688{
 689    g_autoptr(UserDefListUnion) cvalue = NULL;
 690    Visitor *v;
 691    GString *gstr_list = g_string_new("");
 692    GString *gstr_union = g_string_new("");
 693    int i;
 694
 695    for (i = 0; i < 32; i++) {
 696        g_string_append_printf(gstr_list, "%d", i);
 697        if (i != 31) {
 698            g_string_append(gstr_list, ", ");
 699        }
 700    }
 701    g_string_append_printf(gstr_union,  "{ 'type': '%s', 'data': [ %s ] }",
 702                           UserDefListUnionKind_str(kind),
 703                           gstr_list->str);
 704    v = visitor_input_test_init_raw(data,  gstr_union->str);
 705
 706    visit_type_UserDefListUnion(v, NULL, &cvalue, &error_abort);
 707    g_assert(cvalue != NULL);
 708    g_assert_cmpint(cvalue->type, ==, kind);
 709
 710    switch (kind) {
 711    case USER_DEF_LIST_UNION_KIND_INTEGER: {
 712        intList *elem = NULL;
 713        for (i = 0, elem = cvalue->u.integer.data;
 714             elem; elem = elem->next, i++) {
 715            g_assert_cmpint(elem->value, ==, i);
 716        }
 717        break;
 718    }
 719    case USER_DEF_LIST_UNION_KIND_S8: {
 720        int8List *elem = NULL;
 721        for (i = 0, elem = cvalue->u.s8.data; elem; elem = elem->next, i++) {
 722            g_assert_cmpint(elem->value, ==, i);
 723        }
 724        break;
 725    }
 726    case USER_DEF_LIST_UNION_KIND_S16: {
 727        int16List *elem = NULL;
 728        for (i = 0, elem = cvalue->u.s16.data; elem; elem = elem->next, i++) {
 729            g_assert_cmpint(elem->value, ==, i);
 730        }
 731        break;
 732    }
 733    case USER_DEF_LIST_UNION_KIND_S32: {
 734        int32List *elem = NULL;
 735        for (i = 0, elem = cvalue->u.s32.data; elem; elem = elem->next, i++) {
 736            g_assert_cmpint(elem->value, ==, i);
 737        }
 738        break;
 739    }
 740    case USER_DEF_LIST_UNION_KIND_S64: {
 741        int64List *elem = NULL;
 742        for (i = 0, elem = cvalue->u.s64.data; elem; elem = elem->next, i++) {
 743            g_assert_cmpint(elem->value, ==, i);
 744        }
 745        break;
 746    }
 747    case USER_DEF_LIST_UNION_KIND_U8: {
 748        uint8List *elem = NULL;
 749        for (i = 0, elem = cvalue->u.u8.data; elem; elem = elem->next, i++) {
 750            g_assert_cmpint(elem->value, ==, i);
 751        }
 752        break;
 753    }
 754    case USER_DEF_LIST_UNION_KIND_U16: {
 755        uint16List *elem = NULL;
 756        for (i = 0, elem = cvalue->u.u16.data; elem; elem = elem->next, i++) {
 757            g_assert_cmpint(elem->value, ==, i);
 758        }
 759        break;
 760    }
 761    case USER_DEF_LIST_UNION_KIND_U32: {
 762        uint32List *elem = NULL;
 763        for (i = 0, elem = cvalue->u.u32.data; elem; elem = elem->next, i++) {
 764            g_assert_cmpint(elem->value, ==, i);
 765        }
 766        break;
 767    }
 768    case USER_DEF_LIST_UNION_KIND_U64: {
 769        uint64List *elem = NULL;
 770        for (i = 0, elem = cvalue->u.u64.data; elem; elem = elem->next, i++) {
 771            g_assert_cmpint(elem->value, ==, i);
 772        }
 773        break;
 774    }
 775    default:
 776        g_assert_not_reached();
 777    }
 778
 779    g_string_free(gstr_union, true);
 780    g_string_free(gstr_list, true);
 781}
 782
 783static void test_visitor_in_list_union_int(TestInputVisitorData *data,
 784                                           const void *unused)
 785{
 786    test_list_union_integer_helper(data, unused,
 787                                   USER_DEF_LIST_UNION_KIND_INTEGER);
 788}
 789
 790static void test_visitor_in_list_union_int8(TestInputVisitorData *data,
 791                                            const void *unused)
 792{
 793    test_list_union_integer_helper(data, unused,
 794                                   USER_DEF_LIST_UNION_KIND_S8);
 795}
 796
 797static void test_visitor_in_list_union_int16(TestInputVisitorData *data,
 798                                             const void *unused)
 799{
 800    test_list_union_integer_helper(data, unused,
 801                                   USER_DEF_LIST_UNION_KIND_S16);
 802}
 803
 804static void test_visitor_in_list_union_int32(TestInputVisitorData *data,
 805                                             const void *unused)
 806{
 807    test_list_union_integer_helper(data, unused,
 808                                   USER_DEF_LIST_UNION_KIND_S32);
 809}
 810
 811static void test_visitor_in_list_union_int64(TestInputVisitorData *data,
 812                                             const void *unused)
 813{
 814    test_list_union_integer_helper(data, unused,
 815                                   USER_DEF_LIST_UNION_KIND_S64);
 816}
 817
 818static void test_visitor_in_list_union_uint8(TestInputVisitorData *data,
 819                                             const void *unused)
 820{
 821    test_list_union_integer_helper(data, unused,
 822                                   USER_DEF_LIST_UNION_KIND_U8);
 823}
 824
 825static void test_visitor_in_list_union_uint16(TestInputVisitorData *data,
 826                                              const void *unused)
 827{
 828    test_list_union_integer_helper(data, unused,
 829                                   USER_DEF_LIST_UNION_KIND_U16);
 830}
 831
 832static void test_visitor_in_list_union_uint32(TestInputVisitorData *data,
 833                                              const void *unused)
 834{
 835    test_list_union_integer_helper(data, unused,
 836                                   USER_DEF_LIST_UNION_KIND_U32);
 837}
 838
 839static void test_visitor_in_list_union_uint64(TestInputVisitorData *data,
 840                                              const void *unused)
 841{
 842    test_list_union_integer_helper(data, unused,
 843                                   USER_DEF_LIST_UNION_KIND_U64);
 844}
 845
 846static void test_visitor_in_list_union_bool(TestInputVisitorData *data,
 847                                            const void *unused)
 848{
 849    g_autoptr(UserDefListUnion) cvalue = NULL;
 850    boolList *elem = NULL;
 851    Visitor *v;
 852    GString *gstr_list = g_string_new("");
 853    GString *gstr_union = g_string_new("");
 854    int i;
 855
 856    for (i = 0; i < 32; i++) {
 857        g_string_append_printf(gstr_list, "%s",
 858                               (i % 3 == 0) ? "true" : "false");
 859        if (i != 31) {
 860            g_string_append(gstr_list, ", ");
 861        }
 862    }
 863    g_string_append_printf(gstr_union,  "{ 'type': 'boolean', 'data': [ %s ] }",
 864                           gstr_list->str);
 865    v = visitor_input_test_init_raw(data,  gstr_union->str);
 866
 867    visit_type_UserDefListUnion(v, NULL, &cvalue, &error_abort);
 868    g_assert(cvalue != NULL);
 869    g_assert_cmpint(cvalue->type, ==, USER_DEF_LIST_UNION_KIND_BOOLEAN);
 870
 871    for (i = 0, elem = cvalue->u.boolean.data; elem; elem = elem->next, i++) {
 872        g_assert_cmpint(elem->value, ==, (i % 3 == 0) ? 1 : 0);
 873    }
 874
 875    g_string_free(gstr_union, true);
 876    g_string_free(gstr_list, true);
 877}
 878
 879static void test_visitor_in_list_union_string(TestInputVisitorData *data,
 880                                              const void *unused)
 881{
 882    g_autoptr(UserDefListUnion) cvalue = NULL;
 883    strList *elem = NULL;
 884    Visitor *v;
 885    GString *gstr_list = g_string_new("");
 886    GString *gstr_union = g_string_new("");
 887    int i;
 888
 889    for (i = 0; i < 32; i++) {
 890        g_string_append_printf(gstr_list, "'%d'", i);
 891        if (i != 31) {
 892            g_string_append(gstr_list, ", ");
 893        }
 894    }
 895    g_string_append_printf(gstr_union,  "{ 'type': 'string', 'data': [ %s ] }",
 896                           gstr_list->str);
 897    v = visitor_input_test_init_raw(data,  gstr_union->str);
 898
 899    visit_type_UserDefListUnion(v, NULL, &cvalue, &error_abort);
 900    g_assert(cvalue != NULL);
 901    g_assert_cmpint(cvalue->type, ==, USER_DEF_LIST_UNION_KIND_STRING);
 902
 903    for (i = 0, elem = cvalue->u.string.data; elem; elem = elem->next, i++) {
 904        gchar str[8];
 905        sprintf(str, "%d", i);
 906        g_assert_cmpstr(elem->value, ==, str);
 907    }
 908
 909    g_string_free(gstr_union, true);
 910    g_string_free(gstr_list, true);
 911}
 912
 913#define DOUBLE_STR_MAX 16
 914
 915static void test_visitor_in_list_union_number(TestInputVisitorData *data,
 916                                              const void *unused)
 917{
 918    g_autoptr(UserDefListUnion) cvalue = NULL;
 919    numberList *elem = NULL;
 920    Visitor *v;
 921    GString *gstr_list = g_string_new("");
 922    GString *gstr_union = g_string_new("");
 923    int i;
 924
 925    for (i = 0; i < 32; i++) {
 926        g_string_append_printf(gstr_list, "%f", (double)i / 3);
 927        if (i != 31) {
 928            g_string_append(gstr_list, ", ");
 929        }
 930    }
 931    g_string_append_printf(gstr_union,  "{ 'type': 'number', 'data': [ %s ] }",
 932                           gstr_list->str);
 933    v = visitor_input_test_init_raw(data,  gstr_union->str);
 934
 935    visit_type_UserDefListUnion(v, NULL, &cvalue, &error_abort);
 936    g_assert(cvalue != NULL);
 937    g_assert_cmpint(cvalue->type, ==, USER_DEF_LIST_UNION_KIND_NUMBER);
 938
 939    for (i = 0, elem = cvalue->u.number.data; elem; elem = elem->next, i++) {
 940        GString *double_expected = g_string_new("");
 941        GString *double_actual = g_string_new("");
 942
 943        g_string_printf(double_expected, "%.6f", (double)i / 3);
 944        g_string_printf(double_actual, "%.6f", elem->value);
 945        g_assert_cmpstr(double_expected->str, ==, double_actual->str);
 946
 947        g_string_free(double_expected, true);
 948        g_string_free(double_actual, true);
 949    }
 950
 951    g_string_free(gstr_union, true);
 952    g_string_free(gstr_list, true);
 953}
 954
 955static void input_visitor_test_add(const char *testpath,
 956                                   const void *user_data,
 957                                   void (*test_func)(TestInputVisitorData *data,
 958                                                     const void *user_data))
 959{
 960    g_test_add(testpath, TestInputVisitorData, user_data, NULL, test_func,
 961               visitor_input_teardown);
 962}
 963
 964static void test_visitor_in_errors(TestInputVisitorData *data,
 965                                   const void *unused)
 966{
 967    TestStruct *p = NULL;
 968    Error *err = NULL;
 969    Visitor *v;
 970    strList *q = NULL;
 971    UserDefTwo *r = NULL;
 972    WrapAlternate *s = NULL;
 973
 974    v = visitor_input_test_init(data, "{ 'integer': false, 'boolean': 'foo', "
 975                                "'string': -42 }");
 976
 977    visit_type_TestStruct(v, NULL, &p, &err);
 978    error_free_or_abort(&err);
 979    g_assert(!p);
 980
 981    v = visitor_input_test_init(data, "[ '1', '2', false, '3' ]");
 982    visit_type_strList(v, NULL, &q, &err);
 983    error_free_or_abort(&err);
 984    assert(!q);
 985
 986    v = visitor_input_test_init(data, "{ 'str':'hi' }");
 987    visit_type_UserDefTwo(v, NULL, &r, &err);
 988    error_free_or_abort(&err);
 989    assert(!r);
 990
 991    v = visitor_input_test_init(data, "{ }");
 992    visit_type_WrapAlternate(v, NULL, &s, &err);
 993    error_free_or_abort(&err);
 994    assert(!s);
 995}
 996
 997static void test_visitor_in_wrong_type(TestInputVisitorData *data,
 998                                       const void *unused)
 999{
1000    TestStruct *p = NULL;
1001    Visitor *v;
1002    strList *q = NULL;
1003    int64_t i;
1004    Error *err = NULL;
1005
1006    /* Make sure arrays and structs cannot be confused */
1007
1008    v = visitor_input_test_init(data, "[]");
1009    visit_type_TestStruct(v, NULL, &p, &err);
1010    error_free_or_abort(&err);
1011    g_assert(!p);
1012
1013    v = visitor_input_test_init(data, "{}");
1014    visit_type_strList(v, NULL, &q, &err);
1015    error_free_or_abort(&err);
1016    assert(!q);
1017
1018    /* Make sure primitives and struct cannot be confused */
1019
1020    v = visitor_input_test_init(data, "1");
1021    visit_type_TestStruct(v, NULL, &p, &err);
1022    error_free_or_abort(&err);
1023    g_assert(!p);
1024
1025    v = visitor_input_test_init(data, "{}");
1026    visit_type_int(v, NULL, &i, &err);
1027    error_free_or_abort(&err);
1028
1029    /* Make sure primitives and arrays cannot be confused */
1030
1031    v = visitor_input_test_init(data, "1");
1032    visit_type_strList(v, NULL, &q, &err);
1033    error_free_or_abort(&err);
1034    assert(!q);
1035
1036    v = visitor_input_test_init(data, "[]");
1037    visit_type_int(v, NULL, &i, &err);
1038    error_free_or_abort(&err);
1039}
1040
1041static void test_visitor_in_fail_struct(TestInputVisitorData *data,
1042                                        const void *unused)
1043{
1044    TestStruct *p = NULL;
1045    Error *err = NULL;
1046    Visitor *v;
1047
1048    v = visitor_input_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo', 'extra': 42 }");
1049
1050    visit_type_TestStruct(v, NULL, &p, &err);
1051    error_free_or_abort(&err);
1052    g_assert(!p);
1053}
1054
1055static void test_visitor_in_fail_struct_nested(TestInputVisitorData *data,
1056                                               const void *unused)
1057{
1058    UserDefTwo *udp = NULL;
1059    Error *err = NULL;
1060    Visitor *v;
1061
1062    v = visitor_input_test_init(data, "{ 'string0': 'string0', 'dict1': { 'string1': 'string1', 'dict2': { 'userdef1': { 'integer': 42, 'string': 'string', 'extra': [42, 23, {'foo':'bar'}] }, 'string2': 'string2'}}}");
1063
1064    visit_type_UserDefTwo(v, NULL, &udp, &err);
1065    error_free_or_abort(&err);
1066    g_assert(!udp);
1067}
1068
1069static void test_visitor_in_fail_struct_in_list(TestInputVisitorData *data,
1070                                                const void *unused)
1071{
1072    UserDefOneList *head = NULL;
1073    Error *err = NULL;
1074    Visitor *v;
1075
1076    v = visitor_input_test_init(data, "[ { 'string': 'string0', 'integer': 42 }, { 'string': 'string1', 'integer': 43 }, { 'string': 'string2', 'integer': 44, 'extra': 'ggg' } ]");
1077
1078    visit_type_UserDefOneList(v, NULL, &head, &err);
1079    error_free_or_abort(&err);
1080    g_assert(!head);
1081}
1082
1083static void test_visitor_in_fail_struct_missing(TestInputVisitorData *data,
1084                                                const void *unused)
1085{
1086    Error *err = NULL;
1087    Visitor *v;
1088    QObject *any;
1089    QNull *null;
1090    GenericAlternate *alt;
1091    bool present;
1092    int en;
1093    int64_t i64;
1094    uint32_t u32;
1095    int8_t i8;
1096    char *str;
1097    double dbl;
1098
1099    v = visitor_input_test_init(data, "{ 'sub': [ {} ] }");
1100    visit_start_struct(v, NULL, NULL, 0, &error_abort);
1101    visit_start_struct(v, "struct", NULL, 0, &err);
1102    error_free_or_abort(&err);
1103    visit_start_list(v, "list", NULL, 0, &err);
1104    error_free_or_abort(&err);
1105    visit_start_alternate(v, "alternate", &alt, sizeof(*alt), &err);
1106    error_free_or_abort(&err);
1107    visit_optional(v, "optional", &present);
1108    g_assert(!present);
1109    visit_type_enum(v, "enum", &en, &EnumOne_lookup, &err);
1110    error_free_or_abort(&err);
1111    visit_type_int(v, "i64", &i64, &err);
1112    error_free_or_abort(&err);
1113    visit_type_uint32(v, "u32", &u32, &err);
1114    error_free_or_abort(&err);
1115    visit_type_int8(v, "i8", &i8, &err);
1116    error_free_or_abort(&err);
1117    visit_type_str(v, "i8", &str, &err);
1118    error_free_or_abort(&err);
1119    visit_type_number(v, "dbl", &dbl, &err);
1120    error_free_or_abort(&err);
1121    visit_type_any(v, "any", &any, &err);
1122    error_free_or_abort(&err);
1123    visit_type_null(v, "null", &null, &err);
1124    error_free_or_abort(&err);
1125    visit_start_list(v, "sub", NULL, 0, &error_abort);
1126    visit_start_struct(v, NULL, NULL, 0, &error_abort);
1127    visit_type_int(v, "i64", &i64, &err);
1128    error_free_or_abort(&err);
1129    visit_end_struct(v, NULL);
1130    visit_end_list(v, NULL);
1131    visit_end_struct(v, NULL);
1132}
1133
1134static void test_visitor_in_fail_list(TestInputVisitorData *data,
1135                                      const void *unused)
1136{
1137    int64_t i64 = -1;
1138    Error *err = NULL;
1139    Visitor *v;
1140
1141    /* Unvisited list tail */
1142
1143    v = visitor_input_test_init(data, "[ 1, 2, 3 ]");
1144
1145    visit_start_list(v, NULL, NULL, 0, &error_abort);
1146    visit_type_int(v, NULL, &i64, &error_abort);
1147    g_assert_cmpint(i64, ==, 1);
1148    visit_type_int(v, NULL, &i64, &error_abort);
1149    g_assert_cmpint(i64, ==, 2);
1150    visit_check_list(v, &err);
1151    error_free_or_abort(&err);
1152    visit_end_list(v, NULL);
1153
1154    /* Visit beyond end of list */
1155    v = visitor_input_test_init(data, "[]");
1156
1157    visit_start_list(v, NULL, NULL, 0, &error_abort);
1158    visit_type_int(v, NULL, &i64, &err);
1159    error_free_or_abort(&err);
1160    visit_end_list(v, NULL);
1161}
1162
1163static void test_visitor_in_fail_list_nested(TestInputVisitorData *data,
1164                                             const void *unused)
1165{
1166    int64_t i64 = -1;
1167    Error *err = NULL;
1168    Visitor *v;
1169
1170    /* Unvisited nested list tail */
1171
1172    v = visitor_input_test_init(data, "[ 0, [ 1, 2, 3 ] ]");
1173
1174    visit_start_list(v, NULL, NULL, 0, &error_abort);
1175    visit_type_int(v, NULL, &i64, &error_abort);
1176    g_assert_cmpint(i64, ==, 0);
1177    visit_start_list(v, NULL, NULL, 0, &error_abort);
1178    visit_type_int(v, NULL, &i64, &error_abort);
1179    g_assert_cmpint(i64, ==, 1);
1180    visit_check_list(v, &err);
1181    error_free_or_abort(&err);
1182    visit_end_list(v, NULL);
1183    visit_check_list(v, &error_abort);
1184    visit_end_list(v, NULL);
1185}
1186
1187static void test_visitor_in_fail_union_list(TestInputVisitorData *data,
1188                                            const void *unused)
1189{
1190    UserDefListUnion *tmp = NULL;
1191    Error *err = NULL;
1192    Visitor *v;
1193
1194    v = visitor_input_test_init(data,
1195                                "{ 'type': 'integer', 'data' : [ 'string' ] }");
1196
1197    visit_type_UserDefListUnion(v, NULL, &tmp, &err);
1198    error_free_or_abort(&err);
1199    g_assert(!tmp);
1200}
1201
1202static void test_visitor_in_fail_union_flat(TestInputVisitorData *data,
1203                                            const void *unused)
1204{
1205    UserDefFlatUnion *tmp = NULL;
1206    Error *err = NULL;
1207    Visitor *v;
1208
1209    v = visitor_input_test_init(data, "{ 'string': 'c', 'integer': 41, 'boolean': true }");
1210
1211    visit_type_UserDefFlatUnion(v, NULL, &tmp, &err);
1212    error_free_or_abort(&err);
1213    g_assert(!tmp);
1214}
1215
1216static void test_visitor_in_fail_union_flat_no_discrim(TestInputVisitorData *data,
1217                                                       const void *unused)
1218{
1219    UserDefFlatUnion2 *tmp = NULL;
1220    Error *err = NULL;
1221    Visitor *v;
1222
1223    /* test situation where discriminator field ('enum1' here) is missing */
1224    v = visitor_input_test_init(data, "{ 'integer': 42, 'string': 'c', 'string1': 'd', 'string2': 'e' }");
1225
1226    visit_type_UserDefFlatUnion2(v, NULL, &tmp, &err);
1227    error_free_or_abort(&err);
1228    g_assert(!tmp);
1229}
1230
1231static void test_visitor_in_fail_alternate(TestInputVisitorData *data,
1232                                           const void *unused)
1233{
1234    UserDefAlternate *tmp;
1235    Visitor *v;
1236    Error *err = NULL;
1237
1238    v = visitor_input_test_init(data, "3.14");
1239
1240    visit_type_UserDefAlternate(v, NULL, &tmp, &err);
1241    error_free_or_abort(&err);
1242    g_assert(!tmp);
1243}
1244
1245static void do_test_visitor_in_qmp_introspect(TestInputVisitorData *data,
1246                                              const QLitObject *qlit)
1247{
1248    g_autoptr(SchemaInfoList) schema = NULL;
1249    QObject *obj = qobject_from_qlit(qlit);
1250    Visitor *v;
1251
1252    v = qobject_input_visitor_new(obj);
1253
1254    visit_type_SchemaInfoList(v, NULL, &schema, &error_abort);
1255    g_assert(schema);
1256
1257    qobject_unref(obj);
1258    visit_free(v);
1259}
1260
1261static void test_visitor_in_qmp_introspect(TestInputVisitorData *data,
1262                                           const void *unused)
1263{
1264    do_test_visitor_in_qmp_introspect(data, &test_qmp_schema_qlit);
1265}
1266
1267int main(int argc, char **argv)
1268{
1269    g_test_init(&argc, &argv, NULL);
1270
1271    input_visitor_test_add("/visitor/input/int",
1272                           NULL, test_visitor_in_int);
1273    input_visitor_test_add("/visitor/input/uint",
1274                           NULL, test_visitor_in_uint);
1275    input_visitor_test_add("/visitor/input/int_overflow",
1276                           NULL, test_visitor_in_int_overflow);
1277    input_visitor_test_add("/visitor/input/int_keyval",
1278                           NULL, test_visitor_in_int_keyval);
1279    input_visitor_test_add("/visitor/input/int_str_keyval",
1280                           NULL, test_visitor_in_int_str_keyval);
1281    input_visitor_test_add("/visitor/input/int_str_fail",
1282                           NULL, test_visitor_in_int_str_fail);
1283    input_visitor_test_add("/visitor/input/bool",
1284                           NULL, test_visitor_in_bool);
1285    input_visitor_test_add("/visitor/input/bool_keyval",
1286                           NULL, test_visitor_in_bool_keyval);
1287    input_visitor_test_add("/visitor/input/bool_str_keyval",
1288                           NULL, test_visitor_in_bool_str_keyval);
1289    input_visitor_test_add("/visitor/input/bool_str_fail",
1290                           NULL, test_visitor_in_bool_str_fail);
1291    input_visitor_test_add("/visitor/input/number",
1292                           NULL, test_visitor_in_number);
1293    input_visitor_test_add("/visitor/input/large_number",
1294                           NULL, test_visitor_in_large_number);
1295    input_visitor_test_add("/visitor/input/number_keyval",
1296                           NULL, test_visitor_in_number_keyval);
1297    input_visitor_test_add("/visitor/input/number_str_keyval",
1298                           NULL, test_visitor_in_number_str_keyval);
1299    input_visitor_test_add("/visitor/input/number_str_fail",
1300                           NULL, test_visitor_in_number_str_fail);
1301    input_visitor_test_add("/visitor/input/size_str_keyval",
1302                           NULL, test_visitor_in_size_str_keyval);
1303    input_visitor_test_add("/visitor/input/size_str_fail",
1304                           NULL, test_visitor_in_size_str_fail);
1305    input_visitor_test_add("/visitor/input/string",
1306                           NULL, test_visitor_in_string);
1307    input_visitor_test_add("/visitor/input/enum",
1308                           NULL, test_visitor_in_enum);
1309    input_visitor_test_add("/visitor/input/struct",
1310                           NULL, test_visitor_in_struct);
1311    input_visitor_test_add("/visitor/input/struct-nested",
1312                           NULL, test_visitor_in_struct_nested);
1313    input_visitor_test_add("/visitor/input/list",
1314                           NULL, test_visitor_in_list);
1315    input_visitor_test_add("/visitor/input/any",
1316                           NULL, test_visitor_in_any);
1317    input_visitor_test_add("/visitor/input/null",
1318                           NULL, test_visitor_in_null);
1319    input_visitor_test_add("/visitor/input/union-flat",
1320                           NULL, test_visitor_in_union_flat);
1321    input_visitor_test_add("/visitor/input/alternate",
1322                           NULL, test_visitor_in_alternate);
1323    input_visitor_test_add("/visitor/input/errors",
1324                           NULL, test_visitor_in_errors);
1325    input_visitor_test_add("/visitor/input/wrong-type",
1326                           NULL, test_visitor_in_wrong_type);
1327    input_visitor_test_add("/visitor/input/alternate-number",
1328                           NULL, test_visitor_in_alternate_number);
1329    input_visitor_test_add("/visitor/input/list_union/int",
1330                           NULL, test_visitor_in_list_union_int);
1331    input_visitor_test_add("/visitor/input/list_union/int8",
1332                           NULL, test_visitor_in_list_union_int8);
1333    input_visitor_test_add("/visitor/input/list_union/int16",
1334                           NULL, test_visitor_in_list_union_int16);
1335    input_visitor_test_add("/visitor/input/list_union/int32",
1336                           NULL, test_visitor_in_list_union_int32);
1337    input_visitor_test_add("/visitor/input/list_union/int64",
1338                           NULL, test_visitor_in_list_union_int64);
1339    input_visitor_test_add("/visitor/input/list_union/uint8",
1340                           NULL, test_visitor_in_list_union_uint8);
1341    input_visitor_test_add("/visitor/input/list_union/uint16",
1342                           NULL, test_visitor_in_list_union_uint16);
1343    input_visitor_test_add("/visitor/input/list_union/uint32",
1344                           NULL, test_visitor_in_list_union_uint32);
1345    input_visitor_test_add("/visitor/input/list_union/uint64",
1346                           NULL, test_visitor_in_list_union_uint64);
1347    input_visitor_test_add("/visitor/input/list_union/bool",
1348                           NULL, test_visitor_in_list_union_bool);
1349    input_visitor_test_add("/visitor/input/list_union/str",
1350                           NULL, test_visitor_in_list_union_string);
1351    input_visitor_test_add("/visitor/input/list_union/number",
1352                           NULL, test_visitor_in_list_union_number);
1353    input_visitor_test_add("/visitor/input/fail/struct",
1354                           NULL, test_visitor_in_fail_struct);
1355    input_visitor_test_add("/visitor/input/fail/struct-nested",
1356                           NULL, test_visitor_in_fail_struct_nested);
1357    input_visitor_test_add("/visitor/input/fail/struct-in-list",
1358                           NULL, test_visitor_in_fail_struct_in_list);
1359    input_visitor_test_add("/visitor/input/fail/struct-missing",
1360                           NULL, test_visitor_in_fail_struct_missing);
1361    input_visitor_test_add("/visitor/input/fail/list",
1362                           NULL, test_visitor_in_fail_list);
1363    input_visitor_test_add("/visitor/input/fail/list-nested",
1364                           NULL, test_visitor_in_fail_list_nested);
1365    input_visitor_test_add("/visitor/input/fail/union-flat",
1366                           NULL, test_visitor_in_fail_union_flat);
1367    input_visitor_test_add("/visitor/input/fail/union-flat-no-discriminator",
1368                           NULL, test_visitor_in_fail_union_flat_no_discrim);
1369    input_visitor_test_add("/visitor/input/fail/alternate",
1370                           NULL, test_visitor_in_fail_alternate);
1371    input_visitor_test_add("/visitor/input/fail/union-list",
1372                           NULL, test_visitor_in_fail_union_list);
1373    input_visitor_test_add("/visitor/input/qapi-introspect",
1374                           NULL, test_visitor_in_qmp_introspect);
1375
1376    g_test_run();
1377
1378    return 0;
1379}
1380