On Thu, Jan 05, 2023 at 05:30:13PM +0100, Peter Krempa wrote:
Introduce a new argument type for testQemuInfoSetArgs named
ARG_FD_GROUP
which allows users to instantiate tests with populated FD passing hash
table.
I don't like when we need to alter the code in order to be able to test
it. There should be another better way of ensuring we have stable FDs
for tests. Not sure how difficult it would be to change it so we need
to go with this approach for now but would be nice to rework this by
follow up patches.
Signed-off-by: Peter Krempa <pkrempa(a)redhat.com>
---
src/conf/storage_source_conf.c | 1 +
src/conf/storage_source_conf.h | 1 +
tests/qemuxml2argvtest.c | 5 +++++
tests/testutilsqemu.c | 33 +++++++++++++++++++++++++++++++++
tests/testutilsqemu.h | 2 ++
5 files changed, 42 insertions(+)
diff --git a/src/conf/storage_source_conf.c b/src/conf/storage_source_conf.c
index 3fe8c4a900..e9d9c3a558 100644
--- a/src/conf/storage_source_conf.c
+++ b/src/conf/storage_source_conf.c
@@ -1384,6 +1384,7 @@ virStorageSourceFDTupleFinalize(GObject *object)
VIR_FORCE_CLOSE(fdt->fds[i]);
g_free(fdt->fds);
+ g_free(fdt->testfds);
G_OBJECT_CLASS(vir_storage_source_fd_tuple_parent_class)->finalize(object);
}
diff --git a/src/conf/storage_source_conf.h b/src/conf/storage_source_conf.h
index 9cd1a0c137..7c99ac8976 100644
--- a/src/conf/storage_source_conf.h
+++ b/src/conf/storage_source_conf.h
@@ -262,6 +262,7 @@ struct _virStorageSourceFDTuple {
GObject parent;
int *fds;
size_t nfds;
+ int *testfds; /* populated by tests to ensure stable FDs */
bool writable;
bool tryRestoreLabel;
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index 2db0e90f2b..b4b60a0130 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -705,6 +705,11 @@ testCompareXMLToArgv(const void *data)
}
priv = vm->privateData;
+ if (info->args.fds) {
+ g_clear_pointer(&priv->fds, g_hash_table_unref);
+ priv->fds = g_steal_pointer(&info->args.fds);
+ }
+
if (virBitmapParse("0-3", &priv->autoNodeset, 4) < 0)
goto cleanup;
diff --git a/tests/testutilsqemu.c b/tests/testutilsqemu.c
index 6d3decdc16..396803c40b 100644
--- a/tests/testutilsqemu.c
+++ b/tests/testutilsqemu.c
@@ -932,6 +932,38 @@ testQemuInfoSetArgs(struct testQemuInfo *info,
info->args.hostOS = va_arg(argptr, int);
break;
+ case ARG_FD_GROUP: {
+ virStorageSourceFDTuple *new = virStorageSourceFDTupleNew();
+ const char *fdname = va_arg(argptr, char *);
+ VIR_AUTOCLOSE fakefd = open("/dev/zero", O_RDWR);
+ size_t i;
+
+ new->nfds = va_arg(argptr, unsigned int);
+ new->fds = g_new0(int, new->nfds);
+ new->testfds = g_new0(int, new->nfds);
+
+ for (i = 0; i < new->nfds; i++) {
+ new->testfds[i] = va_arg(argptr, unsigned int);
+
+ if (fcntl(new->testfds[i], F_GETFD) != -1) {
+ fprintf(stderr, "fd '%d' is already in use\n",
new->fds[i]);
+ abort();
+ }
+
+ if ((new->fds[i] = dup(fakefd)) < 0) {
+ fprintf(stderr, "failed to duplicate fake fd: %s",
+ g_strerror(errno));
+ abort();
+ }
+ }
+
+ if (!info->args.fds)
+ info->args.fds = virHashNew(g_object_unref);
+
+ g_hash_table_insert(info->args.fds, g_strdup(fdname), new);
+ break;
+ }
+
case ARG_END:
default:
info->args.invalidarg = true;
@@ -1037,6 +1069,7 @@ testQemuInfoClear(struct testQemuInfo *info)
VIR_FREE(info->errfile);
virObjectUnref(info->qemuCaps);
g_clear_pointer(&info->args.fakeCaps, virObjectUnref);
+ g_clear_pointer(&info->args.fds, g_hash_table_unref);
}
diff --git a/tests/testutilsqemu.h b/tests/testutilsqemu.h
index 943958d02a..51c072cb13 100644
--- a/tests/testutilsqemu.h
+++ b/tests/testutilsqemu.h
@@ -52,6 +52,7 @@ typedef enum {
ARG_CAPS_VER,
ARG_CAPS_HOST_CPU_MODEL,
ARG_HOST_OS,
+ ARG_FD_GROUP, /* name, nfds, fd[0], ... fd[n-1] */
ARG_END,
} testQemuInfoArgName;
@@ -87,6 +88,7 @@ struct testQemuArgs {
qemuTestCPUDef capsHostCPUModel;
int gic;
testQemuHostOS hostOS;
+ GHashTable *fds;
bool invalidarg;
};
--
2.38.1