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