#define BOOST_TEST_MODULE fc_task_cancel_tests #include #include #include #include BOOST_AUTO_TEST_CASE( cancel_an_active_task ) { enum task_result{sleep_completed, sleep_aborted}; fc::future task = fc::async([]() { BOOST_TEST_MESSAGE("Starting async task"); try { fc::usleep(fc::seconds(5)); return sleep_completed; } catch (const fc::exception&) { return sleep_aborted; } }); fc::time_point start_time = fc::time_point::now(); // wait a bit for the task to start running fc::usleep(fc::milliseconds(100)); BOOST_TEST_MESSAGE("Canceling task"); task.cancel(); try { task_result result = task.wait(); BOOST_CHECK_MESSAGE(result != sleep_completed, "sleep should have been canceled"); } catch (fc::exception& e) { BOOST_TEST_MESSAGE("Caught exception from canceled task: " << e.what()); BOOST_CHECK_MESSAGE(fc::time_point::now() - start_time < fc::seconds(4), "Task was not canceled quickly"); } } BOOST_AUTO_TEST_CASE( cleanup_cancelled_task ) { std::shared_ptr some_string(std::make_shared("some string")); fc::future task = fc::async([some_string]() { BOOST_TEST_MESSAGE("Starting async task, bound string is " << *some_string); try { fc::usleep(fc::seconds(5)); BOOST_TEST_MESSAGE("Finsihed usleep in async task, leaving the task's functor"); } catch (...) { BOOST_TEST_MESSAGE("Caught exception in async task, leaving the task's functor"); } }); std::weak_ptr weak_string_ptr(some_string); some_string.reset(); BOOST_CHECK_MESSAGE(!weak_string_ptr.expired(), "Weak pointer should still be valid because async task should be holding the strong pointer"); fc::usleep(fc::milliseconds(100)); BOOST_TEST_MESSAGE("Canceling task"); task.cancel(); try { task.wait(); } catch (fc::exception& e) { BOOST_TEST_MESSAGE("Caught exception from canceled task: " << e.what()); } BOOST_CHECK_MESSAGE(weak_string_ptr.expired(), "Weak pointer should now be invalid because async task should be done with it"); task = fc::future(); BOOST_CHECK_MESSAGE(weak_string_ptr.expired(), "Weak pointer should now be invalid because async task should have been destroyed"); } BOOST_AUTO_TEST_CASE( cancel_scheduled_task ) { bool task_executed = false; try { auto result = fc::schedule( [&]() { task_executed = true; }, fc::time_point::now() + fc::seconds(3) ); result.cancel(); result.wait(); } catch ( const fc::exception& e ) { wlog( "${e}", ("e",e.to_detail_string() ) ); } BOOST_CHECK(!task_executed); }