// This file is part of OpenCV project. // It is subject to the license terms in the LICENSE file found in the top-level directory // of this distribution and at http://opencv.org/license.html. #include "test_precomp.hpp" #include #include #include #if !defined(OPENCV_DISABLE_THREAD_SUPPORT) #include #include #endif namespace opencv_test { namespace { TEST(Core_Async, BasicCheck) { Mat m(3, 3, CV_32FC1, Scalar::all(5.0f)); AsyncPromise p; AsyncArray r = p.getArrayResult(); EXPECT_TRUE(r.valid()); // Follow the limitations of std::promise::get_future // https://en.cppreference.com/w/cpp/thread/promise/get_future EXPECT_THROW(AsyncArray r2 = p.getArrayResult(), cv::Exception); p.setValue(m); Mat m2; r.get(m2); EXPECT_EQ(0, cvtest::norm(m, m2, NORM_INF)); // Follow the limitations of std::future::get // https://en.cppreference.com/w/cpp/thread/future/get EXPECT_FALSE(r.valid()); Mat m3; EXPECT_THROW(r.get(m3), cv::Exception); } TEST(Core_Async, ExceptionCheck) { Mat m(3, 3, CV_32FC1, Scalar::all(5.0f)); AsyncPromise p; AsyncArray r = p.getArrayResult(); EXPECT_TRUE(r.valid()); try { CV_Error(Error::StsOk, "Test: Generated async error"); } catch (const cv::Exception& e) { p.setException(e); } try { Mat m2; r.get(m2); FAIL() << "Exception is expected"; } catch (const cv::Exception& e) { EXPECT_EQ(Error::StsOk, e.code) << e.what(); } // Follow the limitations of std::future::get // https://en.cppreference.com/w/cpp/thread/future/get EXPECT_FALSE(r.valid()); } TEST(Core_Async, LikePythonTest) { Mat m(3, 3, CV_32FC1, Scalar::all(5.0f)); AsyncArray r = cv::utils::testAsyncArray(m); EXPECT_TRUE(r.valid()); Mat m2; r.get(m2); EXPECT_EQ(0, cvtest::norm(m, m2, NORM_INF)); // Follow the limitations of std::future::get // https://en.cppreference.com/w/cpp/thread/future/get EXPECT_FALSE(r.valid()); } #if !defined(OPENCV_DISABLE_THREAD_SUPPORT) TEST(Core_Async, AsyncThread_Simple) { Mat m(3, 3, CV_32FC1, Scalar::all(5.0f)); AsyncPromise p; AsyncArray r = p.getArrayResult(); std::thread t([&]{ std::this_thread::sleep_for(std::chrono::milliseconds(100)); try { p.setValue(m); } catch (const std::exception& e) { std::cout << e.what() << std::endl; } catch (...) { std::cout << "Unknown C++ exception" << std::endl; } }); try { Mat m2; r.get(m2); EXPECT_EQ(0, cvtest::norm(m, m2, NORM_INF)); t.join(); } catch (...) { t.join(); throw; } } TEST(Core_Async, AsyncThread_DetachedResult) { Mat m(3, 3, CV_32FC1, Scalar::all(5.0f)); AsyncPromise p; { AsyncArray r = p.getArrayResult(); r.release(); } bool exception_ok = false; std::thread t([&]{ std::this_thread::sleep_for(std::chrono::milliseconds(100)); try { p.setValue(m); } catch (const cv::Exception& e) { if (e.code == Error::StsError) exception_ok = true; else std::cout << e.what() << std::endl; } catch (const std::exception& e) { std::cout << e.what() << std::endl; } catch (...) { std::cout << "Unknown C++ exception" << std::endl; } }); t.join(); EXPECT_TRUE(exception_ok); } #endif }} // namespace