mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2024-12-27 12:46:03 +00:00
unit testing: catch -> doctest (faster compile, thread-safe)
This commit is contained in:
parent
fcc7ce49d9
commit
14ad2f0ba0
11 changed files with 6728 additions and 18098 deletions
File diff suppressed because it is too large
Load diff
6583
tests/TestSvc/source/doctest.h
Normal file
6583
tests/TestSvc/source/doctest.h
Normal file
File diff suppressed because it is too large
Load diff
|
@ -15,8 +15,8 @@
|
||||||
*/
|
*/
|
||||||
#include <stratosphere.hpp>
|
#include <stratosphere.hpp>
|
||||||
|
|
||||||
#define CATCH_CONFIG_RUNNER
|
#define DOCTEST_CONFIG_IMPLEMENT
|
||||||
#include "util_catch.hpp"
|
#include "util_test_framework.hpp"
|
||||||
|
|
||||||
namespace ams {
|
namespace ams {
|
||||||
|
|
||||||
|
@ -62,7 +62,13 @@ namespace ams {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Run tests. */
|
/* Run tests. */
|
||||||
Catch::Session().run(os::GetHostArgc(), os::GetHostArgv());
|
{
|
||||||
|
doctest::Context ctx;
|
||||||
|
|
||||||
|
ctx.applyCommandLine(os::GetHostArgc(), os::GetHostArgv());
|
||||||
|
|
||||||
|
ctx.run();
|
||||||
|
}
|
||||||
|
|
||||||
AMS_INFINITE_LOOP();
|
AMS_INFINITE_LOOP();
|
||||||
|
|
||||||
|
@ -72,7 +78,7 @@ namespace ams {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Catch {
|
namespace doctest {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
@ -89,14 +95,13 @@ namespace Catch {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream& cout() {
|
std::ostream& get_cout() {
|
||||||
static std::ostream ret(new OutputDebugStringStream);
|
static std::ostream ret(new OutputDebugStringStream);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
std::ostream& clog() {
|
|
||||||
return cout();
|
std::ostream& get_cerr() {
|
||||||
}
|
return get_cout();
|
||||||
std::ostream& cerr() {
|
|
||||||
return clog();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -37,12 +37,12 @@ namespace ams::test {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CATCH_TEST_CASE( "The scheduler is preemptive at the preemptive priority and cooperative for all other priorities" ) {
|
DOCTEST_TEST_CASE( "The scheduler is preemptive at the preemptive priority and cooperative for all other priorities" ) {
|
||||||
/* Create heap. */
|
/* Create heap. */
|
||||||
ScopedHeap heap(3 * os::MemoryPageSize);
|
ScopedHeap heap(3 * os::MemoryPageSize);
|
||||||
CATCH_REQUIRE(R_SUCCEEDED(svc::SetMemoryPermission(heap.GetAddress() + os::MemoryPageSize, os::MemoryPageSize, svc::MemoryPermission_None)));
|
DOCTEST_CHECK(R_SUCCEEDED(svc::SetMemoryPermission(heap.GetAddress() + os::MemoryPageSize, os::MemoryPageSize, svc::MemoryPermission_None)));
|
||||||
ON_SCOPE_EXIT {
|
ON_SCOPE_EXIT {
|
||||||
CATCH_REQUIRE(R_SUCCEEDED(svc::SetMemoryPermission(heap.GetAddress() + os::MemoryPageSize, os::MemoryPageSize, svc::MemoryPermission_ReadWrite)));
|
DOCTEST_CHECK(R_SUCCEEDED(svc::SetMemoryPermission(heap.GetAddress() + os::MemoryPageSize, os::MemoryPageSize, svc::MemoryPermission_ReadWrite)));
|
||||||
};
|
};
|
||||||
const uintptr_t sp_0 = heap.GetAddress() + 1 * os::MemoryPageSize;
|
const uintptr_t sp_0 = heap.GetAddress() + 1 * os::MemoryPageSize;
|
||||||
const uintptr_t sp_1 = heap.GetAddress() + 3 * os::MemoryPageSize;
|
const uintptr_t sp_1 = heap.GetAddress() + 3 * os::MemoryPageSize;
|
||||||
|
@ -56,21 +56,21 @@ namespace ams::test {
|
||||||
g_spinloop = true;
|
g_spinloop = true;
|
||||||
|
|
||||||
/* Create threads. */
|
/* Create threads. */
|
||||||
CATCH_REQUIRE(R_SUCCEEDED(svc::CreateThread(thread_handles + 0, reinterpret_cast<uintptr_t>(&TestPreemptionPriorityThreadFunction), reinterpret_cast<uintptr_t>(thread_executed + 0), sp_0, priority, core)));
|
DOCTEST_CHECK(R_SUCCEEDED(svc::CreateThread(thread_handles + 0, reinterpret_cast<uintptr_t>(&TestPreemptionPriorityThreadFunction), reinterpret_cast<uintptr_t>(thread_executed + 0), sp_0, priority, core)));
|
||||||
CATCH_REQUIRE(R_SUCCEEDED(svc::CreateThread(thread_handles + 1, reinterpret_cast<uintptr_t>(&TestPreemptionPriorityThreadFunction), reinterpret_cast<uintptr_t>(thread_executed + 1), sp_1, priority, core)));
|
DOCTEST_CHECK(R_SUCCEEDED(svc::CreateThread(thread_handles + 1, reinterpret_cast<uintptr_t>(&TestPreemptionPriorityThreadFunction), reinterpret_cast<uintptr_t>(thread_executed + 1), sp_1, priority, core)));
|
||||||
|
|
||||||
/* Start threads. */
|
/* Start threads. */
|
||||||
CATCH_REQUIRE(R_SUCCEEDED(svc::StartThread(thread_handles[0])));
|
DOCTEST_CHECK(R_SUCCEEDED(svc::StartThread(thread_handles[0])));
|
||||||
CATCH_REQUIRE(R_SUCCEEDED(svc::StartThread(thread_handles[1])));
|
DOCTEST_CHECK(R_SUCCEEDED(svc::StartThread(thread_handles[1])));
|
||||||
|
|
||||||
/* Wait long enough that we can be confident the threads have been balanced. */
|
/* Wait long enough that we can be confident the threads have been balanced. */
|
||||||
svc::SleepThread(PreemptionTimeSpan.GetNanoSeconds() * 10);
|
svc::SleepThread(PreemptionTimeSpan.GetNanoSeconds() * 10);
|
||||||
|
|
||||||
/* Check that we're in a coherent state. */
|
/* Check that we're in a coherent state. */
|
||||||
if (IsPreemptionPriority(core, priority)) {
|
if (IsPreemptionPriority(core, priority)) {
|
||||||
CATCH_REQUIRE(thread_executed[0] & thread_executed[1]);
|
DOCTEST_CHECK((thread_executed[0] & thread_executed[1]));
|
||||||
} else {
|
} else {
|
||||||
CATCH_REQUIRE(thread_executed[0] ^ thread_executed[1]);
|
DOCTEST_CHECK((thread_executed[0] ^ thread_executed[1]));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Stop spinlooping. */
|
/* Stop spinlooping. */
|
||||||
|
@ -78,12 +78,12 @@ namespace ams::test {
|
||||||
|
|
||||||
/* Wait for threads to exit. */
|
/* Wait for threads to exit. */
|
||||||
s32 dummy;
|
s32 dummy;
|
||||||
CATCH_REQUIRE(R_SUCCEEDED(svc::WaitSynchronization(std::addressof(dummy), thread_handles + 0, 1, -1)));
|
DOCTEST_CHECK(R_SUCCEEDED(svc::WaitSynchronization(std::addressof(dummy), thread_handles + 0, 1, -1)));
|
||||||
CATCH_REQUIRE(R_SUCCEEDED(svc::WaitSynchronization(std::addressof(dummy), thread_handles + 1, 1, -1)));
|
DOCTEST_CHECK(R_SUCCEEDED(svc::WaitSynchronization(std::addressof(dummy), thread_handles + 1, 1, -1)));
|
||||||
|
|
||||||
/* Close thread handles. */
|
/* Close thread handles. */
|
||||||
CATCH_REQUIRE(R_SUCCEEDED(svc::CloseHandle(thread_handles[0])));
|
DOCTEST_CHECK(R_SUCCEEDED(svc::CloseHandle(thread_handles[0])));
|
||||||
CATCH_REQUIRE(R_SUCCEEDED(svc::CloseHandle(thread_handles[1])));
|
DOCTEST_CHECK(R_SUCCEEDED(svc::CloseHandle(thread_handles[1])));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,81 +52,81 @@ namespace ams::test {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CATCH_TEST_CASE("svc::SetHeapSize") {
|
DOCTEST_TEST_CASE("svc::SetHeapSize") {
|
||||||
svc::MemoryInfo mem_info;
|
svc::MemoryInfo mem_info;
|
||||||
svc::PageInfo page_info;
|
svc::PageInfo page_info;
|
||||||
uintptr_t dummy;
|
uintptr_t dummy;
|
||||||
|
|
||||||
/* Reset the heap. */
|
/* Reset the heap. */
|
||||||
uintptr_t addr;
|
uintptr_t addr;
|
||||||
CATCH_REQUIRE(R_SUCCEEDED(svc::SetHeapSize(std::addressof(addr), 0)));
|
DOCTEST_CHECK(R_SUCCEEDED(svc::SetHeapSize(std::addressof(addr), 0)));
|
||||||
|
|
||||||
/* Ensure that we don't leak memory. */
|
/* Ensure that we don't leak memory. */
|
||||||
const size_t initial_memory = GetPhysicalMemorySizeAvailable();
|
const size_t initial_memory = GetPhysicalMemorySizeAvailable();
|
||||||
ON_SCOPE_EXIT { CATCH_REQUIRE(initial_memory == GetPhysicalMemorySizeAvailable()); };
|
ON_SCOPE_EXIT { DOCTEST_CHECK(initial_memory == GetPhysicalMemorySizeAvailable()); };
|
||||||
|
|
||||||
CATCH_SECTION("Unaligned and too big sizes fail") {
|
DOCTEST_SUBCASE("Unaligned and too big sizes fail") {
|
||||||
for (size_t i = 1; i < svc::HeapSizeAlignment; i = util::AlignUp(i + 1, os::MemoryPageSize)){
|
for (size_t i = 1; i < svc::HeapSizeAlignment; i = util::AlignUp(i + 1, os::MemoryPageSize)){
|
||||||
CATCH_REQUIRE(svc::ResultInvalidSize::Includes(svc::SetHeapSize(std::addressof(dummy), i)));
|
DOCTEST_CHECK(svc::ResultInvalidSize::Includes(svc::SetHeapSize(std::addressof(dummy), i)));
|
||||||
}
|
}
|
||||||
CATCH_REQUIRE(svc::ResultInvalidSize::Includes(svc::SetHeapSize(std::addressof(dummy), 64_GB)));
|
DOCTEST_CHECK(svc::ResultInvalidSize::Includes(svc::SetHeapSize(std::addressof(dummy), 64_GB)));
|
||||||
}
|
}
|
||||||
|
|
||||||
CATCH_SECTION("Larger size than address space fails") {
|
DOCTEST_SUBCASE("Larger size than address space fails") {
|
||||||
CATCH_REQUIRE(svc::ResultOutOfMemory::Includes(svc::SetHeapSize(std::addressof(dummy), util::AlignUp(svc::AddressMemoryRegionHeap39Size + 1, svc::HeapSizeAlignment))));
|
DOCTEST_CHECK(svc::ResultOutOfMemory::Includes(svc::SetHeapSize(std::addressof(dummy), util::AlignUp(svc::AddressMemoryRegionHeap39Size + 1, svc::HeapSizeAlignment))));
|
||||||
}
|
}
|
||||||
|
|
||||||
CATCH_SECTION("Bounded by resource limit") {
|
DOCTEST_SUBCASE("Bounded by resource limit") {
|
||||||
CATCH_REQUIRE(svc::ResultLimitReached::Includes(svc::SetHeapSize(std::addressof(dummy), util::AlignUp(GetPhysicalMemorySizeMax() + 1, svc::HeapSizeAlignment))));
|
DOCTEST_CHECK(svc::ResultLimitReached::Includes(svc::SetHeapSize(std::addressof(dummy), util::AlignUp(GetPhysicalMemorySizeMax() + 1, svc::HeapSizeAlignment))));
|
||||||
CATCH_REQUIRE(svc::ResultLimitReached::Includes(svc::SetHeapSize(std::addressof(dummy), util::AlignUp(GetPhysicalMemorySizeAvailable() + 1, svc::HeapSizeAlignment))));
|
DOCTEST_CHECK(svc::ResultLimitReached::Includes(svc::SetHeapSize(std::addressof(dummy), util::AlignUp(GetPhysicalMemorySizeAvailable() + 1, svc::HeapSizeAlignment))));
|
||||||
}
|
}
|
||||||
|
|
||||||
CATCH_SECTION("SetHeapSize gives heap memory") {
|
DOCTEST_SUBCASE("SetHeapSize gives heap memory") {
|
||||||
CATCH_REQUIRE(R_SUCCEEDED(svc::SetHeapSize(std::addressof(addr), svc::HeapSizeAlignment)));
|
DOCTEST_CHECK(R_SUCCEEDED(svc::SetHeapSize(std::addressof(addr), svc::HeapSizeAlignment)));
|
||||||
TestMemory(addr, svc::HeapSizeAlignment, svc::MemoryState_Normal, svc::MemoryPermission_ReadWrite, 0);
|
TestMemory(addr, svc::HeapSizeAlignment, svc::MemoryState_Normal, svc::MemoryPermission_ReadWrite, 0);
|
||||||
|
|
||||||
CATCH_REQUIRE(R_SUCCEEDED(svc::SetHeapSize(std::addressof(addr), 0)));
|
DOCTEST_CHECK(R_SUCCEEDED(svc::SetHeapSize(std::addressof(addr), 0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
CATCH_SECTION("SetHeapSize cannot remove read-only heap") {
|
DOCTEST_SUBCASE("SetHeapSize cannot remove read-only heap") {
|
||||||
CATCH_REQUIRE(R_SUCCEEDED(svc::SetHeapSize(std::addressof(addr), svc::HeapSizeAlignment)));
|
DOCTEST_CHECK(R_SUCCEEDED(svc::SetHeapSize(std::addressof(addr), svc::HeapSizeAlignment)));
|
||||||
|
|
||||||
CATCH_REQUIRE(R_SUCCEEDED(svc::QueryMemory(std::addressof(mem_info), std::addressof(page_info), addr)));
|
DOCTEST_CHECK(R_SUCCEEDED(svc::QueryMemory(std::addressof(mem_info), std::addressof(page_info), addr)));
|
||||||
TestMemory(addr, svc::HeapSizeAlignment, svc::MemoryState_Normal, svc::MemoryPermission_ReadWrite, 0);
|
TestMemory(addr, svc::HeapSizeAlignment, svc::MemoryState_Normal, svc::MemoryPermission_ReadWrite, 0);
|
||||||
|
|
||||||
CATCH_REQUIRE(R_SUCCEEDED(svc::SetMemoryPermission(addr, svc::HeapSizeAlignment, svc::MemoryPermission_Read)));
|
DOCTEST_CHECK(R_SUCCEEDED(svc::SetMemoryPermission(addr, svc::HeapSizeAlignment, svc::MemoryPermission_Read)));
|
||||||
TestMemory(addr, svc::HeapSizeAlignment, svc::MemoryState_Normal, svc::MemoryPermission_Read, 0);
|
TestMemory(addr, svc::HeapSizeAlignment, svc::MemoryState_Normal, svc::MemoryPermission_Read, 0);
|
||||||
|
|
||||||
CATCH_REQUIRE(svc::ResultInvalidCurrentMemory::Includes(svc::SetHeapSize(std::addressof(dummy), 0)));
|
DOCTEST_CHECK(svc::ResultInvalidCurrentMemory::Includes(svc::SetHeapSize(std::addressof(dummy), 0)));
|
||||||
|
|
||||||
CATCH_REQUIRE(R_SUCCEEDED(svc::SetMemoryPermission(addr, svc::HeapSizeAlignment, svc::MemoryPermission_ReadWrite)));
|
DOCTEST_CHECK(R_SUCCEEDED(svc::SetMemoryPermission(addr, svc::HeapSizeAlignment, svc::MemoryPermission_ReadWrite)));
|
||||||
TestMemory(addr, svc::HeapSizeAlignment, svc::MemoryState_Normal, svc::MemoryPermission_ReadWrite, 0);
|
TestMemory(addr, svc::HeapSizeAlignment, svc::MemoryState_Normal, svc::MemoryPermission_ReadWrite, 0);
|
||||||
|
|
||||||
CATCH_REQUIRE(R_SUCCEEDED(svc::SetHeapSize(std::addressof(addr), 0)));
|
DOCTEST_CHECK(R_SUCCEEDED(svc::SetHeapSize(std::addressof(addr), 0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
CATCH_SECTION("Heap memory does not survive unmap/re-map") {
|
DOCTEST_SUBCASE("Heap memory does not survive unmap/re-map") {
|
||||||
CATCH_REQUIRE(R_SUCCEEDED(svc::SetHeapSize(std::addressof(addr), 2 * svc::HeapSizeAlignment)));
|
DOCTEST_CHECK(R_SUCCEEDED(svc::SetHeapSize(std::addressof(addr), 2 * svc::HeapSizeAlignment)));
|
||||||
|
|
||||||
u8 * const heap = reinterpret_cast<u8 *>(addr);
|
u8 * const heap = reinterpret_cast<u8 *>(addr);
|
||||||
|
|
||||||
std::memset(heap, 0xAA, svc::HeapSizeAlignment);
|
std::memset(heap, 0xAA, svc::HeapSizeAlignment);
|
||||||
std::memset(heap + svc::HeapSizeAlignment, 0xBB, svc::HeapSizeAlignment);
|
std::memset(heap + svc::HeapSizeAlignment, 0xBB, svc::HeapSizeAlignment);
|
||||||
|
|
||||||
CATCH_REQUIRE(heap[svc::HeapSizeAlignment] == 0xBB);
|
DOCTEST_CHECK(heap[svc::HeapSizeAlignment] == 0xBB);
|
||||||
CATCH_REQUIRE(std::memcmp(heap + svc::HeapSizeAlignment, heap + svc::HeapSizeAlignment + 1, svc::HeapSizeAlignment - 1) == 0);
|
DOCTEST_CHECK(std::memcmp(heap + svc::HeapSizeAlignment, heap + svc::HeapSizeAlignment + 1, svc::HeapSizeAlignment - 1) == 0);
|
||||||
|
|
||||||
CATCH_REQUIRE(R_SUCCEEDED(svc::SetHeapSize(std::addressof(addr), svc::HeapSizeAlignment)));
|
DOCTEST_CHECK(R_SUCCEEDED(svc::SetHeapSize(std::addressof(addr), svc::HeapSizeAlignment)));
|
||||||
|
|
||||||
CATCH_REQUIRE(heap[0] == 0xAA);
|
DOCTEST_CHECK(heap[0] == 0xAA);
|
||||||
CATCH_REQUIRE(std::memcmp(heap, heap + 1, svc::HeapSizeAlignment - 1) == 0);
|
DOCTEST_CHECK(std::memcmp(heap, heap + 1, svc::HeapSizeAlignment - 1) == 0);
|
||||||
|
|
||||||
CATCH_REQUIRE(R_SUCCEEDED(svc::SetHeapSize(std::addressof(addr), 2 * svc::HeapSizeAlignment)));
|
DOCTEST_CHECK(R_SUCCEEDED(svc::SetHeapSize(std::addressof(addr), 2 * svc::HeapSizeAlignment)));
|
||||||
|
|
||||||
CATCH_REQUIRE(heap[svc::HeapSizeAlignment] == 0x00);
|
DOCTEST_CHECK(heap[svc::HeapSizeAlignment] == 0x00);
|
||||||
CATCH_REQUIRE(std::memcmp(heap + svc::HeapSizeAlignment, heap + svc::HeapSizeAlignment + 1, svc::HeapSizeAlignment - 1) == 0);
|
DOCTEST_CHECK(std::memcmp(heap + svc::HeapSizeAlignment, heap + svc::HeapSizeAlignment + 1, svc::HeapSizeAlignment - 1) == 0);
|
||||||
|
|
||||||
CATCH_REQUIRE(R_SUCCEEDED(svc::SetHeapSize(std::addressof(addr), 0)));
|
DOCTEST_CHECK(R_SUCCEEDED(svc::SetHeapSize(std::addressof(addr), 0)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,22 +30,22 @@ namespace ams::test {
|
||||||
|
|
||||||
alignas(os::MemoryPageSize) constinit u8 g_memory_permission_buffer[2 * os::MemoryPageSize];
|
alignas(os::MemoryPageSize) constinit u8 g_memory_permission_buffer[2 * os::MemoryPageSize];
|
||||||
|
|
||||||
CATCH_TEST_CASE("svc::SetMemoryPermission invalid arguments") {
|
DOCTEST_TEST_CASE("svc::SetMemoryPermission invalid arguments") {
|
||||||
const uintptr_t buffer = reinterpret_cast<uintptr_t>(g_memory_permission_buffer);
|
const uintptr_t buffer = reinterpret_cast<uintptr_t>(g_memory_permission_buffer);
|
||||||
|
|
||||||
for (size_t i = 1; i < os::MemoryPageSize; ++i) {
|
for (size_t i = 1; i < os::MemoryPageSize; ++i) {
|
||||||
CATCH_REQUIRE(svc::ResultInvalidAddress::Includes(svc::SetMemoryPermission(buffer + i, os::MemoryPageSize, svc::MemoryPermission_Read)));
|
DOCTEST_CHECK(svc::ResultInvalidAddress::Includes(svc::SetMemoryPermission(buffer + i, os::MemoryPageSize, svc::MemoryPermission_Read)));
|
||||||
CATCH_REQUIRE(svc::ResultInvalidSize::Includes(svc::SetMemoryPermission(buffer, os::MemoryPageSize + i, svc::MemoryPermission_Read)));
|
DOCTEST_CHECK(svc::ResultInvalidSize::Includes(svc::SetMemoryPermission(buffer, os::MemoryPageSize + i, svc::MemoryPermission_Read)));
|
||||||
}
|
}
|
||||||
|
|
||||||
CATCH_REQUIRE(svc::ResultInvalidSize::Includes(svc::SetMemoryPermission(buffer, 0, svc::MemoryPermission_Read)));
|
DOCTEST_CHECK(svc::ResultInvalidSize::Includes(svc::SetMemoryPermission(buffer, 0, svc::MemoryPermission_Read)));
|
||||||
|
|
||||||
{
|
{
|
||||||
const u64 vmem_end = util::AlignDown(std::numeric_limits<u64>::max(), os::MemoryPageSize);
|
const u64 vmem_end = util::AlignDown(std::numeric_limits<u64>::max(), os::MemoryPageSize);
|
||||||
CATCH_REQUIRE(svc::ResultInvalidCurrentMemory::Includes(svc::SetMemoryPermission(vmem_end, 2 * os::MemoryPageSize, svc::MemoryPermission_Read)));
|
DOCTEST_CHECK(svc::ResultInvalidCurrentMemory::Includes(svc::SetMemoryPermission(vmem_end, 2 * os::MemoryPageSize, svc::MemoryPermission_Read)));
|
||||||
}
|
}
|
||||||
|
|
||||||
CATCH_REQUIRE(svc::ResultInvalidCurrentMemory::Includes(svc::SetMemoryPermission(svc::AddressMap39End, os::MemoryPageSize, svc::MemoryPermission_Read)));
|
DOCTEST_CHECK(svc::ResultInvalidCurrentMemory::Includes(svc::SetMemoryPermission(svc::AddressMap39End, os::MemoryPageSize, svc::MemoryPermission_Read)));
|
||||||
|
|
||||||
for (size_t i = 0; i < 0x100; ++i) {
|
for (size_t i = 0; i < 0x100; ++i) {
|
||||||
const auto perm = static_cast<svc::MemoryPermission>(i);
|
const auto perm = static_cast<svc::MemoryPermission>(i);
|
||||||
|
@ -53,14 +53,14 @@ namespace ams::test {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
CATCH_REQUIRE(svc::ResultInvalidNewMemoryPermission::Includes(svc::SetMemoryPermission(buffer, os::MemoryPageSize, perm)));
|
DOCTEST_CHECK(svc::ResultInvalidNewMemoryPermission::Includes(svc::SetMemoryPermission(buffer, os::MemoryPageSize, perm)));
|
||||||
}
|
}
|
||||||
CATCH_REQUIRE(svc::ResultInvalidNewMemoryPermission::Includes(svc::SetMemoryPermission(buffer, os::MemoryPageSize, svc::MemoryPermission_ReadExecute)));
|
DOCTEST_CHECK(svc::ResultInvalidNewMemoryPermission::Includes(svc::SetMemoryPermission(buffer, os::MemoryPageSize, svc::MemoryPermission_ReadExecute)));
|
||||||
CATCH_REQUIRE(svc::ResultInvalidNewMemoryPermission::Includes(svc::SetMemoryPermission(buffer, os::MemoryPageSize, svc::MemoryPermission_Write)));
|
DOCTEST_CHECK(svc::ResultInvalidNewMemoryPermission::Includes(svc::SetMemoryPermission(buffer, os::MemoryPageSize, svc::MemoryPermission_Write)));
|
||||||
CATCH_REQUIRE(svc::ResultInvalidNewMemoryPermission::Includes(svc::SetMemoryPermission(buffer, os::MemoryPageSize, svc::MemoryPermission_DontCare)));
|
DOCTEST_CHECK(svc::ResultInvalidNewMemoryPermission::Includes(svc::SetMemoryPermission(buffer, os::MemoryPageSize, svc::MemoryPermission_DontCare)));
|
||||||
}
|
}
|
||||||
|
|
||||||
CATCH_TEST_CASE("svc::SetMemoryPermission works on specific states") {
|
DOCTEST_TEST_CASE("svc::SetMemoryPermission works on specific states") {
|
||||||
/* Check that we have CodeData. */
|
/* Check that we have CodeData. */
|
||||||
const uintptr_t bss_buffer = reinterpret_cast<uintptr_t>(g_memory_permission_buffer);
|
const uintptr_t bss_buffer = reinterpret_cast<uintptr_t>(g_memory_permission_buffer);
|
||||||
TestMemory(bss_buffer, sizeof(g_memory_permission_buffer), svc::MemoryState_CodeData, svc::MemoryPermission_ReadWrite, 0);
|
TestMemory(bss_buffer, sizeof(g_memory_permission_buffer), svc::MemoryState_CodeData, svc::MemoryPermission_ReadWrite, 0);
|
||||||
|
@ -76,15 +76,15 @@ namespace ams::test {
|
||||||
/* Get current mapping. */
|
/* Get current mapping. */
|
||||||
svc::MemoryInfo mem_info;
|
svc::MemoryInfo mem_info;
|
||||||
svc::PageInfo page_info;
|
svc::PageInfo page_info;
|
||||||
CATCH_REQUIRE(R_SUCCEEDED(svc::QueryMemory(std::addressof(mem_info), std::addressof(page_info), addr)));
|
DOCTEST_CHECK(R_SUCCEEDED(svc::QueryMemory(std::addressof(mem_info), std::addressof(page_info), addr)));
|
||||||
|
|
||||||
/* Try to set permission. */
|
/* Try to set permission. */
|
||||||
if (CanSetMemoryPermission(mem_info.state) && mem_info.attribute == 0) {
|
if (CanSetMemoryPermission(mem_info.state) && mem_info.attribute == 0) {
|
||||||
CATCH_REQUIRE(R_SUCCEEDED(svc::SetMemoryPermission(mem_info.base_address, mem_info.size, svc::MemoryPermission_ReadWrite)));
|
DOCTEST_CHECK(R_SUCCEEDED(svc::SetMemoryPermission(mem_info.base_address, mem_info.size, svc::MemoryPermission_ReadWrite)));
|
||||||
TestMemory(mem_info.base_address, mem_info.size, mem_info.state, svc::MemoryPermission_ReadWrite, mem_info.attribute);
|
TestMemory(mem_info.base_address, mem_info.size, mem_info.state, svc::MemoryPermission_ReadWrite, mem_info.attribute);
|
||||||
CATCH_REQUIRE(R_SUCCEEDED(svc::SetMemoryPermission(mem_info.base_address, mem_info.size, mem_info.permission)));
|
DOCTEST_CHECK(R_SUCCEEDED(svc::SetMemoryPermission(mem_info.base_address, mem_info.size, mem_info.permission)));
|
||||||
} else {
|
} else {
|
||||||
CATCH_REQUIRE(svc::ResultInvalidCurrentMemory::Includes(svc::SetMemoryPermission(mem_info.base_address, mem_info.size, svc::MemoryPermission_Read)));
|
DOCTEST_CHECK(svc::ResultInvalidCurrentMemory::Includes(svc::SetMemoryPermission(mem_info.base_address, mem_info.size, svc::MemoryPermission_Read)));
|
||||||
}
|
}
|
||||||
|
|
||||||
const uintptr_t next_address = mem_info.base_address + mem_info.size;
|
const uintptr_t next_address = mem_info.base_address + mem_info.size;
|
||||||
|
@ -96,25 +96,25 @@ namespace ams::test {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CATCH_TEST_CASE("svc::SetMemoryPermission allows for free movement between RW-, R--, ---") {
|
DOCTEST_TEST_CASE("svc::SetMemoryPermission allows for free movement between RW-, R--, ---") {
|
||||||
/* Define helper. */
|
/* Define helper. */
|
||||||
auto test_set_memory_permission = [](uintptr_t address, size_t size){
|
auto test_set_memory_permission = [](uintptr_t address, size_t size){
|
||||||
/* Get the permission. */
|
/* Get the permission. */
|
||||||
svc::MemoryInfo mem_info;
|
svc::MemoryInfo mem_info;
|
||||||
svc::PageInfo page_info;
|
svc::PageInfo page_info;
|
||||||
CATCH_REQUIRE(R_SUCCEEDED(svc::QueryMemory(std::addressof(mem_info), std::addressof(page_info), address)));
|
DOCTEST_CHECK(R_SUCCEEDED(svc::QueryMemory(std::addressof(mem_info), std::addressof(page_info), address)));
|
||||||
|
|
||||||
const svc::MemoryPermission legal_states[] = { svc::MemoryPermission_None, svc::MemoryPermission_Read, svc::MemoryPermission_ReadWrite };
|
const svc::MemoryPermission legal_states[] = { svc::MemoryPermission_None, svc::MemoryPermission_Read, svc::MemoryPermission_ReadWrite };
|
||||||
for (const auto src_state : legal_states) {
|
for (const auto src_state : legal_states) {
|
||||||
for (const auto dst_state : legal_states) {
|
for (const auto dst_state : legal_states) {
|
||||||
CATCH_REQUIRE(R_SUCCEEDED(svc::SetMemoryPermission(address, size, svc::MemoryPermission_None)));
|
DOCTEST_CHECK(R_SUCCEEDED(svc::SetMemoryPermission(address, size, svc::MemoryPermission_None)));
|
||||||
CATCH_REQUIRE(R_SUCCEEDED(svc::SetMemoryPermission(address, size, src_state)));
|
DOCTEST_CHECK(R_SUCCEEDED(svc::SetMemoryPermission(address, size, src_state)));
|
||||||
CATCH_REQUIRE(R_SUCCEEDED(svc::SetMemoryPermission(address, size, dst_state)));
|
DOCTEST_CHECK(R_SUCCEEDED(svc::SetMemoryPermission(address, size, dst_state)));
|
||||||
CATCH_REQUIRE(R_SUCCEEDED(svc::SetMemoryPermission(address, size, svc::MemoryPermission_None)));
|
DOCTEST_CHECK(R_SUCCEEDED(svc::SetMemoryPermission(address, size, svc::MemoryPermission_None)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CATCH_REQUIRE(R_SUCCEEDED(svc::SetMemoryPermission(address, size, mem_info.permission)));
|
DOCTEST_CHECK(R_SUCCEEDED(svc::SetMemoryPermission(address, size, mem_info.permission)));
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Test that we can freely move about .bss buffers. */
|
/* Test that we can freely move about .bss buffers. */
|
||||||
|
@ -130,27 +130,27 @@ namespace ams::test {
|
||||||
/* TODO: AliasCodeData */
|
/* TODO: AliasCodeData */
|
||||||
}
|
}
|
||||||
|
|
||||||
CATCH_TEST_CASE("svc::SetMemoryPermission fails when the memory has non-zero attribute") {
|
DOCTEST_TEST_CASE("svc::SetMemoryPermission fails when the memory has non-zero attribute") {
|
||||||
const uintptr_t bss_buffer = reinterpret_cast<uintptr_t>(g_memory_permission_buffer);
|
const uintptr_t bss_buffer = reinterpret_cast<uintptr_t>(g_memory_permission_buffer);
|
||||||
TestMemory(bss_buffer, sizeof(g_memory_permission_buffer), svc::MemoryState_CodeData, svc::MemoryPermission_ReadWrite, 0);
|
TestMemory(bss_buffer, sizeof(g_memory_permission_buffer), svc::MemoryState_CodeData, svc::MemoryPermission_ReadWrite, 0);
|
||||||
|
|
||||||
CATCH_REQUIRE(R_SUCCEEDED(svc::SetMemoryPermission(bss_buffer, sizeof(g_memory_permission_buffer), svc::MemoryPermission_None)));
|
DOCTEST_CHECK(R_SUCCEEDED(svc::SetMemoryPermission(bss_buffer, sizeof(g_memory_permission_buffer), svc::MemoryPermission_None)));
|
||||||
CATCH_REQUIRE(R_SUCCEEDED(svc::SetMemoryPermission(bss_buffer, sizeof(g_memory_permission_buffer), svc::MemoryPermission_Read)));
|
DOCTEST_CHECK(R_SUCCEEDED(svc::SetMemoryPermission(bss_buffer, sizeof(g_memory_permission_buffer), svc::MemoryPermission_Read)));
|
||||||
CATCH_REQUIRE(R_SUCCEEDED(svc::SetMemoryPermission(bss_buffer, sizeof(g_memory_permission_buffer), svc::MemoryPermission_ReadWrite)));
|
DOCTEST_CHECK(R_SUCCEEDED(svc::SetMemoryPermission(bss_buffer, sizeof(g_memory_permission_buffer), svc::MemoryPermission_ReadWrite)));
|
||||||
|
|
||||||
CATCH_REQUIRE(R_SUCCEEDED(svc::SetMemoryAttribute(bss_buffer, sizeof(g_memory_permission_buffer), svc::MemoryAttribute_Uncached, svc::MemoryAttribute_Uncached)));
|
DOCTEST_CHECK(R_SUCCEEDED(svc::SetMemoryAttribute(bss_buffer, sizeof(g_memory_permission_buffer), svc::MemoryAttribute_Uncached, svc::MemoryAttribute_Uncached)));
|
||||||
TestMemory(bss_buffer, sizeof(g_memory_permission_buffer), svc::MemoryState_CodeData, svc::MemoryPermission_ReadWrite, svc::MemoryAttribute_Uncached);
|
TestMemory(bss_buffer, sizeof(g_memory_permission_buffer), svc::MemoryState_CodeData, svc::MemoryPermission_ReadWrite, svc::MemoryAttribute_Uncached);
|
||||||
|
|
||||||
CATCH_REQUIRE(svc::ResultInvalidCurrentMemory::Includes(svc::SetMemoryPermission(bss_buffer, sizeof(g_memory_permission_buffer), svc::MemoryPermission_None)));
|
DOCTEST_CHECK(svc::ResultInvalidCurrentMemory::Includes(svc::SetMemoryPermission(bss_buffer, sizeof(g_memory_permission_buffer), svc::MemoryPermission_None)));
|
||||||
CATCH_REQUIRE(svc::ResultInvalidCurrentMemory::Includes(svc::SetMemoryPermission(bss_buffer, sizeof(g_memory_permission_buffer), svc::MemoryPermission_Read)));
|
DOCTEST_CHECK(svc::ResultInvalidCurrentMemory::Includes(svc::SetMemoryPermission(bss_buffer, sizeof(g_memory_permission_buffer), svc::MemoryPermission_Read)));
|
||||||
CATCH_REQUIRE(svc::ResultInvalidCurrentMemory::Includes(svc::SetMemoryPermission(bss_buffer, sizeof(g_memory_permission_buffer), svc::MemoryPermission_ReadWrite)));
|
DOCTEST_CHECK(svc::ResultInvalidCurrentMemory::Includes(svc::SetMemoryPermission(bss_buffer, sizeof(g_memory_permission_buffer), svc::MemoryPermission_ReadWrite)));
|
||||||
|
|
||||||
CATCH_REQUIRE(R_SUCCEEDED(svc::SetMemoryAttribute(bss_buffer, sizeof(g_memory_permission_buffer), svc::MemoryAttribute_Uncached, 0)));
|
DOCTEST_CHECK(R_SUCCEEDED(svc::SetMemoryAttribute(bss_buffer, sizeof(g_memory_permission_buffer), svc::MemoryAttribute_Uncached, 0)));
|
||||||
TestMemory(bss_buffer, sizeof(g_memory_permission_buffer), svc::MemoryState_CodeData, svc::MemoryPermission_ReadWrite, 0);
|
TestMemory(bss_buffer, sizeof(g_memory_permission_buffer), svc::MemoryState_CodeData, svc::MemoryPermission_ReadWrite, 0);
|
||||||
|
|
||||||
CATCH_REQUIRE(R_SUCCEEDED(svc::SetMemoryPermission(bss_buffer, sizeof(g_memory_permission_buffer), svc::MemoryPermission_None)));
|
DOCTEST_CHECK(R_SUCCEEDED(svc::SetMemoryPermission(bss_buffer, sizeof(g_memory_permission_buffer), svc::MemoryPermission_None)));
|
||||||
CATCH_REQUIRE(R_SUCCEEDED(svc::SetMemoryPermission(bss_buffer, sizeof(g_memory_permission_buffer), svc::MemoryPermission_Read)));
|
DOCTEST_CHECK(R_SUCCEEDED(svc::SetMemoryPermission(bss_buffer, sizeof(g_memory_permission_buffer), svc::MemoryPermission_Read)));
|
||||||
CATCH_REQUIRE(R_SUCCEEDED(svc::SetMemoryPermission(bss_buffer, sizeof(g_memory_permission_buffer), svc::MemoryPermission_ReadWrite)));
|
DOCTEST_CHECK(R_SUCCEEDED(svc::SetMemoryPermission(bss_buffer, sizeof(g_memory_permission_buffer), svc::MemoryPermission_ReadWrite)));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -86,26 +86,26 @@ namespace ams::test {
|
||||||
svc::Handle thread_handles[2];
|
svc::Handle thread_handles[2];
|
||||||
|
|
||||||
/* Create threads. */
|
/* Create threads. */
|
||||||
CATCH_REQUIRE(R_SUCCEEDED(svc::CreateThread(thread_handles + 0, reinterpret_cast<uintptr_t>(&TestYieldHigherOrSamePriorityThread), 0, sp_higher, priority, core)));
|
DOCTEST_CHECK(R_SUCCEEDED(svc::CreateThread(thread_handles + 0, reinterpret_cast<uintptr_t>(&TestYieldHigherOrSamePriorityThread), 0, sp_higher, priority, core)));
|
||||||
CATCH_REQUIRE(R_SUCCEEDED(svc::CreateThread(thread_handles + 1, reinterpret_cast<uintptr_t>(&TestYieldLowerOrSamePriorityThread), 0, sp_lower, priority, core)));
|
DOCTEST_CHECK(R_SUCCEEDED(svc::CreateThread(thread_handles + 1, reinterpret_cast<uintptr_t>(&TestYieldLowerOrSamePriorityThread), 0, sp_lower, priority, core)));
|
||||||
|
|
||||||
/* Start threads. */
|
/* Start threads. */
|
||||||
CATCH_REQUIRE(R_SUCCEEDED(svc::StartThread(thread_handles[1])));
|
DOCTEST_CHECK(R_SUCCEEDED(svc::StartThread(thread_handles[1])));
|
||||||
CATCH_REQUIRE(R_SUCCEEDED(svc::StartThread(thread_handles[0])));
|
DOCTEST_CHECK(R_SUCCEEDED(svc::StartThread(thread_handles[0])));
|
||||||
|
|
||||||
/* Wait for higher priority thread. */
|
/* Wait for higher priority thread. */
|
||||||
WaitSynchronization(thread_handles[0]);
|
WaitSynchronization(thread_handles[0]);
|
||||||
CATCH_REQUIRE(R_SUCCEEDED(svc::CloseHandle(thread_handles[0])));
|
DOCTEST_CHECK(R_SUCCEEDED(svc::CloseHandle(thread_handles[0])));
|
||||||
|
|
||||||
/* Signal the lower priority thread to exit. */
|
/* Signal the lower priority thread to exit. */
|
||||||
CATCH_REQUIRE(R_SUCCEEDED(svc::SignalEvent(g_write_handles[2])));
|
DOCTEST_CHECK(R_SUCCEEDED(svc::SignalEvent(g_write_handles[2])));
|
||||||
|
|
||||||
/* Wait for the lower priority thread. */
|
/* Wait for the lower priority thread. */
|
||||||
WaitSynchronization(thread_handles[1]);
|
WaitSynchronization(thread_handles[1]);
|
||||||
CATCH_REQUIRE(R_SUCCEEDED(svc::CloseHandle(thread_handles[1])));
|
DOCTEST_CHECK(R_SUCCEEDED(svc::CloseHandle(thread_handles[1])));
|
||||||
|
|
||||||
/* Check that the switch was correct. */
|
/* Check that the switch was correct. */
|
||||||
CATCH_REQUIRE(g_correct_switch_threads);
|
DOCTEST_CHECK(g_correct_switch_threads);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -118,55 +118,55 @@ namespace ams::test {
|
||||||
svc::Handle thread_handles[2];
|
svc::Handle thread_handles[2];
|
||||||
|
|
||||||
/* Create threads. */
|
/* Create threads. */
|
||||||
CATCH_REQUIRE(R_SUCCEEDED(svc::CreateThread(thread_handles + 0, reinterpret_cast<uintptr_t>(&TestYieldHigherOrSamePriorityThread), 0, sp_higher, priority, core)));
|
DOCTEST_CHECK(R_SUCCEEDED(svc::CreateThread(thread_handles + 0, reinterpret_cast<uintptr_t>(&TestYieldHigherOrSamePriorityThread), 0, sp_higher, priority, core)));
|
||||||
CATCH_REQUIRE(R_SUCCEEDED(svc::CreateThread(thread_handles + 1, reinterpret_cast<uintptr_t>(&TestYieldLowerOrSamePriorityThread), 0, sp_lower, priority + 1, core)));
|
DOCTEST_CHECK(R_SUCCEEDED(svc::CreateThread(thread_handles + 1, reinterpret_cast<uintptr_t>(&TestYieldLowerOrSamePriorityThread), 0, sp_lower, priority + 1, core)));
|
||||||
|
|
||||||
/* Start threads. */
|
/* Start threads. */
|
||||||
CATCH_REQUIRE(R_SUCCEEDED(svc::StartThread(thread_handles[1])));
|
DOCTEST_CHECK(R_SUCCEEDED(svc::StartThread(thread_handles[1])));
|
||||||
CATCH_REQUIRE(R_SUCCEEDED(svc::StartThread(thread_handles[0])));
|
DOCTEST_CHECK(R_SUCCEEDED(svc::StartThread(thread_handles[0])));
|
||||||
|
|
||||||
/* Wait for higher priority thread. */
|
/* Wait for higher priority thread. */
|
||||||
WaitSynchronization(thread_handles[0]);
|
WaitSynchronization(thread_handles[0]);
|
||||||
CATCH_REQUIRE(R_SUCCEEDED(svc::CloseHandle(thread_handles[0])));
|
DOCTEST_CHECK(R_SUCCEEDED(svc::CloseHandle(thread_handles[0])));
|
||||||
|
|
||||||
/* Signal the lower priority thread to exit. */
|
/* Signal the lower priority thread to exit. */
|
||||||
CATCH_REQUIRE(R_SUCCEEDED(svc::SignalEvent(g_write_handles[2])));
|
DOCTEST_CHECK(R_SUCCEEDED(svc::SignalEvent(g_write_handles[2])));
|
||||||
|
|
||||||
/* Wait for the lower priority thread. */
|
/* Wait for the lower priority thread. */
|
||||||
WaitSynchronization(thread_handles[1]);
|
WaitSynchronization(thread_handles[1]);
|
||||||
CATCH_REQUIRE(R_SUCCEEDED(svc::CloseHandle(thread_handles[1])));
|
DOCTEST_CHECK(R_SUCCEEDED(svc::CloseHandle(thread_handles[1])));
|
||||||
|
|
||||||
/* Check that the switch was correct. */
|
/* Check that the switch was correct. */
|
||||||
CATCH_REQUIRE(g_correct_switch_threads);
|
DOCTEST_CHECK(g_correct_switch_threads);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CATCH_TEST_CASE( "svc::SleepThread: Thread sleeps for time specified" ) {
|
DOCTEST_TEST_CASE( "svc::SleepThread: Thread sleeps for time specified" ) {
|
||||||
for (s64 ns = 1; ns < TimeSpan::FromSeconds(1).GetNanoSeconds(); ns *= 2) {
|
for (s64 ns = 1; ns < TimeSpan::FromSeconds(1).GetNanoSeconds(); ns *= 2) {
|
||||||
const auto start = os::GetSystemTickOrdered();
|
const auto start = os::GetSystemTickOrdered();
|
||||||
svc::SleepThread(ns);
|
svc::SleepThread(ns);
|
||||||
const auto end = os::GetSystemTickOrdered();
|
const auto end = os::GetSystemTickOrdered();
|
||||||
|
|
||||||
const s64 taken_ns = (end - start).ToTimeSpan().GetNanoSeconds();
|
const s64 taken_ns = (end - start).ToTimeSpan().GetNanoSeconds();
|
||||||
CATCH_REQUIRE( taken_ns >= ns );
|
DOCTEST_CHECK( taken_ns >= ns );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CATCH_TEST_CASE( "svc::SleepThread: Yield is behaviorally correct" ) {
|
DOCTEST_TEST_CASE( "svc::SleepThread: Yield is behaviorally correct" ) {
|
||||||
/* Create events. */
|
/* Create events. */
|
||||||
for (size_t i = 0; i < util::size(g_write_handles); ++i) {
|
for (size_t i = 0; i < util::size(g_write_handles); ++i) {
|
||||||
g_read_handles[i] = svc::InvalidHandle;
|
g_read_handles[i] = svc::InvalidHandle;
|
||||||
g_write_handles[i] = svc::InvalidHandle;
|
g_write_handles[i] = svc::InvalidHandle;
|
||||||
CATCH_REQUIRE(R_SUCCEEDED(svc::CreateEvent(g_write_handles + i, g_read_handles + i)));
|
DOCTEST_CHECK(R_SUCCEEDED(svc::CreateEvent(g_write_handles + i, g_read_handles + i)));
|
||||||
}
|
}
|
||||||
|
|
||||||
ON_SCOPE_EXIT {
|
ON_SCOPE_EXIT {
|
||||||
for (size_t i = 0; i < util::size(g_write_handles); ++i) {
|
for (size_t i = 0; i < util::size(g_write_handles); ++i) {
|
||||||
CATCH_REQUIRE(R_SUCCEEDED(svc::CloseHandle(g_read_handles[i])));
|
DOCTEST_CHECK(R_SUCCEEDED(svc::CloseHandle(g_read_handles[i])));
|
||||||
CATCH_REQUIRE(R_SUCCEEDED(svc::CloseHandle(g_write_handles[i])));
|
DOCTEST_CHECK(R_SUCCEEDED(svc::CloseHandle(g_write_handles[i])));
|
||||||
g_read_handles[i] = svc::InvalidHandle;
|
g_read_handles[i] = svc::InvalidHandle;
|
||||||
g_write_handles[i] = svc::InvalidHandle;
|
g_write_handles[i] = svc::InvalidHandle;
|
||||||
}
|
}
|
||||||
|
@ -174,14 +174,14 @@ namespace ams::test {
|
||||||
|
|
||||||
/* Create heap. */
|
/* Create heap. */
|
||||||
ScopedHeap heap(3 * os::MemoryPageSize);
|
ScopedHeap heap(3 * os::MemoryPageSize);
|
||||||
CATCH_REQUIRE(R_SUCCEEDED(svc::SetMemoryPermission(heap.GetAddress() + os::MemoryPageSize, os::MemoryPageSize, svc::MemoryPermission_None)));
|
DOCTEST_CHECK(R_SUCCEEDED(svc::SetMemoryPermission(heap.GetAddress() + os::MemoryPageSize, os::MemoryPageSize, svc::MemoryPermission_None)));
|
||||||
ON_SCOPE_EXIT {
|
ON_SCOPE_EXIT {
|
||||||
CATCH_REQUIRE(R_SUCCEEDED(svc::SetMemoryPermission(heap.GetAddress() + os::MemoryPageSize, os::MemoryPageSize, svc::MemoryPermission_ReadWrite)));
|
DOCTEST_CHECK(R_SUCCEEDED(svc::SetMemoryPermission(heap.GetAddress() + os::MemoryPageSize, os::MemoryPageSize, svc::MemoryPermission_ReadWrite)));
|
||||||
};
|
};
|
||||||
const uintptr_t sp_higher = heap.GetAddress() + 1 * os::MemoryPageSize;
|
const uintptr_t sp_higher = heap.GetAddress() + 1 * os::MemoryPageSize;
|
||||||
const uintptr_t sp_lower = heap.GetAddress() + 3 * os::MemoryPageSize;
|
const uintptr_t sp_lower = heap.GetAddress() + 3 * os::MemoryPageSize;
|
||||||
|
|
||||||
CATCH_SECTION("svc::SleepThread: Yields do not switch to a thread of lower priority.") {
|
DOCTEST_SUBCASE("svc::SleepThread: Yields do not switch to a thread of lower priority.") {
|
||||||
/* Test yield without migration. */
|
/* Test yield without migration. */
|
||||||
{
|
{
|
||||||
/* Configure for yield test. */
|
/* Configure for yield test. */
|
||||||
|
@ -201,7 +201,7 @@ namespace ams::test {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CATCH_SECTION("svc::SleepThread: ToAnyThread switches to a thread of same or lower priority.") {
|
DOCTEST_SUBCASE("svc::SleepThread: ToAnyThread switches to a thread of same or lower priority.") {
|
||||||
/* Test to same priority. */
|
/* Test to same priority. */
|
||||||
{
|
{
|
||||||
/* Configure for yield test. */
|
/* Configure for yield test. */
|
||||||
|
@ -221,7 +221,7 @@ namespace ams::test {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CATCH_SECTION("svc::SleepThread: Yield switches to another thread of same priority.") {
|
DOCTEST_SUBCASE("svc::SleepThread: Yield switches to another thread of same priority.") {
|
||||||
/* Test yield without migration. */
|
/* Test yield without migration. */
|
||||||
{
|
{
|
||||||
/* Configure for yield test. */
|
/* Configure for yield test. */
|
||||||
|
@ -241,7 +241,7 @@ namespace ams::test {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CATCH_SECTION("svc::SleepThread: Yield with bogus timeout does not switch to another thread same priority") {
|
DOCTEST_SUBCASE("svc::SleepThread: Yield with bogus timeout does not switch to another thread same priority") {
|
||||||
/* Configure for yield test. */
|
/* Configure for yield test. */
|
||||||
g_should_switch_threads = false;
|
g_should_switch_threads = false;
|
||||||
g_thread_wait_ns = INT64_C(-5);
|
g_thread_wait_ns = INT64_C(-5);
|
||||||
|
|
|
@ -14,33 +14,33 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "util_catch.hpp"
|
#include "util_test_framework.hpp"
|
||||||
|
|
||||||
namespace ams::test {
|
namespace ams::test {
|
||||||
|
|
||||||
inline void TestMemory(uintptr_t address, svc::MemoryState state, svc::MemoryPermission perm, u32 attr) {
|
inline void TestMemory(uintptr_t address, svc::MemoryState state, svc::MemoryPermission perm, u32 attr) {
|
||||||
svc::MemoryInfo mem_info;
|
svc::MemoryInfo mem_info;
|
||||||
svc::PageInfo page_info;
|
svc::PageInfo page_info;
|
||||||
CATCH_REQUIRE(R_SUCCEEDED(svc::QueryMemory(std::addressof(mem_info), std::addressof(page_info), address)));
|
DOCTEST_CHECK(R_SUCCEEDED(svc::QueryMemory(std::addressof(mem_info), std::addressof(page_info), address)));
|
||||||
|
|
||||||
CATCH_REQUIRE(mem_info.base_address <= address);
|
DOCTEST_CHECK(mem_info.base_address <= address);
|
||||||
CATCH_REQUIRE(address < (mem_info.base_address + mem_info.size));
|
DOCTEST_CHECK(address < (mem_info.base_address + mem_info.size));
|
||||||
CATCH_REQUIRE(mem_info.state == state);
|
DOCTEST_CHECK(mem_info.state == state);
|
||||||
CATCH_REQUIRE(mem_info.permission == perm);
|
DOCTEST_CHECK(mem_info.permission == perm);
|
||||||
CATCH_REQUIRE(mem_info.attribute == attr);
|
DOCTEST_CHECK(mem_info.attribute == attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void TestMemory(uintptr_t address, size_t size, svc::MemoryState state, svc::MemoryPermission perm, u32 attr) {
|
inline void TestMemory(uintptr_t address, size_t size, svc::MemoryState state, svc::MemoryPermission perm, u32 attr) {
|
||||||
svc::MemoryInfo mem_info;
|
svc::MemoryInfo mem_info;
|
||||||
svc::PageInfo page_info;
|
svc::PageInfo page_info;
|
||||||
CATCH_REQUIRE(R_SUCCEEDED(svc::QueryMemory(std::addressof(mem_info), std::addressof(page_info), address)));
|
DOCTEST_CHECK(R_SUCCEEDED(svc::QueryMemory(std::addressof(mem_info), std::addressof(page_info), address)));
|
||||||
|
|
||||||
CATCH_REQUIRE(mem_info.base_address <= address);
|
DOCTEST_CHECK(mem_info.base_address <= address);
|
||||||
CATCH_REQUIRE(mem_info.base_address < (address + size));
|
DOCTEST_CHECK(mem_info.base_address < (address + size));
|
||||||
CATCH_REQUIRE((address + size) <= (mem_info.base_address + mem_info.size));
|
DOCTEST_CHECK((address + size) <= (mem_info.base_address + mem_info.size));
|
||||||
CATCH_REQUIRE(mem_info.state == state);
|
DOCTEST_CHECK(mem_info.state == state);
|
||||||
CATCH_REQUIRE(mem_info.permission == perm);
|
DOCTEST_CHECK(mem_info.permission == perm);
|
||||||
CATCH_REQUIRE(mem_info.attribute == attr);
|
DOCTEST_CHECK(mem_info.attribute == attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -14,7 +14,7 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "util_catch.hpp"
|
#include "util_test_framework.hpp"
|
||||||
|
|
||||||
namespace ams::test {
|
namespace ams::test {
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "util_catch.hpp"
|
#include "util_test_framework.hpp"
|
||||||
|
|
||||||
namespace ams::test {
|
namespace ams::test {
|
||||||
|
|
||||||
|
@ -31,14 +31,14 @@ namespace ams::test {
|
||||||
|
|
||||||
~ScopedHeap() {
|
~ScopedHeap() {
|
||||||
const auto result = svc::SetHeapSize(std::addressof(m_address), 0);
|
const auto result = svc::SetHeapSize(std::addressof(m_address), 0);
|
||||||
CATCH_REQUIRE(R_SUCCEEDED(result));
|
DOCTEST_CHECK(R_SUCCEEDED(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetHeapSize(size_t size) {
|
void SetHeapSize(size_t size) {
|
||||||
m_size = util::AlignUp(size, svc::HeapSizeAlignment);
|
m_size = util::AlignUp(size, svc::HeapSizeAlignment);
|
||||||
|
|
||||||
const auto result = svc::SetHeapSize(std::addressof(m_address), m_size);
|
const auto result = svc::SetHeapSize(std::addressof(m_address), m_size);
|
||||||
CATCH_REQUIRE(R_SUCCEEDED(result));
|
DOCTEST_CHECK(R_SUCCEEDED(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
uintptr_t GetAddress() const { return m_address; }
|
uintptr_t GetAddress() const { return m_address; }
|
||||||
|
|
|
@ -17,7 +17,8 @@
|
||||||
#include <stratosphere.hpp>
|
#include <stratosphere.hpp>
|
||||||
|
|
||||||
#define CATCH_CONFIG_NOSTDOUT
|
#define CATCH_CONFIG_NOSTDOUT
|
||||||
#define CATCH_CONFIG_PREFIX_ALL
|
#define DOCTEST_CONFIG_NO_SHORT_MACRO_NAMES
|
||||||
#define CATCH_CONFIG_DISABLE_EXCEPTIONS
|
#define DOCTEST_CONFIG_SUPER_FAST_ASSERTS
|
||||||
#define CATCH_CONFIG_NO_POSIX_SIGNALS
|
#define DOCTEST_CONFIG_NO_EXCEPTIONS
|
||||||
#include "catch.hpp"
|
#define DOCTEST_CONFIG_NO_POSIX_SIGNALS
|
||||||
|
#include "doctest.h"
|
Loading…
Reference in a new issue