1 // This file is part of OpenCV project.
2 // It is subject to the license terms in the LICENSE file found in the top-level directory
3 // of this distribution and at http://opencv.org/license.html.
11 static bool printTestTag = false;
13 static std::vector<std::string> currentDirectTestTags, currentImpliedTestTags;
14 static std::vector<const ::testing::TestInfo*> skipped_tests;
16 static std::vector<std::string>& getTestTagsSkipList()
18 static std::vector<std::string> testSkipWithTags;
19 static bool initialized = false;
22 #if OPENCV_32BIT_CONFIGURATION
23 testSkipWithTags.push_back(CV_TEST_TAG_MEMORY_2GB);
25 testSkipWithTags.push_back(CV_TEST_TAG_MEMORY_6GB);
27 testSkipWithTags.push_back(CV_TEST_TAG_VERYLONG);
29 testSkipWithTags.push_back(CV_TEST_TAG_DEBUG_VERYLONG);
33 return testSkipWithTags;
36 static std::vector<std::string>& getTestTagsForceList()
38 static std::vector<std::string> getTestTagsForceList;
39 return getTestTagsForceList;
42 static std::vector<std::string>& getTestTagsRequiredList()
44 static std::vector<std::string> getTestTagsRequiredList;
45 return getTestTagsRequiredList;
49 class TestTagsListener: public ::testing::EmptyTestEventListener
52 void OnTestProgramStart(const ::testing::UnitTest& /*unit_test*/) CV_OVERRIDE
55 const std::vector<std::string>& tags = getTestTagsRequiredList();
56 std::ostringstream os, os_direct;
57 for (size_t i = 0; i < tags.size(); i++)
59 os << (i == 0 ? "'" : ", '") << tags[i] << "'";
60 os_direct << (i == 0 ? "" : ",") << tags[i];
62 std::string tags_str = os.str();
64 std::cout << "TEST: Run tests with tags: " << tags_str << std::endl;
65 ::testing::Test::RecordProperty("test_tags", os_direct.str());
68 const std::vector<std::string>& tags = getTestTagsSkipList();
69 std::ostringstream os, os_direct;
70 for (size_t i = 0; i < tags.size(); i++)
72 os << (i == 0 ? "'" : ", '") << tags[i] << "'";
73 os_direct << (i == 0 ? "" : ",") << tags[i];
75 std::string tags_str = os.str();
77 std::cout << "TEST: Skip tests with tags: " << tags_str << std::endl;
78 ::testing::Test::RecordProperty("test_tags_skip", os_direct.str());
81 const std::vector<std::string>& tags = getTestTagsForceList();
82 std::ostringstream os, os_direct;
83 for (size_t i = 0; i < tags.size(); i++)
85 os << (i == 0 ? "'" : ", '") << tags[i] << "'";
86 os_direct << (i == 0 ? "" : ",") << tags[i];
88 std::string tags_str = os.str();
90 std::cout << "TEST: Force tests with tags: " << tags_str << std::endl;
91 ::testing::Test::RecordProperty("test_tags_force", os_direct.str());
95 void OnTestStart(const ::testing::TestInfo& test_info) CV_OVERRIDE
97 currentDirectTestTags.clear();
98 currentImpliedTestTags.clear();
100 const char* value_param_ = test_info.value_param();
103 std::string value_param(value_param_);
104 if (value_param.find("CV_64F") != std::string::npos
105 || (value_param.find("64F") != std::string::npos
106 && value_param.find(" 64F") != std::string::npos
107 && value_param.find(",64F") != std::string::npos
108 && value_param.find("(64F") != std::string::npos
111 applyTestTag_(CV_TEST_TAG_TYPE_64F);
112 if (value_param.find("1280x720") != std::string::npos)
113 applyTestTag_(CV_TEST_TAG_SIZE_HD);
114 if (value_param.find("1920x1080") != std::string::npos)
115 applyTestTag_(CV_TEST_TAG_SIZE_FULLHD);
116 if (value_param.find("3840x2160") != std::string::npos)
117 applyTestTag_(CV_TEST_TAG_SIZE_4K);
121 void OnTestEnd(const ::testing::TestInfo& /*test_info*/) CV_OVERRIDE
123 if (currentDirectTestTags.empty() && currentImpliedTestTags.empty())
125 if (printTestTag) std::cout << "[ TAGS ] No tags" << std::endl;
128 std::ostringstream os;
129 std::ostringstream os_direct;
130 std::ostringstream os_implied;
132 const std::vector<std::string>& tags = currentDirectTestTags;
133 for (size_t i = 0; i < tags.size(); i++)
135 os << (i == 0 ? "" : ", ") << tags[i];
136 os_direct << (i == 0 ? "" : ",") << tags[i];
139 if (!currentImpliedTestTags.empty())
141 os << " (implied tags: ";
142 const std::vector<std::string>& tags = currentImpliedTestTags;
143 for (size_t i = 0; i < tags.size(); i++)
145 os << (i == 0 ? "" : ", ") << tags[i];
146 os_implied << (i == 0 ? "" : ",") << tags[i];
150 if (printTestTag) std::cout << "[ TAGS ] " << os.str() << std::endl;
151 ::testing::Test::RecordProperty("tags", os_direct.str());
152 ::testing::Test::RecordProperty("tags_implied", os_implied.str());
155 void OnTestIterationEnd(const ::testing::UnitTest& /*unit_test*/, int /*iteration*/) CV_OVERRIDE
157 if (!skipped_tests.empty())
159 std::cout << "[ SKIP ] " << skipped_tests.size() << " tests via tags" << std::endl;
161 skipped_tests.clear();
164 void OnTestProgramEnd(const ::testing::UnitTest& /*unit_test*/) CV_OVERRIDE
166 /*if (!skipped_tests.empty())
168 for (size_t i = 0; i < skipped_tests.size(); i++)
170 const ::testing::TestInfo* test_info = skipped_tests[i];
171 if (!test_info) continue;
172 std::cout << "- " << test_info->test_case_name() << "." << test_info->name() << std::endl;
178 static bool isTestTagForced(const std::string& testTag)
180 const std::vector<std::string>& forceTags = getTestTagsForceList();
181 for (size_t i = 0; i < forceTags.size(); ++i)
183 const std::string& forceTag = forceTags[i];
184 if (testTag == forceTag
185 || (testTag.size() >= forceTag.size()
186 && forceTag[forceTag.size() - 1] == '*'
187 && forceTag.substr(0, forceTag.size() - 1) == testTag.substr(0, forceTag.size() - 1)
197 static bool isTestTagSkipped(const std::string& testTag, CV_OUT std::string& skippedByTag)
199 skippedByTag.clear();
200 const std::vector<std::string>& skipTags = getTestTagsSkipList();
201 for (size_t i = 0; i < skipTags.size(); ++i)
203 const std::string& skipTag = skipTags[i];
204 if (testTag == skipTag
205 || (testTag.size() >= skipTag.size()
206 && skipTag[skipTag.size() - 1] == '*'
207 && skipTag.substr(0, skipTag.size() - 1) == testTag.substr(0, skipTag.size() - 1)
211 skippedByTag = skipTag;
221 const std::vector<std::string>& testTags = currentDirectTestTags;
223 const std::vector<std::string>& tags = getTestTagsRequiredList();
227 for (size_t i = 0; i < tags.size(); ++i)
229 const std::string& tag = tags[i];
230 for (size_t j = 0; j < testTags.size(); ++j)
232 const std::string& testTag = testTags[i];
234 || (testTag.size() >= tag.size()
235 && tag[tag.size() - 1] == '*'
236 && tag.substr(0, tag.size() - 1) == testTag.substr(0, tag.size() - 1)
245 if (found != tags.size())
247 skipped_tests.push_back(::testing::UnitTest::GetInstance()->current_test_info());
248 throw SkipTestException("Test tags don't pass required tags list (--test_tag parameter)");
252 for (size_t i = 0; i < testTags.size(); ++i)
254 const std::string& testTag = testTags[i];
255 if (isTestTagForced(testTag))
258 for (size_t i = 0; i < testTags.size(); ++i)
260 const std::string& testTag = testTags[i];
261 if (isTestTagSkipped(testTag, skipTag))
263 skipped_tests.push_back(::testing::UnitTest::GetInstance()->current_test_info());
264 throw SkipTestException("Test with tag '" + testTag + "' is skipped ('" + skipTag + "' is in skip list)");
267 const std::vector<std::string>& testTagsImplied = currentImpliedTestTags;
268 for (size_t i = 0; i < testTagsImplied.size(); ++i)
270 const std::string& testTag = testTagsImplied[i];
271 if (isTestTagSkipped(testTag, skipTag))
273 skipped_tests.push_back(::testing::UnitTest::GetInstance()->current_test_info());
274 throw SkipTestException("Test with tag '" + testTag + "' is skipped ('" + skipTag + "' is in skip list)");
279 static bool applyTestTagImpl(const std::string& tag, bool direct = false)
281 CV_Assert(!tag.empty());
282 std::vector<std::string>& testTags = direct ? currentDirectTestTags : currentImpliedTestTags;
283 for (size_t i = 0; i < testTags.size(); ++i)
285 const std::string& testTag = testTags[i];
288 return false; // already exists, skip
291 testTags.push_back(tag);
293 // Tags implies logic
294 if (tag == CV_TEST_TAG_MEMORY_14GB)
295 applyTestTagImpl(CV_TEST_TAG_MEMORY_6GB);
296 if (tag == CV_TEST_TAG_MEMORY_6GB)
297 applyTestTagImpl(CV_TEST_TAG_MEMORY_2GB);
298 if (tag == CV_TEST_TAG_MEMORY_2GB)
299 applyTestTagImpl(CV_TEST_TAG_MEMORY_1GB);
300 if (tag == CV_TEST_TAG_MEMORY_1GB)
301 applyTestTagImpl(CV_TEST_TAG_MEMORY_512MB);
302 if (tag == CV_TEST_TAG_VERYLONG)
304 applyTestTagImpl(CV_TEST_TAG_DEBUG_VERYLONG);
305 applyTestTagImpl(CV_TEST_TAG_LONG);
307 else if (tag == CV_TEST_TAG_DEBUG_VERYLONG)
309 applyTestTagImpl(CV_TEST_TAG_DEBUG_LONG);
311 else if (tag == CV_TEST_TAG_LONG)
313 applyTestTagImpl(CV_TEST_TAG_DEBUG_LONG);
316 if (tag == CV_TEST_TAG_SIZE_4K)
317 applyTestTagImpl(CV_TEST_TAG_SIZE_FULLHD);
318 if (tag == CV_TEST_TAG_SIZE_FULLHD)
319 applyTestTagImpl(CV_TEST_TAG_SIZE_HD);
324 void applyTestTag(const std::string& tag)
326 if (tag.empty()) return;
327 if (!applyTestTagImpl(tag, true))
332 void applyTestTag_(const std::string& tag)
334 if (tag.empty()) return;
335 if (!applyTestTagImpl(tag, true))
339 static std::vector<std::string> parseStringList(const std::string& s)
341 std::vector<std::string> result;
342 size_t start_pos = 0;
343 while (start_pos != std::string::npos)
345 while (start_pos < s.size() && s[start_pos] == ' ')
347 const size_t pos_ = s.find(',', start_pos);
348 size_t pos = (pos_ == std::string::npos ? s.size() : pos_);
349 while (pos > start_pos && s[pos - 1] == ' ')
353 const std::string one_piece(s, start_pos, pos - start_pos);
354 result.push_back(one_piece);
356 start_pos = (pos_ == std::string::npos ? pos_ : pos_ + 1);
362 void activateTestTags(const cv::CommandLineParser& parser)
364 std::string test_tag_skip = parser.get<std::string>("test_tag_skip");
365 if (!test_tag_skip.empty())
367 const std::vector<std::string> tag_list = parseStringList(test_tag_skip);
368 if (!tag_list.empty())
370 std::vector<std::string>& skipTags = getTestTagsSkipList();
371 for (size_t k = 0; k < tag_list.size(); ++k)
373 const std::string& tag = tag_list[k];
375 for (size_t i = 0; i < skipTags.size(); ++i)
377 if (tag == skipTags[i])
384 skipTags.push_back(tag);
389 std::string test_tag_enable = parser.get<std::string>("test_tag_enable");
390 if (!test_tag_enable.empty())
392 const std::vector<std::string> tag_list = parseStringList(test_tag_enable);
393 if (!tag_list.empty())
395 std::vector<std::string>& skipTags = getTestTagsSkipList();
396 for (size_t k = 0; k < tag_list.size(); ++k)
398 const std::string& tag = tag_list[k];
400 for (size_t i = 0; i < skipTags.size(); ++i)
402 if (tag == skipTags[i])
404 skipTags.erase(skipTags.begin() + i);
410 std::cerr << "Can't re-enable tag '" << tag << "' - it is not in the skip list" << std::endl;
416 std::string test_tag_force = parser.get<std::string>("test_tag_force");
417 if (!test_tag_force.empty())
419 const std::vector<std::string> tag_list = parseStringList(test_tag_force);
420 if (!tag_list.empty())
422 std::vector<std::string>& forceTags = getTestTagsForceList();
423 for (size_t k = 0; k < tag_list.size(); ++k)
425 const std::string& tag = tag_list[k];
427 for (size_t i = 0; i < forceTags.size(); ++i)
429 if (tag == forceTags[i])
436 forceTags.push_back(tag);
441 std::string test_tag = parser.get<std::string>("test_tag");
442 if (!test_tag.empty())
444 const std::vector<std::string> tag_list = parseStringList(test_tag);
445 if (!tag_list.empty())
447 std::vector<std::string>& requiredTags = getTestTagsRequiredList();
448 for (size_t k = 0; k < tag_list.size(); ++k)
450 const std::string& tag = tag_list[k];
452 for (size_t i = 0; i < requiredTags.size(); ++i)
454 if (tag == requiredTags[i])
461 requiredTags.push_back(tag);
466 printTestTag = parser.get<bool>("test_tag_print");
468 ::testing::UnitTest::GetInstance()->listeners().Append(new TestTagsListener());