test_async.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  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.
  4. #include "test_precomp.hpp"
  5. #include <opencv2/core/async.hpp>
  6. #include <opencv2/core/detail/async_promise.hpp>
  7. #include <opencv2/core/bindings_utils.hpp>
  8. #if defined(CV_CXX11) && !defined(OPENCV_DISABLE_THREAD_SUPPORT)
  9. #include <thread>
  10. #include <chrono>
  11. #endif
  12. namespace opencv_test { namespace {
  13. TEST(Core_Async, BasicCheck)
  14. {
  15. Mat m(3, 3, CV_32FC1, Scalar::all(5.0f));
  16. AsyncPromise p;
  17. AsyncArray r = p.getArrayResult();
  18. EXPECT_TRUE(r.valid());
  19. // Follow the limitations of std::promise::get_future
  20. // https://en.cppreference.com/w/cpp/thread/promise/get_future
  21. EXPECT_THROW(AsyncArray r2 = p.getArrayResult(), cv::Exception);
  22. p.setValue(m);
  23. Mat m2;
  24. r.get(m2);
  25. EXPECT_EQ(0, cvtest::norm(m, m2, NORM_INF));
  26. // Follow the limitations of std::future::get
  27. // https://en.cppreference.com/w/cpp/thread/future/get
  28. EXPECT_FALSE(r.valid());
  29. Mat m3;
  30. EXPECT_THROW(r.get(m3), cv::Exception);
  31. }
  32. TEST(Core_Async, ExceptionCheck)
  33. {
  34. Mat m(3, 3, CV_32FC1, Scalar::all(5.0f));
  35. AsyncPromise p;
  36. AsyncArray r = p.getArrayResult();
  37. EXPECT_TRUE(r.valid());
  38. try
  39. {
  40. CV_Error(Error::StsOk, "Test: Generated async error");
  41. }
  42. catch (const cv::Exception& e)
  43. {
  44. p.setException(e);
  45. }
  46. try {
  47. Mat m2;
  48. r.get(m2);
  49. FAIL() << "Exception is expected";
  50. }
  51. catch (const cv::Exception& e)
  52. {
  53. EXPECT_EQ(Error::StsOk, e.code) << e.what();
  54. }
  55. // Follow the limitations of std::future::get
  56. // https://en.cppreference.com/w/cpp/thread/future/get
  57. EXPECT_FALSE(r.valid());
  58. }
  59. TEST(Core_Async, LikePythonTest)
  60. {
  61. Mat m(3, 3, CV_32FC1, Scalar::all(5.0f));
  62. AsyncArray r = cv::utils::testAsyncArray(m);
  63. EXPECT_TRUE(r.valid());
  64. Mat m2;
  65. r.get(m2);
  66. EXPECT_EQ(0, cvtest::norm(m, m2, NORM_INF));
  67. // Follow the limitations of std::future::get
  68. // https://en.cppreference.com/w/cpp/thread/future/get
  69. EXPECT_FALSE(r.valid());
  70. }
  71. #if defined(CV_CXX11) && !defined(OPENCV_DISABLE_THREAD_SUPPORT)
  72. TEST(Core_Async, AsyncThread_Simple)
  73. {
  74. Mat m(3, 3, CV_32FC1, Scalar::all(5.0f));
  75. AsyncPromise p;
  76. AsyncArray r = p.getArrayResult();
  77. std::thread t([&]{
  78. std::this_thread::sleep_for(std::chrono::milliseconds(100));
  79. try {
  80. p.setValue(m);
  81. } catch (const std::exception& e) {
  82. std::cout << e.what() << std::endl;
  83. } catch (...) {
  84. std::cout << "Unknown C++ exception" << std::endl;
  85. }
  86. });
  87. try
  88. {
  89. Mat m2;
  90. r.get(m2);
  91. EXPECT_EQ(0, cvtest::norm(m, m2, NORM_INF));
  92. t.join();
  93. }
  94. catch (...)
  95. {
  96. t.join();
  97. throw;
  98. }
  99. }
  100. TEST(Core_Async, AsyncThread_DetachedResult)
  101. {
  102. Mat m(3, 3, CV_32FC1, Scalar::all(5.0f));
  103. AsyncPromise p;
  104. {
  105. AsyncArray r = p.getArrayResult();
  106. r.release();
  107. }
  108. bool exception_ok = false;
  109. std::thread t([&]{
  110. std::this_thread::sleep_for(std::chrono::milliseconds(100));
  111. try {
  112. p.setValue(m);
  113. } catch (const cv::Exception& e) {
  114. if (e.code == Error::StsError)
  115. exception_ok = true;
  116. else
  117. std::cout << e.what() << std::endl;
  118. } catch (const std::exception& e) {
  119. std::cout << e.what() << std::endl;
  120. } catch (...) {
  121. std::cout << "Unknown C++ exception" << std::endl;
  122. }
  123. });
  124. t.join();
  125. EXPECT_TRUE(exception_ok);
  126. }
  127. #endif
  128. }} // namespace