898951
From 7cef1905e04cef0996df582bf196902a410b4308 Mon Sep 17 00:00:00 2001
898951
Message-Id: <7cef1905e04cef0996df582bf196902a410b4308@dist-git>
898951
From: Peter Krempa <pkrempa@redhat.com>
898951
Date: Thu, 22 Jan 2015 15:53:50 +0100
898951
Subject: [PATCH] tests: Add metadata tests
898951
898951
https://bugzilla.redhat.com/show_bug.cgi?id=1184929
898951
898951
This test exercises the virDomain[Get|Set]Metadata API and tests it for
898951
regressions
898951
898951
(cherry picked from commit 2e23c77b0061c5f1b2fd5eeca79e3d6e963e7a2f)
898951
898951
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
898951
---
898951
 tests/Makefile.am    |   7 ++
898951
 tests/metadatatest.c | 245 +++++++++++++++++++++++++++++++++++++++++++++++++++
898951
 2 files changed, 252 insertions(+)
898951
 create mode 100644 tests/metadatatest.c
898951
898951
diff --git a/tests/Makefile.am b/tests/Makefile.am
898951
index e49eadc..ac816fe 100644
898951
--- a/tests/Makefile.am
898951
+++ b/tests/Makefile.am
898951
@@ -225,6 +225,8 @@ test_programs += interfacexml2xmltest
898951
 
898951
 test_programs += cputest
898951
 
898951
+test_programs += metadatatest
898951
+
898951
 test_scripts = \
898951
 	capabilityschematest \
898951
 	interfaceschematest \
898951
@@ -567,6 +569,11 @@ cputest_SOURCES = \
898951
 	testutils.c testutils.h
898951
 cputest_LDADD = $(LDADDS)
898951
 
898951
+metadatatest_SOURCES = \
898951
+	metadatatest.c \
898951
+	testutils.c testutils.h
898951
+metadatatest_LDADD = $(LDADDS) $(LIBXML_LIBS)
898951
+
898951
 virshtest_SOURCES = \
898951
 	virshtest.c \
898951
 	testutils.c testutils.h
898951
diff --git a/tests/metadatatest.c b/tests/metadatatest.c
898951
new file mode 100644
898951
index 0000000..6bcf335
898951
--- /dev/null
898951
+++ b/tests/metadatatest.c
898951
@@ -0,0 +1,245 @@
898951
+/*
898951
+ * Copyright (C) 2013 Red Hat, Inc.
898951
+ *
898951
+ * This library is free software; you can redistribute it and/or
898951
+ * modify it under the terms of the GNU Lesser General Public
898951
+ * License as published by the Free Software Foundation; either
898951
+ * version 2.1 of the License, or (at your option) any later version.
898951
+ *
898951
+ * This library is distributed in the hope that it will be useful,
898951
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
898951
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
898951
+ * Lesser General Public License for more details.
898951
+ *
898951
+ * You should have received a copy of the GNU Lesser General Public
898951
+ * License along with this library;  If not, see
898951
+ * <http://www.gnu.org/licenses/>.
898951
+ *
898951
+ * Author: Peter Krempa <pkrempa@redhat.com>
898951
+ */
898951
+
898951
+#include <config.h>
898951
+
898951
+#include "testutils.h"
898951
+
898951
+#include "virerror.h"
898951
+#include "virxml.h"
898951
+
898951
+#define VIR_FROM_THIS VIR_FROM_NONE
898951
+
898951
+static const char metadata1[] =
898951
+"<derp xmlns:foobar='http://foo.bar/'>\n"
898951
+"  <bar>foobar</bar>\n"
898951
+"  <foo fooish='blurb'>foofoo</foo>\n"
898951
+"  <foobar:baz>zomg</foobar:baz>\n"
898951
+"</derp>";
898951
+
898951
+
898951
+static const char metadata1_ns[] =
898951
+"<herp:derp xmlns:foobar='http://foo.bar/' xmlns:herp='http://herp.derp/'>\n"
898951
+"  <herp:bar>foobar</herp:bar>\n"
898951
+"  <herp:foo fooish='blurb'>foofoo</herp:foo>\n"
898951
+"  <foobar:baz>zomg</foobar:baz>\n"
898951
+"</herp:derp>";
898951
+
898951
+
898951
+static const char metadata2[] =
898951
+"<foo>\n"
898951
+"  <bar>baz</bar>\n"
898951
+"</foo>";
898951
+
898951
+
898951
+static const char metadata2_ns[] =
898951
+"<blurb:foo xmlns:blurb='http://herp.derp/'>\n"
898951
+"  <blurb:bar>baz</blurb:bar>\n"
898951
+"</blurb:foo>";
898951
+
898951
+
898951
+static char *
898951
+getMetadataFromXML(virDomainPtr dom)
898951
+{
898951
+    xmlDocPtr doc = NULL;
898951
+    xmlXPathContextPtr ctxt = NULL;
898951
+    xmlNodePtr node;
898951
+
898951
+    char *xml = NULL;
898951
+    char *ret = NULL;
898951
+
898951
+    if (!(xml = virDomainGetXMLDesc(dom, 0)))
898951
+        goto cleanup;
898951
+
898951
+    if (!(doc = virXMLParseStringCtxt(xml, "(domain_definition)", &ctxt)))
898951
+        goto cleanup;
898951
+
898951
+    if (!(node = virXPathNode("//metadata/*", ctxt)))
898951
+        goto cleanup;
898951
+
898951
+    ret = virXMLNodeToString(node->doc, node);
898951
+
898951
+cleanup:
898951
+    VIR_FREE(xml);
898951
+    xmlFreeDoc(doc);
898951
+    xmlXPathFreeContext(ctxt);
898951
+
898951
+    return ret;
898951
+}
898951
+
898951
+
898951
+static void
898951
+metadataXMLConvertApostrophe(char *str)
898951
+{
898951
+    do {
898951
+        if (*str == '\"')
898951
+            *str = '\'';
898951
+    } while ((*++str) != '\0');
898951
+}
898951
+
898951
+
898951
+static bool
898951
+verifyMetadata(virDomainPtr dom,
898951
+               const char *expectXML,
898951
+               const char *expectAPI,
898951
+               const char *uri)
898951
+{
898951
+    bool ret = false;
898951
+    char *metadataXML = NULL;
898951
+    char *metadataAPI = NULL;
898951
+
898951
+    if (!expectAPI) {
898951
+        if ((metadataAPI = virDomainGetMetadata(dom,
898951
+                                                VIR_DOMAIN_METADATA_ELEMENT,
898951
+                                                uri, 0))) {
898951
+            virReportError(VIR_ERR_INTERNAL_ERROR,
898951
+                           "expected no metadata in API, but got:\n[%s]",
898951
+                           metadataAPI);
898951
+            goto cleanup;
898951
+        }
898951
+    } else {
898951
+        if (!(metadataAPI = virDomainGetMetadata(dom,
898951
+                                                 VIR_DOMAIN_METADATA_ELEMENT,
898951
+                                                 uri, 0)))
898951
+            goto cleanup;
898951
+
898951
+        metadataXMLConvertApostrophe(metadataAPI);
898951
+
898951
+        if (STRNEQ(metadataAPI, expectAPI)) {
898951
+            virReportError(VIR_ERR_INTERNAL_ERROR,
898951
+                           "XML metadata in API doesn't match expected metadata: "
898951
+                           "expected:\n[%s]\ngot:\n[%s]",
898951
+                           expectAPI, metadataAPI);
898951
+            goto cleanup;
898951
+        }
898951
+
898951
+    }
898951
+
898951
+    if (!expectXML) {
898951
+        if ((metadataXML = getMetadataFromXML(dom))) {
898951
+            virReportError(VIR_ERR_INTERNAL_ERROR,
898951
+                           "expected no metadata in XML, but got:\n[%s]",
898951
+                           metadataXML);
898951
+            goto cleanup;
898951
+        }
898951
+    } else {
898951
+        if (!(metadataXML = getMetadataFromXML(dom)))
898951
+            goto cleanup;
898951
+
898951
+        metadataXMLConvertApostrophe(metadataXML);
898951
+
898951
+        if (STRNEQ(metadataXML, expectXML)) {
898951
+            virReportError(VIR_ERR_INTERNAL_ERROR,
898951
+                           "XML in dump doesn't match expected metadata: "
898951
+                           "expected:\n[%s]\ngot:\n[%s]",
898951
+                           expectXML, metadataXML);
898951
+            goto cleanup;
898951
+        }
898951
+    }
898951
+
898951
+    ret = true;
898951
+
898951
+cleanup:
898951
+    VIR_FREE(metadataXML);
898951
+    VIR_FREE(metadataAPI);
898951
+
898951
+    return ret;
898951
+}
898951
+
898951
+
898951
+struct metadataTest {
898951
+    virConnectPtr conn;
898951
+    virDomainPtr dom;
898951
+};
898951
+
898951
+
898951
+static int
898951
+testAssignMetadata(const void *data)
898951
+{
898951
+    const struct metadataTest *test = data;
898951
+
898951
+    if (virDomainSetMetadata(test->dom, VIR_DOMAIN_METADATA_ELEMENT,
898951
+                             metadata1, "herp", "http://herp.derp/", 0) < 0)
898951
+        return -1;
898951
+
898951
+    if (!verifyMetadata(test->dom, metadata1_ns, metadata1, "http://herp.derp/"))
898951
+        return -1;
898951
+
898951
+    return 0;
898951
+}
898951
+
898951
+static int
898951
+testRewriteMetadata(const void *data)
898951
+{
898951
+    const struct metadataTest *test = data;
898951
+
898951
+    if (virDomainSetMetadata(test->dom, VIR_DOMAIN_METADATA_ELEMENT,
898951
+                             metadata2, "blurb", "http://herp.derp/", 0) < 0)
898951
+        return -1;
898951
+
898951
+    if (!verifyMetadata(test->dom, metadata2_ns, metadata2, "http://herp.derp/"))
898951
+        return -1;
898951
+
898951
+    return 0;
898951
+}
898951
+
898951
+static int
898951
+testEraseMetadata(const void *data)
898951
+{
898951
+    const struct metadataTest *test = data;
898951
+
898951
+    if (virDomainSetMetadata(test->dom, VIR_DOMAIN_METADATA_ELEMENT,
898951
+                             NULL, NULL, "http://herp.derp/", 0) < 0)
898951
+        return -1;
898951
+
898951
+    if (!verifyMetadata(test->dom, NULL, NULL, "http://herp.derp/"))
898951
+        return -1;
898951
+
898951
+    return 0;
898951
+}
898951
+
898951
+static int
898951
+mymain(void)
898951
+{
898951
+    struct metadataTest test;
898951
+    int ret = EXIT_SUCCESS;
898951
+
898951
+    if (!(test.conn = virConnectOpen("test:///default")))
898951
+        return EXIT_FAILURE;
898951
+
898951
+    if (!(test.dom = virDomainLookupByName(test.conn, "test"))) {
898951
+        virConnectClose(test.conn);
898951
+        return EXIT_FAILURE;
898951
+    }
898951
+
898951
+    if (virtTestRun("Assign metadata ", 1, testAssignMetadata, &test) < 0)
898951
+        ret = EXIT_FAILURE;
898951
+    if (virtTestRun("Rewrite Metadata ", 1, testRewriteMetadata, &test) < 0)
898951
+        ret = EXIT_FAILURE;
898951
+    if (virtTestRun("Erase metadata ", 1, testEraseMetadata, &test) < 0)
898951
+        ret = EXIT_FAILURE;
898951
+
898951
+    virDomainFree(test.dom);
898951
+    virConnectClose(test.conn);
898951
+
898951
+    return ret;
898951
+}
898951
+
898951
+VIRT_TEST_MAIN(mymain)
898951
-- 
898951
2.2.1
898951