mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 05:35:25 +00:00
tests: Add testing of qemu migration cookie
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@redhat.com> Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com> Reviewed-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
parent
f8b0866878
commit
5511bf32fe
@ -448,6 +448,7 @@ if conf.has('WITH_QEMU')
|
||||
{ 'name': 'qemuhotplugtest', 'link_with': [ test_qemu_driver_lib, test_utils_qemu_monitor_lib ], 'link_whole': [ test_utils_qemu_lib ] },
|
||||
{ 'name': 'qemumemlocktest', 'link_with': [ test_qemu_driver_lib ], 'link_whole': [ test_utils_qemu_lib ] },
|
||||
{ 'name': 'qemumigparamstest', 'link_with': [ test_qemu_driver_lib, test_utils_qemu_monitor_lib ], 'link_whole': [ test_utils_qemu_lib ] },
|
||||
{ 'name': 'qemumigrationcookiexmltest', 'link_with': [ test_qemu_driver_lib ], 'link_whole': [ test_utils_qemu_lib, test_file_wrapper_lib ] },
|
||||
{ 'name': 'qemumonitorjsontest', 'link_with': [ test_qemu_driver_lib, test_utils_qemu_monitor_lib ], 'link_whole': [ test_utils_qemu_lib ] },
|
||||
{ 'name': 'qemusecuritytest', 'sources': [ 'qemusecuritytest.c', 'qemusecuritymock.c' ], 'link_with': [ test_qemu_driver_lib ], 'link_whole': [ test_utils_qemu_lib ] },
|
||||
{ 'name': 'qemustatusxml2xmltest', 'link_with': [ test_qemu_driver_lib ], 'link_whole': [ test_utils_qemu_lib, test_file_wrapper_lib ] },
|
||||
|
6
tests/qemumigrationcookiexmldata/basic-xml2xml-in.xml
Normal file
6
tests/qemumigrationcookiexmldata/basic-xml2xml-in.xml
Normal file
@ -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>
|
9
tests/qemumigrationcookiexmldata/basic-xml2xml-out.xml
Normal file
9
tests/qemumigrationcookiexmldata/basic-xml2xml-out.xml
Normal file
@ -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>
|
12
tests/qemumigrationcookiexmldata/modern-dom-out-dest.xml
Normal file
12
tests/qemumigrationcookiexmldata/modern-dom-out-dest.xml
Normal file
@ -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>
|
12
tests/qemumigrationcookiexmldata/modern-dom-out-source.xml
Normal file
12
tests/qemumigrationcookiexmldata/modern-dom-out-source.xml
Normal file
@ -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>
|
336
tests/qemumigrationcookiexmltest.c
Normal file
336
tests/qemumigrationcookiexmltest.c
Normal file
@ -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(GHashTable) 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("virhostid"))
|
Loading…
Reference in New Issue
Block a user