libvirt/tests/genericxml2xmltest.c
Pavel Hrdina 21bfd1e9b9 conf: error out for multiple source elements while parsing chardev
Currently we accept and correctly parse this chardev XML:

  ...
  <channel type='tcp'>
    <source mode='connect'/>
    <source mode='bind' host='localhost'/>
    <source service='4567'/>
    <target type='virtio' name='test'/>
  </channel>
  ...

The parsed formatted XML is:

  ...
  <channel type='tcp'>
    <source mode='connect' host='localhost' service='4567'/>
    <target type='virtio' name='test'/>
  </channel>
  ...

That behavior is super wrong and should not be allowed.  If you notice
the current parse takes the first found attribute and uses that value,
so for example from the "<source mode='bind' host='localhost'/>" only
the "host" attribute is used.  It works the same way for all possible
attributes that we are able to parse for source element.

This patch enforces providing only one source element for all character
devices, only for UDP type we allow to provide two source elements
since you can specify both modes.

Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
2017-08-22 17:28:40 +02:00

135 lines
4.5 KiB
C

#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"
#include "internal.h"
#include "virstring.h"
#define VIR_FROM_THIS VIR_FROM_NONE
static virCapsPtr caps;
static virDomainXMLOptionPtr xmlopt;
struct testInfo {
const char *name;
int different;
bool inactive_only;
testCompareDomXML2XMLResult expectResult;
};
static int
testCompareXMLToXMLHelper(const void *data)
{
const struct testInfo *info = data;
char *xml_in = NULL;
char *xml_out = NULL;
int ret = -1;
if (virAsprintf(&xml_in, "%s/genericxml2xmlindata/generic-%s.xml",
abs_srcdir, info->name) < 0 ||
virAsprintf(&xml_out, "%s/genericxml2xmloutdata/generic-%s.xml",
abs_srcdir, info->name) < 0)
goto cleanup;
ret = testCompareDomXML2XMLFiles(caps, xmlopt, xml_in,
info->different ? xml_out : xml_in,
!info->inactive_only, NULL, NULL, 0,
info->expectResult);
cleanup:
VIR_FREE(xml_in);
VIR_FREE(xml_out);
return ret;
}
static int
mymain(void)
{
int ret = 0;
if (!(caps = virTestGenericCapsInit()))
return EXIT_FAILURE;
if (!(xmlopt = virTestGenericDomainXMLConfInit()))
return EXIT_FAILURE;
#define DO_TEST_FULL(name, is_different, inactive, expectResult) \
do { \
const struct testInfo info = {name, is_different, inactive, \
expectResult}; \
if (virTestRun("GENERIC XML-2-XML " name, \
testCompareXMLToXMLHelper, &info) < 0) \
ret = -1; \
} while (0)
#define DO_TEST(name) \
DO_TEST_FULL(name, 0, false, TEST_COMPARE_DOM_XML2XML_RESULT_SUCCESS)
#define DO_TEST_DIFFERENT(name) \
DO_TEST_FULL(name, 1, false, TEST_COMPARE_DOM_XML2XML_RESULT_SUCCESS)
DO_TEST_DIFFERENT("disk-virtio");
DO_TEST_DIFFERENT("graphics-vnc-minimal");
DO_TEST_DIFFERENT("graphics-vnc-manual-port");
DO_TEST_DIFFERENT("graphics-vnc-socket");
DO_TEST_DIFFERENT("graphics-vnc-socket-listen");
DO_TEST_DIFFERENT("graphics-listen-back-compat");
DO_TEST_FULL("graphics-listen-back-compat-mismatch", 0, false,
TEST_COMPARE_DOM_XML2XML_RESULT_FAIL_PARSE);
DO_TEST_DIFFERENT("graphics-vnc-listen-attr-only");
DO_TEST_DIFFERENT("graphics-vnc-listen-element-minimal");
DO_TEST_DIFFERENT("graphics-vnc-listen-element-with-address");
DO_TEST_DIFFERENT("graphics-vnc-socket-attr-listen-address");
DO_TEST_DIFFERENT("graphics-vnc-socket-attr-listen-socket");
DO_TEST_FULL("graphics-vnc-socket-attr-listen-socket-mismatch", 0, false,
TEST_COMPARE_DOM_XML2XML_RESULT_FAIL_PARSE);
DO_TEST("graphics-vnc-autoport-no");
DO_TEST_FULL("name-slash-fail", 0, false,
TEST_COMPARE_DOM_XML2XML_RESULT_FAIL_PARSE);
DO_TEST("perf");
DO_TEST("vcpus-individual");
DO_TEST("disk-network-http");
DO_TEST("cpu-cache-emulate");
DO_TEST("cpu-cache-passthrough");
DO_TEST("cpu-cache-disable");
DO_TEST_DIFFERENT("chardev-tcp");
DO_TEST_FULL("chardev-tcp-missing-host", 0, false,
TEST_COMPARE_DOM_XML2XML_RESULT_FAIL_PARSE);
DO_TEST_FULL("chardev-tcp-missing-service", 0, false,
TEST_COMPARE_DOM_XML2XML_RESULT_FAIL_PARSE);
DO_TEST_FULL("chardev-tcp-multiple-source", 0, false,
TEST_COMPARE_DOM_XML2XML_RESULT_FAIL_PARSE);
DO_TEST_DIFFERENT("chardev-udp");
DO_TEST_FULL("chardev-udp-missing-connect-service", 0, false,
TEST_COMPARE_DOM_XML2XML_RESULT_FAIL_PARSE);
DO_TEST_FULL("chardev-udp-multiple-source", 0, false,
TEST_COMPARE_DOM_XML2XML_RESULT_FAIL_PARSE);
DO_TEST_DIFFERENT("chardev-unix");
DO_TEST_FULL("chardev-unix-smartcard-missing-path", 0, false,
TEST_COMPARE_DOM_XML2XML_RESULT_FAIL_PARSE);
DO_TEST_FULL("chardev-unix-redirdev-missing-path", 0, false,
TEST_COMPARE_DOM_XML2XML_RESULT_FAIL_PARSE);
DO_TEST_FULL("chardev-unix-rng-missing-path", 0, false,
TEST_COMPARE_DOM_XML2XML_RESULT_FAIL_PARSE);
virObjectUnref(caps);
virObjectUnref(xmlopt);
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
}
VIR_TEST_MAIN(mymain)