[libvirt] [PATCH 0/3] libxl: Add a test suite for libxl_domain_config generator

Long ago danpb posted some patches to test libvirt domXML to libxl_domain_config conversion https://www.redhat.com/archives/libvir-list/2014-May/msg01102.html Some of the prerequisite patches were pushed, but we've never managed to push patches actually providing the conversion tests. I sent several follow-ups to Dan's work but never converged on a satisfactory solution for all the Xen versions supported by libvirt. The last attempt was in Sept 2014 https://www.redhat.com/archives/libvir-list/2014-September/msg00698.html I tried to revive the work in Jan 2015, but that also stalled https://www.redhat.com/archives/libvir-list/2015-January/msg00924.html Fast-forward over 2.5 years from the first attempt and libvirt no longer supports older Xen versions 4.2 and 4.3 that were proving to be problematic. Starting with Xen 4.5 libxl added support for libxl_domain_config_from_json, which provides a way to implement the conversion tests that work with all Xen versions >= 4.5 (including latest xen.git master). The previous approaches compared a static json doc with the results of domXML->libxl_domain_config conversion done in the libxl driver. As discussed in those approaches, the json doc returned from libxl_domain_config_to_json can change over Xen releases as the libxl_domain_config object gains new fields, making it difficult to compare the conversion with a static doc. I had some time last week to pick at this thorn and reworked the test to make use of libxl_domain_config_from_json introduced in Xen 4.5. Instead of comparing the conversion results directly to a static json doc, the static doc is first round-tripped through _from_json -> _to_json. Any new fields added to libxl_domain_config object are then included in both docs, allowing comparison across multiple Xen releases. Patch3 provides the conversion tests using this new approach. The tests are not run on Xen 4.4 (oldest version currently supported by libvirt) since it does not provide libxl_domain_config_from_json. Patches 1 and 2 fix some issues found while working on the tests. See their commit messages for details. Jim Fehlig (3): libxl: determine device model version from emulator name libxl: relax checks on <emulator> libxl: Add a test suite for libxl_domain_config generator m4/virt-driver-libxl.m4 | 6 +- src/libxl/libxl_capabilities.c | 37 ++--- src/libxl/libxl_conf.c | 14 -- tests/Makefile.am | 18 ++- tests/libxlxml2domconfigdata/basic-hvm.json | 89 +++++++++++ tests/libxlxml2domconfigdata/basic-hvm.xml | 36 +++++ tests/libxlxml2domconfigdata/basic-pv.json | 65 ++++++++ tests/libxlxml2domconfigdata/basic-pv.xml | 28 ++++ tests/libxlxml2domconfigdata/moredevs-hvm.json | 111 +++++++++++++ tests/libxlxml2domconfigdata/moredevs-hvm.xml | 63 ++++++++ tests/libxlxml2domconfigtest.c | 208 +++++++++++++++++++++++++ tests/virmocklibxl.c | 87 +++++++++++ 12 files changed, 723 insertions(+), 39 deletions(-) create mode 100644 tests/libxlxml2domconfigdata/basic-hvm.json create mode 100644 tests/libxlxml2domconfigdata/basic-hvm.xml create mode 100644 tests/libxlxml2domconfigdata/basic-pv.json create mode 100644 tests/libxlxml2domconfigdata/basic-pv.xml create mode 100644 tests/libxlxml2domconfigdata/moredevs-hvm.json create mode 100644 tests/libxlxml2domconfigdata/moredevs-hvm.xml create mode 100644 tests/libxlxml2domconfigtest.c create mode 100644 tests/virmocklibxl.c -- 2.11.0

libxl exposes a setting for specifying a device model version. The default is LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN, aka upstream qemu. But users can specify LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN_TRADITIONAL if they are using the old forked qemu, aka qemu-dm. libvirt only supports specifying an emulator by name, specifying a version is not supported. Prior to this change libvirt would invoke the specified emulator with '--help' option in an attempt to determine the version. If the help output included the string "Options specific to the Xen version:" it was assumed the emulator was the old forked qemu-dm. This approach works well when creating libxl_domain_config to start a VM, but is problematic when simply creating libxl_domain_config for unit test purposes. Build/development systems running unit tests may not have the emulator installed. Even if installed, invoking the emulator during unit tests is bad form. This change takes the simple-minded approach of determining the device model version based on the emulator name. If it contains "qemu-dm" it is assumed to be LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN_TRADITIONAL, otherwise LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN. Signed-off-by: Jim Fehlig <jfehlig@suse.com> --- src/libxl/libxl_capabilities.c | 37 +++++++++++++++---------------------- 1 file changed, 15 insertions(+), 22 deletions(-) diff --git a/src/libxl/libxl_capabilities.c b/src/libxl/libxl_capabilities.c index 2bbd2d1b4..7ad8e7b57 100644 --- a/src/libxl/libxl_capabilities.c +++ b/src/libxl/libxl_capabilities.c @@ -723,35 +723,28 @@ libxlMakeDomainCapabilities(virDomainCapsPtr domCaps, return 0; } -#define LIBXL_QEMU_DM_STR "Options specific to the Xen version:" +#define LIBXL_QEMU_DM_STR "qemu-dm" + +/* + * libxl exposes a setting for specifying a device model version. The default + * is LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN (aka upstream qemu). But users can + * specify LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN_TRADITIONAL if they are using + * the old, forked qemu (aka qemu-dm). libvirt only supports specifying an + * emulator. This function makes a poor attempt at determining the device + * model version based on the emulator name. If the emulator name contains + * "qemu-dm", it is assumed to be a + * LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN_TRADITIONAL emulator. + */ int libxlDomainGetEmulatorType(const virDomainDef *def) { - int ret = LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN; - virCommandPtr cmd = NULL; - char *output = NULL; - if (def->os.type == VIR_DOMAIN_OSTYPE_HVM) { if (def->emulator) { - if (!virFileExists(def->emulator)) - goto cleanup; - - cmd = virCommandNew(def->emulator); - - virCommandAddArgList(cmd, "-help", NULL); - virCommandSetOutputBuffer(cmd, &output); - - if (virCommandRun(cmd, NULL) < 0) - goto cleanup; - - if (strstr(output, LIBXL_QEMU_DM_STR)) - ret = LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN_TRADITIONAL; + if (strstr(def->emulator, LIBXL_QEMU_DM_STR)) + return LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN_TRADITIONAL; } } - cleanup: - VIR_FREE(output); - virCommandFree(cmd); - return ret; + return LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN; } -- 2.11.0

Checking for the existence and execute permission of a user-specified emulator is fine when actually creating a VM, but is problematic when running unit tests since a development system may not have the emulator installed. Defer the emulator checks to libxl, when actually starting a VM. One downside is errors associated with non-existent or non-executable emulator are reported in the libxl driver log files instead of being returned through the libvirt API. E.g. before this change virsh create test.xml error: Failed to create domain from test.xml error: unsupported configuration: emulator '/foo/bar' not found After this change virsh create test.xml error: Failed to create domain from test.xml error: internal error: libxenlight failed to create new domain 'test' but the libxl driver log file contains 2017-02-23 22:04:18.319+0000: libxl: libxl_dm.c:2050:libxl__spawn_local_dm: device model /foo/bar is not executable: No such file or directory Signed-off-by: Jim Fehlig <jfehlig@suse.com> --- src/libxl/libxl_conf.c | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c index 4bab651b3..2c10fbe25 100644 --- a/src/libxl/libxl_conf.c +++ b/src/libxl/libxl_conf.c @@ -435,20 +435,6 @@ libxlMakeDomBuildInfo(virDomainDefPtr def, b_info->u.hvm.bios = LIBXL_BIOS_TYPE_OVMF; if (def->emulator) { - if (!virFileExists(def->emulator)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("emulator '%s' not found"), - def->emulator); - return -1; - } - - if (!virFileIsExecutable(def->emulator)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("emulator '%s' is not executable"), - def->emulator); - return -1; - } - VIR_FREE(b_info->device_model); if (VIR_STRDUP(b_info->device_model, def->emulator) < 0) return -1; -- 2.11.0

The libxl library allows a libxl_domain_config object to be serialized from/to a JSON string. Use this to allow testing of the XML to libxl_domain_config conversion process. Test XML is converted to libxl_domain_config, which is then serialized to json. A json template corresponding to the test XML is converted to a libxl_domain_config object using libxl_domain_config_from_json(), and then serialized back to json using libxl_domain_config_to_json(). The two json docs are then compared. Using libxl to convert the json template to a libxl_domain_config object and then back to json provides a simple way to account for any changes or additions to the json representation across Xen releases. Signed-off-by: Jim Fehlig <jfehlig@suse.com> --- m4/virt-driver-libxl.m4 | 6 +- tests/Makefile.am | 18 ++- tests/libxlxml2domconfigdata/basic-hvm.json | 89 +++++++++++ tests/libxlxml2domconfigdata/basic-hvm.xml | 36 +++++ tests/libxlxml2domconfigdata/basic-pv.json | 65 ++++++++ tests/libxlxml2domconfigdata/basic-pv.xml | 28 ++++ tests/libxlxml2domconfigdata/moredevs-hvm.json | 111 +++++++++++++ tests/libxlxml2domconfigdata/moredevs-hvm.xml | 63 ++++++++ tests/libxlxml2domconfigtest.c | 208 +++++++++++++++++++++++++ tests/virmocklibxl.c | 87 +++++++++++ 10 files changed, 708 insertions(+), 3 deletions(-) diff --git a/m4/virt-driver-libxl.m4 b/m4/virt-driver-libxl.m4 index 96a9d4736..3d635f0a6 100644 --- a/m4/virt-driver-libxl.m4 +++ b/m4/virt-driver-libxl.m4 @@ -35,7 +35,7 @@ AC_DEFUN([LIBVIRT_DRIVER_CHECK_LIBXL], [ if test "x$with_libxl" = "xyes" ; then LIBXL_FIRMWARE_DIR=$($PKG_CONFIG --variable xenfirmwaredir xenlight) LIBXL_EXECBIN_DIR=$($PKG_CONFIG --variable libexec_bin xenlight) - fi + fi dnl pkgconfig file not found, fallback to lib probe if test "x$with_libxl" = "xno" ; then @@ -80,6 +80,10 @@ AC_DEFUN([LIBVIRT_DRIVER_CHECK_LIBXL], [ LIBXL_LIBS="$LIBXL_LIBS -lxenctrl" ]) + dnl Check if libxl_domain_config_from_json is available for domXML to + dnl libxl_domain_config tests + LIBS="$LIBS -lxenlight -lxenctrl" + AC_CHECK_FUNCS([libxl_domain_config_from_json]) CFLAGS="$old_CFLAGS" LIBS="$old_LIBS" fi diff --git a/tests/Makefile.am b/tests/Makefile.am index 35e82abf5..6b00b4f94 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -100,6 +100,7 @@ EXTRA_DIST = \ genericxml2xmlindata \ genericxml2xmloutdata \ interfaceschemadata \ + libxlxml2domconfigdata \ lxcconf2xmldata \ lxcxml2xmldata \ lxcxml2xmloutdata \ @@ -268,7 +269,8 @@ test_programs += xml2sexprtest sexpr2xmltest \ endif WITH_XEN if WITH_LIBXL -test_programs += xlconfigtest +test_programs += xlconfigtest libxlxml2domconfigtest +test_libraries += virmocklibxl.la endif WITH_LIBXL if WITH_QEMU @@ -521,8 +523,20 @@ xlconfigtest_SOURCES = \ xlconfigtest.c testutilsxen.c testutilsxen.h \ testutils.c testutils.h xlconfigtest_LDADD =$(libxl_LDADDS) + +libxlxml2domconfigtest_SOURCES = \ + libxlxml2domconfigtest.c testutilsxen.c testutilsxen.h \ + testutils.c testutils.h +libxlxml2domconfigtest_LDADD = $(libxl_LDADDS) $(LIBXML_LIBS) + +virmocklibxl_la_SOURCES = \ + virmocklibxl.c +virmocklibxl_la_CFLAGS = $(AM_CFLAGS) +virmocklibxl_la_LDFLAGS = -module -avoid-version \ + -rpath /evil/libtool/hack/to/force/shared/lib/creation + else ! WITH_LIBXL -EXTRA_DIST += xlconfigtest.c +EXTRA_DIST += xlconfigtest.c libxlxml2domconfigtest.c endif ! WITH_LIBXL QEMUMONITORTESTUTILS_SOURCES = \ diff --git a/tests/libxlxml2domconfigdata/basic-hvm.json b/tests/libxlxml2domconfigdata/basic-hvm.json new file mode 100644 index 000000000..e4771920e --- /dev/null +++ b/tests/libxlxml2domconfigdata/basic-hvm.json @@ -0,0 +1,89 @@ +{ + "c_info": { + "type": "hvm", + "name": "test-hvm", + "uuid": "2147d599-9cc6-c0dc-92ab-4064b5446e9b" + }, + "b_info": { + "max_vcpus": 4, + "avail_vcpus": [ + 0, + 1, + 2, + 3 + ], + "max_memkb": 1048576, + "target_memkb": 1048576, + "video_memkb": 8192, + "shadow_memkb": 12288, + "device_model_version": "qemu_xen", + "device_model": "/usr/lib/xen/bin/qemu-system-i386", + "sched_params": { + "weight": 1000 + }, + "type.hvm": { + "pae": "True", + "apic": "True", + "acpi": "True", + "vga": { + "kind": "cirrus" + }, + "vnc": { + "enable": "True", + "listen": "0.0.0.0", + "findunused": "False" + }, + "sdl": { + "enable": "False" + }, + "spice": { + + }, + "boot": "c", + "rdm": { + + } + }, + "arch_arm": { + + } + }, + "disks": [ + { + "pdev_path": "/var/lib/xen/images/test-hvm.img", + "vdev": "hda", + "backend": "qdisk", + "format": "raw", + "removable": 1, + "readwrite": 1 + } + ], + "nics": [ + { + "devid": 0, + "mac": "00:16:3e:66:12:b4", + "bridge": "br0", + "script": "/etc/xen/scripts/vif-bridge", + "nictype": "vif_ioemu" + } + ], + "vfbs": [ + { + "devid": -1, + "vnc": { + "enable": "True", + "listen": "0.0.0.0", + "findunused": "False" + }, + "sdl": { + "enable": "False" + } + } + ], + "vkbs": [ + { + "devid": -1 + } + ], + "on_reboot": "restart" +} diff --git a/tests/libxlxml2domconfigdata/basic-hvm.xml b/tests/libxlxml2domconfigdata/basic-hvm.xml new file mode 100644 index 000000000..9dedf1729 --- /dev/null +++ b/tests/libxlxml2domconfigdata/basic-hvm.xml @@ -0,0 +1,36 @@ +<domain type='xen'> + <name>test-hvm</name> + <description>None</description> + <uuid>2147d599-9cc6-c0dc-92ab-4064b5446e9b</uuid> + <memory>1048576</memory> + <currentMemory>1048576</currentMemory> + <vcpu>4</vcpu> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <clock sync='utc'/> + <os> + <type>hvm</type> + <loader>/usr/lib/xen/boot/hvmloader</loader> + <boot dev='hd'/> + </os> + <features> + <apic/> + <acpi/> + <pae/> + </features> + <devices> + <emulator>/usr/lib/xen/bin/qemu-system-i386</emulator> + <disk type='file' device='disk'> + <driver name='qemu'/> + <source file='/var/lib/xen/images/test-hvm.img'/> + <target dev='hda'/> + </disk> + <interface type='bridge'> + <source bridge='br0'/> + <mac address='00:16:3e:66:12:b4'/> + <script path='/etc/xen/scripts/vif-bridge'/> + </interface> + <graphics type='vnc' port='-1' autoport='yes' listen='0.0.0.0'/> + </devices> +</domain> diff --git a/tests/libxlxml2domconfigdata/basic-pv.json b/tests/libxlxml2domconfigdata/basic-pv.json new file mode 100644 index 000000000..7e1abd3d6 --- /dev/null +++ b/tests/libxlxml2domconfigdata/basic-pv.json @@ -0,0 +1,65 @@ +{ + "c_info": { + "type": "pv", + "name": "test-pv", + "uuid": "039e9ee6-4a84-3055-4c81-8ba426ae2656" + }, + "b_info": { + "max_vcpus": 4, + "avail_vcpus": [ + 0, + 1, + 2, + 3 + ], + "max_memkb": 524288, + "target_memkb": 524288, + "sched_params": { + "weight": 1000 + }, + "type.pv": { + "bootloader": "pygrub" + }, + "arch_arm": { + + } + }, + "disks": [ + { + "pdev_path": "/var/lib/xen/images/test-pv.img", + "vdev": "xvda", + "backend": "qdisk", + "format": "raw", + "removable": 1, + "readwrite": 1 + } + ], + "nics": [ + { + "devid": 0, + "mac": "00:16:3e:3e:86:60", + "bridge": "br0", + "script": "/etc/xen/scripts/vif-bridge", + "nictype": "vif" + } + ], + "vfbs": [ + { + "devid": -1, + "vnc": { + "enable": "True", + "listen": "0.0.0.0", + "findunused": "False" + }, + "sdl": { + "enable": "False" + } + } + ], + "vkbs": [ + { + "devid": -1 + } + ], + "on_reboot": "restart" +} diff --git a/tests/libxlxml2domconfigdata/basic-pv.xml b/tests/libxlxml2domconfigdata/basic-pv.xml new file mode 100644 index 000000000..b3bc6012d --- /dev/null +++ b/tests/libxlxml2domconfigdata/basic-pv.xml @@ -0,0 +1,28 @@ +<domain type='xen'> + <name>test-pv</name> + <uuid>039e9ee6-4a84-3055-4c81-8ba426ae2656</uuid> + <memory>524288</memory> + <currentMemory>524288</currentMemory> + <vcpu>4</vcpu> + <bootloader>pygrub</bootloader> + <os> + <type arch='i686' machine='xenpv'>linux</type> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <disk type='file' device='disk'> + <driver name='qemu'/> + <source file='/var/lib/xen/images/test-pv.img'/> + <target dev='xvda'/> + </disk> + <interface type='bridge'> + <source bridge='br0'/> + <mac address='00:16:3e:3e:86:60'/> + <script path='/etc/xen/scripts/vif-bridge'/> + </interface> + <graphics type='vnc' port='-1' autoport='yes' listen='0.0.0.0'/> + </devices> +</domain> diff --git a/tests/libxlxml2domconfigdata/moredevs-hvm.json b/tests/libxlxml2domconfigdata/moredevs-hvm.json new file mode 100644 index 000000000..70840d2b3 --- /dev/null +++ b/tests/libxlxml2domconfigdata/moredevs-hvm.json @@ -0,0 +1,111 @@ +{ + "c_info": { + "type": "hvm", + "hap": "True", + "name": "test-hvm", + "uuid": "2147d599-9cc6-c0dc-92ab-4064b5446e9b" + }, + "b_info": { + "max_vcpus": 4, + "avail_vcpus": [ + 0, + 1, + 2, + 3 + ], + "tsc_mode": "native", + "max_memkb": 1048576, + "target_memkb": 1048576, + "video_memkb": 8192, + "shadow_memkb": 12288, + "device_model_version": "qemu_xen", + "device_model": "/usr/lib/xen/bin/qemu-system-i386", + "sched_params": { + "weight": 1000 + }, + "type.hvm": { + "pae": "True", + "apic": "True", + "acpi": "True", + "hpet": "True", + "vga": { + "kind": "cirrus" + }, + "vnc": { + "enable": "True", + "findunused": "False" + }, + "sdl": { + "enable": "False" + }, + "spice": { + + }, + "serial": "pty", + "boot": "c", + "usbdevice_list": [ + "mouse", + "tablet" + ], + "rdm": { + + } + }, + "arch_arm": { + + } + }, + "disks": [ + { + "pdev_path": "/var/lib/xen/images/test-hvm.img", + "vdev": "hda", + "backend": "qdisk", + "format": "raw", + "removable": 1, + "readwrite": 1 + }, + { + "pdev_path": "/root/boot.iso", + "vdev": "hdb", + "backend": "qdisk", + "format": "raw", + "removable": 1, + "is_cdrom": 1 + } + ], + "nics": [ + { + "devid": 0, + "model": "netfront", + "mac": "00:16:3e:7a:35:ce", + "bridge": "br0", + "script": "/etc/xen/scripts/vif-bridge", + "nictype": "vif" + } + ], + "pcidevs": [ + { + "dev": 16, + "bus": 10, + "rdm_policy": "invalid" + } + ], + "vfbs": [ + { + "devid": -1, + "vnc": { + "enable": "True", + "findunused": "False" + }, + "sdl": { + "enable": "False" + } + } + ], + "vkbs": [ + { + "devid": -1 + } + ], + "on_reboot": "restart" +} diff --git a/tests/libxlxml2domconfigdata/moredevs-hvm.xml b/tests/libxlxml2domconfigdata/moredevs-hvm.xml new file mode 100644 index 000000000..e93e153c5 --- /dev/null +++ b/tests/libxlxml2domconfigdata/moredevs-hvm.xml @@ -0,0 +1,63 @@ +<domain type='xen'> + <name>test-hvm</name> + <description>None</description> + <uuid>2147d599-9cc6-c0dc-92ab-4064b5446e9b</uuid> + <memory>1048576</memory> + <currentMemory>1048576</currentMemory> + <vcpu>4</vcpu> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <clock offset='variable' adjustment='0' basis='utc'> + <timer name='tsc' present='yes' mode='native'/> + <timer name='hpet' present='yes'/> + </clock> + <os> + <type>hvm</type> + <loader>/usr/lib/xen/boot/hvmloader</loader> + <boot dev='hd'/> + </os> + <features> + <apic/> + <acpi/> + <pae/> + <hap/> + </features> + <devices> + <emulator>/usr/lib/xen/bin/qemu-system-i386</emulator> + <disk type='file' device='disk'> + <driver name='qemu' type='raw' cache='default'/> + <source file='/var/lib/xen/images/test-hvm.img'/> + <target dev='hda'/> + </disk> + <disk type='file' device='cdrom'> + <driver name='qemu' type='raw' cache='default'/> + <source file='/root/boot.iso'/> + <target dev='hdb'/> + </disk> + <interface type='bridge'> + <source bridge='br0'/> + <mac address='00:16:3e:7a:35:ce'/> + <script path='/etc/xen/scripts/vif-bridge'/> + <model type='netfront'/> + </interface> + <interface type='hostdev' managed='yes'> + <mac address='00:16:3e:2e:e7:fc'/> + <driver name='xen'/> + <source> + <address type='pci' domain='0x0000' bus='0x0a' slot='0x10' function='0x0'/> + </source> + </interface> + <graphics type='vnc'/> + <video> + <model type='cirrus' vram='8192' heads='1' primary='yes'/> + </video> + <console type='pty'> + <target port='0'/> + </console> + <input type='mouse' bus='usb'/> + <input type='tablet' bus='usb'/> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + </devices> +</domain> diff --git a/tests/libxlxml2domconfigtest.c b/tests/libxlxml2domconfigtest.c new file mode 100644 index 000000000..9f563a1ec --- /dev/null +++ b/tests/libxlxml2domconfigtest.c @@ -0,0 +1,208 @@ +/* + * libxlxml2domconfigtest.c: test conversion of domXML to + * libxl_domain_config structure. + * + * Copyright (C) 2017 SUSE LINUX Products GmbH, Nuernberg, Germany. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <http://www.gnu.org/licenses/>. + * + * Author: Jim Fehlig <jfehlig@suse.com> + */ + +#include <config.h> + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> + +#include <sys/types.h> +#include <fcntl.h> + +#include "testutils.h" + +#if defined(WITH_LIBXL) && defined(WITH_YAJL) && defined(HAVE_LIBXL_DOMAIN_CONFIG_FROM_JSON) + +# include "internal.h" +# include "viralloc.h" +# include "libxl/libxl_conf.h" +# include "datatypes.h" +# include "virstring.h" +# include "virmock.h" +# include "virjson.h" +# include "testutilsxen.h" + +# define VIR_FROM_THIS VIR_FROM_LIBXL + +static const char *abs_top_srcdir; +static virCapsPtr xencaps; + +static int +testCompareXMLToDomConfig(const char *xmlfile, + const char *jsonfile) +{ + int ret = -1; + libxl_domain_config actualconfig; + libxl_domain_config expectconfig; + xentoollog_logger *log = NULL; + libxl_ctx *ctx = NULL; + virPortAllocatorPtr gports = NULL; + virDomainXMLOptionPtr xmlopt = NULL; + virDomainDefPtr vmdef = NULL; + char *actualjson = NULL; + char *tempjson = NULL; + char *expectjson = NULL; + + libxl_domain_config_init(&actualconfig); + libxl_domain_config_init(&expectconfig); + + if (!(log = (xentoollog_logger *)xtl_createlogger_stdiostream(stderr, XTL_DEBUG, 0))) + goto cleanup; + + if (libxl_ctx_alloc(&ctx, LIBXL_VERSION, 0, log) < 0) + goto cleanup; + + if (!(gports = virPortAllocatorNew("vnc", 5900, 6000, + VIR_PORT_ALLOCATOR_SKIP_BIND_CHECK))) + goto cleanup; + + if (!(xmlopt = libxlCreateXMLConf())) + goto cleanup; + + if (!(vmdef = virDomainDefParseFile(xmlfile, xencaps, xmlopt, + NULL, VIR_DOMAIN_XML_INACTIVE))) + goto cleanup; + + if (libxlBuildDomainConfig(gports, vmdef, NULL, ctx, &actualconfig) < 0) + goto cleanup; + + if (!(actualjson = libxl_domain_config_to_json(ctx, &actualconfig))) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + "Failed to retrieve JSON doc for libxl_domain_config"); + goto cleanup; + } + + virTestLoadFile(jsonfile, &tempjson); + if (libxl_domain_config_from_json(ctx, &expectconfig, tempjson) != 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + "Failed to create libxl_domain_config from JSON doc"); + goto cleanup; + } + if (!(expectjson = libxl_domain_config_to_json(ctx, &expectconfig))) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + "Failed to retrieve JSON doc for libxl_domain_config"); + goto cleanup; + } + + if (strcmp(expectjson, actualjson)) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + "Expected and actual libxl_domain_config objects do not compare"); + goto cleanup; + } + + ret = 0; + + cleanup: + VIR_FREE(expectjson); + VIR_FREE(actualjson); + VIR_FREE(tempjson); + virDomainDefFree(vmdef); + virObjectUnref(gports); + virObjectUnref(xmlopt); + libxl_ctx_free(ctx); + libxl_domain_config_dispose(&actualconfig); + libxl_domain_config_dispose(&expectconfig); + xtl_logger_destroy(log); + return ret; +} + + +struct testInfo { + const char *name; +}; + + +static int +testCompareXMLToDomConfigHelper(const void *data) +{ + int ret = -1; + const struct testInfo *info = data; + char *xmlfile = NULL; + char *jsonfile = NULL; + + if (virAsprintf(&xmlfile, "%s/libxlxml2domconfigdata/%s.xml", + abs_srcdir, info->name) < 0 || + virAsprintf(&jsonfile, "%s/libxlxml2domconfigdata/%s.json", + abs_srcdir, info->name) < 0) + goto cleanup; + + ret = testCompareXMLToDomConfig(xmlfile, jsonfile); + + cleanup: + VIR_FREE(xmlfile); + VIR_FREE(jsonfile); + return ret; +} + + +static int +mymain(void) +{ + int ret = 0; + + abs_top_srcdir = getenv("abs_top_srcdir"); + if (!abs_top_srcdir) + abs_top_srcdir = abs_srcdir "/.."; + + /* Set the timezone because we are mocking the time() function. + * If we don't do that, then localtime() may return unpredictable + * results. In order to detect things that just work by a blind + * chance, we need to set an virtual timezone that no libvirt + * developer resides in. */ + if (setenv("TZ", "VIR00:30", 1) < 0) { + perror("setenv"); + return EXIT_FAILURE; + } + + if ((xencaps = testXenCapsInit()) == NULL) + return EXIT_FAILURE; + +# define DO_TEST(name) \ + do { \ + static struct testInfo info = { \ + name, \ + }; \ + if (virTestRun("LibXL XML-2-JSON " name, \ + testCompareXMLToDomConfigHelper, &info) < 0) \ + ret = -1; \ + } while (0) + + DO_TEST("basic-pv"); + DO_TEST("basic-hvm"); + DO_TEST("moredevs-hvm"); + + return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE; +} + +VIRT_TEST_MAIN_PRELOAD(mymain, abs_builddir "/.libs/virmocklibxl.so") + +#else + +int main(void) +{ + return EXIT_AM_SKIP; +} + +#endif /* WITH_LIBXL && WITH_YAJL && HAVE_LIBXL_DOMAIN_CONFIG_FROM_JSON */ diff --git a/tests/virmocklibxl.c b/tests/virmocklibxl.c new file mode 100644 index 000000000..bc4b53d68 --- /dev/null +++ b/tests/virmocklibxl.c @@ -0,0 +1,87 @@ +/* + * virmocklibxl.c: mocking of xenstore/libxs for libxl + * + * Copyright (C) 2014 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <http://www.gnu.org/licenses/>. + * + * Author: Daniel P. Berrange <berrange@redhat.com> + */ + +#include <config.h> + +#if defined(WITH_LIBXL) && defined(WITH_YAJL) +# include "virmock.h" +# include <sys/stat.h> +# include <unistd.h> +# include <libxl.h> +# include <xenstore.h> +# include <xenctrl.h> + +VIR_MOCK_IMPL_RET_VOID(xs_daemon_open, + struct xs_handle *) +{ + VIR_MOCK_REAL_INIT(xs_daemon_open); + return (void*)0x1; +} + +VIR_MOCK_IMPL_RET_ARGS(xc_interface_open, + xc_interface *, + xentoollog_logger *, logger, + xentoollog_logger *, dombuild_logger, + unsigned, open_flags) +{ + VIR_MOCK_REAL_INIT(xc_interface_open); + return (void*)0x1; +} + + +VIR_MOCK_STUB_RET_ARGS(xc_interface_close, + int, 0, + xc_interface *, handle) + +VIR_MOCK_STUB_VOID_ARGS(xs_daemon_close, + struct xs_handle *, handle) + +VIR_MOCK_IMPL_RET_ARGS(__xstat, int, + int, ver, + const char *, path, + struct stat *, sb) +{ + VIR_MOCK_REAL_INIT(__xstat); + + if (strstr(path, "xenstored.pid")) { + memset(sb, 0, sizeof(*sb)); + return 0; + } + + return real___xstat(ver, path, sb); +} + +VIR_MOCK_IMPL_RET_ARGS(stat, int, + const char *, path, + struct stat *, sb) +{ + VIR_MOCK_REAL_INIT(stat); + + if (strstr(path, "xenstored.pid")) { + memset(sb, 0, sizeof(*sb)); + return 0; + } + + return real_stat(path, sb); +} + +#endif /* WITH_LIBXL && WITH_YAJL */ -- 2.11.0

The libxl library allows a libxl_domain_config object to be serialized from/to a JSON string. Use this to allow testing of the XML to libxl_domain_config conversion process. Test XML is converted to libxl_domain_config, which is then serialized to json. A json template corresponding to the test XML is converted to a libxl_domain_config object using libxl_domain_config_from_json(), and then serialized back to json using libxl_domain_config_to_json(). The two json docs are then compared. Using libxl to convert the json template to a libxl_domain_config object and then back to json provides a simple way to account for any changes or additions to the json representation across Xen releases. Signed-off-by: Jim Fehlig <jfehlig@suse.com> [update to v3.5.0-rc1, improve error reporting] Signed-off-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com> --- m4/virt-driver-libxl.m4 | 6 +- tests/Makefile.am | 18 ++- tests/libxlxml2domconfigdata/basic-hvm.json | 89 +++++++++++ tests/libxlxml2domconfigdata/basic-hvm.xml | 36 +++++ tests/libxlxml2domconfigdata/basic-pv.json | 65 ++++++++ tests/libxlxml2domconfigdata/basic-pv.xml | 28 ++++ tests/libxlxml2domconfigdata/moredevs-hvm.json | 111 +++++++++++++ tests/libxlxml2domconfigdata/moredevs-hvm.xml | 63 ++++++++ tests/libxlxml2domconfigtest.c | 205 +++++++++++++++++++++++++ tests/virmocklibxl.c | 87 +++++++++++ 10 files changed, 705 insertions(+), 3 deletions(-) create mode 100644 tests/libxlxml2domconfigdata/basic-hvm.json create mode 100644 tests/libxlxml2domconfigdata/basic-hvm.xml create mode 100644 tests/libxlxml2domconfigdata/basic-pv.json create mode 100644 tests/libxlxml2domconfigdata/basic-pv.xml create mode 100644 tests/libxlxml2domconfigdata/moredevs-hvm.json create mode 100644 tests/libxlxml2domconfigdata/moredevs-hvm.xml create mode 100644 tests/libxlxml2domconfigtest.c create mode 100644 tests/virmocklibxl.c diff --git a/m4/virt-driver-libxl.m4 b/m4/virt-driver-libxl.m4 index 96a9d47..3d635f0 100644 --- a/m4/virt-driver-libxl.m4 +++ b/m4/virt-driver-libxl.m4 @@ -35,7 +35,7 @@ AC_DEFUN([LIBVIRT_DRIVER_CHECK_LIBXL], [ if test "x$with_libxl" = "xyes" ; then LIBXL_FIRMWARE_DIR=$($PKG_CONFIG --variable xenfirmwaredir xenlight) LIBXL_EXECBIN_DIR=$($PKG_CONFIG --variable libexec_bin xenlight) - fi + fi dnl pkgconfig file not found, fallback to lib probe if test "x$with_libxl" = "xno" ; then @@ -80,6 +80,10 @@ AC_DEFUN([LIBVIRT_DRIVER_CHECK_LIBXL], [ LIBXL_LIBS="$LIBXL_LIBS -lxenctrl" ]) + dnl Check if libxl_domain_config_from_json is available for domXML to + dnl libxl_domain_config tests + LIBS="$LIBS -lxenlight -lxenctrl" + AC_CHECK_FUNCS([libxl_domain_config_from_json]) CFLAGS="$old_CFLAGS" LIBS="$old_LIBS" fi diff --git a/tests/Makefile.am b/tests/Makefile.am index 19986dc..6e4419f 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -102,6 +102,7 @@ EXTRA_DIST = \ genericxml2xmlindata \ genericxml2xmloutdata \ interfaceschemadata \ + libxlxml2domconfigdata \ lxcconf2xmldata \ lxcxml2xmldata \ lxcxml2xmloutdata \ @@ -274,7 +275,8 @@ test_programs += xml2sexprtest sexpr2xmltest \ endif WITH_XEN if WITH_LIBXL -test_programs += xlconfigtest +test_programs += xlconfigtest libxlxml2domconfigtest +test_libraries += virmocklibxl.la endif WITH_LIBXL if WITH_QEMU @@ -529,8 +531,20 @@ xlconfigtest_SOURCES = \ xlconfigtest.c testutilsxen.c testutilsxen.h \ testutils.c testutils.h xlconfigtest_LDADD =$(libxl_LDADDS) + +libxlxml2domconfigtest_SOURCES = \ + libxlxml2domconfigtest.c testutilsxen.c testutilsxen.h \ + testutils.c testutils.h +libxlxml2domconfigtest_LDADD = $(libxl_LDADDS) $(LIBXML_LIBS) + +virmocklibxl_la_SOURCES = \ + virmocklibxl.c +virmocklibxl_la_CFLAGS = $(AM_CFLAGS) +virmocklibxl_la_LDFLAGS = -module -avoid-version \ + -rpath /evil/libtool/hack/to/force/shared/lib/creation + else ! WITH_LIBXL -EXTRA_DIST += xlconfigtest.c +EXTRA_DIST += xlconfigtest.c libxlxml2domconfigtest.c endif ! WITH_LIBXL QEMUMONITORTESTUTILS_SOURCES = \ diff --git a/tests/libxlxml2domconfigdata/basic-hvm.json b/tests/libxlxml2domconfigdata/basic-hvm.json new file mode 100644 index 0000000..e477192 --- /dev/null +++ b/tests/libxlxml2domconfigdata/basic-hvm.json @@ -0,0 +1,89 @@ +{ + "c_info": { + "type": "hvm", + "name": "test-hvm", + "uuid": "2147d599-9cc6-c0dc-92ab-4064b5446e9b" + }, + "b_info": { + "max_vcpus": 4, + "avail_vcpus": [ + 0, + 1, + 2, + 3 + ], + "max_memkb": 1048576, + "target_memkb": 1048576, + "video_memkb": 8192, + "shadow_memkb": 12288, + "device_model_version": "qemu_xen", + "device_model": "/usr/lib/xen/bin/qemu-system-i386", + "sched_params": { + "weight": 1000 + }, + "type.hvm": { + "pae": "True", + "apic": "True", + "acpi": "True", + "vga": { + "kind": "cirrus" + }, + "vnc": { + "enable": "True", + "listen": "0.0.0.0", + "findunused": "False" + }, + "sdl": { + "enable": "False" + }, + "spice": { + + }, + "boot": "c", + "rdm": { + + } + }, + "arch_arm": { + + } + }, + "disks": [ + { + "pdev_path": "/var/lib/xen/images/test-hvm.img", + "vdev": "hda", + "backend": "qdisk", + "format": "raw", + "removable": 1, + "readwrite": 1 + } + ], + "nics": [ + { + "devid": 0, + "mac": "00:16:3e:66:12:b4", + "bridge": "br0", + "script": "/etc/xen/scripts/vif-bridge", + "nictype": "vif_ioemu" + } + ], + "vfbs": [ + { + "devid": -1, + "vnc": { + "enable": "True", + "listen": "0.0.0.0", + "findunused": "False" + }, + "sdl": { + "enable": "False" + } + } + ], + "vkbs": [ + { + "devid": -1 + } + ], + "on_reboot": "restart" +} diff --git a/tests/libxlxml2domconfigdata/basic-hvm.xml b/tests/libxlxml2domconfigdata/basic-hvm.xml new file mode 100644 index 0000000..9dedf17 --- /dev/null +++ b/tests/libxlxml2domconfigdata/basic-hvm.xml @@ -0,0 +1,36 @@ +<domain type='xen'> + <name>test-hvm</name> + <description>None</description> + <uuid>2147d599-9cc6-c0dc-92ab-4064b5446e9b</uuid> + <memory>1048576</memory> + <currentMemory>1048576</currentMemory> + <vcpu>4</vcpu> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <clock sync='utc'/> + <os> + <type>hvm</type> + <loader>/usr/lib/xen/boot/hvmloader</loader> + <boot dev='hd'/> + </os> + <features> + <apic/> + <acpi/> + <pae/> + </features> + <devices> + <emulator>/usr/lib/xen/bin/qemu-system-i386</emulator> + <disk type='file' device='disk'> + <driver name='qemu'/> + <source file='/var/lib/xen/images/test-hvm.img'/> + <target dev='hda'/> + </disk> + <interface type='bridge'> + <source bridge='br0'/> + <mac address='00:16:3e:66:12:b4'/> + <script path='/etc/xen/scripts/vif-bridge'/> + </interface> + <graphics type='vnc' port='-1' autoport='yes' listen='0.0.0.0'/> + </devices> +</domain> diff --git a/tests/libxlxml2domconfigdata/basic-pv.json b/tests/libxlxml2domconfigdata/basic-pv.json new file mode 100644 index 0000000..7e1abd3 --- /dev/null +++ b/tests/libxlxml2domconfigdata/basic-pv.json @@ -0,0 +1,65 @@ +{ + "c_info": { + "type": "pv", + "name": "test-pv", + "uuid": "039e9ee6-4a84-3055-4c81-8ba426ae2656" + }, + "b_info": { + "max_vcpus": 4, + "avail_vcpus": [ + 0, + 1, + 2, + 3 + ], + "max_memkb": 524288, + "target_memkb": 524288, + "sched_params": { + "weight": 1000 + }, + "type.pv": { + "bootloader": "pygrub" + }, + "arch_arm": { + + } + }, + "disks": [ + { + "pdev_path": "/var/lib/xen/images/test-pv.img", + "vdev": "xvda", + "backend": "qdisk", + "format": "raw", + "removable": 1, + "readwrite": 1 + } + ], + "nics": [ + { + "devid": 0, + "mac": "00:16:3e:3e:86:60", + "bridge": "br0", + "script": "/etc/xen/scripts/vif-bridge", + "nictype": "vif" + } + ], + "vfbs": [ + { + "devid": -1, + "vnc": { + "enable": "True", + "listen": "0.0.0.0", + "findunused": "False" + }, + "sdl": { + "enable": "False" + } + } + ], + "vkbs": [ + { + "devid": -1 + } + ], + "on_reboot": "restart" +} diff --git a/tests/libxlxml2domconfigdata/basic-pv.xml b/tests/libxlxml2domconfigdata/basic-pv.xml new file mode 100644 index 0000000..b3bc601 --- /dev/null +++ b/tests/libxlxml2domconfigdata/basic-pv.xml @@ -0,0 +1,28 @@ +<domain type='xen'> + <name>test-pv</name> + <uuid>039e9ee6-4a84-3055-4c81-8ba426ae2656</uuid> + <memory>524288</memory> + <currentMemory>524288</currentMemory> + <vcpu>4</vcpu> + <bootloader>pygrub</bootloader> + <os> + <type arch='i686' machine='xenpv'>linux</type> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <disk type='file' device='disk'> + <driver name='qemu'/> + <source file='/var/lib/xen/images/test-pv.img'/> + <target dev='xvda'/> + </disk> + <interface type='bridge'> + <source bridge='br0'/> + <mac address='00:16:3e:3e:86:60'/> + <script path='/etc/xen/scripts/vif-bridge'/> + </interface> + <graphics type='vnc' port='-1' autoport='yes' listen='0.0.0.0'/> + </devices> +</domain> diff --git a/tests/libxlxml2domconfigdata/moredevs-hvm.json b/tests/libxlxml2domconfigdata/moredevs-hvm.json new file mode 100644 index 0000000..70840d2 --- /dev/null +++ b/tests/libxlxml2domconfigdata/moredevs-hvm.json @@ -0,0 +1,111 @@ +{ + "c_info": { + "type": "hvm", + "hap": "True", + "name": "test-hvm", + "uuid": "2147d599-9cc6-c0dc-92ab-4064b5446e9b" + }, + "b_info": { + "max_vcpus": 4, + "avail_vcpus": [ + 0, + 1, + 2, + 3 + ], + "tsc_mode": "native", + "max_memkb": 1048576, + "target_memkb": 1048576, + "video_memkb": 8192, + "shadow_memkb": 12288, + "device_model_version": "qemu_xen", + "device_model": "/usr/lib/xen/bin/qemu-system-i386", + "sched_params": { + "weight": 1000 + }, + "type.hvm": { + "pae": "True", + "apic": "True", + "acpi": "True", + "hpet": "True", + "vga": { + "kind": "cirrus" + }, + "vnc": { + "enable": "True", + "findunused": "False" + }, + "sdl": { + "enable": "False" + }, + "spice": { + + }, + "serial": "pty", + "boot": "c", + "usbdevice_list": [ + "mouse", + "tablet" + ], + "rdm": { + + } + }, + "arch_arm": { + + } + }, + "disks": [ + { + "pdev_path": "/var/lib/xen/images/test-hvm.img", + "vdev": "hda", + "backend": "qdisk", + "format": "raw", + "removable": 1, + "readwrite": 1 + }, + { + "pdev_path": "/root/boot.iso", + "vdev": "hdb", + "backend": "qdisk", + "format": "raw", + "removable": 1, + "is_cdrom": 1 + } + ], + "nics": [ + { + "devid": 0, + "model": "netfront", + "mac": "00:16:3e:7a:35:ce", + "bridge": "br0", + "script": "/etc/xen/scripts/vif-bridge", + "nictype": "vif" + } + ], + "pcidevs": [ + { + "dev": 16, + "bus": 10, + "rdm_policy": "invalid" + } + ], + "vfbs": [ + { + "devid": -1, + "vnc": { + "enable": "True", + "findunused": "False" + }, + "sdl": { + "enable": "False" + } + } + ], + "vkbs": [ + { + "devid": -1 + } + ], + "on_reboot": "restart" +} diff --git a/tests/libxlxml2domconfigdata/moredevs-hvm.xml b/tests/libxlxml2domconfigdata/moredevs-hvm.xml new file mode 100644 index 0000000..e93e153 --- /dev/null +++ b/tests/libxlxml2domconfigdata/moredevs-hvm.xml @@ -0,0 +1,63 @@ +<domain type='xen'> + <name>test-hvm</name> + <description>None</description> + <uuid>2147d599-9cc6-c0dc-92ab-4064b5446e9b</uuid> + <memory>1048576</memory> + <currentMemory>1048576</currentMemory> + <vcpu>4</vcpu> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <clock offset='variable' adjustment='0' basis='utc'> + <timer name='tsc' present='yes' mode='native'/> + <timer name='hpet' present='yes'/> + </clock> + <os> + <type>hvm</type> + <loader>/usr/lib/xen/boot/hvmloader</loader> + <boot dev='hd'/> + </os> + <features> + <apic/> + <acpi/> + <pae/> + <hap/> + </features> + <devices> + <emulator>/usr/lib/xen/bin/qemu-system-i386</emulator> + <disk type='file' device='disk'> + <driver name='qemu' type='raw' cache='default'/> + <source file='/var/lib/xen/images/test-hvm.img'/> + <target dev='hda'/> + </disk> + <disk type='file' device='cdrom'> + <driver name='qemu' type='raw' cache='default'/> + <source file='/root/boot.iso'/> + <target dev='hdb'/> + </disk> + <interface type='bridge'> + <source bridge='br0'/> + <mac address='00:16:3e:7a:35:ce'/> + <script path='/etc/xen/scripts/vif-bridge'/> + <model type='netfront'/> + </interface> + <interface type='hostdev' managed='yes'> + <mac address='00:16:3e:2e:e7:fc'/> + <driver name='xen'/> + <source> + <address type='pci' domain='0x0000' bus='0x0a' slot='0x10' function='0x0'/> + </source> + </interface> + <graphics type='vnc'/> + <video> + <model type='cirrus' vram='8192' heads='1' primary='yes'/> + </video> + <console type='pty'> + <target port='0'/> + </console> + <input type='mouse' bus='usb'/> + <input type='tablet' bus='usb'/> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + </devices> +</domain> diff --git a/tests/libxlxml2domconfigtest.c b/tests/libxlxml2domconfigtest.c new file mode 100644 index 0000000..d943cf2 --- /dev/null +++ b/tests/libxlxml2domconfigtest.c @@ -0,0 +1,205 @@ +/* + * libxlxml2domconfigtest.c: test conversion of domXML to + * libxl_domain_config structure. + * + * Copyright (C) 2017 SUSE LINUX Products GmbH, Nuernberg, Germany. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <http://www.gnu.org/licenses/>. + * + * Author: Jim Fehlig <jfehlig@suse.com> + */ + +#include <config.h> + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> + +#include <sys/types.h> +#include <fcntl.h> + +#include "testutils.h" + +#if defined(WITH_LIBXL) && defined(WITH_YAJL) && defined(HAVE_LIBXL_DOMAIN_CONFIG_FROM_JSON) + +# include "internal.h" +# include "viralloc.h" +# include "libxl/libxl_conf.h" +# include "datatypes.h" +# include "virstring.h" +# include "virmock.h" +# include "virjson.h" +# include "testutilsxen.h" + +# define VIR_FROM_THIS VIR_FROM_LIBXL + +static const char *abs_top_srcdir; +static virCapsPtr xencaps; + +static int +testCompareXMLToDomConfig(const char *xmlfile, + const char *jsonfile) +{ + int ret = -1; + libxl_domain_config actualconfig; + libxl_domain_config expectconfig; + xentoollog_logger *log = NULL; + libxl_ctx *ctx = NULL; + virPortAllocatorPtr gports = NULL; + virDomainXMLOptionPtr xmlopt = NULL; + virDomainDefPtr vmdef = NULL; + char *actualjson = NULL; + char *tempjson = NULL; + char *expectjson = NULL; + + libxl_domain_config_init(&actualconfig); + libxl_domain_config_init(&expectconfig); + + if (!(log = (xentoollog_logger *)xtl_createlogger_stdiostream(stderr, XTL_DEBUG, 0))) + goto cleanup; + + if (libxl_ctx_alloc(&ctx, LIBXL_VERSION, 0, log) < 0) + goto cleanup; + + if (!(gports = virPortAllocatorNew("vnc", 5900, 6000, + VIR_PORT_ALLOCATOR_SKIP_BIND_CHECK))) + goto cleanup; + + if (!(xmlopt = libxlCreateXMLConf())) + goto cleanup; + + if (!(vmdef = virDomainDefParseFile(xmlfile, xencaps, xmlopt, + NULL, VIR_DOMAIN_XML_INACTIVE))) + goto cleanup; + + if (libxlBuildDomainConfig(gports, vmdef, NULL, ctx, xencaps, &actualconfig) < 0) + goto cleanup; + + if (!(actualjson = libxl_domain_config_to_json(ctx, &actualconfig))) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + "Failed to retrieve JSON doc for libxl_domain_config"); + goto cleanup; + } + + virTestLoadFile(jsonfile, &tempjson); + if (libxl_domain_config_from_json(ctx, &expectconfig, tempjson) != 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + "Failed to create libxl_domain_config from JSON doc"); + goto cleanup; + } + if (!(expectjson = libxl_domain_config_to_json(ctx, &expectconfig))) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + "Failed to retrieve JSON doc for libxl_domain_config"); + goto cleanup; + } + + if (virTestCompareToString(expectjson, actualjson) < 0) + goto cleanup; + + ret = 0; + + cleanup: + VIR_FREE(expectjson); + VIR_FREE(actualjson); + VIR_FREE(tempjson); + virDomainDefFree(vmdef); + virObjectUnref(gports); + virObjectUnref(xmlopt); + libxl_ctx_free(ctx); + libxl_domain_config_dispose(&actualconfig); + libxl_domain_config_dispose(&expectconfig); + xtl_logger_destroy(log); + return ret; +} + + +struct testInfo { + const char *name; +}; + + +static int +testCompareXMLToDomConfigHelper(const void *data) +{ + int ret = -1; + const struct testInfo *info = data; + char *xmlfile = NULL; + char *jsonfile = NULL; + + if (virAsprintf(&xmlfile, "%s/libxlxml2domconfigdata/%s.xml", + abs_srcdir, info->name) < 0 || + virAsprintf(&jsonfile, "%s/libxlxml2domconfigdata/%s.json", + abs_srcdir, info->name) < 0) + goto cleanup; + + ret = testCompareXMLToDomConfig(xmlfile, jsonfile); + + cleanup: + VIR_FREE(xmlfile); + VIR_FREE(jsonfile); + return ret; +} + + +static int +mymain(void) +{ + int ret = 0; + + abs_top_srcdir = getenv("abs_top_srcdir"); + if (!abs_top_srcdir) + abs_top_srcdir = abs_srcdir "/.."; + + /* Set the timezone because we are mocking the time() function. + * If we don't do that, then localtime() may return unpredictable + * results. In order to detect things that just work by a blind + * chance, we need to set an virtual timezone that no libvirt + * developer resides in. */ + if (setenv("TZ", "VIR00:30", 1) < 0) { + perror("setenv"); + return EXIT_FAILURE; + } + + if ((xencaps = testXenCapsInit()) == NULL) + return EXIT_FAILURE; + +# define DO_TEST(name) \ + do { \ + static struct testInfo info = { \ + name, \ + }; \ + if (virTestRun("LibXL XML-2-JSON " name, \ + testCompareXMLToDomConfigHelper, &info) < 0) \ + ret = -1; \ + } while (0) + + DO_TEST("basic-pv"); + DO_TEST("basic-hvm"); + DO_TEST("moredevs-hvm"); + + return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE; +} + +VIR_TEST_MAIN_PRELOAD(mymain, abs_builddir "/.libs/virmocklibxl.so") + +#else + +int main(void) +{ + return EXIT_AM_SKIP; +} + +#endif /* WITH_LIBXL && WITH_YAJL && HAVE_LIBXL_DOMAIN_CONFIG_FROM_JSON */ diff --git a/tests/virmocklibxl.c b/tests/virmocklibxl.c new file mode 100644 index 0000000..bc4b53d --- /dev/null +++ b/tests/virmocklibxl.c @@ -0,0 +1,87 @@ +/* + * virmocklibxl.c: mocking of xenstore/libxs for libxl + * + * Copyright (C) 2014 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <http://www.gnu.org/licenses/>. + * + * Author: Daniel P. Berrange <berrange@redhat.com> + */ + +#include <config.h> + +#if defined(WITH_LIBXL) && defined(WITH_YAJL) +# include "virmock.h" +# include <sys/stat.h> +# include <unistd.h> +# include <libxl.h> +# include <xenstore.h> +# include <xenctrl.h> + +VIR_MOCK_IMPL_RET_VOID(xs_daemon_open, + struct xs_handle *) +{ + VIR_MOCK_REAL_INIT(xs_daemon_open); + return (void*)0x1; +} + +VIR_MOCK_IMPL_RET_ARGS(xc_interface_open, + xc_interface *, + xentoollog_logger *, logger, + xentoollog_logger *, dombuild_logger, + unsigned, open_flags) +{ + VIR_MOCK_REAL_INIT(xc_interface_open); + return (void*)0x1; +} + + +VIR_MOCK_STUB_RET_ARGS(xc_interface_close, + int, 0, + xc_interface *, handle) + +VIR_MOCK_STUB_VOID_ARGS(xs_daemon_close, + struct xs_handle *, handle) + +VIR_MOCK_IMPL_RET_ARGS(__xstat, int, + int, ver, + const char *, path, + struct stat *, sb) +{ + VIR_MOCK_REAL_INIT(__xstat); + + if (strstr(path, "xenstored.pid")) { + memset(sb, 0, sizeof(*sb)); + return 0; + } + + return real___xstat(ver, path, sb); +} + +VIR_MOCK_IMPL_RET_ARGS(stat, int, + const char *, path, + struct stat *, sb) +{ + VIR_MOCK_REAL_INIT(stat); + + if (strstr(path, "xenstored.pid")) { + memset(sb, 0, sizeof(*sb)); + return 0; + } + + return real_stat(path, sb); +} + +#endif /* WITH_LIBXL && WITH_YAJL */ -- 2.7.5

On Sun, Feb 26, 2017 at 07:02:24PM -0700, Jim Fehlig wrote:
Long ago danpb posted some patches to test libvirt domXML to libxl_domain_config conversion
https://www.redhat.com/archives/libvir-list/2014-May/msg01102.html
Some of the prerequisite patches were pushed, but we've never managed to push patches actually providing the conversion tests. I sent several follow-ups to Dan's work but never converged on a satisfactory solution for all the Xen versions supported by libvirt. The last attempt was in Sept 2014
https://www.redhat.com/archives/libvir-list/2014-September/msg00698.html
I tried to revive the work in Jan 2015, but that also stalled
https://www.redhat.com/archives/libvir-list/2015-January/msg00924.html
Fast-forward over 2.5 years from the first attempt and libvirt no longer supports older Xen versions 4.2 and 4.3 that were proving to be problematic. Starting with Xen 4.5 libxl added support for libxl_domain_config_from_json, which provides a way to implement the conversion tests that work with all Xen versions >= 4.5 (including latest xen.git master).
Few more months have passed... FWIW, I've tested it with Xen 4.6. The patch needs very minor update: - s/VIRT_TEST_MAIN_PRELOAD/VIR_TEST_MAIN_PRELOAD/ - add xencaps argument to libxlBuildDomainConfig call After that, it works! When I made some test to fail, reported error is not so helpful ("libvirt: Xen Light Driver error : internal error: Expected and actual libxl_domain_config objects do not compare"), but it do catch failures. Then, if I change strcmp to virTestCompareToString, the output is much more helpful. I'd really love to have it merged, mostly because I want to add more tests using this framework (see "Add setting CPU features (CPUID) with libxenlight driver" thread). Is there anything I can do to make it happen? -- Best Regards, Marek Marczykowski-Górecki Invisible Things Lab A: Because it messes up the order in which people normally read text. Q: Why is top-posting such a bad thing?

On Sun, Jul 02, 2017 at 04:16:02AM +0200, Marek Marczykowski-Górecki wrote:
On Sun, Feb 26, 2017 at 07:02:24PM -0700, Jim Fehlig wrote:
Long ago danpb posted some patches to test libvirt domXML to libxl_domain_config conversion
https://www.redhat.com/archives/libvir-list/2014-May/msg01102.html
Some of the prerequisite patches were pushed, but we've never managed to push patches actually providing the conversion tests. I sent several follow-ups to Dan's work but never converged on a satisfactory solution for all the Xen versions supported by libvirt. The last attempt was in Sept 2014
https://www.redhat.com/archives/libvir-list/2014-September/msg00698.html
I tried to revive the work in Jan 2015, but that also stalled
https://www.redhat.com/archives/libvir-list/2015-January/msg00924.html
Fast-forward over 2.5 years from the first attempt and libvirt no longer supports older Xen versions 4.2 and 4.3 that were proving to be problematic. Starting with Xen 4.5 libxl added support for libxl_domain_config_from_json, which provides a way to implement the conversion tests that work with all Xen versions >= 4.5 (including latest xen.git master).
Few more months have passed...
FWIW, I've tested it with Xen 4.6. The patch needs very minor update: - s/VIRT_TEST_MAIN_PRELOAD/VIR_TEST_MAIN_PRELOAD/ - add xencaps argument to libxlBuildDomainConfig call
After that, it works! When I made some test to fail, reported error is not so helpful ("libvirt: Xen Light Driver error : internal error: Expected and actual libxl_domain_config objects do not compare"), but it do catch failures. Then, if I change strcmp to virTestCompareToString, the output is much more helpful.
I'd really love to have it merged, mostly because I want to add more tests using this framework (see "Add setting CPU features (CPUID) with libxenlight driver" thread). Is there anything I can do to make it happen?
Ping? -- Best Regards, Marek Marczykowski-Górecki Invisible Things Lab A: Because it messes up the order in which people normally read text. Q: Why is top-posting such a bad thing?

On 07/01/2017 08:16 PM, Marek Marczykowski-Górecki wrote:
On Sun, Feb 26, 2017 at 07:02:24PM -0700, Jim Fehlig wrote:
Long ago danpb posted some patches to test libvirt domXML to libxl_domain_config conversion
https://www.redhat.com/archives/libvir-list/2014-May/msg01102.html
Some of the prerequisite patches were pushed, but we've never managed to push patches actually providing the conversion tests. I sent several follow-ups to Dan's work but never converged on a satisfactory solution for all the Xen versions supported by libvirt. The last attempt was in Sept 2014
https://www.redhat.com/archives/libvir-list/2014-September/msg00698.html
I tried to revive the work in Jan 2015, but that also stalled
https://www.redhat.com/archives/libvir-list/2015-January/msg00924.html
Fast-forward over 2.5 years from the first attempt and libvirt no longer supports older Xen versions 4.2 and 4.3 that were proving to be problematic. Starting with Xen 4.5 libxl added support for libxl_domain_config_from_json, which provides a way to implement the conversion tests that work with all Xen versions >= 4.5 (including latest xen.git master).
Few more months have passed...
And a few more weeks :-). Sorry for the delay. Slowly catching up on libvirt mail after some time away...
FWIW, I've tested it with Xen 4.6. The patch needs very minor update: - s/VIRT_TEST_MAIN_PRELOAD/VIR_TEST_MAIN_PRELOAD/ - add xencaps argument to libxlBuildDomainConfig cal >
After that, it works! When I made some test to fail, reported error is not so helpful ("libvirt: Xen Light Driver error : internal error: Expected and actual libxl_domain_config objects do not compare"), but it do catch failures. Then, if I change strcmp to virTestCompareToString, the output is much more helpful.
Thanks for the improvements. I noticed you included them in your V2 of patch 3/3. I assume you needed patches 1 and 2 as well?
I'd really love to have it merged, mostly because I want to add more tests using this framework (see "Add setting CPU features (CPUID) with libxenlight driver" thread).
I really dislike patches 1 and 2. They remove very useful checks IMO. Shortly after posting the series in Feb, I tried mocking the emulator checks. I failed quite a bit before coming up with something that worked, yet not so satisfying :-). I'll attach the (now rather old) patches for reference.
Is there anything I can do to make it happen?
Do you have time to update these old patches, test, and repost to the list? Or perhaps have better ideas on mocking, or approaches that avoid the need for 1/3 and 2/3. Regards, Jim

On Fri, Jul 14, 2017 at 05:59:57PM -0600, Jim Fehlig wrote:
On 07/01/2017 08:16 PM, Marek Marczykowski-Górecki wrote:
On Sun, Feb 26, 2017 at 07:02:24PM -0700, Jim Fehlig wrote:
Long ago danpb posted some patches to test libvirt domXML to libxl_domain_config conversion
https://www.redhat.com/archives/libvir-list/2014-May/msg01102.html
Some of the prerequisite patches were pushed, but we've never managed to push patches actually providing the conversion tests. I sent several follow-ups to Dan's work but never converged on a satisfactory solution for all the Xen versions supported by libvirt. The last attempt was in Sept 2014
https://www.redhat.com/archives/libvir-list/2014-September/msg00698.html
I tried to revive the work in Jan 2015, but that also stalled
https://www.redhat.com/archives/libvir-list/2015-January/msg00924.html
Fast-forward over 2.5 years from the first attempt and libvirt no longer supports older Xen versions 4.2 and 4.3 that were proving to be problematic. Starting with Xen 4.5 libxl added support for libxl_domain_config_from_json, which provides a way to implement the conversion tests that work with all Xen versions >= 4.5 (including latest xen.git master).
Few more months have passed...
And a few more weeks :-). Sorry for the delay. Slowly catching up on libvirt mail after some time away...
It's me this time...
FWIW, I've tested it with Xen 4.6. The patch needs very minor update: - s/VIRT_TEST_MAIN_PRELOAD/VIR_TEST_MAIN_PRELOAD/ - add xencaps argument to libxlBuildDomainConfig cal >
After that, it works! When I made some test to fail, reported error is not so helpful ("libvirt: Xen Light Driver error : internal error: Expected and actual libxl_domain_config objects do not compare"), but it do catch failures. Then, if I change strcmp to virTestCompareToString, the output is much more helpful.
Thanks for the improvements. I noticed you included them in your V2 of patch 3/3. I assume you needed patches 1 and 2 as well?
Yes, in this tests shape. But see below.
I'd really love to have it merged, mostly because I want to add more tests using this framework (see "Add setting CPU features (CPUID) with libxenlight driver" thread).
I really dislike patches 1 and 2. They remove very useful checks IMO. Shortly after posting the series in Feb, I tried mocking the emulator checks. I failed quite a bit before coming up with something that worked, yet not so satisfying :-). I'll attach the (now rather old) patches for reference.
My independent try to this test approach ("tests: check domain XML to libxl structures conversion") had much simpler (but uglier) solution for this problem: use /bin/true as emulator path (replaced in runtime, just after loading XML from file). While proper mocking this check would be better, apparently it isn't trivial.
Is there anything I can do to make it happen?
Do you have time to update these old patches, test, and repost to the list? Or perhaps have better ideas on mocking, or approaches that avoid the need for 1/3 and 2/3.
If using /bin/true as emulator path is acceptable, I can finish this and post updated version. -- Best Regards, Marek Marczykowski-Górecki Invisible Things Lab A: Because it messes up the order in which people normally read text. Q: Why is top-posting such a bad thing?

On 07/26/2017 05:07 PM, Marek Marczykowski-Górecki wrote:
On Fri, Jul 14, 2017 at 05:59:57PM -0600, Jim Fehlig wrote:
On 07/01/2017 08:16 PM, Marek Marczykowski-Górecki wrote:
On Sun, Feb 26, 2017 at 07:02:24PM -0700, Jim Fehlig wrote:
Long ago danpb posted some patches to test libvirt domXML to libxl_domain_config conversion
https://www.redhat.com/archives/libvir-list/2014-May/msg01102.html
Some of the prerequisite patches were pushed, but we've never managed to push patches actually providing the conversion tests. I sent several follow-ups to Dan's work but never converged on a satisfactory solution for all the Xen versions supported by libvirt. The last attempt was in Sept 2014
https://www.redhat.com/archives/libvir-list/2014-September/msg00698.html
I tried to revive the work in Jan 2015, but that also stalled
https://www.redhat.com/archives/libvir-list/2015-January/msg00924.html
Fast-forward over 2.5 years from the first attempt and libvirt no longer supports older Xen versions 4.2 and 4.3 that were proving to be problematic. Starting with Xen 4.5 libxl added support for libxl_domain_config_from_json, which provides a way to implement the conversion tests that work with all Xen versions >= 4.5 (including latest xen.git master).
Few more months have passed...
And a few more weeks :-). Sorry for the delay. Slowly catching up on libvirt mail after some time away...
It's me this time...
FWIW, I've tested it with Xen 4.6. The patch needs very minor update: - s/VIRT_TEST_MAIN_PRELOAD/VIR_TEST_MAIN_PRELOAD/ - add xencaps argument to libxlBuildDomainConfig cal >
After that, it works! When I made some test to fail, reported error is not so helpful ("libvirt: Xen Light Driver error : internal error: Expected and actual libxl_domain_config objects do not compare"), but it do catch failures. Then, if I change strcmp to virTestCompareToString, the output is much more helpful.
Thanks for the improvements. I noticed you included them in your V2 of patch 3/3. I assume you needed patches 1 and 2 as well?
Yes, in this tests shape. But see below.
I'd really love to have it merged, mostly because I want to add more tests using this framework (see "Add setting CPU features (CPUID) with libxenlight driver" thread).
I really dislike patches 1 and 2. They remove very useful checks IMO. Shortly after posting the series in Feb, I tried mocking the emulator checks. I failed quite a bit before coming up with something that worked, yet not so satisfying :-). I'll attach the (now rather old) patches for reference.
My independent try to this test approach ("tests: check domain XML to libxl structures conversion") had much simpler (but uglier) solution for this problem: use /bin/true as emulator path (replaced in runtime, just after loading XML from file).
Ah, clever and devious. For that matter all the test files could be changed to <emulator>/bin/true</emulator> :-).
Do you have time to update these old patches, test, and repost to the list? Or perhaps have better ideas on mocking, or approaches that avoid the need for 1/3 and 2/3.
If using /bin/true as emulator path is acceptable, I can finish this and post updated version.
Did you have any comment on the approach taken in the attachments to this thread? Particularly the patch titled "libxl: make emulator checks mockable"?

On Thu, Jul 27, 2017 at 03:24:38PM -0600, Jim Fehlig wrote:
On 07/26/2017 05:07 PM, Marek Marczykowski-Górecki wrote:
On Fri, Jul 14, 2017 at 05:59:57PM -0600, Jim Fehlig wrote:
On 07/01/2017 08:16 PM, Marek Marczykowski-Górecki wrote:
On Sun, Feb 26, 2017 at 07:02:24PM -0700, Jim Fehlig wrote:
Long ago danpb posted some patches to test libvirt domXML to libxl_domain_config conversion
https://www.redhat.com/archives/libvir-list/2014-May/msg01102.html
Some of the prerequisite patches were pushed, but we've never managed to push patches actually providing the conversion tests. I sent several follow-ups to Dan's work but never converged on a satisfactory solution for all the Xen versions supported by libvirt. The last attempt was in Sept 2014
https://www.redhat.com/archives/libvir-list/2014-September/msg00698.html
I tried to revive the work in Jan 2015, but that also stalled
https://www.redhat.com/archives/libvir-list/2015-January/msg00924.html
Fast-forward over 2.5 years from the first attempt and libvirt no longer supports older Xen versions 4.2 and 4.3 that were proving to be problematic. Starting with Xen 4.5 libxl added support for libxl_domain_config_from_json, which provides a way to implement the conversion tests that work with all Xen versions >= 4.5 (including latest xen.git master).
Few more months have passed...
And a few more weeks :-). Sorry for the delay. Slowly catching up on libvirt mail after some time away...
It's me this time...
FWIW, I've tested it with Xen 4.6. The patch needs very minor update: - s/VIRT_TEST_MAIN_PRELOAD/VIR_TEST_MAIN_PRELOAD/ - add xencaps argument to libxlBuildDomainConfig cal >
After that, it works! When I made some test to fail, reported error is not so helpful ("libvirt: Xen Light Driver error : internal error: Expected and actual libxl_domain_config objects do not compare"), but it do catch failures. Then, if I change strcmp to virTestCompareToString, the output is much more helpful.
Thanks for the improvements. I noticed you included them in your V2 of patch 3/3. I assume you needed patches 1 and 2 as well?
Yes, in this tests shape. But see below.
I'd really love to have it merged, mostly because I want to add more tests using this framework (see "Add setting CPU features (CPUID) with libxenlight driver" thread).
I really dislike patches 1 and 2. They remove very useful checks IMO. Shortly after posting the series in Feb, I tried mocking the emulator checks. I failed quite a bit before coming up with something that worked, yet not so satisfying :-). I'll attach the (now rather old) patches for reference.
My independent try to this test approach ("tests: check domain XML to libxl structures conversion") had much simpler (but uglier) solution for this problem: use /bin/true as emulator path (replaced in runtime, just after loading XML from file).
Ah, clever and devious. For that matter all the test files could be changed to <emulator>/bin/true</emulator> :-).
Do you have time to update these old patches, test, and repost to the list? Or perhaps have better ideas on mocking, or approaches that avoid the need for 1/3 and 2/3.
If using /bin/true as emulator path is acceptable, I can finish this and post updated version.
Did you have any comment on the approach taken in the attachments to this thread? Particularly the patch titled "libxl: make emulator checks mockable"?
I don't see how macros could solve this - those are expanded at individual files compilation time. And you don't recompile the driver for tests. Something that could work would be putting those two functions into separate shared object, then override using LD_PRELOAD or something like this. But it would require significant change in the driver structure just for tests. Alternatively something similar could be done by covering lower level functions (virFileExists, virCommandRun, or even open, stat etc). Using /bin/true is much simpler anyway. -- Best Regards, Marek Marczykowski-Górecki Invisible Things Lab A: Because it messes up the order in which people normally read text. Q: Why is top-posting such a bad thing?

On 07/27/2017 04:51 PM, Marek Marczykowski-Górecki wrote:
On Thu, Jul 27, 2017 at 03:24:38PM -0600, Jim Fehlig wrote:
Did you have any comment on the approach taken in the attachments to this thread? Particularly the patch titled "libxl: make emulator checks mockable"? I don't see how macros could solve this - those are expanded at individual files compilation time. And you don't recompile the driver for tests.
Right. I went back to my mocking attempt and thought that I had something working https://www.redhat.com/archives/libvir-list/2017-July/msg01335.html But while testing I forgot to remove my /usr/lib/xen/bin/qemu-system-i386 specified in the test files. Once I renamed it, the tests fail with "unsupported configuration: emulator '/usr/lib/xen/bin/qemu-system-i386' not found". So the mocked emulator checks are not called :-(.
Something that could work would be putting those two functions into separate shared object, then override using LD_PRELOAD or something like this. But it would require significant change in the driver structure just for tests. Alternatively something similar could be done by covering lower level functions (virFileExists, virCommandRun, or even open, stat etc). Using /bin/true is much simpler anyway.
Unless you spot something obvious in the V2 that I've overlooked, I'm beginning to agree. Regards, Jim

On Fri, Jul 28, 2017 at 05:24:10PM -0600, Jim Fehlig wrote:
On 07/27/2017 04:51 PM, Marek Marczykowski-Górecki wrote:
On Thu, Jul 27, 2017 at 03:24:38PM -0600, Jim Fehlig wrote:
Did you have any comment on the approach taken in the attachments to this thread? Particularly the patch titled "libxl: make emulator checks mockable"? I don't see how macros could solve this - those are expanded at individual files compilation time. And you don't recompile the driver for tests.
Right. I went back to my mocking attempt and thought that I had something working
https://www.redhat.com/archives/libvir-list/2017-July/msg01335.html
But while testing I forgot to remove my /usr/lib/xen/bin/qemu-system-i386 specified in the test files. Once I renamed it, the tests fail with "unsupported configuration: emulator '/usr/lib/xen/bin/qemu-system-i386' not found". So the mocked emulator checks are not called :-(.
Something that could work would be putting those two functions into separate shared object, then override using LD_PRELOAD or something like this. But it would require significant change in the driver structure just for tests. Alternatively something similar could be done by covering lower level functions (virFileExists, virCommandRun, or even open, stat etc). Using /bin/true is much simpler anyway.
Unless you spot something obvious in the V2 that I've overlooked, I'm beginning to agree.
You can override only dynamic symbols this way. If the function is in the same object (or even the same shared library), it is resolved at link time, not load time. You can obtain list of mockable functions this way: objdump -T .../libvirt_driver_libxl.so | grep UND -- Best Regards, Marek Marczykowski-Górecki Invisible Things Lab A: Because it messes up the order in which people normally read text. Q: Why is top-posting such a bad thing?

On 07/28/2017 05:33 PM, Marek Marczykowski-Górecki wrote:
On 07/27/2017 04:51 PM, Marek Marczykowski-Górecki wrote:
On Thu, Jul 27, 2017 at 03:24:38PM -0600, Jim Fehlig wrote:
Did you have any comment on the approach taken in the attachments to this thread? Particularly the patch titled "libxl: make emulator checks mockable"? I don't see how macros could solve this - those are expanded at individual files compilation time. And you don't recompile the driver for tests. Right. I went back to my mocking attempt and thought that I had something working
https://www.redhat.com/archives/libvir-list/2017-July/msg01335.html
But while testing I forgot to remove my /usr/lib/xen/bin/qemu-system-i386 specified in the test files. Once I renamed it, the tests fail with "unsupported configuration: emulator '/usr/lib/xen/bin/qemu-system-i386' not found". So the mocked emulator checks are not called :-(.
Something that could work would be putting those two functions into separate shared object, then override using LD_PRELOAD or something like this. But it would require significant change in the driver structure just for tests. Alternatively something similar could be done by covering lower level functions (virFileExists, virCommandRun, or even open, stat etc). Using /bin/true is much simpler anyway. Unless you spot something obvious in the V2 that I've overlooked, I'm beginning to agree. You can override only dynamic symbols this way. If the function is in
On Fri, Jul 28, 2017 at 05:24:10PM -0600, Jim Fehlig wrote: the same object (or even the same shared library), it is resolved at link time, not load time.
Yep, understood. I think it is time for you to post your patch using /bin/true as emulator :-).
participants (2)
-
Jim Fehlig
-
Marek Marczykowski-Górecki