]> rtime.felk.cvut.cz Git - opencv.git/blobdiff - opencv/tests/cxts/cxts.cpp
fixed build on MSVC 2003
[opencv.git] / opencv / tests / cxts / cxts.cpp
index 0c1edc6d75a74c7ed58603bf95f829e20127644b..37c38cb42568c028bac72000f6fe55bdc9474996 100644 (file)
@@ -169,6 +169,26 @@ static void change_color( int color )
 
 #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
@@ -622,6 +642,8 @@ void CvTest::write_real_list( CvFileStorage* fs, const char* paramname,
 int CvTest::read_params( CvFileStorage* fs )
 {
     int code = 0;
+    
+    if(fs == NULL) return code; 
 
     if( ts->get_testing_mode() == CvTS::TIMING_MODE )
     {
@@ -778,7 +800,26 @@ void CvTest::safe_run( int start_from )
     {
         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 (...)
         {
@@ -922,6 +963,72 @@ int CvTest::update_progress( int progress, int test_case_idx, int count, double
     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                              *
 \*****************************************************************************************/
@@ -948,9 +1055,6 @@ CvTS::CvTS()
     selected_tests = new CvTestPtrVec();
     failed_tests = new CvTestInfoVec();
     written_params = new CvTestPtrVec();
-    logbufsize = 1 << 18; // 256K
-    logbufpos = 0;
-    logbuf = new char[logbufsize];
 
     clear();
 }
@@ -992,7 +1096,7 @@ void CvTS::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;
@@ -1020,7 +1124,6 @@ CvTS::~CvTS()
 
     delete selected_tests;
     delete failed_tests;
-    delete[] logbuf;
 }
 
 
@@ -1211,6 +1314,10 @@ int CvTS::run( int argc, char** argv )
     // 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);
 
@@ -1241,6 +1348,17 @@ int CvTS::run( int argc, char** argv )
             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
@@ -1315,8 +1433,13 @@ int CvTS::run( int argc, char** argv )
         }
     }
 
-    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] );
@@ -1395,7 +1518,7 @@ int CvTS::run( int argc, char** argv )
         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 );
 
@@ -1432,10 +1555,9 @@ int CvTS::run( int argc, char** argv )
                     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 )
@@ -1472,13 +1594,14 @@ int CvTS::run( int argc, char** argv )
 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"
@@ -1516,7 +1639,9 @@ int CvTS::read_params( CvFileStorage* fs )
                         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 )
@@ -1531,22 +1656,8 @@ int CvTS::read_params( CvFileStorage* fs )
     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();
@@ -1672,13 +1783,17 @@ void CvTS::print_summary_tailer( int streams )
     }
 }
 
+#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++ )
         {
@@ -1698,16 +1813,11 @@ void CvTS::vprintf( int streams, const char* fmt, va_list l )
                         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);
                 }