lasso
TestUtil.hpp File Reference
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <signal.h>
#include <setjmp.h>

Go to the source code of this file.

Defines

#define STRINGIFY_(X)   #X
#define STRINGIFY(X)   STRINGIFY_(X)
#define CHECK_ERR(A)   check_equal( iBase_SUCCESS, (A), "iBase_SUCCESS", #A, __LINE__, __FILE__ )
#define CHECK(A)   check_true( (A), #A, __LINE__, __FILE__ )
#define CHECK_EQUAL(EXP, ACT)   check_equal( (EXP), (ACT), #EXP, #ACT, __LINE__, __FILE__ )
#define CHECK_REAL_EQUAL(EXP, ACT, EPS)   check_equal( (EXP), (ACT), (EPS), #EXP, #ACT, __LINE__, __FILE__ )
#define CHECK_ARRAYS_EQUAL(EXP, EXP_LEN, ACT, ACT_LEN)   check_array_equal( (EXP), (EXP_LEN), (ACT), (ACT_LEN), #EXP, #ACT, __LINE__, __FILE__ )
#define RUN_TEST(FUNC)   run_test( &FUNC, #FUNC )
#define EXCEPTION_MODE   1
#define FORK_MODE   2
#define LONGJMP_MODE   3
#define FLAG_ERROR   siglongjmp( jmpenv, -1 )
#define EQUAL_TEST_IMPL(TEST, TYPE)

Typedefs

typedef void(* sigfunc_t )(int)
typedef void(* test_func )(void)

Functions

void sighandler (int sig)
int sethandler (int sig)
int init_signal_handlers ()
void flag_error ()
int run_test (test_func test, const char *func_name)
void check_equal (int A, int B, const char *sA, const char *sB, int line, const char *file)
void check_equal (unsigned A, unsigned B, const char *sA, const char *sB, int line, const char *file)
void check_equal (long A, long B, const char *sA, const char *sB, int line, const char *file)
void check_equal (unsigned long A, unsigned long B, const char *sA, const char *sB, int line, const char *file)
void check_equal (void *A, void *B, const char *sA, const char *sB, int line, const char *file)
void check_equal (const char *A, const char *B, const char *sA, const char *sB, int line, const char *file)
void check_equal (const std::string &A, const std::string &B, const char *sA, const char *sB, int line, const char *file)
void check_equal (float A, float B, float eps, const char *sA, const char *sB, int line, const char *file)
void check_equal (double A, double B, float eps, const char *sA, const char *sB, int line, const char *file)
void check_true (bool cond, const char *str, int line, const char *file)

Variables

sigjmp_buf jmpenv
int junk_init_var = init_signal_handlers()

Define Documentation

#define CHECK (   A)    check_true( (A), #A, __LINE__, __FILE__ )

Ensure that A is true

Definition at line 18 of file TestUtil.hpp.

#define CHECK_ARRAYS_EQUAL (   EXP,
  EXP_LEN,
  ACT,
  ACT_LEN 
)    check_array_equal( (EXP), (EXP_LEN), (ACT), (ACT_LEN), #EXP, #ACT, __LINE__, __FILE__ )

Check that two arrays contain the same values in the same order

Definition at line 24 of file TestUtil.hpp.

#define CHECK_EQUAL (   EXP,
  ACT 
)    check_equal( (EXP), (ACT), #EXP, #ACT, __LINE__, __FILE__ )

Check that two values are equal

Definition at line 20 of file TestUtil.hpp.

#define CHECK_ERR (   A)    check_equal( iBase_SUCCESS, (A), "iBase_SUCCESS", #A, __LINE__, __FILE__ )

Check that A is MB_SUCCESS

Definition at line 16 of file TestUtil.hpp.

#define CHECK_REAL_EQUAL (   EXP,
  ACT,
  EPS 
)    check_equal( (EXP), (ACT), (EPS), #EXP, #ACT, __LINE__, __FILE__ )

Check that two real (float or double) values are equal within EPS

Definition at line 22 of file TestUtil.hpp.

#define EQUAL_TEST_IMPL (   TEST,
  TYPE 
)
Value:
if( !(TEST) ) { \
  printf( "Equality Test Failed: %s == %s\n", sA, sB ); \
  printf( "  at line %d of '%s'\n", line, file ); \
  printf( "  Expected value: %" #TYPE "\n", A ); \
  printf( "  Actual value:   %" #TYPE "\n", B ); \
  printf( "\n" ); \
  flag_error(); \
}

Definition at line 335 of file TestUtil.hpp.

#define EXCEPTION_MODE   1

Definition at line 34 of file TestUtil.hpp.

#define FLAG_ERROR   siglongjmp( jmpenv, -1 )

Definition at line 101 of file TestUtil.hpp.

#define FORK_MODE   2

Definition at line 39 of file TestUtil.hpp.

#define LONGJMP_MODE   3

Definition at line 48 of file TestUtil.hpp.

#define RUN_TEST (   FUNC)    run_test( &FUNC, #FUNC )

Run a test Argument should be a function with the signature: void func(void) Evaluates to zero if test is successful, one otherwise.

Definition at line 29 of file TestUtil.hpp.

#define STRINGIFY (   X)    STRINGIFY_(X)

Definition at line 7 of file TestUtil.hpp.

#define STRINGIFY_ (   X)    #X

Definition at line 6 of file TestUtil.hpp.


Typedef Documentation

typedef void(* sigfunc_t)(int)

Definition at line 125 of file TestUtil.hpp.

typedef void(* test_func)(void)

Definition at line 239 of file TestUtil.hpp.


Function Documentation

void check_equal ( int  A,
int  B,
const char *  sA,
const char *  sB,
int  line,
const char *  file 
)

Definition at line 344 of file TestUtil.hpp.

  {  EQUAL_TEST_IMPL( A == B, d ) }
void check_equal ( unsigned  A,
unsigned  B,
const char *  sA,
const char *  sB,
int  line,
const char *  file 
)

Definition at line 347 of file TestUtil.hpp.

  {  EQUAL_TEST_IMPL( A == B, u ) }
void check_equal ( long  A,
long  B,
const char *  sA,
const char *  sB,
int  line,
const char *  file 
)

Definition at line 350 of file TestUtil.hpp.

  {  EQUAL_TEST_IMPL( A == B, ld ) }
void check_equal ( unsigned long  A,
unsigned long  B,
const char *  sA,
const char *  sB,
int  line,
const char *  file 
)

Definition at line 353 of file TestUtil.hpp.

  {  EQUAL_TEST_IMPL( A == B, lu ) }
void check_equal ( void *  A,
void *  B,
const char *  sA,
const char *  sB,
int  line,
const char *  file 
)

Definition at line 356 of file TestUtil.hpp.

  {  EQUAL_TEST_IMPL( A == B, p ) }
void check_equal ( const char *  A,
const char *  B,
const char *  sA,
const char *  sB,
int  line,
const char *  file 
)

Definition at line 359 of file TestUtil.hpp.

  {  EQUAL_TEST_IMPL( !strcmp((A),(B)), s ) }
void check_equal ( const std::string &  A,
const std::string &  B,
const char *  sA,
const char *  sB,
int  line,
const char *  file 
)

Definition at line 362 of file TestUtil.hpp.

  {  check_equal( A.c_str(), B.c_str(), sA, sB, line, file); }
void check_equal ( float  A,
float  B,
float  eps,
const char *  sA,
const char *  sB,
int  line,
const char *  file 
)

Definition at line 365 of file TestUtil.hpp.

  {  EQUAL_TEST_IMPL( fabsf(A - B) <= eps, f ) }
void check_equal ( double  A,
double  B,
float  eps,
const char *  sA,
const char *  sB,
int  line,
const char *  file 
)

Definition at line 368 of file TestUtil.hpp.

  {  EQUAL_TEST_IMPL( fabs(A - B) <= eps, f ) }
void check_true ( bool  cond,
const char *  str,
int  line,
const char *  file 
)

Definition at line 371 of file TestUtil.hpp.

{
  if( !cond ) { 
    printf( "Test Failed: %s\n", str ); 
    printf( "  at line %d of '%s'\n", line, file ); 
    printf( "\n" ); 
    flag_error(); 
  }
}
void flag_error ( ) [inline]

Definition at line 230 of file TestUtil.hpp.

  { FLAG_ERROR; }

Definition at line 142 of file TestUtil.hpp.

{
  int result = 0;
/* Don't trap these.  It is unlikely that a test would ever generate such 
   a signal on its own and trapping them interfers with a user's ability 
   to stop a test.  SIGHUP implies that the controlling terminal was closed.  
   If the user does ctrl-C or ctrl-\ (SIGINT and SIGQUIT, respectively) and
   we trap these then just the current test stops.  If we leave the default
   behavior for them then the whole test suite stops.  The latter is likely 
   the desired behavior.  SIGTERM is the default signal sent by the 'kill'
   command.
#ifdef SIGHUP
  result += sethandler( SIGHUP );
#endif
#ifdef SIGINT
  result += sethandler( SIGINT );
#endif
#ifdef SIGQUIT
  result += sethandler( SIGQUIT );
#endif
#ifdef SIGTERM
  result += sethandler( SIGTERM );
#endif
*/

#ifdef SIGILL
  result += sethandler( SIGILL );
#endif
#ifdef SIGTRAP
  result += sethandler( SIGTRAP );
#endif
#ifdef SIGABRT
  result += sethandler( SIGABRT );
#endif
#ifdef SIGBUS
  result += sethandler( SIGBUS );
#endif
#ifdef SIGFPE
  result += sethandler( SIGFPE );
#endif
#ifdef SIGSEGV
  result += sethandler( SIGSEGV );
#endif

/* Catching these causes problems with mpich2 1.3.1p1 and a
   test should never receive such a signal anyway.
#ifdef SIGUSR1
  result += sethandler( SIGUSR1 );
#endif
#ifdef SIGUSR2
  result += sethandler( SIGUSR2 );
#endif
*/

/* Don't trap SIGCHLD.  The only way a test should receive
   such a signal is if it actually forked a child process.
   That is unlikely, but if it does happen the test probably
   wants to handle the signal itself.
#ifdef SIGCHLD
  result += sethandler( SIGCHLD );
#endif
*/

#ifdef SIGPIPE
  result += sethandler( SIGPIPE );
#endif
#ifdef SIGIO
  result += sethandler( SIGIO );
#endif
#ifdef SIGSYS
  result += sethandler( SIGSYS );
#endif
  return result;
}
int run_test ( test_func  test,
const char *  func_name 
)

Definition at line 240 of file TestUtil.hpp.

{
  printf("Running %s ...\n", func_name );
  
#if MODE == EXCEPTION_MODE
  /* On Windows, run all tests in same process.
     Flag errors by throwing an exception.
   */
  try {
    (*test)();
    return 0;
  }
  catch (ErrorExcept) {
    printf( "  %s: FAILED\n", func_name );
    return 1;
  }
  catch (...) {
    printf( "  %s: UNCAUGHT EXCEPTION\n", func_name );
    return 1;
  }
    
#elif MODE == FORK_MODE
    /* For non-Windows OSs, fork() and run test in child process. */
  pid_t pid = fork();
  int status;
  
    /* Fork failed? */
  if (pid == -1) {  
    perror( "fork()" );
    abort(); /* abort all tests (can't fork child processes) */
  }
  
    /* If child process*/
  if (pid == 0) {
    (*test)();  /* call test function */
    exit(0);    /* if function returned, then it succeeded */
  }
  
    /* If here, then parent process */
    
    /* Wait until child process exits */
  waitpid( pid, &status, 0 );
  
    /* Check child exit status */
  if (WIFSIGNALED(status)) {
    if (WTERMSIG(status))
      printf("  %s: TERMINATED (signal %d)\n", func_name, (int)WTERMSIG(status) );
    if (WCOREDUMP(status))
      printf("  %s: CORE DUMP\n", func_name);
    return 1;
  }
  else if(WEXITSTATUS(status)) {
    printf( "  %s: FAILED\n", func_name );
    return 1;
  }
  else {
    return 0;
  }
  
#elif MODE == LONGJMP_MODE
    // Save stack state at this location.
  int rval = sigsetjmp( jmpenv, 1 );
    // If rval is zero, then we haven't run the test yet. 
    // If rval is non-zero then
    // a) we ran the test
    // b) the test failed
    // c) we did a longjmp back to the location where we called setsigjmp.
    
    // run test
  if (!rval) {
    (*test)();
    return 0;
  }
    // some check failed
  else if (rval == -1) {
    printf( "  %s: FAILED\n", func_name );
    return 1;
  }
    // a signal was raised (e.g. segfault)
  else {
    printf( "  %s: TERMINATED (signal %d)\n", func_name, rval );
    return 1;
  }
#else
  #error "MODE not set"
#endif // MODE
}
int sethandler ( int  sig)

Definition at line 129 of file TestUtil.hpp.

                          {
  sigfunc_t h = signal( sig, &sighandler );
  if (h == SIG_ERR)
    return  1;
   // If user-defined signal handler (or signal is ignored),
   // than unregister our handler.
  else if (h != SIG_DFL)
    signal( sig, h );
  return 0;
}
void sighandler ( int  sig)

Definition at line 119 of file TestUtil.hpp.

                             {
    signal( sig, sighandler );
    siglongjmp(jmpenv, sig);
    // should never return from longjmp
    exit(1);
  }

Variable Documentation

sigjmp_buf jmpenv

Definition at line 113 of file TestUtil.hpp.

Definition at line 219 of file TestUtil.hpp.

 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines