[libvirt PATCH v4 08/12] nodedev: Add testing for 'mdevctl start'

Jonathon Jongsma jjongsma at redhat.com
Thu Jun 18 21:06:01 UTC 2020


Test that we run 'mdevctl' with the proper arguments when creating new
mediated devices with virNodeDeviceCreateXML().

Signed-off-by: Jonathon Jongsma <jjongsma at redhat.com>
---
 build-aux/syntax-check.mk                     |   2 +-
 tests/Makefile.am                             |  15 +
 ...019_36ea_4111_8f0a_8c9a70e21366-start.argv |   1 +
 ...019_36ea_4111_8f0a_8c9a70e21366-start.json |   1 +
 ...d39_495e_4243_ad9f_beb3f14c23d9-start.argv |   1 +
 ...d39_495e_4243_ad9f_beb3f14c23d9-start.json |   1 +
 ...916_1ca8_49ac_b176_871d16c13076-start.argv |   1 +
 ...916_1ca8_49ac_b176_871d16c13076-start.json |   1 +
 tests/nodedevmdevctltest.c                    | 262 ++++++++++++++++++
 ...v_d069d019_36ea_4111_8f0a_8c9a70e21366.xml |   7 +
 ...v_d2441d39_495e_4243_ad9f_beb3f14c23d9.xml |   9 +
 ...v_fedc4916_1ca8_49ac_b176_871d16c13076.xml |   8 +
 12 files changed, 308 insertions(+), 1 deletion(-)
 create mode 100644 tests/nodedevmdevctldata/mdev_d069d019_36ea_4111_8f0a_8c9a70e21366-start.argv
 create mode 100644 tests/nodedevmdevctldata/mdev_d069d019_36ea_4111_8f0a_8c9a70e21366-start.json
 create mode 100644 tests/nodedevmdevctldata/mdev_d2441d39_495e_4243_ad9f_beb3f14c23d9-start.argv
 create mode 100644 tests/nodedevmdevctldata/mdev_d2441d39_495e_4243_ad9f_beb3f14c23d9-start.json
 create mode 100644 tests/nodedevmdevctldata/mdev_fedc4916_1ca8_49ac_b176_871d16c13076-start.argv
 create mode 100644 tests/nodedevmdevctldata/mdev_fedc4916_1ca8_49ac_b176_871d16c13076-start.json
 create mode 100644 tests/nodedevmdevctltest.c
 create mode 100644 tests/nodedevschemadata/mdev_d069d019_36ea_4111_8f0a_8c9a70e21366.xml
 create mode 100644 tests/nodedevschemadata/mdev_d2441d39_495e_4243_ad9f_beb3f14c23d9.xml
 create mode 100644 tests/nodedevschemadata/mdev_fedc4916_1ca8_49ac_b176_871d16c13076.xml

diff --git a/build-aux/syntax-check.mk b/build-aux/syntax-check.mk
index bf8832a2a5..d47a92b530 100644
--- a/build-aux/syntax-check.mk
+++ b/build-aux/syntax-check.mk
@@ -2015,7 +2015,7 @@ exclude_file_name_regexp--sc_prohibit_close = \
   (\.p[yl]$$|\.spec\.in$$|^docs/|^(src/util/vir(file|event)\.c|src/libvirt-stream\.c|tests/(vir.+mock\.c|commandhelper\.c|qemusecuritymock\.c)|tools/nss/libvirt_nss_(leases|macs)\.c)$$)
 
 exclude_file_name_regexp--sc_prohibit_empty_lines_at_EOF = \
-  (^tests/(virhostcpu|virpcitest)data/|docs/js/.*\.js|docs/fonts/.*\.woff|\.diff|tests/virconfdata/no-newline\.conf$$)
+  (^tests/(nodedevmdevctl|virhostcpu|virpcitest)data/|docs/js/.*\.js|docs/fonts/.*\.woff|\.diff|tests/virconfdata/no-newline\.conf$$)
 
 exclude_file_name_regexp--sc_prohibit_fork_wrappers = \
   (^(src/(util/(vircommand|virdaemon)|lxc/lxc_controller)|tests/testutils)\.c$$)
diff --git a/tests/Makefile.am b/tests/Makefile.am
index f5766a7790..3505c40f42 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -103,6 +103,7 @@ EXTRA_DIST = \
 	networkxml2xmlupdatein \
 	networkxml2xmlupdateout \
 	nodedevschemadata \
+	nodedevmdevctldata \
 	virhostcpudata \
 	nssdata \
 	nwfilterxml2firewalldata \
@@ -388,6 +389,10 @@ test_programs += storagevolxml2xmltest
 
 test_programs += nodedevxml2xmltest
 
+if WITH_NODE_DEVICES
+test_programs += nodedevmdevctltest
+endif WITH_NODE_DEVICES
+
 test_programs += interfacexml2xmltest
 
 test_programs += cputest
@@ -970,6 +975,16 @@ nodedevxml2xmltest_SOURCES = \
 	testutils.c testutils.h
 nodedevxml2xmltest_LDADD = $(LDADDS)
 
+if WITH_NODE_DEVICES
+nodedevmdevctltest_SOURCES = \
+	nodedevmdevctltest.c \
+	testutils.c testutils.h
+
+nodedevmdevctltest_LDADD = \
+	../src/libvirt_driver_nodedev_impl.la \
+	$(LDADDS)
+endif WITH_NODE_DEVICES
+
 interfacexml2xmltest_SOURCES = \
 	interfacexml2xmltest.c \
 	testutils.c testutils.h
diff --git a/tests/nodedevmdevctldata/mdev_d069d019_36ea_4111_8f0a_8c9a70e21366-start.argv b/tests/nodedevmdevctldata/mdev_d069d019_36ea_4111_8f0a_8c9a70e21366-start.argv
new file mode 100644
index 0000000000..eb7262035e
--- /dev/null
+++ b/tests/nodedevmdevctldata/mdev_d069d019_36ea_4111_8f0a_8c9a70e21366-start.argv
@@ -0,0 +1 @@
+$MDEVCTL_BINARY$ start -p 0000:00:02.0 --jsonfile /dev/stdin
diff --git a/tests/nodedevmdevctldata/mdev_d069d019_36ea_4111_8f0a_8c9a70e21366-start.json b/tests/nodedevmdevctldata/mdev_d069d019_36ea_4111_8f0a_8c9a70e21366-start.json
new file mode 100644
index 0000000000..bfc6dcace3
--- /dev/null
+++ b/tests/nodedevmdevctldata/mdev_d069d019_36ea_4111_8f0a_8c9a70e21366-start.json
@@ -0,0 +1 @@
+{"mdev_type":"i915-GVTg_V5_8","start":"manual"}
\ No newline at end of file
diff --git a/tests/nodedevmdevctldata/mdev_d2441d39_495e_4243_ad9f_beb3f14c23d9-start.argv b/tests/nodedevmdevctldata/mdev_d2441d39_495e_4243_ad9f_beb3f14c23d9-start.argv
new file mode 100644
index 0000000000..eb7262035e
--- /dev/null
+++ b/tests/nodedevmdevctldata/mdev_d2441d39_495e_4243_ad9f_beb3f14c23d9-start.argv
@@ -0,0 +1 @@
+$MDEVCTL_BINARY$ start -p 0000:00:02.0 --jsonfile /dev/stdin
diff --git a/tests/nodedevmdevctldata/mdev_d2441d39_495e_4243_ad9f_beb3f14c23d9-start.json b/tests/nodedevmdevctldata/mdev_d2441d39_495e_4243_ad9f_beb3f14c23d9-start.json
new file mode 100644
index 0000000000..e5b22b2c44
--- /dev/null
+++ b/tests/nodedevmdevctldata/mdev_d2441d39_495e_4243_ad9f_beb3f14c23d9-start.json
@@ -0,0 +1 @@
+{"mdev_type":"i915-GVTg_V5_8","start":"manual","attrs":[{"example-attribute-1":"attribute-value-1"},{"example-attribute-2":"attribute-value-2"}]}
\ No newline at end of file
diff --git a/tests/nodedevmdevctldata/mdev_fedc4916_1ca8_49ac_b176_871d16c13076-start.argv b/tests/nodedevmdevctldata/mdev_fedc4916_1ca8_49ac_b176_871d16c13076-start.argv
new file mode 100644
index 0000000000..eb7262035e
--- /dev/null
+++ b/tests/nodedevmdevctldata/mdev_fedc4916_1ca8_49ac_b176_871d16c13076-start.argv
@@ -0,0 +1 @@
+$MDEVCTL_BINARY$ start -p 0000:00:02.0 --jsonfile /dev/stdin
diff --git a/tests/nodedevmdevctldata/mdev_fedc4916_1ca8_49ac_b176_871d16c13076-start.json b/tests/nodedevmdevctldata/mdev_fedc4916_1ca8_49ac_b176_871d16c13076-start.json
new file mode 100644
index 0000000000..2e03d0bd8e
--- /dev/null
+++ b/tests/nodedevmdevctldata/mdev_fedc4916_1ca8_49ac_b176_871d16c13076-start.json
@@ -0,0 +1 @@
+{"mdev_type":"i915-GVTg_V5_8","start":"manual","attrs":[{"example-attribute":"attribute-value"}]}
\ No newline at end of file
diff --git a/tests/nodedevmdevctltest.c b/tests/nodedevmdevctltest.c
new file mode 100644
index 0000000000..4b029c7286
--- /dev/null
+++ b/tests/nodedevmdevctltest.c
@@ -0,0 +1,262 @@
+#include <config.h>
+
+#include "internal.h"
+#include "testutils.h"
+#include "datatypes.h"
+#include "node_device/node_device_driver.h"
+#include "vircommand.h"
+#define LIBVIRT_VIRCOMMANDPRIV_H_ALLOW
+#include "vircommandpriv.h"
+
+#define VIR_FROM_THIS VIR_FROM_NODEDEV
+
+struct startTestInfo {
+    const char *virt_type;
+    int create;
+    const char *filename;
+};
+
+/* capture stdin passed to command */
+static void
+testCommandDryRunCallback(const char *const*args G_GNUC_UNUSED,
+                          const char *const*env G_GNUC_UNUSED,
+                          const char *input,
+                          char **output G_GNUC_UNUSED,
+                          char **error G_GNUC_UNUSED,
+                          int *status G_GNUC_UNUSED,
+                          void *opaque G_GNUC_UNUSED)
+{
+    char **stdinbuf = opaque;
+
+    *stdinbuf = g_strdup(input);
+}
+
+/* We don't want the result of the test to depend on the path to the mdevctl
+ * binary on the developer's machine, so replace the path to mdevctl with a
+ * placeholder string before comparing to the expected output */
+static int
+nodedevCompareToFile(const char *actual,
+                     const char *filename)
+{
+    g_autofree char *replacedCmdline = NULL;
+
+    replacedCmdline = virStringReplace(actual, MDEVCTL, "$MDEVCTL_BINARY$");
+
+    return virTestCompareToFile(replacedCmdline, filename);
+}
+
+static int
+testMdevctlStart(const char *virt_type,
+                 int create,
+                 const char *mdevxml,
+                 const char *startcmdfile,
+                 const char *startjsonfile)
+{
+    g_autoptr(virNodeDeviceDef) def = NULL;
+    virNodeDeviceObjPtr obj = NULL;
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
+    const char *actualCmdline = NULL;
+    int ret = -1;
+    g_autofree char *uuid = NULL;
+    g_autofree char *stdinbuf = NULL;
+    g_autoptr(virCommand) cmd = NULL;
+
+    if (!(def = virNodeDeviceDefParseFile(mdevxml, create, virt_type)))
+        goto cleanup;
+
+    /* this function will set a stdin buffer containing the json configuration
+     * of the device. The json value is captured in the callback above */
+    cmd = nodeDeviceGetMdevctlStartCommand(def, &uuid);
+
+    if (!cmd)
+        goto cleanup;
+
+    virCommandSetDryRun(&buf, testCommandDryRunCallback, &stdinbuf);
+    if (virCommandRun(cmd, NULL) < 0)
+        goto cleanup;
+
+    if (!(actualCmdline = virBufferCurrentContent(&buf)))
+        goto cleanup;
+
+    if (nodedevCompareToFile(actualCmdline, startcmdfile) < 0)
+        goto cleanup;
+
+    if (virTestCompareToFile(stdinbuf, startjsonfile) < 0)
+        goto cleanup;
+
+    ret = 0;
+
+ cleanup:
+    virBufferFreeAndReset(&buf);
+    virCommandSetDryRun(NULL, NULL, NULL);
+    virNodeDeviceObjEndAPI(&obj);
+    return ret;
+}
+
+static int
+testMdevctlStartHelper(const void *data)
+{
+    const struct startTestInfo *info = data;
+
+    g_autofree char *mdevxml = g_strdup_printf("%s/nodedevschemadata/%s.xml",
+                                               abs_srcdir, info->filename);
+    g_autofree char *cmdlinefile = g_strdup_printf("%s/nodedevmdevctldata/%s-start.argv",
+                                                   abs_srcdir, info->filename);
+    g_autofree char *jsonfile = g_strdup_printf("%s/nodedevmdevctldata/%s-start.json",
+                                                   abs_srcdir, info->filename);
+
+    return testMdevctlStart(info->virt_type,
+                            info->create, mdevxml, cmdlinefile,
+                            jsonfile);
+}
+
+static void
+nodedevTestDriverFree(virNodeDeviceDriverStatePtr drv)
+{
+    if (!drv)
+        return;
+
+    virNodeDeviceObjListFree(drv->devs);
+    virCondDestroy(&drv->initCond);
+    virMutexDestroy(&drv->lock);
+    VIR_FREE(drv->stateDir);
+    VIR_FREE(drv);
+}
+
+/* Add a fake root 'computer' device */
+static virNodeDeviceDefPtr
+fakeRootDevice(void)
+{
+    virNodeDeviceDefPtr def = NULL;
+
+    if (VIR_ALLOC(def) != 0 || VIR_ALLOC(def->caps) != 0) {
+        virNodeDeviceDefFree(def);
+        return NULL;
+    }
+
+    def->name = g_strdup("computer");
+
+    return def;
+}
+
+/* Add a fake pci device that can be used as a parent device for mediated
+ * devices. For our purposes, it only needs to have a name that matches the
+ * parent of the mdev, and it needs a PCI address
+ */
+static virNodeDeviceDefPtr
+fakeParentDevice(void)
+{
+    virNodeDeviceDefPtr def = NULL;
+    virNodeDevCapPCIDevPtr pci_dev;
+
+    if (VIR_ALLOC(def) != 0 || VIR_ALLOC(def->caps) != 0) {
+        virNodeDeviceDefFree(def);
+        return NULL;
+    }
+
+    def->name = g_strdup("pci_0000_00_02_0");
+    def->parent = g_strdup("computer");
+
+    def->caps->data.type = VIR_NODE_DEV_CAP_PCI_DEV;
+    pci_dev = &def->caps->data.pci_dev;
+    pci_dev->domain = 0;
+    pci_dev->bus = 0;
+    pci_dev->slot = 2;
+    pci_dev->function = 0;
+
+    return def;
+}
+
+static int
+addDevice(virNodeDeviceDefPtr def)
+{
+    if (!def)
+        return -1;
+
+    virNodeDeviceObjPtr obj = virNodeDeviceObjListAssignDef(driver->devs, def);
+
+    if (!obj) {
+        virNodeDeviceDefFree(def);
+        return -1;
+    }
+
+    virNodeDeviceObjEndAPI(&obj);
+    return 0;
+}
+
+static int
+nodedevTestDriverAddTestDevices(void)
+{
+    if (addDevice(fakeRootDevice()) < 0 ||
+        addDevice(fakeParentDevice()) < 0)
+        return -1;
+
+    return 0;
+}
+
+/* Bare minimum driver init to be able to test nodedev functionality */
+static int
+nodedevTestDriverInit(void)
+{
+    int ret = -1;
+    if (VIR_ALLOC(driver) < 0)
+        return -1;
+
+    driver->lockFD = -1;
+    if (virMutexInit(&driver->lock) < 0 ||
+        virCondInit(&driver->initCond) < 0) {
+        VIR_TEST_DEBUG("Unable to initialize test nodedev driver");
+        goto error;
+    }
+
+    if (!(driver->devs = virNodeDeviceObjListNew()))
+        goto error;
+
+    return 0;
+
+ error:
+    nodedevTestDriverFree(driver);
+    return ret;
+}
+
+static int
+mymain(void)
+{
+    int ret = 0;
+
+    if (nodedevTestDriverInit() < 0)
+        return EXIT_FAILURE;
+
+    /* add a mock device to the device list so it can be used as a parent
+     * reference */
+    if (nodedevTestDriverAddTestDevices() < 0) {
+        ret = EXIT_FAILURE;
+        goto done;
+    }
+
+#define DO_TEST_FULL(desc, func, info) \
+    if (virTestRun(desc, func, &info) < 0) \
+        ret = -1;
+
+#define DO_TEST_START_FULL(virt_type, create, filename) \
+    do { \
+        struct startTestInfo info = { virt_type, create, filename }; \
+        DO_TEST_FULL("mdevctl start " filename, testMdevctlStartHelper, info); \
+       } \
+    while (0);
+
+#define DO_TEST_START(filename) \
+    DO_TEST_START_FULL("QEMU", CREATE_DEVICE, filename)
+
+    /* Test mdevctl start commands */
+    DO_TEST_START("mdev_d069d019_36ea_4111_8f0a_8c9a70e21366");
+    DO_TEST_START("mdev_fedc4916_1ca8_49ac_b176_871d16c13076");
+    DO_TEST_START("mdev_d2441d39_495e_4243_ad9f_beb3f14c23d9");
+
+ done:
+    nodedevTestDriverFree(driver);
+
+    return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
+}
+
+VIR_TEST_MAIN(mymain)
diff --git a/tests/nodedevschemadata/mdev_d069d019_36ea_4111_8f0a_8c9a70e21366.xml b/tests/nodedevschemadata/mdev_d069d019_36ea_4111_8f0a_8c9a70e21366.xml
new file mode 100644
index 0000000000..d6a2e99edc
--- /dev/null
+++ b/tests/nodedevschemadata/mdev_d069d019_36ea_4111_8f0a_8c9a70e21366.xml
@@ -0,0 +1,7 @@
+<device>
+  <name>mdev_d069d019_36ea_4111_8f0a_8c9a70e21366</name>
+  <parent>pci_0000_00_02_0</parent>
+  <capability type='mdev'>
+    <type id='i915-GVTg_V5_8'/>
+  </capability>
+</device>
diff --git a/tests/nodedevschemadata/mdev_d2441d39_495e_4243_ad9f_beb3f14c23d9.xml b/tests/nodedevschemadata/mdev_d2441d39_495e_4243_ad9f_beb3f14c23d9.xml
new file mode 100644
index 0000000000..89568d06ce
--- /dev/null
+++ b/tests/nodedevschemadata/mdev_d2441d39_495e_4243_ad9f_beb3f14c23d9.xml
@@ -0,0 +1,9 @@
+<device>
+  <name>mdev_d2441d39_495e_4243_ad9f_beb3f14c23d9</name>
+  <parent>pci_0000_00_02_0</parent>
+  <capability type='mdev'>
+    <type id='i915-GVTg_V5_8'/>
+    <attr name='example-attribute-1' value='attribute-value-1'/>
+    <attr name='example-attribute-2' value='attribute-value-2'/>
+  </capability>
+</device>
diff --git a/tests/nodedevschemadata/mdev_fedc4916_1ca8_49ac_b176_871d16c13076.xml b/tests/nodedevschemadata/mdev_fedc4916_1ca8_49ac_b176_871d16c13076.xml
new file mode 100644
index 0000000000..7cd0a46e3d
--- /dev/null
+++ b/tests/nodedevschemadata/mdev_fedc4916_1ca8_49ac_b176_871d16c13076.xml
@@ -0,0 +1,8 @@
+<device>
+  <name>mdev_fedc4916_1ca8_49ac_b176_871d16c13076</name>
+  <parent>pci_0000_00_02_0</parent>
+  <capability type='mdev'>
+    <type id='i915-GVTg_V5_8'/>
+    <attr name='example-attribute' value='attribute-value'/>
+  </capability>
+</device>
-- 
2.21.3




More information about the libvir-list mailing list