From bf19b9938508f70011395f4dc283ca758ec6a8d3 Mon Sep 17 00:00:00 2001 From: Ethan Werner Date: Sat, 19 Sep 2026 06:09:54 +0000 Subject: llm tooling --- tests/test_pool.c | 150 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 tests/test_pool.c (limited to 'tests/test_pool.c') diff --git a/tests/test_pool.c b/tests/test_pool.c new file mode 100644 index 0000000..2c75688 --- /dev/null +++ b/tests/test_pool.c @@ -0,0 +1,150 @@ +// Tests for pool.h - memory pool allocation and free-list operations +#define POOL_IMPLEMENTATION +#include "../include/pool.h" + +#include +#include +#include + +#define ASSERT(cond, msg) \ + do { \ + if (!(cond)) { \ + fprintf(stderr, "FAIL: %s (test_pool.c:%d)\n", msg, __LINE__); \ + failures++; \ + } \ + } while (0) + +static int failures = 0; + +void test_init_and_fini() { + pool_t *p = pool_init(32, 10); + ASSERT(p != NULL, "pool_init returns non-NULL"); + if (!p) return; + ASSERT(p->block_s == 32, "block size"); + ASSERT(p->block_n == 10, "block count"); + pool_fini(&p); +} + +void test_malloc_and_free() { + pool_t *p = pool_init(64, 5); + + void *b1 = pool_malloc(p); + void *b2 = pool_malloc(p); + void *b3 = pool_malloc(p); + + ASSERT(b1 != NULL, "malloc 1"); + ASSERT(b2 != NULL, "malloc 2"); + ASSERT(b3 != NULL, "malloc 3"); + ASSERT(b1 != b2, "malloc returns different blocks"); + ASSERT(pool_size(p) == 3, "size after 3 mallocs"); + + pool_free(p, b2); + ASSERT(pool_size(p) == 2, "size after 1 free"); + + pool_free(p, b1); + pool_free(p, b3); + ASSERT(pool_size(p) == 0, "size after all frees"); + + pool_fini(&p); +} + +void test_reuse_freed_block() { + pool_t *p = pool_init(32, 3); + + void *b1 = pool_malloc(p); + void *b2 = pool_malloc(p); + pool_free(p, b1); + + void *b3 = pool_malloc(p); + ASSERT(b3 == b1, "reuses freed block"); + + pool_free(p, b2); + pool_free(p, b3); + pool_fini(&p); +} + +void test_capacity_and_size() { + pool_t *p = pool_init(16, 20); + ASSERT(pool_capacity(p) == 20, "capacity"); + ASSERT(pool_size(p) == 0, "initial size is 0"); + + pool_malloc(p); + pool_malloc(p); + ASSERT(pool_size(p) == 2, "size after 2 mallocs"); + + pool_fini(&p); +} + +void test_exhaust_pool() { + pool_t *p = pool_init(16, 2); + pool_malloc(p); + pool_malloc(p); + void *overflow = pool_malloc(p); + ASSERT(overflow == NULL, "returns NULL when exhausted"); + + pool_fini(&p); +} + +void test_write_and_read_block() { + pool_t *p = pool_init(32, 1); + int32_t *block = pool_malloc(p); + ASSERT(block != NULL, "pool_malloc returns non-NULL"); + if (!block) { pool_fini(&p); return; } + *block = 42; + ASSERT(*block == 42, "can write and read block data"); + pool_fini(&p); +} + +void test_multiple_free_fini() { + pool_t *p = pool_init(16, 1); + pool_fini(&p); + pool_fini(&p); + pool_fini(NULL); +} + +void test_free_invalid_pointer() { + pool_t *p = pool_init(32, 3); + void *b1 = pool_malloc(p); + ASSERT(pool_size(p) == 1, "size before invalid free"); + + int stack_var; + pool_free(p, &stack_var); + ASSERT(pool_size(p) == 1, "invalid free rejected (stack ptr)"); + + pool_free(p, (void *)0x12345678); + ASSERT(pool_size(p) == 1, "invalid free rejected (random ptr)"); + + pool_free(p, NULL); + ASSERT(pool_size(p) == 1, "invalid free rejected (NULL)"); + + pool_free(NULL, b1); + ASSERT(pool_size(p) == 1, "invalid free rejected (NULL pool)"); + + pool_free(p, b1); + ASSERT(pool_size(p) == 0, "valid free accepted"); + + pool_fini(&p); +} + +void test_init_invalid_block_size() { + pool_t *p = pool_init(3, 10); + ASSERT(p == NULL, "block size < sizeof(void*) returns NULL"); + + p = pool_init(7, 10); + ASSERT(p == NULL, "block size not multiple of sizeof(void*) returns NULL"); +} + +int main() { + test_init_and_fini(); + test_malloc_and_free(); + test_reuse_freed_block(); + test_capacity_and_size(); + test_exhaust_pool(); + test_write_and_read_block(); + test_multiple_free_fini(); + test_free_invalid_pointer(); + test_init_invalid_block_size(); + + printf("test_pool: %d failures\n", failures); + return failures; +} -- cgit v1.3.1