cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

test-qobject-output-visitor.c (19209B)


      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-visit.h"
     19#include "qapi/qmp/qbool.h"
     20#include "qapi/qmp/qdict.h"
     21#include "qapi/qmp/qlist.h"
     22#include "qapi/qmp/qnull.h"
     23#include "qapi/qmp/qnum.h"
     24#include "qapi/qmp/qstring.h"
     25
     26typedef struct TestOutputVisitorData {
     27    Visitor *ov;
     28    QObject *obj;
     29} TestOutputVisitorData;
     30
     31static void visitor_output_setup(TestOutputVisitorData *data,
     32                                 const void *unused)
     33{
     34    data->ov = qobject_output_visitor_new(&data->obj);
     35    g_assert(data->ov);
     36}
     37
     38static void visitor_output_teardown(TestOutputVisitorData *data,
     39                                    const void *unused)
     40{
     41    visit_free(data->ov);
     42    data->ov = NULL;
     43    qobject_unref(data->obj);
     44    data->obj = NULL;
     45}
     46
     47static QObject *visitor_get(TestOutputVisitorData *data)
     48{
     49    visit_complete(data->ov, &data->obj);
     50    g_assert(data->obj);
     51    return data->obj;
     52}
     53
     54static void visitor_reset(TestOutputVisitorData *data)
     55{
     56    visitor_output_teardown(data, NULL);
     57    visitor_output_setup(data, NULL);
     58}
     59
     60static void test_visitor_out_int(TestOutputVisitorData *data,
     61                                 const void *unused)
     62{
     63    int64_t value = -42;
     64    int64_t val;
     65    QNum *qnum;
     66
     67    visit_type_int(data->ov, NULL, &value, &error_abort);
     68
     69    qnum = qobject_to(QNum, visitor_get(data));
     70    g_assert(qnum);
     71    g_assert(qnum_get_try_int(qnum, &val));
     72    g_assert_cmpint(val, ==, value);
     73}
     74
     75static void test_visitor_out_bool(TestOutputVisitorData *data,
     76                                  const void *unused)
     77{
     78    bool value = true;
     79    QBool *qbool;
     80
     81    visit_type_bool(data->ov, NULL, &value, &error_abort);
     82
     83    qbool = qobject_to(QBool, visitor_get(data));
     84    g_assert(qbool);
     85    g_assert(qbool_get_bool(qbool) == value);
     86}
     87
     88static void test_visitor_out_number(TestOutputVisitorData *data,
     89                                    const void *unused)
     90{
     91    double value = 3.14;
     92    QNum *qnum;
     93
     94    visit_type_number(data->ov, NULL, &value, &error_abort);
     95
     96    qnum = qobject_to(QNum, visitor_get(data));
     97    g_assert(qnum);
     98    g_assert(qnum_get_double(qnum) == value);
     99}
    100
    101static void test_visitor_out_string(TestOutputVisitorData *data,
    102                                    const void *unused)
    103{
    104    char *string = (char *) "Q E M U";
    105    QString *qstr;
    106
    107    visit_type_str(data->ov, NULL, &string, &error_abort);
    108
    109    qstr = qobject_to(QString, visitor_get(data));
    110    g_assert(qstr);
    111    g_assert_cmpstr(qstring_get_str(qstr), ==, string);
    112}
    113
    114static void test_visitor_out_no_string(TestOutputVisitorData *data,
    115                                       const void *unused)
    116{
    117    char *string = NULL;
    118    QString *qstr;
    119
    120    /* A null string should return "" */
    121    visit_type_str(data->ov, NULL, &string, &error_abort);
    122
    123    qstr = qobject_to(QString, visitor_get(data));
    124    g_assert(qstr);
    125    g_assert_cmpstr(qstring_get_str(qstr), ==, "");
    126}
    127
    128static void test_visitor_out_enum(TestOutputVisitorData *data,
    129                                  const void *unused)
    130{
    131    EnumOne i;
    132    QString *qstr;
    133
    134    for (i = 0; i < ENUM_ONE__MAX; i++) {
    135        visit_type_EnumOne(data->ov, "unused", &i, &error_abort);
    136
    137        qstr = qobject_to(QString, visitor_get(data));
    138        g_assert(qstr);
    139        g_assert_cmpstr(qstring_get_str(qstr), ==, EnumOne_str(i));
    140        visitor_reset(data);
    141    }
    142}
    143
    144static void test_visitor_out_struct(TestOutputVisitorData *data,
    145                                    const void *unused)
    146{
    147    TestStruct test_struct = { .integer = 42,
    148                               .boolean = false,
    149                               .string = (char *) "foo"};
    150    TestStruct *p = &test_struct;
    151    QDict *qdict;
    152
    153    visit_type_TestStruct(data->ov, NULL, &p, &error_abort);
    154
    155    qdict = qobject_to(QDict, visitor_get(data));
    156    g_assert(qdict);
    157    g_assert_cmpint(qdict_size(qdict), ==, 3);
    158    g_assert_cmpint(qdict_get_int(qdict, "integer"), ==, 42);
    159    g_assert_cmpint(qdict_get_bool(qdict, "boolean"), ==, false);
    160    g_assert_cmpstr(qdict_get_str(qdict, "string"), ==, "foo");
    161}
    162
    163static void test_visitor_out_struct_nested(TestOutputVisitorData *data,
    164                                           const void *unused)
    165{
    166    int64_t value = 42;
    167    UserDefTwo *ud2;
    168    QDict *qdict, *dict1, *dict2, *dict3, *userdef;
    169    const char *string = "user def string";
    170    const char *strings[] = { "forty two", "forty three", "forty four",
    171                              "forty five" };
    172
    173    ud2 = g_malloc0(sizeof(*ud2));
    174    ud2->string0 = g_strdup(strings[0]);
    175
    176    ud2->dict1 = g_malloc0(sizeof(*ud2->dict1));
    177    ud2->dict1->string1 = g_strdup(strings[1]);
    178
    179    ud2->dict1->dict2 = g_malloc0(sizeof(*ud2->dict1->dict2));
    180    ud2->dict1->dict2->userdef = g_new0(UserDefOne, 1);
    181    ud2->dict1->dict2->userdef->string = g_strdup(string);
    182    ud2->dict1->dict2->userdef->integer = value;
    183    ud2->dict1->dict2->string = g_strdup(strings[2]);
    184
    185    ud2->dict1->dict3 = g_malloc0(sizeof(*ud2->dict1->dict3));
    186    ud2->dict1->has_dict3 = true;
    187    ud2->dict1->dict3->userdef = g_new0(UserDefOne, 1);
    188    ud2->dict1->dict3->userdef->string = g_strdup(string);
    189    ud2->dict1->dict3->userdef->integer = value;
    190    ud2->dict1->dict3->string = g_strdup(strings[3]);
    191
    192    visit_type_UserDefTwo(data->ov, "unused", &ud2, &error_abort);
    193
    194    qdict = qobject_to(QDict, visitor_get(data));
    195    g_assert(qdict);
    196    g_assert_cmpint(qdict_size(qdict), ==, 2);
    197    g_assert_cmpstr(qdict_get_str(qdict, "string0"), ==, strings[0]);
    198
    199    dict1 = qdict_get_qdict(qdict, "dict1");
    200    g_assert_cmpint(qdict_size(dict1), ==, 3);
    201    g_assert_cmpstr(qdict_get_str(dict1, "string1"), ==, strings[1]);
    202
    203    dict2 = qdict_get_qdict(dict1, "dict2");
    204    g_assert_cmpint(qdict_size(dict2), ==, 2);
    205    g_assert_cmpstr(qdict_get_str(dict2, "string"), ==, strings[2]);
    206    userdef = qdict_get_qdict(dict2, "userdef");
    207    g_assert_cmpint(qdict_size(userdef), ==, 2);
    208    g_assert_cmpint(qdict_get_int(userdef, "integer"), ==, value);
    209    g_assert_cmpstr(qdict_get_str(userdef, "string"), ==, string);
    210
    211    dict3 = qdict_get_qdict(dict1, "dict3");
    212    g_assert_cmpint(qdict_size(dict3), ==, 2);
    213    g_assert_cmpstr(qdict_get_str(dict3, "string"), ==, strings[3]);
    214    userdef = qdict_get_qdict(dict3, "userdef");
    215    g_assert_cmpint(qdict_size(userdef), ==, 2);
    216    g_assert_cmpint(qdict_get_int(userdef, "integer"), ==, value);
    217    g_assert_cmpstr(qdict_get_str(userdef, "string"), ==, string);
    218
    219    qapi_free_UserDefTwo(ud2);
    220}
    221
    222static void test_visitor_out_list(TestOutputVisitorData *data,
    223                                  const void *unused)
    224{
    225    const char *value_str = "list value";
    226    TestStruct *value;
    227    TestStructList *head = NULL;
    228    const int max_items = 10;
    229    bool value_bool = true;
    230    int value_int = 10;
    231    QListEntry *entry;
    232    QList *qlist;
    233    int i;
    234
    235    /* Build the list in reverse order... */
    236    for (i = 0; i < max_items; i++) {
    237        value = g_malloc0(sizeof(*value));
    238        value->integer = value_int + (max_items - i - 1);
    239        value->boolean = value_bool;
    240        value->string = g_strdup(value_str);
    241
    242        QAPI_LIST_PREPEND(head, value);
    243    }
    244
    245    visit_type_TestStructList(data->ov, NULL, &head, &error_abort);
    246
    247    qlist = qobject_to(QList, visitor_get(data));
    248    g_assert(qlist);
    249    g_assert(!qlist_empty(qlist));
    250
    251    /* ...and ensure that the visitor sees it in order */
    252    i = 0;
    253    QLIST_FOREACH_ENTRY(qlist, entry) {
    254        QDict *qdict;
    255
    256        qdict = qobject_to(QDict, entry->value);
    257        g_assert(qdict);
    258        g_assert_cmpint(qdict_size(qdict), ==, 3);
    259        g_assert_cmpint(qdict_get_int(qdict, "integer"), ==, value_int + i);
    260        g_assert_cmpint(qdict_get_bool(qdict, "boolean"), ==, value_bool);
    261        g_assert_cmpstr(qdict_get_str(qdict, "string"), ==, value_str);
    262        i++;
    263    }
    264    g_assert_cmpint(i, ==, max_items);
    265
    266    qapi_free_TestStructList(head);
    267}
    268
    269static void test_visitor_out_list_qapi_free(TestOutputVisitorData *data,
    270                                            const void *unused)
    271{
    272    UserDefTwo *value;
    273    UserDefTwoList *head = NULL;
    274    const char string[] = "foo bar";
    275    int i, max_count = 1024;
    276
    277    for (i = 0; i < max_count; i++) {
    278        value = g_malloc0(sizeof(*value));
    279
    280        value->string0 = g_strdup(string);
    281        value->dict1 = g_new0(UserDefTwoDict, 1);
    282        value->dict1->string1 = g_strdup(string);
    283        value->dict1->dict2 = g_new0(UserDefTwoDictDict, 1);
    284        value->dict1->dict2->userdef = g_new0(UserDefOne, 1);
    285        value->dict1->dict2->userdef->string = g_strdup(string);
    286        value->dict1->dict2->userdef->integer = 42;
    287        value->dict1->dict2->string = g_strdup(string);
    288        value->dict1->has_dict3 = false;
    289
    290        QAPI_LIST_PREPEND(head, value);
    291    }
    292
    293    qapi_free_UserDefTwoList(head);
    294}
    295
    296static void test_visitor_out_any(TestOutputVisitorData *data,
    297                                 const void *unused)
    298{
    299    QObject *qobj;
    300    QNum *qnum;
    301    QBool *qbool;
    302    QString *qstring;
    303    QDict *qdict;
    304    int64_t val;
    305
    306    qobj = QOBJECT(qnum_from_int(-42));
    307    visit_type_any(data->ov, NULL, &qobj, &error_abort);
    308    qnum = qobject_to(QNum, visitor_get(data));
    309    g_assert(qnum);
    310    g_assert(qnum_get_try_int(qnum, &val));
    311    g_assert_cmpint(val, ==, -42);
    312    qobject_unref(qobj);
    313
    314    visitor_reset(data);
    315    qdict = qdict_new();
    316    qdict_put_int(qdict, "integer", -42);
    317    qdict_put_bool(qdict, "boolean", true);
    318    qdict_put_str(qdict, "string", "foo");
    319    qobj = QOBJECT(qdict);
    320    visit_type_any(data->ov, NULL, &qobj, &error_abort);
    321    qobject_unref(qobj);
    322    qdict = qobject_to(QDict, visitor_get(data));
    323    g_assert(qdict);
    324    qnum = qobject_to(QNum, qdict_get(qdict, "integer"));
    325    g_assert(qnum);
    326    g_assert(qnum_get_try_int(qnum, &val));
    327    g_assert_cmpint(val, ==, -42);
    328    qbool = qobject_to(QBool, qdict_get(qdict, "boolean"));
    329    g_assert(qbool);
    330    g_assert(qbool_get_bool(qbool) == true);
    331    qstring = qobject_to(QString, qdict_get(qdict, "string"));
    332    g_assert(qstring);
    333    g_assert_cmpstr(qstring_get_str(qstring), ==, "foo");
    334}
    335
    336static void test_visitor_out_union_flat(TestOutputVisitorData *data,
    337                                        const void *unused)
    338{
    339    QDict *qdict;
    340
    341    UserDefFlatUnion *tmp = g_malloc0(sizeof(UserDefFlatUnion));
    342    tmp->enum1 = ENUM_ONE_VALUE1;
    343    tmp->string = g_strdup("str");
    344    tmp->integer = 41;
    345    tmp->u.value1.boolean = true;
    346
    347    visit_type_UserDefFlatUnion(data->ov, NULL, &tmp, &error_abort);
    348    qdict = qobject_to(QDict, visitor_get(data));
    349    g_assert(qdict);
    350    g_assert_cmpstr(qdict_get_str(qdict, "enum1"), ==, "value1");
    351    g_assert_cmpstr(qdict_get_str(qdict, "string"), ==, "str");
    352    g_assert_cmpint(qdict_get_int(qdict, "integer"), ==, 41);
    353    g_assert_cmpint(qdict_get_bool(qdict, "boolean"), ==, true);
    354
    355    qapi_free_UserDefFlatUnion(tmp);
    356}
    357
    358static void test_visitor_out_alternate(TestOutputVisitorData *data,
    359                                       const void *unused)
    360{
    361    UserDefAlternate *tmp;
    362    QNum *qnum;
    363    QString *qstr;
    364    QDict *qdict;
    365    int64_t val;
    366
    367    tmp = g_new0(UserDefAlternate, 1);
    368    tmp->type = QTYPE_QNUM;
    369    tmp->u.i = 42;
    370
    371    visit_type_UserDefAlternate(data->ov, NULL, &tmp, &error_abort);
    372    qnum = qobject_to(QNum, visitor_get(data));
    373    g_assert(qnum);
    374    g_assert(qnum_get_try_int(qnum, &val));
    375    g_assert_cmpint(val, ==, 42);
    376
    377    qapi_free_UserDefAlternate(tmp);
    378
    379    visitor_reset(data);
    380    tmp = g_new0(UserDefAlternate, 1);
    381    tmp->type = QTYPE_QSTRING;
    382    tmp->u.e = ENUM_ONE_VALUE1;
    383
    384    visit_type_UserDefAlternate(data->ov, NULL, &tmp, &error_abort);
    385    qstr = qobject_to(QString, visitor_get(data));
    386    g_assert(qstr);
    387    g_assert_cmpstr(qstring_get_str(qstr), ==, "value1");
    388
    389    qapi_free_UserDefAlternate(tmp);
    390
    391    visitor_reset(data);
    392    tmp = g_new0(UserDefAlternate, 1);
    393    tmp->type = QTYPE_QNULL;
    394    tmp->u.n = qnull();
    395
    396    visit_type_UserDefAlternate(data->ov, NULL, &tmp, &error_abort);
    397    g_assert_cmpint(qobject_type(visitor_get(data)), ==, QTYPE_QNULL);
    398
    399    qapi_free_UserDefAlternate(tmp);
    400
    401    visitor_reset(data);
    402    tmp = g_new0(UserDefAlternate, 1);
    403    tmp->type = QTYPE_QDICT;
    404    tmp->u.udfu.integer = 1;
    405    tmp->u.udfu.string = g_strdup("str");
    406    tmp->u.udfu.enum1 = ENUM_ONE_VALUE1;
    407    tmp->u.udfu.u.value1.boolean = true;
    408
    409    visit_type_UserDefAlternate(data->ov, NULL, &tmp, &error_abort);
    410    qdict = qobject_to(QDict, visitor_get(data));
    411    g_assert(qdict);
    412    g_assert_cmpint(qdict_size(qdict), ==, 4);
    413    g_assert_cmpint(qdict_get_int(qdict, "integer"), ==, 1);
    414    g_assert_cmpstr(qdict_get_str(qdict, "string"), ==, "str");
    415    g_assert_cmpstr(qdict_get_str(qdict, "enum1"), ==, "value1");
    416    g_assert_cmpint(qdict_get_bool(qdict, "boolean"), ==, true);
    417
    418    qapi_free_UserDefAlternate(tmp);
    419}
    420
    421static void test_visitor_out_null(TestOutputVisitorData *data,
    422                                  const void *unused)
    423{
    424    QNull *null = NULL;
    425    QDict *qdict;
    426    QObject *nil;
    427
    428    visit_start_struct(data->ov, NULL, NULL, 0, &error_abort);
    429    visit_type_null(data->ov, "a", &null, &error_abort);
    430    visit_check_struct(data->ov, &error_abort);
    431    visit_end_struct(data->ov, NULL);
    432    qdict = qobject_to(QDict, visitor_get(data));
    433    g_assert(qdict);
    434    g_assert_cmpint(qdict_size(qdict), ==, 1);
    435    nil = qdict_get(qdict, "a");
    436    g_assert(nil);
    437    g_assert(qobject_type(nil) == QTYPE_QNULL);
    438}
    439
    440static void test_visitor_out_list_struct(TestOutputVisitorData *data,
    441                                         const void *unused)
    442{
    443    const char *int_member[] = {
    444        "integer", "s8", "s16", "s32", "s64", "u8", "u16", "u32", "u64" };
    445    g_autoptr(ArrayStruct) arrs = g_new0(ArrayStruct, 1);
    446    int i, j;
    447    QDict *qdict;
    448    QList *qlist;
    449    QListEntry *e;
    450
    451    for (i = 31; i >= 0; i--) {
    452        QAPI_LIST_PREPEND(arrs->integer, i);
    453    }
    454
    455    for (i = 31; i >= 0; i--) {
    456        QAPI_LIST_PREPEND(arrs->s8, i);
    457    }
    458
    459    for (i = 31; i >= 0; i--) {
    460        QAPI_LIST_PREPEND(arrs->s16, i);
    461    }
    462
    463    for (i = 31; i >= 0; i--) {
    464        QAPI_LIST_PREPEND(arrs->s32, i);
    465    }
    466
    467    for (i = 31; i >= 0; i--) {
    468        QAPI_LIST_PREPEND(arrs->s64, i);
    469    }
    470
    471    for (i = 31; i >= 0; i--) {
    472        QAPI_LIST_PREPEND(arrs->u8, i);
    473    }
    474
    475    for (i = 31; i >= 0; i--) {
    476        QAPI_LIST_PREPEND(arrs->u16, i);
    477    }
    478
    479    for (i = 31; i >= 0; i--) {
    480        QAPI_LIST_PREPEND(arrs->u32, i);
    481    }
    482
    483    for (i = 31; i >= 0; i--) {
    484        QAPI_LIST_PREPEND(arrs->u64, i);
    485    }
    486
    487    for (i = 31; i >= 0; i--) {
    488        QAPI_LIST_PREPEND(arrs->number, (double)i / 3);
    489    }
    490
    491    for (i = 31; i >= 0; i--) {
    492        QAPI_LIST_PREPEND(arrs->boolean, QEMU_IS_ALIGNED(i, 3));
    493    }
    494
    495    for (i = 31; i >= 0; i--) {
    496        QAPI_LIST_PREPEND(arrs->string, g_strdup_printf("%d", i));
    497    }
    498
    499    visit_type_ArrayStruct(data->ov, NULL, &arrs, &error_abort);
    500
    501    qdict = qobject_to(QDict, visitor_get(data));
    502    g_assert(qdict);
    503
    504    for (i = 0; i < G_N_ELEMENTS(int_member); i++) {
    505        qlist = qdict_get_qlist(qdict, int_member[i]);
    506        g_assert(qlist);
    507        j = 0;
    508        QLIST_FOREACH_ENTRY(qlist, e) {
    509            QNum *qvalue = qobject_to(QNum, qlist_entry_obj(e));
    510            g_assert(qvalue);
    511            g_assert_cmpint(qnum_get_int(qvalue), ==, j);
    512            j++;
    513        }
    514    }
    515
    516    qlist = qdict_get_qlist(qdict, "number");
    517    g_assert(qlist);
    518    i = 0;
    519    QLIST_FOREACH_ENTRY(qlist, e) {
    520        QNum *qvalue = qobject_to(QNum, qlist_entry_obj(e));
    521        char expected[32], actual[32];
    522
    523        g_assert(qvalue);
    524        sprintf(expected, "%.6f", (double)i / 3);
    525        sprintf(actual, "%.6f", qnum_get_double(qvalue));
    526        g_assert_cmpstr(actual, ==, expected);
    527        i++;
    528    }
    529
    530    qlist = qdict_get_qlist(qdict, "boolean");
    531    g_assert(qlist);
    532    i = 0;
    533    QLIST_FOREACH_ENTRY(qlist, e) {
    534        QBool *qvalue = qobject_to(QBool, qlist_entry_obj(e));
    535        g_assert(qvalue);
    536        g_assert_cmpint(qbool_get_bool(qvalue), ==, i % 3 == 0);
    537        i++;
    538    }
    539
    540    qlist = qdict_get_qlist(qdict, "string");
    541    g_assert(qlist);
    542    i = 0;
    543    QLIST_FOREACH_ENTRY(qlist, e) {
    544        QString *qvalue = qobject_to(QString, qlist_entry_obj(e));
    545        char expected[32];
    546
    547        g_assert(qvalue);
    548        sprintf(expected, "%d", i);
    549        g_assert_cmpstr(qstring_get_str(qvalue), ==, expected);
    550        i++;
    551    }
    552}
    553
    554static void output_visitor_test_add(const char *testpath,
    555                                    TestOutputVisitorData *data,
    556                                    void (*test_func)(TestOutputVisitorData *data, const void *user_data))
    557{
    558    g_test_add(testpath, TestOutputVisitorData, data, visitor_output_setup,
    559               test_func, visitor_output_teardown);
    560}
    561
    562int main(int argc, char **argv)
    563{
    564    TestOutputVisitorData out_visitor_data;
    565
    566    g_test_init(&argc, &argv, NULL);
    567
    568    output_visitor_test_add("/visitor/output/int",
    569                            &out_visitor_data, test_visitor_out_int);
    570    output_visitor_test_add("/visitor/output/bool",
    571                            &out_visitor_data, test_visitor_out_bool);
    572    output_visitor_test_add("/visitor/output/number",
    573                            &out_visitor_data, test_visitor_out_number);
    574    output_visitor_test_add("/visitor/output/string",
    575                            &out_visitor_data, test_visitor_out_string);
    576    output_visitor_test_add("/visitor/output/no-string",
    577                            &out_visitor_data, test_visitor_out_no_string);
    578    output_visitor_test_add("/visitor/output/enum",
    579                            &out_visitor_data, test_visitor_out_enum);
    580    output_visitor_test_add("/visitor/output/struct",
    581                            &out_visitor_data, test_visitor_out_struct);
    582    output_visitor_test_add("/visitor/output/struct-nested",
    583                            &out_visitor_data, test_visitor_out_struct_nested);
    584    output_visitor_test_add("/visitor/output/list",
    585                            &out_visitor_data, test_visitor_out_list);
    586    output_visitor_test_add("/visitor/output/any",
    587                            &out_visitor_data, test_visitor_out_any);
    588    output_visitor_test_add("/visitor/output/list-qapi-free",
    589                            &out_visitor_data, test_visitor_out_list_qapi_free);
    590    output_visitor_test_add("/visitor/output/union-flat",
    591                            &out_visitor_data, test_visitor_out_union_flat);
    592    output_visitor_test_add("/visitor/output/alternate",
    593                            &out_visitor_data, test_visitor_out_alternate);
    594    output_visitor_test_add("/visitor/output/null",
    595                            &out_visitor_data, test_visitor_out_null);
    596    output_visitor_test_add("/visitor/output/list_struct",
    597                            &out_visitor_data, test_visitor_out_list_struct);
    598
    599    g_test_run();
    600
    601    return 0;
    602}