qemu/tests/test-qmp-commands.c
<<
>>
Prefs
   1#include <glib.h>
   2#include "qemu-objects.h"
   3#include "test-qmp-commands.h"
   4#include "qapi/qmp-core.h"
   5#include "module.h"
   6#include "qapi/qmp-input-visitor.h"
   7#include "tests/test-qapi-types.h"
   8#include "tests/test-qapi-visit.h"
   9
  10void qmp_user_def_cmd(Error **errp)
  11{
  12}
  13
  14void qmp_user_def_cmd1(UserDefOne * ud1, Error **errp)
  15{
  16}
  17
  18UserDefTwo * qmp_user_def_cmd2(UserDefOne * ud1a, UserDefOne * ud1b, Error **errp)
  19{
  20    UserDefTwo *ret;
  21    UserDefOne *ud1c = g_malloc0(sizeof(UserDefOne));
  22    UserDefOne *ud1d = g_malloc0(sizeof(UserDefOne));
  23
  24    ud1c->string = strdup(ud1a->string);
  25    ud1c->integer = ud1a->integer;
  26    ud1d->string = strdup(ud1b->string);
  27    ud1d->integer = ud1b->integer;
  28
  29    ret = g_malloc0(sizeof(UserDefTwo));
  30    ret->string = strdup("blah1");
  31    ret->dict.string = strdup("blah2");
  32    ret->dict.dict.userdef = ud1c;
  33    ret->dict.dict.string = strdup("blah3");
  34    ret->dict.has_dict2 = true;
  35    ret->dict.dict2.userdef = ud1d;
  36    ret->dict.dict2.string = strdup("blah4");
  37
  38    return ret;
  39}
  40
  41/* test commands with no input and no return value */
  42static void test_dispatch_cmd(void)
  43{
  44    QDict *req = qdict_new();
  45    QObject *resp;
  46
  47    qdict_put_obj(req, "execute", QOBJECT(qstring_from_str("user_def_cmd")));
  48
  49    resp = qmp_dispatch(QOBJECT(req));
  50    assert(resp != NULL);
  51    assert(!qdict_haskey(qobject_to_qdict(resp), "error"));
  52
  53    qobject_decref(resp);
  54    QDECREF(req);
  55}
  56
  57/* test commands that return an error due to invalid parameters */
  58static void test_dispatch_cmd_error(void)
  59{
  60    QDict *req = qdict_new();
  61    QObject *resp;
  62
  63    qdict_put_obj(req, "execute", QOBJECT(qstring_from_str("user_def_cmd2")));
  64
  65    resp = qmp_dispatch(QOBJECT(req));
  66    assert(resp != NULL);
  67    assert(qdict_haskey(qobject_to_qdict(resp), "error"));
  68
  69    qobject_decref(resp);
  70    QDECREF(req);
  71}
  72
  73/* test commands that involve both input parameters and return values */
  74static void test_dispatch_cmd_io(void)
  75{
  76    QDict *req = qdict_new();
  77    QDict *args = qdict_new();
  78    QDict *ud1a = qdict_new();
  79    QDict *ud1b = qdict_new();
  80    QObject *resp;
  81
  82    qdict_put_obj(ud1a, "integer", QOBJECT(qint_from_int(42)));
  83    qdict_put_obj(ud1a, "string", QOBJECT(qstring_from_str("hello")));
  84    qdict_put_obj(ud1b, "integer", QOBJECT(qint_from_int(422)));
  85    qdict_put_obj(ud1b, "string", QOBJECT(qstring_from_str("hello2")));
  86    qdict_put_obj(args, "ud1a", QOBJECT(ud1a));
  87    qdict_put_obj(args, "ud1b", QOBJECT(ud1b));
  88    qdict_put_obj(req, "arguments", QOBJECT(args));
  89
  90    qdict_put_obj(req, "execute", QOBJECT(qstring_from_str("user_def_cmd2")));
  91
  92    /* TODO: put in full payload and check for errors */
  93    resp = qmp_dispatch(QOBJECT(req));
  94    assert(resp != NULL);
  95    assert(!qdict_haskey(qobject_to_qdict(resp), "error"));
  96
  97    qobject_decref(resp);
  98    QDECREF(req);
  99}
 100
 101/* test generated dealloc functions for generated types */
 102static void test_dealloc_types(void)
 103{
 104    UserDefOne *ud1test, *ud1a, *ud1b;
 105    UserDefOneList *ud1list;
 106
 107    ud1test = g_malloc0(sizeof(UserDefOne));
 108    ud1test->integer = 42;
 109    ud1test->string = g_strdup("hi there 42");
 110
 111    qapi_free_UserDefOne(ud1test);
 112
 113    ud1a = g_malloc0(sizeof(UserDefOne));
 114    ud1a->integer = 43;
 115    ud1a->string = g_strdup("hi there 43");
 116
 117    ud1b = g_malloc0(sizeof(UserDefOne));
 118    ud1b->integer = 44;
 119    ud1b->string = g_strdup("hi there 44");
 120
 121    ud1list = g_malloc0(sizeof(UserDefOneList));
 122    ud1list->value = ud1a;
 123    ud1list->next = g_malloc0(sizeof(UserDefOneList));
 124    ud1list->next->value = ud1b;
 125
 126    qapi_free_UserDefOneList(ud1list);
 127}
 128
 129/* test generated deallocation on an object whose construction was prematurely
 130 * terminated due to an error */
 131static void test_dealloc_partial(void)
 132{
 133    static const char text[] = "don't leak me";
 134
 135    UserDefTwo *ud2 = NULL;
 136    Error *err = NULL;
 137
 138    /* create partial object */
 139    {
 140        QDict *ud2_dict;
 141        QmpInputVisitor *qiv;
 142
 143        ud2_dict = qdict_new();
 144        qdict_put_obj(ud2_dict, "string", QOBJECT(qstring_from_str(text)));
 145
 146        qiv = qmp_input_visitor_new(QOBJECT(ud2_dict));
 147        visit_type_UserDefTwo(qmp_input_get_visitor(qiv), &ud2, NULL, &err);
 148        qmp_input_visitor_cleanup(qiv);
 149        QDECREF(ud2_dict);
 150    }
 151
 152    /* verify partial success */
 153    assert(ud2 != NULL);
 154    assert(ud2->string != NULL);
 155    assert(strcmp(ud2->string, text) == 0);
 156    assert(ud2->dict.dict.userdef == NULL);
 157
 158    /* confirm & release construction error */
 159    assert(err != NULL);
 160    error_free(err);
 161
 162    /* tear down partial object */
 163    qapi_free_UserDefTwo(ud2);
 164}
 165
 166
 167int main(int argc, char **argv)
 168{
 169    g_test_init(&argc, &argv, NULL);
 170
 171    g_test_add_func("/0.15/dispatch_cmd", test_dispatch_cmd);
 172    g_test_add_func("/0.15/dispatch_cmd_error", test_dispatch_cmd_error);
 173    g_test_add_func("/0.15/dispatch_cmd_io", test_dispatch_cmd_io);
 174    g_test_add_func("/0.15/dealloc_types", test_dealloc_types);
 175    g_test_add_func("/0.15/dealloc_partial", test_dealloc_partial);
 176
 177    module_call_init(MODULE_INIT_QAPI);
 178    g_test_run();
 179
 180    return 0;
 181}
 182