mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-01 17:35:17 +00:00
qemumonitortestutils: Refactor the test helpers to allow reuse
Refactor the test helpers to allow adding callbacks to verify the monitor responses instead of simple command name checking and clean up various parts to prepare for adding guest agent tests.
This commit is contained in:
parent
3383480430
commit
5467cbef4b
@ -36,12 +36,10 @@
|
|||||||
|
|
||||||
#define VIR_FROM_THIS VIR_FROM_NONE
|
#define VIR_FROM_THIS VIR_FROM_NONE
|
||||||
|
|
||||||
typedef struct _qemuMonitorTestItem qemuMonitorTestItem;
|
|
||||||
typedef qemuMonitorTestItem *qemuMonitorTestItemPtr;
|
|
||||||
|
|
||||||
struct _qemuMonitorTestItem {
|
struct _qemuMonitorTestItem {
|
||||||
char *command_name;
|
qemuMonitorTestResponseCallback cb;
|
||||||
char *response;
|
void *opaque;
|
||||||
|
virFreeCallback freecb;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _qemuMonitorTest {
|
struct _qemuMonitorTest {
|
||||||
@ -74,13 +72,23 @@ struct _qemuMonitorTest {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static void qemuMonitorTestItemFree(qemuMonitorTestItemPtr item);
|
static void
|
||||||
|
qemuMonitorTestItemFree(qemuMonitorTestItemPtr item)
|
||||||
|
{
|
||||||
|
if (!item)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (item->freecb)
|
||||||
|
(item->freecb)(item->opaque);
|
||||||
|
|
||||||
|
VIR_FREE(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Appends data for a reply to the outgoing buffer
|
* Appends data for a reply to the outgoing buffer
|
||||||
*/
|
*/
|
||||||
static int
|
int
|
||||||
qemuMonitorTestAddReponse(qemuMonitorTestPtr test,
|
qemuMonitorTestAddReponse(qemuMonitorTestPtr test,
|
||||||
const char *response)
|
const char *response)
|
||||||
{
|
{
|
||||||
@ -101,81 +109,17 @@ qemuMonitorTestAddReponse(qemuMonitorTestPtr test,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Processes a single line, looking for a matching expected
|
|
||||||
* item to reply with, else replies with an error
|
|
||||||
*/
|
|
||||||
static int
|
static int
|
||||||
qemuMonitorTestProcessCommandJSON(qemuMonitorTestPtr test,
|
qemuMonitorTestAddUnexpectedErrorResponse(qemuMonitorTestPtr test)
|
||||||
const char *cmdstr)
|
|
||||||
{
|
{
|
||||||
virJSONValuePtr val;
|
if (test->json) {
|
||||||
const char *cmdname;
|
return qemuMonitorTestAddReponse(test,
|
||||||
int ret = -1;
|
"{ \"error\": "
|
||||||
|
" { \"desc\": \"Unexpected command\", "
|
||||||
if (!(val = virJSONValueFromString(cmdstr)))
|
" \"class\": \"UnexpectedCommand\" } }");
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (!(cmdname = virJSONValueObjectGetString(val, "execute"))) {
|
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
||||||
"Missing command name in %s", cmdstr);
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (test->nitems == 0 ||
|
|
||||||
STRNEQ(test->items[0]->command_name, cmdname)) {
|
|
||||||
ret = qemuMonitorTestAddReponse(test,
|
|
||||||
"{ \"error\": "
|
|
||||||
" { \"desc\": \"Unexpected command\", "
|
|
||||||
" \"class\": \"UnexpectedCommand\" } }");
|
|
||||||
} else {
|
} else {
|
||||||
ret = qemuMonitorTestAddReponse(test, test->items[0]->response);
|
return qemuMonitorTestAddReponse(test, "unexpected command");
|
||||||
qemuMonitorTestItemFree(test->items[0]);
|
|
||||||
if (VIR_DELETE_ELEMENT(test->items, 0, test->nitems) < 0) {
|
|
||||||
ret = -1;
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanup:
|
|
||||||
virJSONValueFree(val);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
qemuMonitorTestProcessCommandText(qemuMonitorTestPtr test,
|
|
||||||
const char *cmdstr)
|
|
||||||
{
|
|
||||||
char *tmp;
|
|
||||||
char *cmdname;
|
|
||||||
int ret = -1;
|
|
||||||
|
|
||||||
if (VIR_STRDUP(cmdname, cmdstr) < 0)
|
|
||||||
return -1;
|
|
||||||
if (!(tmp = strchr(cmdname, ' '))) {
|
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
||||||
"Cannot find command name in '%s'", cmdstr);
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
*tmp = '\0';
|
|
||||||
|
|
||||||
if (test->nitems == 0 ||
|
|
||||||
STRNEQ(test->items[0]->command_name, cmdname)) {
|
|
||||||
ret = qemuMonitorTestAddReponse(test,
|
|
||||||
"unexpected command");
|
|
||||||
} else {
|
|
||||||
ret = qemuMonitorTestAddReponse(test, test->items[0]->response);
|
|
||||||
qemuMonitorTestItemFree(test->items[0]);
|
|
||||||
if (VIR_DELETE_ELEMENT(test->items, 0, test->nitems) < 0) {
|
|
||||||
ret = -1;
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cleanup:
|
|
||||||
VIR_FREE(cmdname);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -183,10 +127,19 @@ static int
|
|||||||
qemuMonitorTestProcessCommand(qemuMonitorTestPtr test,
|
qemuMonitorTestProcessCommand(qemuMonitorTestPtr test,
|
||||||
const char *cmdstr)
|
const char *cmdstr)
|
||||||
{
|
{
|
||||||
if (test->json)
|
int ret;
|
||||||
return qemuMonitorTestProcessCommandJSON(test ,cmdstr);
|
|
||||||
else
|
if (test->nitems == 0) {
|
||||||
return qemuMonitorTestProcessCommandText(test ,cmdstr);
|
return qemuMonitorTestAddUnexpectedErrorResponse(test);
|
||||||
|
} else {
|
||||||
|
qemuMonitorTestItemPtr item = test->items[0];
|
||||||
|
ret = (item->cb)(test, item, cmdstr);
|
||||||
|
qemuMonitorTestItemFree(item);
|
||||||
|
if (VIR_DELETE_ELEMENT(test->items, 0, test->nitems) < 0)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -316,19 +269,6 @@ qemuMonitorTestWorker(void *opaque)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
qemuMonitorTestItemFree(qemuMonitorTestItemPtr item)
|
|
||||||
{
|
|
||||||
if (!item)
|
|
||||||
return;
|
|
||||||
|
|
||||||
VIR_FREE(item->command_name);
|
|
||||||
VIR_FREE(item->response);
|
|
||||||
|
|
||||||
VIR_FREE(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
qemuMonitorTestFreeTimer(int timer ATTRIBUTE_UNUSED,
|
qemuMonitorTestFreeTimer(int timer ATTRIBUTE_UNUSED,
|
||||||
void *opaque ATTRIBUTE_UNUSED)
|
void *opaque ATTRIBUTE_UNUSED)
|
||||||
@ -392,18 +332,19 @@ qemuMonitorTestFree(qemuMonitorTestPtr test)
|
|||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
qemuMonitorTestAddItem(qemuMonitorTestPtr test,
|
qemuMonitorTestAddHandler(qemuMonitorTestPtr test,
|
||||||
const char *command_name,
|
qemuMonitorTestResponseCallback cb,
|
||||||
const char *response)
|
void *opaque,
|
||||||
|
virFreeCallback freecb)
|
||||||
{
|
{
|
||||||
qemuMonitorTestItemPtr item;
|
qemuMonitorTestItemPtr item;
|
||||||
|
|
||||||
if (VIR_ALLOC(item) < 0)
|
if (VIR_ALLOC(item) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (VIR_STRDUP(item->command_name, command_name) < 0 ||
|
item->cb = cb;
|
||||||
VIR_STRDUP(item->response, response) < 0)
|
item->freecb = freecb;
|
||||||
goto error;
|
item->opaque = opaque;
|
||||||
|
|
||||||
virMutexLock(&test->lock);
|
virMutexLock(&test->lock);
|
||||||
if (VIR_APPEND_ELEMENT(test->items, test->nitems, item) < 0) {
|
if (VIR_APPEND_ELEMENT(test->items, test->nitems, item) < 0) {
|
||||||
@ -415,10 +356,91 @@ qemuMonitorTestAddItem(qemuMonitorTestPtr test,
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
qemuMonitorTestItemFree(item);
|
if (freecb)
|
||||||
|
(freecb)(opaque);
|
||||||
|
VIR_FREE(item);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
qemuMonitorTestItemGetPrivateData(qemuMonitorTestItemPtr item)
|
||||||
|
{
|
||||||
|
return item ? item->opaque : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct qemuMonitorTestDefaultHandlerData {
|
||||||
|
const char *command_name;
|
||||||
|
const char *response;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
qemuMonitorTestProcessCommandDefault(qemuMonitorTestPtr test,
|
||||||
|
qemuMonitorTestItemPtr item,
|
||||||
|
const char *cmdstr)
|
||||||
|
{
|
||||||
|
struct qemuMonitorTestDefaultHandlerData *data = item->opaque;
|
||||||
|
virJSONValuePtr val = NULL;
|
||||||
|
char *cmdcopy = NULL;
|
||||||
|
const char *cmdname;
|
||||||
|
char *tmp;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
if (test->json) {
|
||||||
|
if (!(val = virJSONValueFromString(cmdstr)))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (!(cmdname = virJSONValueObjectGetString(val, "execute"))) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
"Missing command name in %s", cmdstr);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (VIR_STRDUP(cmdcopy, cmdstr) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
cmdname = cmdcopy;
|
||||||
|
|
||||||
|
if (!(tmp = strchr(cmdcopy, ' '))) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
"Cannot find command name in '%s'", cmdstr);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
*tmp = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (STRNEQ(data->command_name, cmdname))
|
||||||
|
ret = qemuMonitorTestAddUnexpectedErrorResponse(test);
|
||||||
|
else
|
||||||
|
ret = qemuMonitorTestAddReponse(test, data->response);
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
VIR_FREE(cmdcopy);
|
||||||
|
virJSONValueFree(val);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
qemuMonitorTestAddItem(qemuMonitorTestPtr test,
|
||||||
|
const char *command_name,
|
||||||
|
const char *response)
|
||||||
|
{
|
||||||
|
struct qemuMonitorTestDefaultHandlerData *data;
|
||||||
|
|
||||||
|
if (VIR_ALLOC(data) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
data->command_name = command_name;
|
||||||
|
data->response = response;
|
||||||
|
|
||||||
|
return qemuMonitorTestAddHandler(test,
|
||||||
|
qemuMonitorTestProcessCommandDefault,
|
||||||
|
data,
|
||||||
|
free);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
qemuMonitorTestEOFNotify(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
|
qemuMonitorTestEOFNotify(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
|
||||||
@ -434,7 +456,7 @@ qemuMonitorTestErrorNotify(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static qemuMonitorCallbacks qemuCallbacks = {
|
static qemuMonitorCallbacks qemuMonitorTestCallbacks = {
|
||||||
.eofNotify = qemuMonitorTestEOFNotify,
|
.eofNotify = qemuMonitorTestEOFNotify,
|
||||||
.errorNotify = qemuMonitorTestErrorNotify,
|
.errorNotify = qemuMonitorTestErrorNotify,
|
||||||
};
|
};
|
||||||
@ -502,6 +524,8 @@ error:
|
|||||||
static int
|
static int
|
||||||
qemuMonitorCommonTestInit(qemuMonitorTestPtr test)
|
qemuMonitorCommonTestInit(qemuMonitorTestPtr test)
|
||||||
{
|
{
|
||||||
|
int events = VIR_EVENT_HANDLE_READABLE;
|
||||||
|
|
||||||
if (!test)
|
if (!test)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@ -511,8 +535,11 @@ qemuMonitorCommonTestInit(qemuMonitorTestPtr test)
|
|||||||
if (!test->client)
|
if (!test->client)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
if (test->outgoingLength > 0)
|
||||||
|
events = VIR_EVENT_HANDLE_WRITABLE;
|
||||||
|
|
||||||
if (virNetSocketAddIOCallback(test->client,
|
if (virNetSocketAddIOCallback(test->client,
|
||||||
VIR_EVENT_HANDLE_WRITABLE,
|
events,
|
||||||
qemuMonitorTestIO,
|
qemuMonitorTestIO,
|
||||||
test,
|
test,
|
||||||
NULL) < 0)
|
NULL) < 0)
|
||||||
@ -566,7 +593,7 @@ qemuMonitorTestNew(bool json, virDomainXMLOptionPtr xmlopt)
|
|||||||
if (!(test->mon = qemuMonitorOpen(test->vm,
|
if (!(test->mon = qemuMonitorOpen(test->vm,
|
||||||
&src,
|
&src,
|
||||||
json,
|
json,
|
||||||
&qemuCallbacks)))
|
&qemuMonitorTestCallbacks)))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
virObjectLock(test->mon);
|
virObjectLock(test->mon);
|
||||||
|
@ -26,6 +26,23 @@
|
|||||||
typedef struct _qemuMonitorTest qemuMonitorTest;
|
typedef struct _qemuMonitorTest qemuMonitorTest;
|
||||||
typedef qemuMonitorTest *qemuMonitorTestPtr;
|
typedef qemuMonitorTest *qemuMonitorTestPtr;
|
||||||
|
|
||||||
|
typedef struct _qemuMonitorTestItem qemuMonitorTestItem;
|
||||||
|
typedef qemuMonitorTestItem *qemuMonitorTestItemPtr;
|
||||||
|
typedef int (*qemuMonitorTestResponseCallback)(qemuMonitorTestPtr test,
|
||||||
|
qemuMonitorTestItemPtr item,
|
||||||
|
const char *message);
|
||||||
|
|
||||||
|
int qemuMonitorTestAddHandler(qemuMonitorTestPtr test,
|
||||||
|
qemuMonitorTestResponseCallback cb,
|
||||||
|
void *opaque,
|
||||||
|
virFreeCallback freecb);
|
||||||
|
|
||||||
|
int qemuMonitorTestAddReponse(qemuMonitorTestPtr test,
|
||||||
|
const char *response);
|
||||||
|
|
||||||
|
void *qemuMonitorTestItemGetPrivateData(qemuMonitorTestItemPtr item);
|
||||||
|
|
||||||
|
|
||||||
int qemuMonitorTestAddItem(qemuMonitorTestPtr test,
|
int qemuMonitorTestAddItem(qemuMonitorTestPtr test,
|
||||||
const char *command_name,
|
const char *command_name,
|
||||||
const char *response);
|
const char *response);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user