diff --git a/m4/virt-driver-libxl.m4 b/m4/virt-driver-libxl.m4
index 96a9d4736d..e6dbfef686 100644
--- a/m4/virt-driver-libxl.m4
+++ b/m4/virt-driver-libxl.m4
@@ -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 3e3d58071c..1f8c4cd426 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -99,6 +99,7 @@ EXTRA_DIST = \
genericxml2xmlindata \
genericxml2xmloutdata \
interfaceschemadata \
+ libxlxml2domconfigdata \
lxcconf2xmldata \
lxcxml2xmldata \
lxcxml2xmloutdata \
@@ -271,7 +272,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
@@ -528,8 +530,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 = $(MOCKLIBS_LDFLAGS)
+virmocklibxl_la_LIBADD = $(MOCKLIBS_LIBS)
+
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 0000000000..6fa41f34f9
--- /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": "/bin/true",
+ "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 0000000000..d8cd2a283e
--- /dev/null
+++ b/tests/libxlxml2domconfigdata/basic-hvm.xml
@@ -0,0 +1,36 @@
+
+ test-hvm
+ None
+ 2147d599-9cc6-c0dc-92ab-4064b5446e9b
+ 1048576
+ 1048576
+ 4
+ destroy
+ restart
+ destroy
+
+
+ hvm
+ /usr/lib/xen/boot/hvmloader
+
+
+
+
+
+
+
+
+ /bin/true
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/libxlxml2domconfigdata/basic-pv.json b/tests/libxlxml2domconfigdata/basic-pv.json
new file mode 100644
index 0000000000..7e1abd3d6a
--- /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 0000000000..eba3cc66ae
--- /dev/null
+++ b/tests/libxlxml2domconfigdata/basic-pv.xml
@@ -0,0 +1,28 @@
+
+ test-pv
+ 039e9ee6-4a84-3055-4c81-8ba426ae2656
+ 524288
+ 524288
+ 4
+ pygrub
+
+ linux
+
+
+ destroy
+ restart
+ destroy
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/libxlxml2domconfigdata/moredevs-hvm.json b/tests/libxlxml2domconfigdata/moredevs-hvm.json
new file mode 100644
index 0000000000..8f861f34ec
--- /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": "/bin/true",
+ "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 0000000000..f7eb09fa3b
--- /dev/null
+++ b/tests/libxlxml2domconfigdata/moredevs-hvm.xml
@@ -0,0 +1,63 @@
+
+ test-hvm
+ None
+ 2147d599-9cc6-c0dc-92ab-4064b5446e9b
+ 1048576
+ 1048576
+ 4
+ destroy
+ restart
+ destroy
+
+
+
+
+
+ hvm
+ /usr/lib/xen/boot/hvmloader
+
+
+
+
+
+
+
+
+
+ /bin/true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/libxlxml2domconfigtest.c b/tests/libxlxml2domconfigtest.c
new file mode 100644
index 0000000000..5eea6ff07d
--- /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
+ * .
+ *
+ * Author: Jim Fehlig
+ */
+
+#include
+
+#include
+#include
+#include
+#include
+
+#include
+#include
+
+#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 caps;
+
+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, caps, xmlopt,
+ NULL, VIR_DOMAIN_XML_INACTIVE)))
+ goto cleanup;
+
+ if (libxlBuildDomainConfig(gports, vmdef, NULL, ctx, caps, &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 ((caps = testXLInitCaps()) == 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 0000000000..bc4b53d68f
--- /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
+ * .
+ *
+ * Author: Daniel P. Berrange
+ */
+
+#include
+
+#if defined(WITH_LIBXL) && defined(WITH_YAJL)
+# include "virmock.h"
+# include
+# include
+# include
+# include
+# include
+
+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 */