aboutsummaryrefslogtreecommitdiff
path: root/memstack/test/memstack_test.c
diff options
context:
space:
mode:
Diffstat (limited to 'memstack/test/memstack_test.c')
-rw-r--r--memstack/test/memstack_test.c165
1 files changed, 165 insertions, 0 deletions
diff --git a/memstack/test/memstack_test.c b/memstack/test/memstack_test.c
new file mode 100644
index 0000000..5308be3
--- /dev/null
+++ b/memstack/test/memstack_test.c
@@ -0,0 +1,165 @@
1#include "memstack.h"
2
3#include "test.h"
4
5#define NUM_INTS 10
6#define CAPACITY (NUM_INTS * sizeof(int))
7
8// Create and destroy a statically-backed stack.
9TEST_CASE(memstack_create) {
10 int memory[CAPACITY];
11
12 memstack stack = {0};
13 memstack_make(&stack, CAPACITY, memory);
14 memstack_del(&stack);
15}
16
17// Create and destroy a dynamically-backed stack.
18TEST_CASE(mem_create_dyn) {
19 memstack stack = {0};
20 memstack_make(&stack, CAPACITY, nullptr);
21 memstack_del(&stack);
22}
23
24// Allocate all N ints.
25TEST_CASE(memstack_allocate_until_full) {
26 memstack stack = {0};
27 memstack_make(&stack, CAPACITY, nullptr);
28
29 for (int i = 0; i < NUM_INTS; ++i) {
30 const int* block = memstack_alloc(&stack, sizeof(int));
31 TEST_TRUE(block != nullptr);
32 }
33
34 TEST_TRUE(memstack_size(&stack) == CAPACITY);
35
36 memstack_del(&stack);
37}
38
39// Allocate all N ints, then free them.
40TEST_CASE(memstack_fill_then_free) {
41 memstack stack = {0};
42 memstack_make(&stack, CAPACITY, nullptr);
43
44 int* blocks[NUM_INTS] = {nullptr};
45 for (int i = 0; i < NUM_INTS; ++i) {
46 blocks[i] = memstack_alloc(&stack, sizeof(int));
47 TEST_TRUE(blocks[i] != nullptr);
48 }
49
50 memstack_clear(&stack);
51
52 TEST_EQUAL(memstack_size(&stack), 0);
53
54 memstack_del(&stack);
55}
56
57// Attempt to allocate blocks past the maximum stack size.
58// The stack should handle the failed allocations gracefully.
59TEST_CASE(memstack_allocate_beyond_max_size) {
60 memstack stack = {0};
61 memstack_make(&stack, CAPACITY, nullptr);
62 memstack_enable_traps(&stack, false);
63
64 // Fully allocate the stack.
65 for (int i = 0; i < NUM_INTS; ++i) {
66 TEST_TRUE(memstack_alloc(&stack, sizeof(int)) != nullptr);
67 }
68
69 // Past the end.
70 for (int i = 0; i < NUM_INTS; ++i) {
71 TEST_EQUAL(memstack_alloc(&stack, sizeof(int)), nullptr);
72 }
73
74 TEST_TRUE(memstack_size(&stack) == CAPACITY);
75
76 memstack_del(&stack);
77}
78
79// Free blocks should always remain zeroed out.
80// This tests the invariant right after creating the stack.
81TEST_CASE(memstack_zero_free_blocks_after_creation) {
82 memstack stack = {0};
83 memstack_make(&stack, CAPACITY, nullptr);
84
85 for (int i = 0; i < NUM_INTS; ++i) {
86 const int* block = memstack_alloc(&stack, sizeof(int));
87 TEST_TRUE(block != nullptr);
88 TEST_EQUAL(*block, 0);
89 }
90
91 memstack_del(&stack);
92}
93
94// Free blocks should always remain zeroed out.
95// This tests the invariant after clearing the stack and allocating a new block.
96TEST_CASE(memstack_zero_free_block_after_free) {
97 memstack stack = {0};
98 memstack_make(&stack, CAPACITY, nullptr);
99
100 for (int i = 0; i < NUM_INTS; ++i) {
101 const int* block = memstack_alloc(&stack, sizeof(int));
102 TEST_TRUE(block != nullptr);
103 TEST_EQUAL(*block, 0);
104 }
105
106 memstack_clear(&stack);
107
108 for (int i = 0; i < NUM_INTS; ++i) {
109 const int* block = memstack_alloc(&stack, sizeof(int));
110 TEST_TRUE(block != nullptr);
111 TEST_EQUAL(*block, 0);
112 }
113
114 memstack_del(&stack);
115}
116
117// Aligned allocations should be properly aligned.
118TEST_CASE(memstack_alloc_aligned) {
119 memstack stack = {0};
120 memstack_make(&stack, CAPACITY, nullptr);
121
122 // -1 because the base address of the memory storage might be unaligned.
123 for (int i = 0; i < NUM_INTS - 1; ++i) {
124 const int* block =
125 memstack_alloc_aligned(&stack, sizeof(int), alignof(int));
126 TEST_TRUE(block != nullptr);
127 TEST_EQUAL(*block, 0);
128 TEST_EQUAL((uintptr_t)block % alignof(int), 0);
129 }
130
131 memstack_del(&stack);
132}
133
134// Get and set the watermark.
135TEST_CASE(memstack_watermark) {
136 memstack stack = {0};
137 memstack_make(&stack, CAPACITY, nullptr);
138
139 // Allocate N/2 ints.
140 for (int i = 0; i < NUM_INTS / 2; ++i) {
141 const int* block = memstack_alloc(&stack, sizeof(int));
142 TEST_TRUE(block != nullptr);
143 }
144
145 const size_t watermark = memstack_watermark(&stack);
146
147 // Allocate the remaining N/2 ints.
148 for (int i = 0; i < NUM_INTS / 2; ++i) {
149 const int* block = memstack_alloc(&stack, sizeof(int));
150 TEST_TRUE(block != nullptr);
151 }
152
153 // Now reset the watermark halfway through.
154 memstack_set_watermark(&stack, watermark);
155
156 // Allocate the remaining N/2 ints (again).
157 for (int i = 0; i < NUM_INTS / 2; ++i) {
158 const int* block = memstack_alloc(&stack, sizeof(int));
159 TEST_TRUE(block != nullptr);
160 }
161
162 memstack_del(&stack);
163}
164
165int main() { return 0; }