[libvirt] [PATCH v2 0/2] bhyve: add xml2args unittest

Changes from v1: - Chase MAC address support by adding virMacAddrGenerate() mock, so we can get a constant MAC address - Add a test for the case when MAC address is specified in the domain xml Roman Bogorodskiy (2): Move virBhyveTapGetRealDeviceName to virnetdevtap bhyve: add xml2args unittest src/bhyve/bhyve_command.c | 70 +--------- src/libvirt_private.syms | 1 + src/util/virnetdevtap.c | 78 +++++++++++ src/util/virnetdevtap.h | 3 + tests/Makefile.am | 25 ++++ .../bhyvexml2argvdata/bhyvexml2argv-acpiapic.args | 3 + tests/bhyvexml2argvdata/bhyvexml2argv-acpiapic.xml | 24 ++++ tests/bhyvexml2argvdata/bhyvexml2argv-base.args | 3 + tests/bhyvexml2argvdata/bhyvexml2argv-base.xml | 20 +++ .../bhyvexml2argv-disk-virtio.args | 3 + .../bhyvexml2argv-disk-virtio.xml | 20 +++ tests/bhyvexml2argvdata/bhyvexml2argv-macaddr.args | 3 + tests/bhyvexml2argvdata/bhyvexml2argv-macaddr.xml | 21 +++ tests/bhyvexml2argvmock.c | 49 +++++++ tests/bhyvexml2argvtest.c | 155 +++++++++++++++++++++ 15 files changed, 409 insertions(+), 69 deletions(-) create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-acpiapic.args create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-acpiapic.xml create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-base.args create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-base.xml create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-disk-virtio.args create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-disk-virtio.xml create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-macaddr.args create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-macaddr.xml create mode 100644 tests/bhyvexml2argvmock.c create mode 100644 tests/bhyvexml2argvtest.c -- 1.8.4.2

To ease mocking for bhyve unit tests move virBhyveTapGetRealDeviceName() out of bhyve_command.c to virnetdevtap and rename it to virNetDevTapGetRealDeviceName(). --- src/bhyve/bhyve_command.c | 70 +---------------------------------------- src/libvirt_private.syms | 1 + src/util/virnetdevtap.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++ src/util/virnetdevtap.h | 3 ++ 4 files changed, 84 insertions(+), 69 deletions(-) diff --git a/src/bhyve/bhyve_command.c b/src/bhyve/bhyve_command.c index 6d64c27..5e24b53 100644 --- a/src/bhyve/bhyve_command.c +++ b/src/bhyve/bhyve_command.c @@ -21,10 +21,7 @@ #include <config.h> -#include <fcntl.h> #include <sys/types.h> -#include <dirent.h> -#include <sys/ioctl.h> #include <net/if.h> #include <net/if_tap.h> @@ -41,71 +38,6 @@ VIR_LOG_INIT("bhyve.bhyve_command"); -static char* -virBhyveTapGetRealDeviceName(char *name) -{ - /* This is an ugly hack, because if we rename - * tap device to vnet%d, its device name will be - * still /dev/tap%d, and bhyve tries to open /dev/tap%d, - * so we have to find the real name - */ - char *ret = NULL; - struct dirent *dp; - char *devpath = NULL; - int fd; - - DIR *dirp = opendir("/dev"); - if (dirp == NULL) { - virReportSystemError(errno, - _("Failed to opendir path '%s'"), - "/dev"); - return NULL; - } - - while ((dp = readdir(dirp)) != NULL) { - if (STRPREFIX(dp->d_name, "tap")) { - struct ifreq ifr; - if (virAsprintf(&devpath, "/dev/%s", dp->d_name) < 0) { - goto cleanup; - } - if ((fd = open(devpath, O_RDWR)) < 0) { - virReportSystemError(errno, _("Unable to open '%s'"), devpath); - goto cleanup; - } - - if (ioctl(fd, TAPGIFNAME, (void *)&ifr) < 0) { - virReportSystemError(errno, "%s", - _("Unable to query tap interface name")); - goto cleanup; - } - - if (STREQ(name, ifr.ifr_name)) { - /* we can ignore the return value - * because we still have nothing - * to do but return; - */ - ignore_value(VIR_STRDUP(ret, dp->d_name)); - goto cleanup; - } - - VIR_FREE(devpath); - VIR_FORCE_CLOSE(fd); - } - - errno = 0; - } - - if (errno != 0) - virReportSystemError(errno, "%s", - _("Unable to iterate over TAP devices")); - -cleanup: - VIR_FREE(devpath); - VIR_FORCE_CLOSE(fd); - closedir(dirp); - return ret; -} - static int bhyveBuildNetArgStr(const virDomainDef *def, virCommandPtr cmd) { @@ -157,7 +89,7 @@ bhyveBuildNetArgStr(const virDomainDef *def, virCommandPtr cmd) } } - realifname = virBhyveTapGetRealDeviceName(net->ifname); + realifname = virNetDevTapGetRealDeviceName(net->ifname); if (realifname == NULL) { VIR_FREE(net->ifname); diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 5904036..4861aa9 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1576,6 +1576,7 @@ virNetDevTapCreate; virNetDevTapCreateInBridgePort; virNetDevTapDelete; virNetDevTapGetName; +virNetDevTapGetRealDeviceName; # util/virnetdevveth.h diff --git a/src/util/virnetdevtap.c b/src/util/virnetdevtap.c index a36af76..bd00c28 100644 --- a/src/util/virnetdevtap.c +++ b/src/util/virnetdevtap.c @@ -22,6 +22,10 @@ #include <config.h> +#include <fcntl.h> +#include <sys/types.h> +#include <dirent.h> + #include "virmacaddr.h" #include "virnetdevtap.h" #include "virnetdev.h" @@ -38,8 +42,11 @@ #include <fcntl.h> #ifdef __linux__ # include <linux/if_tun.h> /* IFF_TUN, IFF_NO_PI */ +#elif defined(__FreeBSD__) +# include <net/if_tap.h> #endif + #define VIR_FROM_THIS VIR_FROM_NONE VIR_LOG_INIT("util.netdevtap"); @@ -72,6 +79,78 @@ virNetDevTapGetName(int tapfd ATTRIBUTE_UNUSED, char **ifname ATTRIBUTE_UNUSED) #endif } +/** + * virNetDevTapGetRealDeviceName: + * @ifname: the interface name + * + * Lookup real interface name (i.e. name of the device entry in /dev), + * because e.g. on FreeBSD if we rename tap device to vnetN its device + * entry still remains unchanged (/dev/tapX), but bhyve needs a name + * that matches /dev entry. + * + * Returns the proper interface name or NULL if no corresponding interface + * found. + */ +char* +virNetDevTapGetRealDeviceName(char *ifname) +{ + char *ret = NULL; + struct dirent *dp; + char *devpath = NULL; + int fd; + + DIR *dirp = opendir("/dev"); + if (dirp == NULL) { + virReportSystemError(errno, + _("Failed to opendir path '%s'"), + "/dev"); + return NULL; + } + + while ((dp = readdir(dirp)) != NULL) { + if (STRPREFIX(dp->d_name, "tap")) { + struct ifreq ifr; + if (virAsprintf(&devpath, "/dev/%s", dp->d_name) < 0) { + goto cleanup; + } + if ((fd = open(devpath, O_RDWR)) < 0) { + virReportSystemError(errno, _("Unable to open '%s'"), devpath); + goto cleanup; + } + + if (ioctl(fd, TAPGIFNAME, (void *)&ifr) < 0) { + virReportSystemError(errno, "%s", + _("Unable to query tap interface name")); + goto cleanup; + } + + if (STREQ(ifname, ifr.ifr_name)) { + /* we can ignore the return value + * because we still have nothing + * to do but return; + */ + ignore_value(VIR_STRDUP(ret, dp->d_name)); + goto cleanup; + } + + VIR_FREE(devpath); + VIR_FORCE_CLOSE(fd); + } + + errno = 0; + } + + if (errno != 0) + virReportSystemError(errno, "%s", + _("Unable to iterate over TAP devices")); + +cleanup: + VIR_FREE(devpath); + VIR_FORCE_CLOSE(fd); + closedir(dirp); + return ret; +} + /** * virNetDevProbeVnetHdr: diff --git a/src/util/virnetdevtap.h b/src/util/virnetdevtap.h index 1e5bd19..03fb5f8 100644 --- a/src/util/virnetdevtap.h +++ b/src/util/virnetdevtap.h @@ -45,6 +45,9 @@ int virNetDevTapDelete(const char *ifname) int virNetDevTapGetName(int tapfd, char **ifname) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; +char* virNetDevTapGetRealDeviceName(char *ifname) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; + typedef enum { VIR_NETDEV_TAP_CREATE_NONE = 0, /* Bring the interface up */ -- 1.8.4.2

On 03/23/2014 07:17 AM, Roman Bogorodskiy wrote:
To ease mocking for bhyve unit tests move virBhyveTapGetRealDeviceName() out of bhyve_command.c to virnetdevtap and rename it to virNetDevTapGetRealDeviceName(). --- src/bhyve/bhyve_command.c | 70 +---------------------------------------- src/libvirt_private.syms | 1 + src/util/virnetdevtap.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++ src/util/virnetdevtap.h | 3 ++ 4 files changed, 84 insertions(+), 69 deletions(-)
@@ -72,6 +79,78 @@ virNetDevTapGetName(int tapfd ATTRIBUTE_UNUSED, char **ifname ATTRIBUTE_UNUSED) #endif }
+/** + * virNetDevTapGetRealDeviceName: + * @ifname: the interface name + * + * Lookup real interface name (i.e. name of the device entry in /dev), + * because e.g. on FreeBSD if we rename tap device to vnetN its device + * entry still remains unchanged (/dev/tapX), but bhyve needs a name + * that matches /dev entry. + * + * Returns the proper interface name or NULL if no corresponding interface + * found. + */ +char* +virNetDevTapGetRealDeviceName(char *ifname) +{ + char *ret = NULL; + struct dirent *dp; + char *devpath = NULL; + int fd; + + DIR *dirp = opendir("/dev"); + if (dirp == NULL) { + virReportSystemError(errno, + _("Failed to opendir path '%s'"), + "/dev"); + return NULL; + } + + while ((dp = readdir(dirp)) != NULL) { + if (STRPREFIX(dp->d_name, "tap")) { + struct ifreq ifr; + if (virAsprintf(&devpath, "/dev/%s", dp->d_name) < 0) { + goto cleanup; + } + if ((fd = open(devpath, O_RDWR)) < 0) { + virReportSystemError(errno, _("Unable to open '%s'"), devpath); + goto cleanup; + } + + if (ioctl(fd, TAPGIFNAME, (void *)&ifr) < 0) {
This fails to build on Linux. The whole function should be #ifdef'd and return -1 on non-FreeBSD.
+ virReportSystemError(errno, "%s", + _("Unable to query tap interface name")); + goto cleanup; + } +
Jan

At this point unittest covers 4 basic cases: - minimal working XML for bhyve - same as above, but with virtio disk - ACPI and APIC args test - MAC address test --- src/util/virnetdevtap.c | 1 - tests/Makefile.am | 25 ++++ .../bhyvexml2argvdata/bhyvexml2argv-acpiapic.args | 3 + tests/bhyvexml2argvdata/bhyvexml2argv-acpiapic.xml | 24 ++++ tests/bhyvexml2argvdata/bhyvexml2argv-base.args | 3 + tests/bhyvexml2argvdata/bhyvexml2argv-base.xml | 20 +++ .../bhyvexml2argv-disk-virtio.args | 3 + .../bhyvexml2argv-disk-virtio.xml | 20 +++ tests/bhyvexml2argvdata/bhyvexml2argv-macaddr.args | 3 + tests/bhyvexml2argvdata/bhyvexml2argv-macaddr.xml | 21 +++ tests/bhyvexml2argvmock.c | 49 +++++++ tests/bhyvexml2argvtest.c | 155 +++++++++++++++++++++ 12 files changed, 326 insertions(+), 1 deletion(-) create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-acpiapic.args create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-acpiapic.xml create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-base.args create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-base.xml create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-disk-virtio.args create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-disk-virtio.xml create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-macaddr.args create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-macaddr.xml create mode 100644 tests/bhyvexml2argvmock.c create mode 100644 tests/bhyvexml2argvtest.c diff --git a/src/util/virnetdevtap.c b/src/util/virnetdevtap.c index bd00c28..6ecc1d6 100644 --- a/src/util/virnetdevtap.c +++ b/src/util/virnetdevtap.c @@ -22,7 +22,6 @@ #include <config.h> -#include <fcntl.h> #include <sys/types.h> #include <dirent.h> diff --git a/tests/Makefile.am b/tests/Makefile.am index 8025e77..4da1d60 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -232,6 +232,10 @@ if WITH_VMWARE test_programs += vmwarevertest endif WITH_VMWARE +if WITH_BHYVE +test_programs += bhyvexml2argvtest +endif WITH_BHYVE + if WITH_CIL test_programs += objectlocking endif WITH_CIL @@ -353,6 +357,10 @@ test_libraries += libqemumonitortestutils.la \ $(NULL) endif WITH_QEMU +if WITH_BHYVE +test_libraries += bhyvexml2argvmock.la +endif WITH_BHYVE + if WITH_DBUS test_libraries += virsystemdmock.la endif WITH_DBUS @@ -602,6 +610,23 @@ else ! WITH_VMWARE EXTRA_DIST += vmwarevertest.c endif ! WITH_VMWARE +if WITH_BHYVE +bhyvexml2argvmock_la_SOURCES = \ + bhyvexml2argvmock.c +bhyvexml2argvmock_la_CFLAGS = $(AM_CFLAGS) +bhyvexml2argvmock_la_LDFLAGS = -module -avoid-version \ + -rpath /evil/libtool/hack/to/force/shared/lib/creation + +bhyve_LDADDS = ../src/libvirt_driver_bhyve_impl.la +bhyve_LDADDS += $(LDADDS) +bhyvexml2argvtest_SOURCES = \ + bhyvexml2argvtest.c \ + testutils.c testutils.h +bhyvexml2argvtest_LDADD = $(bhyve_LDADDS) +else ! WITH_BHYVE +EXTRA_DIST += bhyvexml2argvtest.c +endif ! WITH_BHYVE + networkxml2xmltest_SOURCES = \ networkxml2xmltest.c \ testutils.c testutils.h diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-acpiapic.args b/tests/bhyvexml2argvdata/bhyvexml2argv-acpiapic.args new file mode 100644 index 0000000..60a56b9 --- /dev/null +++ b/tests/bhyvexml2argvdata/bhyvexml2argv-acpiapic.args @@ -0,0 +1,3 @@ +/usr/sbin/bhyve -c 1 -m 214 -A -I -H -P -s 0:0,hostbridge \ +-s 1:0,virtio-net,faketapdev,mac=52:54:00:00:00:00 \ +-s 2:0,ahci-hd,/tmp/freebsd.img bhyve diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-acpiapic.xml b/tests/bhyvexml2argvdata/bhyvexml2argv-acpiapic.xml new file mode 100644 index 0000000..b429fef --- /dev/null +++ b/tests/bhyvexml2argvdata/bhyvexml2argv-acpiapic.xml @@ -0,0 +1,24 @@ +<domain type='bhyve'> + <name>bhyve</name> + <uuid>df3be7e7-a104-11e3-aeb0-50e5492bd3dc</uuid> + <memory>219136</memory> + <vcpu>1</vcpu> + <os> + <type>hvm</type> + </os> + <features> + <apic/> + <acpi/> + </features> + <devices> + <disk type='file'> + <driver name='file' type='raw'/> + <source file='/tmp/freebsd.img'/> + <target dev='hda' bus='sata'/> + </disk> + <interface type='bridge'> + <model type='virtio'/> + <source bridge="virbr0"/> + </interface> + </devices> +</domain> diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-base.args b/tests/bhyvexml2argvdata/bhyvexml2argv-base.args new file mode 100644 index 0000000..9d4faa5 --- /dev/null +++ b/tests/bhyvexml2argvdata/bhyvexml2argv-base.args @@ -0,0 +1,3 @@ +/usr/sbin/bhyve -c 1 -m 214 -H -P -s 0:0,hostbridge \ +-s 1:0,virtio-net,faketapdev,mac=52:54:00:00:00:00 \ +-s 2:0,ahci-hd,/tmp/freebsd.img bhyve diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-base.xml b/tests/bhyvexml2argvdata/bhyvexml2argv-base.xml new file mode 100644 index 0000000..8c96f77 --- /dev/null +++ b/tests/bhyvexml2argvdata/bhyvexml2argv-base.xml @@ -0,0 +1,20 @@ +<domain type='bhyve'> + <name>bhyve</name> + <uuid>df3be7e7-a104-11e3-aeb0-50e5492bd3dc</uuid> + <memory>219136</memory> + <vcpu>1</vcpu> + <os> + <type>hvm</type> + </os> + <devices> + <disk type='file'> + <driver name='file' type='raw'/> + <source file='/tmp/freebsd.img'/> + <target dev='hda' bus='sata'/> + </disk> + <interface type='bridge'> + <model type='virtio'/> + <source bridge="virbr0"/> + </interface> + </devices> +</domain> diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-disk-virtio.args b/tests/bhyvexml2argvdata/bhyvexml2argv-disk-virtio.args new file mode 100644 index 0000000..54ad2b8 --- /dev/null +++ b/tests/bhyvexml2argvdata/bhyvexml2argv-disk-virtio.args @@ -0,0 +1,3 @@ +/usr/sbin/bhyve -c 1 -m 214 -H -P -s 0:0,hostbridge \ +-s 1:0,virtio-net,faketapdev,mac=52:54:00:00:00:00 \ +-s 2:0,virtio-blk,/tmp/freebsd.img bhyve diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-disk-virtio.xml b/tests/bhyvexml2argvdata/bhyvexml2argv-disk-virtio.xml new file mode 100644 index 0000000..8cfb518 --- /dev/null +++ b/tests/bhyvexml2argvdata/bhyvexml2argv-disk-virtio.xml @@ -0,0 +1,20 @@ +<domain type='bhyve'> + <name>bhyve</name> + <uuid>df3be7e7-a104-11e3-aeb0-50e5492bd3dc</uuid> + <memory>219136</memory> + <vcpu>1</vcpu> + <os> + <type>hvm</type> + </os> + <devices> + <disk type='file'> + <driver name='file' type='raw'/> + <source file='/tmp/freebsd.img'/> + <target dev='vda' bus='virtio'/> + </disk> + <interface type='bridge'> + <model type='virtio'/> + <source bridge="virbr0"/> + </interface> + </devices> +</domain> diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-macaddr.args b/tests/bhyvexml2argvdata/bhyvexml2argv-macaddr.args new file mode 100644 index 0000000..1a06abd --- /dev/null +++ b/tests/bhyvexml2argvdata/bhyvexml2argv-macaddr.args @@ -0,0 +1,3 @@ +/usr/sbin/bhyve -c 1 -m 214 -H -P -s 0:0,hostbridge \ +-s 1:0,virtio-net,faketapdev,mac=52:54:00:22:ee:11 \ +-s 2:0,ahci-hd,/tmp/freebsd.img bhyve diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-macaddr.xml b/tests/bhyvexml2argvdata/bhyvexml2argv-macaddr.xml new file mode 100644 index 0000000..41a42b0 --- /dev/null +++ b/tests/bhyvexml2argvdata/bhyvexml2argv-macaddr.xml @@ -0,0 +1,21 @@ +<domain type='bhyve'> + <name>bhyve</name> + <uuid>df3be7e7-a104-11e3-aeb0-50e5492bd3dc</uuid> + <memory>219136</memory> + <vcpu>1</vcpu> + <os> + <type>hvm</type> + </os> + <devices> + <disk type='file'> + <driver name='file' type='raw'/> + <source file='/tmp/freebsd.img'/> + <target dev='hda' bus='sata'/> + </disk> + <interface type='bridge'> + <mac address="52:54:00:22:ee:11"/> + <model type='virtio'/> + <source bridge="virbr0"/> + </interface> + </devices> +</domain> diff --git a/tests/bhyvexml2argvmock.c b/tests/bhyvexml2argvmock.c new file mode 100644 index 0000000..0776508 --- /dev/null +++ b/tests/bhyvexml2argvmock.c @@ -0,0 +1,49 @@ +#include <config.h> + +#include "util/virstring.h" +#include "util/virnetdev.h" +#include "util/virnetdevtap.h" +#include "internal.h" + +#define VIR_FROM_THIS VIR_FROM_BHYVE + +void virMacAddrGenerate(const unsigned char prefix[VIR_MAC_PREFIX_BUFLEN], + virMacAddrPtr addr) +{ + addr->addr[0] = prefix[0]; + addr->addr[1] = prefix[1]; + addr->addr[2] = prefix[2]; + addr->addr[3] = 0; + addr->addr[4] = 0; + addr->addr[5] = 0; +} + +int virNetDevTapCreateInBridgePort(const char *brname ATTRIBUTE_UNUSED, + char **ifname, + const virMacAddr *macaddr ATTRIBUTE_UNUSED, + const unsigned char *vmuuid ATTRIBUTE_UNUSED, + int *tapfd ATTRIBUTE_UNUSED, + int tapfdSize ATTRIBUTE_UNUSED, + virNetDevVPortProfilePtr virtPortProfile ATTRIBUTE_UNUSED, + virNetDevVlanPtr virtVlan ATTRIBUTE_UNUSED, + unsigned int fakeflags ATTRIBUTE_UNUSED) +{ + if (VIR_STRDUP(*ifname, "vnet0") < 0) + return -1; + return 0; +} + +char *virNetDevTapGetRealDeviceName(char *name ATTRIBUTE_UNUSED) +{ + char *fakename; + + if (VIR_STRDUP(fakename, "faketapdev") < 0) + return NULL; + return fakename; +} + +int virNetDevSetOnline(const char *ifname ATTRIBUTE_UNUSED, + bool online ATTRIBUTE_UNUSED) +{ + return 0; +} diff --git a/tests/bhyvexml2argvtest.c b/tests/bhyvexml2argvtest.c new file mode 100644 index 0000000..a6ad033 --- /dev/null +++ b/tests/bhyvexml2argvtest.c @@ -0,0 +1,155 @@ +#include <config.h> + +#include <stdio.h> +#include <stdlib.h> + +#include "datatypes.h" +#include "bhyve/bhyve_utils.h" +#include "bhyve/bhyve_command.h" + +#include "testutils.h" + +#ifdef WITH_BHYVE + +# define VIR_FROM_THIS VIR_FROM_BHYVE + +static bhyveConn driver; + +static virCapsPtr +testBhyveBuildCapabilities(void) +{ + virCapsPtr caps; + virCapsGuestPtr guest; + + if ((caps = virCapabilitiesNew(virArchFromHost(), + 0, 0)) == NULL) + return NULL; + + if ((guest = virCapabilitiesAddGuest(caps, "hvm", + VIR_ARCH_X86_64, + "bhyve", + NULL, 0, NULL)) == NULL) + goto error; + + if (virCapabilitiesAddGuestDomain(guest, + "bhyve", NULL, NULL, 0, NULL) == NULL) + goto error; + + return caps; + +error: + virObjectUnref(caps); + return NULL; +} + +static int testCompareXMLToArgvFiles(const char *xml, + const char *cmdline) +{ + char *expectargv = NULL; + int len; + char *actualargv = NULL; + virConnectPtr conn; + virDomainDefPtr vmdef = NULL; + virDomainObj vm; + virCommandPtr cmd = NULL; + int ret = -1; + + + if (!(conn = virGetConnect())) + goto out; + + if (!(vmdef = virDomainDefParseFile(xml, driver.caps, driver.xmlopt, + 1 << VIR_DOMAIN_VIRT_BHYVE, + VIR_DOMAIN_XML_INACTIVE))) + goto out; + + vm.def = vmdef; + + if (!(cmd = virBhyveProcessBuildBhyveCmd(&driver, &vm))) + goto out; + + if (!(actualargv = virCommandToString(cmd))) + goto out; + + len = virtTestLoadFile(cmdline, &expectargv); + if (len < 0) + goto out; + + if (len && expectargv[len - 1] == '\n') + expectargv[len - 1] = '\0'; + + if (STRNEQ(expectargv, actualargv)) { + virtTestDifference(stderr, expectargv, actualargv); + goto out; + } + + ret = 0; + +out: + VIR_FREE(expectargv); + VIR_FREE(actualargv); + virCommandFree(cmd); + virDomainDefFree(vmdef); + virObjectUnref(conn); + return ret; +} + +static int +testCompareXMLToArgvHelper(const void *data) +{ + int ret = -1; + const char *name = data; + char *xml = NULL; + char *args = NULL; + + if (virAsprintf(&xml, "%s/bhyvexml2argvdata/bhyvexml2argv-%s.xml", + abs_srcdir, name) < 0 || + virAsprintf(&args, "%s/bhyvexml2argvdata/bhyvexml2argv-%s.args", + abs_srcdir, name) < 0) + goto cleanup; + + ret = testCompareXMLToArgvFiles(xml, args); + +cleanup: + VIR_FREE(xml); + VIR_FREE(args); + return ret; +} + +static int +mymain(void) +{ + int ret = 0; + + if ((driver.caps = testBhyveBuildCapabilities()) == NULL) + return EXIT_FAILURE; + + if ((driver.xmlopt = virDomainXMLOptionNew(NULL, NULL, NULL)) == NULL) + return EXIT_FAILURE; + +# define DO_TEST(name) \ + do { \ + if (virtTestRun("BHYVE XML-2-ARGV " name, \ + testCompareXMLToArgvHelper, name) < 0) \ + ret = -1; \ + } while (0) + + + DO_TEST("base"); + DO_TEST("acpiapic"); + DO_TEST("disk-virtio"); + DO_TEST("macaddr"); + + return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE; +} + +VIRT_TEST_MAIN_PRELOAD(mymain, abs_builddir "/.libs/bhyvexml2argvmock.so") + +#else + +int main(void) +{ + return EXIT_AM_SKIP; +} + +#endif /* WITH_BHYVE */ -- 1.8.4.2

Roman Bogorodskiy wrote:
diff --git a/src/util/virnetdevtap.c b/src/util/virnetdevtap.c index bd00c28..6ecc1d6 100644 --- a/src/util/virnetdevtap.c +++ b/src/util/virnetdevtap.c @@ -22,7 +22,6 @@
#include <config.h>
-#include <fcntl.h> #include <sys/types.h> #include <dirent.h>
diff --git a/tests/Makefile.am b/tests/Makefile.am
Ah, I've just noticed that it should not have been added in the first patch of the series in the first place. I will not re-send v3 just because of that though and will wait for other comments first. Roman Bogorodskiy

On 03/23/2014 07:17 AM, Roman Bogorodskiy wrote:
At this point unittest covers 4 basic cases:
- minimal working XML for bhyve - same as above, but with virtio disk - ACPI and APIC args test - MAC address test --- src/util/virnetdevtap.c | 1 - tests/Makefile.am | 25 ++++ .../bhyvexml2argvdata/bhyvexml2argv-acpiapic.args | 3 + tests/bhyvexml2argvdata/bhyvexml2argv-acpiapic.xml | 24 ++++ tests/bhyvexml2argvdata/bhyvexml2argv-base.args | 3 + tests/bhyvexml2argvdata/bhyvexml2argv-base.xml | 20 +++ .../bhyvexml2argv-disk-virtio.args | 3 + .../bhyvexml2argv-disk-virtio.xml | 20 +++ tests/bhyvexml2argvdata/bhyvexml2argv-macaddr.args | 3 + tests/bhyvexml2argvdata/bhyvexml2argv-macaddr.xml | 21 +++ tests/bhyvexml2argvmock.c | 49 +++++++ tests/bhyvexml2argvtest.c | 155 +++++++++++++++++++++ 12 files changed, 326 insertions(+), 1 deletion(-) create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-acpiapic.args create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-acpiapic.xml create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-base.args create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-base.xml create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-disk-virtio.args create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-disk-virtio.xml create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-macaddr.args create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-macaddr.xml create mode 100644 tests/bhyvexml2argvmock.c create mode 100644 tests/bhyvexml2argvtest.c
diff --git a/tests/Makefile.am b/tests/Makefile.am index 8025e77..4da1d60 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -232,6 +232,10 @@ if WITH_VMWARE test_programs += vmwarevertest endif WITH_VMWARE
+if WITH_BHYVE +test_programs += bhyvexml2argvtest +endif WITH_BHYVE + if WITH_CIL test_programs += objectlocking endif WITH_CIL @@ -353,6 +357,10 @@ test_libraries += libqemumonitortestutils.la \ $(NULL) endif WITH_QEMU
+if WITH_BHYVE +test_libraries += bhyvexml2argvmock.la +endif WITH_BHYVE + if WITH_DBUS test_libraries += virsystemdmock.la endif WITH_DBUS @@ -602,6 +610,23 @@ else ! WITH_VMWARE EXTRA_DIST += vmwarevertest.c endif ! WITH_VMWARE
+if WITH_BHYVE +bhyvexml2argvmock_la_SOURCES = \ + bhyvexml2argvmock.c +bhyvexml2argvmock_la_CFLAGS = $(AM_CFLAGS) +bhyvexml2argvmock_la_LDFLAGS = -module -avoid-version \ + -rpath /evil/libtool/hack/to/force/shared/lib/creation + +bhyve_LDADDS = ../src/libvirt_driver_bhyve_impl.la +bhyve_LDADDS += $(LDADDS) +bhyvexml2argvtest_SOURCES = \ + bhyvexml2argvtest.c \ + testutils.c testutils.h +bhyvexml2argvtest_LDADD = $(bhyve_LDADDS) +else ! WITH_BHYVE +EXTRA_DIST += bhyvexml2argvtest.c +endif ! WITH_BHYVE
bhyvexml2argvdata should also be in EXTRA_DIST
+ networkxml2xmltest_SOURCES = \ networkxml2xmltest.c \ testutils.c testutils.h
+++ b/tests/bhyvexml2argvmock.c @@ -0,0 +1,49 @@ +#include <config.h> + +#include "util/virstring.h" +#include "util/virnetdev.h" +#include "util/virnetdevtap.h"
These should work without the 'util/' too.
+#include "internal.h" + +#define VIR_FROM_THIS VIR_FROM_BHYVE +
diff --git a/tests/bhyvexml2argvtest.c b/tests/bhyvexml2argvtest.c new file mode 100644 index 0000000..a6ad033 --- /dev/null +++ b/tests/bhyvexml2argvtest.c @@ -0,0 +1,155 @@ +#include <config.h> + +#include <stdio.h> +#include <stdlib.h> + +#include "datatypes.h" +#include "bhyve/bhyve_utils.h" +#include "bhyve/bhyve_command.h" + +#include "testutils.h"
Only config.h and testutils.h are needed without the bhyve driver. Other than that, looks good to me. Jan
participants (2)
-
Ján Tomko
-
Roman Bogorodskiy