From 05d9537cbc905a9cbf54134fc7192a4c07217b86 Mon Sep 17 00:00:00 2001 From: Reece Date: Fri, 1 Apr 2022 05:10:58 +0100 Subject: [PATCH] [+/*] Updated and added a few tests (a hell of a lot more pending) [*] Update modules [+] Add auROXTL --- .gitmodules | 3 + Aurora/ForEach | 2 +- Aurora/ROXTL | 1 + Aurora/Runtime | 2 +- AuroraSolution.lua | 109 ++++++++++---- Build_Scripts | 2 +- Tests/Public/0. Hello AuROXTL/Main.cpp | 137 +++++++++++++++++ Tests/Public/1. Hello System/Main.cpp | 6 +- Tests/Public/10. Hello Logger/Main.cpp | 156 +++++++++++++++++--- Tests/Public/11. Hello Processes/Main.cpp | 3 +- Tests/Public/2. Hello Threading/Main.cpp | 73 ++++++++- Tests/Public/3. Hello Command Line/Main.cpp | 9 +- Tests/Public/4. Hello FS/Main.cpp | 48 ++++-- Tests/Public/5. Hello Loop/Main.cpp | 149 ++++++++++++++++++- Tests/Public/6. Hello Compression/Main.cpp | 5 +- Tests/Public/7. Hello Parse/Main.cpp | 15 +- Tests/Public/8. Hello Locale/Main.cpp | 1 - Tests/Public/9. Hello Registry/Main.cpp | 34 +++++ Tests/googletest | 2 +- Vendor/nlohmannjson | 2 +- Vendor/wxConfig | 2 +- Vendor/wxwidgets | 2 +- Win_x64_Lite.bat | 2 + Win_x64_NoToolkit.bat | 2 + Win_x64_wxWidgets.bat | 2 + Win_x86_Lite.bat | 2 + 26 files changed, 678 insertions(+), 93 deletions(-) create mode 160000 Aurora/ROXTL create mode 100644 Tests/Public/0. Hello AuROXTL/Main.cpp create mode 100644 Tests/Public/9. Hello Registry/Main.cpp create mode 100644 Win_x64_Lite.bat create mode 100644 Win_x64_NoToolkit.bat create mode 100644 Win_x64_wxWidgets.bat create mode 100644 Win_x86_Lite.bat diff --git a/.gitmodules b/.gitmodules index 9aaa2c9..3793004 100644 --- a/.gitmodules +++ b/.gitmodules @@ -67,3 +67,6 @@ [submodule "Tests/googletest"] path = Tests/googletest url = https://github.com/google/googletest +[submodule "Aurora/ROXTL"] + path = Aurora/ROXTL + url = https://gitea.reece.sx/AuroraSupport/auROXTL.git diff --git a/Aurora/ForEach b/Aurora/ForEach index 68a3479..99b365e 160000 --- a/Aurora/ForEach +++ b/Aurora/ForEach @@ -1 +1 @@ -Subproject commit 68a3479d137610dff8857c9054454ed8704c642c +Subproject commit 99b365e260db8b7536d10fafbc7be950251780af diff --git a/Aurora/ROXTL b/Aurora/ROXTL new file mode 160000 index 0000000..a19ae80 --- /dev/null +++ b/Aurora/ROXTL @@ -0,0 +1 @@ +Subproject commit a19ae800aa9ba41c185aa4720442fca41732c50d diff --git a/Aurora/Runtime b/Aurora/Runtime index 260442a..7e1bf30 160000 --- a/Aurora/Runtime +++ b/Aurora/Runtime @@ -1 +1 @@ -Subproject commit 260442a68449de7368522dd0f2f7b34871f5de89 +Subproject commit 7e1bf30131146ac22e08568657b0be0669f343de diff --git a/AuroraSolution.lua b/AuroraSolution.lua index 8d7bb3a..4264814 100644 --- a/AuroraSolution.lua +++ b/AuroraSolution.lua @@ -1,4 +1,17 @@ -require("aurora") +newoption { + trigger = "with-wxWidgets", + description = "enable wxWidgets console + tests" +} + +newoption { + trigger = "with-v8", + description = "enable v8 tests" +} + +newoption { + trigger = "lite", + description = "" +} auStartSolution({name = "Hello Aurora"}) @@ -11,12 +24,16 @@ local kNamespaceJS = "Vendor - 6 - JAVASCRIPT" local kNamespaceGraphics = "Vendor - 7 - GRAPHICS" local kNamespaceAudio = "Vendor - 8 - AUDIO" -auAddVisit({ - namespace = kNamespaceGraphics, - name = "wxwidgets", - path = "Vendor/wxwidgets", - type = "SharedLib" -}) + +if (_OPTIONS["with-wxWidgets"]) then + auAddVisit({ + namespace = kNamespaceGraphics, + name = "wxwidgets", + path = "Vendor/wxwidgets", + type = "SharedLib", + out = "!" + }) +end auAddVisit({ namespace = kNamespaceStlEx, @@ -39,19 +56,21 @@ auAddVisit({ type = "StaticLib" }) -auAddVisit({ - namespace = kNamespaceCompression, - name = "bzip2", - path = "Vendor/bzip2", - type = "StaticLib" -}) - -auAddVisit({ - namespace = kNamespaceCompression, - name = "lz4", - path = "Vendor/lz4", - type = "StaticLib" -}) +if (not _OPTIONS["lite"]) then + auAddVisit({ + namespace = kNamespaceCompression, + name = "bzip2", + path = "Vendor/bzip2", + type = "StaticLib" + }) + + auAddVisit({ + namespace = kNamespaceCompression, + name = "lz4", + path = "Vendor/lz4", + type = "StaticLib" + }) +end --auAddVisit({ -- namespace = kNamespaceCompression, @@ -139,18 +158,45 @@ auAddVisit({ }) auAddVisit({ - namespace = kNamespaceFormats, - name = "png", - path = "Vendor/libpng", + namespace = "Aurora", + name = "auROXTL", + path = "Aurora/ROXTL", type = "StaticLib" }) -auAddVisit({ - namespace = kNamespaceFormats, - name = "expat", - path = "Vendor/libexpat", - type = "StaticLib" -}) +if (_OPTIONS["with-wxWidgets"]) then + auAddVisit({ + namespace = kNamespaceFormats, + name = "png", + path = "Vendor/libpng", + type = "StaticLib" + }) + + auAddVisit({ + namespace = kNamespaceFormats, + name = "expat", + path = "Vendor/libexpat", + type = "StaticLib" + }) +end + +if (_OPTIONS["with-v8"]) then + auAddVisit({ + namespace = kNamespaceJS, + name = "V8", + path = "Vendor/v8", + type = "SharedLib", + out = "!" + }) + + auAddVisit({ + namespace = kNamespaceJS, + name = "icu", + path = "Vendor/unicode", + type = "StaticLib" + }) +end + auProcessSolution() @@ -198,6 +244,11 @@ local processTests = function() addTestGroup("Private") addTestGroup("Public") + + + if (_OPTIONS["with-wxWidgets"]) then + addTestGroup("ToolKit") + end end processTests() \ No newline at end of file diff --git a/Build_Scripts b/Build_Scripts index ac9d592..e3dd284 160000 --- a/Build_Scripts +++ b/Build_Scripts @@ -1 +1 @@ -Subproject commit ac9d592fbc1b272f25b1b52bf001c021bcf6765f +Subproject commit e3dd28450807c05c7e5c2a878d8506c839b4857e diff --git a/Tests/Public/0. Hello AuROXTL/Main.cpp b/Tests/Public/0. Hello AuROXTL/Main.cpp new file mode 100644 index 0000000..b96b7d8 --- /dev/null +++ b/Tests/Public/0. Hello AuROXTL/Main.cpp @@ -0,0 +1,137 @@ +/*** + Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved. + + File: Main.cpp + Date: 2022-2-18 + Author: Reece +***/ +#include +#include + +TEST(Containers, HashMaps) +{ + struct HelloKey : public AuEnableHashCodeOnData + { + AuUInt32 id {}; + AuUInt8 task {}; + +/** + * inline HelloKey(const AuRemoveConst_t> &id ,const AuRemoveConst_t> &task) : id(id) ,task(task) {} + * inline HelloKey(AuRemoveConst_t> &&id ,AuRemoveConst_t> &&task) : id(id) ,task(task) {} + * inline HelloKey(HelloKey &&cpy) noexcept : id(AuMove(cpy.id)) ,task(AuMove(cpy.task)) {} bool operator==(const HelloKey & ref) const noexcept { return this->id == ref.id && this->task == ref.task ; } + * bool operator==(const HelloKey & ref) const noexcept { return this->id == ref.id && this->task == ref.task ; } + * HelloKey& operator=( HelloKey && ref) noexcept { this->id = AuMove(ref.id); this->task = AuMove(ref.task); return *this; } HelloKey& operator=(const HelloKey & ref) { this->id = ref.id; this->task = ref.task; return *this; }; + */ + AU_DEFINE_FOR_VA(HelloKey, + (AU_DEFINE_CTOR_VA, // initializer-list-like ctor (extending AuEnableHashCodeOnData will break lists) + AU_DEFINE_THIS_MOVE_CTOR_VA, // add move HelloKey(HelloKey &&) + AU_DEFINE_EQUALS_VA, // add equals operator + AU_DEFINE_MOVE_VA, // add move assignment operator + AU_DEFINE_COPY_VA), // add copy assignment operator + (id, task)); + }; + + AuHashMap a; + ASSERT_TRUE(AuTryInsert(a, HelloKey {0, 4}, "hello world")); + ASSERT_TRUE(AuTryInsert(a, HelloKey {0, 4}, "hello world2")); + ASSERT_FALSE(AuTryInsert(a, HelloKey {0, 4}, "hello world3", false)); + +} + +TEST(Containers, HashMaps2) +{ + struct HelloKey + { + AuUInt32 id {}; + AuString name {}; + + AU_DEFINE_CTOR_VA(HelloKey, (id, name)) + AU_DEFINE_THIS_MOVE_CTOR_VA(HelloKey, (id, name)) + AU_DEFINE_EQUALS_VA(HelloKey, (id, name)) + AU_DEFINE_MOVE_VA(HelloKey, (id, name)) + AU_DEFINE_COPY_VA(HelloKey, (id, name)) + AU_DEFINE_HASHCODE_VA(HelloKey, (id, name)) +/* AuUInt HashCode() const noexcept { return AuHashCode(this->id) ^ AuHashCode(this->task) ; } */ + }; + + AuHashMap map; + + ASSERT_TRUE(AuTryInsert(map, HelloKey {0, "frog"}, "hello world")); + ASSERT_FALSE(AuTryInsert(map, HelloKey {0, "frog"}, "hello world", false)); + ASSERT_FALSE(AuTryInsert(&map, HelloKey {0, "frog"}, "hello world", false)); + ASSERT_TRUE(AuTryInsert(&map, HelloKey {0, "frog"}, "hello world overwrite", true)); + ASSERT_TRUE(AuTryInsert(&map, HelloKey {0, "frog"}, "hello world overwrite 2")); + ASSERT_TRUE(AuExists(map, HelloKey {0, "frog"})); + ASSERT_TRUE(AuExists(&map, HelloKey {0, "frog"})); + ASSERT_TRUE(AuTryRemove(map, HelloKey {0, "frog"})); + ASSERT_FALSE(AuTryRemove(map, HelloKey {0, "frog"}) ); + ASSERT_FALSE(AuExists(map, HelloKey {0, "frog"})); +} + +TEST(Containers, Lists) +{ + AuList test; + + ASSERT_TRUE(AuListFromArgs(test, 1, 2, 3, 4, 5, 6, 7, 8)); + + for (AU_ITERATE_N_TO_X(i, 1, 9)) + { + ASSERT_TRUE(AuExists(test, i)); + } + + ASSERT_FALSE(AuExists(test, 9)); + ASSERT_TRUE(AuTryInsert(test, 9)); + ASSERT_TRUE(AuExists(test, 9)); + ASSERT_TRUE(AuTryRemove(test, 5)); + ASSERT_FALSE(AuTryRemove(test, 5)); + ASSERT_FALSE(AuExists(test, 5)); +} + +static void StaticAsserts_Tuples() +{ + auto tuplePair = AuMakeTuple(AuUInt32(1), AuUInt16(3)); + auto popFront = AuTuplePopFront(tuplePair); + auto popBack = AuTuplePopBack(tuplePair); + + static_assert(AuIsSame_v(popFront))>); + static_assert(AuIsSame_v(popBack))>); + + // TODO: + + // AuTuplePushBack + // AuTuplePushFront + + // AuTupleTakeRange + + // AuTupleForEach + // AuTupleTransform + + // AuTupleTie + // AuTupleForward +} + +TEST(Debug, NullPointersThrow) +{ +#if !defined(AURORA_ROXTL_NULL_POINTER_CHECKS_DISABLED) + AuSPtr pGold; + + try + { + auto gVal = *pGold; + ASSERT_TRUE(false); + AuLogDbg("ERROR: {}", gVal); + } + catch (...) + { + ASSERT_TRUE(true); + } + +#endif +} + +void RunTests() +{ + Aurora::RuntimeStartInfo info; + info.console.fio.enableLogging = false; + Aurora::RuntimeStart(info); +} \ No newline at end of file diff --git a/Tests/Public/1. Hello System/Main.cpp b/Tests/Public/1. Hello System/Main.cpp index 71a60e9..cc4ee14 100644 --- a/Tests/Public/1. Hello System/Main.cpp +++ b/Tests/Public/1. Hello System/Main.cpp @@ -27,10 +27,11 @@ static void PrintCPUSpecs() AuLogInfo("CpuInfo {} / {} / {} [sockets/cores/threads] ", cpuInfo.uSocket, cpuInfo.uCores, cpuInfo.uThreads); AuLogInfo("Package: {} by {} (arch: {})", cpuInfo.cpuId.brand, cpuInfo.cpuId.vendor, AuBuild::EArchitectureToString(cpuInfo.cpuArch)); - AuLogInfo("Complete CPUs: {} ", cpuInfo.serverTopology.size()); + AuLogInfo("All CPUs: {} ({}) ", cpuInfo.maskAllCores.ToString(), cpuInfo.coreTopology.size()); AuLogInfo("E-Cores: {} ", cpuInfo.maskECores.ToString()); - for (const auto &cpu : cpuInfo.serverTopology) + AuLogInfo("P-Cores: {} ", cpuInfo.maskPCores.ToString()); + for (const auto &cpu : cpuInfo.coreTopology) { AuLogInfo("Core: {}", cpu.ToString()); } @@ -99,7 +100,6 @@ void RunTests() { Aurora::RuntimeStartInfo info; info.console.fio.enableLogging = false; - info.console.forceToolKitWindow = false; Aurora::RuntimeStart(info); PrintSoftwareSpecs(); diff --git a/Tests/Public/10. Hello Logger/Main.cpp b/Tests/Public/10. Hello Logger/Main.cpp index 2b26292..4b797ff 100644 --- a/Tests/Public/10. Hello Logger/Main.cpp +++ b/Tests/Public/10. Hello Logger/Main.cpp @@ -7,42 +7,156 @@ Note: Run the registry template in the ./Aurora/Runtime/Media directory ***/ #include +#include -static void WriteHelloToEventLogGlobal() + +TEST(Echo, HelloReplacedGlobalLogger) { - auto logger = AuLog::NewLoggerShared(AuList>{ - AuLog::NewOSNamedEventDirectorySinkShared("Aurora Demo"), - AuLog::NewStdSinkShared() - }); - SysAssert(logger); + auto logger = AuLog::NewLoggerShared(AuList>{ + AuLog::NewOSNamedEventDirectorySinkShared("Aurora Demo"), + AuLog::NewStdSinkShared() + }); + ASSERT_TRUE(logger); - AuLog::SetGlobalLogger(logger); - AuLogInfo("Hello event log and stdout from from global AuLogInfo shorthand"); - try - { - AU_THROW_STRING("Crinkled and delivered with many of seethes, hello event log"); - } - catch (...) - { - - } - AuLog::SetGlobalLogger({}); + AuLog::SetGlobalLogger(logger); + AuLogInfo("Hello event log and stdout from the global AuLogInfo shorthand"); + try + { + AU_THROW_STRING("Crinkled and delivered with many of seethes, hello event log"); + } + catch (...) + { + + } + + AuLog::SetGlobalLogger({}); } -static void SayHelloEventLog() +TEST(Echo, HelloEventDir) { auto logger = AuLog::NewLoggerShared(AuList>{AuLog::NewOSNamedEventDirectorySinkShared("Aurora Demo")}); + ASSERT_TRUE(logger); logger->LogInfo("hello 2+2={}", 2 + 2); } +TEST(Echo, TextFile) +{ + { + auto logger = AuLog::NewLoggerShared(AuList>{AuLog::NewFileSinkShared("~/TestLog.txt")}); + ASSERT_TRUE(logger); + + logger->LogInfo("hello text file 2+2={}", 2 + 2); + } + + AuString log; + ASSERT_TRUE(AuIOFS::ReadString("~/TestLog.txt", log)); + ASSERT_TRUE(AuStringContains(log, "hello text file")); +} + + +TEST(Echo, RingBuffer) +{ + AuList> sinks; + + auto rb = AuLog::NewRingLoggerShared(10'000); + auto cpy = rb; + ASSERT_TRUE(rb); + ASSERT_TRUE(AuListFromArgs(sinks, AuReference(rb))); + + auto logger = AuLog::NewLoggerShared(sinks); + ASSERT_TRUE(logger); + + for (int i = 0; i < 20'000; i++) + { + logger->LogInfo("hello text file 2+2*n={}", 2 + (2 * i)); + } + + auto list = cpy->Export(); + ASSERT_TRUE(list.size()); + + + logger.reset(); // ensure flush + + AuLogInfo("RB contains: {} ({}-{}-{}...)", list.size(), list[0].line, list[1].line, list[2].line); +} + +/** + * Test 1) @ 1'000'000 LogInfo with format + * [2022-03-31 03:14:15] [Debug] | [Benchmark] Push a boat-load of messages to a ring buffer took 225.05837ms + * [2022-03-31 13:05:02] [Debug] | [Benchmark] Push a boat-load of messages to a ring buffer took 227.09539ms + * [2022-03-31 13:05:19] [Debug] | [Benchmark] Push a boat-load of messages to a ring buffer took 228.08899ms + * [2022-03-31 13:05:32] [Debug] | [Benchmark] Push a boat-load of messages to a ring buffer took 224.04797ms + * [2022-03-31 13:05:43] [Debug] | [Benchmark] Push a boat-load of messages to a ring buffer took 228.00956ms + * 225.05837 / 1000000 = 0.00022505837 ms/tick + * 1000 / 0.00022505837 = 4'443'291 entries per second + * at 225ns per formatted LogInfo +*/ +TEST(Echo, BenchmarckRingbuffer) +{ + AuList> sinks; + + auto rb = AuLog::NewRingLoggerShared(10'000); + auto cpy = rb; + ASSERT_TRUE(rb); + ASSERT_TRUE(AuListFromArgs(sinks, AuReference(rb))); + + auto logger = AuLog::NewLoggerShared(sinks); + ASSERT_TRUE(logger); + + { + SysBenchmark("Push a boat-load of messages to a ring buffer"); + for (int i = 0; i < 1'000'000; i++) + { + logger->LogInfo("hello text file 2+2*n={}", 2 + (2 * i)); + } + } +} + +// Enabling this test will bog down deinit, on-crash, or a dtor somewhere +// One does not simply buffer ~400-500MB of data and expect the notoriously slow +// terminal hosts, character devices, and so on to keep up +// Benchmark data is unreliable, though the relevant profiled user-code seems to be limited to a spinlock +#if 0 +TEST(Echo, BenchmarckMain) +{ + { + SysBenchmark("Push a boat-load of messages to a stdout"); + for (int i = 0; i < 1'000'000; i++) + { + AuLogInfo("hello main 2+2*n={}", 2 + (2 * i)); + } + } +} +#endif + +/** + * Test 1) @ 10'000 AuLogInfo with format + * [2022-03-31 13:01:09] [Debug] | [Benchmark] Push a few messages to a stdout took 2.06834ms + * [2022-03-31 13:06:54] [Debug] | [Benchmark] Push a few messages to a stdout took 2.06753ms + * [2022-03-31 13:07:23] [Debug] | [Benchmark] Push a few messages to a stdout took 3.00249ms + * [2022-03-31 13:07:32] [Debug] | [Benchmark] Push a few messages to a stdout took 2.05887ms + * 2 / 10000 = 0.000206834 ms/tick + * 1000 / 0.000206834 = 4'834'795 entries per second + * at 206.834ns per formatted AuLogInfo +*/ +TEST(Echo, BenchmarckLite) +{ + { + SysBenchmark("Push a few messages to a stdout and friends"); + for (int i = 0; i < 10'000; i++) + { + AuLogInfo("hello global logger 2+2*n={}", 2 + (2 * i)); + } + } +} + void RunTests() { Aurora::RuntimeStartInfo info; info.console.fio.enableLogging = false; - info.console.forceToolKitWindow = false; + info.console.asyncVSLog = true; Aurora::RuntimeStart(info); - SayHelloEventLog(); - WriteHelloToEventLogGlobal(); + AuLogInfo("Hello global logger"); } \ No newline at end of file diff --git a/Tests/Public/11. Hello Processes/Main.cpp b/Tests/Public/11. Hello Processes/Main.cpp index 8555a33..69ede2d 100644 --- a/Tests/Public/11. Hello Processes/Main.cpp +++ b/Tests/Public/11. Hello Processes/Main.cpp @@ -35,13 +35,12 @@ TEST(Process, RunSystem) } process->AsWaitable()->Lock(); - AuLogDbg("Exit Code: 0x{:x}", process->GetExitCode()); + AuLogDbg("Exit Code: 0x{:x}", (AuUInt)process->GetExitCode()); } void RunTests() { Aurora::RuntimeStartInfo info; info.console.fio.enableLogging = false; - info.console.forceToolKitWindow = false; Aurora::RuntimeStart(info); } \ No newline at end of file diff --git a/Tests/Public/2. Hello Threading/Main.cpp b/Tests/Public/2. Hello Threading/Main.cpp index a0514a7..11ba9e8 100644 --- a/Tests/Public/2. Hello Threading/Main.cpp +++ b/Tests/Public/2. Hello Threading/Main.cpp @@ -104,6 +104,76 @@ TEST(RWLocks, GodMode) rwlock->AsReadable()->Unlock(); } +/** + * @brief Test write-entrant read-routines +*/ +TEST(RWLocks, GodMode2) +{ + auto rwlock = AuThreadPrimitives::RWLockUnique(); + + // Test exclusive ownership + ASSERT_TRUE(rwlock->AsReadable()->TryLock()); + ASSERT_FALSE(rwlock->AsWritable()->TryLock()); + rwlock->AsReadable()->Unlock(); + + // Test write-entrancy + { + AU_LOCK_GUARD(rwlock->AsWritable()) + + // Enter read routines + ASSERT_TRUE(rwlock->AsReadable()->TryLock()); + ASSERT_TRUE(rwlock->AsReadable()->TryLock()); + ASSERT_TRUE(rwlock->AsReadable()->TryLock()); + + rwlock->AsReadable()->Unlock(); // NOP + rwlock->AsReadable()->Unlock(); // NOP + rwlock->AsReadable()->Unlock(); // NOP + } + + // Confirm release + ASSERT_TRUE(rwlock->AsReadable()->TryLock()); + rwlock->AsReadable()->Unlock(); +} + + +/** + * @brief Test write-entrant read-routines w/ write-mode escalation + * + * UpgradeReadToWrite: + * "Allows for read-to-write upgrades when the decision to esclate is made based upon a shared resource + * "which would be lost by unlocking and relocking in exclusive mode" + * +*/ +TEST(RWLocks, SlashGod) +{ + auto rwlock = AuThreadPrimitives::RWLockUnique(); + + ASSERT_TRUE(rwlock->AsReadable()->TryLock()); + + ASSERT_FALSE(rwlock->AsWritable()->TryLock()); + ASSERT_TRUE(rwlock->UpgradeReadToWrite(0)); + + + { + // Enter read routines + ASSERT_TRUE(rwlock->AsReadable()->TryLock()); + ASSERT_TRUE(rwlock->AsReadable()->TryLock()); + ASSERT_TRUE(rwlock->AsReadable()->TryLock()); + + rwlock->AsReadable()->Unlock(); // NOP + rwlock->AsReadable()->Unlock(); // NOP + rwlock->AsReadable()->Unlock(); // NOP + } + + + ASSERT_TRUE(rwlock->DowngradeWriteToRead()); + ASSERT_FALSE(rwlock->DowngradeWriteToRead()); + + rwlock->AsReadable()->Unlock(); +} + + + /** * @brief Allocates a new thread, dispatches the ep, destroys the thread, and waits a reasonable amount of time * to rejoin until the the context is terminated by the watchdog. In this instance, the thread exists in time. @@ -229,7 +299,7 @@ TEST(Thread, ForcefulExitNoFree) } // TODO: sample and test code for: -// * Events +// * Events (does it run igors piss 7zip code was a good test lmao) // * Condition Variables // * Rentrant Mutexes // * Sleep @@ -241,6 +311,5 @@ void RunTests() { Aurora::RuntimeStartInfo info; info.console.fio.enableLogging = false; - info.console.forceToolKitWindow = false; Aurora::RuntimeStart(info); } \ No newline at end of file diff --git a/Tests/Public/3. Hello Command Line/Main.cpp b/Tests/Public/3. Hello Command Line/Main.cpp index b05000c..286b96f 100644 --- a/Tests/Public/3. Hello Command Line/Main.cpp +++ b/Tests/Public/3. Hello Command Line/Main.cpp @@ -18,9 +18,15 @@ * Despite this, GetFlags and GetValues will unescape \\ on NT platforms. * * EG: "3. Hello Command Line.Stage.Win32.x86_64.exe" --test=Hello\ World + * "3. Hello Command Line.Stage.Win32.x86_64.exe" --test="Hello World" + * "3. Hello Command Line.Stage.Win32.x86_64.exe" --test "Hello World" + * "3. Hello Command Line.Stage.Win32.x86_64.exe" /test="Hello World" + * "3. Hello Command Line.Stage.Win32.x86_64.exe" /test "Hello World" + * "3. Hello Command Line.Stage.Win32.x86_64.exe" test="Hello World" + * "3. Hello Command Line.Stage.Win32.x86_64.exe" test=Hello\ World * [2022-02-20 18:25:48][Info] | Flags: 0 * [2022-02-20 18:25:48][Info] | Values: 1 - * [2022-02-20 18:25:48][Info] | --test=Hello World + * [2022-02-20 18:25:48][Info] | test=Hello World */ static void PrintAll() @@ -51,7 +57,6 @@ void RunTests() { Aurora::RuntimeStartInfo info; info.console.fio.enableLogging = false; - info.console.forceToolKitWindow = false; Aurora::RuntimeStart(info); PrintAll(); diff --git a/Tests/Public/4. Hello FS/Main.cpp b/Tests/Public/4. Hello FS/Main.cpp index c1d6a5c..6b44db2 100644 --- a/Tests/Public/4. Hello FS/Main.cpp +++ b/Tests/Public/4. Hello FS/Main.cpp @@ -8,22 +8,51 @@ #include #include +/* +Blocking read/write test + +Test 1) + Input parameters: 1k cycles, 32B RNG + With 4k ops and 1600ms average + ~= 0.4ms per blocking read/write + +Test 2) + Input parameters: 1k cycles, 64KiB RNG + Result: FS.WriteRead (9248 ms) + + > 9248 / 4 (ops) + 2312 (time per op) + > (64 *1024 * 1000) / 2312 (bytes / ms) + 28346.020761245676 + > 28346 / 1024 (kB / ms) + 27.681640625 + > 27 * 1000 (kB / s) + 27000 + > 27000 / 1024 (mB / s) + 26.3671875 + 26 MB/s or 208Mb/s + +29/03/2022 (under vm vdisk and with nt caching) +*/ TEST(FS, WriteRead) { AuByteBuffer rngbuffer(32); AuByteBuffer inputblob; AuRng::RngFillRange(rngbuffer); - // Write and read back the RNG blob from a read/writable CWD - ASSERT_TRUE(AuIOFS::WriteFile("./test_rng_blob", rngbuffer)); - ASSERT_TRUE(AuIOFS::ReadFile("./test_rng_blob", inputblob)); - ASSERT_EQ(inputblob, rngbuffer); + for (int i = 0; i < 1000; i++) + { + // Write and read back the RNG blob from a read/writable CWD + ASSERT_TRUE(AuIOFS::WriteFile("./test_rng_blob", rngbuffer)); + ASSERT_TRUE(AuIOFS::ReadFile("./test_rng_blob", inputblob)); + ASSERT_EQ(inputblob, rngbuffer); - // Write and read back the RNG blob from a user specific application directory - // Defer to brand: Aurora::RuntimeStartInfo#fio.defaultBrand - ASSERT_TRUE(AuIOFS::WriteFile("~/my_app_rng_blob", rngbuffer)); - ASSERT_TRUE(AuIOFS::ReadFile("~/my_app_rng_blob", inputblob)); - ASSERT_EQ(inputblob, rngbuffer); + // Write and read back the RNG blob from a user specific application directory + // Defer to brand: Aurora::RuntimeStartInfo#fio.defaultBrand + ASSERT_TRUE(AuIOFS::WriteFile("~/my_app_rng_blob", rngbuffer)); + ASSERT_TRUE(AuIOFS::ReadFile("~/my_app_rng_blob", inputblob)); + ASSERT_EQ(inputblob, rngbuffer); + } } TEST(FS, WriteCopyRead) @@ -151,7 +180,6 @@ void RunTests() { Aurora::RuntimeStartInfo info; info.console.fio.enableLogging = false; - info.console.forceToolKitWindow = false; info.fio.defaultBrand = "AuSdkBrand"; Aurora::RuntimeStart(info); diff --git a/Tests/Public/5. Hello Loop/Main.cpp b/Tests/Public/5. Hello Loop/Main.cpp index fcdbb6d..bb75a26 100644 --- a/Tests/Public/5. Hello Loop/Main.cpp +++ b/Tests/Public/5. Hello Loop/Main.cpp @@ -20,13 +20,11 @@ TEST(Loop, Semaphore) ASSERT_TRUE(loop->SourceAdd(semaB)); ASSERT_TRUE(loop->SourceAddWithTimeout(semac, 2000)); - // Commit source changes - ASSERT_TRUE(loop->Commit()); auto semACallback = AuMakeShared([](const AuSPtr &source) -> bool { AuLogInfo("Hello from semaphore a's work queue"); - return false; // dont evict, we'll reuse this *1 + return false; // dont evict, we'll reuse this *1 (search for me) }); auto semBCallback = AuMakeShared([](const AuSPtr &source) -> bool @@ -47,11 +45,15 @@ TEST(Loop, Semaphore) AuLogInfo("C timedout succesfully!"); }); - // Add optional subscriptions (must come after commit) + // Add optional subscriptions ASSERT_TRUE(loop->AddCallback(semaA, semACallback)); ASSERT_TRUE(loop->AddCallback(semaB, semBCallback)); ASSERT_TRUE(loop->AddCallbackEx(semac, semCCallback)); + + // Commit source changes + ASSERT_TRUE(loop->Commit()); + // Dispatch any (IE: semaphore A) non-blocking ASSERT_TRUE(loop->IsSignaled()); @@ -61,6 +63,7 @@ TEST(Loop, Semaphore) // And demonstrate blocking function ASSERT_TRUE(loop->WaitAny(0)); // *1 + // ...or what about now? now will you block? ASSERT_FALSE(loop->WaitAny(1000)); // Trigger A and B @@ -81,10 +84,146 @@ TEST(Loop, Semaphore) ASSERT_TRUE(loop->WaitAll(100)); } + +TEST(Loop, Performance) +{ + SysBenchmark("Loop Performance A"); + + auto semaA = Aurora::Loop::NewLSSemaphore(1); + auto semaB = Aurora::Loop::NewLSSemaphore(0); + auto semac = Aurora::Loop::NewLSSemaphore(0); + auto loop = Aurora::Loop::NewLoopQueue(); + + + auto semACallback = AuMakeShared([](const AuSPtr &source) -> bool + { + //AuLogInfo("Hello from semaphore a's work queue"); + return false; // dont evict, we'll reuse this *1 + }); + + auto semBCallback = AuMakeShared([](const AuSPtr &source) -> bool + { + //AuLogInfo("Hello from semaphore b's work queue"); + return true; // evict + }); + + + auto semCCallback = AuMakeShared([](const AuSPtr &source) -> bool + { + //AuLogInfo("This should not have been triggered from C"); + return false; + }, + + [](const AuSPtr &source) -> void + { + //AuLogInfo("C timedout succesfully!"); + }); + + + /* + ------------------------------------------------------------------------------------ + NT: + + At 10k iterations: + [2022-03-31 13:10:29] [Debug] | [Benchmark] Loop Performance A took 51.01004ms + [2022-03-31 13:10:54] [Debug] | [Benchmark] Loop Performance A took 50.02065ms + + ...not bad, here's why: + Reece, [30/03/2022 19:39] + 1 whole frame (~20Hhz) of work to blast WaitForMultipleObjectsEx/io_submit/epoll abstraction with a test covering multiple apis 10k times/iterations + + Reece, [30/03/2022 19:39] + imagine a scheduling thread working on 10k unique kernel work objects per frame + + Reece, [30/03/2022 19:39] + that alone isn't comparable to sockets because sockets are grouped into 1 worker event per thread + + Reece, [30/03/2022 19:40] + general purpose work should go through semaphores and condition variables, not a unique object per work item + + Reece, [30/03/2022 19:40] + it would be like sleeping on a kernel object 40,000 times per frame + + Reece, [30/03/2022 19:40] + by "like" i mean 10k iterations * 4 apis that can dispatch a callback or yield to kernel + + Reece, [30/03/2022 19:42] + best practices say you dont fucking spam resources. 40k is a hell of a lot more than, idk, checking a file read transaction a few tens-to-hundreds of times a second on an serializer thread that's not-io bound + + + Further data: + VS Profiler reports: 1.6% other, 77.5% IO, kernel: 20% + [TODO: link] + + ...almost all of the overhead is the semaphore callbacks themselves + [TODO: link] + + Needless to say, I think this is alright. + + ------------------------------------------------------------------------------------ + Linux: TODO: io_submit + + + ------------------------------------------------------------------------------------ + BSD: kevent is a long way away + + ------------------------------------------------------------------------------------ + */ + + for (int i = 0; i < 10'000; i++) + { + // Add initial loop sources + ASSERT_TRUE(loop->SourceAdd(semaA)); + ASSERT_TRUE(loop->SourceAdd(semaB)); + ASSERT_TRUE(loop->SourceAddWithTimeout(semac, 2000)); + + // Add optional subscriptions + ASSERT_TRUE(loop->AddCallback(semaA, semACallback)); + ASSERT_TRUE(loop->AddCallback(semaB, semBCallback)); + ASSERT_TRUE(loop->AddCallbackEx(semac, semCCallback)); + + + // Commit source changes + ASSERT_TRUE(loop->Commit()); + + // Dispatch any (IE: semaphore A) non-blocking + ASSERT_TRUE(loop->IsSignaled()); + + // Reuse semaphore A + semaA->AddOne(); // *1 + + // And demonstrate blocking function + ASSERT_TRUE(loop->WaitAny(0)); // *1 + + //ASSERT_FALSE(loop->WaitAny(1000)); + + // Trigger A and B + semaB->AddOne(); + semaA->AddOne(); + + // Dispatch all + ASSERT_TRUE(loop->WaitAny(1000)); + + // Stall for 10s unless A comes alives (it wont) + //loop->WaitAll(10000); + //ASSERT_FALSE(loop->WaitAll(100)); + + // Manually evict semaphore A + loop->SourceRemove(semaA); + loop->SourceRemove(semac); + loop->Commit(); + + ASSERT_TRUE(loop->WaitAll(100)); + + semaA->AddOne(); // account for initial starting count of 1 + } + printf("."); +} + void RunTests() { Aurora::RuntimeStartInfo info; info.console.fio.enableLogging = false; - info.console.forceToolKitWindow = false; + info.console.asyncVSLog = true; Aurora::RuntimeStart(info); } \ No newline at end of file diff --git a/Tests/Public/6. Hello Compression/Main.cpp b/Tests/Public/6. Hello Compression/Main.cpp index 746f23f..15b548f 100644 --- a/Tests/Public/6. Hello Compression/Main.cpp +++ b/Tests/Public/6. Hello Compression/Main.cpp @@ -89,7 +89,7 @@ static AuByteBuffer GetCompressableBlob() return compressMeBytes; } -static void TestBasicCompression(AuCompression::ECompresionType type) +static void TestBasicCompression(AuCompression::ECompressionType type) { auto compressMeBytes = GetCompressableBlob(); @@ -172,7 +172,7 @@ static void TestBasicCompression(AuCompression::ECompresionType type) #define ADD_TESTS_BASIC(algorithm) \ TEST(BasicCompression, algorithm) \ { \ - TestBasicCompression(AuCompression::ECompresionType::e ## algorithm); \ + TestBasicCompression(AuCompression::ECompressionType::e ## algorithm); \ } #define ADD_TESTS(...) AU_FOR_EACH(ADD_TESTS_BASIC, __VA_ARGS__) @@ -183,6 +183,5 @@ void RunTests() { Aurora::RuntimeStartInfo info; info.console.fio.enableLogging = false; - info.console.forceToolKitWindow = false; Aurora::RuntimeStart(info); } \ No newline at end of file diff --git a/Tests/Public/7. Hello Parse/Main.cpp b/Tests/Public/7. Hello Parse/Main.cpp index 40043cd..aa663c7 100644 --- a/Tests/Public/7. Hello Parse/Main.cpp +++ b/Tests/Public/7. Hello Parse/Main.cpp @@ -80,7 +80,7 @@ TEST(Parse, Vararg) { AuParse::ParseBit(AuParse::ParsableTag::kParseUInt, "Alpha"), AuParse::ParseBit(AuParse::ParsableTag::kParseNumber, "Bravo"), - AuParse::ParseBit(AuParse::ParsableTag::kParseString, "String", false, false, true) + AuParse::ParseBit(AuParse::ParsableTag::kParseString, "Charlie", false, false, true) }; AuString str = "4 5.3 \"re eee\" hello world"; @@ -109,7 +109,7 @@ TEST(Parse, Arrays) AuParse::ParseObject exampleStructure = { AuParse::ParseBit(AuParse::ParsableTag::kParseUInt, "Int Alpha"), - AuParse::ParseBit(AuParse::ParsableTag::kParseString, "String Fren", true, false, false) + AuParse::ParseBit(AuParse::ParsableTag::kParseString, "String Bravo", true, false, false) }; AuString str = "4 3 \"re eee\" hello world"; @@ -142,7 +142,7 @@ TEST(Parse, ArraysReserialize) AuParse::ParseObject exampleStructure = { AuParse::ParseBit(AuParse::ParsableTag::kParseUInt, "Int Alpha"), - AuParse::ParseBit(AuParse::ParsableTag::kParseString, "String Fren", true, false, false) + AuParse::ParseBit(AuParse::ParsableTag::kParseString, "String Bravo", true, false, false) }; AuString reserialized; @@ -214,8 +214,8 @@ TEST(Parse, NewLine) AuParse::ParseObject exampleStructure = { AuParse::ParseBit(AuParse::ParsableTag::kParseUInt, "Alpha"), - AuParse::ParseBit(AuParse::ParsableTag::kParseString, "StringHog"), - AuParse::ParseBit(AuParse::ParsableTag::kParseStringVararg, "String") + AuParse::ParseBit(AuParse::ParsableTag::kParseString, "Bravo"), + AuParse::ParseBit(AuParse::ParsableTag::kParseStringVararg, "Charlie") }; AuString magicStringEscaped = "\"world\nhello\""; @@ -250,7 +250,7 @@ TEST(Parse, Escapes) AuParse::ParseObject exampleStructure = { AuParse::ParseBit(AuParse::ParsableTag::kParseUInt, "Alpha"), - AuParse::ParseBit(AuParse::ParsableTag::kParseString, "StringHog"), + AuParse::ParseBit(AuParse::ParsableTag::kParseString, "Bravo"), }; AuString magicStringEscaped = "\"world \\\"hello\""; @@ -280,7 +280,7 @@ TEST(Parse, EscapesReserialize) AuParse::ParseObject exampleStructure = { AuParse::ParseBit(AuParse::ParsableTag::kParseUInt, "Alpha"), - AuParse::ParseBit(AuParse::ParsableTag::kParseString, "StringHog"), + AuParse::ParseBit(AuParse::ParsableTag::kParseString, "Bravo"), }; AuString reserialized; @@ -297,6 +297,5 @@ void RunTests() { Aurora::RuntimeStartInfo info; info.console.fio.enableLogging = false; - info.console.forceToolKitWindow = false; Aurora::RuntimeStart(info); } \ No newline at end of file diff --git a/Tests/Public/8. Hello Locale/Main.cpp b/Tests/Public/8. Hello Locale/Main.cpp index db7d93f..a32627c 100644 --- a/Tests/Public/8. Hello Locale/Main.cpp +++ b/Tests/Public/8. Hello Locale/Main.cpp @@ -85,7 +85,6 @@ void RunTests() { Aurora::RuntimeStartInfo info; info.console.fio.enableLogging = false; - info.console.forceToolKitWindow = false; Aurora::RuntimeStart(info); PrintLocale(); diff --git a/Tests/Public/9. Hello Registry/Main.cpp b/Tests/Public/9. Hello Registry/Main.cpp new file mode 100644 index 0000000..8eed3c3 --- /dev/null +++ b/Tests/Public/9. Hello Registry/Main.cpp @@ -0,0 +1,34 @@ +/*** + Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved. + + File: Main.cpp + Date: 2022-2-18 + Author: Reece +***/ +#include + + +void RunTests() +{ + std::random_device dev; + std::mt19937 mt(dev()); + uuids::uuid_random_generator gen(mt); + + + Aurora::RuntimeStartInfo info; + info.console.fio.enableLogging = false; + Aurora::RuntimeStart(info); + + + + auto A = gen(); + auto B = gen(); + + auto C = uuids::uuid::from_string(A.to_string()); + auto D = uuids::uuid::from_string(B.to_string()); + + SysAssert(C == A); + SysAssert(B == D); + + AuLogDbg("a"); +} \ No newline at end of file diff --git a/Tests/googletest b/Tests/googletest index 955c7f8..af29db7 160000 --- a/Tests/googletest +++ b/Tests/googletest @@ -1 +1 @@ -Subproject commit 955c7f837efad184ec63e771c42542d37545eaef +Subproject commit af29db7ec28d6df1c7f0f745186884091e602e07 diff --git a/Vendor/nlohmannjson b/Vendor/nlohmannjson index e4643d1..66f6b4b 160000 --- a/Vendor/nlohmannjson +++ b/Vendor/nlohmannjson @@ -1 +1 @@ -Subproject commit e4643d1f1b03fc7a1d7b65f17e012ca93680cad8 +Subproject commit 66f6b4b6a0b897e91f7fdd5f6058a8c62137895f diff --git a/Vendor/wxConfig b/Vendor/wxConfig index dc2f997..014af5d 160000 --- a/Vendor/wxConfig +++ b/Vendor/wxConfig @@ -1 +1 @@ -Subproject commit dc2f9971d1f60aa357a758a014b79dd2f31345a5 +Subproject commit 014af5d92895b598e866b441131e43eef9e57dd7 diff --git a/Vendor/wxwidgets b/Vendor/wxwidgets index f81e0ed..37d983e 160000 --- a/Vendor/wxwidgets +++ b/Vendor/wxwidgets @@ -1 +1 @@ -Subproject commit f81e0ed2cbccf2d9ffba4a93b5948f4cf46111d7 +Subproject commit 37d983ef6f3461c19e0e983eb3886e4e6978859f diff --git a/Win_x64_Lite.bat b/Win_x64_Lite.bat new file mode 100644 index 0000000..eb60139 --- /dev/null +++ b/Win_x64_Lite.bat @@ -0,0 +1,2 @@ +cd .\Build_Scripts +win_x64.bat --lite %* diff --git a/Win_x64_NoToolkit.bat b/Win_x64_NoToolkit.bat new file mode 100644 index 0000000..95d9c2a --- /dev/null +++ b/Win_x64_NoToolkit.bat @@ -0,0 +1,2 @@ +cd .\Build_Scripts +win_x64.bat \ No newline at end of file diff --git a/Win_x64_wxWidgets.bat b/Win_x64_wxWidgets.bat new file mode 100644 index 0000000..2e483cd --- /dev/null +++ b/Win_x64_wxWidgets.bat @@ -0,0 +1,2 @@ +cd .\Build_Scripts +win_x64.bat --with-wxWidgets %* diff --git a/Win_x86_Lite.bat b/Win_x86_Lite.bat new file mode 100644 index 0000000..3dfcc04 --- /dev/null +++ b/Win_x86_Lite.bat @@ -0,0 +1,2 @@ +cd .\Build_Scripts +win_x86.bat --lite %*