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