Make the parser reusable by extracting it and making it parse into command,reply tuples. Signed-off-by: Peter Krempa <pkrempa@xxxxxxxxxx> --- tests/qemumonitortestutils.c | 123 ++++++++++++++++++++++++----------- tests/qemumonitortestutils.h | 13 ++++ 2 files changed, 99 insertions(+), 37 deletions(-) diff --git a/tests/qemumonitortestutils.c b/tests/qemumonitortestutils.c index 0d99b45909..f7a0a37685 100644 --- a/tests/qemumonitortestutils.c +++ b/tests/qemumonitortestutils.c @@ -1278,45 +1278,33 @@ qemuMonitorTestFullAddItem(qemuMonitorTest *test, /** - * qemuMonitorTestNewFromFileFull: - * @fileName: File name to load monitor replies from - * @driver: qemu driver object - * @vm: domain object (may be null if it's not needed by the test) - * @qmpschema: QMP schema data hash table if QMP checking is required + * qemuMonitorTestProcessFileEntries: + * @inputstr: input file contents (modified) + * @fileName: File name of @inputstr (for error reporting) + * @items: filled with command, reply tuples + * @nitems: Count of elements in @items. * - * Create a JSON test monitor simulator object and fill it with expected command - * sequence and replies specified in @fileName. + * Process a monitor interaction file. * * The file contains a sequence of JSON commands and reply objects separated by - * empty lines. A command is followed by a reply. The QMP greeting is added - * automatically. - * - * Returns the monitor object on success; NULL on error. + * empty lines. A command is followed by a reply. */ -qemuMonitorTest * -qemuMonitorTestNewFromFileFull(const char *fileName, - virQEMUDriver *driver, - virDomainObj *vm, - GHashTable *qmpschema) +int +qemuMonitorTestProcessFileEntries(char *inputstr, + const char *fileName, + struct qemuMonitorTestCommandReplyTuple **items, + size_t *nitems) { - g_autoptr(qemuMonitorTest) ret = NULL; - g_autofree char *jsonstr = NULL; - char *tmp; + size_t nalloc = 0; + char *tmp = inputstr; size_t line = 0; - - char *command = NULL; + char *command = inputstr; char *response = NULL; size_t commandln = 0; - if (virTestLoadFile(fileName, &jsonstr) < 0) - return NULL; - - if (!(ret = qemuMonitorTestNew(driver->xmlopt, vm, driver, NULL, - qmpschema))) - return NULL; + *items = NULL; + *nitems = 0; - tmp = jsonstr; - command = tmp; while ((tmp = strchr(tmp, '\n'))) { line++; @@ -1335,11 +1323,16 @@ qemuMonitorTestNewFromFileFull(const char *fileName, *(tmp + 1) = '\0'; if (response) { - if (qemuMonitorTestFullAddItem(ret, fileName, command, - response, commandln) < 0) - return NULL; - command = NULL; - response = NULL; + struct qemuMonitorTestCommandReplyTuple *item; + + VIR_RESIZE_N(*items, nalloc, *nitems, 1); + + item = *items + *nitems; + + item->command = g_steal_pointer(&command); + item->reply = g_steal_pointer(&response); + item->line = commandln; + (*nitems)++; } /* Move the @tmp and @singleReply. */ @@ -1354,14 +1347,70 @@ qemuMonitorTestNewFromFileFull(const char *fileName, } if (command) { + struct qemuMonitorTestCommandReplyTuple *item; + if (!response) { virReportError(VIR_ERR_INTERNAL_ERROR, "missing response for command " "on line '%zu' in '%s'", commandln, fileName); - return NULL; + return -1; } - if (qemuMonitorTestFullAddItem(ret, fileName, command, - response, commandln) < 0) + VIR_RESIZE_N(*items, nalloc, *nitems, 1); + + item = *items + *nitems; + + item->command = g_steal_pointer(&command); + item->reply = g_steal_pointer(&response); + item->line = commandln; + (*nitems)++; + } + + return 0; +} + +/** + * qemuMonitorTestNewFromFileFull: + * @fileName: File name to load monitor replies from + * @driver: qemu driver object + * @vm: domain object (may be null if it's not needed by the test) + * @qmpschema: QMP schema data hash table if QMP checking is required + * + * Create a JSON test monitor simulator object and fill it with expected command + * sequence and replies specified in @fileName. + * + * The file contains a sequence of JSON commands and reply objects separated by + * empty lines. A command is followed by a reply. The QMP greeting is added + * automatically. + * + * Returns the monitor object on success; NULL on error. + */ +qemuMonitorTest * +qemuMonitorTestNewFromFileFull(const char *fileName, + virQEMUDriver *driver, + virDomainObj *vm, + GHashTable *qmpschema) +{ + g_autoptr(qemuMonitorTest) ret = NULL; + g_autofree char *jsonstr = NULL; + g_autofree struct qemuMonitorTestCommandReplyTuple *items = NULL; + size_t nitems = 0; + size_t i; + + if (virTestLoadFile(fileName, &jsonstr) < 0) + return NULL; + + if (!(ret = qemuMonitorTestNew(driver->xmlopt, vm, driver, NULL, + qmpschema))) + return NULL; + + if (qemuMonitorTestProcessFileEntries(jsonstr, fileName, &items, &nitems) < 0) + return NULL; + + for (i = 0; i < nitems; i++) { + struct qemuMonitorTestCommandReplyTuple *item = items + i; + + if (qemuMonitorTestFullAddItem(ret, fileName, item->command, item->reply, + item->line) < 0) return NULL; } diff --git a/tests/qemumonitortestutils.h b/tests/qemumonitortestutils.h index 89c33c434b..56e3d56056 100644 --- a/tests/qemumonitortestutils.h +++ b/tests/qemumonitortestutils.h @@ -126,3 +126,16 @@ virDomainObj * qemuMonitorTestGetDomainObj(qemuMonitorTest *test); G_DEFINE_AUTOPTR_CLEANUP_FUNC(qemuMonitorTest, qemuMonitorTestFree); + +struct qemuMonitorTestCommandReplyTuple { + const char *command; + const char *reply; + size_t line; /* line number of @command */ +}; + + +int +qemuMonitorTestProcessFileEntries(char *inputstr, + const char *fileName, + struct qemuMonitorTestCommandReplyTuple **items, + size_t *nitems); -- 2.31.1