qemu/tests/test-qobject-output-visitor.c
<<
>>
Prefs
   1/*
   2 * QObject Output Visitor unit-tests.
   3 *
   4 * Copyright (C) 2011-2016 Red Hat Inc.
   5 *
   6 * Authors:
   7 *  Luiz Capitulino <lcapitulino@redhat.com>
   8 *
   9 * This work is licensed under the terms of the GNU GPL, version 2 or later.
  10 * See the COPYING file in the top-level directory.
  11 */
  12
  13#include "qemu/osdep.h"
  14
  15#include "qemu-common.h"
  16#include "qapi/error.h"
  17#include "qapi/qobject-output-visitor.h"
  18#include "test-qapi-types.h"
  19#include "test-qapi-visit.h"
  20#include "qapi/qmp/types.h"
  21#include "qapi/qmp/qjson.h"
  22
  23typedef struct TestOutputVisitorData {
  24    Visitor *ov;
  25    QObject *obj;
  26} TestOutputVisitorData;
  27
  28static void visitor_output_setup(TestOutputVisitorData *data,
  29                                 const void *unused)
  30{
  31    data->ov = qobject_output_visitor_new(&data->obj);
  32    g_assert(data->ov);
  33}
  34
  35static void visitor_output_teardown(TestOutputVisitorData *data,
  36                                    const void *unused)
  37{
  38    visit_free(data->ov);
  39    data->ov = NULL;
  40    qobject_decref(data->obj);
  41    data->obj = NULL;
  42}
  43
  44static QObject *visitor_get(TestOutputVisitorData *data)
  45{
  46    visit_complete(data->ov, &data->obj);
  47    g_assert(data->obj);
  48    return data->obj;
  49}
  50
  51static void visitor_reset(TestOutputVisitorData *data)
  52{
  53    visitor_output_teardown(data, NULL);
  54    visitor_output_setup(data, NULL);
  55}
  56
  57static void test_visitor_out_int(TestOutputVisitorData *data,
  58                                 const void *unused)
  59{
  60    int64_t value = -42;
  61    int64_t val;
  62    QNum *qnum;
  63
  64    visit_type_int(data->ov, NULL, &value, &error_abort);
  65
  66    qnum = qobject_to_qnum(visitor_get(data));
  67    g_assert(qnum);
  68    g_assert(qnum_get_try_int(qnum, &val));
  69    g_assert_cmpint(val, ==, value);
  70}
  71
  72static void test_visitor_out_bool(TestOutputVisitorData *data,
  73                                  const void *unused)
  74{
  75    bool value = true;
  76    QBool *qbool;
  77
  78    visit_type_bool(data->ov, NULL, &value, &error_abort);
  79
  80    qbool = qobject_to_qbool(visitor_get(data));
  81    g_assert(qbool);
  82    g_assert(qbool_get_bool(qbool) == value);
  83}
  84
  85static void test_visitor_out_number(TestOutputVisitorData *data,
  86                                    const void *unused)
  87{
  88    double value = 3.14;
  89    QNum *qnum;
  90
  91    visit_type_number(data->ov, NULL, &value, &error_abort);
  92
  93    qnum = qobject_to_qnum(visitor_get(data));
  94    g_assert(qnum);
  95    g_assert(qnum_get_double(qnum) == value);
  96}
  97
  98static void test_visitor_out_string(TestOutputVisitorData *data,
  99                                    const void *unused)
 100{
 101    char *string = (char *) "Q E M U";
 102    QString *qstr;
 103
 104    visit_type_str(data->ov, NULL, &string, &error_abort);
 105
 106    qstr = qobject_to_qstring(visitor_get(data));
 107    g_assert(qstr);
 108    g_assert_cmpstr(qstring_get_str(qstr), ==, string);
 109}
 110
 111static void test_visitor_out_no_string(TestOutputVisitorData *data,
 112                                       const void *unused)
 113{
 114    char *string = NULL;
 115    QString *qstr;
 116
 117    /* A null string should return "" */
 118    visit_type_str(data->ov, NULL, &string, &error_abort);
 119
 120    qstr = qobject_to_qstring(visitor_get(data));
 121    g_assert(qstr);
 122    g_assert_cmpstr(qstring_get_str(qstr), ==, "");
 123}
 124
 125static void test_visitor_out_enum(TestOutputVisitorData *data,
 126                                  const void *unused)
 127{
 128    EnumOne i;
 129    QString *qstr;
 130
 131    for (i = 0; i < ENUM_ONE__MAX; i++) {
 132        visit_type_EnumOne(data->ov, "unused", &i, &error_abort);
 133
 134        qstr = qobject_to_qstring(visitor_get(data));
 135        g_assert(qstr);
 136        g_assert_cmpstr(qstring_get_str(qstr), ==, EnumOne_lookup[i]);
 137        visitor_reset(data);
 138    }
 139}
 140
 141static void test_visitor_out_enum_errors(TestOutputVisitorData *data,
 142                                         const void *unused)
 143{
 144    EnumOne i, bad_values[] = { ENUM_ONE__MAX, -1 };
 145    Error *err;
 146
 147    for (i = 0; i < ARRAY_SIZE(bad_values) ; i++) {
 148        err = NULL;
 149        visit_type_EnumOne(data->ov, "unused", &bad_values[i], &err);
 150        error_free_or_abort(&err);
 151        visitor_reset(data);
 152    }
 153}
 154
 155
 156static void test_visitor_out_struct(TestOutputVisitorData *data,
 157                                    const void *unused)
 158{
 159    TestStruct test_struct = { .integer = 42,
 160                               .boolean = false,
 161                               .string = (char *) "foo"};
 162    TestStruct *p = &test_struct;
 163    QDict *qdict;
 164
 165    visit_type_TestStruct(data->ov, NULL, &p, &error_abort);
 166
 167    qdict = qobject_to_qdict(visitor_get(data));
 168    g_assert(qdict);
 169    g_assert_cmpint(qdict_size(qdict), ==, 3);
 170    g_assert_cmpint(qdict_get_int(qdict, "integer"), ==, 42);
 171    g_assert_cmpint(qdict_get_bool(qdict, "boolean"), ==, false);
 172    g_assert_cmpstr(qdict_get_str(qdict, "string"), ==, "foo");
 173}
 174
 175static void test_visitor_out_struct_nested(TestOutputVisitorData *data,
 176                                           const void *unused)
 177{
 178    int64_t value = 42;
 179    UserDefTwo *ud2;
 180    QDict *qdict, *dict1, *dict2, *dict3, *userdef;
 181    const char *string = "user def string";
 182    const char *strings[] = { "forty two", "forty three", "forty four",
 183                              "forty five" };
 184
 185    ud2 = g_malloc0(sizeof(*ud2));
 186    ud2->string0 = g_strdup(strings[0]);
 187
 188    ud2->dict1 = g_malloc0(sizeof(*ud2->dict1));
 189    ud2->dict1->string1 = g_strdup(strings[1]);
 190
 191    ud2->dict1->dict2 = g_malloc0(sizeof(*ud2->dict1->dict2));
 192    ud2->dict1->dict2->userdef = g_new0(UserDefOne, 1);
 193    ud2->dict1->dict2->userdef->string = g_strdup(string);
 194    ud2->dict1->dict2->userdef->integer = value;
 195    ud2->dict1->dict2->string = g_strdup(strings[2]);
 196
 197    ud2->dict1->dict3 = g_malloc0(sizeof(*ud2->dict1->dict3));
 198    ud2->dict1->has_dict3 = true;
 199    ud2->dict1->dict3->userdef = g_new0(UserDefOne, 1);
 200    ud2->dict1->dict3->userdef->string = g_strdup(string);
 201    ud2->dict1->dict3->userdef->integer = value;
 202    ud2->dict1->dict3->string = g_strdup(strings[3]);
 203
 204    visit_type_UserDefTwo(data->ov, "unused", &ud2, &error_abort);
 205
 206    qdict = qobject_to_qdict(visitor_get(data));
 207    g_assert(qdict);
 208    g_assert_cmpint(qdict_size(qdict), ==, 2);
 209    g_assert_cmpstr(qdict_get_str(qdict, "string0"), ==, strings[0]);
 210
 211    dict1 = qdict_get_qdict(qdict, "dict1");
 212    g_assert_cmpint(qdict_size(dict1), ==, 3);
 213    g_assert_cmpstr(qdict_get_str(dict1, "string1"), ==, strings[1]);
 214
 215    dict2 = qdict_get_qdict(dict1, "dict2");
 216    g_assert_cmpint(qdict_size(dict2), ==, 2);
 217    g_assert_cmpstr(qdict_get_str(dict2, "string"), ==, strings[2]);
 218    userdef = qdict_get_qdict(dict2, "userdef");
 219    g_assert_cmpint(qdict_size(userdef), ==, 2);
 220    g_assert_cmpint(qdict_get_int(userdef, "integer"), ==, value);
 221    g_assert_cmpstr(qdict_get_str(userdef, "string"), ==, string);
 222
 223    dict3 = qdict_get_qdict(dict1, "dict3");
 224    g_assert_cmpint(qdict_size(dict3), ==, 2);
 225    g_assert_cmpstr(qdict_get_str(dict3, "string"), ==, strings[3]);
 226    userdef = qdict_get_qdict(dict3, "userdef");
 227    g_assert_cmpint(qdict_size(userdef), ==, 2);
 228    g_assert_cmpint(qdict_get_int(userdef, "integer"), ==, value);
 229    g_assert_cmpstr(qdict_get_str(userdef, "string"), ==, string);
 230
 231    qapi_free_UserDefTwo(ud2);
 232}
 233
 234static void test_visitor_out_struct_errors(TestOutputVisitorData *data,
 235                                           const void *unused)
 236{
 237    EnumOne bad_values[] = { ENUM_ONE__MAX, -1 };
 238    UserDefOne u = {0};
 239    UserDefOne *pu = &u;
 240    Error *err;
 241    int i;
 242
 243    for (i = 0; i < ARRAY_SIZE(bad_values) ; i++) {
 244        err = NULL;
 245        u.has_enum1 = true;
 246        u.enum1 = bad_values[i];
 247        visit_type_UserDefOne(data->ov, "unused", &pu, &err);
 248        error_free_or_abort(&err);
 249        visitor_reset(data);
 250    }
 251}
 252
 253
 254static void test_visitor_out_list(TestOutputVisitorData *data,
 255                                  const void *unused)
 256{
 257    const char *value_str = "list value";
 258    TestStructList *p, *head = NULL;
 259    const int max_items = 10;
 260    bool value_bool = true;
 261    int value_int = 10;
 262    QListEntry *entry;
 263    QList *qlist;
 264    int i;
 265
 266    /* Build the list in reverse order... */
 267    for (i = 0; i < max_items; i++) {
 268        p = g_malloc0(sizeof(*p));
 269        p->value = g_malloc0(sizeof(*p->value));
 270        p->value->integer = value_int + (max_items - i - 1);
 271        p->value->boolean = value_bool;
 272        p->value->string = g_strdup(value_str);
 273
 274        p->next = head;
 275        head = p;
 276    }
 277
 278    visit_type_TestStructList(data->ov, NULL, &head, &error_abort);
 279
 280    qlist = qobject_to_qlist(visitor_get(data));
 281    g_assert(qlist);
 282    g_assert(!qlist_empty(qlist));
 283
 284    /* ...and ensure that the visitor sees it in order */
 285    i = 0;
 286    QLIST_FOREACH_ENTRY(qlist, entry) {
 287        QDict *qdict;
 288
 289        qdict = qobject_to_qdict(entry->value);
 290        g_assert(qdict);
 291        g_assert_cmpint(qdict_size(qdict), ==, 3);
 292        g_assert_cmpint(qdict_get_int(qdict, "integer"), ==, value_int + i);
 293        g_assert_cmpint(qdict_get_bool(qdict, "boolean"), ==, value_bool);
 294        g_assert_cmpstr(qdict_get_str(qdict, "string"), ==, value_str);
 295        i++;
 296    }
 297    g_assert_cmpint(i, ==, max_items);
 298
 299    qapi_free_TestStructList(head);
 300}
 301
 302static void test_visitor_out_list_qapi_free(TestOutputVisitorData *data,
 303                                            const void *unused)
 304{
 305    UserDefTwoList *p, *head = NULL;
 306    const char string[] = "foo bar";
 307    int i, max_count = 1024;
 308
 309    for (i = 0; i < max_count; i++) {
 310        p = g_malloc0(sizeof(*p));
 311        p->value = g_malloc0(sizeof(*p->value));
 312
 313        p->value->string0 = g_strdup(string);
 314        p->value->dict1 = g_new0(UserDefTwoDict, 1);
 315        p->value->dict1->string1 = g_strdup(string);
 316        p->value->dict1->dict2 = g_new0(UserDefTwoDictDict, 1);
 317        p->value->dict1->dict2->userdef = g_new0(UserDefOne, 1);
 318        p->value->dict1->dict2->userdef->string = g_strdup(string);
 319        p->value->dict1->dict2->userdef->integer = 42;
 320        p->value->dict1->dict2->string = g_strdup(string);
 321        p->value->dict1->has_dict3 = false;
 322
 323        p->next = head;
 324        head = p;
 325    }
 326
 327    qapi_free_UserDefTwoList(head);
 328}
 329
 330static void test_visitor_out_any(TestOutputVisitorData *data,
 331                                 const void *unused)
 332{
 333    QObject *qobj;
 334    QNum *qnum;
 335    QBool *qbool;
 336    QString *qstring;
 337    QDict *qdict;
 338    int64_t val;
 339
 340    qobj = QOBJECT(qnum_from_int(-42));
 341    visit_type_any(data->ov, NULL, &qobj, &error_abort);
 342    qnum = qobject_to_qnum(visitor_get(data));
 343    g_assert(qnum);
 344    g_assert(qnum_get_try_int(qnum, &val));
 345    g_assert_cmpint(val, ==, -42);
 346    qobject_decref(qobj);
 347
 348    visitor_reset(data);
 349    qdict = qdict_new();
 350    qdict_put_int(qdict, "integer", -42);
 351    qdict_put_bool(qdict, "boolean", true);
 352    qdict_put_str(qdict, "string", "foo");
 353    qobj = QOBJECT(qdict);
 354    visit_type_any(data->ov, NULL, &qobj, &error_abort);
 355    qobject_decref(qobj);
 356    qdict = qobject_to_qdict(visitor_get(data));
 357    g_assert(qdict);
 358    qnum = qobject_to_qnum(qdict_get(qdict, "integer"));
 359    g_assert(qnum);
 360    g_assert(qnum_get_try_int(qnum, &val));
 361    g_assert_cmpint(val, ==, -42);
 362    qbool = qobject_to_qbool(qdict_get(qdict, "boolean"));
 363    g_assert(qbool);
 364    g_assert(qbool_get_bool(qbool) == true);
 365    qstring = qobject_to_qstring(qdict_get(qdict, "string"));
 366    g_assert(qstring);
 367    g_assert_cmpstr(qstring_get_str(qstring), ==, "foo");
 368}
 369
 370static void test_visitor_out_union_flat(TestOutputVisitorData *data,
 371                                        const void *unused)
 372{
 373    QDict *qdict;
 374
 375    UserDefFlatUnion *tmp = g_malloc0(sizeof(UserDefFlatUnion));
 376    tmp->enum1 = ENUM_ONE_VALUE1;
 377    tmp->string = g_strdup("str");
 378    tmp->integer = 41;
 379    tmp->u.value1.boolean = true;
 380
 381    visit_type_UserDefFlatUnion(data->ov, NULL, &tmp, &error_abort);
 382    qdict = qobject_to_qdict(visitor_get(data));
 383    g_assert(qdict);
 384    g_assert_cmpstr(qdict_get_str(qdict, "enum1"), ==, "value1");
 385    g_assert_cmpstr(qdict_get_str(qdict, "string"), ==, "str");
 386    g_assert_cmpint(qdict_get_int(qdict, "integer"), ==, 41);
 387    g_assert_cmpint(qdict_get_bool(qdict, "boolean"), ==, true);
 388
 389    qapi_free_UserDefFlatUnion(tmp);
 390}
 391
 392static void test_visitor_out_alternate(TestOutputVisitorData *data,
 393                                       const void *unused)
 394{
 395    UserDefAlternate *tmp;
 396    QNum *qnum;
 397    QString *qstr;
 398    QDict *qdict;
 399    int64_t val;
 400
 401    tmp = g_new0(UserDefAlternate, 1);
 402    tmp->type = QTYPE_QNUM;
 403    tmp->u.i = 42;
 404
 405    visit_type_UserDefAlternate(data->ov, NULL, &tmp, &error_abort);
 406    qnum = qobject_to_qnum(visitor_get(data));
 407    g_assert(qnum);
 408    g_assert(qnum_get_try_int(qnum, &val));
 409    g_assert_cmpint(val, ==, 42);
 410
 411    qapi_free_UserDefAlternate(tmp);
 412
 413    visitor_reset(data);
 414    tmp = g_new0(UserDefAlternate, 1);
 415    tmp->type = QTYPE_QSTRING;
 416    tmp->u.e = ENUM_ONE_VALUE1;
 417
 418    visit_type_UserDefAlternate(data->ov, NULL, &tmp, &error_abort);
 419    qstr = qobject_to_qstring(visitor_get(data));
 420    g_assert(qstr);
 421    g_assert_cmpstr(qstring_get_str(qstr), ==, "value1");
 422
 423    qapi_free_UserDefAlternate(tmp);
 424
 425    visitor_reset(data);
 426    tmp = g_new0(UserDefAlternate, 1);
 427    tmp->type = QTYPE_QNULL;
 428    tmp->u.n = qnull();
 429
 430    visit_type_UserDefAlternate(data->ov, NULL, &tmp, &error_abort);
 431    g_assert_cmpint(qobject_type(visitor_get(data)), ==, QTYPE_QNULL);
 432
 433    qapi_free_UserDefAlternate(tmp);
 434
 435    visitor_reset(data);
 436    tmp = g_new0(UserDefAlternate, 1);
 437    tmp->type = QTYPE_QDICT;
 438    tmp->u.udfu.integer = 1;
 439    tmp->u.udfu.string = g_strdup("str");
 440    tmp->u.udfu.enum1 = ENUM_ONE_VALUE1;
 441    tmp->u.udfu.u.value1.boolean = true;
 442
 443    visit_type_UserDefAlternate(data->ov, NULL, &tmp, &error_abort);
 444    qdict = qobject_to_qdict(visitor_get(data));
 445    g_assert(qdict);
 446    g_assert_cmpint(qdict_size(qdict), ==, 4);
 447    g_assert_cmpint(qdict_get_int(qdict, "integer"), ==, 1);
 448    g_assert_cmpstr(qdict_get_str(qdict, "string"), ==, "str");
 449    g_assert_cmpstr(qdict_get_str(qdict, "enum1"), ==, "value1");
 450    g_assert_cmpint(qdict_get_bool(qdict, "boolean"), ==, true);
 451
 452    qapi_free_UserDefAlternate(tmp);
 453}
 454
 455static void test_visitor_out_null(TestOutputVisitorData *data,
 456                                  const void *unused)
 457{
 458    QNull *null = NULL;
 459    QDict *qdict;
 460    QObject *nil;
 461
 462    visit_start_struct(data->ov, NULL, NULL, 0, &error_abort);
 463    visit_type_null(data->ov, "a", &null, &error_abort);
 464    visit_check_struct(data->ov, &error_abort);
 465    visit_end_struct(data->ov, NULL);
 466    qdict = qobject_to_qdict(visitor_get(data));
 467    g_assert(qdict);
 468    g_assert_cmpint(qdict_size(qdict), ==, 1);
 469    nil = qdict_get(qdict, "a");
 470    g_assert(nil);
 471    g_assert(qobject_type(nil) == QTYPE_QNULL);
 472}
 473
 474static void init_native_list(UserDefNativeListUnion *cvalue)
 475{
 476    int i;
 477    switch (cvalue->type) {
 478    case USER_DEF_NATIVE_LIST_UNION_KIND_INTEGER: {
 479        intList **list = &cvalue->u.integer.data;
 480        for (i = 0; i < 32; i++) {
 481            *list = g_new0(intList, 1);
 482            (*list)->value = i;
 483            (*list)->next = NULL;
 484            list = &(*list)->next;
 485        }
 486        break;
 487    }
 488    case USER_DEF_NATIVE_LIST_UNION_KIND_S8: {
 489        int8List **list = &cvalue->u.s8.data;
 490        for (i = 0; i < 32; i++) {
 491            *list = g_new0(int8List, 1);
 492            (*list)->value = i;
 493            (*list)->next = NULL;
 494            list = &(*list)->next;
 495        }
 496        break;
 497    }
 498    case USER_DEF_NATIVE_LIST_UNION_KIND_S16: {
 499        int16List **list = &cvalue->u.s16.data;
 500        for (i = 0; i < 32; i++) {
 501            *list = g_new0(int16List, 1);
 502            (*list)->value = i;
 503            (*list)->next = NULL;
 504            list = &(*list)->next;
 505        }
 506        break;
 507    }
 508    case USER_DEF_NATIVE_LIST_UNION_KIND_S32: {
 509        int32List **list = &cvalue->u.s32.data;
 510        for (i = 0; i < 32; i++) {
 511            *list = g_new0(int32List, 1);
 512            (*list)->value = i;
 513            (*list)->next = NULL;
 514            list = &(*list)->next;
 515        }
 516        break;
 517    }
 518    case USER_DEF_NATIVE_LIST_UNION_KIND_S64: {
 519        int64List **list = &cvalue->u.s64.data;
 520        for (i = 0; i < 32; i++) {
 521            *list = g_new0(int64List, 1);
 522            (*list)->value = i;
 523            (*list)->next = NULL;
 524            list = &(*list)->next;
 525        }
 526        break;
 527    }
 528    case USER_DEF_NATIVE_LIST_UNION_KIND_U8: {
 529        uint8List **list = &cvalue->u.u8.data;
 530        for (i = 0; i < 32; i++) {
 531            *list = g_new0(uint8List, 1);
 532            (*list)->value = i;
 533            (*list)->next = NULL;
 534            list = &(*list)->next;
 535        }
 536        break;
 537    }
 538    case USER_DEF_NATIVE_LIST_UNION_KIND_U16: {
 539        uint16List **list = &cvalue->u.u16.data;
 540        for (i = 0; i < 32; i++) {
 541            *list = g_new0(uint16List, 1);
 542            (*list)->value = i;
 543            (*list)->next = NULL;
 544            list = &(*list)->next;
 545        }
 546        break;
 547    }
 548    case USER_DEF_NATIVE_LIST_UNION_KIND_U32: {
 549        uint32List **list = &cvalue->u.u32.data;
 550        for (i = 0; i < 32; i++) {
 551            *list = g_new0(uint32List, 1);
 552            (*list)->value = i;
 553            (*list)->next = NULL;
 554            list = &(*list)->next;
 555        }
 556        break;
 557    }
 558    case USER_DEF_NATIVE_LIST_UNION_KIND_U64: {
 559        uint64List **list = &cvalue->u.u64.data;
 560        for (i = 0; i < 32; i++) {
 561            *list = g_new0(uint64List, 1);
 562            (*list)->value = i;
 563            (*list)->next = NULL;
 564            list = &(*list)->next;
 565        }
 566        break;
 567    }
 568    case USER_DEF_NATIVE_LIST_UNION_KIND_BOOLEAN: {
 569        boolList **list = &cvalue->u.boolean.data;
 570        for (i = 0; i < 32; i++) {
 571            *list = g_new0(boolList, 1);
 572            (*list)->value = (i % 3 == 0);
 573            (*list)->next = NULL;
 574            list = &(*list)->next;
 575        }
 576        break;
 577    }
 578    case USER_DEF_NATIVE_LIST_UNION_KIND_STRING: {
 579        strList **list = &cvalue->u.string.data;
 580        for (i = 0; i < 32; i++) {
 581            *list = g_new0(strList, 1);
 582            (*list)->value = g_strdup_printf("%d", i);
 583            (*list)->next = NULL;
 584            list = &(*list)->next;
 585        }
 586        break;
 587    }
 588    case USER_DEF_NATIVE_LIST_UNION_KIND_NUMBER: {
 589        numberList **list = &cvalue->u.number.data;
 590        for (i = 0; i < 32; i++) {
 591            *list = g_new0(numberList, 1);
 592            (*list)->value = (double)i / 3;
 593            (*list)->next = NULL;
 594            list = &(*list)->next;
 595        }
 596        break;
 597    }
 598    default:
 599        g_assert_not_reached();
 600    }
 601}
 602
 603static void check_native_list(QObject *qobj,
 604                              UserDefNativeListUnionKind kind)
 605{
 606    QDict *qdict;
 607    QList *qlist;
 608    int i;
 609
 610    qdict = qobject_to_qdict(qobj);
 611    g_assert(qdict);
 612    g_assert(qdict_haskey(qdict, "data"));
 613    qlist = qlist_copy(qobject_to_qlist(qdict_get(qdict, "data")));
 614
 615    switch (kind) {
 616    case USER_DEF_NATIVE_LIST_UNION_KIND_U8:
 617    case USER_DEF_NATIVE_LIST_UNION_KIND_U16:
 618    case USER_DEF_NATIVE_LIST_UNION_KIND_U32:
 619    case USER_DEF_NATIVE_LIST_UNION_KIND_U64:
 620        for (i = 0; i < 32; i++) {
 621            QObject *tmp;
 622            QNum *qvalue;
 623            uint64_t val;
 624
 625            tmp = qlist_peek(qlist);
 626            g_assert(tmp);
 627            qvalue = qobject_to_qnum(tmp);
 628            g_assert(qnum_get_try_uint(qvalue, &val));
 629            g_assert_cmpint(val, ==, i);
 630            qobject_decref(qlist_pop(qlist));
 631        }
 632        break;
 633
 634    case USER_DEF_NATIVE_LIST_UNION_KIND_S8:
 635    case USER_DEF_NATIVE_LIST_UNION_KIND_S16:
 636    case USER_DEF_NATIVE_LIST_UNION_KIND_S32:
 637    case USER_DEF_NATIVE_LIST_UNION_KIND_S64:
 638        /*
 639         * All integer elements in JSON arrays get stored into QNums
 640         * when we convert to QObjects, so we can check them all in
 641         * the same fashion, so simply fall through here.
 642         */
 643    case USER_DEF_NATIVE_LIST_UNION_KIND_INTEGER:
 644        for (i = 0; i < 32; i++) {
 645            QObject *tmp;
 646            QNum *qvalue;
 647            int64_t val;
 648
 649            tmp = qlist_peek(qlist);
 650            g_assert(tmp);
 651            qvalue = qobject_to_qnum(tmp);
 652            g_assert(qnum_get_try_int(qvalue, &val));
 653            g_assert_cmpint(val, ==, i);
 654            qobject_decref(qlist_pop(qlist));
 655        }
 656        break;
 657    case USER_DEF_NATIVE_LIST_UNION_KIND_BOOLEAN:
 658        for (i = 0; i < 32; i++) {
 659            QObject *tmp;
 660            QBool *qvalue;
 661            tmp = qlist_peek(qlist);
 662            g_assert(tmp);
 663            qvalue = qobject_to_qbool(tmp);
 664            g_assert_cmpint(qbool_get_bool(qvalue), ==, i % 3 == 0);
 665            qobject_decref(qlist_pop(qlist));
 666        }
 667        break;
 668    case USER_DEF_NATIVE_LIST_UNION_KIND_STRING:
 669        for (i = 0; i < 32; i++) {
 670            QObject *tmp;
 671            QString *qvalue;
 672            gchar str[8];
 673            tmp = qlist_peek(qlist);
 674            g_assert(tmp);
 675            qvalue = qobject_to_qstring(tmp);
 676            sprintf(str, "%d", i);
 677            g_assert_cmpstr(qstring_get_str(qvalue), ==, str);
 678            qobject_decref(qlist_pop(qlist));
 679        }
 680        break;
 681    case USER_DEF_NATIVE_LIST_UNION_KIND_NUMBER:
 682        for (i = 0; i < 32; i++) {
 683            QObject *tmp;
 684            QNum *qvalue;
 685            GString *double_expected = g_string_new("");
 686            GString *double_actual = g_string_new("");
 687
 688            tmp = qlist_peek(qlist);
 689            g_assert(tmp);
 690            qvalue = qobject_to_qnum(tmp);
 691            g_string_printf(double_expected, "%.6f", (double)i / 3);
 692            g_string_printf(double_actual, "%.6f", qnum_get_double(qvalue));
 693            g_assert_cmpstr(double_actual->str, ==, double_expected->str);
 694
 695            qobject_decref(qlist_pop(qlist));
 696            g_string_free(double_expected, true);
 697            g_string_free(double_actual, true);
 698        }
 699        break;
 700    default:
 701        g_assert_not_reached();
 702    }
 703    QDECREF(qlist);
 704}
 705
 706static void test_native_list(TestOutputVisitorData *data,
 707                             const void *unused,
 708                             UserDefNativeListUnionKind kind)
 709{
 710    UserDefNativeListUnion *cvalue = g_new0(UserDefNativeListUnion, 1);
 711    QObject *obj;
 712
 713    cvalue->type = kind;
 714    init_native_list(cvalue);
 715
 716    visit_type_UserDefNativeListUnion(data->ov, NULL, &cvalue, &error_abort);
 717
 718    obj = visitor_get(data);
 719    check_native_list(obj, cvalue->type);
 720    qapi_free_UserDefNativeListUnion(cvalue);
 721}
 722
 723static void test_visitor_out_native_list_int(TestOutputVisitorData *data,
 724                                             const void *unused)
 725{
 726    test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_INTEGER);
 727}
 728
 729static void test_visitor_out_native_list_int8(TestOutputVisitorData *data,
 730                                              const void *unused)
 731{
 732    test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_S8);
 733}
 734
 735static void test_visitor_out_native_list_int16(TestOutputVisitorData *data,
 736                                               const void *unused)
 737{
 738    test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_S16);
 739}
 740
 741static void test_visitor_out_native_list_int32(TestOutputVisitorData *data,
 742                                               const void *unused)
 743{
 744    test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_S32);
 745}
 746
 747static void test_visitor_out_native_list_int64(TestOutputVisitorData *data,
 748                                               const void *unused)
 749{
 750    test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_S64);
 751}
 752
 753static void test_visitor_out_native_list_uint8(TestOutputVisitorData *data,
 754                                               const void *unused)
 755{
 756    test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_U8);
 757}
 758
 759static void test_visitor_out_native_list_uint16(TestOutputVisitorData *data,
 760                                                const void *unused)
 761{
 762    test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_U16);
 763}
 764
 765static void test_visitor_out_native_list_uint32(TestOutputVisitorData *data,
 766                                                const void *unused)
 767{
 768    test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_U32);
 769}
 770
 771static void test_visitor_out_native_list_uint64(TestOutputVisitorData *data,
 772                                                const void *unused)
 773{
 774    test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_U64);
 775}
 776
 777static void test_visitor_out_native_list_bool(TestOutputVisitorData *data,
 778                                              const void *unused)
 779{
 780    test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_BOOLEAN);
 781}
 782
 783static void test_visitor_out_native_list_str(TestOutputVisitorData *data,
 784                                              const void *unused)
 785{
 786    test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_STRING);
 787}
 788
 789static void test_visitor_out_native_list_number(TestOutputVisitorData *data,
 790                                                const void *unused)
 791{
 792    test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_NUMBER);
 793}
 794
 795static void output_visitor_test_add(const char *testpath,
 796                                    TestOutputVisitorData *data,
 797                                    void (*test_func)(TestOutputVisitorData *data, const void *user_data))
 798{
 799    g_test_add(testpath, TestOutputVisitorData, data, visitor_output_setup,
 800               test_func, visitor_output_teardown);
 801}
 802
 803int main(int argc, char **argv)
 804{
 805    TestOutputVisitorData out_visitor_data;
 806
 807    g_test_init(&argc, &argv, NULL);
 808
 809    output_visitor_test_add("/visitor/output/int",
 810                            &out_visitor_data, test_visitor_out_int);
 811    output_visitor_test_add("/visitor/output/bool",
 812                            &out_visitor_data, test_visitor_out_bool);
 813    output_visitor_test_add("/visitor/output/number",
 814                            &out_visitor_data, test_visitor_out_number);
 815    output_visitor_test_add("/visitor/output/string",
 816                            &out_visitor_data, test_visitor_out_string);
 817    output_visitor_test_add("/visitor/output/no-string",
 818                            &out_visitor_data, test_visitor_out_no_string);
 819    output_visitor_test_add("/visitor/output/enum",
 820                            &out_visitor_data, test_visitor_out_enum);
 821    output_visitor_test_add("/visitor/output/enum-errors",
 822                            &out_visitor_data, test_visitor_out_enum_errors);
 823    output_visitor_test_add("/visitor/output/struct",
 824                            &out_visitor_data, test_visitor_out_struct);
 825    output_visitor_test_add("/visitor/output/struct-nested",
 826                            &out_visitor_data, test_visitor_out_struct_nested);
 827    output_visitor_test_add("/visitor/output/struct-errors",
 828                            &out_visitor_data, test_visitor_out_struct_errors);
 829    output_visitor_test_add("/visitor/output/list",
 830                            &out_visitor_data, test_visitor_out_list);
 831    output_visitor_test_add("/visitor/output/any",
 832                            &out_visitor_data, test_visitor_out_any);
 833    output_visitor_test_add("/visitor/output/list-qapi-free",
 834                            &out_visitor_data, test_visitor_out_list_qapi_free);
 835    output_visitor_test_add("/visitor/output/union-flat",
 836                            &out_visitor_data, test_visitor_out_union_flat);
 837    output_visitor_test_add("/visitor/output/alternate",
 838                            &out_visitor_data, test_visitor_out_alternate);
 839    output_visitor_test_add("/visitor/output/null",
 840                            &out_visitor_data, test_visitor_out_null);
 841    output_visitor_test_add("/visitor/output/native_list/int",
 842                            &out_visitor_data,
 843                            test_visitor_out_native_list_int);
 844    output_visitor_test_add("/visitor/output/native_list/int8",
 845                            &out_visitor_data,
 846                            test_visitor_out_native_list_int8);
 847    output_visitor_test_add("/visitor/output/native_list/int16",
 848                            &out_visitor_data,
 849                            test_visitor_out_native_list_int16);
 850    output_visitor_test_add("/visitor/output/native_list/int32",
 851                            &out_visitor_data,
 852                            test_visitor_out_native_list_int32);
 853    output_visitor_test_add("/visitor/output/native_list/int64",
 854                            &out_visitor_data,
 855                            test_visitor_out_native_list_int64);
 856    output_visitor_test_add("/visitor/output/native_list/uint8",
 857                            &out_visitor_data,
 858                            test_visitor_out_native_list_uint8);
 859    output_visitor_test_add("/visitor/output/native_list/uint16",
 860                            &out_visitor_data,
 861                            test_visitor_out_native_list_uint16);
 862    output_visitor_test_add("/visitor/output/native_list/uint32",
 863                            &out_visitor_data,
 864                            test_visitor_out_native_list_uint32);
 865    output_visitor_test_add("/visitor/output/native_list/uint64",
 866                            &out_visitor_data,
 867                            test_visitor_out_native_list_uint64);
 868    output_visitor_test_add("/visitor/output/native_list/bool",
 869                            &out_visitor_data,
 870                            test_visitor_out_native_list_bool);
 871    output_visitor_test_add("/visitor/output/native_list/string",
 872                            &out_visitor_data,
 873                            test_visitor_out_native_list_str);
 874    output_visitor_test_add("/visitor/output/native_list/number",
 875                            &out_visitor_data,
 876                            test_visitor_out_native_list_number);
 877
 878    g_test_run();
 879
 880    return 0;
 881}
 882