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 3bf4754011..98931952e9 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -547,6 +547,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))) @@ -770,6 +778,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 7f8bf4c01c..1e9512d478 100644 --- a/tests/testutilsqemu.c +++ b/tests/testutilsqemu.c @@ -33,6 +33,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 @@ -232,6 +236,7 @@ void qemuTestDriverFree(virQEMUDriver *driver) virObjectUnref(driver->caps); virObjectUnref(driver->config); virObjectUnref(driver->securityManager); + g_clear_object(&driver->nbdkitCapsCache); virCPUDefFree(cpuDefault); virCPUDefFree(cpuHaswell); @@ -348,6 +353,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; @@ -641,6 +652,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; @@ -926,6 +945,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; @@ -944,6 +968,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 8398627f71..8dbc480756 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, @@ -50,6 +51,7 @@ typedef enum { ARG_CAPS_HOST_CPU_MODEL, ARG_FD_GROUP, /* name, nfds, fd[0], ... fd[n-1] */ ARG_VDPA_FD, /* vdpadev, fd */ + 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; @@ -96,6 +99,7 @@ struct testQemuInfo { char *outfile; char *errfile; virQEMUCaps *qemuCaps; + qemuNbdkitCaps *nbdkitCaps; const char *migrateFrom; int migrateFd; unsigned int flags;