2012-11-30 19:21:02 +04:00
/*
2013-05-08 01:26:28 +04:00
* Copyright ( C ) 2012 - 2013 Red Hat , Inc .
2012-11-30 19:21:02 +04: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/>.
*
* Author : Daniel P . Berrange < berrange @ redhat . com >
*/
# include <config.h>
# include <stdlib.h>
# include "testutils.h"
2012-12-13 22:21:53 +04:00
# include "virerror.h"
2012-12-12 22:06:53 +04:00
# include "viralloc.h"
2013-05-17 18:11:24 +04:00
# include "virfile.h"
2012-12-12 21:59:27 +04:00
# include "virlog.h"
2012-11-30 19:21:02 +04:00
# include "virstring.h"
# define VIR_FROM_THIS VIR_FROM_NONE
struct testSplitData {
const char * string ;
const char * delim ;
size_t max_tokens ;
const char * * tokens ;
} ;
struct testJoinData {
const char * string ;
const char * delim ;
const char * * tokens ;
} ;
static int testSplit ( const void * args )
{
const struct testSplitData * data = args ;
char * * got ;
char * * tmp1 ;
const char * * tmp2 ;
int ret = - 1 ;
if ( ! ( got = virStringSplit ( data - > string , data - > delim , data - > max_tokens ) ) ) {
VIR_DEBUG ( " Got no tokens at all " ) ;
return - 1 ;
}
tmp1 = got ;
tmp2 = data - > tokens ;
while ( * tmp1 & & * tmp2 ) {
if ( STRNEQ ( * tmp1 , * tmp2 ) ) {
2013-05-17 18:11:24 +04:00
virFilePrintf ( stderr , " Mismatch '%s' vs '%s' \n " , * tmp1 , * tmp2 ) ;
2012-11-30 19:21:02 +04:00
goto cleanup ;
}
tmp1 + + ;
tmp2 + + ;
}
if ( * tmp1 ) {
2013-05-17 18:11:24 +04:00
virFilePrintf ( stderr , " Too many pieces returned \n " ) ;
2012-11-30 19:21:02 +04:00
goto cleanup ;
}
if ( * tmp2 ) {
2013-05-17 18:11:24 +04:00
virFilePrintf ( stderr , " Too few pieces returned \n " ) ;
2012-11-30 19:21:02 +04:00
goto cleanup ;
}
ret = 0 ;
cleanup :
virStringFreeList ( got ) ;
return ret ;
}
static int testJoin ( const void * args )
{
const struct testJoinData * data = args ;
char * got ;
int ret = - 1 ;
if ( ! ( got = virStringJoin ( data - > tokens , data - > delim ) ) ) {
VIR_DEBUG ( " Got no result " ) ;
return - 1 ;
}
if ( STRNEQ ( got , data - > string ) ) {
2013-05-17 18:11:24 +04:00
virFilePrintf ( stderr , " Mismatch '%s' vs '%s' \n " , got , data - > string ) ;
2012-11-30 19:21:02 +04:00
goto cleanup ;
}
ret = 0 ;
cleanup :
VIR_FREE ( got ) ;
return ret ;
}
2013-05-08 01:26:28 +04:00
static bool fail ;
static const char *
testStrdupLookup1 ( size_t i )
{
switch ( i ) {
case 0 :
return " hello " ;
case 1 :
return NULL ;
default :
fail = true ;
return " oops " ;
}
}
static size_t
testStrdupLookup2 ( size_t i )
{
if ( i )
fail = true ;
return 5 ;
}
static int
testStrdup ( const void * data ATTRIBUTE_UNUSED )
{
char * array [ ] = { NULL , NULL } ;
size_t i = 0 ;
size_t j = 0 ;
size_t k = 0 ;
int ret = - 1 ;
int value ;
value = VIR_STRDUP ( array [ i + + ] , testStrdupLookup1 ( j + + ) ) ;
if ( value ! = 1 ) {
2013-05-17 18:11:24 +04:00
virFilePrintf ( stderr , " unexpected strdup result %d, expected 1 \n " , value ) ;
2013-05-08 01:26:28 +04:00
goto cleanup ;
}
if ( i ! = 1 ) {
2013-05-17 18:11:24 +04:00
virFilePrintf ( stderr , " unexpected side effects i=%zu, expected 1 \n " , i ) ;
2013-05-08 01:26:28 +04:00
goto cleanup ;
}
if ( j ! = 1 ) {
2013-05-17 18:11:24 +04:00
virFilePrintf ( stderr , " unexpected side effects j=%zu, expected 1 \n " , j ) ;
2013-05-08 01:26:28 +04:00
goto cleanup ;
}
if ( STRNEQ_NULLABLE ( array [ 0 ] , " hello " ) | | array [ 1 ] ) {
2013-05-17 18:11:24 +04:00
virFilePrintf ( stderr , " incorrect array contents '%s' '%s' \n " ,
NULLSTR ( array [ 0 ] ) , NULLSTR ( array [ 1 ] ) ) ;
2013-05-08 01:26:28 +04:00
goto cleanup ;
}
value = VIR_STRNDUP ( array [ i + + ] , testStrdupLookup1 ( j + + ) ,
testStrdupLookup2 ( k + + ) ) ;
if ( value ! = 0 ) {
2013-05-17 18:11:24 +04:00
virFilePrintf ( stderr , " unexpected strdup result %d, expected 0 \n " , value ) ;
2013-05-08 01:26:28 +04:00
goto cleanup ;
}
if ( i ! = 2 ) {
2013-05-17 18:11:24 +04:00
virFilePrintf ( stderr , " unexpected side effects i=%zu, expected 2 \n " , i ) ;
2013-05-08 01:26:28 +04:00
goto cleanup ;
}
if ( j ! = 2 ) {
2013-05-17 18:11:24 +04:00
virFilePrintf ( stderr , " unexpected side effects j=%zu, expected 2 \n " , j ) ;
2013-05-08 01:26:28 +04:00
goto cleanup ;
}
if ( k ! = 1 ) {
2013-05-17 18:11:24 +04:00
virFilePrintf ( stderr , " unexpected side effects k=%zu, expected 1 \n " , k ) ;
2013-05-08 01:26:28 +04:00
goto cleanup ;
}
if ( STRNEQ_NULLABLE ( array [ 0 ] , " hello " ) | | array [ 1 ] ) {
2013-05-17 18:11:24 +04:00
virFilePrintf ( stderr , " incorrect array contents '%s' '%s' \n " ,
NULLSTR ( array [ 0 ] ) , NULLSTR ( array [ 1 ] ) ) ;
2013-05-08 01:26:28 +04:00
goto cleanup ;
}
if ( fail ) {
2013-05-17 18:11:24 +04:00
virFilePrintf ( stderr , " side effects failed \n " ) ;
2013-05-08 01:26:28 +04:00
goto cleanup ;
}
ret = 0 ;
cleanup :
for ( i = 0 ; i < ARRAY_CARDINALITY ( array ) ; i + + )
VIR_FREE ( array [ i ] ) ;
return ret ;
}
2013-05-24 12:45:57 +04:00
static int
testStrndupNegative ( const void * opaque ATTRIBUTE_UNUSED )
{
int ret = - 1 ;
char * dst ;
const char * src = " Hello world " ;
int value ;
if ( ( value = VIR_STRNDUP ( dst , src , 5 ) ) ! = 1 ) {
fprintf ( stderr , " unexpected virStrndup result %d, expected 1 \n " , value ) ;
goto cleanup ;
}
if ( STRNEQ_NULLABLE ( dst , " Hello " ) ) {
fprintf ( stderr , " unexpected content '%s' " , dst ) ;
goto cleanup ;
}
VIR_FREE ( dst ) ;
if ( ( value = VIR_STRNDUP ( dst , src , - 1 ) ) ! = 1 ) {
fprintf ( stderr , " unexpected virStrndup result %d, expected 1 \n " , value ) ;
goto cleanup ;
}
if ( STRNEQ_NULLABLE ( dst , src ) ) {
fprintf ( stderr , " unexpected content '%s' " , dst ) ;
goto cleanup ;
}
ret = 0 ;
cleanup :
VIR_FREE ( dst ) ;
return ret ;
}
2012-11-30 19:21:02 +04:00
2013-11-28 15:14:59 +04:00
static int
testStringSortCompare ( const void * opaque ATTRIBUTE_UNUSED )
{
const char * randlist [ ] = {
" tasty " , " astro " , " goat " , " chicken " , " turducken " ,
} ;
const char * randrlist [ ] = {
" tasty " , " astro " , " goat " , " chicken " , " turducken " ,
} ;
const char * sortlist [ ] = {
" astro " , " chicken " , " goat " , " tasty " , " turducken " ,
} ;
const char * sortrlist [ ] = {
" turducken " , " tasty " , " goat " , " chicken " , " astro " ,
} ;
int ret = - 1 ;
size_t i ;
qsort ( randlist , ARRAY_CARDINALITY ( randlist ) , sizeof ( randlist [ 0 ] ) ,
virStringSortCompare ) ;
qsort ( randrlist , ARRAY_CARDINALITY ( randrlist ) , sizeof ( randrlist [ 0 ] ) ,
virStringSortRevCompare ) ;
for ( i = 0 ; i < ARRAY_CARDINALITY ( randlist ) ; i + + ) {
if ( STRNEQ ( randlist [ i ] , sortlist [ i ] ) ) {
fprintf ( stderr , " sortlist[%zu] '%s' != randlist[%zu] '%s' \n " ,
i , sortlist [ i ] , i , randlist [ i ] ) ;
goto cleanup ;
}
if ( STRNEQ ( randrlist [ i ] , sortrlist [ i ] ) ) {
fprintf ( stderr , " sortrlist[%zu] '%s' != randrlist[%zu] '%s' \n " ,
i , sortrlist [ i ] , i , randrlist [ i ] ) ;
goto cleanup ;
}
}
ret = 0 ;
cleanup :
return ret ;
}
2012-11-30 19:21:02 +04:00
static int
mymain ( void )
{
int ret = 0 ;
# define TEST_SPLIT(str, del, max, toks) \
do { \
struct testSplitData splitData = { \
. string = str , \
. delim = del , \
. max_tokens = max , \
. tokens = toks , \
} ; \
struct testJoinData joinData = { \
. string = str , \
. delim = del , \
. tokens = toks , \
} ; \
2013-09-20 22:13:35 +04:00
if ( virtTestRun ( " Split " # str , testSplit , & splitData ) < 0 ) \
2012-11-30 19:21:02 +04:00
ret = - 1 ; \
2013-09-20 22:13:35 +04:00
if ( virtTestRun ( " Join " # str , testJoin , & joinData ) < 0 ) \
2012-11-30 19:21:02 +04:00
ret = - 1 ; \
} while ( 0 )
const char * tokens1 [ ] = { NULL } ;
TEST_SPLIT ( " " , " " , 0 , tokens1 ) ;
const char * tokens2 [ ] = { " " , " " , NULL } ;
TEST_SPLIT ( " " , " " , 0 , tokens2 ) ;
const char * tokens3 [ ] = { " " , " " , " " , NULL } ;
TEST_SPLIT ( " " , " " , 0 , tokens3 ) ;
const char * tokens4 [ ] = { " The " , " quick " , " brown " , " fox " , NULL } ;
TEST_SPLIT ( " The quick brown fox " , " " , 0 , tokens4 ) ;
const char * tokens5 [ ] = { " The quick " , " fox " , NULL } ;
TEST_SPLIT ( " The quick brown fox " , " brown " , 0 , tokens5 ) ;
const char * tokens6 [ ] = { " " , " The " , " quick " , " brown " , " fox " , NULL } ;
TEST_SPLIT ( " The quick brown fox " , " " , 0 , tokens6 ) ;
const char * tokens7 [ ] = { " The " , " quick " , " brown " , " fox " , " " , NULL } ;
TEST_SPLIT ( " The quick brown fox " , " " , 0 , tokens7 ) ;
2013-09-20 22:13:35 +04:00
if ( virtTestRun ( " strdup " , testStrdup , NULL ) < 0 )
2013-05-08 01:26:28 +04:00
ret = - 1 ;
2012-11-30 19:21:02 +04:00
2013-09-20 22:13:35 +04:00
if ( virtTestRun ( " strdup " , testStrndupNegative , NULL ) < 0 )
2013-05-24 12:45:57 +04:00
ret = - 1 ;
2013-11-28 15:14:59 +04:00
if ( virtTestRun ( " virStringSortCompare " , testStringSortCompare , NULL ) < 0 )
ret = - 1 ;
2012-11-30 19:21:02 +04:00
return ret = = 0 ? EXIT_SUCCESS : EXIT_FAILURE ;
}
VIRT_TEST_MAIN ( mymain )