#include <stdarg.h>
#include <fcntl.h>
#include <time.h>
-#if defined WIN32 || defined WIN64
+#if defined WIN32 || defined _WIN32 || defined WIN64 || defined _WIN64
#include <io.h>
#else
#include <unistd.h>
#define CV_TS_GREEN 2
#define CV_TS_RED 4
-#if defined WIN32 || defined WIN64
+#if defined WIN32 || defined _WIN32 || defined WIN64 || defined _WIN64
#include <windows.h>
#ifdef _MSC_VER
#include <eh.h>
#endif
+#ifdef _MSC_VER
static void cv_seh_translator( unsigned int /*u*/, EXCEPTION_POINTERS* pExp )
{
int code = CvTS::FAIL_EXCEPTION;
}
throw code;
}
-
-
-#define CV_TS_TRY_BLOCK_BEGIN \
- try {
-
-#define CV_TS_TRY_BLOCK_END \
- } catch( int _code ) { \
- ts->set_failed_test_info( _code ); \
- }
+#endif
static void change_color( int color )
{
#include <signal.h>
-static const int cv_ts_sig_id[] = { SIGSEGV, SIGBUS, SIGFPE, SIGILL, -1 };
+static const int cv_ts_sig_id[] = { SIGSEGV, SIGBUS, SIGFPE, SIGILL, SIGABRT, -1 };
static jmp_buf cv_ts_jmp_mark;
longjmp( cv_ts_jmp_mark, code );
}
-#define CV_TS_TRY_BLOCK_BEGIN \
- { \
- int _code = setjmp( cv_ts_jmp_mark ); \
- if( !_code ) {
-
-#define CV_TS_TRY_BLOCK_END \
- } \
- else { \
- ts->set_failed_test_info( _code ); \
- } \
- }
-
static void change_color( int color )
{
static const uchar ansi_tab[] = { 30, 34, 32, 36, 31, 35, 33, 37 };
if( color != CV_TS_NORMAL )
code = ansi_tab[color & (CV_TS_BLUE|CV_TS_GREEN|CV_TS_RED)];
sprintf( buf, "\x1b[%dm", code );
- printf( buf );
+ fputs( buf, stdout );
}
#endif
+// reads 16-digit hexadecimal number (i.e. 64-bit integer)
+static int64 read_seed( const char* str )
+{
+ int64 val = 0;
+ if( str && strlen(str) == 16 )
+ {
+ for( int i = 0; str[i]; i++ )
+ {
+ int c = tolower(str[i]);
+ if( !isxdigit(c) )
+ return 0;
+ val = val * 16 +
+ (str[i] < 'a' ? str[i] - '0' : str[i] - 'a' + 10);
+ }
+ }
+ return val;
+}
+
+
/***************************** memory manager *****************************/
typedef struct CvTestAllocBlock
int alloc_index = -1;
CvTestAllocBlock* block;
int leak_size = 0, leak_block_count = 0, mem_size = 0;
- void* mem_addr = 0;
+ void* mem_addr = 0;
while( marks_top > 0 && marks[marks_top - 1] >= min_index )
marks_top--;
ts->printf( CvTS::LOG, "Memory leaks: %u blocks, %u bytes total\n"
"%s leaked block: %p, %u bytes\n",
leak_block_count, leak_size, leak_block_count > 1 ? "The first" : "The",
- mem_addr, mem_size );
+ mem_addr, mem_size );
}
index = block ? block->index + 1 : 0;
{
int code = 0;
char* data = block->data;
-
+
if( block->origin == 0 || ((size_t)block->origin & (sizeof(double)-1)) != 0 )
code = CvTS::FAIL_MEMORY_CORRUPTION_BEGIN;
-
+
if( memcmp( data - guard_size, guard_pattern, guard_size ) != 0 )
code = CvTS::FAIL_MEMORY_CORRUPTION_BEGIN;
else if( memcmp( data + block->size, guard_pattern, guard_size ) != 0 )
{
if( show_msg_box )
{
- #ifdef WIN32
+ #if defined WIN32 || defined _WIN32
MessageBox( NULL, "The block that is corrupted and/or not deallocated has been just allocated\n"
"Press Ok to start debugging", "Memory Manager", MB_ICONERROR|MB_OK|MB_SYSTEMMODAL );
#endif
clear();
}
+CvTest* CvTest::get_first_test()
+{
+ return first;
+}
void CvTest::clear()
{
const char* dash_pos = strrchr( name ? name : "", '-' );
if( !dash_pos )
return 0;
-
+
if( name != (const char*)buffer )
strncpy( buffer, name, dash_pos - name );
buffer[dash_pos - name] = '\0';
{
int code = 0;
+ if(fs == NULL) return code;
+
if( ts->get_testing_mode() == CvTS::TIMING_MODE )
{
timing_param_names = find_param( fs, "timing_params" );
code = -1;
}
}
-
+
return code;
}
{
bool increment;
int i;
-
+
if( timing_param_count <= 0 || !timing_param_names || !timing_param_seqs )
return -1;
void CvTest::safe_run( int start_from )
{
- CV_TS_TRY_BLOCK_BEGIN;
-
- run( start_from );
-
- CV_TS_TRY_BLOCK_END;
+ if(ts->is_debug_mode())
+ run( start_from );
+ else
+ {
+ try
+ {
+ #if !defined WIN32 && !defined _WIN32
+ int _code = setjmp( cv_ts_jmp_mark );
+ if( !_code )
+ run( start_from );
+ else
+ throw _code;
+ #else
+ run( start_from );
+ #endif
+ }
+ catch (const cv::Exception& exc)
+ {
+ const char* errorStr = cvErrorStr(exc.code);
+ char buf[1 << 16];
+
+ sprintf( buf, "OpenCV Error: %s (%s) in %s, file %s, line %d",
+ errorStr, exc.err.c_str(), exc.func.size() > 0 ?
+ exc.func.c_str() : "unknown function", exc.file.c_str(), exc.line );
+ ts->printf(CvTS::LOG, "%s\n", buf);
+ ts->set_failed_test_info( CvTS::FAIL_ERROR_IN_CALLED_FUNC );
+ }
+ catch (...)
+ {
+ ts->set_failed_test_info( CvTS::FAIL_EXCEPTION );
+ }
+ }
}
{
int i, test_case_idx, count = get_test_case_count();
int64 t_start = cvGetTickCount();
- double freq = cvGetTickFrequency();
+ double freq = cv::getTickFrequency();
bool ff = can_do_fast_forward();
int progress = 0, code;
-
+ std::vector<double> v_cpe, v_time;
+ int64 t1 = t_start;
+
for( test_case_idx = ff && start_from >= 0 ? start_from : 0;
count < 0 || test_case_idx < count; test_case_idx++ )
{
ts->update_context( this, test_case_idx, ff );
- int64 t00 = 0, t0, t1 = 0;
- double t_acc = 0;
-
+ progress = update_progress( progress, test_case_idx, count, (double)(t1 - t_start)/(freq*1000) );
+
+ int64 t00 = 0, t0 = 0, t2 = 0, t3 = 0;
+ double t_acc = 0, t_cpu_acc = 0;
+
if( ts->get_testing_mode() == CvTS::TIMING_MODE )
{
- const int iterations = 15;
+ const int iterations = 20;
code = prepare_test_case( test_case_idx );
-
+
if( code < 0 || ts->get_err_code() < 0 )
return;
if( code == 0 )
continue;
+
+ v_cpe.resize(0);
+ v_time.resize(0);
for( i = 0; i < iterations; i++ )
{
- t0 = cvGetTickCount();
- run_func();
- t1 = cvGetTickCount();
- if( ts->get_err_code() < 0 )
- return;
-
- if( i == 0 )
- {
- t_acc = (double)(t1 - t0);
- t00 = t0;
- }
- else
+ for(;;)
{
- t0 = t1 - t0;
-
- if( ts->get_timing_mode() == CvTS::MIN_TIME )
- {
- if( (double)t0 < t_acc )
- t_acc = (double)t0;
- }
- else
- {
- assert( ts->get_timing_mode() == CvTS::AVG_TIME );
- t_acc += (double)t0;
- }
-
- if( t1 - t00 > freq*2000000 )
- break;
- }
+ t0 = cv::getTickCount();
+ t2 = cv::getCPUTickCount();
+ run_func();
+ t3 = cv::getCPUTickCount();
+ t1 = cv::getTickCount();
+ if( ts->get_err_code() < 0 )
+ return;
+
+ if( t3 - t2 > 0 && t1 - t0 > 1 )
+ break;
+ }
+
+ if( i == 0 )
+ t00 = t0;
+ v_cpe.push_back((double)(t3 - t2));
+ v_time.push_back((double)(t1 - t0));
+ if( i >= 5 && t1 - t00 > freq*5 )
+ break;
}
- if( ts->get_timing_mode() == CvTS::AVG_TIME )
- t_acc /= i;
- print_time( test_case_idx, t_acc );
+ sort(v_cpe.begin(), v_cpe.end());
+ sort(v_time.begin(), v_time.end());
+
+ t_cpu_acc = v_cpe[i/2];
+ t_acc = v_time[i/2];
+ print_time( test_case_idx, t_acc, t_cpu_acc );
}
else
{
if( validate_test_results( test_case_idx ) < 0 || ts->get_err_code() < 0 )
return;
}
-
- progress = update_progress( progress, test_case_idx, count, (double)(t1 - t_start)/(freq*1000) );
}
}
}
-void CvTest::print_time( int /*test_case_idx*/, double /*time_usecs*/ )
+void CvTest::print_time( int /*test_case_idx*/, double /*time_usecs*/, double /*time_cpu_clocks*/ )
{
}
progress = t;
}
}
- else if( cvRound(dt*0.001) > progress )
+ else if( cvRound(dt) > progress )
{
ts->printf( CvTS::CONSOLE, "." );
- progress = cvRound(dt*0.001);
+ progress = cvRound(dt);
}
return progress;
}
+
+CvBadArgTest::CvBadArgTest( const char* _test_name, const char* _test_funcs, const char* _test_descr )
+ : CvTest( _test_name, _test_funcs, _test_descr )
+{
+ progress = -1;
+ test_case_idx = -1;
+ freq = cv::getTickFrequency();
+}
+
+CvBadArgTest::~CvBadArgTest()
+{
+}
+
+int CvBadArgTest::run_test_case( int expected_code, const char* descr )
+{
+ double new_t = (double)cv::getTickCount(), dt;
+ if( test_case_idx < 0 )
+ {
+ test_case_idx = 0;
+ progress = 0;
+ dt = 0;
+ }
+ else
+ {
+ dt = (new_t - t)/(freq*1000);
+ t = new_t;
+ }
+ progress = update_progress(progress, test_case_idx, 0, dt);
+
+ int errcount = 0;
+ bool thrown = false;
+ if(!descr)
+ descr = "";
+
+ try
+ {
+ run_func();
+ }
+ catch(const cv::Exception& e)
+ {
+ thrown = true;
+ if( e.code != expected_code )
+ {
+ ts->printf(CvTS::LOG, "%s (test case #%d): the error code %d is different from the expected %d\n",
+ descr, test_case_idx, e.code, expected_code);
+ errcount = 1;
+ }
+ }
+ catch(...)
+ {
+ thrown = true;
+ ts->printf(CvTS::LOG, "%s (test case #%d): unknown exception was thrown (the function has likely crashed)\n",
+ descr, test_case_idx);
+ errcount = 1;
+ }
+ if(!thrown)
+ {
+ ts->printf(CvTS::LOG, "%s (test case #%d): no expected exception was thrown\n",
+ descr, test_case_idx);
+ errcount = 1;
+ }
+ test_case_idx++;
+
+ return errcount;
+}
+
/*****************************************************************************************\
* Base Class for Test System *
\*****************************************************************************************/
fclose( output_streams[i].f );
output_streams[i].f = 0;
}
-
+
if( i == LOG_IDX && output_streams[i].default_handle > 0 )
{
dup2( output_streams[i].default_handle, 2 );
free( ostrm_base_name );
ostrm_base_name = 0;
}
- params.rng_seed = (uint64)-1;
- params.debug_mode = 1;
+ params.rng_seed = 0;
+ params.debug_mode = -1;
params.print_only_failed = 0;
params.skip_header = 0;
params.test_mode = CORRECTNESS_CHECK_MODE;
params.timing_mode = MIN_TIME;
params.use_optimized = -1;
+ params.color_terminal = 1;
if( memory_manager )
memory_manager->clear_and_check();
CvTS::~CvTS()
{
clear();
+ set_data_path(0);
if( written_params )
{
delete selected_tests;
delete failed_tests;
- cvSetMemoryManager( 0, 0 );
}
case OK: return "Ok";
case FAIL_GENERIC: return "Generic/Unknown";
case FAIL_MISSING_TEST_DATA: return "No test data";
+ case FAIL_INVALID_TEST_DATA: return "Invalid test data";
case FAIL_ERROR_IN_CALLED_FUNC: return "cvError invoked";
case FAIL_EXCEPTION: return "Hardware/OS exception";
case FAIL_MEMORY_EXCEPTION: return "Invalid memory access";
if( k > 0 && config_name[k] == '.' )
len = k;
-
+
ostrm_base_name = (char*)malloc( len + 1 );
memcpy( ostrm_base_name, config_name, len );
ostrm_base_name[len] = '\0';
{
cvSetErrMode( CV_ErrModeParent );
cvRedirectError( cvStdErrReport );
- #ifdef WIN32
+ #if defined WIN32 || defined _WIN32
#ifdef _MSC_VER
_set_se_translator( cv_seh_translator );
#endif
{
cvSetErrMode( CV_ErrModeLeaf );
cvRedirectError( cvGuiBoxReport );
- #ifdef WIN32
+ #if defined WIN32 || defined _WIN32
#ifdef _MSC_VER
_set_se_translator( 0 );
#endif
}
+void CvTS::set_data_path( const char* data_path )
+{
+ if( data_path == params.data_path )
+ return;
+
+ if( params.data_path )
+ delete[] params.data_path;
+ if( data_path )
+ {
+ int size = (int)strlen(data_path)+1;
+ bool append_slash = data_path[size-1] != '/' && data_path[size-1] != '\\';
+ params.data_path = new char[size+1];
+ memcpy( params.data_path, data_path, size );
+ if( append_slash )
+ strcat( params.data_path, "/" );
+ }
+}
+
+
typedef struct CvTsParamVal
{
const char* fullname;
CvTsParamVal* param = (CvTsParamVal*)written_params->at(i);
if( strcmp( param->fullname, buffer ) == 0 )
{
- if( paramval_len > 0 && memcmp( param->val, val, paramval_len ) == 0 ||
- paramval_len < 0 && strcmp( (const char*)param->val, (const char*)val ) == 0 )
+ if( (paramval_len > 0 && memcmp( param->val, val, paramval_len ) == 0) ||
+ (paramval_len < 0 && strcmp( (const char*)param->val, (const char*)val ) == 0) )
return 1;
break;
}
int CvTS::run( int argc, char** argv )
{
time( &start_time );
-
+
int i, write_params = 0;
int list_tests = 0;
CvTestPtrVec all_tests;
// 0. reset all the parameters, reorder tests
clear();
+/*#if defined WIN32 || defined _WIN32
+ cv::setBreakOnError(true);
+#endif*/
+
for( test = get_first_test(), i = 0; test != 0; test = test->get_next(), i++ )
all_tests.push(test);
// 1. parse command line options
for( i = 1; i < argc; i++ )
{
- if( argv[i] && argv[i][0] != '-' )
+ if( strcmp( argv[i], "-h" ) == 0 || strcmp( argv[i], "--help" ) == 0 )
{
- config_name = argv[i];
- break;
+ print_help();
+ return 0;
}
- else
+ else if( strcmp( argv[i], "-f" ) == 0 )
+ config_name = argv[++i];
+ else if( strcmp( argv[i], "-w" ) == 0 )
+ write_params = 1;
+ else if( strcmp( argv[i], "-t" ) == 0 )
+ params.test_mode = TIMING_MODE;
+ else if( strcmp( argv[i], "-O0" ) == 0 || strcmp( argv[i], "-O1" ) == 0 )
+ params.use_optimized = argv[i][2] - '0';
+ else if( strcmp( argv[i], "-l" ) == 0 )
+ list_tests = 1;
+ else if( strcmp( argv[i], "-d" ) == 0 )
+ set_data_path(argv[++i]);
+ else if( strcmp( argv[i], "-nc" ) == 0 )
+ params.color_terminal = 0;
+ else if( strcmp( argv[i], "-r" ) == 0 )
+ params.debug_mode = 0;
+ else if( strcmp( argv[i], "-tn" ) == 0 )
{
- if( strcmp( argv[i], "-w" ) == 0 )
- write_params = 1;
- else if( strcmp( argv[i], "-t" ) == 0 )
- params.test_mode = TIMING_MODE;
- else if( strcmp( argv[i], "-l" ) == 0 )
- list_tests = 1;
+ params.test_filter_pattern = argv[++i];
+ params.test_filter_mode = CHOOSE_TESTS;
+ }
+ else if( strcmp( argv[i], "-seed" ) == 0 )
+ {
+ params.rng_seed = read_seed(argv[++i]);
+ if( params.rng_seed == 0 )
+ fprintf(stderr, "Invalid or zero RNG seed. Will use the seed from the config file or default one\n");
}
}
+#if 0
+//#if !defined WIN32 && !defined _WIN32
+ if (! config_name )
+ {
+ char * confname = getenv("configname");
+ if (confname)
+ config_name = confname;
+ }
+
+ if( !params.data_path || !params.data_path[0] )
+ {
+ char* datapath = getenv("datapath");
+ if( datapath )
+ set_data_path(datapath);
+ }
+
+ // this is the fallback for the current OpenCV autotools setup
+ if( !params.data_path || !params.data_path[0] )
+ {
+ char* srcdir = getenv("srcdir");
+ char buf[1024];
+ if( srcdir )
+ {
+ sprintf( buf, "%s/../../opencv_extra/testdata/", srcdir );
+ set_data_path(buf);
+ }
+ }
+#endif
+
if( write_params )
{
if( !config_name )
fs = cvOpenFileStorage( config_name, 0, CV_STORAGE_WRITE );
if( !fs )
{
- printf( LOG, "ERROR: could not open config file %s", config_name );
+ printf( LOG, "ERROR: could not open config file %s\n", config_name );
return -1;
}
cvWriteComment( fs, CV_TS_VERSION " config file", 0 );
}
}
- if( read_params(fs) < 0 )
- return -1;
+ if( params.test_mode == CORRECTNESS_CHECK_MODE || fs )
+ {
+ // in the case of algorithmic tests we always run read_params,
+ // even if there is no config file
+ if( read_params(fs) < 0 )
+ return -1;
+ }
if( !ostrm_base_name )
make_output_stream_base_name( config_name ? config_name : argv[0] );
}
if( list_tests )
- goto _exit_;
+ {
+ clear();
+ return 0;
+ }
// 5. setup all the neccessary handlers and print header
set_handlers( !params.debug_mode );
- if( params.use_optimized >= 0 )
- {
- printf( LOG, params.use_optimized ? "Loading optimized plugins..." : "Unloading optimized plugins..." );
- if( params.use_optimized == 0 )
- cvUseOptimized(0);
- /*else
- cvUseOptimized(1); // this is done anyway, so we comment it off
- */
- }
+ if( params.use_optimized == 0 )
+ cvUseOptimized(0);
if( !params.skip_header )
print_summary_header( SUMMARY + LOG + CONSOLE + CSV );
if( memory_manager )
memory_manager->start_tracking();
update_context( test, -1, true );
+ current_test_info.rng_seed0 = current_test_info.rng_seed;
+
ostream_testname_mask = 0; // reset "test name was printed" flags
+ logbuf = std::string();
if( output_streams[LOG_IDX].f )
fflush( output_streams[LOG_IDX].f );
if( !params.print_only_failed )
{
printf( SUMMARY + CONSOLE, "\t" );
- change_color( CV_TS_GREEN );
+ set_color( CV_TS_GREEN );
printf( SUMMARY + CONSOLE, "Ok\n" );
- change_color( CV_TS_NORMAL );
+ set_color( CV_TS_NORMAL );
}
}
else
{
printf( SUMMARY + CONSOLE, "\t" );
- change_color( CV_TS_RED );
+ set_color( CV_TS_RED );
printf( SUMMARY + CONSOLE, "FAIL(%s)\n", str_from_code(code) );
- change_color( CV_TS_NORMAL );
+ set_color( CV_TS_NORMAL );
printf( LOG, "context: test case = %d, seed = %08x%08x\n",
current_test_info.test_case_idx,
(unsigned)(current_test_info.rng_seed>>32),
(unsigned)(current_test_info.rng_seed));
+ if(logbuf.size() > 0)
+ {
+ printf( SUMMARY + CONSOLE, ">>>\n%s\n", logbuf.c_str());
+ }
failed_tests->push(current_test_info);
if( params.rerun_immediately )
break;
test->safe_run( info.test_case_idx );
}
}
-_exit_:
+ int nfailed = failed_tests ? (int)failed_tests->size() : 0;
clear();
- return 0;
+ return nfailed;
+}
+
+
+void CvTS::print_help()
+{
+ ::printf(
+ "Usage: <test_executable> [{-h|--help}][-l] [-r] [-w] [-t] [-f <config_name>] [-d <data_path>] [-O{0|1}] [-tn <test_name>]\n\n"
+ "-d - specify the test data path\n"
+ "-f - use parameters from the provided XML/YAML config file\n"
+ " instead of the default parameters\n"
+ "-h or --help - print this help information\n"
+ "-l - list all the registered tests or subset of the tests,\n"
+ " selected in the config file, and exit\n"
+ "-tn - only run a specific test\n"
+ "-nc - do not use colors in the console output\n"
+ "-O{0|1} - disable/enable on-fly detection of IPP and other\n"
+ " supported optimized libs. It's enabled by default\n"
+ "-r - continue running tests after OS/Hardware exception occured\n"
+ "-t - switch to the performance testing mode instead of\n"
+ " the default algorithmic/correctness testing mode\n"
+ "-w - write default parameters of the algorithmic or\n"
+ " performance (when -t is passed) tests to the specifed\n"
+ " config file (see -f) and exit\n\n"
+ //"Test data path and config file can also be specified by the environment variables 'config' and 'datapath'.\n\n"
+ );
}
+#if defined WIN32 || defined _WIN32
+const char* default_data_path = "../tests/cv/testdata/";
+#else
+const char* default_data_path = "../../../../tests/cv/testdata/";
+#endif
+
+
int CvTS::read_params( CvFileStorage* fs )
{
CvFileNode* node = fs ? cvGetFileNodeByName( fs, 0, "common" ) : 0;
- params.debug_mode = cvReadIntByName( fs, node, "debug_mode", 1 ) != 0;
+ if(params.debug_mode < 0)
+ params.debug_mode = cvReadIntByName( fs, node, "debug_mode", 1 ) != 0;
params.skip_header = cvReadIntByName( fs, node, "skip_header", 0 ) != 0;
params.print_only_failed = cvReadIntByName( fs, node, "print_only_failed", 0 ) != 0;
params.rerun_failed = cvReadIntByName( fs, node, "rerun_failed", 0 ) != 0;
params.rerun_immediately = cvReadIntByName( fs, node, "rerun_immediately", 0 ) != 0;
const char* str = cvReadStringByName( fs, node, "filter_mode", "tests" );
params.test_filter_mode = strcmp( str, "functions" ) == 0 ? CHOOSE_FUNCTIONS : CHOOSE_TESTS;
- str = cvReadStringByName( fs, node, "test_mode", params.test_mode == TIMING_MODE ? "timing" : "correctness" );
+ str = cvReadStringByName( fs, node, "test_mode", params.test_mode == TIMING_MODE ? "timing" : "correctness" );
params.test_mode = strcmp( str, "timing" ) == 0 || strcmp( str, "performance" ) == 0 ?
TIMING_MODE : CORRECTNESS_CHECK_MODE;
- str = cvReadStringByName( fs, node, "timing_mode", params.timing_mode == AVG_TIME ? "avg" : "min" );
+ str = cvReadStringByName( fs, node, "timing_mode", params.timing_mode == AVG_TIME ? "avg" : "min" );
params.timing_mode = strcmp( str, "average" ) == 0 || strcmp( str, "avg" ) == 0 ? AVG_TIME : MIN_TIME;
- params.test_filter_pattern = cvReadStringByName( fs, node, params.test_filter_mode == CHOOSE_FUNCTIONS ?
+ params.test_filter_pattern = params.test_filter_pattern != 0 &&
+ strlen(params.test_filter_pattern) > 0 ? params.test_filter_pattern :
+ cvReadStringByName( fs, node, params.test_filter_mode == CHOOSE_FUNCTIONS ?
"functions" : "tests", "" );
params.resource_path = cvReadStringByName( fs, node, "." );
- params.use_optimized = cvReadIntByName( fs, node, "use_optimized", -1 );
- str = cvReadStringByName( fs, node, "seed", 0 );
- params.rng_seed = 0;
- if( str && strlen(str) == 16 )
+ if( params.use_optimized < 0 )
+ params.use_optimized = cvReadIntByName( fs, node, "use_optimized", -1 );
+ if( !params.data_path || !params.data_path[0] )
{
- params.rng_seed = 0;
- for( int i = 0; i < 16; i++ )
- {
- int c = tolower(str[i]);
- if( !isxdigit(c) )
- {
- params.rng_seed = 0;
- break;
- }
- params.rng_seed = params.rng_seed * 16 +
- (str[i] < 'a' ? str[i] - '0' : str[i] - 'a' + 10);
- }
+ const char* data_path =
+ cvReadStringByName( fs, node, "data_path", default_data_path );
+ set_data_path(data_path);
}
-
+ params.test_case_count_scale = cvReadRealByName( fs, node, "test_case_count_scale", 1. );
+ if( params.test_case_count_scale <= 0 )
+ params.test_case_count_scale = 1.;
+ str = cvReadStringByName( fs, node, "seed", 0 );
+ if( str && params.rng_seed == 0 )
+ params.rng_seed = read_seed(str);
+
if( params.rng_seed == 0 )
params.rng_seed = cvGetTickCount();
cvWriteInt( fs, "rerun_immediately", params.rerun_immediately );
cvWriteString( fs, "filter_mode", params.test_filter_mode == CHOOSE_FUNCTIONS ? "functions" : "tests" );
cvWriteString( fs, "test_mode", params.test_mode == TIMING_MODE ? "timing" : "correctness" );
+ cvWriteString( fs, "data_path", params.data_path ? params.data_path : default_data_path, 1 );
if( params.test_mode == TIMING_MODE )
cvWriteString( fs, "timing_mode", params.timing_mode == AVG_TIME ? "avg" : "min" );
// test_filter, seed & output_file_base_name are not written
void CvTS::print_summary_header( int streams )
{
char csv_header[256], *ptr = csv_header;
- int i, len;
+ int i;
printf( streams, "Engine: %s\n", version );
time_t t1;
printf( streams, "Optimized Low-level Plugin\'s: %s\n", plugins );
printf( streams, "=================================================\n");
- len = 0;
- sprintf( ptr, "funcName,dataType,channels,size,%n", &len );
- ptr += len;
+ sprintf( ptr, "funcName,dataType,channels,size," );
+ ptr += strlen(ptr);
for( i = 0; i < CvTest::TIMING_EXTRA_PARAMS; i++ )
{
- len = 0;
- sprintf( ptr, "param%d,%n", i, &len );
- ptr += len;
+ sprintf( ptr, "param%d,", i );
+ ptr += strlen(ptr);
}
sprintf( ptr, "CPE,Time(uSecs)" );
printf( CSV, "%s\n", csv_header );
}
-
+
void CvTS::print_summary_tailer( int streams )
{
printf( streams, "=================================================\n");
}
}
+#if defined _MSC_VER && _MSC_VER < 1400
+#undef vsnprintf
+#define vsnprintf _vsnprintf
+#endif
void CvTS::vprintf( int streams, const char* fmt, va_list l )
{
if( streams )
{
char str[1 << 14];
- vsprintf( str, fmt, l );
+ vsnprintf( str, sizeof(str)-1, fmt, l );
for( int i = 0; i < MAX_IDX; i++ )
{
if( i != CSV_IDX && !(ostream_testname_mask & (1 << i)) && current_test_info.test )
{
fprintf( f, "-------------------------------------------------\n" );
+ if( i == CONSOLE_IDX || i == SUMMARY_IDX )
+ fprintf( f, "[%08x%08x]\n", (int)(current_test_info.rng_seed0 >> 32),
+ (int)(current_test_info.rng_seed0));
fprintf( f, "%s: ", current_test_info.test->get_name() );
fflush( f );
ostream_testname_mask |= 1 << i;
+ if( i == LOG_IDX )
+ logbuf = std::string();
}
fputs( str, f );
+ if( i == LOG_IDX )
+ logbuf += std::string(str);
if( i == CONSOLE_IDX )
fflush(f);
}
}
}
+void CvTS::set_color(int color)
+{
+ if( params.color_terminal )
+ change_color(color);
+}
static char* cv_strnstr( const char* str, int len,
const char* pattern,
if( str[i] == pattern[0] &&
memcmp( str + i, pattern, pattern_len ) == 0 &&
(!whole_word ||
- ((i == 0 || !isalnum(str[i-1]) && str[i-1] != '_') &&
- (j == len || !isalnum(str[j]) && str[j] != '_'))))
+ ((i == 0 || (!isalnum(str[i-1]) && str[i-1] != '_')) &&
+ (j == len || (!isalnum(str[j]) && str[j] != '_')))))
return (char*)(str + i);
}
int CvTS::filter( CvTest* test )
{
const char* pattern = params.test_filter_pattern;
+ int inverse = 0;
+
+ if( pattern && pattern[0] == '!' )
+ {
+ inverse = 1;
+ pattern++;
+ }
if( !pattern || strcmp( pattern, "" ) == 0 || strcmp( pattern, "*" ) == 0 )
- return 1;
+ return 1 ^ inverse;
if( params.test_filter_mode == CHOOSE_TESTS )
{
int found = 0;
-
+
while( pattern && *pattern )
{
char *ptr, *endptr = (char*)strchr( pattern, ',' );
}
t_name_len = (int)strlen( test->get_name() );
- found = (t_name_len == len || have_wildcard && t_name_len > len) &&
+ found = (t_name_len == len || (have_wildcard && t_name_len > len)) &&
(len == 0 || memcmp( test->get_name(), pattern, len ) == 0);
if( endptr )
{
break;
}
- return found;
+ return found ^ inverse;
}
else
{
if( *endptr == '*' )
{
if( name_first_match )
- return 1;
+ return 1 ^ inverse;
}
else
{
assert( isalpha(c) );
method_name_ptr = endptr;
-
+
do c = *++endptr;
while( isalnum(c) || c == '_' );
-
+
method_name_len = (int)(endptr - method_name_ptr);
-
+
// search for class_name::* or
// class_name::{...method_name...}
tmp_ptr = name_first_match;
if( cv_strnstr( tmp_ptr, (int)(tmp_ptr2 - tmp_ptr) + 1,
method_name_ptr, method_name_len, 1 ))
- return 1;
+ return 1 ^ inverse;
tmp_ptr = cv_strnstr( tmp_ptr2, glob_len -
(int)(tmp_ptr2 - pattern),
// make sure it is not a method
tmp_ptr2 = strchr( tmp_ptr, '}' );
if( !tmp_ptr2 )
- return 1;
+ return 1 ^ inverse;
tmp_ptr3 = strchr( tmp_ptr, '{' );
if( tmp_ptr3 < tmp_ptr2 )
- return 1;
+ return 1 ^ inverse;
tmp_ptr = tmp_ptr2 + 1;
}
ptr = endptr;
}
- return 0;
+ return 0 ^ inverse;
}
}