#include "../../src/ErrorSimulator.hpp" #include "../Tests.hpp" #include "core/Test.hpp" #include "core/Thread.hpp" static int runDone = 0; struct IntHolder { int value; }; static void run(void*) { runDone = 1; } static void testStart() { runDone = 0; { Core::Thread t; TEST_FALSE(t.start(run, nullptr)); } TEST(1, runDone); } static void testLambda() { IntHolder i(0); Core::Thread t; TEST_FALSE(t.start([](void* p) { IntHolder* ip = static_cast(p); ip->value = 2; }, &i)); TEST_FALSE(t.join()); TEST(2, i.value); } static void testJoinWithoutStart() { Core::Thread t; TEST_FALSE(t.join()); } static void testAutoJoin() { Core::Thread t; TEST_FALSE(t.start([](void*) {}, nullptr)); } static void testMove() { Core::Thread t; TEST_FALSE(t.start([](void*) {}, nullptr)); Core::Thread m = Core::move(t); TEST_FALSE(m.join()); } static void testMoveAssignment() { Core::Thread t; TEST_FALSE(t.start([](void*) {}, nullptr)); Core::Thread m; m = Core::move(t); TEST_FALSE(m.join()); } static void testMoveIntoActive() { Core::Thread t; TEST_FALSE(t.start([](void*) {}, nullptr)); Core::Thread m; t = Core::move(m); } static void testDoubleJoin() { Core::Thread t; TEST_FALSE(t.start([](void*) {}, nullptr)); TEST_FALSE(t.join()); TEST_FALSE(t.join()); } struct MutexCounter { Core::Mutex m{}; int counter = 0; }; static void incrementMutexCounter(void* p) { MutexCounter* mcp = static_cast(p); for(int i = 0; i < 100'000; i++) { Core::MutexGuard mg(mcp->m); mcp->counter++; } } static void testMutex() { MutexCounter mc; Core::Thread t[2]; TEST_FALSE(t[0].start(incrementMutexCounter, &mc)); TEST_FALSE(t[1].start(incrementMutexCounter, &mc)); TEST_FALSE(t[0].join()); TEST_FALSE(t[1].join()); TEST(200'000, mc.counter); } static void testDoubleStart() { Core::Thread t; TEST_FALSE(t.start([](void*) {}, nullptr)); TEST_TRUE(t.start([](void*) {}, nullptr)); } static void testFail() { #ifdef ERROR_SIMULATOR Core::Mutex m; failStepThrow = 1; m.lock(); failStepThrow = 1; m.unlock(); Core::Thread t; failStepThrow = 1; TEST_TRUE(t.start([](void*) {}, nullptr)); TEST_FALSE(t.start([](void*) {}, nullptr)); failStepThrow = 1; TEST_TRUE(t.join()); #endif } void testThread() { testStart(); testLambda(); testJoinWithoutStart(); testAutoJoin(); testMove(); testMoveAssignment(); testMoveIntoActive(); testDoubleJoin(); testMutex(); testDoubleStart(); testFail(); }