qemu/tests/test-qmp-commands.c
<<
>>
Prefs
   1#include "qemu/osdep.h"
   2#include <glib.h>
   3#include "qemu-common.h"
   4#include "qapi/qmp/types.h"
   5#include "test-qmp-commands.h"
   6#include "qapi/qmp/dispatch.h"
   7#include "qemu/module.h"
   8#include "qapi/qmp-input-visitor.h"
   9#include "tests/test-qapi-types.h"
  10#include "tests/test-qapi-visit.h"
  11
  12void qmp_user_def_cmd(Error **errp)
  13{
  14}
  15
  16Empty2 *qmp_user_def_cmd0(Error **errp)
  17{
  18    return g_new0(Empty2, 1);
  19}
  20
  21void qmp_user_def_cmd1(UserDefOne * ud1, Error **errp)
  22{
  23}
  24
  25UserDefTwo *qmp_user_def_cmd2(UserDefOne *ud1a,
  26                              bool has_udb1, UserDefOne *ud1b,
  27                              Error **errp)
  28{
  29    UserDefTwo *ret;
  30    UserDefOne *ud1c = g_malloc0(sizeof(UserDefOne));
  31    UserDefOne *ud1d = g_malloc0(sizeof(UserDefOne));
  32
  33    ud1c->string = strdup(ud1a->string);
  34    ud1c->integer = ud1a->integer;
  35    ud1d->string = strdup(has_udb1 ? ud1b->string : "blah0");
  36    ud1d->integer = has_udb1 ? ud1b->integer : 0;
  37
  38    ret = g_new0(UserDefTwo, 1);
  39    ret->string0 = strdup("blah1");
  40    ret->dict1 = g_new0(UserDefTwoDict, 1);
  41    ret->dict1->string1 = strdup("blah2");
  42    ret->dict1->dict2 = g_new0(UserDefTwoDictDict, 1);
  43    ret->dict1->dict2->userdef = ud1c;
  44    ret->dict1->dict2->string = strdup("blah3");
  45    ret->dict1->dict3 = g_new0(UserDefTwoDictDict, 1);
  46    ret->dict1->has_dict3 = true;
  47    ret->dict1->dict3->userdef = ud1d;
  48    ret->dict1->dict3->string = strdup("blah4");
  49
  50    return ret;
  51}
  52
  53int64_t qmp_guest_get_time(int64_t a, bool has_b, int64_t b, Error **errp)
  54{
  55    return a + (has_b ? b : 0);
  56}
  57
  58QObject *qmp_guest_sync(QObject *arg, Error **errp)
  59{
  60    return arg;
  61}
  62
  63__org_qemu_x_Union1 *qmp___org_qemu_x_command(__org_qemu_x_EnumList *a,
  64                                              __org_qemu_x_StructList *b,
  65                                              __org_qemu_x_Union2 *c,
  66                                              __org_qemu_x_Alt *d,
  67                                              Error **errp)
  68{
  69    __org_qemu_x_Union1 *ret = g_new0(__org_qemu_x_Union1, 1);
  70
  71    ret->type = ORG_QEMU_X_UNION1_KIND___ORG_QEMU_X_BRANCH;
  72    ret->u.__org_qemu_x_branch.data = strdup("blah1");
  73
  74    /* Also test that 'wchar-t' was munged to 'q_wchar_t' */
  75    if (b && b->value && !b->value->has_q_wchar_t) {
  76        b->value->q_wchar_t = 1;
  77    }
  78    return ret;
  79}
  80
  81
  82/* test commands with no input and no return value */
  83static void test_dispatch_cmd(void)
  84{
  85    QDict *req = qdict_new();
  86    QObject *resp;
  87
  88    qdict_put_obj(req, "execute", QOBJECT(qstring_from_str("user_def_cmd")));
  89
  90    resp = qmp_dispatch(QOBJECT(req));
  91    assert(resp != NULL);
  92    assert(!qdict_haskey(qobject_to_qdict(resp), "error"));
  93
  94    qobject_decref(resp);
  95    QDECREF(req);
  96}
  97
  98/* test commands that return an error due to invalid parameters */
  99static void test_dispatch_cmd_error(void)
 100{
 101    QDict *req = qdict_new();
 102    QObject *resp;
 103
 104    qdict_put_obj(req, "execute", QOBJECT(qstring_from_str("user_def_cmd2")));
 105
 106    resp = qmp_dispatch(QOBJECT(req));
 107    assert(resp != NULL);
 108    assert(qdict_haskey(qobject_to_qdict(resp), "error"));
 109
 110    qobject_decref(resp);
 111    QDECREF(req);
 112}
 113
 114static QObject *test_qmp_dispatch(QDict *req)
 115{
 116    QObject *resp_obj;
 117    QDict *resp;
 118    QObject *ret;
 119
 120    resp_obj = qmp_dispatch(QOBJECT(req));
 121    assert(resp_obj);
 122    resp = qobject_to_qdict(resp_obj);
 123    assert(resp && !qdict_haskey(resp, "error"));
 124    ret = qdict_get(resp, "return");
 125    assert(ret);
 126    qobject_incref(ret);
 127    qobject_decref(resp_obj);
 128    return ret;
 129}
 130
 131/* test commands that involve both input parameters and return values */
 132static void test_dispatch_cmd_io(void)
 133{
 134    QDict *req = qdict_new();
 135    QDict *args = qdict_new();
 136    QDict *args3 = qdict_new();
 137    QDict *ud1a = qdict_new();
 138    QDict *ud1b = qdict_new();
 139    QDict *ret, *ret_dict, *ret_dict_dict, *ret_dict_dict_userdef;
 140    QDict *ret_dict_dict2, *ret_dict_dict2_userdef;
 141    QInt *ret3;
 142
 143    qdict_put_obj(ud1a, "integer", QOBJECT(qint_from_int(42)));
 144    qdict_put_obj(ud1a, "string", QOBJECT(qstring_from_str("hello")));
 145    qdict_put_obj(ud1b, "integer", QOBJECT(qint_from_int(422)));
 146    qdict_put_obj(ud1b, "string", QOBJECT(qstring_from_str("hello2")));
 147    qdict_put_obj(args, "ud1a", QOBJECT(ud1a));
 148    qdict_put_obj(args, "ud1b", QOBJECT(ud1b));
 149    qdict_put_obj(req, "arguments", QOBJECT(args));
 150    qdict_put_obj(req, "execute", QOBJECT(qstring_from_str("user_def_cmd2")));
 151
 152    ret = qobject_to_qdict(test_qmp_dispatch(req));
 153
 154    assert(!strcmp(qdict_get_str(ret, "string0"), "blah1"));
 155    ret_dict = qdict_get_qdict(ret, "dict1");
 156    assert(!strcmp(qdict_get_str(ret_dict, "string1"), "blah2"));
 157    ret_dict_dict = qdict_get_qdict(ret_dict, "dict2");
 158    ret_dict_dict_userdef = qdict_get_qdict(ret_dict_dict, "userdef");
 159    assert(qdict_get_int(ret_dict_dict_userdef, "integer") == 42);
 160    assert(!strcmp(qdict_get_str(ret_dict_dict_userdef, "string"), "hello"));
 161    assert(!strcmp(qdict_get_str(ret_dict_dict, "string"), "blah3"));
 162    ret_dict_dict2 = qdict_get_qdict(ret_dict, "dict3");
 163    ret_dict_dict2_userdef = qdict_get_qdict(ret_dict_dict2, "userdef");
 164    assert(qdict_get_int(ret_dict_dict2_userdef, "integer") == 422);
 165    assert(!strcmp(qdict_get_str(ret_dict_dict2_userdef, "string"), "hello2"));
 166    assert(!strcmp(qdict_get_str(ret_dict_dict2, "string"), "blah4"));
 167    QDECREF(ret);
 168
 169    qdict_put(args3, "a", qint_from_int(66));
 170    qdict_put(req, "arguments", args3);
 171    qdict_put(req, "execute", qstring_from_str("guest-get-time"));
 172
 173    ret3 = qobject_to_qint(test_qmp_dispatch(req));
 174    assert(qint_get_int(ret3) == 66);
 175    QDECREF(ret3);
 176
 177    QDECREF(req);
 178}
 179
 180/* test generated dealloc functions for generated types */
 181static void test_dealloc_types(void)
 182{
 183    UserDefOne *ud1test, *ud1a, *ud1b;
 184    UserDefOneList *ud1list;
 185
 186    ud1test = g_malloc0(sizeof(UserDefOne));
 187    ud1test->integer = 42;
 188    ud1test->string = g_strdup("hi there 42");
 189
 190    qapi_free_UserDefOne(ud1test);
 191
 192    ud1a = g_malloc0(sizeof(UserDefOne));
 193    ud1a->integer = 43;
 194    ud1a->string = g_strdup("hi there 43");
 195
 196    ud1b = g_malloc0(sizeof(UserDefOne));
 197    ud1b->integer = 44;
 198    ud1b->string = g_strdup("hi there 44");
 199
 200    ud1list = g_malloc0(sizeof(UserDefOneList));
 201    ud1list->value = ud1a;
 202    ud1list->next = g_malloc0(sizeof(UserDefOneList));
 203    ud1list->next->value = ud1b;
 204
 205    qapi_free_UserDefOneList(ud1list);
 206}
 207
 208/* test generated deallocation on an object whose construction was prematurely
 209 * terminated due to an error */
 210static void test_dealloc_partial(void)
 211{
 212    static const char text[] = "don't leak me";
 213
 214    UserDefTwo *ud2 = NULL;
 215    Error *err = NULL;
 216
 217    /* create partial object */
 218    {
 219        QDict *ud2_dict;
 220        QmpInputVisitor *qiv;
 221
 222        ud2_dict = qdict_new();
 223        qdict_put_obj(ud2_dict, "string0", QOBJECT(qstring_from_str(text)));
 224
 225        qiv = qmp_input_visitor_new(QOBJECT(ud2_dict));
 226        visit_type_UserDefTwo(qmp_input_get_visitor(qiv), NULL, &ud2, &err);
 227        qmp_input_visitor_cleanup(qiv);
 228        QDECREF(ud2_dict);
 229    }
 230
 231    /* verify partial success */
 232    assert(ud2 != NULL);
 233    assert(ud2->string0 != NULL);
 234    assert(strcmp(ud2->string0, text) == 0);
 235    assert(ud2->dict1 == NULL);
 236
 237    /* confirm & release construction error */
 238    error_free_or_abort(&err);
 239
 240    /* tear down partial object */
 241    qapi_free_UserDefTwo(ud2);
 242}
 243
 244
 245int main(int argc, char **argv)
 246{
 247    g_test_init(&argc, &argv, NULL);
 248
 249    g_test_add_func("/0.15/dispatch_cmd", test_dispatch_cmd);
 250    g_test_add_func("/0.15/dispatch_cmd_error", test_dispatch_cmd_error);
 251    g_test_add_func("/0.15/dispatch_cmd_io", test_dispatch_cmd_io);
 252    g_test_add_func("/0.15/dealloc_types", test_dealloc_types);
 253    g_test_add_func("/0.15/dealloc_partial", test_dealloc_partial);
 254
 255    module_call_init(MODULE_INIT_QAPI);
 256    g_test_run();
 257
 258    return 0;
 259}
 260