2006-03-25 17:49:00 +03:00
/*
Unix SMB / CIFS implementation .
SMB torture UI functions
Copyright ( C ) Jelmer Vernooij 2006
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 2 of the License , or
( at your option ) any later version .
This program 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 General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
# include "includes.h"
# include "torture/ui.h"
2006-10-17 00:05:19 +04:00
# include "torture/torture.h"
2006-08-30 15:29:34 +04:00
# include "lib/util/dlinklist.h"
2006-03-25 17:49:00 +03:00
2006-10-17 23:36:55 +04:00
void torture_comment ( struct torture_context * context , const char * comment , . . . )
2006-06-13 03:03:02 +04:00
{
2006-06-17 02:06:09 +04:00
va_list ap ;
char * tmp ;
2006-06-17 03:10:15 +04:00
if ( ! context - > ui_ops - > comment )
return ;
2006-06-17 02:06:09 +04:00
va_start ( ap , comment ) ;
tmp = talloc_vasprintf ( context , comment , ap ) ;
context - > ui_ops - > comment ( context , tmp ) ;
talloc_free ( tmp ) ;
}
2006-06-13 03:03:02 +04:00
2006-10-17 23:06:50 +04:00
void torture_result ( struct torture_context * context ,
enum torture_result result , const char * fmt , . . . )
2006-06-17 02:06:09 +04:00
{
va_list ap ;
2006-06-17 03:10:15 +04:00
2006-06-17 02:06:09 +04:00
va_start ( ap , fmt ) ;
2006-10-17 23:06:50 +04:00
context - > last_result = result ;
2006-06-17 04:17:50 +04:00
context - > last_reason = talloc_vasprintf ( context , fmt , ap ) ;
2006-06-17 02:06:09 +04:00
va_end ( ap ) ;
}
2006-03-25 17:49:00 +03:00
2006-06-17 02:06:09 +04:00
struct torture_suite * torture_suite_create ( TALLOC_CTX * ctx , const char * name )
{
2006-10-17 00:05:19 +04:00
struct torture_suite * suite = talloc_zero ( ctx , struct torture_suite ) ;
2006-03-25 17:49:00 +03:00
2006-06-17 02:06:09 +04:00
suite - > name = talloc_strdup ( suite , name ) ;
suite - > testcases = NULL ;
2006-10-16 17:06:41 +04:00
suite - > children = NULL ;
2006-06-13 03:03:02 +04:00
2006-06-17 02:06:09 +04:00
return suite ;
}
void torture_tcase_set_fixture ( struct torture_tcase * tcase ,
BOOL ( * setup ) ( struct torture_context * , void * * ) ,
BOOL ( * teardown ) ( struct torture_context * , void * ) )
{
tcase - > setup = setup ;
tcase - > teardown = teardown ;
2006-03-25 17:49:00 +03:00
}
2006-10-16 17:06:41 +04:00
static bool wrap_test_with_testcase ( struct torture_context * torture_ctx ,
struct torture_tcase * tcase ,
struct torture_test * test )
{
bool ( * fn ) ( struct torture_context * ,
const void * tcase_data ,
const void * test_data ) ;
fn = test - > fn ;
return fn ( torture_ctx , tcase - > data , test - > data ) ;
}
2006-06-17 02:06:09 +04:00
struct torture_test * torture_tcase_add_test ( struct torture_tcase * tcase ,
const char * name ,
2006-10-16 17:06:41 +04:00
bool ( * run ) ( struct torture_context * ,
2006-06-17 02:06:09 +04:00
const void * tcase_data ,
const void * test_data ) ,
const void * data )
2006-03-25 17:49:00 +03:00
{
2006-06-17 02:06:09 +04:00
struct torture_test * test = talloc ( tcase , struct torture_test ) ;
2006-03-25 17:49:00 +03:00
test - > name = talloc_strdup ( test , name ) ;
2006-06-17 02:06:09 +04:00
test - > description = NULL ;
2006-10-16 17:06:41 +04:00
test - > run = wrap_test_with_testcase ;
test - > fn = run ;
2006-06-17 02:48:50 +04:00
test - > dangerous = False ;
2006-06-17 02:06:09 +04:00
test - > data = data ;
2006-03-25 17:49:00 +03:00
2006-09-14 15:47:13 +04:00
DLIST_ADD_END ( tcase - > tests , test , struct torture_test * ) ;
2006-06-13 03:03:02 +04:00
return test ;
2006-03-25 17:49:00 +03:00
}
2006-06-17 02:06:09 +04:00
struct torture_tcase * torture_suite_add_tcase ( struct torture_suite * suite ,
const char * name )
2006-03-25 17:49:00 +03:00
{
2006-06-17 02:06:09 +04:00
struct torture_tcase * tcase = talloc ( suite , struct torture_tcase ) ;
tcase - > name = talloc_strdup ( tcase , name ) ;
tcase - > description = NULL ;
tcase - > setup = NULL ;
tcase - > teardown = NULL ;
tcase - > fixture_persistent = True ;
tcase - > tests = NULL ;
2006-10-16 17:06:41 +04:00
DLIST_ADD_END ( suite - > testcases , tcase , struct torture_tcase * ) ;
2006-06-17 02:06:09 +04:00
return tcase ;
}
BOOL torture_run_suite ( struct torture_context * context ,
struct torture_suite * suite )
{
BOOL ret = True ;
struct torture_tcase * tcase ;
2006-10-16 17:06:41 +04:00
struct torture_suite * tsuite ;
2006-10-18 02:06:43 +04:00
char * old_testname ;
2006-06-17 02:06:09 +04:00
2006-10-16 17:06:41 +04:00
context - > level + + ;
2006-06-17 03:10:15 +04:00
if ( context - > ui_ops - > suite_start )
context - > ui_ops - > suite_start ( context , suite ) ;
2006-10-18 02:06:43 +04:00
old_testname = context - > active_testname ;
2006-11-03 01:17:11 +03:00
if ( old_testname ! = NULL )
2006-10-18 02:06:43 +04:00
context - > active_testname = talloc_asprintf ( context , " %s-%s " ,
old_testname , suite - > name ) ;
else
context - > active_testname = talloc_strdup ( context , suite - > name ) ;
2006-10-17 00:05:19 +04:00
if ( suite - > path )
2006-10-18 14:03:30 +04:00
ret & = torture_subunit_run_suite ( context , suite ) ;
2006-10-17 00:05:19 +04:00
2006-06-17 02:06:09 +04:00
for ( tcase = suite - > testcases ; tcase ; tcase = tcase - > next ) {
ret & = torture_run_tcase ( context , tcase ) ;
}
2006-06-17 03:10:15 +04:00
2006-10-16 17:06:41 +04:00
for ( tsuite = suite - > children ; tsuite ; tsuite = tsuite - > next ) {
ret & = torture_run_suite ( context , tsuite ) ;
}
2006-10-18 02:06:43 +04:00
talloc_free ( context - > active_testname ) ;
context - > active_testname = old_testname ;
2006-06-17 03:10:15 +04:00
if ( context - > ui_ops - > suite_finish )
context - > ui_ops - > suite_finish ( context , suite ) ;
2006-10-16 17:06:41 +04:00
context - > level - - ;
2006-03-25 17:49:00 +03:00
2006-06-17 02:06:09 +04:00
return ret ;
2006-03-25 17:49:00 +03:00
}
2006-10-17 00:05:19 +04:00
void torture_ui_test_start ( struct torture_context * context ,
struct torture_tcase * tcase ,
struct torture_test * test )
{
if ( context - > ui_ops - > test_start )
context - > ui_ops - > test_start ( context , tcase , test ) ;
}
2006-10-18 02:06:43 +04:00
int str_list_match ( const char * name , char * * list )
{
int i , ret = 0 ;
if ( list = = NULL )
return 0 ;
for ( i = 0 ; list [ i ] ; i + + ) {
if ( gen_fnmatch ( list [ i ] , name ) = = 0 )
ret + + ;
}
return ret ;
}
2006-10-17 00:05:19 +04:00
void torture_ui_test_result ( struct torture_context * context ,
enum torture_result result ,
const char * comment )
{
if ( context - > ui_ops - > test_result )
context - > ui_ops - > test_result ( context , result , comment ) ;
2006-10-18 02:06:43 +04:00
if ( result = = TORTURE_SKIP ) {
context - > results . skipped + + ;
} else if ( result = = TORTURE_OK ) {
if ( str_list_match ( context - > active_testname ,
context - > expected_failures ) ) {
context - > results . unexpected_successes = str_list_add (
context - > results . unexpected_successes ,
talloc_reference ( context , context - > active_testname ) ) ;
}
context - > results . success + + ;
} else if ( result = = TORTURE_ERROR ) {
context - > results . unexpected_errors = str_list_add (
context - > results . unexpected_errors ,
talloc_reference ( context , context - > active_testname ) ) ;
context - > results . errors + + ;
2006-10-18 14:03:30 +04:00
context - > results . returncode = false ;
2006-10-18 02:06:43 +04:00
} else if ( result = = TORTURE_FAIL ) {
if ( 0 = = str_list_match ( context - > active_testname ,
context - > expected_failures ) ) {
context - > results . unexpected_failures = str_list_add (
context - > results . unexpected_failures ,
talloc_reference ( context , context - > active_testname ) ) ;
2006-10-18 14:03:30 +04:00
context - > results . returncode = false ;
2006-10-18 02:06:43 +04:00
}
context - > results . failed + + ;
2006-10-17 00:05:19 +04:00
}
}
2006-06-17 02:48:50 +04:00
static BOOL internal_torture_run_test ( struct torture_context * context ,
struct torture_tcase * tcase ,
struct torture_test * test ,
2006-10-16 17:06:41 +04:00
BOOL already_setup )
2006-06-17 02:48:50 +04:00
{
BOOL ret ;
2006-10-18 02:06:43 +04:00
char * old_testname ;
2006-06-17 02:48:50 +04:00
2006-10-16 17:06:41 +04:00
if ( test - > dangerous & & ! torture_setting_bool ( context , " dangerous " , False ) ) {
2006-10-17 23:06:50 +04:00
torture_result ( context , TORTURE_SKIP ,
2006-10-16 17:06:41 +04:00
" disabled %s - enable dangerous tests to use " , test - > name ) ;
2006-06-17 02:48:50 +04:00
return True ;
}
2006-10-16 17:06:41 +04:00
if ( ! already_setup & & tcase - > setup & &
! tcase - > setup ( context , & ( tcase - > data ) ) )
2006-06-17 02:48:50 +04:00
return False ;
2006-10-18 02:06:43 +04:00
if ( tcase = = NULL | | strcmp ( test - > name , tcase - > name ) ! = 0 ) {
old_testname = context - > active_testname ;
context - > active_testname = talloc_asprintf ( context , " %s-%s " ,
old_testname , test - > name ) ;
}
2006-06-17 02:48:50 +04:00
context - > active_tcase = tcase ;
context - > active_test = test ;
2006-06-17 04:17:50 +04:00
2006-10-17 00:05:19 +04:00
torture_ui_test_start ( context , tcase , test ) ;
2006-06-17 02:48:50 +04:00
2006-10-18 02:06:43 +04:00
2006-06-17 04:17:50 +04:00
context - > last_reason = NULL ;
context - > last_result = TORTURE_OK ;
2006-10-16 17:06:41 +04:00
ret = test - > run ( context , tcase , test ) ;
2006-10-18 02:06:43 +04:00
if ( ! ret & & context - > last_result = = TORTURE_OK ) {
2006-10-16 17:06:41 +04:00
if ( context - > last_reason = = NULL )
2006-10-17 23:36:55 +04:00
context - > last_reason = talloc_strdup ( context , " Unknown error/failure " ) ;
context - > last_result = TORTURE_ERROR ;
2006-06-21 21:47:19 +04:00
}
2006-06-17 04:17:50 +04:00
2006-10-17 00:05:19 +04:00
torture_ui_test_result ( context , context - > last_result , context - > last_reason ) ;
2006-06-17 04:17:50 +04:00
talloc_free ( context - > last_reason ) ;
2006-10-18 02:06:43 +04:00
if ( tcase = = NULL | | strcmp ( test - > name , tcase - > name ) ! = 0 ) {
talloc_free ( context - > active_testname ) ;
context - > active_testname = old_testname ;
}
2006-06-17 02:48:50 +04:00
context - > active_test = NULL ;
context - > active_tcase = NULL ;
2006-10-16 17:06:41 +04:00
if ( ! already_setup & & tcase - > teardown & & ! tcase - > teardown ( context , tcase - > data ) )
2006-06-17 02:48:50 +04:00
return False ;
return ret ;
}
2006-06-17 02:06:09 +04:00
BOOL torture_run_tcase ( struct torture_context * context ,
struct torture_tcase * tcase )
{
BOOL ret = True ;
2006-10-18 02:06:43 +04:00
char * old_testname ;
2006-06-17 02:06:09 +04:00
struct torture_test * test ;
2006-10-16 17:06:41 +04:00
context - > level + + ;
2006-06-17 02:06:09 +04:00
context - > active_tcase = tcase ;
if ( context - > ui_ops - > tcase_start )
context - > ui_ops - > tcase_start ( context , tcase ) ;
if ( tcase - > fixture_persistent & & tcase - > setup
2006-10-16 17:06:41 +04:00
& & ! tcase - > setup ( context , & tcase - > data ) ) {
2006-06-17 03:10:15 +04:00
ret = False ;
goto done ;
}
2006-06-17 02:06:09 +04:00
2006-10-18 02:06:43 +04:00
old_testname = context - > active_testname ;
context - > active_testname = talloc_asprintf ( context , " %s-%s " ,
old_testname , tcase - > name ) ;
2006-06-17 02:06:09 +04:00
for ( test = tcase - > tests ; test ; test = test - > next ) {
2006-06-17 02:48:50 +04:00
ret & = internal_torture_run_test ( context , tcase , test ,
2006-10-16 17:06:41 +04:00
tcase - > fixture_persistent ) ;
2006-06-17 02:06:09 +04:00
}
2006-10-18 02:06:43 +04:00
talloc_free ( context - > active_testname ) ;
context - > active_testname = old_testname ;
2006-06-17 02:06:09 +04:00
if ( tcase - > fixture_persistent & & tcase - > teardown & &
2006-10-16 17:06:41 +04:00
! tcase - > teardown ( context , tcase - > data ) )
2006-06-17 03:10:15 +04:00
ret = False ;
2006-06-17 02:06:09 +04:00
2006-06-17 03:10:15 +04:00
done :
2006-06-17 02:06:09 +04:00
context - > active_tcase = NULL ;
2006-06-17 03:10:15 +04:00
if ( context - > ui_ops - > tcase_finish )
context - > ui_ops - > tcase_finish ( context , tcase ) ;
2006-10-16 17:06:41 +04:00
context - > level - - ;
2006-06-17 02:06:09 +04:00
return ret ;
}
BOOL torture_run_test ( struct torture_context * context ,
struct torture_tcase * tcase ,
struct torture_test * test )
2006-03-25 17:49:00 +03:00
{
2006-10-16 17:06:41 +04:00
return internal_torture_run_test ( context , tcase , test , False ) ;
2006-03-25 17:49:00 +03:00
}
2006-10-16 17:06:41 +04:00
int torture_setting_int ( struct torture_context * test , const char * name ,
int default_value )
{
return lp_parm_int ( - 1 , " torture " , name , default_value ) ;
}
bool torture_setting_bool ( struct torture_context * test , const char * name ,
bool default_value )
{
return lp_parm_bool ( - 1 , " torture " , name , default_value ) ;
}
const char * torture_setting_string ( struct torture_context * test , const char * name ,
2006-06-17 02:06:09 +04:00
const char * default_value )
2006-03-25 17:49:00 +03:00
{
2006-06-17 02:06:09 +04:00
const char * ret = lp_parm_string ( - 1 , " torture " , name ) ;
2006-05-22 22:59:29 +04:00
2006-06-17 02:06:09 +04:00
if ( ret = = NULL )
return default_value ;
return ret ;
2006-03-25 17:49:00 +03:00
}
2006-10-16 17:06:41 +04:00
static bool wrap_test_with_simple_tcase ( struct torture_context * torture_ctx ,
struct torture_tcase * tcase ,
struct torture_test * test )
2006-06-12 23:49:53 +04:00
{
2006-10-16 17:06:41 +04:00
bool ( * fn ) ( struct torture_context * , const void * tcase_data ) ;
fn = test - > fn ;
2006-06-17 02:06:09 +04:00
2006-10-16 17:06:41 +04:00
return fn ( torture_ctx , test - > data ) ;
2006-06-12 23:49:53 +04:00
}
2006-06-17 02:06:09 +04:00
struct torture_tcase * torture_suite_add_simple_tcase (
struct torture_suite * suite ,
const char * name ,
2006-10-16 17:06:41 +04:00
bool ( * run ) ( struct torture_context * test , const void * ) ,
2006-06-17 02:06:09 +04:00
const void * data )
2006-03-25 17:49:00 +03:00
{
2006-06-17 02:06:09 +04:00
struct torture_tcase * tcase ;
2006-10-16 17:06:41 +04:00
struct torture_test * test ;
2006-06-17 02:06:09 +04:00
tcase = torture_suite_add_tcase ( suite , name ) ;
2006-06-21 21:47:19 +04:00
2006-10-16 17:06:41 +04:00
test = talloc ( tcase , struct torture_test ) ;
test - > name = talloc_strdup ( test , name ) ;
test - > description = NULL ;
test - > run = wrap_test_with_simple_tcase ;
test - > fn = run ;
test - > data = data ;
test - > dangerous = False ;
DLIST_ADD_END ( tcase - > tests , test , struct torture_test * ) ;
return tcase ;
}
static bool wrap_simple_test ( struct torture_context * torture_ctx ,
struct torture_tcase * tcase ,
struct torture_test * test )
{
bool ( * fn ) ( struct torture_context * ) ;
fn = test - > fn ;
return fn ( torture_ctx ) ;
}
struct torture_tcase * torture_suite_add_simple_test (
struct torture_suite * suite ,
const char * name ,
bool ( * run ) ( struct torture_context * test ) )
{
struct torture_test * test ;
struct torture_tcase * tcase ;
tcase = torture_suite_add_tcase ( suite , name ) ;
test = talloc ( tcase , struct torture_test ) ;
test - > name = talloc_strdup ( test , name ) ;
test - > description = NULL ;
test - > run = wrap_simple_test ;
test - > fn = run ;
test - > dangerous = false ;
DLIST_ADD_END ( tcase - > tests , test , struct torture_test * ) ;
2006-06-17 02:06:09 +04:00
return tcase ;
}
2006-10-16 17:06:41 +04:00
bool torture_suite_add_suite ( struct torture_suite * suite ,
struct torture_suite * child )
{
if ( child = = NULL )
return false ;
DLIST_ADD_END ( suite - > children , child , struct torture_suite * ) ;
/* FIXME: Check for duplicates and return false if the
* added suite already exists as a child */
return true ;
}
2006-10-17 03:09:15 +04:00
struct torture_suite * torture_find_suite ( struct torture_suite * parent ,
const char * name )
2006-10-16 17:06:41 +04:00
{
2006-10-17 03:09:15 +04:00
struct torture_suite * child ;
for ( child = parent - > children ; child ; child = child - > next )
if ( ! strcmp ( child - > name , name ) )
return child ;
2006-10-16 17:06:41 +04:00
return NULL ;
}