On Sun, Mar 15, 2020 at 3:55 PM Markus Armbruster <arm...@redhat.com> wrote: > > Building requests with qdict_put() & friends is tedious to write and > hard to read. Parse them from string literals with > qdict_from_vjsonf_nofail() instead. > > Signed-off-by: Markus Armbruster <arm...@redhat.com>
& fixes the leak introduced in patch 5. Reviewed-by: Marc-André Lureau <marcandre.lur...@redhat.com> > --- > tests/test-qmp-cmds.c | 93 ++++++++++++++++++------------------------- > 1 file changed, 38 insertions(+), 55 deletions(-) > > diff --git a/tests/test-qmp-cmds.c b/tests/test-qmp-cmds.c > index 464b370189..99013ff37b 100644 > --- a/tests/test-qmp-cmds.c > +++ b/tests/test-qmp-cmds.c > @@ -1,5 +1,6 @@ > #include "qemu/osdep.h" > #include "qapi/qmp/qdict.h" > +#include "qapi/qmp/qjson.h" > #include "qapi/qmp/qnum.h" > #include "qapi/qmp/qstring.h" > #include "qapi/error.h" > @@ -145,11 +146,16 @@ __org_qemu_x_Union1 > *qmp___org_qemu_x_command(__org_qemu_x_EnumList *a, > } > > > -static QObject *do_qmp_dispatch(QDict *req, bool allow_oob) > +static QObject *do_qmp_dispatch(bool allow_oob, const char *template, ...) > { > - QDict *resp; > + va_list ap; > + QDict *req, *resp; > QObject *ret; > > + va_start(ap, template); > + req = qdict_from_vjsonf_nofail(template, ap); > + va_end(ap); > + > resp = qmp_dispatch(&qmp_commands, QOBJECT(req), allow_oob); > g_assert(resp); > ret = qdict_get(resp, "return"); > @@ -158,14 +164,21 @@ static QObject *do_qmp_dispatch(QDict *req, bool > allow_oob) > > qobject_ref(ret); > qobject_unref(resp); > + qobject_unref(req); > return ret; > } > > -static void do_qmp_dispatch_error(QDict *req, bool allow_oob, ErrorClass cls) > +static void do_qmp_dispatch_error(bool allow_oob, ErrorClass cls, > + const char *template, ...) > { > - QDict *resp; > + va_list ap; > + QDict *req, *resp; > QDict *error; > > + va_start(ap, template); > + req = qdict_from_vjsonf_nofail(template, ap); > + va_end(ap); > + > resp = qmp_dispatch(&qmp_commands, QOBJECT(req), allow_oob); > g_assert(resp); > error = qdict_get_qdict(resp, "error"); > @@ -177,59 +190,43 @@ static void do_qmp_dispatch_error(QDict *req, bool > allow_oob, ErrorClass cls) > g_assert(qdict_size(resp) == 1); > > qobject_unref(resp); > + qobject_unref(req); > } > > /* test commands with no input and no return value */ > static void test_dispatch_cmd(void) > { > - QDict *req = qdict_new(); > QDict *ret; > > - qdict_put_str(req, "execute", "user_def_cmd"); > - > - ret = qobject_to(QDict, do_qmp_dispatch(req, false)); > + ret = qobject_to(QDict, > + do_qmp_dispatch(false, > + "{ 'execute': 'user_def_cmd' }")); > assert(ret && qdict_size(ret) == 0); > - > qobject_unref(ret); > - qobject_unref(req); > } > > static void test_dispatch_cmd_oob(void) > { > - QDict *req = qdict_new(); > QDict *ret; > > - qdict_put_str(req, "exec-oob", "test-flags-command"); > - > - ret = qobject_to(QDict, do_qmp_dispatch(req, true)); > + ret = qobject_to(QDict, > + do_qmp_dispatch(true, > + "{ 'exec-oob': 'test-flags-command' > }")); > assert(ret && qdict_size(ret) == 0); > - > qobject_unref(ret); > - qobject_unref(req); > } > > /* test commands that return an error due to invalid parameters */ > static void test_dispatch_cmd_failure(void) > { > - QDict *req = qdict_new(); > - QDict *args = qdict_new(); > - > - qdict_put_str(req, "execute", "user_def_cmd2"); > - > - do_qmp_dispatch_error(req, false, ERROR_CLASS_GENERIC_ERROR); > - > - qobject_unref(req); > - > - /* check that with extra arguments it throws an error */ > - req = qdict_new(); > - qdict_put_int(args, "a", 66); > - qdict_put(req, "arguments", args); > - > - qdict_put_str(req, "execute", "user_def_cmd"); > - > - do_qmp_dispatch_error(req, false, ERROR_CLASS_GENERIC_ERROR); > - > - qobject_unref(req); > + /* missing arguments */ > + do_qmp_dispatch_error(false, ERROR_CLASS_GENERIC_ERROR, > + "{ 'execute': 'user_def_cmd2' }"); > + > + /* extra arguments */ > + do_qmp_dispatch_error(false, ERROR_CLASS_GENERIC_ERROR, > + "{ 'execute': 'user_def_cmd'," > + " 'arguments': { 'a': 66 } }"); > } > > static void test_dispatch_cmd_success_response(void) > @@ -246,26 +243,15 @@ static void test_dispatch_cmd_success_response(void) > /* 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 *args3 = qdict_new(); > - QDict *ud1a = qdict_new(); > - QDict *ud1b = qdict_new(); > QDict *ret, *ret_dict, *ret_dict_dict, *ret_dict_dict_userdef; > QDict *ret_dict_dict2, *ret_dict_dict2_userdef; > QNum *ret3; > int64_t val; > > - qdict_put_int(ud1a, "integer", 42); > - qdict_put_str(ud1a, "string", "hello"); > - qdict_put_int(ud1b, "integer", 422); > - qdict_put_str(ud1b, "string", "hello2"); > - qdict_put(args, "ud1a", ud1a); > - qdict_put(args, "ud1b", ud1b); > - qdict_put(req, "arguments", args); > - qdict_put_str(req, "execute", "user_def_cmd2"); > - > - ret = qobject_to(QDict, do_qmp_dispatch(req, false)); > + ret = qobject_to(QDict, do_qmp_dispatch(false, > + "{ 'execute': 'user_def_cmd2', 'arguments': {" > + " 'ud1a': { 'integer': 42, 'string': 'hello' }," > + " 'ud1b': { 'integer': 422, 'string': 'hello2' } } }")); > > assert(!strcmp(qdict_get_str(ret, "string0"), "blah1")); > ret_dict = qdict_get_qdict(ret, "dict1"); > @@ -282,11 +268,8 @@ static void test_dispatch_cmd_io(void) > assert(!strcmp(qdict_get_str(ret_dict_dict2, "string"), "blah4")); > qobject_unref(ret); > > - qdict_put_int(args3, "a", 66); > - qdict_put(req, "arguments", args3); > - qdict_put_str(req, "execute", "guest-get-time"); > - > - ret3 = qobject_to(QNum, do_qmp_dispatch(req, false)); > + ret3 = qobject_to(QNum, do_qmp_dispatch(false, > + "{ 'execute': 'guest-get-time', 'arguments': { 'a': 66 } }")); > g_assert(qnum_get_try_int(ret3, &val)); > g_assert_cmpint(val, ==, 66); > qobject_unref(ret3); > -- > 2.21.1 > > -- Marc-André Lureau