[+/*] Updated and added a few tests (a hell of a lot more pending)
[*] Update modules [+] Add auROXTL
This commit is contained in:
parent
d3f6124c07
commit
05d9537cbc
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -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
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 68a3479d137610dff8857c9054454ed8704c642c
|
||||
Subproject commit 99b365e260db8b7536d10fafbc7be950251780af
|
1
Aurora/ROXTL
Submodule
1
Aurora/ROXTL
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit a19ae800aa9ba41c185aa4720442fca41732c50d
|
@ -1 +1 @@
|
||||
Subproject commit 260442a68449de7368522dd0f2f7b34871f5de89
|
||||
Subproject commit 7e1bf30131146ac22e08568657b0be0669f343de
|
@ -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({
|
||||
|
||||
if (_OPTIONS["with-wxWidgets"]) then
|
||||
auAddVisit({
|
||||
namespace = kNamespaceGraphics,
|
||||
name = "wxwidgets",
|
||||
path = "Vendor/wxwidgets",
|
||||
type = "SharedLib"
|
||||
})
|
||||
type = "SharedLib",
|
||||
out = "!"
|
||||
})
|
||||
end
|
||||
|
||||
auAddVisit({
|
||||
namespace = kNamespaceStlEx,
|
||||
@ -39,19 +56,21 @@ auAddVisit({
|
||||
type = "StaticLib"
|
||||
})
|
||||
|
||||
auAddVisit({
|
||||
if (not _OPTIONS["lite"]) then
|
||||
auAddVisit({
|
||||
namespace = kNamespaceCompression,
|
||||
name = "bzip2",
|
||||
path = "Vendor/bzip2",
|
||||
type = "StaticLib"
|
||||
})
|
||||
})
|
||||
|
||||
auAddVisit({
|
||||
auAddVisit({
|
||||
namespace = kNamespaceCompression,
|
||||
name = "lz4",
|
||||
path = "Vendor/lz4",
|
||||
type = "StaticLib"
|
||||
})
|
||||
})
|
||||
end
|
||||
|
||||
--auAddVisit({
|
||||
-- namespace = kNamespaceCompression,
|
||||
@ -139,18 +158,45 @@ auAddVisit({
|
||||
})
|
||||
|
||||
auAddVisit({
|
||||
namespace = "Aurora",
|
||||
name = "auROXTL",
|
||||
path = "Aurora/ROXTL",
|
||||
type = "StaticLib"
|
||||
})
|
||||
|
||||
if (_OPTIONS["with-wxWidgets"]) then
|
||||
auAddVisit({
|
||||
namespace = kNamespaceFormats,
|
||||
name = "png",
|
||||
path = "Vendor/libpng",
|
||||
type = "StaticLib"
|
||||
})
|
||||
})
|
||||
|
||||
auAddVisit({
|
||||
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()
|
@ -1 +1 @@
|
||||
Subproject commit ac9d592fbc1b272f25b1b52bf001c021bcf6765f
|
||||
Subproject commit e3dd28450807c05c7e5c2a878d8506c839b4857e
|
137
Tests/Public/0. Hello AuROXTL/Main.cpp
Normal file
137
Tests/Public/0. Hello AuROXTL/Main.cpp
Normal file
@ -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 <AuroraRuntime.hpp>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
TEST(Containers, HashMaps)
|
||||
{
|
||||
struct HelloKey : public AuEnableHashCodeOnData<HelloKey>
|
||||
{
|
||||
AuUInt32 id {};
|
||||
AuUInt8 task {};
|
||||
|
||||
/**
|
||||
* inline HelloKey(const AuRemoveConst_t<AuRemoveReference_t<decltype(id)>> &id ,const AuRemoveConst_t<AuRemoveReference_t<decltype(task)>> &task) : id(id) ,task(task) {}
|
||||
* inline HelloKey(AuRemoveConst_t<AuRemoveReference_t<decltype(id)>> &&id ,AuRemoveConst_t<AuRemoveReference_t<decltype(task)>> &&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<HelloKey, AuString> 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<HelloKey, AuString> 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<AuUInt8> 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<AuUInt16 &, decltype(AuGet<0>(popFront))>);
|
||||
static_assert(AuIsSame_v<AuUInt32 &, decltype(AuGet<0>(popBack))>);
|
||||
|
||||
// TODO:
|
||||
|
||||
// AuTuplePushBack
|
||||
// AuTuplePushFront
|
||||
|
||||
// AuTupleTakeRange
|
||||
|
||||
// AuTupleForEach
|
||||
// AuTupleTransform
|
||||
|
||||
// AuTupleTie
|
||||
// AuTupleForward
|
||||
}
|
||||
|
||||
TEST(Debug, NullPointersThrow)
|
||||
{
|
||||
#if !defined(AURORA_ROXTL_NULL_POINTER_CHECKS_DISABLED)
|
||||
AuSPtr<AuUInt32> 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);
|
||||
}
|
@ -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();
|
||||
|
@ -7,17 +7,19 @@
|
||||
Note: Run the registry template in the ./Aurora/Runtime/Media directory
|
||||
***/
|
||||
#include <AuroraRuntime.hpp>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
static void WriteHelloToEventLogGlobal()
|
||||
|
||||
TEST(Echo, HelloReplacedGlobalLogger)
|
||||
{
|
||||
auto logger = AuLog::NewLoggerShared(AuList<AuSPtr<AuLog::IBasicSink>>{
|
||||
AuLog::NewOSNamedEventDirectorySinkShared("Aurora Demo"),
|
||||
AuLog::NewStdSinkShared()
|
||||
});
|
||||
SysAssert(logger);
|
||||
ASSERT_TRUE(logger);
|
||||
|
||||
AuLog::SetGlobalLogger(logger);
|
||||
AuLogInfo("Hello event log and stdout from from global AuLogInfo shorthand");
|
||||
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");
|
||||
@ -26,23 +28,135 @@ static void WriteHelloToEventLogGlobal()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
AuLog::SetGlobalLogger({});
|
||||
}
|
||||
|
||||
static void SayHelloEventLog()
|
||||
TEST(Echo, HelloEventDir)
|
||||
{
|
||||
auto logger = AuLog::NewLoggerShared(AuList<AuSPtr<AuLog::IBasicSink>>{AuLog::NewOSNamedEventDirectorySinkShared("Aurora Demo")});
|
||||
ASSERT_TRUE(logger);
|
||||
|
||||
logger->LogInfo("hello 2+2={}", 2 + 2);
|
||||
}
|
||||
|
||||
TEST(Echo, TextFile)
|
||||
{
|
||||
{
|
||||
auto logger = AuLog::NewLoggerShared(AuList<AuSPtr<AuLog::IBasicSink>>{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<AuSPtr<AuLog::IBasicSink>> 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<AuSPtr<AuLog::IBasicSink>> 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");
|
||||
}
|
@ -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);
|
||||
}
|
@ -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);
|
||||
}
|
@ -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();
|
||||
|
@ -8,12 +8,40 @@
|
||||
#include <AuroraRuntime.hpp>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
/*
|
||||
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);
|
||||
|
||||
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));
|
||||
@ -24,6 +52,7 @@ TEST(FS, WriteRead)
|
||||
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);
|
||||
|
||||
|
@ -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<Aurora::Loop::ILoopSourceSubscriberFunctional>([](const AuSPtr<Aurora::Loop::ILoopSource> &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<Aurora::Loop::ILoopSourceSubscriberFunctional>([](const AuSPtr<Aurora::Loop::ILoopSource> &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<Aurora::Loop::ILoopSourceSubscriberFunctional>([](const AuSPtr<Aurora::Loop::ILoopSource> &source) -> bool
|
||||
{
|
||||
//AuLogInfo("Hello from semaphore a's work queue");
|
||||
return false; // dont evict, we'll reuse this *1
|
||||
});
|
||||
|
||||
auto semBCallback = AuMakeShared<Aurora::Loop::ILoopSourceSubscriberFunctional>([](const AuSPtr<Aurora::Loop::ILoopSource> &source) -> bool
|
||||
{
|
||||
//AuLogInfo("Hello from semaphore b's work queue");
|
||||
return true; // evict
|
||||
});
|
||||
|
||||
|
||||
auto semCCallback = AuMakeShared<Aurora::Loop::ILoopSourceSubscriberExFunctional>([](const AuSPtr<Aurora::Loop::ILoopSource> &source) -> bool
|
||||
{
|
||||
//AuLogInfo("This should not have been triggered from C");
|
||||
return false;
|
||||
},
|
||||
|
||||
[](const AuSPtr<Aurora::Loop::ILoopSource> &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);
|
||||
}
|
@ -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);
|
||||
}
|
@ -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);
|
||||
}
|
@ -85,7 +85,6 @@ void RunTests()
|
||||
{
|
||||
Aurora::RuntimeStartInfo info;
|
||||
info.console.fio.enableLogging = false;
|
||||
info.console.forceToolKitWindow = false;
|
||||
Aurora::RuntimeStart(info);
|
||||
|
||||
PrintLocale();
|
||||
|
34
Tests/Public/9. Hello Registry/Main.cpp
Normal file
34
Tests/Public/9. Hello Registry/Main.cpp
Normal file
@ -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 <AuroraRuntime.hpp>
|
||||
|
||||
|
||||
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");
|
||||
}
|
@ -1 +1 @@
|
||||
Subproject commit 955c7f837efad184ec63e771c42542d37545eaef
|
||||
Subproject commit af29db7ec28d6df1c7f0f745186884091e602e07
|
2
Vendor/nlohmannjson
vendored
2
Vendor/nlohmannjson
vendored
@ -1 +1 @@
|
||||
Subproject commit e4643d1f1b03fc7a1d7b65f17e012ca93680cad8
|
||||
Subproject commit 66f6b4b6a0b897e91f7fdd5f6058a8c62137895f
|
2
Vendor/wxConfig
vendored
2
Vendor/wxConfig
vendored
@ -1 +1 @@
|
||||
Subproject commit dc2f9971d1f60aa357a758a014b79dd2f31345a5
|
||||
Subproject commit 014af5d92895b598e866b441131e43eef9e57dd7
|
2
Vendor/wxwidgets
vendored
2
Vendor/wxwidgets
vendored
@ -1 +1 @@
|
||||
Subproject commit f81e0ed2cbccf2d9ffba4a93b5948f4cf46111d7
|
||||
Subproject commit 37d983ef6f3461c19e0e983eb3886e4e6978859f
|
2
Win_x64_Lite.bat
Normal file
2
Win_x64_Lite.bat
Normal file
@ -0,0 +1,2 @@
|
||||
cd .\Build_Scripts
|
||||
win_x64.bat --lite %*
|
2
Win_x64_NoToolkit.bat
Normal file
2
Win_x64_NoToolkit.bat
Normal file
@ -0,0 +1,2 @@
|
||||
cd .\Build_Scripts
|
||||
win_x64.bat
|
2
Win_x64_wxWidgets.bat
Normal file
2
Win_x64_wxWidgets.bat
Normal file
@ -0,0 +1,2 @@
|
||||
cd .\Build_Scripts
|
||||
win_x64.bat --with-wxWidgets %*
|
2
Win_x86_Lite.bat
Normal file
2
Win_x86_Lite.bat
Normal file
@ -0,0 +1,2 @@
|
||||
cd .\Build_Scripts
|
||||
win_x86.bat --lite %*
|
Loading…
Reference in New Issue
Block a user