diff options
Diffstat (limited to 'src/unit/allocator_utils.h')
-rw-r--r-- | src/unit/allocator_utils.h | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/src/unit/allocator_utils.h b/src/unit/allocator_utils.h new file mode 100644 index 0000000..f0af88c --- /dev/null +++ b/src/unit/allocator_utils.h @@ -0,0 +1,86 @@ +#ifndef SAND_UNIT_ALLOCATOR_UTILS_H +#define SAND_UNIT_ALLOCATOR_UTILS_H + +// This module defines some tests for running against allocators. + +#include "../core/allocator.h" + +#include "greatest.h" + +inline TEST test_allocator_basic_usage(SandAllocator *a) { + size_t count = 100; + int *ptr = sand_allocate(a, sizeof(int) * count); + ASSERT_NEQm("Small allocation should not fail", ptr, NULL); + // Unit tests are run under address sanitizer, so this should catch when + // returned memory isn't actually writable. + for (size_t i = 0; i < count; ++i) { + ptr[i] = 123; + } + // FIXME: I don't really know how to test this. + sand_deallocate(a, ptr, sizeof(int) * count); + PASS(); +} + +inline TEST test_allocator_reallocation(SandAllocator *a) { + size_t count = 50; + int *ptr = sand_allocate(a, sizeof(int) * count); + ASSERT_NEQm("Small allocation should not fail", ptr, NULL); + + for (size_t i = 0; i < count; ++i) { + ptr[i] = 123; + } + + size_t new_count = 100; + int *new_ptr = sand_reallocate(a, ptr, sizeof(int) * count, sizeof(int) * new_count); + ASSERT_NEQm("Small reallocation should not fail", new_ptr, NULL); + + for (size_t i = 0; i < count; ++i) { + ASSERT_EQm("Reallocated memory is copied over", new_ptr[i], 123); + } + + // Just like `test_std_allocator_basic_usage` this should + // ensure newly allocated memory is reallocated. + for (size_t i = count; i < new_count; ++i) { + new_ptr[i] = 456; + } + + sand_deallocate(a, new_ptr, sizeof(int) * new_count); + PASS(); +} + +inline TEST test_allocator_weird_alignments(SandAllocator *a) { + size_t alignments[] = {2,4,8,16,32,64,128,256,1024}; + + for (unsigned i = 0; i < sizeof(alignments)/sizeof((alignments)[0]); ++i) { + int *allocation = sand_allocate_aligned(a, sizeof(*allocation), alignments[i]); + *allocation = 123; // ASAN will crash us if invalid memory is returned. + sand_deallocate(a, allocation, sizeof(*allocation)); + } + + PASS(); +} + +inline TEST test_allocator_unreasonably_large_allocation_fails_gracefully(SandAllocator *a) { +#if defined(__has_feature) +# if __has_feature(address_sanitizer) + SKIPm("Test does not work under address_sanitizer"); +# endif +#endif + + // Compute a request size which is very unlikely to be available. + // kibi mebi gibi tebi -byte + size_t size = (size_t)1024 * 1024 * 1024 * 1024; + + void *result = sand_allocate(a, size); + ASSERT_EQm("Allocation should fail", result, NULL); + + PASS(); +} + +#define RUN_ALLOCATOR_TESTS(DO) \ + DO(test_allocator_basic_usage) \ + DO(test_allocator_reallocation) \ + DO(test_allocator_weird_alignments) \ + DO(test_allocator_unreasonably_large_allocation_fails_gracefully) + +#endif |