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