2020-10-30 17:10:29 +03:00
/*
* 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 ( " \n failed 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 ( " \n failed 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 ( " \n failed 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 ( " \n failed 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 ;
2020-10-30 19:09:47 +03:00
if ( testQemuMigrationCookieXML2XML ( " basic " , " qemustatusxml2xmldata/modern-in.xml " , 0 ) < 0 | |
testQemuMigrationCookieXML2XML ( " full " , " qemustatusxml2xmldata/modern-in.xml " , 0 ) < 0 )
2020-10-30 17:10:29 +03:00
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 " ) )