#include "cx/test.h"
#if __GNUC__
#define __alloc_size__(...)
#endif
#include "cx/allocator.h"
#include <errno.h>
CX_TEST(test_allocator_stdlib_malloc) {
void *test = cxMalloc(cxStdlibAllocator,
16);
CX_TEST_DO {
CX_TEST_ASSERT(test !=
NULL);
memcpy(test,
"0123456789ABCDEF",
16);
}
cxFree(cxStdlibAllocator, test);
}
CX_TEST(test_allocator_stdlib_zalloc) {
void *test = cxZalloc(cxStdlibAllocator,
16);
CX_TEST_DO {
CX_TEST_ASSERT(test !=
NULL);
CX_TEST_ASSERT(
0 == memcmp(test,
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0",
16));
}
cxFree(cxStdlibAllocator, test);
}
CX_TEST(test_allocator_stdlib_calloc) {
char *test = cxCalloc(cxStdlibAllocator,
8,
2);
CX_TEST_DO {
CX_TEST_ASSERT(test !=
NULL);
for (
int i =
0; i <
16; i++) {
CX_TEST_ASSERT(test[i] ==
0);
}
}
cxFree(cxStdlibAllocator, test);
}
CX_TEST(test_allocator_stdlib_realloc) {
char *test = cxCalloc(cxStdlibAllocator,
8,
1);
memcpy(test,
"Test",
5);
CX_TEST_DO {
test = cxRealloc(cxStdlibAllocator, test,
16);
CX_TEST_ASSERT(test !=
NULL);
CX_TEST_ASSERT(
0 == strcmp(test,
"Test"));
}
cxFree(cxStdlibAllocator, test);
}
CX_TEST(test_allocator_stdlib_reallocarray) {
char *test = cxCalloc(cxStdlibAllocator,
8,
1);
memcpy(test,
"Test",
5);
CX_TEST_DO {
test = cxReallocArray(cxStdlibAllocator, test,
16,
2);
CX_TEST_ASSERT(test !=
NULL);
CX_TEST_ASSERT(
0 == strcmp(test,
"Test"));
}
cxFree(cxStdlibAllocator, test);
}
CX_TEST(test_allocator_stdlib_reallocarray_overflow) {
char *test = cxCalloc(cxStdlibAllocator,
8,
1);
memcpy(test,
"Test",
5);
CX_TEST_DO {
void *fail = cxReallocArray(cxStdlibAllocator, test,
SIZE_MAX/
2,
4);
CX_TEST_ASSERT(errno ==
EOVERFLOW);
CX_TEST_ASSERT(fail ==
NULL);
CX_TEST_ASSERT(
0 == strcmp(test,
"Test"));
}
cxFree(cxStdlibAllocator, test);
}
CX_TEST(test_allocator_stdlib_free) {
void *test = cxMalloc(cxStdlibAllocator,
16);
CX_TEST_DO {
cxFree(cxStdlibAllocator, test);
CX_TEST_ASSERT(true);
}
}
CX_TEST(test_allocator_default_malloc) {
void *test = cxMallocDefault(
16);
CX_TEST_DO {
CX_TEST_ASSERT(test !=
NULL);
memcpy(test,
"0123456789ABCDEF",
16);
}
cxFreeDefault(test);
}
CX_TEST(test_allocator_default_zalloc) {
void *test = cxZallocDefault(
16);
CX_TEST_DO {
CX_TEST_ASSERT(test !=
NULL);
CX_TEST_ASSERT(
0 == memcmp(test,
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0",
16));
}
cxFreeDefault(test);
}
CX_TEST(test_allocator_default_calloc) {
char *test = cxCallocDefault(
8,
2);
CX_TEST_DO {
CX_TEST_ASSERT(test !=
NULL);
for (
int i =
0; i <
16; i++) {
CX_TEST_ASSERT(test[i] ==
0);
}
}
cxFreeDefault(test);
}
CX_TEST(test_allocator_default_realloc) {
char *test = cxCallocDefault(
8,
1);
memcpy(test,
"Test",
5);
CX_TEST_DO {
test = cxReallocDefault(test,
16);
CX_TEST_ASSERT(test !=
NULL);
CX_TEST_ASSERT(
0 == strcmp(test,
"Test"));
}
cxFreeDefault(test);
}
CX_TEST(test_allocator_default_reallocarray) {
char *test = cxCallocDefault(
8,
1);
memcpy(test,
"Test",
5);
CX_TEST_DO {
test = cxReallocArrayDefault(test,
16,
2);
CX_TEST_ASSERT(test !=
NULL);
CX_TEST_ASSERT(
0 == strcmp(test,
"Test"));
}
cxFreeDefault(test);
}
CX_TEST(test_allocator_default_reallocarray_overflow) {
char *test = cxCallocDefault(
8,
1);
memcpy(test,
"Test",
5);
CX_TEST_DO {
void *fail = cxReallocArrayDefault(test,
SIZE_MAX/
2,
4);
CX_TEST_ASSERT(errno ==
EOVERFLOW);
CX_TEST_ASSERT(fail ==
NULL);
CX_TEST_ASSERT(
0 == strcmp(test,
"Test"));
}
cxFreeDefault(test);
}
CX_TEST(test_allocator_default_free) {
void *test = cxMallocDefault(
16);
CX_TEST_DO {
cxFreeDefault(test);
CX_TEST_ASSERT(true);
}
}
CX_TEST(test_allocator_reallocate) {
char *test = cxCallocDefault(
8,
1);
memcpy(test,
"Test",
5);
CX_TEST_DO {
int ret = cxReallocateDefault(&test,
16);
CX_TEST_ASSERT(ret ==
0);
CX_TEST_ASSERT(test !=
NULL);
CX_TEST_ASSERT(
0 == strcmp(test,
"Test"));
}
cxFreeDefault(test);
}
CX_TEST(test_allocator_reallocate_low_level) {
void *test = calloc(
8,
1);
memcpy(test,
"Test",
5);
CX_TEST_DO {
int ret = cx_reallocate(&test,
16);
CX_TEST_ASSERT(ret ==
0);
CX_TEST_ASSERT(test !=
NULL);
CX_TEST_ASSERT(
0 == strcmp(test,
"Test"));
}
free(test);
}
CX_TEST(test_allocator_reallocatearray) {
char *test = cxCallocDefault(
8,
1);
memcpy(test,
"Test",
5);
CX_TEST_DO {
int ret = cxReallocateArrayDefault(&test,
16,
2);
CX_TEST_ASSERT(ret ==
0);
CX_TEST_ASSERT(test !=
NULL);
CX_TEST_ASSERT(
0 == strcmp(test,
"Test"));
}
cxFreeDefault(test);
}
CX_TEST(test_allocator_reallocatearray_overflow) {
char *test = cxCallocDefault(
8,
1);
memcpy(test,
"Test",
5);
CX_TEST_DO {
int ret = cxReallocateArrayDefault(&test,
SIZE_MAX/
2,
4);
CX_TEST_ASSERT(ret !=
0);
CX_TEST_ASSERT(errno ==
EOVERFLOW);
CX_TEST_ASSERT(test !=
NULL);
CX_TEST_ASSERT(
0 == strcmp(test,
"Test"));
}
cxFreeDefault(test);
}
CX_TEST(test_allocator_reallocatearray_low_level) {
char *test = calloc(
8,
1);
memcpy(test,
"Test",
5);
CX_TEST_DO {
int ret = cx_reallocatearray(&test,
16,
2);
CX_TEST_ASSERT(ret ==
0);
CX_TEST_ASSERT(test !=
NULL);
CX_TEST_ASSERT(
0 == strcmp(test,
"Test"));
}
free(test);
}
CX_TEST(test_allocator_reallocatearray_low_level_overflow) {
char *test = calloc(
8,
1);
memcpy(test,
"Test",
5);
CX_TEST_DO {
int ret = cx_reallocatearray(&test,
SIZE_MAX/
2,
4);
CX_TEST_ASSERT(ret !=
0);
CX_TEST_ASSERT(errno ==
EOVERFLOW);
CX_TEST_ASSERT(test !=
NULL);
CX_TEST_ASSERT(
0 == strcmp(test,
"Test"));
}
free(test);
}
static void *test_allocator_mock_failing_realloc(
cx_attr_unused
void *p,
cx_attr_unused
void *d,
cx_attr_unused
size_t n
) {
return NULL;
}
CX_TEST(test_allocator_reallocate_fails) {
cx_allocator_class mock_cl;
mock_cl.realloc = test_allocator_mock_failing_realloc;
CxAllocator mock = {&mock_cl,
NULL};
void *test = calloc(
8,
1);
memcpy(test,
"Test",
5);
void *original = test;
CX_TEST_DO {
int ret = cxReallocate(&mock, &test,
16);
CX_TEST_ASSERT(ret !=
0);
CX_TEST_ASSERT(test == original);
CX_TEST_ASSERT(
0 == strcmp(test,
"Test"));
}
free(test);
}
CxTestSuite *cx_test_suite_allocator(
void) {
CxTestSuite *suite = cx_test_suite_new(
"allocator");
cx_test_register(suite, test_allocator_stdlib_malloc);
cx_test_register(suite, test_allocator_stdlib_zalloc);
cx_test_register(suite, test_allocator_stdlib_calloc);
cx_test_register(suite, test_allocator_stdlib_realloc);
cx_test_register(suite, test_allocator_stdlib_reallocarray);
cx_test_register(suite, test_allocator_stdlib_reallocarray_overflow);
cx_test_register(suite, test_allocator_stdlib_free);
cx_test_register(suite, test_allocator_default_malloc);
cx_test_register(suite, test_allocator_default_zalloc);
cx_test_register(suite, test_allocator_default_calloc);
cx_test_register(suite, test_allocator_default_realloc);
cx_test_register(suite, test_allocator_default_reallocarray);
cx_test_register(suite, test_allocator_default_reallocarray_overflow);
cx_test_register(suite, test_allocator_default_free);
cx_test_register(suite, test_allocator_reallocate);
cx_test_register(suite, test_allocator_reallocate_fails);
cx_test_register(suite, test_allocator_reallocate_low_level);
cx_test_register(suite, test_allocator_reallocatearray);
cx_test_register(suite, test_allocator_reallocatearray_overflow);
cx_test_register(suite, test_allocator_reallocatearray_low_level);
cx_test_register(suite, test_allocator_reallocatearray_low_level_overflow);
return suite;
}