Daniel P. Berrange wrote:
The libxl library allows a libxl_domain_config object to be
serialized to a JSON string. Use this to allow testing of
the XML -> libxl_domain_config conversion process
Signed-off-by: Daniel P. Berrange <berrange(a)redhat.com>
---
configure.ac | 2 +
tests/Makefile.am | 25 ++++-
tests/libxlxml2jsondata/minimal.json | 172 ++++++++++++++++++++++++++++++++
tests/libxlxml2jsondata/minimal.xml | 36 +++++++
tests/libxlxml2jsontest.c | 186 +++++++++++++++++++++++++++++++++++
tests/virmocklibxl.c | 87 ++++++++++++++++
6 files changed, 507 insertions(+), 1 deletion(-)
create mode 100644 tests/libxlxml2jsondata/minimal.json
create mode 100644 tests/libxlxml2jsondata/minimal.xml
create mode 100644 tests/libxlxml2jsontest.c
create mode 100644 tests/virmocklibxl.c
diff --git a/configure.ac b/configure.ac
index 368d094..e87be85 100644
--- a/configure.ac
+++ b/configure.ac
@@ -875,6 +875,8 @@ if test "$with_libxl" != "no" ; then
AC_CHECK_LIB([xenlight], [libxl_ctx_alloc], [
with_libxl=yes
LIBXL_LIBS="$LIBXL_LIBS -lxenlight -lxenctrl"
+ LIBS="$LIBS -lxenlight -lxenctrl"
+ AC_CHECK_FUNCS([libxl_domain_config_to_json])
This function exists in Xen 4.2 as well, in libxl.h.
],[
if test "$with_libxl" = "yes"; then
fail=1
diff --git a/tests/Makefile.am b/tests/Makefile.am
index f9f2b84..742503d 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -82,6 +82,7 @@ EXTRA_DIST = \
domainsnapshotxml2xmlout \
fchostdata \
interfaceschemadata \
+ libxlxml2jsondata \
lxcconf2xmldata \
lxcxml2xmldata \
lxcxml2xmloutdata \
@@ -216,6 +217,9 @@ if WITH_XEN
test_programs += xml2sexprtest sexpr2xmltest \
xmconfigtest xencapstest statstest reconnect
endif WITH_XEN
+if WITH_LIBXL
+test_programs += libxlxml2jsontest
+endif WITH_LIBXL
if WITH_QEMU
test_programs += qemuxml2argvtest qemuxml2xmltest qemuxmlnstest \
qemuargv2xmltest qemuhelptest domainsnapshotxml2xmltest \
@@ -378,7 +382,9 @@ test_libraries += libqemumonitortestutils.la \
qemuxml2argvmock.la \
$(NULL)
endif WITH_QEMU
-
+if WITH_LIBXL
+test_libraries += virmocklibxl.la
+endif WITH_LIBXL
if WITH_BHYVE
test_libraries += bhyvexml2argvmock.la
endif WITH_BHYVE
@@ -577,6 +583,23 @@ EXTRA_DIST += qemuxml2argvtest.c qemuxml2xmltest.c
qemuargv2xmltest.c \
$(QEMUMONITORTESTUTILS_SOURCES)
endif ! WITH_QEMU
+if WITH_LIBXL
+libxl_LDADDS = ../src/libvirt_driver_libxl_impl.la
+libxl_LDADDS += $(LDADDS)
+
+libxlxml2jsontest_SOURCES = \
+ libxlxml2jsontest.c testutilsxen.c testutilsxen.h \
+ testutils.c testutils.h
+libxlxml2jsontest_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
+
+endif WITH_LIBXL
+
if WITH_LXC
lxc_LDADDS = ../src/libvirt_driver_lxc_impl.la
diff --git a/tests/libxlxml2jsondata/minimal.json b/tests/libxlxml2jsondata/minimal.json
new file mode 100644
index 0000000..930e1d8
--- /dev/null
+++ b/tests/libxlxml2jsondata/minimal.json
@@ -0,0 +1,172 @@
+{
+ "c_info": {
+ "type": "pv",
+ "hap": "<default>",
+ "oos": "<default>",
+ "ssidref": 0,
+ "name": "rhel5pv",
+ "uuid": "8f07fe28-753f-2729-d76d-bdbd892f949a",
+ "xsdata": {
+
+ },
+ "platformdata": {
+
+ },
+ "poolid": 0,
+ "run_hotplug_scripts": "<default>"
+ },
+ "b_info": {
+ "max_vcpus": 4,
+ "avail_vcpus": [
+ 0,
+ 1,
+ 2,
+ 3
+ ],
+ "cpumap": [
+
+ ],
+ "nodemap": [
+
+ ],
But 4.2 does not have nodemap,
+ "numa_placement": "<default>",
+ "tsc_mode": "default",
+ "max_memkb": 2560000,
+ "target_memkb": 307200,
+ "video_memkb": -1,
+ "shadow_memkb": -1,
+ "rtc_timeoffset": 0,
+ "exec_ssidref": 0,
doesn't have exec_ssidref,
+ "localtime": "<default>",
+ "disable_migrate": "<default>",
+ "cpuid": [
+
+ ],
+ "blkdev_start": null,
+ "device_model_version": null,
+ "device_model_stubdomain": "<default>",
+ "device_model": null,
+ "device_model_ssidref": 0,
+ "extra": [
+
+ ],
+ "extra_pv": [
+
+ ],
+ "extra_hvm": [
+
+ ],
+ "sched_params": {
+ "sched": "unknown",
+ "weight": 1000,
+ "cap": -1,
+ "period": -1,
+ "slice": -1,
+ "latency": -1,
+ "extratime": -1
+ },
+ "ioports": [
+
+ ],
+ "irqs": [
+
+ ],
+ "iomem": [
+
+ ],
+ "claim_mode": "<default>",
doesn't have iomem or claim_mode,
+ "u": {
+ "kernel": null,
+ "slack_memkb": -1,
+ "bootloader": "/usr/bin/pygrub",
+ "bootloader_args": [
+
+ ],
+ "cmdline": null,
+ "ramdisk": null,
+ "e820_host": "<default>"
+ }
+ },
+ "disks": [
+ {
+ "backend_domid": 0,
+ "backend_domname": null,
none of the devices have backend_domname,
+ "pdev_path":
"/var/lib/xen/images/rhel5pv.img",
+ "vdev": "xvda",
+ "backend": "tap",
+ "format": "raw",
+ "script": null,
+ "removable": 1,
+ "readwrite": 1,
+ "is_cdrom": 0
+ },
+ {
+ "backend_domid": 0,
+ "backend_domname": null,
+ "pdev_path": "/root/qcow1-xen.img",
+ "vdev": "xvdd",
+ "backend": "qdisk",
+ "format": "qcow",
+ "script": null,
+ "removable": 1,
+ "readwrite": 1,
+ "is_cdrom": 0
+ }
+ ],
+ "nics": [
+ {
+ "backend_domid": 0,
+ "backend_domname": null,
+ "devid": 0,
+ "mtu": 0,
+ "model": null,
+ "mac": "00:16:3e:60:36:ba",
+ "ip": null,
+ "bridge": "xenbr0",
+ "ifname": null,
+ "script": null,
+ "nictype": "vif",
+ "rate_bytes_per_interval": 0,
+ "rate_interval_usecs": 0,
+ "gatewaydev": null
+ }
+ ],
+ "pcidevs": [
+
+ ],
+ "vfbs": [
+ {
+ "backend_domid": 0,
+ "backend_domname": null,
+ "devid": -1,
+ "vnc": {
+ "enable": "True",
+ "listen": "0.0.0.0",
+ "passwd": null,
+ "display": 0,
+ "findunused": "False"
+ },
+ "sdl": {
+ "enable": "<default>",
+ "opengl": "<default>",
+ "display": null,
+ "xauthority": null
+ },
+ "keymap": null
+ }
+ ],
+ "vkbs": [
+ {
+ "backend_domid": 0,
+ "backend_domname": null,
+ "devid": -1
+ }
+ ],
+ "vtpms": [
+
+ ],
and doesn't contain vtpms, so the test fails. Should we base the
expected data on Xen 4.2, or look for some other way to disable the test
on 4.2?
Regards,
Jim
+ "on_poweroff": null,
+ "on_reboot": "destroy",
+ "on_watchdog": null,
+ "on_crash": "destroy"
+}
diff --git a/tests/libxlxml2jsondata/minimal.xml b/tests/libxlxml2jsondata/minimal.xml
new file mode 100644
index 0000000..1361028
--- /dev/null
+++ b/tests/libxlxml2jsondata/minimal.xml
@@ -0,0 +1,36 @@
+<domain type='xen'>
+ <name>rhel5pv</name>
+ <uuid>8f07fe28-753f-2729-d76d-bdbd892f949a</uuid>
+ <memory>2560000</memory>
+ <currentMemory>307200</currentMemory>
+ <vcpu>4</vcpu>
+ <bootloader>/usr/bin/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>restart</on_crash>
+ <devices>
+ <disk type='file' device='disk'>
+ <driver name='tap' type='aio'/>
+ <source file='/var/lib/xen/images/rhel5pv.img'/>
+ <target dev='xvda' bus='xen'/>
+ </disk>
+ <disk type='file' device='disk'>
+ <driver name='tap' type='qcow'/>
+ <source file='/root/qcow1-xen.img'/>
+ <target dev='xvdd' bus='xen'/>
+ </disk>
+ <interface type='bridge'>
+ <mac address='00:16:3e:60:36:ba'/>
+ <source bridge='xenbr0'/>
+ </interface>
+ <console type='pty'>
+ <target port='0'/>
+ </console>
+ <input type='mouse' bus='xen'/>
+ <graphics type='vnc' port='-1' autoport='yes'
listen='0.0.0.0'/>
+ </devices>
+</domain>
diff --git a/tests/libxlxml2jsontest.c b/tests/libxlxml2jsontest.c
new file mode 100644
index 0000000..a0f7d88
--- /dev/null
+++ b/tests/libxlxml2jsontest.c
@@ -0,0 +1,186 @@
+/*
+ * 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(a)redhat.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_TO_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_XEN
+
+static const char *abs_top_srcdir;
+static virCapsPtr xencaps;
+
+static int testCompareXMLToJSONFiles(const char *xml,
+ const char *cmdline)
+{
+ char *expectargv = NULL;
+ int ret = -1;
+ virDomainDefPtr vmdef = NULL;
+ virPortAllocatorPtr gports = NULL;
+ libxl_ctx *ctx = NULL;
+ libxl_domain_config config;
+ xentoollog_logger *log = NULL;
+ virDomainXMLOptionPtr xmlopt = NULL;
+ char *actualargv;
+
+ libxl_domain_config_init(&config);
+
+ 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(xml, xencaps, xmlopt,
+ 1 << VIR_DOMAIN_VIRT_XEN,
+ VIR_DOMAIN_XML_INACTIVE)))
+ goto cleanup;
+
+ if (libxlBuildDomainConfig(gports, vmdef, ctx, &config) < 0)
+ goto cleanup;
+
+ if (!(actualargv = libxl_domain_config_to_json(ctx, &config))) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ "Failed to create JSON doc for xl config");
+ goto cleanup;
+ }
+
+ virtTestLoadFile(cmdline, &expectargv);
+
+ if (!virJSONStringCompare(expectargv, actualargv,
+ VIR_JSON_COMPARE_IGNORE_EXTRA_OBJECT_KEYS |
+ VIR_JSON_COMPARE_IGNORE_EXPECTED_NULL))
+ goto cleanup;
+
+ ret = 0;
+
+ cleanup:
+ VIR_FREE(expectargv);
+ VIR_FREE(actualargv);
+ virDomainDefFree(vmdef);
+ virObjectUnref(gports);
+ virObjectUnref(xmlopt);
+ libxl_ctx_free(ctx);
+ libxl_domain_config_dispose(&config);
+ xtl_logger_destroy(log);
+ return ret;
+}
+
+
+struct testInfo {
+ const char *name;
+};
+
+static int
+testCompareXMLToJSONHelper(const void *data)
+{
+ int ret = -1;
+ const struct testInfo *info = data;
+ char *xml = NULL;
+ char *args = NULL;
+
+ if (virAsprintf(&xml, "%s/libxlxml2jsondata/%s.xml",
+ abs_srcdir, info->name) < 0 ||
+ virAsprintf(&args, "%s/libxlxml2jsondata/%s.json",
+ abs_srcdir, info->name) < 0)
+ goto cleanup;
+
+ ret = testCompareXMLToJSONFiles(xml, args);
+
+ cleanup:
+ VIR_FREE(xml);
+ VIR_FREE(args);
+ 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 (virtTestRun("LibXL XML-2-JSON " name, \
+ testCompareXMLToJSONHelper, &info) < 0) \
+ ret = -1; \
+ } while (0)
+
+ DO_TEST("minimal");
+
+ 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_XEN && WITH_YAJL && HAVE_LIBXL_DOMAIN_CONFIG_TO_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(a)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 */