libvirt/tests/metadatatest.c

248 lines
6.2 KiB
C

/*
* Copyright (C) 2013 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: Peter Krempa <pkrempa@redhat.com>
*/
#include <config.h>
#include "testutils.h"
#include "virerror.h"
#include "virxml.h"
#define VIR_FROM_THIS VIR_FROM_NONE
static const char metadata1[] =
"<derp xmlns:foobar='http://foo.bar/'>\n"
" <bar>foobar</bar>\n"
" <foo fooish='blurb'>foofoo</foo>\n"
" <foobar:baz>zomg</foobar:baz>\n"
"</derp>";
static const char metadata1_ns[] =
"<herp:derp xmlns:foobar='http://foo.bar/' xmlns:herp='http://herp.derp/'>\n"
" <herp:bar>foobar</herp:bar>\n"
" <herp:foo fooish='blurb'>foofoo</herp:foo>\n"
" <foobar:baz>zomg</foobar:baz>\n"
"</herp:derp>";
static const char metadata2[] =
"<foo>\n"
" <bar>baz</bar>\n"
"</foo>";
static const char metadata2_ns[] =
"<blurb:foo xmlns:blurb='http://herp.derp/'>\n"
" <blurb:bar>baz</blurb:bar>\n"
"</blurb:foo>";
static char *
getMetadataFromXML(virDomainPtr dom)
{
xmlDocPtr doc = NULL;
xmlXPathContextPtr ctxt = NULL;
xmlNodePtr node;
char *xml = NULL;
char *ret = NULL;
if (!(xml = virDomainGetXMLDesc(dom, 0)))
goto cleanup;
if (!(doc = virXMLParseStringCtxt(xml, "(domain_definition)", &ctxt)))
goto cleanup;
if (!(node = virXPathNode("//metadata/*", ctxt)))
goto cleanup;
ret = virXMLNodeToString(node->doc, node);
cleanup:
VIR_FREE(xml);
xmlFreeDoc(doc);
xmlXPathFreeContext(ctxt);
return ret;
}
static void
metadataXMLConvertApostrophe(char *str)
{
do {
if (*str == '\"')
*str = '\'';
} while ((*++str) != '\0');
}
static bool
verifyMetadata(virDomainPtr dom,
const char *expectXML,
const char *expectAPI,
const char *uri)
{
bool ret = false;
char *metadataXML = NULL;
char *metadataAPI = NULL;
if (!expectAPI) {
if ((metadataAPI = virDomainGetMetadata(dom,
VIR_DOMAIN_METADATA_ELEMENT,
uri, 0))) {
virReportError(VIR_ERR_INTERNAL_ERROR,
"expected no metadata in API, but got:\n[%s]",
metadataAPI);
goto cleanup;
}
} else {
if (!(metadataAPI = virDomainGetMetadata(dom,
VIR_DOMAIN_METADATA_ELEMENT,
uri, 0)))
goto cleanup;
metadataXMLConvertApostrophe(metadataAPI);
if (STRNEQ(metadataAPI, expectAPI)) {
virReportError(VIR_ERR_INTERNAL_ERROR,
"XML metadata in API doesn't match expected metadata: "
"expected:\n[%s]\ngot:\n[%s]",
expectAPI, metadataAPI);
goto cleanup;
}
}
if (!expectXML) {
if ((metadataXML = getMetadataFromXML(dom))) {
virReportError(VIR_ERR_INTERNAL_ERROR,
"expected no metadata in XML, but got:\n[%s]",
metadataXML);
goto cleanup;
}
} else {
if (!(metadataXML = getMetadataFromXML(dom)))
goto cleanup;
metadataXMLConvertApostrophe(metadataXML);
if (STRNEQ(metadataXML, expectXML)) {
virReportError(VIR_ERR_INTERNAL_ERROR,
"XML in dump doesn't match expected metadata: "
"expected:\n[%s]\ngot:\n[%s]",
expectXML, metadataXML);
goto cleanup;
}
}
ret = true;
cleanup:
VIR_FREE(metadataXML);
VIR_FREE(metadataAPI);
return ret;
}
struct metadataTest {
virConnectPtr conn;
virDomainPtr dom;
};
static int
testAssignMetadata(const void *data)
{
const struct metadataTest *test = data;
if (virDomainSetMetadata(test->dom, VIR_DOMAIN_METADATA_ELEMENT,
metadata1, "herp", "http://herp.derp/", 0) < 0)
return -1;
if (!verifyMetadata(test->dom, metadata1_ns, metadata1, "http://herp.derp/"))
return -1;
return 0;
}
static int
testRewriteMetadata(const void *data)
{
const struct metadataTest *test = data;
if (virDomainSetMetadata(test->dom, VIR_DOMAIN_METADATA_ELEMENT,
metadata2, "blurb", "http://herp.derp/", 0) < 0)
return -1;
if (!verifyMetadata(test->dom, metadata2_ns, metadata2, "http://herp.derp/"))
return -1;
return 0;
}
static int
testEraseMetadata(const void *data)
{
const struct metadataTest *test = data;
if (virDomainSetMetadata(test->dom, VIR_DOMAIN_METADATA_ELEMENT,
NULL, NULL, "http://herp.derp/", 0) < 0)
return -1;
if (!verifyMetadata(test->dom, NULL, NULL, "http://herp.derp/"))
return -1;
return 0;
}
static int
mymain(void)
{
struct metadataTest test;
int ret = EXIT_SUCCESS;
if (!(test.conn = virConnectOpen("test:///default")))
return EXIT_FAILURE;
if (!(test.dom = virDomainLookupByName(test.conn, "test"))) {
virConnectClose(test.conn);
return EXIT_FAILURE;
}
virtTestQuiesceLibvirtErrors(false);
if (virtTestRun("Assign metadata ", 1, testAssignMetadata, &test) < 0)
ret = EXIT_FAILURE;
if (virtTestRun("Rewrite Metadata ", 1, testRewriteMetadata, &test) < 0)
ret = EXIT_FAILURE;
if (virtTestRun("Erase metadata ", 1, testEraseMetadata, &test) < 0)
ret = EXIT_FAILURE;
virDomainFree(test.dom);
virConnectClose(test.conn);
return ret;
}
VIRT_TEST_MAIN(mymain)