qemu/tests/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    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    qapi_free_UserDefTwo(udp);
 438}
 439
 440static void test_visitor_in_list(TestInputVisitorData *data,
 441                                 const void *unused)
 442{
 443    UserDefOneList *item, *head = NULL;
 444    Visitor *v;
 445    int i;
 446
 447    v = visitor_input_test_init(data, "[ { 'string': 'string0', 'integer': 42 }, { 'string': 'string1', 'integer': 43 }, { 'string': 'string2', 'integer': 44 } ]");
 448
 449    visit_type_UserDefOneList(v, NULL, &head, &error_abort);
 450    g_assert(head != NULL);
 451
 452    for (i = 0, item = head; item; item = item->next, i++) {
 453        char string[12];
 454
 455        snprintf(string, sizeof(string), "string%d", i);
 456        g_assert_cmpstr(item->value->string, ==, string);
 457        g_assert_cmpint(item->value->integer, ==, 42 + i);
 458    }
 459
 460    qapi_free_UserDefOneList(head);
 461    head = NULL;
 462
 463    /* An empty list is valid */
 464    v = visitor_input_test_init(data, "[]");
 465    visit_type_UserDefOneList(v, NULL, &head, &error_abort);
 466    g_assert(!head);
 467}
 468
 469static void test_visitor_in_any(TestInputVisitorData *data,
 470                                const void *unused)
 471{
 472    QObject *res = NULL;
 473    Visitor *v;
 474    QNum *qnum;
 475    QBool *qbool;
 476    QString *qstring;
 477    QDict *qdict;
 478    QObject *qobj;
 479    int64_t val;
 480
 481    v = visitor_input_test_init(data, "-42");
 482    visit_type_any(v, NULL, &res, &error_abort);
 483    qnum = qobject_to(QNum, res);
 484    g_assert(qnum);
 485    g_assert(qnum_get_try_int(qnum, &val));
 486    g_assert_cmpint(val, ==, -42);
 487    qobject_unref(res);
 488
 489    v = visitor_input_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo' }");
 490    visit_type_any(v, NULL, &res, &error_abort);
 491    qdict = qobject_to(QDict, res);
 492    g_assert(qdict && qdict_size(qdict) == 3);
 493    qobj = qdict_get(qdict, "integer");
 494    g_assert(qobj);
 495    qnum = qobject_to(QNum, qobj);
 496    g_assert(qnum);
 497    g_assert(qnum_get_try_int(qnum, &val));
 498    g_assert_cmpint(val, ==, -42);
 499    qobj = qdict_get(qdict, "boolean");
 500    g_assert(qobj);
 501    qbool = qobject_to(QBool, qobj);
 502    g_assert(qbool);
 503    g_assert(qbool_get_bool(qbool) == true);
 504    qobj = qdict_get(qdict, "string");
 505    g_assert(qobj);
 506    qstring = qobject_to(QString, qobj);
 507    g_assert(qstring);
 508    g_assert_cmpstr(qstring_get_str(qstring), ==, "foo");
 509    qobject_unref(res);
 510}
 511
 512static void test_visitor_in_null(TestInputVisitorData *data,
 513                                 const void *unused)
 514{
 515    Visitor *v;
 516    Error *err = NULL;
 517    QNull *null;
 518    char *tmp;
 519
 520    /*
 521     * FIXME: Since QAPI doesn't know the 'null' type yet, we can't
 522     * test visit_type_null() by reading into a QAPI struct then
 523     * checking that it was populated correctly.  The best we can do
 524     * for now is ensure that we consumed null from the input, proven
 525     * by the fact that we can't re-read the key; and that we detect
 526     * when input is not null.
 527     */
 528
 529    v = visitor_input_test_init_full(data, false,
 530                                     "{ 'a': null, 'b': '' }");
 531    visit_start_struct(v, NULL, NULL, 0, &error_abort);
 532    visit_type_null(v, "a", &null, &error_abort);
 533    g_assert(qobject_type(QOBJECT(null)) == QTYPE_QNULL);
 534    qobject_unref(null);
 535    visit_type_null(v, "b", &null, &err);
 536    error_free_or_abort(&err);
 537    g_assert(!null);
 538    visit_type_str(v, "c", &tmp, &err);
 539    error_free_or_abort(&err);
 540    g_assert(!tmp);
 541    visit_check_struct(v, &error_abort);
 542    visit_end_struct(v, NULL);
 543}
 544
 545static void test_visitor_in_union_flat(TestInputVisitorData *data,
 546                                       const void *unused)
 547{
 548    Visitor *v;
 549    UserDefFlatUnion *tmp;
 550    UserDefUnionBase *base;
 551
 552    v = visitor_input_test_init(data,
 553                                "{ 'enum1': 'value1', "
 554                                "'integer': 41, "
 555                                "'string': 'str', "
 556                                "'boolean': true }");
 557
 558    visit_type_UserDefFlatUnion(v, NULL, &tmp, &error_abort);
 559    g_assert_cmpint(tmp->enum1, ==, ENUM_ONE_VALUE1);
 560    g_assert_cmpstr(tmp->string, ==, "str");
 561    g_assert_cmpint(tmp->integer, ==, 41);
 562    g_assert_cmpint(tmp->u.value1.boolean, ==, true);
 563
 564    base = qapi_UserDefFlatUnion_base(tmp);
 565    g_assert(&base->enum1 == &tmp->enum1);
 566
 567    qapi_free_UserDefFlatUnion(tmp);
 568}
 569
 570static void test_visitor_in_alternate(TestInputVisitorData *data,
 571                                      const void *unused)
 572{
 573    Visitor *v;
 574    UserDefAlternate *tmp;
 575    WrapAlternate *wrap;
 576
 577    v = visitor_input_test_init(data, "42");
 578    visit_type_UserDefAlternate(v, NULL, &tmp, &error_abort);
 579    g_assert_cmpint(tmp->type, ==, QTYPE_QNUM);
 580    g_assert_cmpint(tmp->u.i, ==, 42);
 581    qapi_free_UserDefAlternate(tmp);
 582
 583    v = visitor_input_test_init(data, "'value1'");
 584    visit_type_UserDefAlternate(v, NULL, &tmp, &error_abort);
 585    g_assert_cmpint(tmp->type, ==, QTYPE_QSTRING);
 586    g_assert_cmpint(tmp->u.e, ==, ENUM_ONE_VALUE1);
 587    qapi_free_UserDefAlternate(tmp);
 588
 589    v = visitor_input_test_init(data, "null");
 590    visit_type_UserDefAlternate(v, NULL, &tmp, &error_abort);
 591    g_assert_cmpint(tmp->type, ==, QTYPE_QNULL);
 592    qapi_free_UserDefAlternate(tmp);
 593
 594    v = visitor_input_test_init(data, "{'integer':1, 'string':'str', "
 595                                "'enum1':'value1', 'boolean':true}");
 596    visit_type_UserDefAlternate(v, NULL, &tmp, &error_abort);
 597    g_assert_cmpint(tmp->type, ==, QTYPE_QDICT);
 598    g_assert_cmpint(tmp->u.udfu.integer, ==, 1);
 599    g_assert_cmpstr(tmp->u.udfu.string, ==, "str");
 600    g_assert_cmpint(tmp->u.udfu.enum1, ==, ENUM_ONE_VALUE1);
 601    g_assert_cmpint(tmp->u.udfu.u.value1.boolean, ==, true);
 602    g_assert_cmpint(tmp->u.udfu.u.value1.has_a_b, ==, false);
 603    qapi_free_UserDefAlternate(tmp);
 604
 605    v = visitor_input_test_init(data, "{ 'alt': 42 }");
 606    visit_type_WrapAlternate(v, NULL, &wrap, &error_abort);
 607    g_assert_cmpint(wrap->alt->type, ==, QTYPE_QNUM);
 608    g_assert_cmpint(wrap->alt->u.i, ==, 42);
 609    qapi_free_WrapAlternate(wrap);
 610
 611    v = visitor_input_test_init(data, "{ 'alt': 'value1' }");
 612    visit_type_WrapAlternate(v, NULL, &wrap, &error_abort);
 613    g_assert_cmpint(wrap->alt->type, ==, QTYPE_QSTRING);
 614    g_assert_cmpint(wrap->alt->u.e, ==, ENUM_ONE_VALUE1);
 615    qapi_free_WrapAlternate(wrap);
 616
 617    v = visitor_input_test_init(data, "{ 'alt': {'integer':1, 'string':'str', "
 618                                "'enum1':'value1', 'boolean':true} }");
 619    visit_type_WrapAlternate(v, NULL, &wrap, &error_abort);
 620    g_assert_cmpint(wrap->alt->type, ==, QTYPE_QDICT);
 621    g_assert_cmpint(wrap->alt->u.udfu.integer, ==, 1);
 622    g_assert_cmpstr(wrap->alt->u.udfu.string, ==, "str");
 623    g_assert_cmpint(wrap->alt->u.udfu.enum1, ==, ENUM_ONE_VALUE1);
 624    g_assert_cmpint(wrap->alt->u.udfu.u.value1.boolean, ==, true);
 625    g_assert_cmpint(wrap->alt->u.udfu.u.value1.has_a_b, ==, false);
 626    qapi_free_WrapAlternate(wrap);
 627}
 628
 629static void test_visitor_in_alternate_number(TestInputVisitorData *data,
 630                                             const void *unused)
 631{
 632    Visitor *v;
 633    Error *err = NULL;
 634    AltEnumBool *aeb;
 635    AltEnumNum *aen;
 636    AltNumEnum *ans;
 637    AltEnumInt *asi;
 638
 639    /* Parsing an int */
 640
 641    v = visitor_input_test_init(data, "42");
 642    visit_type_AltEnumBool(v, NULL, &aeb, &err);
 643    error_free_or_abort(&err);
 644    qapi_free_AltEnumBool(aeb);
 645
 646    v = visitor_input_test_init(data, "42");
 647    visit_type_AltEnumNum(v, NULL, &aen, &error_abort);
 648    g_assert_cmpint(aen->type, ==, QTYPE_QNUM);
 649    g_assert_cmpfloat(aen->u.n, ==, 42);
 650    qapi_free_AltEnumNum(aen);
 651
 652    v = visitor_input_test_init(data, "42");
 653    visit_type_AltNumEnum(v, NULL, &ans, &error_abort);
 654    g_assert_cmpint(ans->type, ==, QTYPE_QNUM);
 655    g_assert_cmpfloat(ans->u.n, ==, 42);
 656    qapi_free_AltNumEnum(ans);
 657
 658    v = visitor_input_test_init(data, "42");
 659    visit_type_AltEnumInt(v, NULL, &asi, &error_abort);
 660    g_assert_cmpint(asi->type, ==, QTYPE_QNUM);
 661    g_assert_cmpint(asi->u.i, ==, 42);
 662    qapi_free_AltEnumInt(asi);
 663
 664    /* Parsing a double */
 665
 666    v = visitor_input_test_init(data, "42.5");
 667    visit_type_AltEnumBool(v, NULL, &aeb, &err);
 668    error_free_or_abort(&err);
 669    qapi_free_AltEnumBool(aeb);
 670
 671    v = visitor_input_test_init(data, "42.5");
 672    visit_type_AltEnumNum(v, NULL, &aen, &error_abort);
 673    g_assert_cmpint(aen->type, ==, QTYPE_QNUM);
 674    g_assert_cmpfloat(aen->u.n, ==, 42.5);
 675    qapi_free_AltEnumNum(aen);
 676
 677    v = visitor_input_test_init(data, "42.5");
 678    visit_type_AltNumEnum(v, NULL, &ans, &error_abort);
 679    g_assert_cmpint(ans->type, ==, QTYPE_QNUM);
 680    g_assert_cmpfloat(ans->u.n, ==, 42.5);
 681    qapi_free_AltNumEnum(ans);
 682
 683    v = visitor_input_test_init(data, "42.5");
 684    visit_type_AltEnumInt(v, NULL, &asi, &err);
 685    error_free_or_abort(&err);
 686    qapi_free_AltEnumInt(asi);
 687}
 688
 689static void test_list_union_integer_helper(TestInputVisitorData *data,
 690                                           const void *unused,
 691                                           UserDefListUnionKind kind)
 692{
 693    UserDefListUnion *cvalue = NULL;
 694    Visitor *v;
 695    GString *gstr_list = g_string_new("");
 696    GString *gstr_union = g_string_new("");
 697    int i;
 698
 699    for (i = 0; i < 32; i++) {
 700        g_string_append_printf(gstr_list, "%d", i);
 701        if (i != 31) {
 702            g_string_append(gstr_list, ", ");
 703        }
 704    }
 705    g_string_append_printf(gstr_union,  "{ 'type': '%s', 'data': [ %s ] }",
 706                           UserDefListUnionKind_str(kind),
 707                           gstr_list->str);
 708    v = visitor_input_test_init_raw(data,  gstr_union->str);
 709
 710    visit_type_UserDefListUnion(v, NULL, &cvalue, &error_abort);
 711    g_assert(cvalue != NULL);
 712    g_assert_cmpint(cvalue->type, ==, kind);
 713
 714    switch (kind) {
 715    case USER_DEF_LIST_UNION_KIND_INTEGER: {
 716        intList *elem = NULL;
 717        for (i = 0, elem = cvalue->u.integer.data;
 718             elem; elem = elem->next, i++) {
 719            g_assert_cmpint(elem->value, ==, i);
 720        }
 721        break;
 722    }
 723    case USER_DEF_LIST_UNION_KIND_S8: {
 724        int8List *elem = NULL;
 725        for (i = 0, elem = cvalue->u.s8.data; elem; elem = elem->next, i++) {
 726            g_assert_cmpint(elem->value, ==, i);
 727        }
 728        break;
 729    }
 730    case USER_DEF_LIST_UNION_KIND_S16: {
 731        int16List *elem = NULL;
 732        for (i = 0, elem = cvalue->u.s16.data; elem; elem = elem->next, i++) {
 733            g_assert_cmpint(elem->value, ==, i);
 734        }
 735        break;
 736    }
 737    case USER_DEF_LIST_UNION_KIND_S32: {
 738        int32List *elem = NULL;
 739        for (i = 0, elem = cvalue->u.s32.data; elem; elem = elem->next, i++) {
 740            g_assert_cmpint(elem->value, ==, i);
 741        }
 742        break;
 743    }
 744    case USER_DEF_LIST_UNION_KIND_S64: {
 745        int64List *elem = NULL;
 746        for (i = 0, elem = cvalue->u.s64.data; elem; elem = elem->next, i++) {
 747            g_assert_cmpint(elem->value, ==, i);
 748        }
 749        break;
 750    }
 751    case USER_DEF_LIST_UNION_KIND_U8: {
 752        uint8List *elem = NULL;
 753        for (i = 0, elem = cvalue->u.u8.data; elem; elem = elem->next, i++) {
 754            g_assert_cmpint(elem->value, ==, i);
 755        }
 756        break;
 757    }
 758    case USER_DEF_LIST_UNION_KIND_U16: {
 759        uint16List *elem = NULL;
 760        for (i = 0, elem = cvalue->u.u16.data; elem; elem = elem->next, i++) {
 761            g_assert_cmpint(elem->value, ==, i);
 762        }
 763        break;
 764    }
 765    case USER_DEF_LIST_UNION_KIND_U32: {
 766        uint32List *elem = NULL;
 767        for (i = 0, elem = cvalue->u.u32.data; elem; elem = elem->next, i++) {
 768            g_assert_cmpint(elem->value, ==, i);
 769        }
 770        break;
 771    }
 772    case USER_DEF_LIST_UNION_KIND_U64: {
 773        uint64List *elem = NULL;
 774        for (i = 0, elem = cvalue->u.u64.data; elem; elem = elem->next, i++) {
 775            g_assert_cmpint(elem->value, ==, i);
 776        }
 777        break;
 778    }
 779    default:
 780        g_assert_not_reached();
 781    }
 782
 783    g_string_free(gstr_union, true);
 784    g_string_free(gstr_list, true);
 785    qapi_free_UserDefListUnion(cvalue);
 786}
 787
 788static void test_visitor_in_list_union_int(TestInputVisitorData *data,
 789                                           const void *unused)
 790{
 791    test_list_union_integer_helper(data, unused,
 792                                   USER_DEF_LIST_UNION_KIND_INTEGER);
 793}
 794
 795static void test_visitor_in_list_union_int8(TestInputVisitorData *data,
 796                                            const void *unused)
 797{
 798    test_list_union_integer_helper(data, unused,
 799                                   USER_DEF_LIST_UNION_KIND_S8);
 800}
 801
 802static void test_visitor_in_list_union_int16(TestInputVisitorData *data,
 803                                             const void *unused)
 804{
 805    test_list_union_integer_helper(data, unused,
 806                                   USER_DEF_LIST_UNION_KIND_S16);
 807}
 808
 809static void test_visitor_in_list_union_int32(TestInputVisitorData *data,
 810                                             const void *unused)
 811{
 812    test_list_union_integer_helper(data, unused,
 813                                   USER_DEF_LIST_UNION_KIND_S32);
 814}
 815
 816static void test_visitor_in_list_union_int64(TestInputVisitorData *data,
 817                                             const void *unused)
 818{
 819    test_list_union_integer_helper(data, unused,
 820                                   USER_DEF_LIST_UNION_KIND_S64);
 821}
 822
 823static void test_visitor_in_list_union_uint8(TestInputVisitorData *data,
 824                                             const void *unused)
 825{
 826    test_list_union_integer_helper(data, unused,
 827                                   USER_DEF_LIST_UNION_KIND_U8);
 828}
 829
 830static void test_visitor_in_list_union_uint16(TestInputVisitorData *data,
 831                                              const void *unused)
 832{
 833    test_list_union_integer_helper(data, unused,
 834                                   USER_DEF_LIST_UNION_KIND_U16);
 835}
 836
 837static void test_visitor_in_list_union_uint32(TestInputVisitorData *data,
 838                                              const void *unused)
 839{
 840    test_list_union_integer_helper(data, unused,
 841                                   USER_DEF_LIST_UNION_KIND_U32);
 842}
 843
 844static void test_visitor_in_list_union_uint64(TestInputVisitorData *data,
 845                                              const void *unused)
 846{
 847    test_list_union_integer_helper(data, unused,
 848                                   USER_DEF_LIST_UNION_KIND_U64);
 849}
 850
 851static void test_visitor_in_list_union_bool(TestInputVisitorData *data,
 852                                            const void *unused)
 853{
 854    UserDefListUnion *cvalue = NULL;
 855    boolList *elem = NULL;
 856    Visitor *v;
 857    GString *gstr_list = g_string_new("");
 858    GString *gstr_union = g_string_new("");
 859    int i;
 860
 861    for (i = 0; i < 32; i++) {
 862        g_string_append_printf(gstr_list, "%s",
 863                               (i % 3 == 0) ? "true" : "false");
 864        if (i != 31) {
 865            g_string_append(gstr_list, ", ");
 866        }
 867    }
 868    g_string_append_printf(gstr_union,  "{ 'type': 'boolean', 'data': [ %s ] }",
 869                           gstr_list->str);
 870    v = visitor_input_test_init_raw(data,  gstr_union->str);
 871
 872    visit_type_UserDefListUnion(v, NULL, &cvalue, &error_abort);
 873    g_assert(cvalue != NULL);
 874    g_assert_cmpint(cvalue->type, ==, USER_DEF_LIST_UNION_KIND_BOOLEAN);
 875
 876    for (i = 0, elem = cvalue->u.boolean.data; elem; elem = elem->next, i++) {
 877        g_assert_cmpint(elem->value, ==, (i % 3 == 0) ? 1 : 0);
 878    }
 879
 880    g_string_free(gstr_union, true);
 881    g_string_free(gstr_list, true);
 882    qapi_free_UserDefListUnion(cvalue);
 883}
 884
 885static void test_visitor_in_list_union_string(TestInputVisitorData *data,
 886                                              const void *unused)
 887{
 888    UserDefListUnion *cvalue = NULL;
 889    strList *elem = NULL;
 890    Visitor *v;
 891    GString *gstr_list = g_string_new("");
 892    GString *gstr_union = g_string_new("");
 893    int i;
 894
 895    for (i = 0; i < 32; i++) {
 896        g_string_append_printf(gstr_list, "'%d'", i);
 897        if (i != 31) {
 898            g_string_append(gstr_list, ", ");
 899        }
 900    }
 901    g_string_append_printf(gstr_union,  "{ 'type': 'string', 'data': [ %s ] }",
 902                           gstr_list->str);
 903    v = visitor_input_test_init_raw(data,  gstr_union->str);
 904
 905    visit_type_UserDefListUnion(v, NULL, &cvalue, &error_abort);
 906    g_assert(cvalue != NULL);
 907    g_assert_cmpint(cvalue->type, ==, USER_DEF_LIST_UNION_KIND_STRING);
 908
 909    for (i = 0, elem = cvalue->u.string.data; elem; elem = elem->next, i++) {
 910        gchar str[8];
 911        sprintf(str, "%d", i);
 912        g_assert_cmpstr(elem->value, ==, str);
 913    }
 914
 915    g_string_free(gstr_union, true);
 916    g_string_free(gstr_list, true);
 917    qapi_free_UserDefListUnion(cvalue);
 918}
 919
 920#define DOUBLE_STR_MAX 16
 921
 922static void test_visitor_in_list_union_number(TestInputVisitorData *data,
 923                                              const void *unused)
 924{
 925    UserDefListUnion *cvalue = NULL;
 926    numberList *elem = NULL;
 927    Visitor *v;
 928    GString *gstr_list = g_string_new("");
 929    GString *gstr_union = g_string_new("");
 930    int i;
 931
 932    for (i = 0; i < 32; i++) {
 933        g_string_append_printf(gstr_list, "%f", (double)i / 3);
 934        if (i != 31) {
 935            g_string_append(gstr_list, ", ");
 936        }
 937    }
 938    g_string_append_printf(gstr_union,  "{ 'type': 'number', 'data': [ %s ] }",
 939                           gstr_list->str);
 940    v = visitor_input_test_init_raw(data,  gstr_union->str);
 941
 942    visit_type_UserDefListUnion(v, NULL, &cvalue, &error_abort);
 943    g_assert(cvalue != NULL);
 944    g_assert_cmpint(cvalue->type, ==, USER_DEF_LIST_UNION_KIND_NUMBER);
 945
 946    for (i = 0, elem = cvalue->u.number.data; elem; elem = elem->next, i++) {
 947        GString *double_expected = g_string_new("");
 948        GString *double_actual = g_string_new("");
 949
 950        g_string_printf(double_expected, "%.6f", (double)i / 3);
 951        g_string_printf(double_actual, "%.6f", elem->value);
 952        g_assert_cmpstr(double_expected->str, ==, double_actual->str);
 953
 954        g_string_free(double_expected, true);
 955        g_string_free(double_actual, true);
 956    }
 957
 958    g_string_free(gstr_union, true);
 959    g_string_free(gstr_list, true);
 960    qapi_free_UserDefListUnion(cvalue);
 961}
 962
 963static void input_visitor_test_add(const char *testpath,
 964                                   const void *user_data,
 965                                   void (*test_func)(TestInputVisitorData *data,
 966                                                     const void *user_data))
 967{
 968    g_test_add(testpath, TestInputVisitorData, user_data, NULL, test_func,
 969               visitor_input_teardown);
 970}
 971
 972static void test_visitor_in_errors(TestInputVisitorData *data,
 973                                   const void *unused)
 974{
 975    TestStruct *p = NULL;
 976    Error *err = NULL;
 977    Visitor *v;
 978    strList *q = NULL;
 979    UserDefTwo *r = NULL;
 980    WrapAlternate *s = NULL;
 981
 982    v = visitor_input_test_init(data, "{ 'integer': false, 'boolean': 'foo', "
 983                                "'string': -42 }");
 984
 985    visit_type_TestStruct(v, NULL, &p, &err);
 986    error_free_or_abort(&err);
 987    g_assert(!p);
 988
 989    v = visitor_input_test_init(data, "[ '1', '2', false, '3' ]");
 990    visit_type_strList(v, NULL, &q, &err);
 991    error_free_or_abort(&err);
 992    assert(!q);
 993
 994    v = visitor_input_test_init(data, "{ 'str':'hi' }");
 995    visit_type_UserDefTwo(v, NULL, &r, &err);
 996    error_free_or_abort(&err);
 997    assert(!r);
 998
 999    v = visitor_input_test_init(data, "{ }");
1000    visit_type_WrapAlternate(v, NULL, &s, &err);
1001    error_free_or_abort(&err);
1002    assert(!s);
1003}
1004
1005static void test_visitor_in_wrong_type(TestInputVisitorData *data,
1006                                       const void *unused)
1007{
1008    TestStruct *p = NULL;
1009    Visitor *v;
1010    strList *q = NULL;
1011    int64_t i;
1012    Error *err = NULL;
1013
1014    /* Make sure arrays and structs cannot be confused */
1015
1016    v = visitor_input_test_init(data, "[]");
1017    visit_type_TestStruct(v, NULL, &p, &err);
1018    error_free_or_abort(&err);
1019    g_assert(!p);
1020
1021    v = visitor_input_test_init(data, "{}");
1022    visit_type_strList(v, NULL, &q, &err);
1023    error_free_or_abort(&err);
1024    assert(!q);
1025
1026    /* Make sure primitives and struct cannot be confused */
1027
1028    v = visitor_input_test_init(data, "1");
1029    visit_type_TestStruct(v, NULL, &p, &err);
1030    error_free_or_abort(&err);
1031    g_assert(!p);
1032
1033    v = visitor_input_test_init(data, "{}");
1034    visit_type_int(v, NULL, &i, &err);
1035    error_free_or_abort(&err);
1036
1037    /* Make sure primitives and arrays cannot be confused */
1038
1039    v = visitor_input_test_init(data, "1");
1040    visit_type_strList(v, NULL, &q, &err);
1041    error_free_or_abort(&err);
1042    assert(!q);
1043
1044    v = visitor_input_test_init(data, "[]");
1045    visit_type_int(v, NULL, &i, &err);
1046    error_free_or_abort(&err);
1047}
1048
1049static void test_visitor_in_fail_struct(TestInputVisitorData *data,
1050                                        const void *unused)
1051{
1052    TestStruct *p = NULL;
1053    Error *err = NULL;
1054    Visitor *v;
1055
1056    v = visitor_input_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo', 'extra': 42 }");
1057
1058    visit_type_TestStruct(v, NULL, &p, &err);
1059    error_free_or_abort(&err);
1060    g_assert(!p);
1061}
1062
1063static void test_visitor_in_fail_struct_nested(TestInputVisitorData *data,
1064                                               const void *unused)
1065{
1066    UserDefTwo *udp = NULL;
1067    Error *err = NULL;
1068    Visitor *v;
1069
1070    v = visitor_input_test_init(data, "{ 'string0': 'string0', 'dict1': { 'string1': 'string1', 'dict2': { 'userdef1': { 'integer': 42, 'string': 'string', 'extra': [42, 23, {'foo':'bar'}] }, 'string2': 'string2'}}}");
1071
1072    visit_type_UserDefTwo(v, NULL, &udp, &err);
1073    error_free_or_abort(&err);
1074    g_assert(!udp);
1075}
1076
1077static void test_visitor_in_fail_struct_in_list(TestInputVisitorData *data,
1078                                                const void *unused)
1079{
1080    UserDefOneList *head = NULL;
1081    Error *err = NULL;
1082    Visitor *v;
1083
1084    v = visitor_input_test_init(data, "[ { 'string': 'string0', 'integer': 42 }, { 'string': 'string1', 'integer': 43 }, { 'string': 'string2', 'integer': 44, 'extra': 'ggg' } ]");
1085
1086    visit_type_UserDefOneList(v, NULL, &head, &err);
1087    error_free_or_abort(&err);
1088    g_assert(!head);
1089}
1090
1091static void test_visitor_in_fail_struct_missing(TestInputVisitorData *data,
1092                                                const void *unused)
1093{
1094    Error *err = NULL;
1095    Visitor *v;
1096    QObject *any;
1097    QNull *null;
1098    GenericAlternate *alt;
1099    bool present;
1100    int en;
1101    int64_t i64;
1102    uint32_t u32;
1103    int8_t i8;
1104    char *str;
1105    double dbl;
1106
1107    v = visitor_input_test_init(data, "{ 'sub': [ {} ] }");
1108    visit_start_struct(v, NULL, NULL, 0, &error_abort);
1109    visit_start_struct(v, "struct", NULL, 0, &err);
1110    error_free_or_abort(&err);
1111    visit_start_list(v, "list", NULL, 0, &err);
1112    error_free_or_abort(&err);
1113    visit_start_alternate(v, "alternate", &alt, sizeof(*alt), &err);
1114    error_free_or_abort(&err);
1115    visit_optional(v, "optional", &present);
1116    g_assert(!present);
1117    visit_type_enum(v, "enum", &en, &EnumOne_lookup, &err);
1118    error_free_or_abort(&err);
1119    visit_type_int(v, "i64", &i64, &err);
1120    error_free_or_abort(&err);
1121    visit_type_uint32(v, "u32", &u32, &err);
1122    error_free_or_abort(&err);
1123    visit_type_int8(v, "i8", &i8, &err);
1124    error_free_or_abort(&err);
1125    visit_type_str(v, "i8", &str, &err);
1126    error_free_or_abort(&err);
1127    visit_type_number(v, "dbl", &dbl, &err);
1128    error_free_or_abort(&err);
1129    visit_type_any(v, "any", &any, &err);
1130    error_free_or_abort(&err);
1131    visit_type_null(v, "null", &null, &err);
1132    error_free_or_abort(&err);
1133    visit_start_list(v, "sub", NULL, 0, &error_abort);
1134    visit_start_struct(v, NULL, NULL, 0, &error_abort);
1135    visit_type_int(v, "i64", &i64, &err);
1136    error_free_or_abort(&err);
1137    visit_end_struct(v, NULL);
1138    visit_end_list(v, NULL);
1139    visit_end_struct(v, NULL);
1140}
1141
1142static void test_visitor_in_fail_list(TestInputVisitorData *data,
1143                                      const void *unused)
1144{
1145    int64_t i64 = -1;
1146    Error *err = NULL;
1147    Visitor *v;
1148
1149    /* Unvisited list tail */
1150
1151    v = visitor_input_test_init(data, "[ 1, 2, 3 ]");
1152
1153    visit_start_list(v, NULL, NULL, 0, &error_abort);
1154    visit_type_int(v, NULL, &i64, &error_abort);
1155    g_assert_cmpint(i64, ==, 1);
1156    visit_type_int(v, NULL, &i64, &error_abort);
1157    g_assert_cmpint(i64, ==, 2);
1158    visit_check_list(v, &err);
1159    error_free_or_abort(&err);
1160    visit_end_list(v, NULL);
1161
1162    /* Visit beyond end of list */
1163    v = visitor_input_test_init(data, "[]");
1164
1165    visit_start_list(v, NULL, NULL, 0, &error_abort);
1166    visit_type_int(v, NULL, &i64, &err);
1167    error_free_or_abort(&err);
1168    visit_end_list(v, NULL);
1169}
1170
1171static void test_visitor_in_fail_list_nested(TestInputVisitorData *data,
1172                                             const void *unused)
1173{
1174    int64_t i64 = -1;
1175    Error *err = NULL;
1176    Visitor *v;
1177
1178    /* Unvisited nested list tail */
1179
1180    v = visitor_input_test_init(data, "[ 0, [ 1, 2, 3 ] ]");
1181
1182    visit_start_list(v, NULL, NULL, 0, &error_abort);
1183    visit_type_int(v, NULL, &i64, &error_abort);
1184    g_assert_cmpint(i64, ==, 0);
1185    visit_start_list(v, NULL, NULL, 0, &error_abort);
1186    visit_type_int(v, NULL, &i64, &error_abort);
1187    g_assert_cmpint(i64, ==, 1);
1188    visit_check_list(v, &err);
1189    error_free_or_abort(&err);
1190    visit_end_list(v, NULL);
1191    visit_check_list(v, &error_abort);
1192    visit_end_list(v, NULL);
1193}
1194
1195static void test_visitor_in_fail_union_list(TestInputVisitorData *data,
1196                                            const void *unused)
1197{
1198    UserDefListUnion *tmp = NULL;
1199    Error *err = NULL;
1200    Visitor *v;
1201
1202    v = visitor_input_test_init(data,
1203                                "{ 'type': 'integer', 'data' : [ 'string' ] }");
1204
1205    visit_type_UserDefListUnion(v, NULL, &tmp, &err);
1206    error_free_or_abort(&err);
1207    g_assert(!tmp);
1208}
1209
1210static void test_visitor_in_fail_union_flat(TestInputVisitorData *data,
1211                                            const void *unused)
1212{
1213    UserDefFlatUnion *tmp = NULL;
1214    Error *err = NULL;
1215    Visitor *v;
1216
1217    v = visitor_input_test_init(data, "{ 'string': 'c', 'integer': 41, 'boolean': true }");
1218
1219    visit_type_UserDefFlatUnion(v, NULL, &tmp, &err);
1220    error_free_or_abort(&err);
1221    g_assert(!tmp);
1222}
1223
1224static void test_visitor_in_fail_union_flat_no_discrim(TestInputVisitorData *data,
1225                                                       const void *unused)
1226{
1227    UserDefFlatUnion2 *tmp = NULL;
1228    Error *err = NULL;
1229    Visitor *v;
1230
1231    /* test situation where discriminator field ('enum1' here) is missing */
1232    v = visitor_input_test_init(data, "{ 'integer': 42, 'string': 'c', 'string1': 'd', 'string2': 'e' }");
1233
1234    visit_type_UserDefFlatUnion2(v, NULL, &tmp, &err);
1235    error_free_or_abort(&err);
1236    g_assert(!tmp);
1237}
1238
1239static void test_visitor_in_fail_alternate(TestInputVisitorData *data,
1240                                           const void *unused)
1241{
1242    UserDefAlternate *tmp;
1243    Visitor *v;
1244    Error *err = NULL;
1245
1246    v = visitor_input_test_init(data, "3.14");
1247
1248    visit_type_UserDefAlternate(v, NULL, &tmp, &err);
1249    error_free_or_abort(&err);
1250    g_assert(!tmp);
1251}
1252
1253static void do_test_visitor_in_qmp_introspect(TestInputVisitorData *data,
1254                                              const QLitObject *qlit)
1255{
1256    SchemaInfoList *schema = NULL;
1257    QObject *obj = qobject_from_qlit(qlit);
1258    Visitor *v;
1259
1260    v = qobject_input_visitor_new(obj);
1261
1262    visit_type_SchemaInfoList(v, NULL, &schema, &error_abort);
1263    g_assert(schema);
1264
1265    qapi_free_SchemaInfoList(schema);
1266    qobject_unref(obj);
1267    visit_free(v);
1268}
1269
1270static void test_visitor_in_qmp_introspect(TestInputVisitorData *data,
1271                                           const void *unused)
1272{
1273    do_test_visitor_in_qmp_introspect(data, &test_qmp_schema_qlit);
1274}
1275
1276int main(int argc, char **argv)
1277{
1278    g_test_init(&argc, &argv, NULL);
1279
1280    input_visitor_test_add("/visitor/input/int",
1281                           NULL, test_visitor_in_int);
1282    input_visitor_test_add("/visitor/input/uint",
1283                           NULL, test_visitor_in_uint);
1284    input_visitor_test_add("/visitor/input/int_overflow",
1285                           NULL, test_visitor_in_int_overflow);
1286    input_visitor_test_add("/visitor/input/int_keyval",
1287                           NULL, test_visitor_in_int_keyval);
1288    input_visitor_test_add("/visitor/input/int_str_keyval",
1289                           NULL, test_visitor_in_int_str_keyval);
1290    input_visitor_test_add("/visitor/input/int_str_fail",
1291                           NULL, test_visitor_in_int_str_fail);
1292    input_visitor_test_add("/visitor/input/bool",
1293                           NULL, test_visitor_in_bool);
1294    input_visitor_test_add("/visitor/input/bool_keyval",
1295                           NULL, test_visitor_in_bool_keyval);
1296    input_visitor_test_add("/visitor/input/bool_str_keyval",
1297                           NULL, test_visitor_in_bool_str_keyval);
1298    input_visitor_test_add("/visitor/input/bool_str_fail",
1299                           NULL, test_visitor_in_bool_str_fail);
1300    input_visitor_test_add("/visitor/input/number",
1301                           NULL, test_visitor_in_number);
1302    input_visitor_test_add("/visitor/input/large_number",
1303                           NULL, test_visitor_in_large_number);
1304    input_visitor_test_add("/visitor/input/number_keyval",
1305                           NULL, test_visitor_in_number_keyval);
1306    input_visitor_test_add("/visitor/input/number_str_keyval",
1307                           NULL, test_visitor_in_number_str_keyval);
1308    input_visitor_test_add("/visitor/input/number_str_fail",
1309                           NULL, test_visitor_in_number_str_fail);
1310    input_visitor_test_add("/visitor/input/size_str_keyval",
1311                           NULL, test_visitor_in_size_str_keyval);
1312    input_visitor_test_add("/visitor/input/size_str_fail",
1313                           NULL, test_visitor_in_size_str_fail);
1314    input_visitor_test_add("/visitor/input/string",
1315                           NULL, test_visitor_in_string);
1316    input_visitor_test_add("/visitor/input/enum",
1317                           NULL, test_visitor_in_enum);
1318    input_visitor_test_add("/visitor/input/struct",
1319                           NULL, test_visitor_in_struct);
1320    input_visitor_test_add("/visitor/input/struct-nested",
1321                           NULL, test_visitor_in_struct_nested);
1322    input_visitor_test_add("/visitor/input/list",
1323                           NULL, test_visitor_in_list);
1324    input_visitor_test_add("/visitor/input/any",
1325                           NULL, test_visitor_in_any);
1326    input_visitor_test_add("/visitor/input/null",
1327                           NULL, test_visitor_in_null);
1328    input_visitor_test_add("/visitor/input/union-flat",
1329                           NULL, test_visitor_in_union_flat);
1330    input_visitor_test_add("/visitor/input/alternate",
1331                           NULL, test_visitor_in_alternate);
1332    input_visitor_test_add("/visitor/input/errors",
1333                           NULL, test_visitor_in_errors);
1334    input_visitor_test_add("/visitor/input/wrong-type",
1335                           NULL, test_visitor_in_wrong_type);
1336    input_visitor_test_add("/visitor/input/alternate-number",
1337                           NULL, test_visitor_in_alternate_number);
1338    input_visitor_test_add("/visitor/input/list_union/int",
1339                           NULL, test_visitor_in_list_union_int);
1340    input_visitor_test_add("/visitor/input/list_union/int8",
1341                           NULL, test_visitor_in_list_union_int8);
1342    input_visitor_test_add("/visitor/input/list_union/int16",
1343                           NULL, test_visitor_in_list_union_int16);
1344    input_visitor_test_add("/visitor/input/list_union/int32",
1345                           NULL, test_visitor_in_list_union_int32);
1346    input_visitor_test_add("/visitor/input/list_union/int64",
1347                           NULL, test_visitor_in_list_union_int64);
1348    input_visitor_test_add("/visitor/input/list_union/uint8",
1349                           NULL, test_visitor_in_list_union_uint8);
1350    input_visitor_test_add("/visitor/input/list_union/uint16",
1351                           NULL, test_visitor_in_list_union_uint16);
1352    input_visitor_test_add("/visitor/input/list_union/uint32",
1353                           NULL, test_visitor_in_list_union_uint32);
1354    input_visitor_test_add("/visitor/input/list_union/uint64",
1355                           NULL, test_visitor_in_list_union_uint64);
1356    input_visitor_test_add("/visitor/input/list_union/bool",
1357                           NULL, test_visitor_in_list_union_bool);
1358    input_visitor_test_add("/visitor/input/list_union/str",
1359                           NULL, test_visitor_in_list_union_string);
1360    input_visitor_test_add("/visitor/input/list_union/number",
1361                           NULL, test_visitor_in_list_union_number);
1362    input_visitor_test_add("/visitor/input/fail/struct",
1363                           NULL, test_visitor_in_fail_struct);
1364    input_visitor_test_add("/visitor/input/fail/struct-nested",
1365                           NULL, test_visitor_in_fail_struct_nested);
1366    input_visitor_test_add("/visitor/input/fail/struct-in-list",
1367                           NULL, test_visitor_in_fail_struct_in_list);
1368    input_visitor_test_add("/visitor/input/fail/struct-missing",
1369                           NULL, test_visitor_in_fail_struct_missing);
1370    input_visitor_test_add("/visitor/input/fail/list",
1371                           NULL, test_visitor_in_fail_list);
1372    input_visitor_test_add("/visitor/input/fail/list-nested",
1373                           NULL, test_visitor_in_fail_list_nested);
1374    input_visitor_test_add("/visitor/input/fail/union-flat",
1375                           NULL, test_visitor_in_fail_union_flat);
1376    input_visitor_test_add("/visitor/input/fail/union-flat-no-discriminator",
1377                           NULL, test_visitor_in_fail_union_flat_no_discrim);
1378    input_visitor_test_add("/visitor/input/fail/alternate",
1379                           NULL, test_visitor_in_fail_alternate);
1380    input_visitor_test_add("/visitor/input/fail/union-list",
1381                           NULL, test_visitor_in_fail_union_list);
1382    input_visitor_test_add("/visitor/input/qapi-introspect",
1383                           NULL, test_visitor_in_qmp_introspect);
1384
1385    g_test_run();
1386
1387    return 0;
1388}
1389