summaryrefslogtreecommitdiff
path: root/src/unit/allocator_utils.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/unit/allocator_utils.h')
-rw-r--r--src/unit/allocator_utils.h86
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