[*] Updated tests

(linux almost certainly will not build post net connect multiple endpoints commit)
This commit is contained in:
Reece Wilson 2023-04-22 01:39:06 +01:00
parent d22eb40b4e
commit 709cb9ca97
16 changed files with 982 additions and 50 deletions

@ -1 +1 @@
Subproject commit 122fc74a669596e200481ada884497854d07c5d1 Subproject commit b61015a6a5fabbdc28f3f4229344c5437d0c26a4

@ -1 +1 @@
Subproject commit 85a575eb9531d92c67cae5a547206494b55f4ebf Subproject commit 62c29d060062f4add0c5c4b59ccad5dde0c3d937

@ -1 +1 @@
Subproject commit 1e9053b9383167eca317a941945ecf5d6a61aed4 Subproject commit 91ee13089027fe3ff80a9514238c5c394ffd2e02

View File

@ -0,0 +1,29 @@
{
"name": "brotli",
"type": "generic",
"include": "c/include",
"sources": [
"c/common/**.*",
"c/dec/**.*",
"c/enc/**.*",
"c/include/**.*"
],
"actions": [
{
"filter": {
"platforms": "mac"
},
"then": {
"defines": "OS_MACOSX"
}
},
{
"filter": {
"platforms": "linux"
},
"then": {
"defines": "OS_LINUX"
}
}
]
}

View File

@ -150,6 +150,50 @@ TEST(Echo, BenchmarkLite)
} }
} }
TEST(FilterNames, GetIdx)
{
auto uIdx = AuLog::LogClassGetNext();
ASSERT_TRUE(uIdx);
AuLogDbg("Got unique id: {}", uIdx.value());
AuLog::LogClassRelease(uIdx.value());
}
TEST(FilterNames, GetIdx2)
{
auto uIdx = AuLog::LogClassGetNext();
ASSERT_TRUE(uIdx);
AuLogDbg("Got unique id: {} (same as last time? or +1 at least?))", uIdx.value());
ASSERT_TRUE(AuLog::LogClassInUse(uIdx.value()));
AuLog::LogClassRelease(uIdx.value());
ASSERT_FALSE(AuLog::LogClassInUse(uIdx.value()));
ASSERT_FALSE(AuLog::LogClassInUse(uIdx.value() - 1));
}
TEST(FilterNames, GetIdx3)
{
auto uIdx = AuLog::LogClassGetNext();
ASSERT_TRUE(uIdx);
AuLogDbg("Got unique id: {} (same as last time? or +1 at least?))", uIdx.value());
ASSERT_TRUE(AuLog::LogClassInUse(uIdx.value()));
AuLog::LogClassRelease(uIdx.value());
ASSERT_FALSE(AuLog::LogClassInUse(uIdx.value()));
ASSERT_FALSE(AuLog::LogClassInUse(uIdx.value() - 1));
}
TEST(FilterNames, Strings)
{
auto uIdx = AuLog::LogClassGetNext();
ASSERT_TRUE(uIdx);
AuLogDbg("Got unique id: {} (same as last time? or +1 at least?))", uIdx.value());
ASSERT_TRUE(AuLog::LogClassInUse(uIdx.value()));
static const auto kString = "hello world";
AuLog::LogClassAssociateName(uIdx.value(), kString);
ASSERT_EQ(AuLog::LogClassGetNameUnsafe(uIdx.value()), kString);
AuLog::LogClassRelease(uIdx.value());
ASSERT_FALSE(AuLog::LogClassInUse(uIdx.value()));
ASSERT_TRUE(AuLog::LogClassGetNameUnsafe(uIdx.value()).empty());
}
void RunTests() void RunTests()
{ {
Aurora::RuntimeStartInfo info; Aurora::RuntimeStartInfo info;

View File

@ -237,6 +237,178 @@ TEST(Net, ConnectGoogleIP2022)
} }
} }
TEST(Net, ConnectGoogleIP2022SingleshotEvent)
{
auto pIoProcessor = AuIO::NewIOProcessorNoQueue(false);
ASSERT_TRUE(bool(pIoProcessor));
auto pNetProcessor = AuNet::NewNetworkInterface();
ASSERT_TRUE(bool(pNetProcessor));
auto pNetWorker = pNetProcessor->GetWorkersService()->Attach(pIoProcessor);
ASSERT_TRUE(bool(pNetWorker));
auto pStats = AuMakeShared<DriverStat>();
ASSERT_TRUE(bool(pStats));
auto pDriver = NewTestSocketDriver(pStats);
ASSERT_TRUE(bool(pDriver));
auto pRealDriver = AuMakeShared<AuNet::ISocketDriverFunctional>();
static AuSPtr<AuNet::ISocket> gDriverSocket;
pRealDriver->OnPreestablishFunctional = [&](const AuSPtr<AuNet::ISocket> &socket) -> bool
{
gDriverSocket = socket;
return true;
};
pRealDriver->OnEstablishFunctional = [&]()
{
auto pChannel = gDriverSocket->ToChannel();
pChannel->AsStreamWriter()->Write(AuMemoryViewRead("GET / HTTP/1.1\r\nConnection: close\r\n\r\n", 37));
};
pRealDriver->OnFatalErrorReportedFunctional = [&](const AuNet::NetError &error)
{
AuLogDbg("[3] On error: {}", NetErrorToExtendedString(error));
};
pRealDriver->OnStreamUpdatedFunctional = [&]()
{
auto pChannel = gDriverSocket->ToChannel();
auto pReader = pChannel->AsReadableByteBuffer();
AuString message;
message.resize(pReader->RemainingBytes());
pReader->Read(message.data(), message.size());
AuLogDbg("Stream updated: {}", message);
};
pDriver->pProxy = pRealDriver;
AuNet::NetSocketConnect nsConnect;
nsConnect.pDriver = pDriver;
nsConnect.endpoint = AuNet::NetEndpoint(AuNet::ETransportProtocol::eProtocolTCP, kHTTP11Address, 80);
auto pSocket = pNetProcessor->GetSocketService()->Connect(nsConnect);
ASSERT_TRUE(bool(pSocket));
auto pSocketListener = AuMakeShared<AuNet::ISocketChannelEventListenerFunctional>();
pSocketListener->OnDataFunctional = []()
{
AuLogDbg("ISocketChannelEventListenerFunctional::OnDataFunctional");
// singleshot / reject after 1
return false;
};
pSocketListener->OnRejectedFunctional = []()
{
AuLogDbg("ISocketChannelEventListenerFunctional::OnRejectedFunctional");
};
pSocketListener->OnCompleteFunctional = []()
{
AuLogDbg("ISocketChannelEventListenerFunctional::OnCompleteFunctional");
};
pSocket->ToChannel()->AddEventListener(pSocketListener);
while (pIoProcessor->HasItems())
{
pIoProcessor->RunTick();
}
}
TEST(Net, ConnectGoogleIP2022Multiple)
{
auto pIoProcessor = AuIO::NewIOProcessorNoQueue(false);
ASSERT_TRUE(bool(pIoProcessor));
auto pNetProcessor = AuNet::NewNetworkInterface();
ASSERT_TRUE(bool(pNetProcessor));
auto pNetWorker = pNetProcessor->GetWorkersService()->Attach(pIoProcessor);
ASSERT_TRUE(bool(pNetWorker));
auto pStats = AuMakeShared<DriverStat>();
ASSERT_TRUE(bool(pStats));
auto pDriver = NewTestSocketDriver(pStats);
ASSERT_TRUE(bool(pDriver));
auto pRealDriver = AuMakeShared<AuNet::ISocketDriverFunctional>();
static AuSPtr<AuNet::ISocket> gDriverSocket;
pRealDriver->OnPreestablishFunctional = [&](const AuSPtr<AuNet::ISocket> &socket) -> bool
{
gDriverSocket = socket;
return true;
};
pRealDriver->OnEstablishFunctional = [&]()
{
auto pChannel = gDriverSocket->ToChannel();
pChannel->AsStreamWriter()->Write(AuMemoryViewRead("GET / HTTP/1.1\r\nConnection: close\r\n\r\n", 37));
};
pRealDriver->OnFatalErrorReportedFunctional = [&](const AuNet::NetError &error)
{
AuLogDbg("[3] On error: {}", NetErrorToExtendedString(error));
};
pRealDriver->OnStreamUpdatedFunctional = [&]()
{
auto pChannel = gDriverSocket->ToChannel();
auto pReader = pChannel->AsReadableByteBuffer();
AuString message;
message.resize(pReader->RemainingBytes());
pReader->Read(message.data(), message.size());
AuLogDbg("Stream updated: {}", message);
};
pDriver->pProxy = pRealDriver;
AuNet::NetSocketConnect nsConnect;
nsConnect.pDriver = pDriver;
nsConnect.endpoint = AuNet::NetEndpoint(AuNet::ETransportProtocol::eProtocolTCP, kHTTP11Address, 80);
auto pSocket = pNetProcessor->GetSocketService()->Connect(nsConnect);
ASSERT_TRUE(bool(pSocket));
auto pSocketListener = AuMakeShared<AuNet::ISocketChannelEventListenerFunctional>();
pSocketListener->OnDataFunctional = []()
{
AuLogDbg("ISocketChannelEventListenerFunctional::OnDataFunctional (multiple)");
return true;
};
pSocketListener->OnRejectedFunctional = []()
{
AuLogDbg("ISocketChannelEventListenerFunctional::OnRejectedFunctional (multiple)");
};
pSocketListener->OnCompleteFunctional = []()
{
AuLogDbg("ISocketChannelEventListenerFunctional::OnCompleteFunctional (multiple)");
};
pSocket->ToChannel()->AddEventListener(pSocketListener);
while (pIoProcessor->HasItems())
{
pIoProcessor->RunTick();
}
}
TEST(Resolve, GoogleA) TEST(Resolve, GoogleA)
{ {
auto pIoProcessor = AuIO::NewIOProcessorNoQueue(false); auto pIoProcessor = AuIO::NewIOProcessorNoQueue(false);
@ -301,33 +473,6 @@ TEST(Resolve, GoogleAAAA)
} }
} }
TEST(Adapters, Print)
{
auto pNetProcessor = AuNet::NewNetworkInterface();
ASSERT_TRUE(bool(pNetProcessor));
AuLogInfo("Hostname: {}", pNetProcessor->GetInterfacesService()->GetHostname());
auto ifaces = pNetProcessor->GetInterfacesService()->GetAdapters();
for (const auto &pAdapter : ifaces)
{
AuString dns = "";
for (const auto &dnsIP : pAdapter->GetDNS())
{
dns += fmt::format(" dns-server={}", dnsIP.ToString());
}
AuLogInfo("Found adapter interface (family: {}): \n\tName: {}\n\tDevice: {}\n\tAddress: {}\n\tMulticast: {}\n\tGateway: {}\n\tDNS: {}\n\n",
AuNet::EIPProtocolToString(pAdapter->ToFamily()),
pAdapter->ToName(),
pAdapter->ToDevice(),
pAdapter->ToAddress().ToString(),
pAdapter->ToBroadcastAddress().ToString(),
pAdapter->ToGateway().ToString(),
dns);
}
}
void RunTests() void RunTests()
{ {
Aurora::RuntimeStartInfo info; Aurora::RuntimeStartInfo info;

View File

@ -81,7 +81,6 @@ TEST(DemoTelemetryPoke, TelemetryHint)
} }
} }
TEST(Demo, ThrowStringLiteral) TEST(Demo, ThrowStringLiteral)
{ {
try try
@ -100,11 +99,6 @@ TEST(DemoTelemetryPoke, ErrnoHint)
AuDebug::CheckErrors(); AuDebug::CheckErrors();
} }
TEST(DemoSysError, AA)
{
SysPushErrorGeneric("Hello World");
}
TEST(DemoAssert, A) TEST(DemoAssert, A)
{ {
SysAssertExp(true, "i will not fail {}", 100); SysAssertExp(true, "i will not fail {}", 100);

View File

@ -8,6 +8,65 @@
#include <AuroraRuntime.hpp> #include <AuroraRuntime.hpp>
#include <gtest/gtest.h> #include <gtest/gtest.h>
#if defined(AURORA_IS_MODERNNT_DERIVED)
#define TO_PROVE_A_POINT
#include <shared_mutex>
#include <windows.h>
#include <semaphore>
#endif
TEST(Allocationless, SOO)
{
AuThreadPrimitives::ConditionMutexSOO condMutex;
AuThreadPrimitives::ConditionVariableSOO condVariable(AuUnsafeRaiiToShared(condMutex.AsPointer()));
AuThreadPrimitives::MutexSOO mutex;
AuThreadPrimitives::EventSOO event(false, true, false);
AuThreadPrimitives::SemaphoreSOO semaphore;
AuThreadPrimitives::CriticalSectionSOO cs;
AuThreadPrimitives::RWLockSOO rwLock;
AuThreadPrimitives::RWRenterableLockSOO rwLock2;
#if defined(TO_PROVE_A_POINT)
static_assert(sizeof(AuThreadPrimitives::MutexSOO) < sizeof(std::mutex));
static_assert(sizeof(AuThreadPrimitives::MutexSOO) <= sizeof(std::mutex) / 5); // to really prove a point
// we can be up-to 4x faster, usually at least a few ms at scale.
static_assert(sizeof(AuThreadPrimitives::RWLockSOO) < sizeof(std::shared_timed_mutex));
static_assert(sizeof(AuThreadPrimitives::RWLockSOO) < (sizeof(std::shared_timed_mutex) / 2));
static_assert(230 < sizeof(std::shared_timed_mutex));
static_assert(103 < sizeof(AuThreadPrimitives::RWLockSOO));
static_assert(sizeof(AuThreadPrimitives::MutexSOO) < sizeof(SRWLOCK) + sizeof(CONDITION_VARIABLE) + 4); // (SRWLOCKs are too dumb to used by themselves)
static_assert(sizeof(AuThreadPrimitives::ConditionVariableSOO) < sizeof(std::condition_variable));
static_assert(sizeof(AuThreadPrimitives::ConditionMutexSOO) < sizeof(std::mutex));
static_assert(sizeof(AuThreadPrimitives::CriticalSectionSOO) < sizeof(CRITICAL_SECTION));
static_assert(sizeof(AuThreadPrimitives::MutexSOO) <= sizeof(SRWLOCK) + 8 /*vtable*/); // should be more featureful than a SRWLock
// Optimized OS range given this SOO overhead: Windows NT 5.1 through Win 11.
// AuRT could be dropped down to XP, if not for other subsystems and deps.
ASSERT_TRUE(AuSwInfo::IsWindowsXPOrGreater()); // ok this doesnt prove a point, but still
ASSERT_FALSE(!AuSwInfo::IsWindowsXPOrGreater());
// 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
// here's some fails where you might be able optimize a bit if you cared so deeply about shaving a few bytes off for
// less optimization, more slow compatibility layers, and lower res yielding, just to, i dont know, be forced into
// "windows 8+ optimization?" "ucrt optimization?" to save like 8-16 bytes???
#if 0
static_assert(sizeof(AuThreadPrimitives::SemaphoreSOO) <= sizeof(SRWLOCK) + sizeof(CONDITION_VARIABLE) + 4);
static_assert(sizeof(AuThreadPrimitives::MutexSOO) <= sizeof(SRWLOCK));
static_assert(sizeof(AuThreadPrimitives::RWLockSOO) <= sizeof(std::shared_lock<std::shared_mutex>)); // optimized around winshit apis, not IWaitable
// note: performance will suffer under the stl under older windows versions
static_assert(sizeof(AuThreadPrimitives::SemaphoreSOO) <= sizeof(std::counting_semaphore)); // once again, this is optimized for a win8+ interface, and will suffer under older oses
// wont cuck our apis into being this small and intentionally bad. im not microsoft.
#endif
#endif
}
/** /**
* @brief Single threaded mutex lock test (rentrant mutexes are called critical sections in this subsystem) * @brief Single threaded mutex lock test (rentrant mutexes are called critical sections in this subsystem)
*/ */
@ -18,12 +77,185 @@ TEST(Mutex, LockTest)
ASSERT_FALSE(mutex->TryLock()); ASSERT_FALSE(mutex->TryLock());
mutex->Unlock(); mutex->Unlock();
ASSERT_TRUE(mutex->TryLock()); ASSERT_TRUE(mutex->TryLock());
ASSERT_FALSE(mutex->Lock(10)); ASSERT_FALSE(mutex->LockMS(10));
mutex->Unlock(); mutex->Unlock();
ASSERT_TRUE(mutex->TryLock()); ASSERT_TRUE(mutex->TryLock());
mutex->Unlock(); mutex->Unlock();
} }
TEST(Mutex, Benchmark)
{
{
SysBenchmark("Mutex Benchmark 1'000'000");
for (AU_ITERATE_N(i, 1'000'000))
{
AuThreadPrimitives::MutexSOO mutex;
AU_LOCK_GUARD(mutex);
}
}
{
SysBenchmark("Mutex 2 Benchmark 1'000'000 [no-new]");
AuThreadPrimitives::MutexSOO mutex;
for (AU_ITERATE_N(i, 1'000'000))
{
AU_LOCK_GUARD(mutex);
}
}
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// Windows 7 users should see a 14-20ms deviation here!!!
// Windows 8-11 users should see a 8ms deviation here!!!
// (relative to Mutex 1 Benchmark)
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
{
SysBenchmark("Mutex 3 Benchmark 1'000'000 [MS-STL]");
for (AU_ITERATE_N(i, 1'000'000))
{
std::mutex mutex;
std::lock_guard gross(mutex);
}
}
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// Windows 7 users should see a 8-15ms deviation here!!!
// Windows 8-11 users should see a 8ms deviation here!!!
// (relative to Mutex 2 Benchmark)
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
{
SysBenchmark("Mutex 4 Benchmark 1'000'000 [no-new] [MS-STL]");
std::mutex mutex;
for (AU_ITERATE_N(i, 1'000'000))
{
std::lock_guard gross(mutex);
}
}
#if defined(AURORA_IS_MODERNNT_DERIVED)
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// Windows Vista through Windows 11 users should see a 2-3ms deviation here!!!
// (relative to Mutex 1 Benchmark)
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
{
SysBenchmark("Mutex 5 Benchmark 1'000'000 [SRW-Lock]");
for (AU_ITERATE_N(i, 1'000'000))
{
SRWLOCK lock;
InitializeSRWLock(&lock);
AcquireSRWLockExclusive(&lock);
ReleaseSRWLockExclusive(&lock);
}
}
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// Windows Vista through Windows 11 users should see a 4-5ms deviation here!!!
// (relative to Mutex 2 Benchmark)
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
{
SysBenchmark("Mutex 6 Benchmark 1'000'000 [no-new] [SRW-Lock]");
SRWLOCK lock;
InitializeSRWLock(&lock);
for (AU_ITERATE_N(i, 1'000'000))
{
AcquireSRWLockExclusive(&lock);
ReleaseSRWLockExclusive(&lock);
}
}
#endif
/*
Windows 7, i9 9900k (Q4 2018) @ 5GHz under KVM (v5.16.16), modified OVMF/EDK II, and modified QEMU:
08:13:17 [Debug] | [Benchmark] Mutex Benchmark 1'000'000 took 10.23965ms
08:13:17 [Debug] | [Benchmark] Mutex 2 Benchmark 1'000'000 [no-new] took 8.14648ms
08:13:17 [Debug] | [Benchmark] Mutex 3 Benchmark 1'000'000 [MS-STL] took 22.51583ms
08:13:17 [Debug] | [Benchmark] Mutex 4 Benchmark 1'000'000 [no-new] [MS-STL] took 18.39793ms
08:13:17 [Debug] | [Benchmark] Mutex 5 Benchmark 1'000'000 [SRW-Lock] took 12.35815ms
08:13:17 [Debug] | [Benchmark] Mutex 6 Benchmark 1'000'000 [no-new] [SRW-Lock] took 11.59034ms
08:13:47 [Debug] | [Benchmark] Mutex Benchmark 1'000'000 took 10.36226ms
08:13:47 [Debug] | [Benchmark] Mutex 2 Benchmark 1'000'000 [no-new] took 8.37862ms
08:13:47 [Debug] | [Benchmark] Mutex 3 Benchmark 1'000'000 [MS-STL] took 21.23885ms
08:13:47 [Debug] | [Benchmark] Mutex 4 Benchmark 1'000'000 [no-new] [MS-STL] took 19.33754ms
08:13:47 [Debug] | [Benchmark] Mutex 5 Benchmark 1'000'000 [SRW-Lock] took 12.31698ms
08:13:47 [Debug] | [Benchmark] Mutex 6 Benchmark 1'000'000 [no-new] [SRW-Lock] took 11.25236ms
08:14:45 [Debug] | [Benchmark] Mutex Benchmark 1'000'000 took 10.64171ms
08:14:45 [Debug] | [Benchmark] Mutex 2 Benchmark 1'000'000 [no-new] took 8.151ms
08:14:45 [Debug] | [Benchmark] Mutex 3 Benchmark 1'000'000 [MS-STL] took 26.10599ms
08:14:45 [Debug] | [Benchmark] Mutex 4 Benchmark 1'000'000 [no-new] [MS-STL] took 20.5948ms
08:14:45 [Debug] | [Benchmark] Mutex 5 Benchmark 1'000'000 [SRW-Lock] took 13.47083ms
08:14:45 [Debug] | [Benchmark] Mutex 6 Benchmark 1'000'000 [no-new] [SRW-Lock] took 12.53163ms
08:15:21 [Debug] | [Benchmark] Mutex Benchmark 1'000'000 took 10.10466ms
08:15:21 [Debug] | [Benchmark] Mutex 2 Benchmark 1'000'000 [no-new] took 8.74967ms
08:15:21 [Debug] | [Benchmark] Mutex 3 Benchmark 1'000'000 [MS-STL] took 24.1452ms
08:15:21 [Debug] | [Benchmark] Mutex 4 Benchmark 1'000'000 [no-new] [MS-STL] took 17.68036ms
08:15:21 [Debug] | [Benchmark] Mutex 5 Benchmark 1'000'000 [SRW-Lock] took 12.21169ms
08:15:21 [Debug] | [Benchmark] Mutex 6 Benchmark 1'000'000 [no-new] [SRW-Lock] took 11.26151ms
08:18:35 [Debug] | [Benchmark] Mutex Benchmark 1'000'000 took 12.05167ms
08:18:35 [Debug] | [Benchmark] Mutex 2 Benchmark 1'000'000 [no-new] took 8.80412ms
08:18:35 [Debug] | [Benchmark] Mutex 3 Benchmark 1'000'000 [MS-STL] took 27.12312ms
08:18:35 [Debug] | [Benchmark] Mutex 4 Benchmark 1'000'000 [no-new] [MS-STL] took 20.42462ms
08:18:35 [Debug] | [Benchmark] Mutex 5 Benchmark 1'000'000 [SRW-Lock] took 12.6167ms
08:18:35 [Debug] | [Benchmark] Mutex 6 Benchmark 1'000'000 [no-new] [SRW-Lock] took 12.41549ms
08:28:07 [Debug] | [Benchmark] Mutex Benchmark 1'000'000 took 12.85569ms
08:28:07 [Debug] | [Benchmark] Mutex 2 Benchmark 1'000'000 [no-new] took 9.33194ms
08:28:07 [Debug] | [Benchmark] Mutex 3 Benchmark 1'000'000 [MS-STL] took 21.12753ms
08:28:07 [Debug] | [Benchmark] Mutex 4 Benchmark 1'000'000 [no-new] [MS-STL] took 20.86612ms
08:28:07 [Debug] | [Benchmark] Mutex 5 Benchmark 1'000'000 [SRW-Lock] took 12.4472ms
08:28:07 [Debug] | [Benchmark] Mutex 6 Benchmark 1'000'000 [no-new] [SRW-Lock] took 11.39755ms|
Windows 11, i9 9900k (Q4 2018) @ 5GHz under KVM (v5.16.16) and stock OVMF/EDK II bootstrapped by stock QEMU (v7.1.) via libvirtd:
TBD
Windows 11, i7 12700kf (Q4 2021) @ Turbo 5 GHz:
13:37:43 [Debug] | [Benchmark] Mutex Benchmark 1'000'000 took 8.4802ms
13:37:43 [Debug] | [Benchmark] Mutex 2 Benchmark 1'000'000 [no-new] took 7.2406ms
13:37:43 [Debug] | [Benchmark] Mutex 3 Benchmark 1'000'000 [MS-STL] took 15.6057ms
13:37:43 [Debug] | [Benchmark] Mutex 4 Benchmark 1'000'000 [no-new] [MS-STL] took 12.0535ms
13:37:44 [Debug] | [Benchmark] Mutex 5 Benchmark 1'000'000 [SRW-Lock] took 14.4723ms
13:37:44 [Debug] | [Benchmark] Mutex 6 Benchmark 1'000'000 [no-new] [SRW-Lock] took 11.7877ms
13:38:54 [Debug] | [Benchmark] Mutex Benchmark 1'000'000 took 8.3546ms
13:38:54 [Debug] | [Benchmark] Mutex 2 Benchmark 1'000'000 [no-new] took 7.0924ms
13:38:54 [Debug] | [Benchmark] Mutex 3 Benchmark 1'000'000 [MS-STL] took 15.6814ms
13:38:54 [Debug] | [Benchmark] Mutex 4 Benchmark 1'000'000 [no-new] [MS-STL] took 11.9347ms
13:38:54 [Debug] | [Benchmark] Mutex 5 Benchmark 1'000'000 [SRW-Lock] took 14.4644ms
13:38:54 [Debug] | [Benchmark] Mutex 6 Benchmark 1'000'000 [no-new] [SRW-Lock] took 11.7549ms
13:39:37 [Debug] | [Benchmark] Mutex Benchmark 1'000'000 took 8.3741ms
13:39:37 [Debug] | [Benchmark] Mutex 2 Benchmark 1'000'000 [no-new] took 7.105ms
13:39:37 [Debug] | [Benchmark] Mutex 3 Benchmark 1'000'000 [MS-STL] took 15.4845ms
13:39:37 [Debug] | [Benchmark] Mutex 4 Benchmark 1'000'000 [no-new] [MS-STL] took 11.9213ms
13:39:37 [Debug] | [Benchmark] Mutex 5 Benchmark 1'000'000 [SRW-Lock] took 14.432ms
13:39:37 [Debug] | [Benchmark] Mutex 6 Benchmark 1'000'000 [no-new] [SRW-Lock] took 11.759ms
13:40:14 [Debug] | [Benchmark] Mutex Benchmark 1'000'000 took 8.3792ms
13:40:14 [Debug] | [Benchmark] Mutex 2 Benchmark 1'000'000 [no-new] took 7.1186ms
13:40:14 [Debug] | [Benchmark] Mutex 3 Benchmark 1'000'000 [MS-STL] took 16.3227ms
13:40:14 [Debug] | [Benchmark] Mutex 4 Benchmark 1'000'000 [no-new] [MS-STL] took 11.7837ms
13:40:14 [Debug] | [Benchmark] Mutex 5 Benchmark 1'000'000 [SRW-Lock] took 15.9249ms
13:40:14 [Debug] | [Benchmark] Mutex 6 Benchmark 1'000'000 [no-new] [SRW-Lock] took 11.4668ms
13:40:47 [Debug] | [Benchmark] Mutex Benchmark 1'000'000 took 8.3893ms
13:40:47 [Debug] | [Benchmark] Mutex 2 Benchmark 1'000'000 [no-new] took 7.0334ms
13:40:47 [Debug] | [Benchmark] Mutex 3 Benchmark 1'000'000 [MS-STL] took 16.3345ms
13:40:47 [Debug] | [Benchmark] Mutex 4 Benchmark 1'000'000 [no-new] [MS-STL] took 11.7077ms
13:40:47 [Debug] | [Benchmark] Mutex 5 Benchmark 1'000'000 [SRW-Lock] took 16.5125ms
13:40:47 [Debug] | [Benchmark] Mutex 6 Benchmark 1'000'000 [no-new] [SRW-Lock] took 11.148ms
*/
}
/** /**
* @brief Spinlock lock test * @brief Spinlock lock test
*/ */
@ -34,7 +266,7 @@ TEST(Spinlock, LockTest)
ASSERT_FALSE(mutex.TryLock()); ASSERT_FALSE(mutex.TryLock());
mutex.Unlock(); mutex.Unlock();
ASSERT_TRUE(mutex.TryLock()); ASSERT_TRUE(mutex.TryLock());
ASSERT_FALSE(mutex.Lock(10)); ASSERT_FALSE(mutex.LockMS(10));
mutex.Unlock(); mutex.Unlock();
ASSERT_TRUE(mutex.TryLock()); ASSERT_TRUE(mutex.TryLock());
mutex.Unlock(); mutex.Unlock();
@ -49,7 +281,7 @@ TEST(Semaphore, LockTest)
ASSERT_FALSE(semaphore->TryLock()); ASSERT_FALSE(semaphore->TryLock());
semaphore->Unlock(1); semaphore->Unlock(1);
ASSERT_TRUE(semaphore->TryLock()); ASSERT_TRUE(semaphore->TryLock());
ASSERT_FALSE(semaphore->Lock(10)); ASSERT_FALSE(semaphore->LockMS(10));
semaphore->Unlock(2); semaphore->Unlock(2);
ASSERT_TRUE(semaphore->TryLock()); ASSERT_TRUE(semaphore->TryLock());
ASSERT_TRUE(semaphore->TryLock()); ASSERT_TRUE(semaphore->TryLock());
@ -118,7 +350,7 @@ TEST(RWLocks, GodMode2)
// Test write-entrancy // Test write-entrancy
{ {
AU_LOCK_GUARD(rwlock->AsWritable()) AU_LOCK_GUARD(rwlock->AsWritable());
// Enter read routines // Enter read routines
ASSERT_TRUE(rwlock->AsReadable()->TryLock()); ASSERT_TRUE(rwlock->AsReadable()->TryLock());
@ -135,7 +367,6 @@ TEST(RWLocks, GodMode2)
rwlock->AsReadable()->Unlock(); rwlock->AsReadable()->Unlock();
} }
/** /**
* @brief Test write-entrant read-routines w/ write-mode escalation * @brief Test write-entrant read-routines w/ write-mode escalation
* *
@ -172,7 +403,214 @@ TEST(RWLocks, SlashGod)
rwlock->AsReadable()->Unlock(); rwlock->AsReadable()->Unlock();
} }
// Test RWLocks in critical section mode
TEST(RWLocks, DoubleReentrant)
{
AuThreadPrimitives::RWRenterableLockSOO rwlock;
// Test exclusive ownership
ASSERT_TRUE(rwlock->AsReadable()->TryLock());
ASSERT_FALSE(rwlock->AsWritable()->TryLock());
rwlock->AsReadable()->Unlock();
// Test write-entrancy
{
AU_LOCK_GUARD(rwlock->AsWritable());
// test thread-local 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();
}
TEST(WakeOnAddress, WaitOnConstantForTimeout5Milliseconds)
{
ASSERT_TRUE(AuSwInfo::IsWindowsXPOrGreater() || AuBuild::kIsLinuxDerived || true); // heres your forced thy must upgrade to windows 8+ "limitation"
AuUInt32 uAtomic {};
AuUInt32 uExpect { 0 };
ASSERT_FALSE(AuThreading::WaitOnAddress(&uAtomic, &uExpect, sizeof(AuUInt32), AuMSToNS<AuUInt32>(5)));
}
TEST(WakeOnAddress, WaitOnConstantForTimeout5Seconds)
{
ASSERT_TRUE(AuSwInfo::IsWindowsXPOrGreater() || AuBuild::kIsLinuxDerived || true);
AuUInt32 uAtomic {};
AuUInt32 uExpect { 0 };
ASSERT_FALSE(AuThreading::WaitOnAddress(&uAtomic, &uExpect, sizeof(AuUInt32), AuMSToNS<AuUInt64>(AuSToMS<AuUInt32>(5))));
}
TEST(WakeOnAddress, WaitOnUnexpectedConstantForTimeout5Seconds)
{
ASSERT_TRUE(AuSwInfo::IsWindowsXPOrGreater() || AuBuild::kIsLinuxDerived || true);
AuUInt32 uAtomic { 0 };
AuUInt32 uExpect { 1 };
ASSERT_TRUE(AuThreading::WaitOnAddress(&uAtomic, &uExpect, sizeof(AuUInt32), AuMSToNS<AuUInt64>(AuSToMS<AuUInt32>(5))));
}
TEST(WaitOnAddress, WaitOnConstantForTimeout20SecondsUpdateAfter5)
{
ASSERT_TRUE(AuSwInfo::IsWindowsXPOrGreater() || AuBuild::kIsLinuxDerived || true);
AuUInt32 uAtomic { 0 };
AuUInt32 uExpect { 0 };
AuUInt32 uUpdate { 1 };
AuUInt64 uEndTime { AuTime::SteadyClockNS() + AuMSToNS<AuUInt64>(AuSToMS<AuUInt64>(5)) };
AuUInt64 uTimeFromAlert {};
AuUInt64 uTimeToAlert {};
auto thread = AuThreads::ThreadUnique(AuThreads::ThreadInfo(
AuMakeShared<AuThreads::IThreadVectorsFunctional>(
[&](AuThreads::IAuroraThread *pThread)
{
while (uEndTime > AuTime::SteadyClockNS()) AuThreading::ContextYield();
uAtomic = uUpdate;
uTimeFromAlert = AuTime::SteadyClockNS();
AuThreading::WakeOnAddress(&uAtomic);
},
AuThreads::IThreadVectorsFunctional::OnExit_t {}),
"PokeWaitAddress"
));
ASSERT_TRUE(bool(thread));
ASSERT_TRUE(thread->Run());
ASSERT_TRUE(AuThreading::WaitOnAddress(&uAtomic, &uExpect, sizeof(AuUInt32), AuMSToNS<AuUInt64>(AuSToMS<AuUInt32>(20))));
uTimeToAlert = AuTime::SteadyClockNS();
AuLogDbg("[WaitOnAddress, WaitOnConstantForTimeout20SecondsUpdateAfter5] Time to alert: {}", uTimeToAlert - uTimeFromAlert);
}
TEST(WaitOnAddress, WaitOnConstantForTimeout20SecondsUpdateAfter50ms)
{
ASSERT_TRUE(AuSwInfo::IsWindowsXPOrGreater() || AuBuild::kIsLinuxDerived || true);
AuUInt32 uAtomic { 0 };
AuUInt32 uExpect { 0 };
AuUInt32 uUpdate { 1 };
AuUInt64 uEndTime { };
AuUInt64 uTimeFromAlert {};
AuUInt64 uTimeToAlert {};
AuThreadPrimitives::SemaphoreSOO semaphore;
AuThreadPrimitives::SemaphoreSOO semaphore2;
auto thread = AuThreads::ThreadUnique(AuThreads::ThreadInfo(
AuMakeShared<AuThreads::IThreadVectorsFunctional>(
[&](AuThreads::IAuroraThread *pThread)
{
semaphore2->Unlock(1);
semaphore->Lock();
while (uEndTime > AuTime::SteadyClockNS()) AuThreading::ContextYield();
uAtomic = uUpdate;
uTimeFromAlert = AuTime::SteadyClockNS();
AuThreading::WakeOnAddress(&uAtomic);
},
AuThreads::IThreadVectorsFunctional::OnExit_t {}),
"PokeWaitAddress"
));
ASSERT_TRUE(bool(thread));
ASSERT_TRUE(thread->Run());
semaphore2->Lock();
{
uEndTime = { AuTime::SteadyClockNS() + AuMSToNS<AuUInt64>(50) };
semaphore->Unlock(1);
{
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// Windows 7 users as compared to Windows 8.1+/11 users should see a 0.02-0.05ms deviation here!!!
// (Win7: ~24'000 - ~30'000 nanosecond overshoot from expected wakeup time)
// (Win11: ~1'000 - 5'100 nanosecond overshoot from expected wakeup time)
// (native windows 11 support blows us out of the water, but at least vista + 7 and/or installations
// of legacy hardware arent left behind. even xp has an unoptimized implementation of the underlying
// keyedevent primitive. though, you would be at the point of wanting an nt 4 fork to run well. )
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
SysBenchmark("WaitOnAddress/WakeOnAddress remote poke in 50ms");
ASSERT_TRUE(AuThreading::WaitOnAddress(&uAtomic, &uExpect, sizeof(AuUInt32), AuMSToNS<AuUInt64>(AuSToMS<AuUInt32>(20))));
uTimeToAlert = AuTime::SteadyClockNS();
}
// ...Windows 7 again: expect to see a factor of 4-6x slowdown in time to wake
// trust me bro numbers i9 9900k @ 5Ghz (emulated):
// * rare undershoots: ~23'000
// * more often than not ~24'700 - 38'000
// * worst case peaks: ~55'000
// * very very rarely: ~70'000
// and Windows 11 (8+ native), i7 12700KF @ 5Ghz:
// * rare undershoots: ~4'800
// * more often than not ~5'100
// * worst case peaks: ~30'000
// and Windows 11 (8+ native), i7 12700KF @ 5Ghz (emulated - patched to force it):
// * around: ~7'500
// and Microsofts game developer docs state:
// * expect 5,000 nanosecond switches on the Xbox
// * target 1,000 switches per second (seems low?)
//
// " Use this topic to learn how to find threads that are frequently context switching—degrading your title's performance.
// " Context switching is the process of storing the state of a thread so that it can be restored to resume execution at a later point in time.
// " Rapid context switching between threads is expensive in terms of CPU utilization. Each context switch takes the kernel about 5 μs (on average) to process.
// " However, the resulting Cache misses add additional execution time that is difficult to quantify.
// " The more frequent the context switches, the more your CPU utilization degrades.
// " Each title is different, but a reasonable goal is to have fewer than 1,000 context switches per second, per core. "
// - GDK docs
//
// Tick-based kernels with out improved chipset drivers are indisputably 4-6 slower, yet its not in the ball park of mattering
// Considering worst case of 0.05ms overshoots @ 144 hz using Microsofts suggested target switch rate of 1'000:
// > (1000 - (0.005 * 1000 * 0)) / 144 (Best case)
// 6.944444444444445
//
// > (1000 - (0.005 * 1000 * 1)) / 144 (Win11 best case)
// 6.909722222222222
//
// > (1000 - (0.05 * 1000 * 1)) / 144 (Win 7 average ballpark)
// 6.597222222222222
//
// > (1000 - (0.02 * 1000 * 1)) / 144 (Win 7 average ballpark)
// 6.805555555555555
//
// > (1000 - (0.02 * 10000 * 1)) / 144 (0.02ms optimistic but reasonable, 10'000 iterations)
// 5.555555555555555
// ~= 1.4ms for 10'000 switches (?)
//
// > (1000 - (0.005 * 10000 * 1)) / 144 (Windows 11 worst case at 10'000 iterations)
// 6.597222222222222
// ~= 0.347ms for 10'000 switches (?)
// ~4x slower in emulation mode UNDER a crippled kernel. Win10+ can be forced into emu mode and achieve much faster results.
// ...implying the 4x slowdown is the improvement between os generations? not the sync interface?
// ...maybe hardware?
//
// -> No real game-breaking difference in CPU time allocation for any given 144 Hhz frame. Even an order of magnitude increase wouldn't make a difference.
// Two orders, maybe so; just don't target hundreds of thousands of switches per second. It should be possible to still get ok performance out of Windows 7.
// Saving ~1ms in a frame allocation would be nice, but i'll take that trade-off for a sync primitive that doesnt exist.
//
// Note: Windows 7s best case, assuming atomics are always being followed and preemptive fast-paths are considered, should always match other unsupported
// Operating Systems with comparable hardware. Specifically platforms without a known or stable futex interface.
// That above mucho-texto is more representative of switch speeds in the worst case. Windows 11 under emulation mode will perform much much faster than 7.
// Best and average cases (respecters of the smt backoff value - `uSpinLoopPowerA`) should be more comparable between emulated WaitOnAddress platforms.
AuLogDbg("[WaitOnAddress, WaitOnConstantForTimeout20SecondsUpdateAfter50ms] Time to alert: {}", uTimeToAlert - uTimeFromAlert);
}
}
/** /**
* @brief Allocates a new thread, dispatches the ep, destroys the thread, and waits a reasonable amount of time * @brief Allocates a new thread, dispatches the ep, destroys the thread, and waits a reasonable amount of time
@ -311,5 +749,8 @@ void RunTests()
{ {
Aurora::RuntimeStartInfo info; Aurora::RuntimeStartInfo info;
info.console.fio.enableLogging = false; info.console.fio.enableLogging = false;
info.threadingConfig.uSpinLoopPowerA = 7;
Aurora::RuntimeStart(info); Aurora::RuntimeStart(info);
AuThreads::GetThread()->SetPriority(AuThreads::EThreadPriority::ePrioRT);
} }

View File

@ -147,6 +147,13 @@ TEST(Map, IPC)
} }
} }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Unmodified Windows 7 Runtimes will start to fail here.
// It is possible to get this to run with the help of a driver.
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TEST(Reserve, HasInterface) TEST(Reserve, HasInterface)
{ {
ASSERT_TRUE(bool(AuProcess::ReserveAddressSpace(4096 * 2))); ASSERT_TRUE(bool(AuProcess::ReserveAddressSpace(4096 * 2)));

View File

@ -49,11 +49,15 @@ TEST(FS, WriteRead)
for (int i = 0; i < 1000; i++) for (int i = 0; i < 1000; i++)
{ {
inputblob.writePtr = inputblob.base;
// Write and read back the RNG blob from a read/writable CWD // Write and read back the RNG blob from a read/writable CWD
ASSERT_TRUE(AuIOFS::WriteFile("./test_rng_blob", rngbuffer)); ASSERT_TRUE(AuIOFS::WriteFile("./test_rng_blob", rngbuffer));
ASSERT_TRUE(AuIOFS::ReadFile("./test_rng_blob", inputblob)); ASSERT_TRUE(AuIOFS::ReadFile("./test_rng_blob", inputblob));
ASSERT_EQ(inputblob, rngbuffer); ASSERT_EQ(inputblob, rngbuffer);
inputblob.writePtr = inputblob.base;
// Write and read back the RNG blob from a user specific application directory // Write and read back the RNG blob from a user specific application directory
// Defer to brand: Aurora::RuntimeStartInfo#fio.defaultBrand // Defer to brand: Aurora::RuntimeStartInfo#fio.defaultBrand
ASSERT_TRUE(AuIOFS::WriteFile("~/my_app_rng_blob", rngbuffer)); ASSERT_TRUE(AuIOFS::WriteFile("~/my_app_rng_blob", rngbuffer));
@ -359,6 +363,62 @@ static void PrintSystemRoot()
// * file stream objects // * file stream objects
// * stat // * stat
TEST(FS, TestBlock)
{
if (AuCmdLine::HasValue("block"))
{
AuLogDbg("Blocking file...");
ASSERT_TRUE(AuFS::BlockFile(AuCmdLine::GetValue("block")));
}
}
TEST(FS, TestUnblock)
{
if (AuCmdLine::HasValue("unblock"))
{
AuLogDbg("Unblocking file...");
ASSERT_TRUE(AuFS::UnblockFile(AuCmdLine::GetValue("unblock")));
}
}
TEST(FS, TestTrust)
{
if (AuCmdLine::HasValue("trust"))
{
AuLogDbg("Trusting file...");
ASSERT_TRUE(AuFS::TrustFile(AuCmdLine::GetValue("trust")));
}
}
TEST(FS, TestCompress)
{
if (AuCmdLine::HasValue("compress"))
{
AuLogDbg("Compressing file...");
ASSERT_TRUE(AuFS::Compress(AuCmdLine::GetValue("compress")));
}
}
TEST(FS, TestDecompress)
{
if (AuCmdLine::HasValue("decompress"))
{
AuLogDbg("Decompressing file...");
ASSERT_TRUE(AuFS::Decompress(AuCmdLine::GetValue("decompress")));
}
}
TEST(FS, TestListAttr)
{
if (AuCmdLine::HasValue("attrs"))
{
auto list = AuFS::FileAttrsList(AuCmdLine::GetValue("attrs"));
AuLogDbg("Found attrs: {}", list);
}
}
void RunTests() void RunTests()
{ {
Aurora::RuntimeStartInfo info; Aurora::RuntimeStartInfo info;

View File

@ -251,7 +251,7 @@ TEST(BasicCompression, algorithm) \
#define ADD_TESTS(...) AU_FOR_EACH(ADD_TESTS_BASIC, __VA_ARGS__) #define ADD_TESTS(...) AU_FOR_EACH(ADD_TESTS_BASIC, __VA_ARGS__)
ADD_TESTS(LZ4, ZSTD, BZIP2, Deflate, Zip, GZip); ADD_TESTS(LZ4, ZSTD, BZIP2, Deflate, Zip, GZip, Brotli);
void RunTests() void RunTests()
{ {

View File

@ -12,6 +12,7 @@ static void TestPath(const AuString &handleString)
auto pipeImported = AuIPC::ImportPipe(handleString); auto pipeImported = AuIPC::ImportPipe(handleString);
SysAssert(bool(pipeImported)); SysAssert(bool(pipeImported));
new decltype(pipeImported)(pipeImported); // Leak :S new decltype(pipeImported)(pipeImported); // Leak :S
// // If we dont call any dtors and the server recovers, theres no client-side pipe trickery going on
//SysAssert(pipeImported->AsReadChannelIsOpen()->IsSignaled()); //SysAssert(pipeImported->AsReadChannelIsOpen()->IsSignaled());
@ -33,10 +34,10 @@ static void TestPath(const AuString &handleString)
SysAssert(transactionB->StartWrite(0, AuUnsafeRaiiToShared(&writeView))); SysAssert(transactionB->StartWrite(0, AuUnsafeRaiiToShared(&writeView)));
// Create loop to sync against the two outstanding IO requests // Create loop to sync against the outstanding IO requests
auto loop = AuLoop::NewLoopQueue(); auto loop = AuLoop::NewLoopQueue();
// Add initial loop sources // Add initial loop source[s]
SysAssert(loop->SourceAdd(transactionB->NewLoopSource())); SysAssert(loop->SourceAdd(transactionB->NewLoopSource()));
SysAssert(loop->Commit()); SysAssert(loop->Commit());

View File

@ -133,7 +133,7 @@ TEST(Net, TLSGoogle)
(const AuSPtr<AuIO::TLS::ICertificateChain> &pChain, (const AuSPtr<AuIO::TLS::ICertificateChain> &pChain,
const AuMemoryViewRead &derCertificate) -> bool const AuMemoryViewRead &derCertificate) -> bool
{ {
AuLogDbg("Incoming handshake..."); AuLogDbg("Incoming 2 handshake...");
for (AuUInt32 i = 0; i < pChain->GetCertificateCount(); i++) for (AuUInt32 i = 0; i < pChain->GetCertificateCount(); i++)
{ {
auto details = pChain->GetCertificateDetails(i); auto details = pChain->GetCertificateDetails(i);
@ -199,6 +199,105 @@ TEST(Net, TLSGoogle)
} }
} }
TEST(Net, DnsTLSGoogle)
{
auto pIoProcessor = AuIO::NewIOProcessorNoQueue(false);
ASSERT_TRUE(bool(pIoProcessor));
auto pNetProcessor = AuNet::NewNetworkInterface();
ASSERT_TRUE(bool(pNetProcessor));
auto pNetWorker = pNetProcessor->GetWorkersService()->Attach(pIoProcessor);
ASSERT_TRUE(bool(pNetWorker));
auto pStats = AuMakeShared<DriverStat>();
ASSERT_TRUE(bool(pStats));
auto pDriver = NewTestSocketDriver(pStats);
ASSERT_TRUE(bool(pDriver));
auto pRealDriver = AuMakeShared<AuNet::ISocketDriverFunctional>();
static AuSPtr<AuNet::ISocket> gDriverSocket;
pRealDriver->OnPreestablishFunctional = [&](const AuSPtr<AuNet::ISocket> &socket) -> bool
{
#define ENABLE_TLS
#if defined(ENABLE_TLS)
Aurora::IO::TLS::TLSMeta tlsMeta;
tlsMeta.bIsClient = true;
tlsMeta.client.sSNIServerName = "google.com";
tlsMeta.pCertPin = AuMakeSharedThrow<AuIO::TLS::IPinCertificateFunctional>([]
(const AuSPtr<AuIO::TLS::ICertificateChain> &pChain,
const AuMemoryViewRead &derCertificate) -> bool
{
AuLogDbg("Incoming handshake...");
for (AuUInt32 i = 0; i < pChain->GetCertificateCount(); i++)
{
auto details = pChain->GetCertificateDetails(i);
auto cert = pChain->GetCertificate(i);
AuLogDbg("{}: {} (from {})", i, details.subject.commonName, details.issuer.commonName);
}
return true;
});
auto pContext = Aurora::IO::TLS::NewTLSContextEx(socket->ToChannel()->NewProtocolSendStack(),
socket->ToChannel()->NewProtocolRecvStack(),
tlsMeta);
pContext->Attach(socket);
pContext->StartHandshake();
#endif
gDriverSocket = socket;
return true;
};
pRealDriver->OnEstablishFunctional = [&]()
{
auto pChannel = gDriverSocket->ToChannel();
pChannel->AsStreamWriter()->Write(AuMemoryViewRead("GET / HTTP/1.1\r\nConnection: close\r\n\r\n", 37));
};
pRealDriver->OnFatalErrorReportedFunctional = [&](const AuNet::NetError &error)
{
AuLogDbg("[3] On error: {}", NetErrorToExtendedString(error));
};
pRealDriver->OnStreamUpdatedFunctional = [&]()
{
auto pChannel = gDriverSocket->ToChannel();
auto pReader = pChannel->AsReadableByteBuffer();
AuString message;
message.resize(pReader->RemainingBytes());
pReader->Read(message.data(), message.size());
AuLogDbg("Stream updated: {}", message);
};
pRealDriver->OnFinalizeFunctional = [&]()
{
AuLogDbg("[3] On finalize");
};
pDriver->pProxy = pRealDriver;
AuNet::NetSocketConnect nsConnect;
nsConnect.pDriver = pDriver;
nsConnect.byHost.netHostname = AuNet::NetHostname("google.com");
nsConnect.byHost.uPort = 443;
nsConnect.byHost.protocol = AuNet::ETransportProtocol::eProtocolTCP;
auto pSocket = pNetProcessor->GetSocketService()->Connect(nsConnect);
ASSERT_TRUE(bool(pSocket));
while (pIoProcessor->HasItems())
{
pIoProcessor->RunTick();
}
}
void RunTests() void RunTests()
{ {
Aurora::RuntimeStartInfo info; Aurora::RuntimeStartInfo info;

View File

@ -0,0 +1,112 @@
/***
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 <Aurora/IO/IOExperimental.hpp>
#include <Aurora/IO/Net/NetExperimental.hpp>
#include <gtest/gtest.h>
TEST(Net, ServerDemo)
{
auto pIoProcessor = AuIO::NewIOProcessorNoQueue(false);
ASSERT_TRUE(bool(pIoProcessor));
auto pNetProcessor = AuNet::NewNetworkInterface();
ASSERT_TRUE(bool(pNetProcessor));
auto pNetWorker = pNetProcessor->GetWorkersService()->Attach(pIoProcessor);
ASSERT_TRUE(bool(pNetWorker));
auto pSocketFactory = AuMakeShared<AuNet::ISocketDriverFactoryFunctional>();
ASSERT_TRUE(bool(pSocketFactory));
pSocketFactory->NewSocketDriverFunctional = []() -> AuSPtr<AuNet::ISocketDriver>
{
struct TempDriver : AuNet::ISocketDriverFunctional
{
AuSPtr<AuNet::ISocket> pDriverSocket;
};
auto pRealDriver = AuMakeShared<TempDriver>();
pRealDriver->OnPreestablishFunctional = [=](const AuSPtr<AuNet::ISocket> &socket) -> bool
{
pRealDriver->pDriverSocket = socket;
return true;
};
pRealDriver->OnEstablishFunctional = [=]()
{
auto pChannel = pRealDriver->pDriverSocket->ToChannel();
pChannel->AsStreamWriter()->Write(AuMemoryViewRead("Hello World", 11));
};
pRealDriver->OnFatalErrorReportedFunctional = [=](const AuNet::NetError &error)
{
AuLogDbg("[2] On error: {}", NetErrorToExtendedString(error));
};
pRealDriver->OnStreamUpdatedFunctional = [=]()
{
auto pChannel = pRealDriver->pDriverSocket->ToChannel();
auto pReader = pChannel->AsReadableByteBuffer();
AuString message;
message.resize(pReader->RemainingBytes());
pReader->Read(message.data(), message.size());
AuLogDbg("[2] Got: {}", message);
};
pRealDriver->OnFinalizeFunctional = [=]()
{
AuResetMember(*pRealDriver.get()); // reset circular dependence on captured pRealDriver
AuLogDbg("[2] Finalize");
};
return pRealDriver;
};
auto pServerDriver = AuMakeShared<AuNet::ISocketServerDriverFunctional>();
ASSERT_TRUE(bool(pServerDriver));
pServerDriver->OnBindFunctional = [&]()
{
AuLogDbg("[1] On bind");
};
pServerDriver->OnFatalErrorReportedFunctional = [&](const AuNet::NetError &error)
{
AuLogDbg("[1] On error: {}", NetErrorToExtendedString(error));
};
pServerDriver->OnFinalizeFunctional = [&]()
{
AuLogDbg("[1] On finalize");
};
AuNet::NetSocketBind nsSocketBind;
nsSocketBind.pDriver = pServerDriver;
nsSocketBind.ip = AuNet::IPAddress("127.0.0.1");
nsSocketBind.protocol = AuNet::ETransportProtocol::eProtocolTCP;
nsSocketBind.uPort = 8087;
nsSocketBind.pFactory = pSocketFactory;
auto pSocket = pNetProcessor->GetSocketService()->NewServer(nsSocketBind);
ASSERT_TRUE(bool(pSocket));
while (pIoProcessor->HasItems())
{
pIoProcessor->RunTick();
}
}
void RunTests()
{
Aurora::RuntimeStartInfo info;
info.console.fio.enableLogging = false;
Aurora::RuntimeStart(info);
}

@ -1 +1 @@
Subproject commit 9c332145b71c36a5bad9688312c79184f98601ff Subproject commit 783d00fd19865fcbc3065e3fb3e17144761fcf5a

2
Vendor/nlohmannjson vendored

@ -1 +1 @@
Subproject commit a3e6e26dc83a726b292f5be0492fcc408663ce55 Subproject commit 6af826d0bdb55e4b69e3ad817576745335f243ca