Migration cookie transports a lot of information but there are no tests
for it.
The test supports both xml2xml testing and also testing of the
population of the migration cookie data from a domain object, although
that option is not very useful as many things are collected from running
qemu and thus can't be tested efficiently here.
Signed-off-by: Peter Krempa <pkrempa(a)redhat.com>
---
tests/meson.build | 1 +
.../basic-xml2xml-in.xml | 6 +
.../basic-xml2xml-out.xml | 9 +
.../modern-dom-out-dest.xml | 12 +
.../modern-dom-out-source.xml | 12 +
tests/qemumigrationcookiexmltest.c | 336 ++++++++++++++++++
6 files changed, 376 insertions(+)
create mode 100644 tests/qemumigrationcookiexmldata/basic-xml2xml-in.xml
create mode 100644 tests/qemumigrationcookiexmldata/basic-xml2xml-out.xml
create mode 100644 tests/qemumigrationcookiexmldata/modern-dom-out-dest.xml
create mode 100644 tests/qemumigrationcookiexmldata/modern-dom-out-source.xml
create mode 100644 tests/qemumigrationcookiexmltest.c
diff --git a/tests/meson.build b/tests/meson.build
index 818fce65f3..68a309ebfb 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -456,6 +456,7 @@ if conf.has('WITH_QEMU')
{ 'name': 'qemuxml2argvtest', 'link_with': [
test_qemu_driver_lib, test_utils_qemu_monitor_lib ], 'link_whole': [
test_utils_qemu_lib, test_file_wrapper_lib ] },
{ 'name': 'qemuxml2xmltest', 'link_with': [
test_qemu_driver_lib ], 'link_whole': [ test_utils_qemu_lib, test_file_wrapper_lib
] },
{ 'name': 'qemustatusxml2xmltest', 'link_with': [
test_qemu_driver_lib ], 'link_whole': [ test_utils_qemu_lib, test_file_wrapper_lib
] },
+ { 'name': 'qemumigrationcookiexmltest', 'link_with': [
test_qemu_driver_lib ], 'link_whole': [ test_utils_qemu_lib, test_file_wrapper_lib
] },
]
endif
diff --git a/tests/qemumigrationcookiexmldata/basic-xml2xml-in.xml
b/tests/qemumigrationcookiexmldata/basic-xml2xml-in.xml
new file mode 100644
index 0000000000..5722bafe89
--- /dev/null
+++ b/tests/qemumigrationcookiexmldata/basic-xml2xml-in.xml
@@ -0,0 +1,6 @@
+<qemu-migration>
+ <name>upstream</name>
+ <uuid>dcf47dbd-46d1-4d5b-b442-262a806a333a</uuid>
+ <hostname>hostname2</hostname>
+ <hostuuid>8b3f4dc4-6a8e-5f9b-94a5-4c35babd8d95</hostuuid>
+</qemu-migration>
diff --git a/tests/qemumigrationcookiexmldata/basic-xml2xml-out.xml
b/tests/qemumigrationcookiexmldata/basic-xml2xml-out.xml
new file mode 100644
index 0000000000..42b351047e
--- /dev/null
+++ b/tests/qemumigrationcookiexmldata/basic-xml2xml-out.xml
@@ -0,0 +1,9 @@
+<qemu-migration>
+ <name>upstream</name>
+ <uuid>dcf47dbd-46d1-4d5b-b442-262a806a333a</uuid>
+ <hostname>hostname</hostname>
+ <hostuuid>4a802f00-4cba-5df6-9679-a08c4c5b577f</hostuuid>
+ <allowReboot value='default'/>
+ <capabilities>
+ </capabilities>
+</qemu-migration>
diff --git a/tests/qemumigrationcookiexmldata/modern-dom-out-dest.xml
b/tests/qemumigrationcookiexmldata/modern-dom-out-dest.xml
new file mode 100644
index 0000000000..ba84c65a3d
--- /dev/null
+++ b/tests/qemumigrationcookiexmldata/modern-dom-out-dest.xml
@@ -0,0 +1,12 @@
+<qemu-migration>
+ <name>upstream</name>
+ <uuid>dcf47dbd-46d1-4d5b-b442-262a806a333a</uuid>
+ <hostname>hostname2</hostname>
+ <hostuuid>8b3f4dc4-6a8e-5f9b-94a5-4c35babd8d95</hostuuid>
+ <feature name='memory-hotplug'/>
+ <feature name='cpu-hotplug'/>
+ <graphics type='spice' port='5900' listen='127.0.0.1'
tlsPort='-1'/>
+ <allowReboot value='yes'/>
+ <capabilities>
+ </capabilities>
+</qemu-migration>
diff --git a/tests/qemumigrationcookiexmldata/modern-dom-out-source.xml
b/tests/qemumigrationcookiexmldata/modern-dom-out-source.xml
new file mode 100644
index 0000000000..ba84c65a3d
--- /dev/null
+++ b/tests/qemumigrationcookiexmldata/modern-dom-out-source.xml
@@ -0,0 +1,12 @@
+<qemu-migration>
+ <name>upstream</name>
+ <uuid>dcf47dbd-46d1-4d5b-b442-262a806a333a</uuid>
+ <hostname>hostname2</hostname>
+ <hostuuid>8b3f4dc4-6a8e-5f9b-94a5-4c35babd8d95</hostuuid>
+ <feature name='memory-hotplug'/>
+ <feature name='cpu-hotplug'/>
+ <graphics type='spice' port='5900' listen='127.0.0.1'
tlsPort='-1'/>
+ <allowReboot value='yes'/>
+ <capabilities>
+ </capabilities>
+</qemu-migration>
diff --git a/tests/qemumigrationcookiexmltest.c b/tests/qemumigrationcookiexmltest.c
new file mode 100644
index 0000000000..d8ed8b253c
--- /dev/null
+++ b/tests/qemumigrationcookiexmltest.c
@@ -0,0 +1,336 @@
+/*
+ * 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/>.
+ */
+
+#include <config.h>
+
+#include <unistd.h>
+
+#include <sys/types.h>
+#include <fcntl.h>
+
+#include "testutils.h"
+
+#include "internal.h"
+#include "testutilsqemu.h"
+#include "configmake.h"
+
+#include "qemu/qemu_migration_cookie.h"
+
+#define VIR_FROM_THIS VIR_FROM_NONE
+
+static virQEMUDriver driver;
+
+static virBuffer testnamebuf = VIR_BUFFER_INITIALIZER;
+
+static const char *
+tn(const char *str, ...)
+{
+ va_list ap;
+
+ virBufferFreeAndReset(&testnamebuf);
+ virBufferAdd(&testnamebuf, str, -1);
+
+ va_start(ap, str);
+ virBufferStrcatVArgs(&testnamebuf, ap);
+ va_end(ap);
+
+ return virBufferCurrentContent(&testnamebuf);
+}
+
+
+struct testQemuMigrationCookieData {
+ const char *name;
+ char *inStatus;
+ virDomainObjPtr vm;
+
+ unsigned int cookiePopulateFlags;
+ unsigned int cookieParseFlags;
+
+ qemuMigrationParty cookiePopulateParty;
+
+ char *xmlstr;
+ int xmlstrlen;
+ char *infile;
+ char *outfile;
+};
+
+
+static int
+testQemuMigrationCookiePopulate(const void *opaque)
+{
+ struct testQemuMigrationCookieData *data = (struct testQemuMigrationCookieData *)
opaque;
+ g_autoptr(qemuMigrationCookie) cookie = NULL;
+
+ if (!(cookie = qemuMigrationCookieNew(data->vm->def, NULL)))
+ return -1;
+
+ /* doctor the hostname and uuid, so that the output can be simply used for
+ * the xml2xmltest where the parser validates UUID match (yuck) */
+ g_free(cookie->localHostname);
+ cookie->localHostname = g_strdup("hostname2");
+
+ /* uuidgen --sha1 --namespace @dns --name "hostname2" */
+ if (virUUIDParse("8b3f4dc4-6a8e-5f9b-94a5-4c35babd8d95",
cookie->localHostuuid) < 0) {
+ VIR_TEST_DEBUG("\nfailed to parse fake UUID");
+ return -1;
+ }
+
+ /* allow re-run for checking both miration parties */
+ g_clear_pointer(&data->xmlstr, g_free);
+
+ if (qemuMigrationCookieFormat(cookie,
+ &driver,
+ data->vm,
+ data->cookiePopulateParty,
+ &data->xmlstr,
+ &data->xmlstrlen,
+ data->cookiePopulateFlags) < 0) {
+ VIR_TEST_DEBUG("\n failed to populate and format qemu migration
cookie");
+ return -1;
+ }
+
+ if (virTestCompareToFile(data->xmlstr, data->outfile) < 0)
+ return -1;
+
+ return 0;
+}
+
+
+static int
+testQemuMigrationCookieParse(const void *opaque)
+{
+ struct testQemuMigrationCookieData *data = (struct testQemuMigrationCookieData *)
opaque;
+ qemuDomainObjPrivatePtr priv = data->vm->privateData;
+ g_auto(virBuffer) actual = VIR_BUFFER_INITIALIZER;
+ g_autoptr(qemuMigrationCookie) cookie = NULL;
+
+ if (!(cookie = qemuMigrationCookieParse(&driver,
+ data->vm->def,
+ NULL,
+ priv,
+ data->xmlstr,
+ data->xmlstrlen,
+ data->cookieParseFlags))) {
+ VIR_TEST_DEBUG("\nfailed to parse qemu migration cookie:\n%s\n",
data->xmlstr);
+ return -1;
+ }
+
+ /* set all flags so that formatter attempts to format everything */
+ cookie->flags = ~0;
+
+ if (qemuMigrationCookieXMLFormat(&driver,
+ priv->qemuCaps,
+ &actual,
+ cookie) < 0) {
+ VIR_TEST_DEBUG("\nfailed to format back qemu migration cookie");
+ return -1;
+ }
+
+ if (virTestCompareToFile(virBufferCurrentContent(&actual), data->outfile) <
0)
+ return -1;
+
+ return 0;
+}
+
+
+static int
+testQemuMigrationCookieDomInit(const void *opaque)
+{
+ struct testQemuMigrationCookieData *data = (struct testQemuMigrationCookieData *)
opaque;
+
+ if (!(data->vm = virDomainObjParseFile(data->inStatus, driver.xmlopt,
+ VIR_DOMAIN_DEF_PARSE_STATUS |
+ VIR_DOMAIN_DEF_PARSE_ACTUAL_NET |
+ VIR_DOMAIN_DEF_PARSE_PCI_ORIG_STATES |
+ VIR_DOMAIN_DEF_PARSE_SKIP_VALIDATE |
+ VIR_DOMAIN_DEF_PARSE_ALLOW_POST_PARSE_FAIL)))
{
+ VIR_TEST_DEBUG("\nfailed to parse status xml'%s'",
data->inStatus);
+ return -1;
+ }
+
+ return 0;
+}
+
+
+static int
+testQemuMigrationCookieXMLLoad(const void *opaque)
+{
+ struct testQemuMigrationCookieData *data = (struct testQemuMigrationCookieData *)
opaque;
+
+ if (virTestLoadFile(data->infile, &data->xmlstr) < 0)
+ return -1;
+
+ data->xmlstrlen = strlen(data->xmlstr) + 1;
+
+ return 0;
+}
+
+
+static void
+testQemuMigrationCookieDataFree(struct testQemuMigrationCookieData *data)
+{
+ if (!data)
+ return;
+
+ g_free(data->xmlstr);
+ g_free(data->outfile);
+ g_free(data->infile);
+ g_free(data->inStatus);
+ virDomainObjEndAPI(&data->vm);
+ g_free(data);
+}
+
+
+static int
+testQemuMigrationCookieDom2XML(const char *namesuffix,
+ const char *domxml,
+ unsigned int cookiePopulateFlags,
+ unsigned int cookieParseFlags)
+{
+ struct testQemuMigrationCookieData *data = g_new0(struct testQemuMigrationCookieData,
1);
+ int ret = 0;
+
+ if (cookiePopulateFlags == 0) {
+ /* flags unsupported by default:
+ * - lockstate: internals are NULL in tests, causes crash
+ * - nbd: monitor not present
+ */
+ unsigned int cookiePopulateFlagMask = QEMU_MIGRATION_COOKIE_LOCKSTATE |
+ QEMU_MIGRATION_COOKIE_NBD;
+ data->cookiePopulateFlags = ~cookiePopulateFlagMask;
+ }
+
+ if (cookieParseFlags == 0)
+ data->cookieParseFlags = ~0;
+
+ data->inStatus = g_strconcat(abs_srcdir, "/", domxml, NULL);
+
+ /* load status XML as domain object */
+
+ if (virTestRun(tn("qemumigrationcookiedom2xml-load-", namesuffix, NULL),
+ testQemuMigrationCookieDomInit, data) < 0)
+ ret = -1;
+
+ /* test dom -> migration cookie conversion for source */
+
+ data->cookiePopulateParty = QEMU_MIGRATION_SOURCE;
+ data->outfile = g_strconcat(abs_srcdir, "/qemumigrationcookiexmldata/",
+ namesuffix, "-dom-out-source.xml", NULL);
+
+ if (virTestRun(tn("qemumigrationcookiedom2xml-source-populate-",
namesuffix, NULL),
+ testQemuMigrationCookiePopulate, data) < 0)
+ ret = -1;
+
+ /* test dom -> migration cookie conversion for destination */
+
+ g_free(data->outfile);
+ data->cookiePopulateParty = QEMU_MIGRATION_DESTINATION;
+ data->outfile = g_strconcat(abs_srcdir, "/qemumigrationcookiexmldata/",
+ namesuffix, "-dom-out-dest.xml", NULL);
+
+ if (virTestRun(tn("qemumigrationcookiedom2xml-dest-populate-", namesuffix,
NULL),
+ testQemuMigrationCookiePopulate, data) < 0)
+ ret = -1;
+
+ testQemuMigrationCookieDataFree(data);
+
+ return ret;
+}
+
+
+static int
+testQemuMigrationCookieXML2XML(const char *name,
+ const char *statusxml,
+ unsigned int cookieParseFlags)
+{
+ struct testQemuMigrationCookieData *data = g_new0(struct testQemuMigrationCookieData,
1);
+ int ret = 0;
+
+ if (cookieParseFlags == 0)
+ data->cookieParseFlags = ~0;
+
+ data->inStatus = g_strconcat(abs_srcdir, "/", statusxml, NULL);
+ data->infile = g_strconcat(abs_srcdir, "/qemumigrationcookiexmldata/",
+ name, "-xml2xml-in.xml", NULL);
+ data->outfile = g_strconcat(abs_srcdir, "/qemumigrationcookiexmldata/",
+ name, "-xml2xml-out.xml", NULL);
+
+ if (virTestRun(tn("qemumigrationcookieXML2XML-dom-", name, NULL),
+ testQemuMigrationCookieDomInit, data) < 0)
+ ret = -1;
+
+ if (virTestRun(tn("qemumigrationcookieXML2XML-load-", name, NULL),
+ testQemuMigrationCookieXMLLoad, data) < 0)
+ ret = -1;
+
+ if (virTestRun(tn("qemumigrationcookieXML2XML-parse-", name, NULL),
+ testQemuMigrationCookieParse, data) < 0)
+ ret = -1;
+
+ testQemuMigrationCookieDataFree(data);
+
+ return ret;
+}
+
+
+static int
+mymain(void)
+{
+ int ret = 0;
+ g_autoptr(virQEMUDriverConfig) cfg = NULL;
+ g_autoptr(virHashTable) capslatest = NULL;
+ g_autoptr(virConnect) conn = NULL;
+
+ capslatest = testQemuGetLatestCaps();
+ if (!capslatest)
+ return EXIT_FAILURE;
+
+ if (qemuTestDriverInit(&driver) < 0)
+ return EXIT_FAILURE;
+
+ cfg = virQEMUDriverGetConfig(&driver);
+ driver.privileged = true;
+
+ if (!(conn = virGetConnect()))
+ goto cleanup;
+
+ virSetConnectInterface(conn);
+ virSetConnectNetwork(conn);
+ virSetConnectNWFilter(conn);
+ virSetConnectNodeDev(conn);
+ virSetConnectSecret(conn);
+ virSetConnectStorage(conn);
+
+ if (testQemuMigrationCookieDom2XML("modern",
"qemustatusxml2xmldata/modern-in.xml", 0, 0) < 0)
+ ret = -1;
+
+ if (testQemuMigrationCookieXML2XML("basic",
"qemustatusxml2xmldata/modern-in.xml", 0) < 0)
+ ret = -1;
+
+ virBufferFreeAndReset(&testnamebuf);
+
+ cleanup:
+
+ qemuTestDriverFree(&driver);
+
+ return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
+}
+
+VIR_TEST_MAIN_PRELOAD(mymain,
+ VIR_TEST_MOCK("virpci"),
+ VIR_TEST_MOCK("virrandom"),
+ VIR_TEST_MOCK("domaincaps"),
+ VIR_TEST_MOCK("hostid"))
--
2.26.2