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