[PATCH v4 8/8] tests: Add generichotplugtest

Luke Yue lukedyue at gmail.com
Fri Dec 3 12:45:17 UTC 2021


For testing hypervisor independent device detach / attach / update
functions, currently only detaching included.

Signed-off-by: Luke Yue <lukedyue at gmail.com>
---
The test would show error messages with expected to fail tests even
with VIR_TEST_DEBUG=0, really don't know what I missed to make it quiet :(
I would really appreciate it if anyone could tell me what should I do, thanks.
---
 tests/generichotplugtest.c | 178 +++++++++++++++++++++++++++++++++++++
 tests/meson.build          |   1 +
 2 files changed, 179 insertions(+)
 create mode 100644 tests/generichotplugtest.c

diff --git a/tests/generichotplugtest.c b/tests/generichotplugtest.c
new file mode 100644
index 0000000000..443fc907d3
--- /dev/null
+++ b/tests/generichotplugtest.c
@@ -0,0 +1,178 @@
+#include <config.h>
+
+#include "internal.h"
+#include "testutils.h"
+
+enum {
+    ATTACH,
+    DETACH,
+    UPDATE
+};
+
+#define VIR_FROM_THIS VIR_FROM_NONE
+
+struct genericHotplugTestData {
+    const char *device_filename;
+    const char *device_alias;
+    bool fail;
+    bool alias;
+    bool keep;
+    int action;
+    unsigned int flags;
+    virDomainPtr dom;
+};
+
+static int
+testGenericHotplug(const void *data)
+{
+    int ret = 0;
+    g_autofree char *domain_xml = g_strdup_printf("test://%s/../examples/xml/test/testnode.xml",
+                                                  abs_srcdir);
+    struct genericHotplugTestData *test = (struct genericHotplugTestData *) data;
+    g_autofree char *device_filename = NULL;
+    g_autofree char *device_alias = NULL;
+    g_autofree char *device_xml = NULL;
+    bool fail = test->fail;
+    bool alias = test->alias;
+    unsigned int flags = test->flags;
+    virConnectPtr conn = virConnectOpen(domain_xml);
+    virDomainPtr dom = NULL;
+
+    if (!test->dom) {
+        dom = virDomainLookupByName(conn, "fc5");
+        test->dom = dom;
+    }
+
+    if (alias) {
+        device_alias = g_strdup_printf("%s", test->device_alias);
+    } else {
+        device_filename = g_strdup_printf("%s/generichotplugdata/generichotplug-%s.xml",
+                                          abs_srcdir, test->device_filename);
+
+        if (virTestLoadFile(device_filename, &device_xml) < 0)
+            return -1;
+    }
+
+    switch (test->action) {
+    case ATTACH:
+        ret = virDomainAttachDeviceFlags(test->dom, device_xml, flags);
+        break;
+
+    case DETACH:
+        if (alias) {
+            ret = virDomainDetachDeviceAlias(test->dom, device_alias, flags);
+        } else {
+            ret = virDomainDetachDeviceFlags(test->dom, device_xml, flags);
+        }
+        break;
+
+    case UPDATE:
+        ret = virDomainUpdateDeviceFlags(test->dom, device_xml, flags);
+        break;
+    }
+
+    if (!test->keep) {
+        virDomainDestroy(test->dom);
+        virDomainFree(test->dom);
+        test->dom = NULL;
+    } else {
+        test->dom = dom;
+    }
+    virConnectClose(conn);
+
+    return ((ret < 0 && fail) || (!ret && !fail)) ? 0 : -1;
+}
+
+static int
+mymain(void)
+{
+    int ret = 0;
+    struct genericHotplugTestData data = {0};
+    unsigned int test_flags = VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_AFFECT_CONFIG;
+
+#define DO_TEST(ACTION, dev, dev_alias, alias_, fail_, keep_, flags_) \
+    do { \
+        const char *name = (alias_) ? \
+                           "Generic " #ACTION " alias " dev_alias : \
+                           "Generic " #ACTION " " dev; \
+        data.action = ACTION; \
+        data.device_filename = dev; \
+        data.device_alias = dev_alias; \
+        data.alias = alias_; \
+        data.fail = fail_; \
+        data.flags = flags_; \
+        data.keep = keep_; \
+        if (virTestRun(name, testGenericHotplug, &data) < 0) \
+            ret = -1; \
+    } while (0)
+
+#define DO_TEST_DETACH(dev, dev_alias, alias, fail, keep, flags) \
+    DO_TEST(DETACH, dev, dev_alias, alias, fail, keep, flags)
+
+    /* Every detach test is followed by a repeated one that is expected
+    to fail, cause the previous one should detach the device successfully */
+    DO_TEST_DETACH("controller", "", false, false, true, test_flags);
+    DO_TEST_DETACH("controller", "", false, true, false, test_flags);
+
+    DO_TEST_DETACH("disk-cdrom", "", false, false, true, test_flags);
+    DO_TEST_DETACH("disk-cdrom", "", false, true, false, test_flags);
+
+    DO_TEST_DETACH("filesystem", "", false, false, true, test_flags);
+    DO_TEST_DETACH("filesystem", "", false, true, false, test_flags);
+
+    DO_TEST_DETACH("hostdev", "", false, false, true, test_flags);
+    DO_TEST_DETACH("hostdev", "", false, true, false, test_flags);
+
+    DO_TEST_DETACH("input", "", false, false, true, test_flags);
+    DO_TEST_DETACH("input", "", false, true, false, test_flags);
+
+    DO_TEST_DETACH("interface", "", false, false, true, test_flags);
+    DO_TEST_DETACH("interface", "", false, true, false, test_flags);
+
+    DO_TEST_DETACH("lease", "", false, false, true, test_flags);
+    DO_TEST_DETACH("lease", "", false, true, false, test_flags);
+
+    DO_TEST_DETACH("memory", "", false, false, true, test_flags);
+    DO_TEST_DETACH("memory", "", false, true, false, test_flags);
+
+    DO_TEST_DETACH("rng", "", false, false, true, test_flags);
+    DO_TEST_DETACH("rng", "", false, true, false, test_flags);
+
+    DO_TEST_DETACH("shmem", "", false, false, true, test_flags);
+    DO_TEST_DETACH("shmem", "", false, true, false, test_flags);
+
+    DO_TEST_DETACH("sound", "", false, false, true, test_flags);
+    DO_TEST_DETACH("sound", "", false, true, false, test_flags);
+
+    DO_TEST_DETACH("tpm", "", false, false, true, test_flags);
+    DO_TEST_DETACH("tpm", "", false, true, false, test_flags);
+
+    DO_TEST_DETACH("vsock", "", false, false, true, test_flags);
+    DO_TEST_DETACH("vsock", "", false, true, false, test_flags);
+
+    DO_TEST_DETACH("watchdog", "", false, false, true, test_flags);
+    DO_TEST_DETACH("watchdog", "", false, true, false, test_flags);
+
+    DO_TEST_DETACH("disk-cdrom", "", false, false, true, test_flags);
+    DO_TEST_DETACH("", "ua-testCD", true, true, false, test_flags);
+
+    DO_TEST_DETACH("", "ua-testCD", true, false, true, test_flags);
+    DO_TEST_DETACH("", "ua-testCD", true, true, false, test_flags);
+
+    /* Memballoon device shouldn't be hotpluggable */
+    DO_TEST_DETACH("memballoon", "", false, true, false, test_flags);
+
+    DO_TEST_DETACH("memballoon", "", false, false, true,
+                   VIR_DOMAIN_AFFECT_CONFIG);
+    DO_TEST_DETACH("memballoon", "", false, true, false,
+                   VIR_DOMAIN_AFFECT_CONFIG);
+
+    if (data.dom) {
+        virDomainDestroy(data.dom);
+        virDomainFree(data.dom);
+    }
+
+    return (ret == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
+}
+
+VIR_TEST_MAIN(mymain)
diff --git a/tests/meson.build b/tests/meson.build
index f75c248720..659b044984 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -288,6 +288,7 @@ tests += [
   { 'name': 'cputest', 'link_with': cputest_link_with, 'link_whole': cputest_link_whole },
   { 'name': 'domaincapstest', 'link_with': domaincapstest_link_with, 'link_whole': domaincapstest_link_whole },
   { 'name': 'domainconftest' },
+  { 'name': 'generichotplugtest' },
   { 'name': 'genericxml2xmltest' },
   { 'name': 'interfacexml2xmltest' },
   { 'name': 'metadatatest' },
--
2.34.1




More information about the libvir-list mailing list