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