test-qmp-commands.c 5.0 KB
Newer Older
1
#include <glib.h>
2
#include "qemu-common.h"
3 4 5 6
#include "qemu-objects.h"
#include "test-qmp-commands.h"
#include "qapi/qmp-core.h"
#include "module.h"
7 8 9
#include "qapi/qmp-input-visitor.h"
#include "tests/test-qapi-types.h"
#include "tests/test-qapi-visit.h"
10 11 12 13 14 15 16 17 18 19 20 21

void qmp_user_def_cmd(Error **errp)
{
}

void qmp_user_def_cmd1(UserDefOne * ud1, Error **errp)
{
}

UserDefTwo * qmp_user_def_cmd2(UserDefOne * ud1a, UserDefOne * ud1b, Error **errp)
{
    UserDefTwo *ret;
22 23
    UserDefOne *ud1c = g_malloc0(sizeof(UserDefOne));
    UserDefOne *ud1d = g_malloc0(sizeof(UserDefOne));
24 25 26 27 28 29

    ud1c->string = strdup(ud1a->string);
    ud1c->integer = ud1a->integer;
    ud1d->string = strdup(ud1b->string);
    ud1d->integer = ud1b->integer;

30
    ret = g_malloc0(sizeof(UserDefTwo));
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
    ret->string = strdup("blah1");
    ret->dict.string = strdup("blah2");
    ret->dict.dict.userdef = ud1c;
    ret->dict.dict.string = strdup("blah3");
    ret->dict.has_dict2 = true;
    ret->dict.dict2.userdef = ud1d;
    ret->dict.dict2.string = strdup("blah4");

    return ret;
}

/* test commands with no input and no return value */
static void test_dispatch_cmd(void)
{
    QDict *req = qdict_new();
    QObject *resp;

    qdict_put_obj(req, "execute", QOBJECT(qstring_from_str("user_def_cmd")));

    resp = qmp_dispatch(QOBJECT(req));
    assert(resp != NULL);
    assert(!qdict_haskey(qobject_to_qdict(resp), "error"));

    qobject_decref(resp);
    QDECREF(req);
}

/* test commands that return an error due to invalid parameters */
static void test_dispatch_cmd_error(void)
{
    QDict *req = qdict_new();
    QObject *resp;

    qdict_put_obj(req, "execute", QOBJECT(qstring_from_str("user_def_cmd2")));

    resp = qmp_dispatch(QOBJECT(req));
    assert(resp != NULL);
    assert(qdict_haskey(qobject_to_qdict(resp), "error"));

    qobject_decref(resp);
    QDECREF(req);
}

/* test commands that involve both input parameters and return values */
static void test_dispatch_cmd_io(void)
{
    QDict *req = qdict_new();
    QDict *args = qdict_new();
    QDict *ud1a = qdict_new();
    QDict *ud1b = qdict_new();
    QObject *resp;

    qdict_put_obj(ud1a, "integer", QOBJECT(qint_from_int(42)));
    qdict_put_obj(ud1a, "string", QOBJECT(qstring_from_str("hello")));
    qdict_put_obj(ud1b, "integer", QOBJECT(qint_from_int(422)));
    qdict_put_obj(ud1b, "string", QOBJECT(qstring_from_str("hello2")));
    qdict_put_obj(args, "ud1a", QOBJECT(ud1a));
    qdict_put_obj(args, "ud1b", QOBJECT(ud1b));
    qdict_put_obj(req, "arguments", QOBJECT(args));

    qdict_put_obj(req, "execute", QOBJECT(qstring_from_str("user_def_cmd2")));

    /* TODO: put in full payload and check for errors */
    resp = qmp_dispatch(QOBJECT(req));
    assert(resp != NULL);
    assert(!qdict_haskey(qobject_to_qdict(resp), "error"));

    qobject_decref(resp);
    QDECREF(req);
}

102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
/* test generated dealloc functions for generated types */
static void test_dealloc_types(void)
{
    UserDefOne *ud1test, *ud1a, *ud1b;
    UserDefOneList *ud1list;

    ud1test = g_malloc0(sizeof(UserDefOne));
    ud1test->integer = 42;
    ud1test->string = g_strdup("hi there 42");

    qapi_free_UserDefOne(ud1test);

    ud1a = g_malloc0(sizeof(UserDefOne));
    ud1a->integer = 43;
    ud1a->string = g_strdup("hi there 43");

    ud1b = g_malloc0(sizeof(UserDefOne));
    ud1b->integer = 44;
    ud1b->string = g_strdup("hi there 44");

    ud1list = g_malloc0(sizeof(UserDefOneList));
    ud1list->value = ud1a;
    ud1list->next = g_malloc0(sizeof(UserDefOneList));
    ud1list->next->value = ud1b;

    qapi_free_UserDefOneList(ud1list);
}

130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
/* test generated deallocation on an object whose construction was prematurely
 * terminated due to an error */
static void test_dealloc_partial(void)
{
    static const char text[] = "don't leak me";

    UserDefTwo *ud2 = NULL;
    Error *err = NULL;

    /* create partial object */
    {
        QDict *ud2_dict;
        QmpInputVisitor *qiv;

        ud2_dict = qdict_new();
        qdict_put_obj(ud2_dict, "string", QOBJECT(qstring_from_str(text)));

        qiv = qmp_input_visitor_new(QOBJECT(ud2_dict));
        visit_type_UserDefTwo(qmp_input_get_visitor(qiv), &ud2, NULL, &err);
        qmp_input_visitor_cleanup(qiv);
        QDECREF(ud2_dict);
    }

    /* verify partial success */
    assert(ud2 != NULL);
    assert(ud2->string != NULL);
    assert(strcmp(ud2->string, text) == 0);
    assert(ud2->dict.dict.userdef == NULL);

    /* confirm & release construction error */
    assert(err != NULL);
    error_free(err);

    /* tear down partial object */
    qapi_free_UserDefTwo(ud2);
}


168 169 170 171 172 173 174
int main(int argc, char **argv)
{
    g_test_init(&argc, &argv, NULL);

    g_test_add_func("/0.15/dispatch_cmd", test_dispatch_cmd);
    g_test_add_func("/0.15/dispatch_cmd_error", test_dispatch_cmd_error);
    g_test_add_func("/0.15/dispatch_cmd_io", test_dispatch_cmd_io);
175
    g_test_add_func("/0.15/dealloc_types", test_dealloc_types);
176
    g_test_add_func("/0.15/dealloc_partial", test_dealloc_partial);
177 178 179 180 181 182

    module_call_init(MODULE_INIT_QAPI);
    g_test_run();

    return 0;
}