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