Files
CoopAllTheThings/tests/shared_memory_test.cpp
BlackMark 30eccf749d Apply clang-format across the whole tree
Run clang-format (the repo's .clang-format: LLVM base, 120 cols, tabs,
Allman functions) over every source file so the tree is formatter-clean.
Whitespace only -- no behavior change; full x64 + x86 suites pass.

Also set SortIncludes: false in .clang-format. Windows include order is
load-bearing (windows.h must precede tlhelp32.h / mmreg.h / xinput.h /
dinput.h; winsock2.h must precede windows.h), and the default
alphabetical sort reorders tlhelp32.h ahead of windows.h -- a build
break. Leaving order alone keeps the manual, correct grouping.
2026-07-12 11:52:53 +02:00

79 lines
2.7 KiB
C++

// Unit test for the SharedMemory RAII wrapper (common/include/coop/shared_memory.hpp): create-or-open
// aliasing, move (steal handles + leave the source empty, no double-free), reset, and open-missing.
#include <cstdint>
#include <cstdio>
#include <string>
#include <windows.h>
#include "coop/shared_memory.hpp"
using namespace coop;
namespace {
int g_failures = 0;
void check(bool ok, const char* what)
{
std::printf("%s %s\n", ok ? " ok:" : "FAIL:", what);
if (!ok) {
++g_failures;
}
}
std::wstring uniq_name()
{
return L"Local\\coop_shmtest_" + std::to_wstring(GetCurrentProcessId());
}
} // namespace
int main()
{
const std::wstring name = uniq_name();
constexpr std::size_t kSize = 4096;
check(!SharedMemory{}.valid(), "default-constructed: not valid");
{
SharedMemory a;
check(a.create(name, kSize) && a.valid(), "create a named section");
a.as<std::uint32_t>()[0] = 0xC0FFEEu;
// open() the same name -> a second view of the SAME section (aliases a's memory).
SharedMemory b;
check(b.open(name, kSize) && b.valid(), "open the existing section");
check(b.as<std::uint32_t>()[0] == 0xC0FFEEu, "open aliases the same memory (sees the write)");
b.as<std::uint32_t>()[1] = 0x1234u;
check(a.as<std::uint32_t>()[1] == 0x1234u, "writes through one view are visible in the other");
// create() again with the same name -> opens the existing section (create-or-open).
SharedMemory c;
check(c.create(name, kSize) && c.valid() && c.as<std::uint32_t>()[0] == 0xC0FFEEu,
"create-or-open: a second create sees the existing data");
// Move: the destination owns the mapping, the source is emptied (no double-free at scope end).
const void* a_ptr = a.data();
SharedMemory moved = std::move(a);
check(moved.valid() && moved.data() == a_ptr, "move-construct steals the view");
check(!a.valid() && a.data() == nullptr, "moved-from source is emptied");
check(moved.as<std::uint32_t>()[0] == 0xC0FFEEu, "moved view still maps the section");
SharedMemory move_assigned;
move_assigned.create(uniq_name() + L"_x", kSize); // give it something to reset first
move_assigned = std::move(moved);
check(move_assigned.valid() && !moved.valid(), "move-assign steals and empties the source");
check(move_assigned.as<std::uint32_t>()[1] == 0x1234u, "move-assigned view sees prior writes");
move_assigned.reset();
check(!move_assigned.valid() && move_assigned.data() == nullptr, "reset releases the mapping");
}
// open() a name that no longer exists (all handles closed at scope end above) -> false.
{
SharedMemory gone;
check(!gone.open(name, kSize), "open a non-existent section returns false");
}
std::printf(g_failures == 0 ? "PASS shared_memory_test\n" : "FAILED shared_memory_test (%d)\n", g_failures);
return g_failures == 0 ? 0 : 1;
}