2012-04-04 18:01:46 +04:00
/*
* Copyright ( C ) 2012 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
2012-09-21 02:30:55 +04:00
* License along with this library . If not , see
2012-07-21 14:06:23 +04:00
* < http : //www.gnu.org/licenses/>.
2012-04-04 18:01:46 +04:00
*
* Author : Daniel P . Berrange < berrange @ redhat . com >
*/
# include <config.h>
# include <stdlib.h>
# include "testutils.h"
# include "daemon/libvirtd-config.h"
2012-12-13 21:44:57 +04:00
# include "virutil.h"
2012-04-04 18:01:46 +04:00
# include "c-ctype.h"
2012-12-13 22:21:53 +04:00
# include "virerror.h"
2012-12-12 21:59:27 +04:00
# include "virlog.h"
2012-12-12 20:35:35 +04:00
# include "virconf.h"
2012-04-04 18:01:46 +04:00
# define VIR_FROM_THIS VIR_FROM_NONE
struct testCorruptData {
size_t * params ;
const char * filedata ;
const char * filename ;
size_t paramnum ;
} ;
static char *
munge_param ( const char * datain ,
size_t * params ,
size_t paramnum ,
int * type )
{
char * dataout ;
const char * sol ;
const char * eol ;
const char * eq ;
const char * tmp ;
size_t dataoutlen ;
const char * replace = NULL ;
sol = datain + params [ paramnum ] ;
eq = strchr ( sol , ' = ' ) ;
eol = strchr ( sol , ' \n ' ) ;
for ( tmp = eq + 1 ; tmp < eol & & ! replace ; tmp + + ) {
if ( c_isspace ( * tmp ) )
continue ;
if ( c_isdigit ( * tmp ) ) {
* type = VIR_CONF_LONG ;
replace = " \" foo \" " ;
} else if ( * tmp = = ' [ ' ) {
* type = VIR_CONF_LIST ;
replace = " 666 " ;
} else {
* type = VIR_CONF_STRING ;
replace = " 666 " ;
}
}
dataoutlen = ( eq - datain ) + 1 +
strlen ( replace ) +
strlen ( eol ) + 1 ;
if ( VIR_ALLOC_N ( dataout , dataoutlen ) < 0 ) {
virReportOOMError ( ) ;
return NULL ;
}
memcpy ( dataout , datain , ( eq - datain ) + 1 ) ;
memcpy ( dataout + ( eq - datain ) + 1 ,
replace , strlen ( replace ) ) ;
memcpy ( dataout + ( eq - datain ) + 1 + strlen ( replace ) ,
eol , strlen ( eol ) + 1 ) ;
return dataout ;
}
static int
testCorrupt ( const void * opaque )
{
const struct testCorruptData * data = opaque ;
struct daemonConfig * conf = daemonConfigNew ( false ) ;
int ret = 0 ;
int type = VIR_CONF_NONE ;
char * newdata = munge_param ( data - > filedata ,
data - > params ,
data - > paramnum ,
& type ) ;
virErrorPtr err = NULL ;
if ( ! newdata )
return - 1 ;
//VIR_DEBUG("New config [%s]", newdata);
if ( daemonConfigLoadData ( conf , data - > filename , newdata ) ! = - 1 ) {
VIR_DEBUG ( " Did not see a failure " ) ;
ret = - 1 ;
goto cleanup ;
}
err = virGetLastError ( ) ;
if ( ! err | | ! err - > message ) {
VIR_DEBUG ( " No error or message %p " , err ) ;
ret = - 1 ;
goto cleanup ;
}
2012-09-20 15:58:29 +04:00
# if !WITH_SASL
2012-09-06 01:02:01 +04:00
if ( strstr ( err - > message , " unsupported auth sasl " ) ) {
VIR_DEBUG ( " sasl unsupported, skipping this config " ) ;
goto cleanup ;
}
# endif
2012-04-04 18:01:46 +04:00
switch ( type ) {
case VIR_CONF_LONG :
if ( ! strstr ( err - > message , " invalid type: got string; expected long " ) ) {
VIR_DEBUG ( " Wrong error for long: '%s' " ,
err - > message ) ;
ret = - 1 ;
}
break ;
case VIR_CONF_STRING :
if ( ! strstr ( err - > message , " invalid type: got long; expected string " ) ) {
VIR_DEBUG ( " Wrong error for string: '%s' " ,
err - > message ) ;
ret = - 1 ;
}
break ;
case VIR_CONF_LIST :
if ( ! strstr ( err - > message , " must be a string or list of strings " ) ) {
VIR_DEBUG ( " Wrong error for list: '%s' " ,
err - > message ) ;
ret = - 1 ;
}
break ;
}
cleanup :
VIR_FREE ( newdata ) ;
daemonConfigFree ( conf ) ;
return ret ;
}
static int
uncomment_all_params ( char * data ,
size_t * * ret )
{
size_t count = 0 ;
char * tmp ;
size_t * params = 0 ;
tmp = data ;
while ( tmp & & * tmp ) {
tmp = strchr ( tmp , ' \n ' ) ;
if ( ! tmp )
break ;
tmp + + ;
/* Uncomment any lines starting #some_var */
if ( * tmp = = ' # ' & &
c_isalpha ( * ( tmp + 1 ) ) ) {
if ( VIR_EXPAND_N ( params , count , 1 ) < 0 ) {
VIR_FREE ( params ) ;
return - 1 ;
}
* tmp = ' ' ;
params [ count - 1 ] = ( tmp + 1 ) - data ;
}
}
if ( VIR_EXPAND_N ( params , count , 1 ) < 0 ) {
VIR_FREE ( params ) ;
return - 1 ;
}
params [ count - 1 ] = 0 ;
* ret = params ;
return count ;
}
static int
mymain ( void )
{
int ret = 0 ;
char * filedata = NULL ;
char * filename = NULL ;
size_t i ;
size_t * params = NULL ;
if ( virAsprintf ( & filename , " %s/../daemon/libvirtd.conf " ,
abs_srcdir ) < 0 ) {
perror ( " Format filename " ) ;
return EXIT_FAILURE ;
}
if ( virFileReadAll ( filename , 1024 * 1024 , & filedata ) < 0 ) {
virErrorPtr err = virGetLastError ( ) ;
fprintf ( stderr , " Cannot load %s for testing: %s " , filename , err - > message ) ;
ret = - 1 ;
goto cleanup ;
}
if ( uncomment_all_params ( filedata , & params ) < 0 ) {
perror ( " Find params " ) ;
ret = - 1 ;
goto cleanup ;
}
VIR_DEBUG ( " Initial config [%s] " , filedata ) ;
for ( i = 0 ; params [ i ] ! = 0 ; i + + ) {
const struct testCorruptData data = { params , filedata , filename , i } ;
if ( virtTestRun ( " Test corruption " , 1 , testCorrupt , & data ) < 0 )
ret = - 1 ;
}
cleanup :
VIR_FREE ( filename ) ;
VIR_FREE ( filedata ) ;
VIR_FREE ( params ) ;
return ret = = 0 ? EXIT_SUCCESS : EXIT_FAILURE ;
}
VIRT_TEST_MAIN ( mymain )