Add new DO_TEST_CAPS_LATEST_NBDKIT macro to test xml2argv for various
nbdkit capability scenarios.

Signed-off-by: Jonathon Jongsma <jjong...@redhat.com>
Reviewed-by: Peter Krempa <pkre...@redhat.com>
---
 src/qemu/qemu_nbdkit.c   | 20 +++++++++++++++++---
 tests/qemuxml2argvtest.c | 11 +++++++++++
 tests/testutilsqemu.c    | 26 ++++++++++++++++++++++++++
 tests/testutilsqemu.h    |  4 ++++
 4 files changed, 58 insertions(+), 3 deletions(-)

diff --git a/src/qemu/qemu_nbdkit.c b/src/qemu/qemu_nbdkit.c
index 2d70e72c42..81861bae4a 100644
--- a/src/qemu/qemu_nbdkit.c
+++ b/src/qemu/qemu_nbdkit.c
@@ -290,10 +290,16 @@ virNbkditCapsCheckModdir(const char *moddir,
 
 static bool
 virNbdkitCapsIsValid(void *data,
-                     void *privData G_GNUC_UNUSED)
+                     void *privData)
 {
     qemuNbdkitCaps *nbdkitCaps = data;
     struct stat st;
+    /* when run under test, we will use privData as a signal to indicate that
+     * we shouldn't touch the filesystem */
+    bool skipValidation = (privData != NULL);
+
+    if (skipValidation)
+        return true;
 
     if (!nbdkitCaps->path)
         return true;
@@ -334,9 +340,17 @@ virNbdkitCapsIsValid(void *data,
 
 static void*
 virNbdkitCapsNewData(const char *binary,
-                     void *privData G_GNUC_UNUSED)
+                     void *privData)
 {
-    qemuNbdkitCaps *caps = qemuNbdkitCapsNew(binary);
+    /* when run under test, we will use privData as a signal to indicate that
+     * we shouldn't touch the filesystem */
+    bool skipNewData = (privData != NULL);
+    qemuNbdkitCaps *caps = NULL;
+
+    if (skipNewData)
+        return NULL;
+
+    caps = qemuNbdkitCapsNew(binary);
     qemuNbdkitCapsQuery(caps);
 
     return caps;
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index 1b76b32812..d64c21ae17 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -611,6 +611,14 @@ testCompareXMLToArgv(const void *data)
     if (qemuTestCapsCacheInsert(driver.qemuCapsCache, info->qemuCaps) < 0)
         goto cleanup;
 
+    if (info->nbdkitCaps) {
+        if (virFileCacheInsertData(driver.nbdkitCapsCache, TEST_NBDKIT_PATH,
+                                   g_object_ref(info->nbdkitCaps)) < 0) {
+            g_object_unref(info->nbdkitCaps);
+            goto cleanup;
+        }
+    }
+
     if (info->migrateFrom &&
         !(migrateURI = qemuMigrationDstGetURI(info->migrateFrom,
                                               info->migrateFd)))
@@ -831,6 +839,9 @@ mymain(void)
 # define DO_TEST_CAPS_ARCH_VER(name, arch, ver) \
     DO_TEST_CAPS_ARCH_VER_FULL(name, arch, ver, ARG_END)
 
+# define DO_TEST_CAPS_LATEST_NBDKIT(name, ...) \
+    DO_TEST_CAPS_ARCH_LATEST_FULL(name, "x86_64", ARG_NBDKIT_CAPS, 
__VA_ARGS__, QEMU_NBDKIT_CAPS_LAST, ARG_END)
+
 # define DO_TEST_CAPS_LATEST(name) \
     DO_TEST_CAPS_ARCH_LATEST(name, "x86_64")
 
diff --git a/tests/testutilsqemu.c b/tests/testutilsqemu.c
index fdbad16abe..9a607ab5a3 100644
--- a/tests/testutilsqemu.c
+++ b/tests/testutilsqemu.c
@@ -50,6 +50,10 @@ virFindFileInPath(const char *file)
         return g_strdup_printf("/usr/bin/%s", file);
     }
 
+    if (g_str_equal(file, "nbdkit")) {
+        return g_strdup(TEST_NBDKIT_PATH);
+    }
+
     /* Nothing in tests should be relying on real files
      * in host OS, so we return NULL to try to force
      * an error in such a case
@@ -288,6 +292,7 @@ void qemuTestDriverFree(virQEMUDriver *driver)
     virObjectUnref(driver->caps);
     virObjectUnref(driver->config);
     virObjectUnref(driver->securityManager);
+    g_clear_object(&driver->nbdkitCapsCache);
 
     virCPUDefFree(cpuDefault);
     virCPUDefFree(cpuHaswell);
@@ -487,6 +492,12 @@ int qemuTestDriverInit(virQEMUDriver *driver)
     if (!driver->qemuCapsCache)
         goto error;
 
+    driver->nbdkitCapsCache = qemuNbdkitCapsCacheNew("/dev/null");
+    /* the nbdkitCapsCache just interprets the presence of a non-null private
+     * data pointer as a signal to skip cache validation. This prevents the
+     * cache from trying to validate the plugindir mtime, etc during test */
+    virFileCacheSetPriv(driver->nbdkitCapsCache, GUINT_TO_POINTER(1));
+
     driver->xmlopt = virQEMUDriverCreateXMLConf(driver, "none");
     if (!driver->xmlopt)
         goto error;
@@ -780,6 +791,14 @@ testQemuInfoSetArgs(struct testQemuInfo *info,
                 ignore_value(virBitmapSetBit(info->args.fakeCapsDel, flag));
             break;
 
+        case ARG_NBDKIT_CAPS:
+            if (!(info->args.fakeNbdkitCaps))
+                info->args.fakeNbdkitCaps = 
virBitmapNew(QEMU_NBDKIT_CAPS_LAST);
+
+            while ((flag = va_arg(argptr, int)) < QEMU_NBDKIT_CAPS_LAST)
+                ignore_value(virBitmapSetBit(info->args.fakeNbdkitCaps, flag));
+            break;
+
         case ARG_GIC:
             info->args.gic = va_arg(argptr, int);
             break;
@@ -1054,6 +1073,11 @@ testQemuInfoInitArgs(struct testQemuInfo *info)
     for (cap = -1; (cap = virBitmapNextSetBit(info->args.fakeCapsDel, cap)) >= 
0;)
         virQEMUCapsClear(info->qemuCaps, cap);
 
+    info->nbdkitCaps = qemuNbdkitCapsNew(TEST_NBDKIT_PATH);
+
+    for (cap = -1; (cap = virBitmapNextSetBit(info->args.fakeNbdkitCaps, cap)) 
>= 0;)
+        qemuNbdkitCapsSet(info->nbdkitCaps, cap);
+
     if (info->args.gic != GIC_NONE &&
         testQemuCapsSetGIC(info->qemuCaps, info->args.gic) < 0)
         return -1;
@@ -1072,6 +1096,8 @@ testQemuInfoClear(struct testQemuInfo *info)
     g_clear_pointer(&info->args.fakeCapsAdd, virBitmapFree);
     g_clear_pointer(&info->args.fakeCapsDel, virBitmapFree);
     g_clear_pointer(&info->args.fds, g_hash_table_unref);
+    g_clear_object(&info->nbdkitCaps);
+    g_clear_pointer(&info->args.fakeNbdkitCaps, virBitmapFree);
 }
 
 
diff --git a/tests/testutilsqemu.h b/tests/testutilsqemu.h
index 7845ac7cb6..ad6874fdc3 100644
--- a/tests/testutilsqemu.h
+++ b/tests/testutilsqemu.h
@@ -28,6 +28,7 @@
 # define TEST_TPM_ENV_VAR "VIR_TEST_MOCK_FAKE_TPM_VERSION"
 # define TPM_VER_1_2 "1.2"
 # define TPM_VER_2_0 "2.0"
+# define TEST_NBDKIT_PATH "/fakebindir/nbdkit"
 
 enum {
     GIC_NONE = 0,
@@ -49,6 +50,7 @@ typedef enum {
     ARG_CAPS_VARIANT,
     ARG_CAPS_HOST_CPU_MODEL,
     ARG_FD_GROUP, /* name, nfds, fd[0], ... fd[n-1] */
+    ARG_NBDKIT_CAPS,
     ARG_END,
 } testQemuInfoArgName;
 
@@ -80,6 +82,7 @@ struct testQemuArgs {
     bool newargs;
     virBitmap *fakeCapsAdd;
     virBitmap *fakeCapsDel;
+    virBitmap *fakeNbdkitCaps;
     char *capsver;
     char *capsarch;
     const char *capsvariant;
@@ -95,6 +98,7 @@ struct testQemuInfo {
     char *outfile;
     char *errfile;
     virQEMUCaps *qemuCaps;
+    qemuNbdkitCaps *nbdkitCaps;
     const char *migrateFrom;
     int migrateFd;
     unsigned int flags;
-- 
2.41.0

Reply via email to