[libvirt] [PATCH 10/20] qemumonitortestutils: Refactor the test helpers to allow reuse

Peter Krempa pkrempa at redhat.com
Tue Jul 30 13:05:45 UTC 2013


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.
---
 tests/qemumonitortestutils.c | 220 ++++++++++++++++++++++++-------------------
 1 file changed, 121 insertions(+), 99 deletions(-)

diff --git a/tests/qemumonitortestutils.c b/tests/qemumonitortestutils.c
index 1785293..941dfea 100644
--- a/tests/qemumonitortestutils.c
+++ b/tests/qemumonitortestutils.c
@@ -38,10 +38,14 @@

 typedef struct _qemuMonitorTestItem qemuMonitorTestItem;
 typedef qemuMonitorTestItem *qemuMonitorTestItemPtr;
+typedef int (*qemuMonitorTestResponseCallback)(qemuMonitorTestPtr test,
+                                               qemuMonitorTestItemPtr item,
+                                               const char *message);

 struct _qemuMonitorTestItem {
-    char *command_name;
-    char *response;
+    qemuMonitorTestResponseCallback cb;
+    void *opaque;
+    virFreeCallback freecb;
 };

 struct _qemuMonitorTest {
@@ -74,7 +78,17 @@ 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);
+}


 /*
@@ -101,95 +115,40 @@ qemuMonitorTestAddReponse(qemuMonitorTestPtr test,
 }


-/*
- * Processes a single line, looking for a matching expected
- * item to reply with, else replies with an error
- */
 static int
-qemuMonitorTestProcessCommandJSON(qemuMonitorTestPtr test,
-                                  const char *cmdstr)
+qemuMonitorTestAddUnexpectedErrorResponse(qemuMonitorTestPtr test)
 {
-    virJSONValuePtr val;
-    const char *cmdname;
-    int ret = -1;
-
-    if (!(val = virJSONValueFromString(cmdstr)))
-        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\" } }");
+    if (test->json) {
+        return qemuMonitorTestAddReponse(test,
+                                         "{ \"error\": "
+                                         " { \"desc\": \"Unexpected command\", "
+                                         "   \"class\": \"UnexpectedCommand\" } }");
     } 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;
-        }
+        return qemuMonitorTestAddReponse(test, "unexpected command");
     }
-
-cleanup:
-    virJSONValueFree(val);
-    return ret;
 }


 static int
-qemuMonitorTestProcessCommandText(qemuMonitorTestPtr test,
-                                  const char *cmdstr)
+qemuMonitorTestProcessCommand(qemuMonitorTestPtr test,
+                              const char *cmdstr)
 {
-    char *tmp;
-    char *cmdname;
-    int ret = -1;
+    int ret;

-    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");
+    if (test->nitems == 0) {
+        return qemuMonitorTestAddUnexpectedErrorResponse(test);
     } 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;
-        }
+        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;
     }

-cleanup:
-    VIR_FREE(cmdname);
     return ret;
 }


-static int
-qemuMonitorTestProcessCommand(qemuMonitorTestPtr test,
-                              const char *cmdstr)
-{
-    if (test->json)
-        return qemuMonitorTestProcessCommandJSON(test ,cmdstr);
-    else
-        return qemuMonitorTestProcessCommandText(test ,cmdstr);
-}
-
-
 /*
  * Handles read/write of monitor data on the monitor server side
  */
@@ -317,19 +276,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
 qemuMonitorTestFreeTimer(int timer ATTRIBUTE_UNUSED,
                          void *opaque ATTRIBUTE_UNUSED)
 {
@@ -391,19 +337,20 @@ qemuMonitorTestFree(qemuMonitorTestPtr test)
 }


-int
-qemuMonitorTestAddItem(qemuMonitorTestPtr test,
-                       const char *command_name,
-                       const char *response)
+static int
+qemuMonitorTestAddHandler(qemuMonitorTestPtr test,
+                          qemuMonitorTestResponseCallback cb,
+                          void *opaque,
+                          virFreeCallback freecb)
 {
     qemuMonitorTestItemPtr item;

     if (VIR_ALLOC(item) < 0)
         goto error;

-    if (VIR_STRDUP(item->command_name, command_name) < 0 ||
-        VIR_STRDUP(item->response, response) < 0)
-        goto error;
+    item->cb = cb;
+    item->freecb = freecb;
+    item->opaque = opaque;

     virMutexLock(&test->lock);
     if (VIR_APPEND_ELEMENT(test->items, test->nitems, item) < 0) {
@@ -415,11 +362,86 @@ qemuMonitorTestAddItem(qemuMonitorTestPtr test,
     return 0;

 error:
-    qemuMonitorTestItemFree(item);
+    if (freecb)
+        (freecb)(opaque);
+    VIR_FREE(item);
     return -1;
 }


+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
 qemuMonitorTestEOFNotify(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
                          virDomainObjPtr vm ATTRIBUTE_UNUSED)
@@ -434,7 +456,7 @@ qemuMonitorTestErrorNotify(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
 }


-static qemuMonitorCallbacks qemuCallbacks = {
+static qemuMonitorCallbacks qemuMonitorTestCallbacks = {
     .eofNotify = qemuMonitorTestEOFNotify,
     .errorNotify = qemuMonitorTestErrorNotify,
 };
@@ -512,7 +534,7 @@ qemuMonitorCommonTestInit(qemuMonitorTestPtr test)
         goto error;

     if (virNetSocketAddIOCallback(test->client,
-                                  VIR_EVENT_HANDLE_WRITABLE,
+                                  test->outgoingLength > 0 ? VIR_EVENT_HANDLE_WRITABLE : VIR_EVENT_HANDLE_READABLE,
                                   qemuMonitorTestIO,
                                   test,
                                   NULL) < 0)
@@ -554,7 +576,7 @@ qemuMonitorTestNew(bool json, virDomainXMLOptionPtr xmlopt)
     if (!(test->mon = qemuMonitorOpen(test->vm,
                                       &src,
                                       json,
-                                      &qemuCallbacks)))
+                                      &qemuMonitorTestCallbacks)))
         goto error;

     virObjectLock(test->mon);
-- 
1.8.3.2




More information about the libvir-list mailing list