aboutsummaryrefslogtreecommitdiff
path: root/listpool/test/listpool_test.c
diff options
context:
space:
mode:
author3gg <3gg@shellblade.net>2023-07-13 08:22:18 -0700
committer3gg <3gg@shellblade.net>2023-07-13 08:22:18 -0700
commit9f254f0c7b03236be615b1235cf3fc765d6000ea (patch)
treef0b878ef2b431b909d9efd45c1f9ec8ed8ca54f8 /listpool/test/listpool_test.c
parentfc5886c75ab2626acbc0d7b3db475d17d2cbe01f (diff)
Add mem allocator, remove listpool.
Diffstat (limited to 'listpool/test/listpool_test.c')
-rw-r--r--listpool/test/listpool_test.c183
1 files changed, 0 insertions, 183 deletions
diff --git a/listpool/test/listpool_test.c b/listpool/test/listpool_test.c
deleted file mode 100644
index 7a7b0cf..0000000
--- a/listpool/test/listpool_test.c
+++ /dev/null
@@ -1,183 +0,0 @@
1#include "listpool.h"
2
3#include "test.h"
4
5#define NUM_BLOCKS 10
6
7DEF_LISTPOOL(test_pool, int, NUM_BLOCKS);
8
9static int count(test_pool* pool) {
10 int count = 0;
11 listpool_foreach(pool, n, { count++; });
12 return count;
13}
14
15static int sum(test_pool* pool) {
16 int sum = 0;
17 listpool_foreach(pool, n, { sum += *n; });
18 return sum;
19}
20
21// Create a pool.
22TEST_CASE(listpool_create) {
23 test_pool pool;
24 listpool_make(&pool);
25}
26
27// Allocate all N blocks.
28TEST_CASE(listpool_fully_allocate) {
29 test_pool pool;
30 listpool_make(&pool);
31
32 for (int i = 0; i < NUM_BLOCKS; ++i) {
33 const int* block = listpool_alloc(&pool);
34 TEST_TRUE(block != 0);
35 }
36}
37
38// Allocate all N blocks, then free them.
39TEST_CASE(listpool_fill_then_free) {
40 test_pool pool;
41 listpool_make(&pool);
42
43 int* blocks[NUM_BLOCKS] = {0};
44 for (int i = 0; i < NUM_BLOCKS; i++) {
45 blocks[i] = listpool_alloc(&pool);
46 TEST_TRUE(blocks[i] != 0);
47 }
48
49 for (int i = 0; i < NUM_BLOCKS; i++) {
50 listpool_free(&pool, &blocks[i]);
51 TEST_EQUAL(blocks[i], 0); // Pointer should be set to 0 on free.
52 }
53
54 TEST_EQUAL(count(&pool), 0);
55}
56
57// Attempt to allocate blocks past the maximum pool size.
58// The pool should handle the failed allocations gracefully.
59TEST_CASE(listpool_allocate_beyond_max_size) {
60 test_pool pool;
61 listpool_make(&pool);
62
63 // Fully allocate the pool.
64 for (int i = 0; i < NUM_BLOCKS; ++i) {
65 TEST_TRUE(listpool_alloc(&pool) != 0);
66 }
67
68 // Past the end.
69 for (int i = 0; i < NUM_BLOCKS; ++i) {
70 TEST_EQUAL(listpool_alloc(&pool), 0);
71 }
72}
73
74// Free blocks should always remain zeroed out.
75// This tests the invariant right after creating the pool.
76TEST_CASE(listpool_zero_free_blocks_after_creation) {
77 test_pool pool;
78 listpool_make(&pool);
79
80 const int zero = 0;
81 for (int i = 0; i < NUM_BLOCKS; ++i) {
82 const int* block = (const int*)(pool.blocks) + i;
83 TEST_EQUAL(memcmp(block, &zero, sizeof(int)), 0);
84 }
85}
86
87// Free blocks should always remain zeroed out.
88// This tests the invariant after freeing a block.
89TEST_CASE(listpool_zero_free_block_after_free) {
90 test_pool pool;
91 listpool_make(&pool);
92
93 int* val = listpool_alloc(&pool);
94 TEST_TRUE(val != 0);
95 *val = 177;
96
97 int* old_val = val;
98 listpool_free(&pool, &val); // val pointer is set to 0.
99 TEST_EQUAL(*old_val, 0); // Block is zeroed out after free.
100}
101
102// Traverse an empty pool.
103TEST_CASE(listpool_traverse_empty) {
104 test_pool pool;
105 listpool_make(&pool);
106
107 TEST_EQUAL(count(&pool), 0);
108}
109
110// Traverse a partially full pool.
111TEST_CASE(listpool_traverse_partially_full) {
112 const int N = NUM_BLOCKS / 2;
113
114 test_pool pool;
115 listpool_make(&pool);
116
117 for (int i = 0; i < N; ++i) {
118 int* val = listpool_alloc(&pool);
119 TEST_TRUE(val != 0);
120 *val = i + 1;
121 }
122
123 TEST_EQUAL(sum(&pool), (N) * (N + 1) / 2);
124}
125
126// Traverse a full pool.
127TEST_CASE(listpool_traverse_full) {
128 test_pool pool;
129 listpool_make(&pool);
130
131 for (int i = 0; i < NUM_BLOCKS; ++i) {
132 int* val = listpool_alloc(&pool);
133 TEST_TRUE(val != 0);
134 *val = i + 1;
135 }
136
137 TEST_EQUAL(sum(&pool), (NUM_BLOCKS) * (NUM_BLOCKS + 1) / 2);
138}
139
140// Get the ith (allocated) block.
141TEST_CASE(listpool_get_block) {
142 test_pool pool;
143 listpool_make(&pool);
144
145 for (int i = 0; i < NUM_BLOCKS; ++i) {
146 int* block = listpool_alloc(&pool);
147 TEST_TRUE(block != 0);
148 *block = i;
149 TEST_EQUAL(listpool_get_block_index(&pool, block), (size_t)i);
150 }
151
152 for (int i = 0; i < NUM_BLOCKS; ++i) {
153 TEST_EQUAL(*listpool_get_block(&pool, i), i);
154 }
155}
156
157// Remove a value from the list.
158TEST_CASE(listpool_remove_value) {
159 test_pool pool;
160 listpool_make(&pool);
161
162 int* x = listpool_alloc(&pool);
163 int* y = listpool_alloc(&pool);
164 TEST_TRUE(x != 0);
165 TEST_TRUE(y != 0);
166
167 *x = 155;
168 *y = 177;
169
170 listpool_remove(&pool, 155); // x
171
172 TEST_EQUAL(count(&pool), 1);
173 TEST_EQUAL(sum(&pool), *y);
174}
175
176// Stress test.
177//
178// 1. Allocate the pool, either fully or partially. If fully, attempt to
179// allocate some items past the end.
180//
181// 2. Free all allocated items in some random order.
182
183int main() { return 0; }