MOAB: Mesh Oriented datABase  (version 5.4.0)
TestUtil.hpp
Go to the documentation of this file.
00001 #ifndef TEST_UTIL_HPP
00002 #define TEST_UTIL_HPP
00003 
00004 #ifdef __cplusplus
00005 #include <string>
00006 #include <fstream>
00007 #endif
00008 #include "moab/MOABConfig.h"
00009 #ifdef MOAB_HAVE_MPI
00010 #include "moab_mpi.h"
00011 #endif
00012 
00013 /* Define these here because they are used by many tests
00014  * to find the add directory for input files */
00015 #define STRINGIFY_( X ) #X
00016 #define STRINGIFY( X )  STRINGIFY_( X )
00017 
00018 #ifdef MOAB_MESH_DIR
00019 #ifdef __cplusplus
00020 const std::string TestDir( MOAB_MESH_DIR );
00021 #else
00022 const char* TestDir = MOAB_MESH_DIR;
00023 #endif
00024 #else
00025 #error Specify MOAB_MESH_DIR to compile test
00026 #endif
00027 
00028 /* How to use this test suite utility:
00029  * 1) Write tests that use the CHECK and CHECK_* macros defined below to assert test conditions.
00030  * 2) Write a main routine that invokes each test through the RUN_TEST macro
00031  * 3) RUN_TEST evaluates to 1 if test failed, zero otherwize.  Count failures and print summary.
00032  */
00033 
00034 /** Check that A is MB_SUCCESS */
00035 #define CHECK_ERR( A ) check_equal( MB_SUCCESS, ( A ), "MB_SUCCESS", #A, __LINE__, __FILE__ )
00036 /**  Ensure that A is true */
00037 #define CHECK( A ) check_true( ( A ), #A, __LINE__, __FILE__ )
00038 /** Check that two values are equal */
00039 #define CHECK_EQUAL( EXP, ACT ) check_equal( ( EXP ), ( ACT ), #EXP, #ACT, __LINE__, __FILE__ )
00040 /** Check that two real (float or double) values are equal within EPS */
00041 #define CHECK_REAL_EQUAL( EXP, ACT, EPS ) check_equal( ( EXP ), ( ACT ), ( EPS ), #EXP, #ACT, __LINE__, __FILE__ )
00042 /** Check that two arrays contain the same values in the same order */
00043 #define CHECK_ARRAYS_EQUAL( EXP, EXP_LEN, ACT, ACT_LEN ) \
00044     check_array_equal( ( EXP ), ( EXP_LEN ), ( ACT ), ( ACT_LEN ), #EXP, #ACT, __LINE__, __FILE__ )
00045 /** Check that two CartVect objects contain same values */
00046 #define CHECK_VECREAL_EQUAL( EXP, ACT, EPS ) \
00047     check_equal_cartvect( ( EXP ), ( ACT ), ( EPS ), #EXP, #ACT, __LINE__, __FILE__ )
00048 /** Run a test
00049  *  Argument should be a function with the signature:  void func(void)
00050  *  Evaluates to zero if test is successful, one otherwise.
00051  */
00052 #define RUN_TEST( FUNC ) run_test( &( ( ( ( FUNC ) ) ) ), #FUNC )
00053 
00054 // Use C++ exceptions to return error state to test runner
00055 // Portable, but whole test suite stops if any test segfaults, asserts, etc.
00056 #define EXCEPTION_MODE 1
00057 
00058 // Test runner forks separate process for each test.
00059 // Difficult to debug tests (with debugger).  Not portable to Windows.
00060 // Very robust (no test can distrub test running code)
00061 #define FORK_MODE 2
00062 
00063 // Use signal handler and long jumps to return error state to test runner.
00064 // Might be portable to Windows (not sure).  Possibly undefined behavior (e.g. continuing
00065 // with next test after catching segfault is technically undefined behavior.)
00066 // Also, tests can corrupt heap memory management, interferring with later tests.
00067 // Leaks memory on test failure (no stack unwind).  This is actually a feature, as
00068 // we don't care too much about tests leaking memory and trying to reconver memory
00069 // might make things worse, depending on why the test failed.
00070 #define LONGJMP_MODE 3
00071 
00072 // If test application hasn't set MODE, set to default
00073 #ifndef MODE
00074 #if defined( _MSC_VER ) || defined( __MINGW32__ )
00075 #define MODE EXCEPTION_MODE
00076 #else
00077 #define MODE LONGJMP_MODE
00078 #endif
00079 #endif
00080 
00081 /***************************************************************************************
00082  * NOTE: The remainder of this file contains the implementation of the above macros.
00083  *       The above macros constitute the entire intended API.
00084  ***************************************************************************************/
00085 
00086 #include <cmath>
00087 #include <cstdio>
00088 #include <cstdlib>
00089 #include <cstring>
00090 #ifdef __cplusplus
00091 #include <iostream>
00092 #include <vector>
00093 #include <algorithm>
00094 #include <map>
00095 #endif
00096 
00097 /***************************************************************************************
00098  *                     Define What to do when a test fails.
00099  ***************************************************************************************/
00100 
00101 // For EXCEPTION_MODE, throw an exception when a test fails.
00102 // This will unwind stack, recover memory, etc.
00103 #if MODE == EXCEPTION_MODE
00104 struct ErrorExcept
00105 {
00106 };
00107 #define FLAG_ERROR throw ErrorExcept()
00108 // For FORK_MODE, the test is running in its own processs.  Just
00109 // terminate the process with a non-zero exit code when the test
00110 // fails.
00111 #elif MODE == FORK_MODE
00112 #include <sys/types.h>
00113 #include <sys/wait.h>
00114 #include <unistd.h>
00115 #include <errno.h>
00116 #define FLAG_ERROR exit( 1 )
00117 // For LONGJMP_MODE, we do a long jump to just before the test is
00118 // run, with a return value of -1 to indicate failures (positive
00119 // return codes are used if the test caused a segfault or other
00120 // signal.)
00121 #elif MODE == LONGJMP_MODE
00122 #include <csignal>
00123 #include <csetjmp>
00124 #define FLAG_ERROR siglongjmp( jmpenv, -1 )
00125 #else
00126 #error "MODE not set"
00127 #endif
00128 
00129 /***************************************************************************************
00130  *                              Setup for LONGJMP_MODE
00131  ***************************************************************************************/
00132 
00133 #if MODE == LONGJMP_MODE
00134 
00135 // Variable to hold stack state for longjmp
00136 sigjmp_buf jmpenv;
00137 
00138 // Define signal handler used to catch errors such as segfaults.
00139 // Signal handler does longjmp with the signal number as the
00140 // return value.
00141 extern "C" {
00142 void sighandler( int sig )
00143 {
00144     signal( sig, sighandler );
00145     siglongjmp( jmpenv, sig );
00146     // should never return from longjmp
00147     exit( 1 );
00148 }
00149 typedef void ( *sigfunc_t )( int );
00150 }  // extern "C"
00151 
00152 // Helper function to register signal handlers.
00153 int sethandler( int sig )
00154 {
00155     sigfunc_t h = signal( sig, &sighandler );
00156     if( h == SIG_ERR ) return 1;
00157     // If user-defined signal handler (or signal is ignored),
00158     // than unregister our handler.
00159     else if( h != SIG_DFL )
00160         signal( sig, h );
00161     return 0;
00162 }
00163 
00164 // Register signal handlers for all defined signals that typicall result
00165 // in process termination.
00166 int init_signal_handlers()
00167 {
00168     int result = 0;
00169     /* Don't trap these.  It is unlikely that a test would ever generate such
00170        a signal on its own and trapping them interfers with a user's ability
00171        to stop a test.  SIGHUP implies that the controlling terminal was closed.
00172        If the user does ctrl-C or ctrl-\ (SIGINT and SIGQUIT, respectively) and
00173        we trap these then just the current test stops.  If we leave the default
00174        behavior for them then the whole test suite stops.  The latter is likely
00175        the desired behavior.  SIGTERM is the default signal sent by the 'kill'
00176        command.
00177     #ifdef SIGHUP
00178       result += sethandler( SIGHUP );
00179     #endif
00180     #ifdef SIGINT
00181       result += sethandler( SIGINT );
00182     #endif
00183     #ifdef SIGQUIT
00184       result += sethandler( SIGQUIT );
00185     #endif
00186     #ifdef SIGTERM
00187       result += sethandler( SIGTERM );
00188     #endif
00189     */
00190 
00191 #ifdef SIGILL
00192     result += sethandler( SIGILL );
00193 #endif
00194 #ifdef SIGTRAP
00195     result += sethandler( SIGTRAP );
00196 #endif
00197 #ifdef SIGABRT
00198     result += sethandler( SIGABRT );
00199 #endif
00200 #ifdef SIGBUS
00201     result += sethandler( SIGBUS );
00202 #endif
00203 #ifdef SIGFPE
00204     result += sethandler( SIGFPE );
00205 #endif
00206 #ifdef SIGSEGV
00207     result += sethandler( SIGSEGV );
00208 #endif
00209 
00210     /* Catching these causes problems with mpich2 1.3.1p1 and a
00211        test should never receive such a signal anyway.
00212     #ifdef SIGUSR1
00213       result += sethandler( SIGUSR1 );
00214     #endif
00215     #ifdef SIGUSR2
00216       result += sethandler( SIGUSR2 );
00217     #endif
00218     */
00219 
00220     /* Don't trap SIGCHLD.  The only way a test should receive
00221        such a signal is if it actually forked a child process.
00222        That is unlikely, but if it does happen the test probably
00223        wants to handle the signal itself.
00224     #ifdef SIGCHLD
00225       result += sethandler( SIGCHLD );
00226     #endif
00227     */
00228 
00229 #ifdef SIGPIPE
00230     result += sethandler( SIGPIPE );
00231 #endif
00232 #ifdef SIGIO
00233     result += sethandler( SIGIO );
00234 #endif
00235 #ifdef SIGSYS
00236     result += sethandler( SIGSYS );
00237 #endif
00238     return result;
00239 }
00240 
00241 // Declare a garbage global variable.  Use variable initialization to
00242 // force call to init_signal_handlers().
00243 int junk_init_var = init_signal_handlers();
00244 
00245 #endif  // LONGJMP_MODE
00246 
00247 /***************************************************************************************
00248  *                            Function to handle failed tests
00249  ***************************************************************************************/
00250 
00251 // use a function rather than substituting FLAG_ERROR directly
00252 // so we have a convenient place to set a break point
00253 inline void flag_error()
00254 {
00255     FLAG_ERROR;
00256 }
00257 
00258 /***************************************************************************************
00259  *                            The Code to Run Tests
00260  ***************************************************************************************/
00261 
00262 /* Make sure IS_BUILDING_MB is defined so we can include MBInternals.hpp */
00263 #include "moab/Types.hpp"
00264 #ifndef IS_BUILDING_MB
00265 #define IS_BUILDING_MB
00266 #include "Internals.hpp"
00267 #undef IS_BUILDING_MB
00268 #else
00269 #include "Internals.hpp"
00270 #endif
00271 
00272 #ifndef TEST_USES_ERR_CODES
00273 typedef void ( *test_func )( void );
00274 int run_test( test_func test, const char* func_name )
00275 #else
00276 typedef moab::ErrorCode ( *test_func_err )( void );
00277 int run_test( test_func_err test, const char* func_name )
00278 #endif
00279 {
00280     // check if we are running parallel MPI tests
00281     int rank = 0;
00282 #ifdef MOAB_HAVE_MPI
00283     int isInit;
00284     MPI_Initialized( &isInit );
00285     if( isInit )
00286     {
00287         MPI_Comm_rank( MPI_COMM_WORLD, &rank );
00288     }
00289 #endif
00290 
00291     if( rank == 0 ) printf( "Running %s ...\n", func_name );
00292 
00293 #if MODE == EXCEPTION_MODE
00294     /* On Windows, run all tests in same process.
00295        Flag errors by throwing an exception.
00296      */
00297     try
00298     {
00299         ( *test )();
00300         return 0;
00301     }
00302     catch( ErrorExcept )
00303     {
00304         printf( "[%d]  %s: FAILED\n", rank, func_name );
00305         return 1;
00306     }
00307     catch( ... )
00308     {
00309         printf( "[%d]  %s: UNCAUGHT EXCEPTION\n", rank, func_name );
00310         return 1;
00311     }
00312 
00313 #elif MODE == FORK_MODE
00314     /* For non-Windows OSs, fork() and run test in child process. */
00315     pid_t pid = fork();
00316     int status;
00317 
00318     /* Fork failed? */
00319     if( pid == -1 )
00320     {
00321         perror( "fork()" );
00322         abort(); /* abort all tests (can't fork child processes) */
00323     }
00324 
00325     /* If child process*/
00326     if( pid == 0 )
00327     {
00328         ( *test )(); /* call test function */
00329         exit( 0 );   /* if function returned, then it succeeded */
00330     }
00331 
00332     /* If here, then parent process */
00333 
00334     /* Wait until child process exits */
00335     waitpid( pid, &status, 0 );
00336 
00337     /* Check child exit status */
00338     if( WIFSIGNALED( status ) )
00339     {
00340         if( WTERMSIG( status ) ) printf( "  %s: TERMINATED (signal %d)\n", func_name, (int)WTERMSIG( status ) );
00341         if( WCOREDUMP( status ) ) printf( "  %s: CORE DUMP\n", func_name );
00342         return 1;
00343     }
00344     else if( WEXITSTATUS( status ) )
00345     {
00346         printf( "  %s: FAILED\n", func_name );
00347         return 1;
00348     }
00349     else
00350     {
00351         return 0;
00352     }
00353 
00354 #elif MODE == LONGJMP_MODE
00355     // Save stack state at this location.
00356     int rval = sigsetjmp( jmpenv, 1 );
00357     // If rval is zero, then we haven't run the test yet.
00358     // If rval is non-zero then
00359     // a) we ran the test
00360     // b) the test failed
00361     // c) we did a longjmp back to the location where we called setsigjmp.
00362 
00363     // run test
00364     if( !rval )
00365     {
00366         ( *test )();
00367         return 0;
00368     }
00369     // some check failed
00370     else if( rval == -1 )
00371     {
00372         printf( "  %s: FAILED\n", func_name );
00373         return 1;
00374     }
00375     // a signal was raised (e.g. segfault)
00376     else
00377     {
00378         printf( "  %s: TERMINATED (signal %d)\n", func_name, rval );
00379         return 1;
00380     }
00381 #else
00382 #error "MODE not set"
00383 #endif  // MODE
00384 }
00385 
00386 /***************************************************************************************
00387  *                            CHECK_EQUAL implementations
00388  ***************************************************************************************/
00389 
00390 // Common implementatation for most types
00391 #define EQUAL_TEST_IMPL( TEST, TYPE )                         \
00392     if( !( TEST ) )                                           \
00393     {                                                         \
00394         printf( "Equality Test Failed: %s == %s\n", sA, sB ); \
00395         printf( "  at line %d of '%s'\n", line, file );       \
00396         printf( "  Expected value: %" #TYPE "\n", A );        \
00397         printf( "  Actual value:   %" #TYPE "\n", B );        \
00398         printf( "\n" );                                       \
00399         flag_error();                                         \
00400     }
00401 
00402 void check_equal( int A, int B, const char* sA, const char* sB, int line, const char* file )
00403 {
00404     EQUAL_TEST_IMPL( A == B, d )
00405 }
00406 
00407 void check_equal( unsigned A, unsigned B, const char* sA, const char* sB, int line, const char* file )
00408 {
00409     EQUAL_TEST_IMPL( A == B, u )
00410 }
00411 
00412 void check_equal( long A, long B, const char* sA, const char* sB, int line, const char* file )
00413 {
00414     EQUAL_TEST_IMPL( A == B, ld )
00415 }
00416 
00417 void check_equal( unsigned long A, unsigned long B, const char* sA, const char* sB, int line, const char* file )
00418 {
00419     EQUAL_TEST_IMPL( A == B, lu )
00420 }
00421 
00422 void check_equal( unsigned long long A,
00423                   unsigned long long B,
00424                   const char* sA,
00425                   const char* sB,
00426                   int line,
00427                   const char* file )
00428 {
00429     EQUAL_TEST_IMPL( A == B, llu )
00430 }
00431 
00432 void check_equal( long long A, long long B, const char* sA, const char* sB, int line, const char* file )
00433 {
00434     EQUAL_TEST_IMPL( A == B, lld )
00435 }
00436 
00437 void check_equal( void* A, void* B, const char* sA, const char* sB, int line, const char* file )
00438 {
00439     EQUAL_TEST_IMPL( A == B, p )
00440 }
00441 
00442 void check_equal( const char* A, const char* B, const char* sA, const char* sB, int line, const char* file )
00443 {
00444     EQUAL_TEST_IMPL( !strcmp( ( A ), ( B ) ), s )
00445 }
00446 
00447 void check_equal( const std::string& A,
00448                   const std::string& B,
00449                   const char* sA,
00450                   const char* sB,
00451                   int line,
00452                   const char* file )
00453 {
00454     check_equal( A.c_str(), B.c_str(), sA, sB, line, file );
00455 }
00456 
00457 void check_equal( float A, float B, float eps, const char* sA, const char* sB, int line, const char* file )
00458 {
00459     EQUAL_TEST_IMPL( fabsf( A - B ) <= eps, f )
00460 }
00461 
00462 void check_equal( double A, double B, double eps, const char* sA, const char* sB, int line, const char* file )
00463 {
00464     EQUAL_TEST_IMPL( fabs( A - B ) <= eps, f )
00465 }
00466 
00467 const char* mb_error_str( moab::ErrorCode err )
00468 {
00469     switch( err )
00470     {
00471         case moab::MB_SUCCESS:
00472             return "Success";
00473         case moab::MB_INDEX_OUT_OF_RANGE:
00474             return "Index Out of Range";
00475         case moab::MB_TYPE_OUT_OF_RANGE:
00476             return "Type Out of Range";
00477         case moab::MB_MEMORY_ALLOCATION_FAILED:
00478             return "Memory Alloc. Failed";
00479         case moab::MB_ENTITY_NOT_FOUND:
00480             return "Entity Not Found";
00481         case moab::MB_MULTIPLE_ENTITIES_FOUND:
00482             return "Multiple Entities Found";
00483         case moab::MB_TAG_NOT_FOUND:
00484             return "Tag Not Found";
00485         case moab::MB_FILE_DOES_NOT_EXIST:
00486             return "File Not Found";
00487         case moab::MB_FILE_WRITE_ERROR:
00488             return "File Write Error";
00489         case moab::MB_NOT_IMPLEMENTED:
00490             return "Not Implemented";
00491         case moab::MB_ALREADY_ALLOCATED:
00492             return "Already Allocated";
00493         case moab::MB_VARIABLE_DATA_LENGTH:
00494             return "Variable Data Length";
00495         case moab::MB_INVALID_SIZE:
00496             return "Invalid Size";
00497         case moab::MB_UNSUPPORTED_OPERATION:
00498             return "Unsupported Operation";
00499         case moab::MB_UNHANDLED_OPTION:
00500             return "Unhandled Option";
00501         case moab::MB_STRUCTURED_MESH:
00502             return "Structured Mesh";
00503         case moab::MB_FAILURE:
00504             return "Failure";
00505         default:
00506             return "(unknown)";
00507     }
00508 }
00509 
00510 // Special case for MBErrorCode, use mb_error_str() to print the
00511 // string name of the error code.
00512 void check_equal( moab::ErrorCode A, moab::ErrorCode B, const char* sA, const char* sB, int line, const char* file )
00513 {
00514     if( A == B ) return;
00515 
00516     printf( "ErrorCode Test Failed: %s == %s\n", sA, sB );
00517     printf( "  at line %d of '%s'\n", line, file );
00518     printf( "  Expected value: %s (%d)\n", mb_error_str( A ), (int)A );
00519     printf( "  Actual value:   %s (%d)\n", mb_error_str( B ), (int)B );
00520     printf( "\n" );
00521     flag_error();
00522 }
00523 
00524 const char* mb_type_str( moab::EntityType type )
00525 {
00526     switch( type )
00527     {
00528         case moab::MBVERTEX:
00529             return "Vertex";
00530         case moab::MBEDGE:
00531             return "Edge";
00532         case moab::MBTRI:
00533             return "Triangle";
00534         case moab::MBQUAD:
00535             return "Quadrilateral";
00536         case moab::MBPOLYGON:
00537             return "Polygon";
00538         case moab::MBTET:
00539             return "Tetrahedron";
00540         case moab::MBPYRAMID:
00541             return "Pyramid";
00542         case moab::MBPRISM:
00543             return "Prism (wedge)";
00544         case moab::MBKNIFE:
00545             return "Knife";
00546         case moab::MBHEX:
00547             return "Hexahedron";
00548         case moab::MBPOLYHEDRON:
00549             return "Polyhedron";
00550         case moab::MBENTITYSET:
00551             return "Entity (Mesh) Set";
00552         case moab::MBMAXTYPE:
00553             return "(max type)";
00554         default:
00555             return "(unknown)";
00556     }
00557 }
00558 
00559 const char* mb_type_str( moab::EntityHandle a )
00560 {
00561     return mb_type_str( moab::TYPE_FROM_HANDLE( a ) );
00562 }
00563 /*
00564 void check_equal( moab::EntityHandle A, moab::EntityHandle B, const char* sA, const char* sB, int line, const char* file
00565 )
00566 {
00567   if (A == B)
00568     return;
00569 
00570   printf( "Entity handles not equal: %s == %s\n", sA, sB );
00571   printf( "  at line %d of '%s'\n", line, file );
00572   if (A)
00573     printf( "  Expected value: %lx (%s %ld)\n", (unsigned long)A, mb_type_str( A ), (long)ID_FROM_HANDLE(A) );
00574   else
00575     printf( "  Expected value: 0\n" );
00576   if (B)
00577     printf( "  Actual value:   %lx (%s %ld)\n", (unsigned long)B, mb_type_str( B ), (long)ID_FROM_HANDLE(B) );
00578   else
00579     printf( "  Actual value: 0\n" );
00580   printf( "\n" );
00581   flag_error();
00582 }
00583 */
00584 
00585 void check_true( bool cond, const char* str, int line, const char* file )
00586 {
00587     if( !cond )
00588     {
00589         printf( "Test Failed: %s\n", str );
00590         printf( "  at line %d of '%s'\n", line, file );
00591         printf( "\n" );
00592         flag_error();
00593     }
00594 }
00595 
00596 #ifdef MB_CART_VECT_HPP
00597 
00598 void check_equal_cartvect( const moab::CartVect& A,
00599                            const moab::CartVect& B,
00600                            double eps,
00601                            const char* sA,
00602                            const char* sB,
00603                            int line,
00604                            const char* file )
00605 {
00606     check_equal( A.length(), B.length(), eps, sA, sB, line, file );
00607 
00608     if( fabs( A[0] - B[0] ) <= eps && fabs( A[1] - B[1] ) <= eps && fabs( A[2] - B[2] ) <= eps ) return;
00609 
00610     std::cout << "Equality Test Failed: " << sA << " == " << sB << std::endl;
00611     std::cout << "  at line " << line << " of '" << file << "'" << std::endl;
00612 
00613     std::cout << "  Expected: ";
00614     std::cout << A << std::endl;
00615 
00616     std::cout << "  Actual:   ";
00617     std::cout << B << std::endl;
00618 
00619     flag_error();
00620 }
00621 
00622 #endif  // #ifdef MB_CART_VECT_HPP
00623 
00624 #ifdef __cplusplus
00625 
00626 template < typename T >
00627 void check_array_equal( const T* A,
00628                         size_t A_size,
00629                         const T* B,
00630                         size_t B_size,
00631                         const char* sA,
00632                         const char* sB,
00633                         int line,
00634                         const char* file )
00635 {
00636     size_t i = 0;
00637     for( ;; )
00638     {
00639         if( i == A_size && i == B_size )
00640             return;  // equal
00641         else if( i == A_size || i == B_size )
00642             break;  // differene lengths
00643         else if( A[i] != B[i] )
00644             break;
00645         ++i;
00646     }
00647 
00648     std::cout << "Equality Test Failed: " << sA << " == " << sB << std::endl;
00649     std::cout << "  at line " << line << " of '" << file << "'" << std::endl;
00650     std::cout << "  Vectors differ at position " << i << std::endl;
00651 
00652     // print at most 10 values, roughly centered on the unequal one
00653     size_t count = 10, num_front_values = std::min( count / 2, i );
00654     size_t max_len = std::max( A_size, B_size );
00655     if( i + count - num_front_values > max_len )
00656     {
00657         if( count > max_len )
00658         {
00659             num_front_values = i;
00660             count            = max_len;
00661         }
00662         else
00663         {
00664             num_front_values = count - ( max_len - i );
00665         }
00666     }
00667 
00668     std::cout << "  Expected: ";
00669     if( !A_size )
00670     {
00671         std::cout << "(empty)" << std::endl;
00672     }
00673     else
00674     {
00675         size_t j   = i - num_front_values;
00676         size_t end = std::min( j + count, A_size );
00677         if( j ) std::cout << "... ";
00678         for( ; j < end; ++j )
00679         {
00680             if( j == i )
00681                 std::cout << '>' << A[j] << "< ";
00682             else
00683                 std::cout << A[j] << " ";
00684         }
00685         if( end != A_size ) std::cout << "...";
00686         std::cout << std::endl;
00687     }
00688 
00689     std::cout << "  Actual:   ";
00690     if( !B_size )
00691     {
00692         std::cout << "(empty)" << std::endl;
00693     }
00694     else
00695     {
00696         size_t j   = i - num_front_values;
00697         size_t end = std::min( j + count, B_size );
00698         if( j ) std::cout << "... ";
00699         for( ; j < end; ++j )
00700         {
00701             if( j == i )
00702                 std::cout << '>' << B[j] << "< ";
00703             else
00704                 std::cout << B[j] << " ";
00705         }
00706         if( end != B_size ) std::cout << ", ...";
00707         std::cout << std::endl;
00708     }
00709 
00710     flag_error();
00711 }
00712 
00713 template < typename T >
00714 void check_equal( const std::vector< T >& A,
00715                   const std::vector< T >& B,
00716                   const char* sA,
00717                   const char* sB,
00718                   int line,
00719                   const char* file )
00720 {
00721     if( A.empty() || B.empty() )
00722     {
00723         if( A.size() != B.size() )
00724         {
00725             std::cout << "Equality Test Failed: " << sA << " == " << sB << std::endl;
00726             std::cout << "  at line " << line << " of '" << file << "'" << std::endl;
00727             std::cout << "  Both are not empty " << std::endl;
00728         }
00729         return;
00730     }
00731     check_array_equal( &A[0], A.size(), &B[0], B.size(), sA, sB, line, file );
00732 }
00733 
00734 #ifdef MOAB_RANGE_HPP
00735 
00736 void check_equal( const moab::Range& A,
00737                   const moab::Range& B,
00738                   const char* sA,
00739                   const char* sB,
00740                   int line,
00741                   const char* file )
00742 {
00743     if( A == B ) return;
00744 
00745     std::cout << "moab::ErrorCode Test Failed: " << sA << " == " << sB << std::endl;
00746     std::cout << "  at line " << line << " of '" << file << "'" << std::endl;
00747     std::cout << "   Expected: " << A << std::endl;
00748     std::cout << "   Actual  : " << B << std::endl;
00749     std::cout << std::endl;
00750     flag_error();
00751 }
00752 
00753 #endif  // #ifdef MOAB_RANGE_HPP
00754 
00755 void check_baseline_file( std::string basefile,
00756                           std::vector< int >& gids,
00757                           std::vector< double >& vals,
00758                           double eps,
00759                           int& err_code )
00760 {
00761     err_code = 1;
00762     std::fstream fs;
00763     fs.open( basefile.c_str(), std::fstream::in );
00764     if( !fs.is_open() )
00765     {
00766         std::cout << " error opening base file  " << basefile << "\n";
00767         flag_error();
00768         return;
00769     }
00770     std::map< int, double > mapVals;
00771     int id     = 0;
00772     double val = 0;
00773     while( !fs.eof() )
00774     {
00775         fs >> id >> val;
00776         mapVals[id] = val;
00777     }
00778     for( size_t i = 0; i < gids.size(); i++ )
00779     {
00780         std::map< int, double >::iterator it = mapVals.find( gids[i] );
00781         if( it == mapVals.end() )
00782         {
00783             std::cout << "id - value not found:" << gids[i] << "\n";
00784             flag_error();
00785             return;
00786         }
00787         if( fabs( it->second - vals[i] ) > eps )
00788         {
00789             std::cout << " value out of range: index i=" << i << " id: " << gids[i] << "  value:" << vals[i]
00790                       << " expected : " << it->second << "\n";
00791             flag_error();
00792             return;
00793         }
00794     }
00795     err_code = 0;  // no error
00796 }
00797 #endif /* ifdef __cplusplus */
00798 
00799 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines