summaryrefslogtreecommitdiff
path: root/test/memory/general.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'test/memory/general.cpp')
-rw-r--r--test/memory/general.cpp220
1 files changed, 220 insertions, 0 deletions
diff --git a/test/memory/general.cpp b/test/memory/general.cpp
new file mode 100644
index 0000000..825e2f6
--- /dev/null
+++ b/test/memory/general.cpp
@@ -0,0 +1,220 @@
+
+#include "memory.hpp"
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+struct TMemBlock {
+ char *data;
+ size_t size;
+};
+
+struct TMemBucket {
+ int64_t size;
+ int64_t head;
+ int64_t lostBytes;
+ int64_t allocs;
+ int64_t lastEmptyBlockIndex;
+ int64_t maxBlockCount;
+ TMemBlock *blocks;
+ char *ptr;
+ bool transient;
+};
+
+class MemoryTest : public ::testing::Test {
+protected:
+ void SetUp() override {
+ MemBkt_Test = Pke_BeginTransientBucket(1024 * 1024);
+ bkt = reinterpret_cast<TMemBucket *>(MemBkt_Test);
+ };
+ void TearDown() override {
+ Pke_EndTransientBucket(MemBkt_Test);
+ };
+ MemBucket *MemBkt_Test = nullptr;
+ TMemBucket *bkt = nullptr;
+};
+
+/*
+ * Test that memory can be allocated predictably
+ */
+TEST_F(MemoryTest, EnsureAllocation001) {
+ // arrange
+ size_t sz = 2;
+ size_t alignment = 1;
+
+ // act
+ Pke_New(sz, alignment, MemBkt_Test);
+
+ // assert
+ EXPECT_EQ(-1, bkt->lastEmptyBlockIndex);
+ EXPECT_EQ(sz, bkt->head);
+};
+
+/*
+ * Test that memory can be freed predictably
+ */
+TEST_F(MemoryTest, EnsureFree001) {
+ // arrange
+ size_t sz = 2;
+ size_t alignment = 1;
+
+ // act
+ void *ptr1 = Pke_New(sz, alignment, MemBkt_Test);
+ Pke_Delete(ptr1, sz, MemBkt_Test);
+
+ // assert
+ EXPECT_EQ(-1, bkt->lastEmptyBlockIndex);
+ EXPECT_EQ(0, bkt->head);
+};
+
+
+/*
+ * Test that memory can be allocated and freed predictably
+ */
+class MemoryTestScenario100 : public MemoryTest {
+ void SetUp() override {
+ MemoryTest::SetUp();
+ for (long i = 0; i < cnt; ++i) {
+ ptrs[i] = Pke_New(sz[i], alignment[i], MemBkt_Test);
+ }
+ }
+protected:
+ void TestExpectedState() {
+ EXPECT_EQ(2, bkt->lastEmptyBlockIndex);
+ EXPECT_EQ(80, bkt->head);
+ EXPECT_EQ(bkt->ptr + 00, ptrs[0]);
+ EXPECT_EQ(bkt->ptr + 64, ptrs[1]);
+ EXPECT_EQ(bkt->ptr + 16, ptrs[2]);
+ EXPECT_EQ(bkt->ptr + 8, ptrs[3]);
+ }
+ const long cnt = 4;
+ const size_t sz[4] = {2, 16, 16, 4};
+ const size_t alignment[4] = {1, 64, 16, 8};
+ void * ptrs[4];
+};
+
+/* allocation events
+ * 1st = alignment 01, size 02, move head ( =02 )
+ * 2nd = alignment 64, size 16, move head ( =80 ) memBlock { +02, 62 }
+ * 3rd = alignment 16, size 16, memBlock { +2, 14 } memBlock { +32, 32 }
+ * 4th = alignment 08, size 04, memBlock { +2, 06 } memBlock { +12, 04 } memBlock { +32, 32 }
+ */
+
+TEST_F(MemoryTestScenario100, EnsureAllocFree0000) {
+ EXPECT_NO_FATAL_FAILURE(this->TestExpectedState());
+
+ // arrange
+
+ // act
+
+ // assert
+ EXPECT_EQ(bkt->ptr + 2, bkt->blocks[0].data);
+ EXPECT_EQ(6, bkt->blocks[0].size);
+
+ EXPECT_EQ(bkt->ptr + 12, bkt->blocks[1].data);
+ EXPECT_EQ(4, bkt->blocks[1].size);
+
+ EXPECT_EQ(bkt->ptr + 32, bkt->blocks[2].data);
+ EXPECT_EQ(32, bkt->blocks[2].size);
+}
+
+TEST_F(MemoryTestScenario100, EnsureAllocFree1000) {
+ EXPECT_NO_FATAL_FAILURE(this->TestExpectedState());
+
+ // arrange
+ size_t expectedHead = 80;
+ long freeIndex = 0;
+
+ // act
+ /* free events
+ * 1st = ptr +00, size 02, memBlock { +00, 08 }
+ */
+ Pke_Delete(ptrs[freeIndex], sz[freeIndex], MemBkt_Test);
+
+ // assert
+ EXPECT_EQ(2, bkt->lastEmptyBlockIndex);
+ EXPECT_EQ(expectedHead, bkt->head);
+
+ EXPECT_EQ(bkt->ptr + 0, bkt->blocks[0].data);
+ EXPECT_EQ(8, bkt->blocks[0].size);
+
+ EXPECT_EQ(bkt->ptr + 12, bkt->blocks[1].data);
+ EXPECT_EQ(4, bkt->blocks[1].size);
+
+ EXPECT_EQ(bkt->ptr + 32, bkt->blocks[2].data);
+ EXPECT_EQ(32, bkt->blocks[2].size);
+};
+
+TEST_F(MemoryTestScenario100, EnsureAllocFree0100) {
+ EXPECT_NO_FATAL_FAILURE(this->TestExpectedState());
+
+ // arrange
+ size_t expectedHead = 32;
+ long freeIndex = 1;
+
+ // act
+ /* free events
+ * 1st = ptr +64, size 16, move head ( =32 ) memBlock { +02, 06 } memBlock { +12, 4 }
+ */
+ Pke_Delete(ptrs[freeIndex], sz[freeIndex], MemBkt_Test);
+
+ // assert
+ EXPECT_EQ(1, bkt->lastEmptyBlockIndex);
+ EXPECT_EQ(expectedHead, bkt->head);
+
+ EXPECT_EQ(bkt->ptr + 2, bkt->blocks[0].data);
+ EXPECT_EQ(6, bkt->blocks[0].size);
+
+ EXPECT_EQ(bkt->ptr + 12, bkt->blocks[1].data);
+ EXPECT_EQ(4, bkt->blocks[1].size);
+};
+
+TEST_F(MemoryTestScenario100, EnsureAllocFree0010) {
+ EXPECT_NO_FATAL_FAILURE(this->TestExpectedState());
+
+ // arrange
+ size_t expectedHead = 80;
+ long freeIndex = 2;
+
+ // act
+ /* free events
+ * 1st = ptr +16, size 16, memBlock { +02, 06 } memBlock { +12, 04 } memBlock { +16, 48 }
+ * memBlock { +02, 06 } memBlock { +12, 52 }
+ */
+ Pke_Delete(ptrs[freeIndex], sz[freeIndex], MemBkt_Test);
+
+ // assert
+ EXPECT_EQ(1, bkt->lastEmptyBlockIndex);
+ EXPECT_EQ(expectedHead, bkt->head);
+
+ EXPECT_EQ(bkt->ptr + 2, bkt->blocks[0].data);
+ EXPECT_EQ(6, bkt->blocks[0].size);
+
+ EXPECT_EQ(bkt->ptr + 12, bkt->blocks[1].data);
+ EXPECT_EQ(52, bkt->blocks[1].size);
+}
+
+TEST_F(MemoryTestScenario100, EnsureAllocFree0001) {
+ EXPECT_NO_FATAL_FAILURE(this->TestExpectedState());
+
+ // arrange
+ size_t expectedHead = 80;
+ long freeIndex = 3;
+
+ // act
+ /* free events
+ * 1st = ptr +08, size 4, memBlock { +02, 06 } memBlock { +08, 08 } memBlock { +32, 32 }
+ * memBlock { +02, 14 } memBlock { +32, 32 }
+ */
+ Pke_Delete(ptrs[freeIndex], sz[freeIndex], MemBkt_Test);
+
+ // assert
+ EXPECT_EQ(1, bkt->lastEmptyBlockIndex);
+ EXPECT_EQ(expectedHead, bkt->head);
+
+ EXPECT_EQ(bkt->ptr + 2, bkt->blocks[0].data);
+ EXPECT_EQ(14, bkt->blocks[0].size);
+
+ EXPECT_EQ(bkt->ptr + 32, bkt->blocks[1].data);
+ EXPECT_EQ(32, bkt->blocks[1].size);
+}