#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 CvTest::read_params( CvFileStorage* fs )
{
int code = 0;
+
+ if(fs == NULL) return code;
if( ts->get_testing_mode() == CvTS::TIMING_MODE )
{
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 *
\*****************************************************************************************/
selected_tests = new CvTestPtrVec();
failed_tests = new CvTestInfoVec();
written_params = new CvTestPtrVec();
- logbufsize = 1 << 18; // 256K
- logbufpos = 0;
- logbuf = new char[logbufsize];
clear();
}
free( ostrm_base_name );
ostrm_base_name = 0;
}
- params.rng_seed = (uint64)-1;
+ params.rng_seed = 0;
params.debug_mode = -1;
params.print_only_failed = 0;
params.skip_header = 0;
delete selected_tests;
delete failed_tests;
- delete[] logbuf;
}
// 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);
params.color_terminal = 0;
else if( strcmp( argv[i], "-r" ) == 0 )
params.debug_mode = 0;
+ else if( strcmp( argv[i], "-tn" ) == 0 )
+ {
+ 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( 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] );
current_test_info.rng_seed0 = current_test_info.rng_seed;
ostream_testname_mask = 0; // reset "test name was printed" flags
- logbufpos = 0;
+ logbuf = std::string();
if( output_streams[LOG_IDX].f )
fflush( output_streams[LOG_IDX].f );
current_test_info.test_case_idx,
(unsigned)(current_test_info.rng_seed>>32),
(unsigned)(current_test_info.rng_seed));
- if(logbufpos > 0)
+ if(logbuf.size() > 0)
{
- logbuf[logbufpos] = '\0';
- printf( SUMMARY + CONSOLE, ">>>\n%s\n", logbuf);
+ printf( SUMMARY + CONSOLE, ">>>\n%s\n", logbuf.c_str());
}
failed_tests->push(current_test_info);
if( params.rerun_immediately )
void CvTS::print_help()
{
::printf(
- "Usage: <test_executable> [{-h|--help}][-l] [-r] [-w] [-t] [-f <config_name>] [-d <data_path>] [-O{0|1}]\n\n"
+ "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"
TIMING_MODE : CORRECTNESS_CHECK_MODE;
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, "." );
if( params.use_optimized < 0 )
if( params.test_case_count_scale <= 0 )
params.test_case_count_scale = 1.;
str = cvReadStringByName( fs, node, "seed", 0 );
- params.rng_seed = 0;
- if( str && strlen(str) == 16 )
- {
- 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);
- }
- }
+ if( str && params.rng_seed == 0 )
+ params.rng_seed = read_seed(str);
if( params.rng_seed == 0 )
params.rng_seed = cvGetTickCount();
}
}
+#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++ )
{
fflush( f );
ostream_testname_mask |= 1 << i;
if( i == LOG_IDX )
- logbufpos = 0;
+ logbuf = std::string();
}
fputs( str, f );
if( i == LOG_IDX )
- {
- size_t len = strlen(str);
- CV_Assert(logbufpos + len < logbufsize);
- strcpy(logbuf + logbufpos, str);
- logbufpos += len;
- }
+ logbuf += std::string(str);
if( i == CONSOLE_IDX )
fflush(f);
}