mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-18 02:25:18 +00:00
nodedev: Add testing for 'mdevctl start'
Test that we run 'mdevctl' with the proper arguments when creating new mediated devices with virNodeDeviceCreateXML(). Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com> Reviewed-by: Erik Skultety <eskultet@redhat.com> Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
parent
c44bffb9af
commit
9badcbbb1d
@ -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)$$)
|
(\.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 = \
|
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 = \
|
exclude_file_name_regexp--sc_prohibit_fork_wrappers = \
|
||||||
(^(src/(util/(vircommand|virdaemon)|lxc/lxc_controller)|tests/testutils)\.c$$)
|
(^(src/(util/(vircommand|virdaemon)|lxc/lxc_controller)|tests/testutils)\.c$$)
|
||||||
|
@ -103,6 +103,7 @@ EXTRA_DIST = \
|
|||||||
networkxml2xmlupdatein \
|
networkxml2xmlupdatein \
|
||||||
networkxml2xmlupdateout \
|
networkxml2xmlupdateout \
|
||||||
nodedevschemadata \
|
nodedevschemadata \
|
||||||
|
nodedevmdevctldata \
|
||||||
virhostcpudata \
|
virhostcpudata \
|
||||||
nssdata \
|
nssdata \
|
||||||
nwfilterxml2firewalldata \
|
nwfilterxml2firewalldata \
|
||||||
@ -388,6 +389,10 @@ test_programs += storagevolxml2xmltest
|
|||||||
|
|
||||||
test_programs += nodedevxml2xmltest
|
test_programs += nodedevxml2xmltest
|
||||||
|
|
||||||
|
if WITH_NODE_DEVICES
|
||||||
|
test_programs += nodedevmdevctltest
|
||||||
|
endif WITH_NODE_DEVICES
|
||||||
|
|
||||||
test_programs += interfacexml2xmltest
|
test_programs += interfacexml2xmltest
|
||||||
|
|
||||||
test_programs += cputest
|
test_programs += cputest
|
||||||
@ -970,6 +975,16 @@ nodedevxml2xmltest_SOURCES = \
|
|||||||
testutils.c testutils.h
|
testutils.c testutils.h
|
||||||
nodedevxml2xmltest_LDADD = $(LDADDS)
|
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_SOURCES = \
|
||||||
interfacexml2xmltest.c \
|
interfacexml2xmltest.c \
|
||||||
testutils.c testutils.h
|
testutils.c testutils.h
|
||||||
|
@ -0,0 +1 @@
|
|||||||
|
$MDEVCTL_BINARY$ start -p 0000:00:02.0 --jsonfile /dev/stdin
|
@ -0,0 +1 @@
|
|||||||
|
{"mdev_type":"i915-GVTg_V5_8","start":"manual"}
|
@ -0,0 +1 @@
|
|||||||
|
$MDEVCTL_BINARY$ start -p 0000:00:02.0 --jsonfile /dev/stdin
|
@ -0,0 +1 @@
|
|||||||
|
{"mdev_type":"i915-GVTg_V5_8","start":"manual","attrs":[{"example-attribute-1":"attribute-value-1"},{"example-attribute-2":"attribute-value-2"}]}
|
@ -0,0 +1 @@
|
|||||||
|
$MDEVCTL_BINARY$ start -p 0000:00:02.0 --jsonfile /dev/stdin
|
@ -0,0 +1 @@
|
|||||||
|
{"mdev_type":"i915-GVTg_V5_8","start":"manual","attrs":[{"example-attribute":"attribute-value"}]}
|
262
tests/nodedevmdevctltest.c
Normal file
262
tests/nodedevmdevctltest.c
Normal file
@ -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)
|
@ -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>
|
@ -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>
|
@ -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>
|
Loading…
x
Reference in New Issue
Block a user