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
2007-07-10 06:07:03 +04:00
the Free Software Foundation ; either version 3 of the License , or
2006-03-25 17:49:00 +03:00
( 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
2007-07-10 06:07:03 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2006-03-25 17:49:00 +03:00
*/
2006-06-17 02:06:09 +04:00
# ifndef __TORTURE_UI_H__
# define __TORTURE_UI_H__
2006-03-25 17:49:00 +03:00
struct torture_test ;
2006-06-17 02:06:09 +04:00
struct torture_context ;
2006-06-17 03:10:15 +04:00
struct torture_suite ;
2006-06-17 02:06:09 +04:00
struct torture_tcase ;
2008-11-01 02:24:55 +03:00
struct torture_results ;
2006-03-25 17:49:00 +03:00
enum torture_result {
TORTURE_OK = 0 ,
2006-10-17 23:36:55 +04:00
TORTURE_FAIL = 1 ,
TORTURE_ERROR = 2 ,
TORTURE_SKIP = 3
2006-03-25 17:49:00 +03:00
} ;
2006-10-16 17:06:41 +04:00
/*
* These callbacks should be implemented by any backend that wishes
* to listen to reports from the torture tests .
*/
2006-03-25 17:49:00 +03:00
struct torture_ui_ops
{
2008-11-01 02:24:55 +03:00
void ( * init ) ( struct torture_results * ) ;
2006-06-17 02:06:09 +04:00
void ( * comment ) ( struct torture_context * , const char * ) ;
2007-03-06 00:28:55 +03:00
void ( * warning ) ( struct torture_context * , const char * ) ;
2006-06-17 03:10:15 +04:00
void ( * suite_start ) ( struct torture_context * , struct torture_suite * ) ;
void ( * suite_finish ) ( struct torture_context * , struct torture_suite * ) ;
2006-06-17 02:06:09 +04:00
void ( * tcase_start ) ( struct torture_context * , struct torture_tcase * ) ;
void ( * tcase_finish ) ( struct torture_context * , struct torture_tcase * ) ;
void ( * test_start ) ( struct torture_context * ,
struct torture_tcase * ,
struct torture_test * ) ;
2006-10-16 17:06:41 +04:00
void ( * test_result ) ( struct torture_context * ,
enum torture_result , const char * reason ) ;
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 ) ;
void torture_ui_test_result ( struct torture_context * context ,
enum torture_result result ,
const char * comment ) ;
2006-10-16 17:06:41 +04:00
/*
* Holds information about a specific run of the testsuite .
* The data in this structure should be considered private to
* the torture tests and should only be used directly by the torture
* code and the ui backends .
*
* Torture tests should instead call the torture_ * ( ) macros and functions
* specified below .
*/
2006-03-25 17:49:00 +03:00
struct torture_context
{
2008-11-01 02:24:55 +03:00
struct torture_results * results ;
2006-03-25 21:45:51 +03:00
2006-10-18 02:06:43 +04:00
char * active_testname ;
2006-06-17 02:06:09 +04:00
struct torture_test * active_test ;
struct torture_tcase * active_tcase ;
2006-06-17 04:17:50 +04:00
enum torture_result last_result ;
char * last_reason ;
2006-06-27 00:09:35 +04:00
2008-10-31 18:37:02 +03:00
/** Directory used for temporary test data */
2007-08-31 22:35:30 +04:00
const char * outputdir ;
2008-10-31 18:37:02 +03:00
/** Indentation level */
2006-10-16 17:06:41 +04:00
int level ;
2008-10-31 18:37:02 +03:00
/** Event context */
2007-05-17 12:47:04 +04:00
struct event_context * ev ;
2007-12-03 02:28:22 +03:00
2008-10-31 18:37:02 +03:00
/** Loadparm context (will go away in favor of torture_setting_ at some point) */
2007-12-03 02:28:22 +03:00
struct loadparm_context * lp_ctx ;
2006-10-16 17:06:41 +04:00
} ;
2008-11-01 02:24:55 +03:00
struct torture_results
{
const struct torture_ui_ops * ui_ops ;
void * ui_data ;
/** Whether tests should avoid writing output to stdout */
bool quiet ;
bool returncode ;
} ;
2006-10-16 17:06:41 +04:00
/*
* Describes a particular torture test
*/
struct torture_test {
2008-10-31 18:37:02 +03:00
/** Short unique name for the test. */
2006-10-16 17:06:41 +04:00
const char * name ;
2008-10-31 18:37:02 +03:00
/** Long description for the test. */
2006-10-16 17:06:41 +04:00
const char * description ;
2008-10-31 18:37:02 +03:00
/** Whether this is a dangerous test
* ( can corrupt the remote servers data or bring it down ) . */
2006-10-16 17:06:41 +04:00
bool dangerous ;
2008-10-31 18:37:02 +03:00
/** Function to call to run this test */
2006-10-16 17:06:41 +04:00
bool ( * run ) ( struct torture_context * torture_ctx ,
struct torture_tcase * tcase ,
struct torture_test * test ) ;
struct torture_test * prev , * next ;
2008-10-31 18:37:02 +03:00
/** Pointer to the actual test function. This is run by the
* run ( ) function above . */
2006-10-16 17:06:41 +04:00
void * fn ;
2008-10-31 18:37:02 +03:00
/** Use data for this test */
2006-10-16 17:06:41 +04:00
const void * data ;
} ;
/*
* Describes a particular test case .
*/
struct torture_tcase {
const char * name ;
const char * description ;
bool ( * setup ) ( struct torture_context * tcase , void * * data ) ;
bool ( * teardown ) ( struct torture_context * tcase , void * data ) ;
bool fixture_persistent ;
void * data ;
struct torture_test * tests ;
struct torture_tcase * prev , * next ;
2006-03-25 17:49:00 +03:00
} ;
2006-05-22 22:59:29 +04:00
2006-06-17 02:06:09 +04:00
struct torture_suite
{
const char * name ;
const char * description ;
2006-10-16 17:06:41 +04:00
struct torture_tcase * testcases ;
struct torture_suite * children ;
/* Pointers to siblings of this torture suite */
struct torture_suite * prev , * next ;
2006-06-17 02:06:09 +04:00
} ;
2006-10-16 17:06:41 +04:00
/** Create a new torture suite */
2007-12-24 22:04:56 +03:00
struct torture_suite * torture_suite_create ( TALLOC_CTX * mem_ctx ,
const char * name ) ;
2006-10-16 17:06:41 +04:00
/** Change the setup and teardown functions for a testcase */
2007-12-24 22:04:56 +03:00
void torture_tcase_set_fixture ( struct torture_tcase * tcase ,
2006-10-16 17:06:41 +04:00
bool ( * setup ) ( struct torture_context * , void * * ) ,
bool ( * teardown ) ( struct torture_context * , void * ) ) ;
/* Add another test to run for a particular testcase */
2007-12-24 22:04:56 +03:00
struct torture_test * torture_tcase_add_test_const ( struct torture_tcase * tcase ,
const char * name ,
bool ( * run ) ( struct torture_context * test ,
const void * tcase_data , const void * test_data ) ,
2006-06-17 02:06:09 +04:00
const void * test_data ) ;
2006-10-16 17:06:41 +04:00
/* Add a testcase to a testsuite */
2007-12-24 22:04:56 +03:00
struct torture_tcase * torture_suite_add_tcase ( struct torture_suite * suite ,
2006-06-17 02:06:09 +04:00
const char * name ) ;
2006-10-16 17:06:41 +04:00
2007-12-24 22:04:56 +03:00
/* Convenience wrapper that adds a testcase against only one
2006-10-16 17:06:41 +04:00
* test will be run */
2007-12-24 22:04:56 +03:00
struct torture_tcase * torture_suite_add_simple_tcase_const (
struct torture_suite * suite ,
2006-06-17 02:06:09 +04:00
const char * name ,
2007-12-24 22:04:56 +03:00
bool ( * run ) ( struct torture_context * test ,
const void * test_data ) ,
2006-06-17 02:06:09 +04:00
const void * data ) ;
2007-12-24 22:04:56 +03:00
/* Convenience function that adds a test which only
2007-08-26 19:16:40 +04:00
* gets the test case data */
2007-12-24 22:04:56 +03:00
struct torture_test * torture_tcase_add_simple_test_const (
2007-08-26 19:16:40 +04:00
struct torture_tcase * tcase ,
const char * name ,
2007-12-24 22:04:56 +03:00
bool ( * run ) ( struct torture_context * test ,
const void * tcase_data ) ) ;
2007-08-26 19:16:40 +04:00
2007-12-24 22:04:56 +03:00
/* Convenience wrapper that adds a test that doesn't need any
2006-10-16 17:06:41 +04:00
* testcase data */
struct torture_tcase * torture_suite_add_simple_test (
2007-12-24 22:04:56 +03:00
struct torture_suite * suite ,
2006-10-16 17:06:41 +04:00
const char * name ,
bool ( * run ) ( struct torture_context * test ) ) ;
/* Add a child testsuite to an existing testsuite */
bool torture_suite_add_suite ( struct torture_suite * suite ,
2007-12-24 22:04:56 +03:00
struct torture_suite * child ) ;
2006-10-16 17:06:41 +04:00
/* Run the specified testsuite recursively */
2007-12-24 22:04:56 +03:00
bool torture_run_suite ( struct torture_context * context ,
2006-06-17 02:06:09 +04:00
struct torture_suite * suite ) ;
2006-10-16 17:06:41 +04:00
/* Run the specified testcase */
2007-12-24 22:04:56 +03:00
bool torture_run_tcase ( struct torture_context * context ,
2006-06-17 02:06:09 +04:00
struct torture_tcase * tcase ) ;
2006-10-16 17:06:41 +04:00
/* Run the specified test */
2007-12-24 22:04:56 +03:00
bool torture_run_test ( struct torture_context * context ,
2006-06-17 02:06:09 +04:00
struct torture_tcase * tcase ,
struct torture_test * test ) ;
2006-10-16 17:06:41 +04:00
void torture_comment ( struct torture_context * test , const char * comment , . . . ) PRINTF_ATTRIBUTE ( 2 , 3 ) ;
2007-03-06 00:28:55 +03:00
void torture_warning ( struct torture_context * test , const char * comment , . . . ) PRINTF_ATTRIBUTE ( 2 , 3 ) ;
2007-12-24 22:04:56 +03:00
void torture_result ( struct torture_context * test ,
2006-10-17 23:06:50 +04:00
enum torture_result , const char * reason , . . . ) PRINTF_ATTRIBUTE ( 3 , 4 ) ;
2006-10-16 17:06:41 +04:00
# define torture_assert(torture_ctx,expr,cmt) \
2006-05-22 22:59:29 +04:00
if ( ! ( expr ) ) { \
2006-10-17 23:06:50 +04:00
torture_result ( torture_ctx , TORTURE_FAIL , __location__ " : Expression `%s' failed: %s " , __STRING ( expr ) , cmt ) ; \
2006-10-16 17:06:41 +04:00
return false ; \
2006-05-22 22:59:29 +04:00
}
2006-10-16 17:06:41 +04:00
# define torture_assert_werr_equal(torture_ctx, got, expected, cmt) \
2006-06-26 23:23:21 +04:00
do { WERROR __got = got , __expected = expected ; \
if ( ! W_ERROR_EQUAL ( __got , __expected ) ) { \
2006-10-17 23:06:50 +04:00
torture_result ( torture_ctx , TORTURE_FAIL , __location__ " : " # got " was %s, expected %s: %s " , win_errstr ( __got ) , win_errstr ( __expected ) , cmt ) ; \
2006-10-16 17:06:41 +04:00
return false ; \
2006-06-26 23:23:21 +04:00
} \
} while ( 0 )
2006-05-22 22:59:29 +04:00
2006-10-16 17:06:41 +04:00
# define torture_assert_ntstatus_equal(torture_ctx,got,expected,cmt) \
2006-06-26 23:23:21 +04:00
do { NTSTATUS __got = got , __expected = expected ; \
if ( ! NT_STATUS_EQUAL ( __got , __expected ) ) { \
2006-10-17 23:06:50 +04:00
torture_result ( torture_ctx , TORTURE_FAIL , __location__ " : " # got " was %s, expected %s: %s " , nt_errstr ( __got ) , nt_errstr ( __expected ) , cmt ) ; \
2006-10-16 17:06:41 +04:00
return false ; \
2006-06-26 23:23:21 +04:00
} \
} while ( 0 )
2007-11-09 21:24:51 +03:00
# define torture_assert_ndr_err_equal(torture_ctx,got,expected,cmt) \
do { enum ndr_err_code __got = got , __expected = expected ; \
if ( __got ! = __expected ) { \
torture_result ( torture_ctx , TORTURE_FAIL , __location__ " : " # got " was %d, expected %d (%s): %s " , __got , __expected , __STRING ( expected ) , cmt ) ; \
return false ; \
} \
} while ( 0 )
2006-05-22 22:59:29 +04:00
2006-10-16 17:06:41 +04:00
# define torture_assert_casestr_equal(torture_ctx,got,expected,cmt) \
do { const char * __got = ( got ) , * __expected = ( expected ) ; \
if ( ! strequal ( __got , __expected ) ) { \
2006-10-17 23:06:50 +04:00
torture_result ( torture_ctx , TORTURE_FAIL , __location__ " : " # got " was %s, expected %s: %s " , __got , __expected , cmt ) ; \
2006-10-16 17:06:41 +04:00
return false ; \
2006-06-26 23:23:21 +04:00
} \
} while ( 0 )
2006-06-12 23:49:53 +04:00
2006-10-16 17:06:41 +04:00
# define torture_assert_str_equal(torture_ctx,got,expected,cmt)\
do { const char * __got = ( got ) , * __expected = ( expected ) ; \
if ( strcmp_safe ( __got , __expected ) ! = 0 ) { \
2006-10-17 23:06:50 +04:00
torture_result ( torture_ctx , TORTURE_FAIL , \
__location__ " : " # got " was %s, expected %s: %s " , \
__got , __expected , cmt ) ; \
2006-10-16 17:06:41 +04:00
return false ; \
2006-06-26 23:23:21 +04:00
} \
} while ( 0 )
2006-06-12 23:49:53 +04:00
2008-04-13 23:31:06 +04:00
# define torture_assert_mem_equal(torture_ctx,got,expected,len,cmt)\
do { const void * __got = ( got ) , * __expected = ( expected ) ; \
if ( memcmp ( __got , __expected , len ) ! = 0 ) { \
torture_result ( torture_ctx , TORTURE_FAIL , \
2008-06-02 05:02:37 +04:00
__location__ " : " # got " of len %d did not match " # expected " : %s " , ( int ) len , cmt ) ; \
2008-04-13 23:31:06 +04:00
return false ; \
} \
} while ( 0 )
2008-11-05 04:00:44 +03:00
# define torture_assert_data_blob_equal(torture_ctx,got,expected,cmt)\
do { const DATA_BLOB __got = ( got ) , __expected = ( expected ) ; \
if ( __got . length ! = __expected . length ) { \
torture_result ( torture_ctx , TORTURE_FAIL , \
__location__ " : " # got " .len %d did not match " # expected " len %d: %s " , \
( int ) __got . length , ( int ) __expected . length , cmt ) ; \
return false ; \
} \
if ( memcmp ( __got . data , __expected . data , __got . length ) ! = 0 ) { \
torture_result ( torture_ctx , TORTURE_FAIL , \
__location__ " : " # got " of len %d did not match " # expected " : %s " , ( int ) __got . length , cmt ) ; \
return false ; \
} \
} while ( 0 )
2007-08-11 21:08:22 +04:00
# define torture_assert_file_contains_text(torture_ctx,filename,expected,cmt)\
do { \
char * __got ; \
const char * __expected = ( expected ) ; \
size_t __size ; \
2008-10-12 21:46:38 +04:00
__got = file_load ( filename , & __size , 0 , torture_ctx ) ; \
2007-08-11 21:08:22 +04:00
if ( __got = = NULL ) { \
torture_result ( torture_ctx , TORTURE_FAIL , \
__location__ " : unable to open %s: %s \n " , \
filename , cmt ) ; \
return false ; \
} \
\
if ( strcmp_safe ( __got , __expected ) ! = 0 ) { \
torture_result ( torture_ctx , TORTURE_FAIL , \
__location__ " : %s contained: \n %sExpected: %s%s \n " , \
filename , __got , __expected , cmt ) ; \
talloc_free ( __got ) ; \
return false ; \
} \
talloc_free ( __got ) ; \
} while ( 0 )
2007-08-26 19:16:40 +04:00
# define torture_assert_file_contains(torture_ctx,filename,expected,cmt)\
do { const char * __got , * __expected = ( expected ) ; \
size_t __size ; \
2008-10-12 21:46:38 +04:00
__got = file_load ( filename , * size , 0 , torture_ctx ) ; \
2007-08-26 19:16:40 +04:00
if ( strcmp_safe ( __got , __expected ) ! = 0 ) { \
torture_result ( torture_ctx , TORTURE_FAIL , \
__location__ " : %s contained: \n %sExpected: %s%s \n " , \
__got , __expected , cmt ) ; \
talloc_free ( __got ) ; \
return false ; \
} \
talloc_free ( __got ) ; \
} while ( 0 )
2006-10-16 17:06:41 +04:00
# define torture_assert_int_equal(torture_ctx,got,expected,cmt)\
do { int __got = ( got ) , __expected = ( expected ) ; \
if ( __got ! = __expected ) { \
2006-10-17 23:06:50 +04:00
torture_result ( torture_ctx , TORTURE_FAIL , \
2007-08-11 21:08:22 +04:00
__location__ " : " # got " was %d, expected %d: %s " , \
__got , __expected , cmt ) ; \
2006-10-16 17:06:41 +04:00
return false ; \
} \
} while ( 0 )
2007-03-06 01:26:38 +03:00
# define torture_assert_u64_equal(torture_ctx,got,expected,cmt)\
do { uint64_t __got = ( got ) , __expected = ( expected ) ; \
if ( __got ! = __expected ) { \
torture_result ( torture_ctx , TORTURE_FAIL , \
__location__ " : " # got " was %llu, expected %llu: %s " , \
( unsigned long long ) __got , ( unsigned long long ) __expected , cmt ) ; \
return false ; \
} \
} while ( 0 )
2006-10-16 17:06:41 +04:00
# define torture_assert_errno_equal(torture_ctx,expected,cmt)\
do { int __expected = ( expected ) ; \
if ( errno ! = __expected ) { \
2006-10-17 23:06:50 +04:00
torture_result ( torture_ctx , TORTURE_FAIL , \
__location__ " : errno was %d (%s), expected %d: %s: %s " , \
errno , strerror ( errno ) , __expected , \
strerror ( __expected ) , cmt ) ; \
2006-10-16 17:06:41 +04:00
return false ; \
} \
} while ( 0 )
# define torture_skip(torture_ctx,cmt) do {\
2006-10-17 23:06:50 +04:00
torture_result ( torture_ctx , TORTURE_SKIP , __location__ " : %s " , cmt ) ; \
2006-10-16 17:06:41 +04:00
return true ; \
} while ( 0 )
# define torture_fail(torture_ctx,cmt) do {\
2006-10-17 23:06:50 +04:00
torture_result ( torture_ctx , TORTURE_FAIL , __location__ " : %s " , cmt ) ; \
2006-10-16 17:06:41 +04:00
return false ; \
} while ( 0 )
2007-03-06 00:28:55 +03:00
# define torture_fail_goto(torture_ctx,label,cmt) do {\
torture_result ( torture_ctx , TORTURE_FAIL , __location__ " : %s " , cmt ) ; \
goto label ; \
} while ( 0 )
2006-10-16 17:06:41 +04:00
# define torture_out stderr
2006-06-12 23:49:53 +04:00
2006-05-22 22:59:29 +04:00
/* Convenience macros */
2006-10-16 17:06:41 +04:00
# define torture_assert_ntstatus_ok(torture_ctx,expr,cmt) \
torture_assert_ntstatus_equal ( torture_ctx , expr , NT_STATUS_OK , cmt )
2006-05-22 22:59:29 +04:00
2006-10-16 17:06:41 +04:00
# define torture_assert_werr_ok(torture_ctx,expr,cmt) \
torture_assert_werr_equal ( torture_ctx , expr , WERR_OK , cmt )
2006-05-22 22:59:29 +04:00
2007-11-09 21:24:51 +03:00
# define torture_assert_ndr_success(torture_ctx,expr,cmt) \
torture_assert_ndr_err_equal ( torture_ctx , expr , NDR_ERR_SUCCESS , cmt )
2006-10-16 17:06:41 +04:00
/* Getting settings */
const char * torture_setting_string ( struct torture_context * test , \
const char * name ,
const char * default_value ) ;
2006-05-22 22:59:29 +04:00
2006-10-16 17:06:41 +04:00
int torture_setting_int ( struct torture_context * test ,
const char * name ,
int default_value ) ;
2007-08-28 04:16:58 +04:00
double torture_setting_double ( struct torture_context * test ,
const char * name ,
double default_value ) ;
2006-10-16 17:06:41 +04:00
bool torture_setting_bool ( struct torture_context * test ,
const char * name ,
bool default_value ) ;
2006-06-17 02:06:09 +04:00
2006-10-17 03:09:15 +04:00
struct torture_suite * torture_find_suite ( struct torture_suite * parent ,
const char * name ) ;
2008-04-02 06:53:27 +04:00
NTSTATUS torture_temp_dir ( struct torture_context * tctx ,
const char * prefix ,
char * * tempdir ) ;
struct torture_test * torture_tcase_add_simple_test ( struct torture_tcase * tcase ,
const char * name ,
bool ( * run ) ( struct torture_context * test , void * tcase_data ) ) ;
bool torture_suite_init_tcase ( struct torture_suite * suite ,
struct torture_tcase * tcase ,
const char * name ) ;
2008-11-01 02:24:55 +03:00
struct torture_context * torture_context_init ( struct event_context * event_ctx , struct torture_results * results ) ;
struct torture_results * torture_results_init ( TALLOC_CTX * mem_ctx , const struct torture_ui_ops * ui_ops ) ;
2008-04-02 06:53:27 +04:00
2008-10-31 18:37:02 +03:00
struct torture_context * torture_context_child ( struct torture_context * tctx ) ;
2008-10-23 23:30:41 +04:00
extern const struct torture_ui_ops torture_subunit_ui_ops ;
2006-06-17 02:06:09 +04:00
# endif /* __TORTURE_UI_H__ */