2013-09-09 21:22:19 +04:00
/*
* Copyright ( C ) 2013 Red Hat , Inc .
*
* 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 "testutils.h"
# include "virerror.h"
# include "virxml.h"
# define VIR_FROM_THIS VIR_FROM_NONE
static const char metadata1 [ ] =
" <derp xmlns:foobar='http://foo.bar/'> \n "
" <bar>foobar</bar> \n "
" <foo fooish='blurb'>foofoo</foo> \n "
" <foobar:baz>zomg</foobar:baz> \n "
" </derp> " ;
static const char metadata1_ns [ ] =
" <herp:derp xmlns:foobar='http://foo.bar/' xmlns:herp='http://herp.derp/'> \n "
" <herp:bar>foobar</herp:bar> \n "
" <herp:foo fooish='blurb'>foofoo</herp:foo> \n "
" <foobar:baz>zomg</foobar:baz> \n "
" </herp:derp> " ;
static const char metadata2 [ ] =
" <foo> \n "
" <bar>baz</bar> \n "
" </foo> " ;
static const char metadata2_ns [ ] =
" <blurb:foo xmlns:blurb='http://herp.derp/'> \n "
" <blurb:bar>baz</blurb:bar> \n "
" </blurb:foo> " ;
static char *
getMetadataFromXML ( virDomainPtr dom )
{
xmlDocPtr doc = NULL ;
xmlXPathContextPtr ctxt = NULL ;
xmlNodePtr node ;
char * xml = NULL ;
char * ret = NULL ;
if ( ! ( xml = virDomainGetXMLDesc ( dom , 0 ) ) )
goto cleanup ;
if ( ! ( doc = virXMLParseStringCtxt ( xml , " (domain_definition) " , & ctxt ) ) )
goto cleanup ;
if ( ! ( node = virXPathNode ( " //metadata/* " , ctxt ) ) )
goto cleanup ;
ret = virXMLNodeToString ( node - > doc , node ) ;
2014-03-25 10:53:44 +04:00
cleanup :
2013-09-09 21:22:19 +04:00
VIR_FREE ( xml ) ;
xmlFreeDoc ( doc ) ;
xmlXPathFreeContext ( ctxt ) ;
return ret ;
}
static void
metadataXMLConvertApostrophe ( char * str )
{
do {
if ( * str = = ' \" ' )
* str = ' \' ' ;
} while ( ( * + + str ) ! = ' \0 ' ) ;
}
static bool
verifyMetadata ( virDomainPtr dom ,
const char * expectXML ,
const char * expectAPI ,
const char * uri )
{
bool ret = false ;
char * metadataXML = NULL ;
char * metadataAPI = NULL ;
if ( ! expectAPI ) {
if ( ( metadataAPI = virDomainGetMetadata ( dom ,
VIR_DOMAIN_METADATA_ELEMENT ,
uri , 0 ) ) ) {
virReportError ( VIR_ERR_INTERNAL_ERROR ,
" expected no metadata in API, but got: \n [%s] " ,
metadataAPI ) ;
goto cleanup ;
}
} else {
if ( ! ( metadataAPI = virDomainGetMetadata ( dom ,
VIR_DOMAIN_METADATA_ELEMENT ,
uri , 0 ) ) )
goto cleanup ;
metadataXMLConvertApostrophe ( metadataAPI ) ;
if ( STRNEQ ( metadataAPI , expectAPI ) ) {
virReportError ( VIR_ERR_INTERNAL_ERROR ,
" XML metadata in API doesn't match expected metadata: "
" expected: \n [%s] \n got: \n [%s] " ,
expectAPI , metadataAPI ) ;
goto cleanup ;
}
}
if ( ! expectXML ) {
if ( ( metadataXML = getMetadataFromXML ( dom ) ) ) {
virReportError ( VIR_ERR_INTERNAL_ERROR ,
" expected no metadata in XML, but got: \n [%s] " ,
metadataXML ) ;
goto cleanup ;
}
} else {
if ( ! ( metadataXML = getMetadataFromXML ( dom ) ) )
goto cleanup ;
metadataXMLConvertApostrophe ( metadataXML ) ;
if ( STRNEQ ( metadataXML , expectXML ) ) {
virReportError ( VIR_ERR_INTERNAL_ERROR ,
" XML in dump doesn't match expected metadata: "
" expected: \n [%s] \n got: \n [%s] " ,
expectXML , metadataXML ) ;
goto cleanup ;
}
}
ret = true ;
2014-03-25 10:53:44 +04:00
cleanup :
2013-09-09 21:22:19 +04:00
VIR_FREE ( metadataXML ) ;
VIR_FREE ( metadataAPI ) ;
return ret ;
}
struct metadataTest {
virConnectPtr conn ;
virDomainPtr dom ;
2014-07-17 18:24:23 +04:00
const char * data ;
2019-02-27 17:52:45 +03:00
const char * expect ;
2014-07-17 18:24:23 +04:00
int type ;
bool fail ;
2013-09-09 21:22:19 +04:00
} ;
static int
testAssignMetadata ( const void * data )
{
const struct metadataTest * test = data ;
if ( virDomainSetMetadata ( test - > dom , VIR_DOMAIN_METADATA_ELEMENT ,
metadata1 , " herp " , " http://herp.derp/ " , 0 ) < 0 )
return - 1 ;
if ( ! verifyMetadata ( test - > dom , metadata1_ns , metadata1 , " http://herp.derp/ " ) )
return - 1 ;
return 0 ;
}
static int
testRewriteMetadata ( const void * data )
{
const struct metadataTest * test = data ;
if ( virDomainSetMetadata ( test - > dom , VIR_DOMAIN_METADATA_ELEMENT ,
metadata2 , " blurb " , " http://herp.derp/ " , 0 ) < 0 )
return - 1 ;
if ( ! verifyMetadata ( test - > dom , metadata2_ns , metadata2 , " http://herp.derp/ " ) )
return - 1 ;
return 0 ;
}
static int
testEraseMetadata ( const void * data )
{
const struct metadataTest * test = data ;
if ( virDomainSetMetadata ( test - > dom , VIR_DOMAIN_METADATA_ELEMENT ,
NULL , NULL , " http://herp.derp/ " , 0 ) < 0 )
return - 1 ;
if ( ! verifyMetadata ( test - > dom , NULL , NULL , " http://herp.derp/ " ) )
return - 1 ;
return 0 ;
}
2014-07-17 18:24:23 +04:00
static int
testTextMetadata ( const void * data )
{
const struct metadataTest * test = data ;
char * actual = NULL ;
int ret = - 1 ;
if ( virDomainSetMetadata ( test - > dom , test - > type , test - > data , NULL , NULL , 0 ) < 0 ) {
if ( test - > fail )
return 0 ;
return - 1 ;
}
actual = virDomainGetMetadata ( test - > dom , test - > type , NULL , 0 ) ;
2019-02-27 17:52:45 +03:00
if ( STRNEQ_NULLABLE ( test - > expect , actual ) ) {
2014-07-17 18:24:23 +04:00
virReportError ( VIR_ERR_INTERNAL_ERROR ,
" expected metadata doesn't match actual: "
" expected:'%s' \n got: '%s' " ,
NULLSTR ( test - > data ) , NULLSTR ( actual ) ) ;
goto cleanup ;
}
ret = 0 ;
cleanup :
VIR_FREE ( actual ) ;
return ret ;
}
2019-02-27 17:52:45 +03:00
# define TEST_TEXT_METADATA(INDEX, TYPE, DATA, EXPECT, FAIL) \
2017-11-03 15:09:47 +03:00
do { \
test . type = VIR_DOMAIN_METADATA_ # # TYPE ; \
test . data = DATA ; \
2019-02-27 17:52:45 +03:00
test . expect = EXPECT ; \
2017-11-03 15:09:47 +03:00
test . fail = FAIL ; \
\
if ( virTestRun ( " text metadata: " # TYPE " " INDEX " " , \
testTextMetadata , & test ) < 0 ) \
ret = EXIT_FAILURE ; \
2014-07-17 18:24:23 +04:00
} while ( 0 )
2019-02-27 17:52:45 +03:00
# define TEST_TITLE(INDEX, DATA) \
TEST_TEXT_METADATA ( INDEX , TITLE , DATA , DATA , false )
# define TEST_TITLE_EXPECT(INDEX, DATA, EXPECT) \
TEST_TEXT_METADATA ( INDEX , TITLE , DATA , EXPECT , false )
# define TEST_TITLE_FAIL(INDEX, DATA) \
TEST_TEXT_METADATA ( INDEX , TITLE , DATA , DATA , true )
# define TEST_DESCR(INDEX, DATA) \
TEST_TEXT_METADATA ( INDEX , DESCRIPTION , DATA , DATA , false )
# define TEST_DESCR_EXPECT(INDEX, DATA, EXPECT) \
TEST_TEXT_METADATA ( INDEX , DESCRIPTION , DATA , EXPECT , false )
2014-07-17 18:24:23 +04:00
2013-09-09 21:22:19 +04:00
static int
mymain ( void )
{
2018-05-28 10:05:29 +03:00
struct metadataTest test = { 0 } ;
2013-09-09 21:22:19 +04:00
int ret = EXIT_SUCCESS ;
if ( ! ( test . conn = virConnectOpen ( " test:///default " ) ) )
return EXIT_FAILURE ;
if ( ! ( test . dom = virDomainLookupByName ( test . conn , " test " ) ) ) {
virConnectClose ( test . conn ) ;
return EXIT_FAILURE ;
}
2016-05-26 18:02:00 +03:00
virTestQuiesceLibvirtErrors ( false ) ;
2013-09-17 17:22:42 +04:00
2016-05-26 18:01:50 +03:00
if ( virTestRun ( " Assign metadata " , testAssignMetadata , & test ) < 0 )
2013-09-09 21:22:19 +04:00
ret = EXIT_FAILURE ;
2016-05-26 18:01:50 +03:00
if ( virTestRun ( " Rewrite Metadata " , testRewriteMetadata , & test ) < 0 )
2013-09-09 21:22:19 +04:00
ret = EXIT_FAILURE ;
2016-05-26 18:01:50 +03:00
if ( virTestRun ( " Erase metadata " , testEraseMetadata , & test ) < 0 )
2013-09-09 21:22:19 +04:00
ret = EXIT_FAILURE ;
2014-07-17 18:24:23 +04:00
TEST_TITLE ( " 1 " , " qwert " ) ;
TEST_TITLE ( " 2 " , NULL ) ;
TEST_TITLE ( " 3 " , " blah " ) ;
TEST_TITLE_FAIL ( " 4 " , " qwe \n rt " ) ;
2019-02-27 17:52:45 +03:00
TEST_TITLE_EXPECT ( " 5 " , " " , NULL ) ;
2014-07-17 18:24:23 +04:00
TEST_TITLE_FAIL ( " 6 " , " qwert \n " ) ;
TEST_TITLE_FAIL ( " 7 " , " \n " ) ;
TEST_DESCR ( " 1 " , " qwert \n qwert " ) ;
TEST_DESCR ( " 2 " , NULL ) ;
TEST_DESCR ( " 3 " , " qwert " ) ;
TEST_DESCR ( " 4 " , " \n " ) ;
2019-02-27 17:52:45 +03:00
TEST_DESCR_EXPECT ( " 5 " , " " , NULL ) ;
2014-07-17 18:24:23 +04:00
2013-09-09 21:22:19 +04:00
virDomainFree ( test . dom ) ;
virConnectClose ( test . conn ) ;
return ret ;
}
2017-03-29 17:45:42 +03:00
VIR_TEST_MAIN ( mymain )