[libvirt] [PATCH 7/9] virpcitest: More tests for device detach and reattach

Jiri Denemark jdenemar at redhat.com
Fri Jan 17 10:39:23 UTC 2014


Especially for devices that are not bound to any driver.

Signed-off-by: Jiri Denemark <jdenemar at redhat.com>
---
 tests/virpcimock.c |   3 +
 tests/virpcitest.c | 157 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 159 insertions(+), 1 deletion(-)

diff --git a/tests/virpcimock.c b/tests/virpcimock.c
index bf56143..f8ea9c7 100644
--- a/tests/virpcimock.c
+++ b/tests/virpcimock.c
@@ -809,6 +809,9 @@ init_env(void)
     MAKE_PCI_DEVICE("0005:90:01.0", 0x1033, 0x0035);
     MAKE_PCI_DEVICE("0005:90:01.1", 0x1033, 0x0035);
     MAKE_PCI_DEVICE("0005:90:01.2", 0x1033, 0x00e0);
+    MAKE_PCI_DEVICE("0000:0a:01.0", 0x8086, 0x0047);
+    MAKE_PCI_DEVICE("0000:0a:02.0", 0x8286, 0x0048);
+    MAKE_PCI_DEVICE("0000:0a:03.0", 0x8386, 0x0048);
 }
 
 
diff --git a/tests/virpcitest.c b/tests/virpcitest.c
index e96d7c0..848014d 100644
--- a/tests/virpcitest.c
+++ b/tests/virpcitest.c
@@ -34,6 +34,30 @@
 # define VIR_FROM_THIS VIR_FROM_NONE
 
 static int
+testVirPCIDeviceCheckDriver(virPCIDevicePtr dev, const char *expected)
+{
+    char *path = NULL;
+    char *driver = NULL;
+    int ret = -1;
+
+    if (virPCIDeviceGetDriverPathAndName(dev, &path, &driver) < 0)
+        goto cleanup;
+
+    if (STRNEQ_NULLABLE(driver, expected)) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       "PCI device %s driver mismatch: %s, expecting %s",
+                       virPCIDeviceGetName(dev), driver, expected);
+        goto cleanup;
+    }
+
+    ret = 0;
+cleanup:
+    VIR_FREE(path);
+    VIR_FREE(driver);
+    return ret;
+}
+
+static int
 testVirPCIDeviceNew(const void *opaque ATTRIBUTE_UNUSED)
 {
     int ret = -1;
@@ -89,6 +113,9 @@ testVirPCIDeviceDetach(const void *oaque ATTRIBUTE_UNUSED)
         if (virPCIDeviceDetach(dev[i], activeDevs, inactiveDevs) < 0)
             goto cleanup;
 
+        if (testVirPCIDeviceCheckDriver(dev[i], "pci-stub") < 0)
+            goto cleanup;
+
         CHECK_LIST_COUNT(activeDevs, 0);
         CHECK_LIST_COUNT(inactiveDevs, i + 1);
     }
@@ -188,6 +215,7 @@ struct testPCIDevData {
     unsigned int bus;
     unsigned int slot;
     unsigned int function;
+    const char *driver;
 };
 
 static int
@@ -208,6 +236,88 @@ cleanup:
     return ret;
 }
 
+static int
+testVirPCIDeviceDetachSingle(const void *opaque)
+{
+    const struct testPCIDevData *data = opaque;
+    int ret = -1;
+    virPCIDevicePtr dev;
+
+    dev = virPCIDeviceNew(data->domain, data->bus, data->slot, data->function);
+    if (!dev)
+        goto cleanup;
+
+    if (virPCIDeviceSetStubDriver(dev, "pci-stub") < 0 ||
+        virPCIDeviceDetach(dev, NULL, NULL) < 0)
+        goto cleanup;
+
+    ret = 0;
+cleanup:
+    virPCIDeviceFree(dev);
+    return ret;
+}
+
+static int
+testVirPCIDeviceReattachSingle(const void *opaque)
+{
+    const struct testPCIDevData *data = opaque;
+    int ret = -1;
+    virPCIDevicePtr dev;
+
+    dev = virPCIDeviceNew(data->domain, data->bus, data->slot, data->function);
+    if (!dev)
+        goto cleanup;
+
+    virPCIDeviceReattachInit(dev);
+    if (virPCIDeviceReattach(dev, NULL, NULL) < 0)
+        goto cleanup;
+
+    ret = 0;
+cleanup:
+    virPCIDeviceFree(dev);
+    return ret;
+}
+
+static int
+testVirPCIDeviceCheckDriverTest(const void *opaque)
+{
+    const struct testPCIDevData *data = opaque;
+    int ret = -1;
+    virPCIDevicePtr dev;
+
+    dev = virPCIDeviceNew(data->domain, data->bus, data->slot, data->function);
+    if (!dev)
+        goto cleanup;
+
+    if (testVirPCIDeviceCheckDriver(dev, data->driver) < 0)
+        goto cleanup;
+
+    ret = 0;
+cleanup:
+    virPCIDeviceFree(dev);
+    return ret;
+}
+
+static int
+testVirPCIDeviceUnbind(const void *opaque)
+{
+    const struct testPCIDevData *data = opaque;
+    int ret = -1;
+    virPCIDevicePtr dev;
+
+    dev = virPCIDeviceNew(data->domain, data->bus, data->slot, data->function);
+    if (!dev)
+        goto cleanup;
+
+    if (virPCIDeviceUnbind(dev, false) < 0)
+        goto cleanup;
+
+    ret = 0;
+cleanup:
+    virPCIDeviceFree(dev);
+    return ret;
+}
+
 # define FAKESYSFSDIRTEMPLATE abs_builddir "/fakesysfsdir-XXXXXX"
 
 static int
@@ -236,7 +346,9 @@ mymain(void)
 
 # define DO_TEST_PCI(fnc, domain, bus, slot, function)                  \
     do {                                                                \
-        struct testPCIDevData data = { domain, bus, slot, function };   \
+        struct testPCIDevData data = {                                  \
+            domain, bus, slot, function, NULL                           \
+        };                                                              \
         char *label = NULL;                                             \
         if (virAsprintf(&label, "%s(%04x:%02x:%02x.%x)",                \
                         #fnc, domain, bus, slot, function) < 0) {       \
@@ -248,6 +360,28 @@ mymain(void)
         VIR_FREE(label);                                                \
     } while (0)
 
+# define DO_TEST_PCI_DRIVER(domain, bus, slot, function, driver)        \
+    do {                                                                \
+        struct testPCIDevData data = {                                  \
+            domain, bus, slot, function, driver                         \
+        };                                                              \
+        char *label = NULL;                                             \
+        if (virAsprintf(&label, "PCI driver %04x:%02x:%02x.%x is %s",   \
+                        domain, bus, slot, function,                    \
+                        NULLSTR(driver)) < 0) {                         \
+            ret = -1;                                                   \
+            break;                                                      \
+        }                                                               \
+        if (virtTestRun(label, testVirPCIDeviceCheckDriverTest,         \
+                        &data) < 0)                                     \
+            ret = -1;                                                   \
+        VIR_FREE(label);                                                \
+    } while (0)
+
+    /* Changes made to individual devices are persistent and the
+     * tests often rely on the state set by previous tests.
+     */
+
     DO_TEST(testVirPCIDeviceNew);
     DO_TEST(testVirPCIDeviceDetach);
     DO_TEST(testVirPCIDeviceReset);
@@ -255,6 +389,27 @@ mymain(void)
     DO_TEST_PCI(testVirPCIDeviceIsAssignable, 5, 0x90, 1, 0);
     DO_TEST_PCI(testVirPCIDeviceIsAssignable, 1, 1, 0, 0);
 
+    /* Reattach a device already bound to non-stub a driver */
+    DO_TEST_PCI_DRIVER(0, 0x0a, 1, 0, "i915");
+    DO_TEST_PCI(testVirPCIDeviceReattachSingle, 0, 0x0a, 1, 0);
+    DO_TEST_PCI_DRIVER(0, 0x0a, 1, 0, "i915");
+
+    /* Reattach an unbound device */
+    DO_TEST_PCI(testVirPCIDeviceUnbind, 0, 0x0a, 1, 0);
+    DO_TEST_PCI_DRIVER(0, 0x0a, 1, 0, NULL);
+    DO_TEST_PCI(testVirPCIDeviceReattachSingle, 0, 0x0a, 1, 0);
+    DO_TEST_PCI_DRIVER(0, 0x0a, 1, 0, "i915");
+
+    /* Detach an unbound device */
+    DO_TEST_PCI_DRIVER(0, 0x0a, 2, 0, NULL);
+    DO_TEST_PCI(testVirPCIDeviceDetachSingle, 0, 0x0a, 2, 0);
+    DO_TEST_PCI_DRIVER(0, 0x0a, 2, 0, "pci-stub");
+
+    /* Reattach an unknown unbound device */
+    DO_TEST_PCI_DRIVER(0, 0x0a, 3, 0, NULL);
+    DO_TEST_PCI(testVirPCIDeviceReattachSingle, 0, 0x0a, 3, 0);
+    DO_TEST_PCI_DRIVER(0, 0x0a, 3, 0, NULL);
+
     if (getenv("LIBVIRT_SKIP_CLEANUP") == NULL)
         virFileDeleteTree(fakesysfsdir);
 
-- 
1.8.5.3




More information about the libvir-list mailing list