MOAB: Mesh Oriented datABase
(version 5.4.1)
|
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