[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [libvirt] [PATCH v2 4/4] libxl: Add a test suite for libxl option generator



Jim Fehlig wrote:
> 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@xxxxxxxxxx>
>> ---
>>  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.
>   

Any ideas on how to handle this?  I'm not aware of an existing macro to
check for func 'foo' defined in header 'bar'.  Is writing a custom macro
along these lines a good solution?  A bad solution I tried was hacking
the test to check libxl version via libxl_get_version_info(), but that
API does not work if not running Xen.

Regards,
Jim

>>      ],[
>>          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@xxxxxxxxxx>
>> + */
>> +
>> +#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@xxxxxxxxxx>
>> + */
>> +
>> +#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 */
>>   
>>     
>
> --
> libvir-list mailing list
> libvir-list@xxxxxxxxxx
> https://www.redhat.com/mailman/listinfo/libvir-list
>
>   

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.