mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-10-03 04:45:46 +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': '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': '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': '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': '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': '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 ] },
|
{ '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