From d03bf313bc2894b81e95218a64e862d41729a08b Mon Sep 17 00:00:00 2001 From: Eugene Gershnik Date: Sat, 10 Aug 2024 19:03:34 -0700 Subject: [PATCH] Tests cleanup --- test/CoDispatchTests.mm | 24 +++++++++---------- test/CoDispatchTestsCpp.cpp | 6 ++--- test/CoDispatchTestsNoexcept.cpp | 21 ++++++++-------- test/Makefile | 6 ++--- test/TestGlobal.cpp | 24 +++++++++++++++---- test/TestGlobal.h | 7 +++--- test/main-linux.cpp | 18 -------------- test/main.mm | 21 ++++++++++++---- test/test.xcodeproj/project.pbxproj | 2 +- .../xcshareddata/xcschemes/test.xcscheme | 2 +- 10 files changed, 69 insertions(+), 62 deletions(-) delete mode 100644 test/main-linux.cpp diff --git a/test/CoDispatchTests.mm b/test/CoDispatchTests.mm index bf1dda0..d478335 100644 --- a/test/CoDispatchTests.mm +++ b/test/CoDispatchTests.mm @@ -700,19 +700,19 @@ static auto checkIO() -> DispatchTask<> { co_await resumeOnMainQueue(); } +static DispatchTask<> runTests() { + co_await checkReturnPropagation(); + co_await checkDispatchToDifferentQueue(); + co_await checkMakeAwaitable(); + co_await checkTasks(); + co_await checkGenerator(); + co_await checkIO(); + finishAsyncTest(); +} + TEST_CASE("CoDispatchTests") { - startAsync(); - dispatch_async(dispatch_get_main_queue(), ^ { - []() -> DispatchTask<> { - co_await checkReturnPropagation(); - co_await checkDispatchToDifferentQueue(); - co_await checkMakeAwaitable(); - co_await checkTasks(); - co_await checkGenerator(); - co_await checkIO(); - endAsync(); - }(); + waitForAsyncTest(^ { + runTests(); }); - waitForNoAsync(); } diff --git a/test/CoDispatchTestsCpp.cpp b/test/CoDispatchTestsCpp.cpp index 73f14fa..fc52421 100644 --- a/test/CoDispatchTestsCpp.cpp +++ b/test/CoDispatchTestsCpp.cpp @@ -151,14 +151,12 @@ static DispatchTask<> runTests() { } co_await checkIO(); - endAsync(); + finishAsyncTest(); } TEST_CASE("CoDispatchTestsCpp") { - startAsync(); - dispatch_async(dispatch_get_main_queue(), ^ { + waitForAsyncTest(^ { runTests(); }); - waitForNoAsync(); } diff --git a/test/CoDispatchTestsNoexcept.cpp b/test/CoDispatchTestsNoexcept.cpp index 6f36e79..aa64d54 100644 --- a/test/CoDispatchTestsNoexcept.cpp +++ b/test/CoDispatchTestsNoexcept.cpp @@ -4,18 +4,17 @@ #include "TestGlobal.h" +static DispatchTask<> runTests() { + auto i = co_await co_dispatch([]() { + return 7; + }); + CHECK(i == 7); + finishAsyncTest(); +} + TEST_CASE("CoDispatchTestsNoExcept") { - - startAsync(); - dispatch_async(dispatch_get_main_queue(), ^ { - []() -> DispatchTask<> { - auto i = co_await co_dispatch([]() { - return 7; - }); - CHECK(i == 7); - endAsync(); - }(); + waitForAsyncTest(^ { + runTests(); }); - waitForNoAsync(); } diff --git a/test/Makefile b/test/Makefile index 5baa734..948a777 100644 --- a/test/Makefile +++ b/test/Makefile @@ -9,8 +9,8 @@ LDFLAGS:=--std=c++20 -fblocks -ldispatch -lBlocksRuntime build: mkdir $@ -build/main-linux.o: main-linux.cpp ../include/objc-helpers/BlockUtil.h doctest.h build - $(CLANG) $(CPPFLAGS) -c -o $@ $< +build/main.o: main.mm ../include/objc-helpers/BlockUtil.h doctest.h build + $(CLANG) $(CPPFLAGS) -c -o $@ --language 'c++' $< build/TestGlobal.o: TestGlobal.cpp TestGlobal.h build $(CLANG) $(CPPFLAGS) -c -o $@ $< @@ -32,7 +32,7 @@ build/CoDispatchTestsNoexcept.o: CoDispatchTestsNoexcept.cpp \ build $(CLANG) $(CPPFLAGS) -fno-exceptions -c -o $@ $< -build/test: build/main-linux.o \ +build/test: build/main.o \ build/TestGlobal.o \ build/BlockUtilTestCpp.o \ build/CoDispatchTestsCpp.o \ diff --git a/test/TestGlobal.cpp b/test/TestGlobal.cpp index d830b7b..5c98ee4 100644 --- a/test/TestGlobal.cpp +++ b/test/TestGlobal.cpp @@ -9,27 +9,41 @@ static int g_AsyncCount = 0; static std::mutex g_AsyncCountMutex; static std::condition_variable g_AsyncCountCond; -dispatch_queue_t g_TestQueue; -int g_IsMainKey; +static int g_IsMainKey; -void startAsync() { +static void startAsync() { std::lock_guard lk(g_AsyncCountMutex); ++g_AsyncCount; } -void endAsync() { +static void endAsync() { std::lock_guard lk(g_AsyncCountMutex); if (--g_AsyncCount == 0) g_AsyncCountCond.notify_one(); } -void waitForNoAsync() { +static void waitForNoAsync() { std::unique_lock lk(g_AsyncCountMutex); g_AsyncCountCond.wait(lk, []{ return g_AsyncCount == 0; }); } +void waitForAsyncTest(void (^block)()) { + startAsync(); + dispatch_async(dispatch_get_main_queue(), block); + waitForNoAsync(); +} + +void finishAsyncTest() { + endAsync(); +} + bool isMainQueue() { return (intptr_t)dispatch_get_specific(&g_IsMainKey) == 1; } +void runMainQueue() { + dispatch_queue_set_specific(dispatch_get_main_queue(), &g_IsMainKey, (void*)intptr_t(1), nullptr); + dispatch_main(); +} + diff --git a/test/TestGlobal.h b/test/TestGlobal.h index 0f1b7c8..1207159 100644 --- a/test/TestGlobal.h +++ b/test/TestGlobal.h @@ -1,9 +1,10 @@ #ifndef HEADER_TEST_GLOBAL_H_INCLUDED #define HEADER_TEST_GLOBAL_H_INCLUDED -void startAsync(); -void endAsync(); -void waitForNoAsync(); +void waitForAsyncTest(void (^block)()); +void finishAsyncTest(); + bool isMainQueue(); +void runMainQueue(); #endif diff --git a/test/main-linux.cpp b/test/main-linux.cpp deleted file mode 100644 index a0a0881..0000000 --- a/test/main-linux.cpp +++ /dev/null @@ -1,18 +0,0 @@ - -#define DOCTEST_CONFIG_IMPLEMENT -#include "doctest.h" - -#include - -extern dispatch_queue_t g_TestQueue; -extern int g_IsMainKey; - -int main(int argc, const char * argv[]) { - g_TestQueue = dispatch_queue_create("tests", DISPATCH_QUEUE_SERIAL); - dispatch_async(g_TestQueue, ^ { - auto ret = doctest::Context(argc, argv).run(); - exit(ret); - }); - dispatch_queue_set_specific(dispatch_get_main_queue(), &g_IsMainKey, (void*)1, nullptr); - dispatch_main(); -} diff --git a/test/main.mm b/test/main.mm index fff040e..362dc19 100644 --- a/test/main.mm +++ b/test/main.mm @@ -4,19 +4,32 @@ #include -extern dispatch_queue_t g_TestQueue; -extern int g_IsMainKey; +#include "TestGlobal.h" + +static dispatch_queue_t g_TestQueue; int main(int argc, const char * argv[]) { + //We run tests on a separate serial queue because we can then block it waiting for async operations + //launched from a test to finish. We cannot do this from main queue since some async tests must themselves + //run on main queue. There is no way to portably have "modal loop" with libdispatch. On Mac only + //we could run a runloop but not on Linux. +#ifdef __OBJC__ @autoreleasepool { +#endif g_TestQueue = dispatch_queue_create("tests", DISPATCH_QUEUE_SERIAL); dispatch_async(g_TestQueue, ^ { +#ifdef __OBJC__ @autoreleasepool { +#endif auto ret = doctest::Context(argc, argv).run(); exit(ret); +#ifdef __OBJC__ } +#endif }); - dispatch_queue_set_specific(dispatch_get_main_queue(), &g_IsMainKey, (void*)1, nullptr); - dispatch_main(); + runMainQueue(); + +#ifdef __OBJC__ } +#endif } diff --git a/test/test.xcodeproj/project.pbxproj b/test/test.xcodeproj/project.pbxproj index a7d150b..eb5e370 100644 --- a/test/test.xcodeproj/project.pbxproj +++ b/test/test.xcodeproj/project.pbxproj @@ -181,7 +181,7 @@ isa = PBXProject; attributes = { BuildIndependentTargetsInParallel = 1; - LastUpgradeCheck = 1500; + LastUpgradeCheck = 1600; TargetAttributes = { 441779112B20136E0036AF9F = { CreatedOnToolsVersion = 15.0; diff --git a/test/test.xcodeproj/xcshareddata/xcschemes/test.xcscheme b/test/test.xcodeproj/xcshareddata/xcschemes/test.xcscheme index 3dd3eb7..f59edec 100644 --- a/test/test.xcodeproj/xcshareddata/xcschemes/test.xcscheme +++ b/test/test.xcodeproj/xcshareddata/xcschemes/test.xcscheme @@ -1,6 +1,6 @@