Introduced memory_arena_tests
This commit is contained in:
parent
7a67bd8c74
commit
baf4c5d5a6
|
@ -37,7 +37,9 @@ cl %CommonCompilerFlags% %ProjectDevPath%\src\sculpture_gen\gen_blumen_lumen.cpp
|
|||
REM COMPILE AND RUN TESTS
|
||||
cl %CommonCompilerFlags% %ProjectDevPath%\src\tests\sanity_tests.cpp /Fesanity_tests.exe /link %CommonLinkerFlags% user32.lib winmm.lib gdi32.lib
|
||||
|
||||
ECHO SANITY TESTS BEGIN
|
||||
sanity_tests.exe
|
||||
ECHO SANITY TESTS END
|
||||
|
||||
popd
|
||||
|
||||
|
|
|
@ -0,0 +1,184 @@
|
|||
#include "../app/platform_win32/win32_foldhaus_memory.h"
|
||||
|
||||
internal u32
|
||||
TESTNextRandom(u32* LastRandomValue)
|
||||
{
|
||||
u32 Result = *LastRandomValue;
|
||||
Result ^= Result << 13;
|
||||
Result ^= Result >> 17;
|
||||
Result ^= Result << 5;
|
||||
*LastRandomValue = Result;
|
||||
return Result;
|
||||
}
|
||||
|
||||
internal void
|
||||
MemoryArenaTests()
|
||||
{
|
||||
Test("Allocator")
|
||||
{
|
||||
gs_allocator Allocator = CreateAllocator(Win32Alloc, Win32Free);
|
||||
|
||||
u8* Data = AllocatorAllocArray(Allocator, u8, 4096);
|
||||
for (int i = 0; i < 4096; i++) Data[i] = (i % MaxU8);
|
||||
bool Success = true;
|
||||
for (int i = 0; i < 4096; i++) Success &= (Data[i] == (i % MaxU8));
|
||||
TestResult(Success);
|
||||
|
||||
AllocatorFreeArray(Allocator, Data, u8, 4096);
|
||||
// idk how to test free
|
||||
}
|
||||
|
||||
Test("Memory Cursor")
|
||||
{
|
||||
gs_allocator A = CreateAllocator(Win32Alloc, Win32Free);
|
||||
|
||||
u64 Size = 4096;
|
||||
gs_data D = AllocatorAlloc(A, Size);
|
||||
gs_memory_cursor C = CreateMemoryCursor(D);
|
||||
|
||||
u64 RoomLeft = CursorRoomLeft(C);
|
||||
TestResult(RoomLeft == Size);
|
||||
|
||||
TestResult(CursorHasRoom(C, 2048));
|
||||
TestResult(CursorHasRoom(C, Size));
|
||||
TestResult(!CursorHasRoom(C, Size + 1));
|
||||
|
||||
for (u64 i = 0; i < 2048; i++)
|
||||
{
|
||||
u8* Byte = PushSizeOnCursor(&C, 1).Memory;
|
||||
*Byte = (u8)(i % 256);
|
||||
}
|
||||
RoomLeft = CursorRoomLeft(C);
|
||||
TestResult(RoomLeft == (Size - 2048));
|
||||
|
||||
PopSizeOnCursor(&C, 2048);
|
||||
TestResult(C.Position == 0);
|
||||
|
||||
bool Success = true;
|
||||
for (u64 i = 0; i < 2048; i++)
|
||||
{
|
||||
u8* Byte = PushSizeOnCursor(&C, 1).Memory;
|
||||
Success &= *Byte == (u8)(i % 256);
|
||||
}
|
||||
TestResult(Success);
|
||||
|
||||
AllocatorFree(A, D.Memory, D.Size);
|
||||
}
|
||||
|
||||
Test("Memory Arena")
|
||||
{
|
||||
gs_allocator Al = CreateAllocator(Win32Alloc, Win32Free);
|
||||
gs_memory_arena A = CreateMemoryArena(Al, "test", 128, 4);
|
||||
|
||||
// NOTE(PS): We loop through this block 3 times
|
||||
// 1. Make sure the arena works out of the box
|
||||
// 2. Make sure the arena works the same way after clearing
|
||||
// 3. Make sure the arena works the same way after freeing
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
gs_data D0 = PushSize_(&A, 32, FileNameAndLineNumberString);
|
||||
TestResult(D0.Size == 32);
|
||||
|
||||
// NOTE(PS): This should still result in 32 bytes
|
||||
// because its going to align the Cursor after
|
||||
// it allocates to a multiple of 4 bytes
|
||||
gs_data D1 = PushSize_(&A, 30, FileNameAndLineNumberString);
|
||||
TestResult(D1.Size == 32);
|
||||
|
||||
// NOTE(PS): Allocating bigger than the size remaining
|
||||
// in the current cursor
|
||||
gs_data D2 = PushSize_(&A, 128, FileNameAndLineNumberString);
|
||||
TestResult(D2.Size == 128);
|
||||
TestResult(A.CursorsCount != 1);
|
||||
|
||||
// NOTE(PS): Because there is still room in cursor
|
||||
// 0, the head of this gs_data should be one byte
|
||||
// past the end of D1
|
||||
gs_data D3 = PushSize_(&A, 32, FileNameAndLineNumberString);
|
||||
TestResult(D3.Memory == D1.Memory + D1.Size);
|
||||
|
||||
if (i == 0)
|
||||
{
|
||||
ClearArena(&A);
|
||||
} else if (i == 1) {
|
||||
FreeMemoryArena(&A);
|
||||
}
|
||||
}
|
||||
|
||||
FreeMemoryArena(&A);
|
||||
}
|
||||
|
||||
Test("Memory Arena: Push")
|
||||
{
|
||||
gs_allocator Al = CreateAllocator(Win32Alloc, Win32Free);
|
||||
gs_memory_arena A = CreateMemoryArena(Al, "test", 128, 4);
|
||||
|
||||
// NOTE(PS): This makes sure that the Arena is moving its next allocation
|
||||
// pointer forward the appropriate amount after each allocation. If it isnt'
|
||||
// then Array1 should be overlapping with Array0 in the event that the arena
|
||||
// doesn't push the pointer forward enough
|
||||
u32* Array0 = PushArray(&A, u32, 32);
|
||||
u32* Array1 = PushArray(&A, u32, 32);
|
||||
|
||||
for (u32 i = 0; i < 32; i++)
|
||||
{
|
||||
Array0[i] = i;
|
||||
Array1[i] = i * 4;
|
||||
}
|
||||
|
||||
bool Success = true;
|
||||
for (u32 i = 0; i < 32; i++)
|
||||
{
|
||||
Success &= Array0[i] == i && Array1[i] == i * 4;
|
||||
}
|
||||
TestResult(Success);
|
||||
|
||||
FreeArena(&A);
|
||||
}
|
||||
|
||||
int FreeCount = 0;
|
||||
int ClearCount = 0;
|
||||
|
||||
Test("Memory Arena: Stress Test")
|
||||
{
|
||||
gs_allocator Al = CreateAllocator(Win32Alloc, Win32Free);
|
||||
gs_memory_arena A = CreateMemoryArena(Al, "test", 128, 4);
|
||||
|
||||
// NOTE(PS): This is an array of allocation sizes
|
||||
// As we repeat the loop we will get values out of this array
|
||||
// semi-randomly.
|
||||
// * if the value is 0, we will clear the arena
|
||||
// * if the value is 2, we will free the arena
|
||||
// * otherwise we will push a value sized allocation on the arena
|
||||
u64 RandomSizes[] = { 8, 32, 128, 93, 1256, 4098, 0, 1024, 7, 18, 967, 53, 1, 2 };
|
||||
u32 RandomSizesCount = sizeof(RandomSizes) / sizeof(u64);
|
||||
|
||||
bool Success = true;
|
||||
u32 RandomSeed = 1923;
|
||||
for (u64 i = 0; i < (4096 * 14); i++)
|
||||
{
|
||||
TESTNextRandom(&RandomSeed);
|
||||
u32 SizeIndex = RandomSeed % RandomSizesCount;
|
||||
u64 RandomSize = RandomSizes[SizeIndex];
|
||||
|
||||
if (RandomSize == 0)
|
||||
{
|
||||
ClearArena(&A);
|
||||
ClearCount++;
|
||||
} else if (RandomSize == 2) {
|
||||
FreeArena(&A);
|
||||
FreeCount++;
|
||||
} else {
|
||||
gs_data D = PushSize_(&A, RandomSize, FileNameAndLineNumberString);
|
||||
// NOTE(PS): This check has to be >= because the arena
|
||||
// might have adjusted to maintain alignment on this
|
||||
// allocation.
|
||||
Success &= D.Size >= RandomSize;
|
||||
}
|
||||
}
|
||||
|
||||
TestResult(Success);
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -5,6 +5,7 @@
|
|||
//
|
||||
#ifndef SANITY_TESTS_CPP
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include "../gs_libs/gs_types.h"
|
||||
#include "../gs_libs/gs_types.cpp"
|
||||
|
@ -13,21 +14,23 @@
|
|||
#include "../gs_libs/gs_path.h"
|
||||
#include "../gs_libs/gs_csv.h"
|
||||
|
||||
#include "./memory_arena_tests.cpp"
|
||||
|
||||
gs_memory_arena Scratch = {};
|
||||
void* Alloc(u64 Size, u64* ResultSize) { *ResultSize = Size; return malloc(Size); }
|
||||
void Free(void* Ptr, u64 Size) { return free(Ptr); }
|
||||
|
||||
bool StringTest (gs_const_string StrA, gs_const_string StrB)
|
||||
{
|
||||
return StringsEqual(StrA, StrB);
|
||||
return StringsEqual(StrA, StrB);
|
||||
}
|
||||
bool StringTest (gs_string StrA, gs_string StrB)
|
||||
{
|
||||
return StringsEqual(StrA, StrB);
|
||||
return StringsEqual(StrA, StrB);
|
||||
}
|
||||
|
||||
bool PathTest (char* In, char* Out) {
|
||||
return StringsEqual(SanitizePath(ConstString(In), &Scratch), ConstString(Out));
|
||||
return StringsEqual(SanitizePath(ConstString(In), &Scratch), ConstString(Out));
|
||||
}
|
||||
|
||||
global char* SampleCSV = R"FOO(Flower Primary Hue (0-365) Secondary Hue (0-365) Tertiary Hue (0-365) Homonyms
|
||||
|
@ -37,93 +40,95 @@ Flower C 55 32 128 foo, bar, blah, baz, whatever)FOO";
|
|||
|
||||
int main (int ArgCount, char** Args)
|
||||
{
|
||||
Scratch = CreateMemoryArena(CreateAllocator(Alloc, Free), "Scratch");
|
||||
Scratch = CreateMemoryArena(CreateAllocator(Alloc, Free), "Scratch");
|
||||
|
||||
Test("gs_string")
|
||||
{
|
||||
gs_string TestString = PushStringF(&Scratch, 256, "Hello there, Sailor!");
|
||||
|
||||
Test("gs_string")
|
||||
{
|
||||
gs_string TestString = PushStringF(&Scratch, 256, "Hello there, Sailor!");
|
||||
|
||||
NullTerminate(&TestString);
|
||||
TestResult(IsNullTerminated(TestString));
|
||||
|
||||
TestResult(StringTest(GetStringPrefix(TestString.ConstString, 5), ConstString("Hello")));
|
||||
TestResult(StringTest(GetStringPostfix(TestString.ConstString, 5), ConstString("ilor!")));
|
||||
TestResult(StringTest(GetStringAfter(TestString.ConstString, 13), ConstString("Sailor!")));
|
||||
TestResult(StringTest(GetStringBefore(TestString.ConstString, 5), ConstString("Hello")));
|
||||
TestResult(StringTest(Substring(TestString.ConstString, 5, 11), ConstString(" there")));
|
||||
|
||||
TestResult(FindFirst(TestString, 5, 'l') == 16);
|
||||
TestResult(FindFirst(TestString, 0, 'k') == -1);
|
||||
TestResult(FindLast(TestString, 10, 'l') == 3);
|
||||
TestResult(FindLast(TestString, 'k') == -1);
|
||||
|
||||
TestResult(FindFirstFromSet(TestString.ConstString, "re") == 1);
|
||||
TestResult(FindFirstFromSet(TestString.ConstString, "er") == 1);
|
||||
TestResult(FindFirstFromSet(TestString.ConstString, "bk") == -1);
|
||||
TestResult(FindFirstFromSet(TestString.ConstString, "ek") == 1);
|
||||
|
||||
TestResult(FindLastFromSet(TestString.ConstString, "re") == 18);
|
||||
TestResult(FindLastFromSet(TestString.ConstString, "er") == 18);
|
||||
TestResult(FindLastFromSet(TestString.ConstString, "bk") == -1);
|
||||
TestResult(FindLastFromSet(TestString.ConstString, "rk") == 18);
|
||||
|
||||
TestResult(StringContains(TestString.ConstString, ','));
|
||||
TestResult(!StringContains(TestString.ConstString, '@'));
|
||||
TestResult(StringsEqual(TestString, TestString));
|
||||
|
||||
TestResult(StringEqualsCharArray(TestString, "Hello there, Sailor!"));
|
||||
TestResult(!StringEqualsCharArray(TestString, "Hello there, Sailor"));
|
||||
TestResult(!StringEqualsCharArray(TestString, "Foobar"));
|
||||
|
||||
ReverseStringInPlace(&TestString);
|
||||
TestResult(StringTest(TestString, MakeString("!roliaS ,ereht olleH")));
|
||||
ReverseStringInPlace(&TestString);
|
||||
|
||||
TestResult(ParseUInt(ConstString("532")) == 532);
|
||||
TestResult(ParseInt(ConstString("-1234567890")) == -1234567890);
|
||||
TestResult(ParseFloat(ConstString("-12345.6789")) == -12345.6789);
|
||||
TestResult(ParseFloat(ConstString("-1")) == -1);
|
||||
TestResult(ParseFloat(ConstString("-.035")) == -.035);
|
||||
|
||||
TestString.Length = 0;
|
||||
U64ToASCII(&TestString, 53298, 10);
|
||||
TestResult(StringTest(TestString.ConstString, ConstString("53298")));
|
||||
|
||||
TestString.Length = 0;
|
||||
R64ToASCII(&TestString, -145732.321, 2);
|
||||
TestResult(StringTest(TestString.ConstString, ConstString("-145732.32")));
|
||||
}
|
||||
NullTerminate(&TestString);
|
||||
TestResult(IsNullTerminated(TestString));
|
||||
|
||||
Test("gs_path.h")
|
||||
{
|
||||
TestResult(PathTest(".", "."));
|
||||
TestResult(PathTest(".\\", ".\\"));
|
||||
TestResult(PathTest("./", ".\\"));
|
||||
TestResult(PathTest("./../", "..\\"));
|
||||
TestResult(PathTest("C:/users/pslattery\\test.foo", "C:\\users\\pslattery\\test.foo"));
|
||||
TestResult(PathTest("./test/../foo.bar", ".\\foo.bar"));
|
||||
TestResult(PathTest("C:\\hello\\world\\.\\test", "C:\\hello\\world\\test"));
|
||||
}
|
||||
TestResult(StringTest(GetStringPrefix(TestString.ConstString, 5), ConstString("Hello")));
|
||||
TestResult(StringTest(GetStringPostfix(TestString.ConstString, 5), ConstString("ilor!")));
|
||||
TestResult(StringTest(GetStringAfter(TestString.ConstString, 13), ConstString("Sailor!")));
|
||||
TestResult(StringTest(GetStringBefore(TestString.ConstString, 5), ConstString("Hello")));
|
||||
TestResult(StringTest(Substring(TestString.ConstString, 5, 11), ConstString(" there")));
|
||||
|
||||
Test("gs_csv.h")
|
||||
{
|
||||
gs_const_string TestCSV = ConstString(SampleCSV);
|
||||
gscsv_sheet Sheet = CSV_Parse(TestCSV, { '\t' }, &Scratch);
|
||||
|
||||
gs_const_string Cell = CSVSheet_GetCell(Sheet, 0, 0);
|
||||
TestResult(StringsEqual(Cell, ConstString("Flower")));
|
||||
|
||||
Cell = CSVSheet_GetCell(Sheet, 1, 1);
|
||||
TestResult(StringsEqual(Cell, ConstString("55")));
|
||||
|
||||
Cell = CSVSheet_GetCell(Sheet, 4, 1);
|
||||
TestResult(StringsEqual(Cell, ConstString("foo, bar, blah, baz, whatever")));
|
||||
|
||||
Cell = CSVSheet_GetCell(Sheet, 4, 3);
|
||||
TestResult(StringsEqual(Cell, ConstString("foo, bar, blah, baz, whatever")));
|
||||
}
|
||||
TestResult(FindFirst(TestString, 5, 'l') == 16);
|
||||
TestResult(FindFirst(TestString, 0, 'k') == -1);
|
||||
TestResult(FindLast(TestString, 10, 'l') == 3);
|
||||
TestResult(FindLast(TestString, 'k') == -1);
|
||||
|
||||
return 0;
|
||||
TestResult(FindFirstFromSet(TestString.ConstString, "re") == 1);
|
||||
TestResult(FindFirstFromSet(TestString.ConstString, "er") == 1);
|
||||
TestResult(FindFirstFromSet(TestString.ConstString, "bk") == -1);
|
||||
TestResult(FindFirstFromSet(TestString.ConstString, "ek") == 1);
|
||||
|
||||
TestResult(FindLastFromSet(TestString.ConstString, "re") == 18);
|
||||
TestResult(FindLastFromSet(TestString.ConstString, "er") == 18);
|
||||
TestResult(FindLastFromSet(TestString.ConstString, "bk") == -1);
|
||||
TestResult(FindLastFromSet(TestString.ConstString, "rk") == 18);
|
||||
|
||||
TestResult(StringContains(TestString.ConstString, ','));
|
||||
TestResult(!StringContains(TestString.ConstString, '@'));
|
||||
TestResult(StringsEqual(TestString, TestString));
|
||||
|
||||
TestResult(StringEqualsCharArray(TestString, "Hello there, Sailor!"));
|
||||
TestResult(!StringEqualsCharArray(TestString, "Hello there, Sailor"));
|
||||
TestResult(!StringEqualsCharArray(TestString, "Foobar"));
|
||||
|
||||
ReverseStringInPlace(&TestString);
|
||||
TestResult(StringTest(TestString, MakeString("!roliaS ,ereht olleH")));
|
||||
ReverseStringInPlace(&TestString);
|
||||
|
||||
TestResult(ParseUInt(ConstString("532")) == 532);
|
||||
TestResult(ParseInt(ConstString("-1234567890")) == -1234567890);
|
||||
TestResult(ParseFloat(ConstString("-12345.6789")) == -12345.6789);
|
||||
TestResult(ParseFloat(ConstString("-1")) == -1);
|
||||
TestResult(ParseFloat(ConstString("-.035")) == -.035);
|
||||
|
||||
TestString.Length = 0;
|
||||
U64ToASCII(&TestString, 53298, 10);
|
||||
TestResult(StringTest(TestString.ConstString, ConstString("53298")));
|
||||
|
||||
TestString.Length = 0;
|
||||
R64ToASCII(&TestString, -145732.321, 2);
|
||||
TestResult(StringTest(TestString.ConstString, ConstString("-145732.32")));
|
||||
}
|
||||
|
||||
Test("gs_path.h")
|
||||
{
|
||||
TestResult(PathTest(".", "."));
|
||||
TestResult(PathTest(".\\", ".\\"));
|
||||
TestResult(PathTest("./", ".\\"));
|
||||
TestResult(PathTest("./../", "..\\"));
|
||||
TestResult(PathTest("C:/users/pslattery\\test.foo", "C:\\users\\pslattery\\test.foo"));
|
||||
TestResult(PathTest("./test/../foo.bar", ".\\foo.bar"));
|
||||
TestResult(PathTest("C:\\hello\\world\\.\\test", "C:\\hello\\world\\test"));
|
||||
}
|
||||
|
||||
Test("gs_csv.h")
|
||||
{
|
||||
gs_const_string TestCSV = ConstString(SampleCSV);
|
||||
gscsv_sheet Sheet = CSV_Parse(TestCSV, { '\t' }, &Scratch);
|
||||
|
||||
gs_const_string Cell = CSVSheet_GetCell(Sheet, 0, 0);
|
||||
TestResult(StringsEqual(Cell, ConstString("Flower")));
|
||||
|
||||
Cell = CSVSheet_GetCell(Sheet, 1, 1);
|
||||
TestResult(StringsEqual(Cell, ConstString("55")));
|
||||
|
||||
Cell = CSVSheet_GetCell(Sheet, 4, 1);
|
||||
TestResult(StringsEqual(Cell, ConstString("foo, bar, blah, baz, whatever")));
|
||||
|
||||
Cell = CSVSheet_GetCell(Sheet, 4, 3);
|
||||
TestResult(StringsEqual(Cell, ConstString("foo, bar, blah, baz, whatever")));
|
||||
}
|
||||
|
||||
MemoryArenaTests();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue