doctest

FORK: The fastest feature-rich C++11/14/17/20 single-header testing framework
git clone https://git.neptards.moe/neptards/doctest.git
Log | Files | Refs | README

concurrency.cpp (2237B)


      1 #include <doctest/doctest.h>
      2 
      3 #ifndef DOCTEST_CONFIG_NO_EXCEPTIONS
      4 
      5 DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_BEGIN
      6 #include <thread>
      7 #include <mutex>
      8 #include <exception>
      9 #include <stdexcept>
     10 DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_END
     11 
     12 DOCTEST_MSVC_SUPPRESS_WARNING(4626) // assignment operator was implicitly defined as deleted
     13 
     14 TEST_CASE("threads...") {
     15     auto call_from_thread = [](int value) {
     16         INFO("print me!");
     17         // one of these has to fail
     18         CHECK(value == 1);
     19         CHECK(value == 2);
     20     };
     21 
     22     int data_1 = 1;
     23     int data_2 = 2;
     24     CAPTURE(data_1); // will not be used for assertions in other threads
     25 
     26     // subcases have to be used only in the main thread (where the test runner is)
     27     SUBCASE("test runner thread") {
     28         call_from_thread(data_1);
     29     }
     30 
     31     // normal threads which are assumed not to throw
     32     SUBCASE("spawned threads") {
     33         std::thread t1(call_from_thread, data_1);
     34         std::thread t2(call_from_thread, data_2);
     35 
     36         t1.join();
     37         t2.join();
     38     }
     39 
     40     // exceptions from threads (that includes failing REQUIRE asserts) have to be handled explicitly
     41     SUBCASE("spawned threads with exception propagation") {
     42         std::exception_ptr exception_ptr = nullptr;
     43         std::mutex         mutex;
     44 
     45         auto might_throw = [&]() {
     46             try {
     47                 REQUIRE(1 == 1);
     48                 REQUIRE(1 == 2); // will fail and throw an exception
     49                 MESSAGE("not reached!");
     50             } catch(...) {
     51                 // make sure there are no races when dealing with the exception ptr
     52                 std::lock_guard<std::mutex> lock(mutex);
     53 
     54                 // set the exception pointer in case of an exception - might overwrite
     55                 // another exception but here we care about propagating any exception - not all
     56                 exception_ptr = std::current_exception();
     57             }
     58         };
     59         std::thread t1(might_throw);
     60         std::thread t2(might_throw);
     61 
     62         t1.join();
     63         t2.join();
     64 
     65         // if any thread has thrown an exception - rethrow it
     66         if(exception_ptr)
     67             std::rethrow_exception(exception_ptr);
     68     }
     69 }
     70 
     71 #endif // DOCTEST_CONFIG_NO_EXCEPTIONS