MOAB: Mesh Oriented datABase  (version 5.3.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 "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 MESHDIR
00019 #ifdef __cplusplus
00020 const std::string TestDir( STRINGIFY( MESHDIR ) );
00021 #else
00022 const char* TestDir = STRINGIFY( MESHDIR );
00023 #endif
00024 #else
00025 #error Specify MESHDIR 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 ) { MPI_Comm_rank( MPI_COMM_WORLD, &rank ); }
00286 #endif
00287 
00288     if( rank == 0 ) printf( "Running %s ...\n", func_name );
00289 
00290 #if MODE == EXCEPTION_MODE
00291     /* On Windows, run all tests in same process.
00292        Flag errors by throwing an exception.
00293      */
00294     try
00295     {
00296         ( *test )();
00297         return 0;
00298     }
00299     catch( ErrorExcept )
00300     {
00301         printf( "[%d]  %s: FAILED\n", rank, func_name );
00302         return 1;
00303     }
00304     catch( ... )
00305     {
00306         printf( "[%d]  %s: UNCAUGHT EXCEPTION\n", rank, func_name );
00307         return 1;
00308     }
00309 
00310 #elif MODE == FORK_MODE
00311     /* For non-Windows OSs, fork() and run test in child process. */
00312     pid_t pid = fork();
00313     int status;
00314 
00315     /* Fork failed? */
00316     if( pid == -1 )
00317     {
00318         perror( "fork()" );
00319         abort(); /* abort all tests (can't fork child processes) */
00320     }
00321 
00322     /* If child process*/
00323     if( pid == 0 )
00324     {
00325         ( *test )(); /* call test function */
00326         exit( 0 );   /* if function returned, then it succeeded */
00327     }
00328 
00329     /* If here, then parent process */
00330 
00331     /* Wait until child process exits */
00332     waitpid( pid, &status, 0 );
00333 
00334     /* Check child exit status */
00335     if( WIFSIGNALED( status ) )
00336     {
00337         if( WTERMSIG( status ) ) printf( "  %s: TERMINATED (signal %d)\n", func_name, (int)WTERMSIG( status ) );
00338         if( WCOREDUMP( status ) ) printf( "  %s: CORE DUMP\n", func_name );
00339         return 1;
00340     }
00341     else if( WEXITSTATUS( status ) )
00342     {
00343         printf( "  %s: FAILED\n", func_name );
00344         return 1;
00345     }
00346     else
00347     {
00348         return 0;
00349     }
00350 
00351 #elif MODE == LONGJMP_MODE
00352     // Save stack state at this location.
00353     int rval = sigsetjmp( jmpenv, 1 );
00354     // If rval is zero, then we haven't run the test yet.
00355     // If rval is non-zero then
00356     // a) we ran the test
00357     // b) the test failed
00358     // c) we did a longjmp back to the location where we called setsigjmp.
00359 
00360     // run test
00361     if( !rval )
00362     {
00363         ( *test )();
00364         return 0;
00365     }
00366     // some check failed
00367     else if( rval == -1 )
00368     {
00369         printf( "  %s: FAILED\n", func_name );
00370         return 1;
00371     }
00372     // a signal was raised (e.g. segfault)
00373     else
00374     {
00375         printf( "  %s: TERMINATED (signal %d)\n", func_name, rval );
00376         return 1;
00377     }
00378 #else
00379 #error "MODE not set"
00380 #endif  // MODE
00381 }
00382 
00383 /***************************************************************************************
00384  *                            CHECK_EQUAL implementations
00385  ***************************************************************************************/
00386 
00387 // Common implementatation for most types
00388 #define EQUAL_TEST_IMPL( TEST, TYPE )                         \
00389     if( !( TEST ) )                                           \
00390     {                                                         \
00391         printf( "Equality Test Failed: %s == %s\n", sA, sB ); \
00392         printf( "  at line %d of '%s'\n", line, file );       \
00393         printf( "  Expected value: %" #TYPE "\n", A );        \
00394         printf( "  Actual value:   %" #TYPE "\n", B );        \
00395         printf( "\n" );                                       \
00396         flag_error();                                         \
00397     }
00398 
00399 void check_equal( int A, int B, const char* sA, const char* sB, int line, const char* file )
00400 {
00401     EQUAL_TEST_IMPL( A == B, d )
00402 }
00403 
00404 void check_equal( unsigned A, unsigned B, const char* sA, const char* sB, int line, const char* file )
00405 {
00406     EQUAL_TEST_IMPL( A == B, u )
00407 }
00408 
00409 void check_equal( long A, long B, const char* sA, const char* sB, int line, const char* file )
00410 {
00411     EQUAL_TEST_IMPL( A == B, ld )
00412 }
00413 
00414 void check_equal( unsigned long A, unsigned long B, const char* sA, const char* sB, int line, const char* file )
00415 {
00416     EQUAL_TEST_IMPL( A == B, lu )
00417 }
00418 
00419 void check_equal( unsigned long long A, unsigned long long B, const char* sA, const char* sB, int line,
00420                   const char* file )
00421 {
00422     EQUAL_TEST_IMPL( A == B, llu )
00423 }
00424 
00425 void check_equal( long long A, long long B, const char* sA, const char* sB, int line, const char* file )
00426 {
00427     EQUAL_TEST_IMPL( A == B, lld )
00428 }
00429 
00430 void check_equal( void* A, void* B, const char* sA, const char* sB, int line, const char* file )
00431 {
00432     EQUAL_TEST_IMPL( A == B, p )
00433 }
00434 
00435 void check_equal( const char* A, const char* B, const char* sA, const char* sB, int line, const char* file )
00436 {
00437     EQUAL_TEST_IMPL( !strcmp( ( A ), ( B ) ), s )
00438 }
00439 
00440 void check_equal( const std::string& A, const std::string& B, const char* sA, const char* sB, int line,
00441                   const char* file )
00442 {
00443     check_equal( A.c_str(), B.c_str(), sA, sB, line, file );
00444 }
00445 
00446 void check_equal( float A, float B, float eps, const char* sA, const char* sB, int line, const char* file )
00447 {
00448     EQUAL_TEST_IMPL( fabsf( A - B ) <= eps, f )
00449 }
00450 
00451 void check_equal( double A, double B, double eps, const char* sA, const char* sB, int line, const char* file )
00452 {
00453     EQUAL_TEST_IMPL( fabs( A - B ) <= eps, f )
00454 }
00455 
00456 const char* mb_error_str( moab::ErrorCode err )
00457 {
00458     switch( err )
00459     {
00460         case moab::MB_SUCCESS:
00461             return "Success";
00462         case moab::MB_INDEX_OUT_OF_RANGE:
00463             return "Index Out of Range";
00464         case moab::MB_TYPE_OUT_OF_RANGE:
00465             return "Type Out of Range";
00466         case moab::MB_MEMORY_ALLOCATION_FAILED:
00467             return "Memory Alloc. Failed";
00468         case moab::MB_ENTITY_NOT_FOUND:
00469             return "Entity Not Found";
00470         case moab::MB_MULTIPLE_ENTITIES_FOUND:
00471             return "Multiple Entities Found";
00472         case moab::MB_TAG_NOT_FOUND:
00473             return "Tag Not Found";
00474         case moab::MB_FILE_DOES_NOT_EXIST:
00475             return "File Not Found";
00476         case moab::MB_FILE_WRITE_ERROR:
00477             return "File Write Error";
00478         case moab::MB_NOT_IMPLEMENTED:
00479             return "Not Implemented";
00480         case moab::MB_ALREADY_ALLOCATED:
00481             return "Already Allocated";
00482         case moab::MB_VARIABLE_DATA_LENGTH:
00483             return "Variable Data Length";
00484         case moab::MB_INVALID_SIZE:
00485             return "Invalid Size";
00486         case moab::MB_UNSUPPORTED_OPERATION:
00487             return "Unsupported Operation";
00488         case moab::MB_UNHANDLED_OPTION:
00489             return "Unhandled Option";
00490         case moab::MB_STRUCTURED_MESH:
00491             return "Structured Mesh";
00492         case moab::MB_FAILURE:
00493             return "Failure";
00494         default:
00495             return "(unknown)";
00496     }
00497 }
00498 
00499 // Special case for MBErrorCode, use mb_error_str() to print the
00500 // string name of the error code.
00501 void check_equal( moab::ErrorCode A, moab::ErrorCode B, const char* sA, const char* sB, int line, const char* file )
00502 {
00503     if( A == B ) return;
00504 
00505     printf( "ErrorCode Test Failed: %s == %s\n", sA, sB );
00506     printf( "  at line %d of '%s'\n", line, file );
00507     printf( "  Expected value: %s (%d)\n", mb_error_str( A ), (int)A );
00508     printf( "  Actual value:   %s (%d)\n", mb_error_str( B ), (int)B );
00509     printf( "\n" );
00510     flag_error();
00511 }
00512 
00513 const char* mb_type_str( moab::EntityType type )
00514 {
00515     switch( type )
00516     {
00517         case moab::MBVERTEX:
00518             return "Vertex";
00519         case moab::MBEDGE:
00520             return "Edge";
00521         case moab::MBTRI:
00522             return "Triangle";
00523         case moab::MBQUAD:
00524             return "Quadrilateral";
00525         case moab::MBPOLYGON:
00526             return "Polygon";
00527         case moab::MBTET:
00528             return "Tetrahedron";
00529         case moab::MBPYRAMID:
00530             return "Pyramid";
00531         case moab::MBPRISM:
00532             return "Prism (wedge)";
00533         case moab::MBKNIFE:
00534             return "Knife";
00535         case moab::MBHEX:
00536             return "Hexahedron";
00537         case moab::MBPOLYHEDRON:
00538             return "Polyhedron";
00539         case moab::MBENTITYSET:
00540             return "Entity (Mesh) Set";
00541         case moab::MBMAXTYPE:
00542             return "(max type)";
00543         default:
00544             return "(unknown)";
00545     }
00546 }
00547 
00548 const char* mb_type_str( moab::EntityHandle a )
00549 {
00550     return mb_type_str( moab::TYPE_FROM_HANDLE( a ) );
00551 }
00552 /*
00553 void check_equal( moab::EntityHandle A, moab::EntityHandle B, const char* sA, const char* sB, int line, const char* file
00554 )
00555 {
00556   if (A == B)
00557     return;
00558 
00559   printf( "Entity handles not equal: %s == %s\n", sA, sB );
00560   printf( "  at line %d of '%s'\n", line, file );
00561   if (A)
00562     printf( "  Expected value: %lx (%s %ld)\n", (unsigned long)A, mb_type_str( A ), (long)ID_FROM_HANDLE(A) );
00563   else
00564     printf( "  Expected value: 0\n" );
00565   if (B)
00566     printf( "  Actual value:   %lx (%s %ld)\n", (unsigned long)B, mb_type_str( B ), (long)ID_FROM_HANDLE(B) );
00567   else
00568     printf( "  Actual value: 0\n" );
00569   printf( "\n" );
00570   flag_error();
00571 }
00572 */
00573 
00574 void check_true( bool cond, const char* str, int line, const char* file )
00575 {
00576     if( !cond )
00577     {
00578         printf( "Test Failed: %s\n", str );
00579         printf( "  at line %d of '%s'\n", line, file );
00580         printf( "\n" );
00581         flag_error();
00582     }
00583 }
00584 
00585 #ifdef MB_CART_VECT_HPP
00586 
00587 void check_equal_cartvect( const moab::CartVect& A, const moab::CartVect& B, double eps, const char* sA, const char* sB,
00588                            int line, const char* file )
00589 {
00590     check_equal( A.length(), B.length(), eps, sA, sB, line, file );
00591 
00592     if( fabs( A[0] - B[0] ) <= eps && fabs( A[1] - B[1] ) <= eps && fabs( A[2] - B[2] ) <= eps ) return;
00593 
00594     std::cout << "Equality Test Failed: " << sA << " == " << sB << std::endl;
00595     std::cout << "  at line " << line << " of '" << file << "'" << std::endl;
00596 
00597     std::cout << "  Expected: ";
00598     std::cout << A << std::endl;
00599 
00600     std::cout << "  Actual:   ";
00601     std::cout << B << std::endl;
00602 
00603     flag_error();
00604 }
00605 
00606 #endif  // #ifdef MB_CART_VECT_HPP
00607 
00608 #ifdef __cplusplus
00609 
00610 template < typename T >
00611 void check_array_equal( const T* A, size_t A_size, const T* B, size_t B_size, const char* sA, const char* sB, int line,
00612                         const char* file )
00613 {
00614     size_t i = 0;
00615     for( ;; )
00616     {
00617         if( i == A_size && i == B_size )
00618             return;  // equal
00619         else if( i == A_size || i == B_size )
00620             break;  // differene lengths
00621         else if( A[i] != B[i] )
00622             break;
00623         ++i;
00624     }
00625 
00626     std::cout << "Equality Test Failed: " << sA << " == " << sB << std::endl;
00627     std::cout << "  at line " << line << " of '" << file << "'" << std::endl;
00628     std::cout << "  Vectors differ at position " << i << std::endl;
00629 
00630     // print at most 10 values, roughly centered on the unequal one
00631     size_t count = 10, num_front_values = std::min( count / 2, i );
00632     size_t max_len = std::max( A_size, B_size );
00633     if( i + count - num_front_values > max_len )
00634     {
00635         if( count > max_len )
00636         {
00637             num_front_values = i;
00638             count            = max_len;
00639         }
00640         else
00641         {
00642             num_front_values = count - ( max_len - i );
00643         }
00644     }
00645 
00646     std::cout << "  Expected: ";
00647     if( !A_size ) { std::cout << "(empty)" << std::endl; }
00648     else
00649     {
00650         size_t j   = i - num_front_values;
00651         size_t end = std::min( j + count, A_size );
00652         if( j ) std::cout << "... ";
00653         for( ; j < end; ++j )
00654         {
00655             if( j == i )
00656                 std::cout << '>' << A[j] << "< ";
00657             else
00658                 std::cout << A[j] << " ";
00659         }
00660         if( end != A_size ) std::cout << "...";
00661         std::cout << std::endl;
00662     }
00663 
00664     std::cout << "  Actual:   ";
00665     if( !B_size ) { std::cout << "(empty)" << std::endl; }
00666     else
00667     {
00668         size_t j   = i - num_front_values;
00669         size_t end = std::min( j + count, B_size );
00670         if( j ) std::cout << "... ";
00671         for( ; j < end; ++j )
00672         {
00673             if( j == i )
00674                 std::cout << '>' << B[j] << "< ";
00675             else
00676                 std::cout << B[j] << " ";
00677         }
00678         if( end != B_size ) std::cout << ", ...";
00679         std::cout << std::endl;
00680     }
00681 
00682     flag_error();
00683 }
00684 
00685 template < typename T >
00686 void check_equal( const std::vector< T >& A, const std::vector< T >& B, const char* sA, const char* sB, int line,
00687                   const char* file )
00688 {
00689     if( A.empty() || B.empty() )
00690     {
00691         if( A.size() != B.size() )
00692         {
00693             std::cout << "Equality Test Failed: " << sA << " == " << sB << std::endl;
00694             std::cout << "  at line " << line << " of '" << file << "'" << std::endl;
00695             std::cout << "  Both are not empty " << std::endl;
00696         }
00697         return;
00698     }
00699     check_array_equal( &A[0], A.size(), &B[0], B.size(), sA, sB, line, file );
00700 }
00701 
00702 #ifdef MOAB_RANGE_HPP
00703 
00704 void check_equal( const moab::Range& A, const moab::Range& B, const char* sA, const char* sB, int line,
00705                   const char* file )
00706 {
00707     if( A == B ) return;
00708 
00709     std::cout << "moab::ErrorCode Test Failed: " << sA << " == " << sB << std::endl;
00710     std::cout << "  at line " << line << " of '" << file << "'" << std::endl;
00711     std::cout << "   Expected: " << A << std::endl;
00712     std::cout << "   Actual  : " << B << std::endl;
00713     std::cout << std::endl;
00714     flag_error();
00715 }
00716 
00717 #endif  // #ifdef MOAB_RANGE_HPP
00718 
00719 void check_baseline_file( std::string basefile, std::vector< int >& gids, std::vector< double >& vals, double eps,
00720                           int& err_code )
00721 {
00722     err_code = 1;
00723     std::fstream fs;
00724     fs.open( basefile.c_str(), std::fstream::in );
00725     if( !fs.is_open() )
00726     {
00727         std::cout << " error opening base file  " << basefile << "\n";
00728         flag_error();
00729         return;
00730     }
00731     std::map< int, double > mapVals;
00732     int id     = 0;
00733     double val = 0;
00734     while( !fs.eof() )
00735     {
00736         fs >> id >> val;
00737         mapVals[id] = val;
00738     }
00739     for( size_t i = 0; i < gids.size(); i++ )
00740     {
00741         std::map< int, double >::iterator it = mapVals.find( gids[i] );
00742         if( it == mapVals.end() )
00743         {
00744             std::cout << "id - value not found:" << gids[i] << "\n";
00745             flag_error();
00746             return;
00747         }
00748         if( fabs( it->second - vals[i] ) > eps )
00749         {
00750             std::cout << " value out of range: index i=" << i << " id: " << gids[i] << vals[i]
00751                       << " expected : " << it->second << "\n";
00752             flag_error();
00753             return;
00754         }
00755     }
00756     err_code = 0;  // no error
00757 }
00758 #endif /* ifdef __cplusplus */
00759 
00760 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines