From e32f6e778b25b8be580d1116dd1f821927e59218 Mon Sep 17 00:00:00 2001 From: Peter Krempa Date: Thu, 25 Jul 2013 15:42:38 +0200 Subject: [PATCH] qemumonitortestutils: Add the ability to check arguments of commands This patch adds helpers that allow to check for argument values in commands sent to the monitor. --- tests/qemumonitortestutils.c | 174 +++++++++++++++++++++++++++++++++-- tests/qemumonitortestutils.h | 6 ++ 2 files changed, 171 insertions(+), 9 deletions(-) diff --git a/tests/qemumonitortestutils.c b/tests/qemumonitortestutils.c index 721b7c6550..fb76156a57 100644 --- a/tests/qemumonitortestutils.c +++ b/tests/qemumonitortestutils.c @@ -414,18 +414,47 @@ qemuMonitorTestItemGetPrivateData(qemuMonitorTestItemPtr item) } -struct qemuMonitorTestDefaultHandlerData { - const char *command_name; - const char *response; +typedef struct _qemuMonitorTestCommandArgs qemuMonitorTestCommandArgs; +typedef qemuMonitorTestCommandArgs *qemuMonitorTestCommandArgsPtr; +struct _qemuMonitorTestCommandArgs { + char *argname; + char *argval; }; +struct qemuMonitorTestHandlerData { + char *command_name; + char *response; + size_t nargs; + qemuMonitorTestCommandArgsPtr args; +}; + +static void +qemuMonitorTestHandlerDataFree(void *opaque) +{ + struct qemuMonitorTestHandlerData *data = opaque; + size_t i; + + if (!data) + return; + + for (i = 0; i < data->nargs; i++) { + VIR_FREE(data->args[i].argname); + VIR_FREE(data->args[i].argval); + } + + VIR_FREE(data->command_name); + VIR_FREE(data->response); + VIR_FREE(data->args); + VIR_FREE(data); +} + static int qemuMonitorTestProcessCommandDefault(qemuMonitorTestPtr test, qemuMonitorTestItemPtr item, const char *cmdstr) { - struct qemuMonitorTestDefaultHandlerData *data = item->opaque; + struct qemuMonitorTestHandlerData *data = item->opaque; virJSONValuePtr val = NULL; char *cmdcopy = NULL; const char *cmdname; @@ -472,18 +501,20 @@ qemuMonitorTestAddItem(qemuMonitorTestPtr test, const char *command_name, const char *response) { - struct qemuMonitorTestDefaultHandlerData *data; + struct qemuMonitorTestHandlerData *data; if (VIR_ALLOC(data) < 0) return -1; - data->command_name = command_name; - data->response = response; + if (VIR_STRDUP(data->command_name, command_name) < 0 || + VIR_STRDUP(data->response, response) < 0) { + qemuMonitorTestHandlerDataFree(data); + return -1; + } return qemuMonitorTestAddHandler(test, qemuMonitorTestProcessCommandDefault, - data, - free); + data, qemuMonitorTestHandlerDataFree); } @@ -550,6 +581,131 @@ qemuMonitorTestAddAgentSyncResponse(qemuMonitorTestPtr test) } +static int +qemuMonitorTestProcessCommandWithArgs(qemuMonitorTestPtr test, + qemuMonitorTestItemPtr item, + const char *cmdstr) +{ + struct qemuMonitorTestHandlerData *data = item->opaque; + virJSONValuePtr val = NULL; + virJSONValuePtr args; + virJSONValuePtr argobj; + char *argstr = NULL; + const char *cmdname; + size_t i; + int ret = -1; + + if (!(val = virJSONValueFromString(cmdstr))) + return -1; + + if (!(cmdname = virJSONValueObjectGetString(val, "execute"))) { + ret = qemuMonitorReportError(test, "Missing command name in %s", cmdstr); + goto cleanup; + } + + if (STRNEQ(data->command_name, cmdname)) { + ret = qemuMonitorTestAddUnexpectedErrorResponse(test); + goto cleanup; + } + + if (!(args = virJSONValueObjectGet(val, "arguments"))) { + ret = qemuMonitorReportError(test, + "Missing arguments section for command '%s'", + data->command_name); + goto cleanup; + } + + /* validate the args */ + for (i = 0; i < data->nargs; i++) { + qemuMonitorTestCommandArgsPtr arg = &data->args[i]; + if (!(argobj = virJSONValueObjectGet(args, arg->argname))) { + ret = qemuMonitorReportError(test, + "Missing argument '%s' for command '%s'", + arg->argname, data->command_name); + goto cleanup; + } + + /* convert the argument to string */ + if (!(argstr = virJSONValueToString(argobj, false))) + goto cleanup; + + /* verify that the argument value is expected */ + if (STRNEQ(argstr, arg->argval)) { + ret = qemuMonitorReportError(test, + "Invalid value of argument '%s' " + "of command '%s': " + "expected '%s' got '%s'", + arg->argname, data->command_name, + arg->argval, argstr); + goto cleanup; + } + + VIR_FREE(argstr); + } + + /* arguments checked out, return the response */ + ret = qemuMonitorTestAddReponse(test, data->response); + +cleanup: + VIR_FREE(argstr); + virJSONValueFree(val); + return ret; +} + + +/* this allows to add a responder that is able to check + * a (shallow) structure of arguments for a command */ +int +qemuMonitorTestAddItemParams(qemuMonitorTestPtr test, + const char *cmdname, + const char *response, + ...) +{ + struct qemuMonitorTestHandlerData *data; + const char *argname; + const char *argval; + va_list args; + + va_start(args, response); + + if (VIR_ALLOC(data) < 0) + return -1; + + if (VIR_STRDUP(data->command_name, cmdname) < 0 || + VIR_STRDUP(data->response, response) < 0) + goto error; + + while ((argname = va_arg(args, char *))) { + size_t i; + if (!(argval = va_arg(args, char *))) { + virReportError(VIR_ERR_INTERNAL_ERROR, + "Missing argument value for argument '%s'", + argname); + goto error; + } + + i = data->nargs; + if (VIR_EXPAND_N(data->args, data->nargs, 1)) + goto error; + + if (VIR_STRDUP(data->args[i].argname, argname) < 0 || + VIR_STRDUP(data->args[i].argval, argval) < 0) + goto error; + } + + va_end(args); + + return qemuMonitorTestAddHandler(test, + qemuMonitorTestProcessCommandWithArgs, + data, qemuMonitorTestHandlerDataFree); + +error: + va_end(args); + qemuMonitorTestHandlerDataFree(data); + return -1; +} + + static void qemuMonitorTestEOFNotify(qemuMonitorPtr mon ATTRIBUTE_UNUSED, virDomainObjPtr vm ATTRIBUTE_UNUSED) diff --git a/tests/qemumonitortestutils.h b/tests/qemumonitortestutils.h index 5e90150b67..1122409bd4 100644 --- a/tests/qemumonitortestutils.h +++ b/tests/qemumonitortestutils.h @@ -53,6 +53,12 @@ int qemuMonitorTestAddItem(qemuMonitorTestPtr test, int qemuMonitorTestAddAgentSyncResponse(qemuMonitorTestPtr test); +int qemuMonitorTestAddItemParams(qemuMonitorTestPtr test, + const char *cmdname, + const char *response, + ...) + ATTRIBUTE_SENTINEL; + qemuMonitorTestPtr qemuMonitorTestNew(bool json, virDomainXMLOptionPtr xmlopt);