ts.hpp 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961
  1. #ifndef OPENCV_TS_HPP
  2. #define OPENCV_TS_HPP
  3. #ifndef __OPENCV_TESTS
  4. #define __OPENCV_TESTS 1
  5. #endif
  6. #include "opencv2/opencv_modules.hpp"
  7. #include "opencv2/core.hpp"
  8. #include "opencv2/imgproc.hpp"
  9. #include "opencv2/imgcodecs.hpp"
  10. #include "opencv2/videoio.hpp"
  11. #include "opencv2/highgui.hpp"
  12. #include "opencv2/core/utility.hpp"
  13. #include "opencv2/core/utils/trace.hpp"
  14. #include "opencv2/core/hal/hal.hpp"
  15. #include <stdarg.h> // for va_list
  16. #include "cvconfig.h"
  17. #include <cmath>
  18. #include <vector>
  19. #include <list>
  20. #include <map>
  21. #include <queue>
  22. #include <string>
  23. #include <iostream>
  24. #include <fstream>
  25. #include <iomanip>
  26. #include <sstream>
  27. #include <cstdio>
  28. #include <iterator>
  29. #include <limits>
  30. #include <algorithm>
  31. #include <set>
  32. #ifndef OPENCV_32BIT_CONFIGURATION
  33. # if defined(INTPTR_MAX) && defined(INT32_MAX) && INTPTR_MAX == INT32_MAX
  34. # define OPENCV_32BIT_CONFIGURATION 1
  35. # elif defined(_WIN32) && !defined(_WIN64)
  36. # define OPENCV_32BIT_CONFIGURATION 1
  37. # endif
  38. #else
  39. # if OPENCV_32BIT_CONFIGURATION == 0
  40. # undef OPENCV_32BIT_CONFIGURATION
  41. # endif
  42. #endif
  43. // most part of OpenCV tests are fit into 200Mb limit, but some tests are not:
  44. // Note: due memory fragmentation real limits are usually lower on 20-25% (400Mb memory usage goes into mem_1Gb class)
  45. #define CV_TEST_TAG_MEMORY_512MB "mem_512mb" // used memory: 200..512Mb - enabled by default
  46. #define CV_TEST_TAG_MEMORY_1GB "mem_1gb" // used memory: 512Mb..1Gb - enabled by default
  47. #define CV_TEST_TAG_MEMORY_2GB "mem_2gb" // used memory: 1..2Gb - enabled by default on 64-bit configuration (32-bit - disabled)
  48. #define CV_TEST_TAG_MEMORY_6GB "mem_6gb" // used memory: 2..6Gb - disabled by default
  49. #define CV_TEST_TAG_MEMORY_14GB "mem_14gb" // used memory: 6..14Gb - disabled by default
  50. // Large / huge video streams or complex workloads
  51. #define CV_TEST_TAG_LONG "long" // 5+ seconds on modern desktop machine (single thread)
  52. #define CV_TEST_TAG_VERYLONG "verylong" // 20+ seconds on modern desktop machine (single thread)
  53. // Large / huge video streams or complex workloads for debug builds
  54. #define CV_TEST_TAG_DEBUG_LONG "debug_long" // 10+ seconds on modern desktop machine (single thread)
  55. #define CV_TEST_TAG_DEBUG_VERYLONG "debug_verylong" // 40+ seconds on modern desktop machine (single thread)
  56. // Lets skip processing of high resolution images via instrumentation tools (valgrind/coverage/sanitizers).
  57. // It is enough to run lower resolution (VGA: 640x480) tests.
  58. #define CV_TEST_TAG_SIZE_HD "size_hd" // 720p+, enabled
  59. #define CV_TEST_TAG_SIZE_FULLHD "size_fullhd" // 1080p+, enabled (disable these tests for valgrind/coverage run)
  60. #define CV_TEST_TAG_SIZE_4K "size_4k" // 2160p+, enabled (disable these tests for valgrind/coverage run)
  61. // Other misc test tags
  62. #define CV_TEST_TAG_TYPE_64F "type_64f" // CV_64F, enabled (disable these tests on low power embedded devices)
  63. // Kernel-based image processing
  64. #define CV_TEST_TAG_FILTER_SMALL "filter_small" // Filtering with kernels <= 3x3
  65. #define CV_TEST_TAG_FILTER_MEDIUM "filter_medium" // Filtering with kernels: 3x3 < kernel <= 5x5
  66. #define CV_TEST_TAG_FILTER_LARGE "filter_large" // Filtering with kernels: 5x5 < kernel <= 9x9
  67. #define CV_TEST_TAG_FILTER_HUGE "filter_huge" // Filtering with kernels: > 9x9
  68. // Other tests categories
  69. #define CV_TEST_TAG_OPENCL "opencl" // Tests with OpenCL
  70. #ifdef WINRT
  71. #pragma warning(disable:4447) // Disable warning 'main' signature found without threading model
  72. #endif
  73. #ifdef _MSC_VER
  74. #pragma warning( disable: 4503 ) // decorated name length exceeded, name was truncated
  75. #endif
  76. #define GTEST_DONT_DEFINE_FAIL 0
  77. #define GTEST_DONT_DEFINE_SUCCEED 0
  78. #define GTEST_DONT_DEFINE_ASSERT_EQ 0
  79. #define GTEST_DONT_DEFINE_ASSERT_NE 0
  80. #define GTEST_DONT_DEFINE_ASSERT_LE 0
  81. #define GTEST_DONT_DEFINE_ASSERT_LT 0
  82. #define GTEST_DONT_DEFINE_ASSERT_GE 0
  83. #define GTEST_DONT_DEFINE_ASSERT_GT 0
  84. #define GTEST_DONT_DEFINE_TEST 0
  85. #ifndef GTEST_LANG_CXX11
  86. #if __cplusplus >= 201103L || (defined(_MSVC_LANG) && !(_MSVC_LANG < 201103))
  87. # define GTEST_LANG_CXX11 1
  88. # define GTEST_HAS_TR1_TUPLE 0
  89. # define GTEST_HAS_COMBINE 1
  90. # endif
  91. #endif
  92. #if defined(__OPENCV_BUILD) && defined(__clang__)
  93. #pragma clang diagnostic ignored "-Winconsistent-missing-override"
  94. #endif
  95. #if defined(__OPENCV_BUILD) && defined(__GNUC__) && __GNUC__ >= 5
  96. //#pragma GCC diagnostic push
  97. #pragma GCC diagnostic ignored "-Wsuggest-override"
  98. #endif
  99. #include "opencv2/ts/ts_gtest.h"
  100. #if defined(__OPENCV_BUILD) && defined(__GNUC__) && __GNUC__ >= 5
  101. //#pragma GCC diagnostic pop
  102. #endif
  103. #include "opencv2/ts/ts_ext.hpp"
  104. #ifndef GTEST_USES_SIMPLE_RE
  105. # define GTEST_USES_SIMPLE_RE 0
  106. #endif
  107. #ifndef GTEST_USES_POSIX_RE
  108. # define GTEST_USES_POSIX_RE 0
  109. #endif
  110. #define PARAM_TEST_CASE(name, ...) struct name : testing::TestWithParam< testing::tuple< __VA_ARGS__ > >
  111. #define GET_PARAM(k) testing::get< k >(GetParam())
  112. namespace cvtest
  113. {
  114. using std::vector;
  115. using std::map;
  116. using std::string;
  117. using std::stringstream;
  118. using std::cout;
  119. using std::cerr;
  120. using std::endl;
  121. using std::min;
  122. using std::max;
  123. using std::numeric_limits;
  124. using std::pair;
  125. using std::make_pair;
  126. using testing::TestWithParam;
  127. using testing::Values;
  128. using testing::ValuesIn;
  129. using testing::Combine;
  130. using cv::Mat;
  131. using cv::Mat_;
  132. using cv::UMat;
  133. using cv::InputArray;
  134. using cv::OutputArray;
  135. using cv::noArray;
  136. using cv::Range;
  137. using cv::Point;
  138. using cv::Rect;
  139. using cv::Size;
  140. using cv::Scalar;
  141. using cv::RNG;
  142. // Tuple stuff from Google Tests
  143. using testing::get;
  144. using testing::make_tuple;
  145. using testing::tuple;
  146. using testing::tuple_size;
  147. using testing::tuple_element;
  148. namespace details {
  149. class SkipTestExceptionBase: public cv::Exception
  150. {
  151. public:
  152. SkipTestExceptionBase(bool handlingTags);
  153. SkipTestExceptionBase(const cv::String& message, bool handlingTags);
  154. };
  155. }
  156. class SkipTestException: public details::SkipTestExceptionBase
  157. {
  158. public:
  159. int dummy; // workaround for MacOSX Xcode 7.3 bug (don't make class "empty")
  160. SkipTestException() : details::SkipTestExceptionBase(false), dummy(0) {}
  161. SkipTestException(const cv::String& message) : details::SkipTestExceptionBase(message, false), dummy(0) { }
  162. };
  163. /** Apply tag to the current test
  164. Automatically apply corresponding additional tags (for example, 4K => FHD => HD => VGA).
  165. If tag is in skip list, then SkipTestException is thrown
  166. */
  167. void applyTestTag(const std::string& tag);
  168. /** Run postponed checks of applied test tags
  169. If tag is in skip list, then SkipTestException is thrown
  170. */
  171. void checkTestTags();
  172. void applyTestTag_(const std::string& tag);
  173. static inline void applyTestTag(const std::string& tag1, const std::string& tag2)
  174. { applyTestTag_(tag1); applyTestTag_(tag2); checkTestTags(); }
  175. static inline void applyTestTag(const std::string& tag1, const std::string& tag2, const std::string& tag3)
  176. { applyTestTag_(tag1); applyTestTag_(tag2); applyTestTag_(tag3); checkTestTags(); }
  177. static inline void applyTestTag(const std::string& tag1, const std::string& tag2, const std::string& tag3, const std::string& tag4)
  178. { applyTestTag_(tag1); applyTestTag_(tag2); applyTestTag_(tag3); applyTestTag_(tag4); checkTestTags(); }
  179. static inline void applyTestTag(const std::string& tag1, const std::string& tag2, const std::string& tag3, const std::string& tag4, const std::string& tag5)
  180. { applyTestTag_(tag1); applyTestTag_(tag2); applyTestTag_(tag3); applyTestTag_(tag4); applyTestTag_(tag5); checkTestTags(); }
  181. /** Append global skip test tags
  182. */
  183. void registerGlobalSkipTag(const std::string& skipTag);
  184. static inline void registerGlobalSkipTag(const std::string& tag1, const std::string& tag2)
  185. { registerGlobalSkipTag(tag1); registerGlobalSkipTag(tag2); }
  186. static inline void registerGlobalSkipTag(const std::string& tag1, const std::string& tag2, const std::string& tag3)
  187. { registerGlobalSkipTag(tag1); registerGlobalSkipTag(tag2); registerGlobalSkipTag(tag3); }
  188. static inline void registerGlobalSkipTag(const std::string& tag1, const std::string& tag2, const std::string& tag3, const std::string& tag4)
  189. { registerGlobalSkipTag(tag1); registerGlobalSkipTag(tag2); registerGlobalSkipTag(tag3); registerGlobalSkipTag(tag4); }
  190. static inline void registerGlobalSkipTag(const std::string& tag1, const std::string& tag2, const std::string& tag3, const std::string& tag4,
  191. const std::string& tag5)
  192. {
  193. registerGlobalSkipTag(tag1); registerGlobalSkipTag(tag2); registerGlobalSkipTag(tag3); registerGlobalSkipTag(tag4);
  194. registerGlobalSkipTag(tag5);
  195. }
  196. static inline void registerGlobalSkipTag(const std::string& tag1, const std::string& tag2, const std::string& tag3, const std::string& tag4,
  197. const std::string& tag5, const std::string& tag6)
  198. {
  199. registerGlobalSkipTag(tag1); registerGlobalSkipTag(tag2); registerGlobalSkipTag(tag3); registerGlobalSkipTag(tag4);
  200. registerGlobalSkipTag(tag5); registerGlobalSkipTag(tag6);
  201. }
  202. static inline void registerGlobalSkipTag(const std::string& tag1, const std::string& tag2, const std::string& tag3, const std::string& tag4,
  203. const std::string& tag5, const std::string& tag6, const std::string& tag7)
  204. {
  205. registerGlobalSkipTag(tag1); registerGlobalSkipTag(tag2); registerGlobalSkipTag(tag3); registerGlobalSkipTag(tag4);
  206. registerGlobalSkipTag(tag5); registerGlobalSkipTag(tag6); registerGlobalSkipTag(tag7);
  207. }
  208. class TS;
  209. int64 readSeed(const char* str);
  210. void randUni( RNG& rng, Mat& a, const Scalar& param1, const Scalar& param2 );
  211. inline unsigned randInt( RNG& rng )
  212. {
  213. return (unsigned)rng;
  214. }
  215. inline double randReal( RNG& rng )
  216. {
  217. return (double)rng;
  218. }
  219. const char* getTypeName( int type );
  220. int typeByName( const char* type_name );
  221. string vec2str(const string& sep, const int* v, size_t nelems);
  222. inline int clipInt( int val, int min_val, int max_val )
  223. {
  224. if( val < min_val )
  225. val = min_val;
  226. if( val > max_val )
  227. val = max_val;
  228. return val;
  229. }
  230. double getMinVal(int depth);
  231. double getMaxVal(int depth);
  232. Size randomSize(RNG& rng, double maxSizeLog);
  233. void randomSize(RNG& rng, int minDims, int maxDims, double maxSizeLog, vector<int>& sz);
  234. int randomType(RNG& rng, cv::_OutputArray::DepthMask typeMask, int minChannels, int maxChannels);
  235. Mat randomMat(RNG& rng, Size size, int type, double minVal, double maxVal, bool useRoi);
  236. Mat randomMat(RNG& rng, const vector<int>& size, int type, double minVal, double maxVal, bool useRoi);
  237. void add(const Mat& a, double alpha, const Mat& b, double beta,
  238. Scalar gamma, Mat& c, int ctype, bool calcAbs=false);
  239. void multiply(const Mat& a, const Mat& b, Mat& c, double alpha=1);
  240. void divide(const Mat& a, const Mat& b, Mat& c, double alpha=1);
  241. void convert(const Mat& src, cv::OutputArray dst, int dtype, double alpha=1, double beta=0);
  242. void copy(const Mat& src, Mat& dst, const Mat& mask=Mat(), bool invertMask=false);
  243. void set(Mat& dst, const Scalar& gamma, const Mat& mask=Mat());
  244. // working with multi-channel arrays
  245. void extract( const Mat& a, Mat& plane, int coi );
  246. void insert( const Mat& plane, Mat& a, int coi );
  247. // checks that the array does not have NaNs and/or Infs and all the elements are
  248. // within [min_val,max_val). idx is the index of the first "bad" element.
  249. int check( const Mat& data, double min_val, double max_val, vector<int>* idx );
  250. // modifies values that are close to zero
  251. void patchZeros( Mat& mat, double level );
  252. void transpose(const Mat& src, Mat& dst);
  253. void erode(const Mat& src, Mat& dst, const Mat& _kernel, Point anchor=Point(-1,-1),
  254. int borderType=0, const Scalar& borderValue=Scalar());
  255. void dilate(const Mat& src, Mat& dst, const Mat& _kernel, Point anchor=Point(-1,-1),
  256. int borderType=0, const Scalar& borderValue=Scalar());
  257. void filter2D(const Mat& src, Mat& dst, int ddepth, const Mat& kernel,
  258. Point anchor, double delta, int borderType,
  259. const Scalar& borderValue=Scalar());
  260. void copyMakeBorder(const Mat& src, Mat& dst, int top, int bottom, int left, int right,
  261. int borderType, const Scalar& borderValue=Scalar());
  262. Mat calcSobelKernel2D( int dx, int dy, int apertureSize, int origin=0 );
  263. Mat calcLaplaceKernel2D( int aperture_size );
  264. void initUndistortMap( const Mat& a, const Mat& k, const Mat& R, const Mat& new_a, Size sz, Mat& mapx, Mat& mapy, int map_type );
  265. void initInverseRectificationMap( const Mat& a, const Mat& k, const Mat& R, const Mat& new_a, Size sz, Mat& mapx, Mat& mapy, int map_type );
  266. void minMaxLoc(const Mat& src, double* minval, double* maxval,
  267. vector<int>* minloc, vector<int>* maxloc, const Mat& mask=Mat());
  268. double norm(InputArray src, int normType, InputArray mask=noArray());
  269. double norm(InputArray src1, InputArray src2, int normType, InputArray mask=noArray());
  270. Scalar mean(const Mat& src, const Mat& mask=Mat());
  271. double PSNR(InputArray src1, InputArray src2);
  272. bool cmpUlps(const Mat& data, const Mat& refdata, int expMaxDiff, double* realMaxDiff, vector<int>* idx);
  273. // compares two arrays. max_diff is the maximum actual difference,
  274. // success_err_level is maximum allowed difference, idx is the index of the first
  275. // element for which difference is >success_err_level
  276. // (or index of element with the maximum difference)
  277. int cmpEps( const Mat& data, const Mat& refdata, double* max_diff,
  278. double success_err_level, vector<int>* idx,
  279. bool element_wise_relative_error );
  280. // a wrapper for the previous function. in case of error prints the message to log file.
  281. int cmpEps2( TS* ts, const Mat& data, const Mat& refdata, double success_err_level,
  282. bool element_wise_relative_error, const char* desc );
  283. int cmpEps2_64f( TS* ts, const double* val, const double* refval, int len,
  284. double eps, const char* param_name );
  285. void logicOp(const Mat& src1, const Mat& src2, Mat& dst, char c);
  286. void logicOp(const Mat& src, const Scalar& s, Mat& dst, char c);
  287. void min(const Mat& src1, const Mat& src2, Mat& dst);
  288. void min(const Mat& src, double s, Mat& dst);
  289. void max(const Mat& src1, const Mat& src2, Mat& dst);
  290. void max(const Mat& src, double s, Mat& dst);
  291. void compare(const Mat& src1, const Mat& src2, Mat& dst, int cmpop);
  292. void compare(const Mat& src, double s, Mat& dst, int cmpop);
  293. void gemm(const Mat& src1, const Mat& src2, double alpha,
  294. const Mat& src3, double beta, Mat& dst, int flags);
  295. void transform( const Mat& src, Mat& dst, const Mat& transmat, const Mat& shift );
  296. double crossCorr(const Mat& src1, const Mat& src2);
  297. void threshold( const Mat& src, Mat& dst, double thresh, double maxval, int thresh_type );
  298. void minMaxIdx( InputArray _img, double* minVal, double* maxVal,
  299. Point* minLoc, Point* maxLoc, InputArray _mask );
  300. struct MatInfo
  301. {
  302. MatInfo(const Mat& _m) : m(&_m) {}
  303. const Mat* m;
  304. };
  305. std::ostream& operator << (std::ostream& out, const MatInfo& m);
  306. struct MatComparator
  307. {
  308. public:
  309. MatComparator(double maxdiff, int context);
  310. ::testing::AssertionResult operator()(const char* expr1, const char* expr2,
  311. const Mat& m1, const Mat& m2);
  312. double maxdiff;
  313. double realmaxdiff;
  314. vector<int> loc0;
  315. int context;
  316. };
  317. class BaseTest;
  318. class TS;
  319. class BaseTest
  320. {
  321. public:
  322. // constructor(s) and destructor
  323. BaseTest();
  324. virtual ~BaseTest();
  325. // the main procedure of the test
  326. virtual void run( int start_from );
  327. // the wrapper for run that cares of exceptions
  328. virtual void safe_run( int start_from=0 );
  329. const string& get_name() const { return name; }
  330. // returns true if and only if the different test cases do not depend on each other
  331. // (so that test system could get right to a problematic test case)
  332. virtual bool can_do_fast_forward();
  333. // deallocates all the memory.
  334. // called by init() (before initialization) and by the destructor
  335. virtual void clear();
  336. protected:
  337. int test_case_count; // the total number of test cases
  338. // read test params
  339. virtual int read_params( const cv::FileStorage& fs );
  340. // returns the number of tests or -1 if it is unknown a-priori
  341. virtual int get_test_case_count();
  342. // prepares data for the next test case. rng seed is updated by the function
  343. virtual int prepare_test_case( int test_case_idx );
  344. // checks if the test output is valid and accurate
  345. virtual int validate_test_results( int test_case_idx );
  346. // calls the tested function. the method is called from run_test_case()
  347. virtual void run_func(); // runs tested func(s)
  348. // updates progress bar
  349. virtual int update_progress( int progress, int test_case_idx, int count, double dt );
  350. // dump test case input parameters
  351. virtual void dump_test_case(int test_case_idx, std::ostream* out);
  352. // finds test parameter
  353. cv::FileNode find_param( const cv::FileStorage& fs, const char* param_name );
  354. // name of the test (it is possible to locate a test by its name)
  355. string name;
  356. // pointer to the system that includes the test
  357. TS* ts;
  358. };
  359. /*****************************************************************************************\
  360. * Information about a failed test *
  361. \*****************************************************************************************/
  362. struct TestInfo
  363. {
  364. TestInfo();
  365. // pointer to the test
  366. BaseTest* test;
  367. // failure code (TS::FAIL_*)
  368. int code;
  369. // seed value right before the data for the failed test case is prepared.
  370. uint64 rng_seed;
  371. // seed value right before running the test
  372. uint64 rng_seed0;
  373. // index of test case, can be then passed to BaseTest::proceed_to_test_case()
  374. int test_case_idx;
  375. };
  376. /*****************************************************************************************\
  377. * Base Class for test system *
  378. \*****************************************************************************************/
  379. // common parameters:
  380. struct TSParams
  381. {
  382. TSParams();
  383. // RNG seed, passed to and updated by every test executed.
  384. uint64 rng_seed;
  385. // whether to use IPP, MKL etc. or not
  386. bool use_optimized;
  387. // extensivity of the tests, scale factor for test_case_count
  388. double test_case_count_scale;
  389. };
  390. class TS
  391. {
  392. TS();
  393. virtual ~TS();
  394. public:
  395. enum
  396. {
  397. NUL=0,
  398. SUMMARY_IDX=0,
  399. SUMMARY=1 << SUMMARY_IDX,
  400. LOG_IDX=1,
  401. LOG=1 << LOG_IDX,
  402. CSV_IDX=2,
  403. CSV=1 << CSV_IDX,
  404. CONSOLE_IDX=3,
  405. CONSOLE=1 << CONSOLE_IDX,
  406. MAX_IDX=4
  407. };
  408. static TS* ptr();
  409. // initialize test system before running the first test
  410. virtual void init( const string& modulename );
  411. // low-level printing functions that are used by individual tests and by the system itself
  412. virtual void printf( int streams, const char* fmt, ... );
  413. virtual void vprintf( int streams, const char* fmt, va_list arglist );
  414. // updates the context: current test, test case, rng state
  415. virtual void update_context( BaseTest* test, int test_case_idx, bool update_ts_context );
  416. const TestInfo* get_current_test_info() { return &current_test_info; }
  417. // sets information about a failed test
  418. virtual void set_failed_test_info( int fail_code );
  419. virtual void set_gtest_status();
  420. // test error codes
  421. enum FailureCode
  422. {
  423. // everything is Ok
  424. OK=0,
  425. // generic error: stub value to be used
  426. // temporarily if the error's cause is unknown
  427. FAIL_GENERIC=-1,
  428. // the test is missing some essential data to proceed further
  429. FAIL_MISSING_TEST_DATA=-2,
  430. // the tested function raised an error via cxcore error handler
  431. FAIL_ERROR_IN_CALLED_FUNC=-3,
  432. // an exception has been raised;
  433. // for memory and arithmetic exception
  434. // there are two specialized codes (see below...)
  435. FAIL_EXCEPTION=-4,
  436. // a memory exception
  437. // (access violation, access to missed page, stack overflow etc.)
  438. FAIL_MEMORY_EXCEPTION=-5,
  439. // arithmetic exception (overflow, division by zero etc.)
  440. FAIL_ARITHM_EXCEPTION=-6,
  441. // the tested function corrupted memory (no exception have been raised)
  442. FAIL_MEMORY_CORRUPTION_BEGIN=-7,
  443. FAIL_MEMORY_CORRUPTION_END=-8,
  444. // the tested function (or test itself) do not deallocate some memory
  445. FAIL_MEMORY_LEAK=-9,
  446. // the tested function returned invalid object, e.g. matrix, containing NaNs,
  447. // structure with NULL or out-of-range fields (while it should not)
  448. FAIL_INVALID_OUTPUT=-10,
  449. // the tested function returned valid object, but it does not match
  450. // the original (or produced by the test) object
  451. FAIL_MISMATCH=-11,
  452. // the tested function returned valid object (a single number or numerical array),
  453. // but it differs too much from the original (or produced by the test) object
  454. FAIL_BAD_ACCURACY=-12,
  455. // the tested function hung. Sometimes, it can be determined by unexpectedly long
  456. // processing time (in this case there should be possibility to interrupt such a function
  457. FAIL_HANG=-13,
  458. // unexpected response on passing bad arguments to the tested function
  459. // (the function crashed, proceed successfully (while it should not), or returned
  460. // error code that is different from what is expected)
  461. FAIL_BAD_ARG_CHECK=-14,
  462. // the test data (in whole or for the particular test case) is invalid
  463. FAIL_INVALID_TEST_DATA=-15,
  464. // the test has been skipped because it is not in the selected subset of the tests to run,
  465. // because it has been run already within the same run with the same parameters, or because
  466. // of some other reason and this is not considered as an error.
  467. // Normally TS::run() (or overridden method in the derived class) takes care of what
  468. // needs to be run, so this code should not occur.
  469. SKIPPED=1
  470. };
  471. // get RNG to generate random input data for a test
  472. RNG& get_rng() { return rng; }
  473. // returns the current error code
  474. TS::FailureCode get_err_code() { return TS::FailureCode(current_test_info.code); }
  475. // returns the test extensivity scale
  476. double get_test_case_count_scale() { return params.test_case_count_scale; }
  477. const string& get_data_path() const { return data_path; }
  478. // returns textual description of failure code
  479. static string str_from_code( const TS::FailureCode code );
  480. std::vector<std::string> data_search_path;
  481. std::vector<std::string> data_search_subdir;
  482. protected:
  483. // these are allocated within a test to try to keep them valid in case of stack corruption
  484. RNG rng;
  485. // information about the current test
  486. TestInfo current_test_info;
  487. // the path to data files used by tests
  488. string data_path;
  489. TSParams params;
  490. std::string output_buf[MAX_IDX];
  491. };
  492. /*****************************************************************************************\
  493. * Subclass of BaseTest for testing functions that process dense arrays *
  494. \*****************************************************************************************/
  495. class ArrayTest : public BaseTest
  496. {
  497. public:
  498. // constructor(s) and destructor
  499. ArrayTest();
  500. virtual ~ArrayTest();
  501. virtual void clear() CV_OVERRIDE;
  502. protected:
  503. virtual int read_params( const cv::FileStorage& fs ) CV_OVERRIDE;
  504. virtual int prepare_test_case( int test_case_idx ) CV_OVERRIDE;
  505. virtual int validate_test_results( int test_case_idx ) CV_OVERRIDE;
  506. virtual void prepare_to_validation( int test_case_idx );
  507. virtual void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );
  508. virtual void fill_array( int test_case_idx, int i, int j, Mat& arr );
  509. virtual void get_minmax_bounds( int i, int j, int type, Scalar& low, Scalar& high );
  510. virtual double get_success_error_level( int test_case_idx, int i, int j );
  511. bool cvmat_allowed;
  512. bool iplimage_allowed;
  513. bool optional_mask;
  514. bool element_wise_relative_error;
  515. int min_log_array_size;
  516. int max_log_array_size;
  517. enum { INPUT, INPUT_OUTPUT, OUTPUT, REF_INPUT_OUTPUT, REF_OUTPUT, TEMP, MASK, MAX_ARR };
  518. vector<vector<void*> > test_array;
  519. vector<vector<Mat> > test_mat;
  520. float buf[4];
  521. };
  522. class BadArgTest : public BaseTest
  523. {
  524. public:
  525. // constructor(s) and destructor
  526. BadArgTest();
  527. virtual ~BadArgTest();
  528. protected:
  529. virtual int run_test_case( int expected_code, const string& descr );
  530. virtual void run_func(void) CV_OVERRIDE = 0;
  531. int test_case_idx;
  532. template<class F>
  533. int run_test_case( int expected_code, const string& _descr, F f)
  534. {
  535. int errcount = 0;
  536. bool thrown = false;
  537. const char* descr = _descr.c_str() ? _descr.c_str() : "";
  538. try
  539. {
  540. f();
  541. }
  542. catch(const cv::Exception& e)
  543. {
  544. thrown = true;
  545. if( e.code != expected_code && e.code != cv::Error::StsAssert && e.code != cv::Error::StsError )
  546. {
  547. ts->printf(TS::LOG, "%s (test case #%d): the error code %d is different from the expected %d\n",
  548. descr, test_case_idx, e.code, expected_code);
  549. errcount = 1;
  550. }
  551. }
  552. catch(...)
  553. {
  554. thrown = true;
  555. ts->printf(TS::LOG, "%s (test case #%d): unknown exception was thrown (the function has likely crashed)\n",
  556. descr, test_case_idx);
  557. errcount = 1;
  558. }
  559. if(!thrown)
  560. {
  561. ts->printf(TS::LOG, "%s (test case #%d): no expected exception was thrown\n",
  562. descr, test_case_idx);
  563. errcount = 1;
  564. }
  565. test_case_idx++;
  566. return errcount;
  567. }
  568. };
  569. extern uint64 param_seed;
  570. struct DefaultRngAuto
  571. {
  572. const uint64 old_state;
  573. DefaultRngAuto() : old_state(cv::theRNG().state) { cv::theRNG().state = cvtest::param_seed; }
  574. ~DefaultRngAuto() { cv::theRNG().state = old_state; }
  575. DefaultRngAuto& operator=(const DefaultRngAuto&);
  576. };
  577. // test images generation functions
  578. void fillGradient(Mat& img, int delta = 5);
  579. void smoothBorder(Mat& img, const Scalar& color, int delta = 3);
  580. // Utility functions
  581. void addDataSearchPath(const std::string& path);
  582. void addDataSearchSubDirectory(const std::string& subdir);
  583. /*! @brief Try to find requested data file
  584. Search directories:
  585. 0. TS::data_search_path (search sub-directories are not used)
  586. 1. OPENCV_TEST_DATA_PATH environment variable
  587. 2. One of these:
  588. a. OpenCV testdata based on build location: "./" + "share/OpenCV/testdata"
  589. b. OpenCV testdata at install location: CMAKE_INSTALL_PREFIX + "share/OpenCV/testdata"
  590. Search sub-directories:
  591. - addDataSearchSubDirectory()
  592. - modulename from TS::init()
  593. */
  594. std::string findDataFile(const std::string& relative_path, bool required = true);
  595. /*! @brief Try to find requested data directory
  596. @sa findDataFile
  597. */
  598. std::string findDataDirectory(const std::string& relative_path, bool required = true);
  599. // Test definitions
  600. class SystemInfoCollector : public testing::EmptyTestEventListener
  601. {
  602. private:
  603. virtual void OnTestProgramStart(const testing::UnitTest&);
  604. };
  605. #ifndef __CV_TEST_EXEC_ARGS
  606. #if defined(_MSC_VER) && (_MSC_VER <= 1400)
  607. #define __CV_TEST_EXEC_ARGS(...) \
  608. while (++argc >= (--argc,-1)) {__VA_ARGS__; break;} /*this ugly construction is needed for VS 2005*/
  609. #else
  610. #define __CV_TEST_EXEC_ARGS(...) \
  611. __VA_ARGS__;
  612. #endif
  613. #endif
  614. void parseCustomOptions(int argc, char **argv);
  615. #define CV_TEST_INIT0_NOOP (void)0
  616. #define CV_TEST_MAIN(resourcesubdir, ...) CV_TEST_MAIN_EX(resourcesubdir, NOOP, __VA_ARGS__)
  617. #define CV_TEST_MAIN_EX(resourcesubdir, INIT0, ...) \
  618. int main(int argc, char **argv) \
  619. { \
  620. CV_TRACE_FUNCTION(); \
  621. { CV_TRACE_REGION("INIT"); \
  622. using namespace cvtest; using namespace opencv_test; \
  623. TS* ts = TS::ptr(); \
  624. ts->init(resourcesubdir); \
  625. __CV_TEST_EXEC_ARGS(CV_TEST_INIT0_ ## INIT0) \
  626. ::testing::InitGoogleTest(&argc, argv); \
  627. ::testing::UnitTest::GetInstance()->listeners().Append(new SystemInfoCollector); \
  628. __CV_TEST_EXEC_ARGS(__VA_ARGS__) \
  629. parseCustomOptions(argc, argv); \
  630. } \
  631. return RUN_ALL_TESTS(); \
  632. }
  633. // This usually only makes sense in perf tests with several implementations,
  634. // some of which are not available.
  635. #define CV_TEST_FAIL_NO_IMPL() do { \
  636. ::testing::Test::RecordProperty("custom_status", "noimpl"); \
  637. FAIL() << "No equivalent implementation."; \
  638. } while (0)
  639. } //namespace cvtest
  640. #include "opencv2/ts/ts_perf.hpp"
  641. namespace cvtest {
  642. using perf::MatDepth;
  643. using perf::MatType;
  644. }
  645. #ifdef WINRT
  646. #ifndef __FSTREAM_EMULATED__
  647. #define __FSTREAM_EMULATED__
  648. #include <stdlib.h>
  649. #include <fstream>
  650. #include <sstream>
  651. #undef ifstream
  652. #undef ofstream
  653. #define ifstream ifstream_emulated
  654. #define ofstream ofstream_emulated
  655. namespace std {
  656. class ifstream : public stringstream
  657. {
  658. FILE* f;
  659. public:
  660. ifstream(const char* filename, ios_base::openmode mode = ios_base::in)
  661. : f(NULL)
  662. {
  663. string modeStr("r");
  664. printf("Open file (read): %s\n", filename);
  665. if (mode & ios_base::binary)
  666. modeStr += "b";
  667. f = fopen(filename, modeStr.c_str());
  668. if (f == NULL)
  669. {
  670. printf("Can't open file: %s\n", filename);
  671. return;
  672. }
  673. fseek(f, 0, SEEK_END);
  674. size_t sz = ftell(f);
  675. if (sz > 0)
  676. {
  677. char* buf = (char*) malloc(sz);
  678. fseek(f, 0, SEEK_SET);
  679. if (fread(buf, 1, sz, f) == sz)
  680. {
  681. this->str(std::string(buf, sz));
  682. }
  683. free(buf);
  684. }
  685. }
  686. ~ifstream() { close(); }
  687. bool is_open() const { return f != NULL; }
  688. void close()
  689. {
  690. if (f)
  691. fclose(f);
  692. f = NULL;
  693. this->str("");
  694. }
  695. };
  696. class ofstream : public stringstream
  697. {
  698. FILE* f;
  699. public:
  700. ofstream(const char* filename, ios_base::openmode mode = ios_base::out)
  701. : f(NULL)
  702. {
  703. open(filename, mode);
  704. }
  705. ~ofstream() { close(); }
  706. void open(const char* filename, ios_base::openmode mode = ios_base::out)
  707. {
  708. string modeStr("w+");
  709. if (mode & ios_base::trunc)
  710. modeStr = "w";
  711. if (mode & ios_base::binary)
  712. modeStr += "b";
  713. f = fopen(filename, modeStr.c_str());
  714. printf("Open file (write): %s\n", filename);
  715. if (f == NULL)
  716. {
  717. printf("Can't open file (write): %s\n", filename);
  718. return;
  719. }
  720. }
  721. bool is_open() const { return f != NULL; }
  722. void close()
  723. {
  724. if (f)
  725. {
  726. fwrite(reinterpret_cast<const char *>(this->str().c_str()), this->str().size(), 1, f);
  727. fclose(f);
  728. }
  729. f = NULL;
  730. this->str("");
  731. }
  732. };
  733. } // namespace std
  734. #endif // __FSTREAM_EMULATED__
  735. #endif // WINRT
  736. namespace opencv_test {
  737. using namespace cvtest;
  738. using namespace cv;
  739. #ifdef CV_CXX11
  740. #define CVTEST_GUARD_SYMBOL(name) \
  741. class required_namespace_specificatin_here_for_symbol_ ## name {}; \
  742. using name = required_namespace_specificatin_here_for_symbol_ ## name;
  743. #else
  744. #define CVTEST_GUARD_SYMBOL(name) /* nothing */
  745. #endif
  746. CVTEST_GUARD_SYMBOL(norm)
  747. CVTEST_GUARD_SYMBOL(add)
  748. CVTEST_GUARD_SYMBOL(multiply)
  749. CVTEST_GUARD_SYMBOL(divide)
  750. CVTEST_GUARD_SYMBOL(transpose)
  751. CVTEST_GUARD_SYMBOL(copyMakeBorder)
  752. CVTEST_GUARD_SYMBOL(filter2D)
  753. CVTEST_GUARD_SYMBOL(compare)
  754. CVTEST_GUARD_SYMBOL(minMaxIdx)
  755. CVTEST_GUARD_SYMBOL(threshold)
  756. extern bool required_opencv_test_namespace; // compilation check for non-refactored tests
  757. }
  758. #endif // OPENCV_TS_HPP