From 7d932b4e8022b8d42d8d546920aa8fc684d212ad Mon Sep 17 00:00:00 2001 From: Hamza Chandad Date: Mon, 12 Sep 2022 18:25:58 +0000 Subject: [PATCH] test: port test/test-api.c Signed-off-by: Hamza Chandad --- Config.uk | 11 + Makefile.uk | 7 + ...001-test-use-uk-test.h-in-test-api.c.patch | 468 ++++++++++++++++++ 3 files changed, 486 insertions(+) create mode 100644 patches/0001-test-use-uk-test.h-in-test-api.c.patch diff --git a/Config.uk b/Config.uk index 6dd18fd..05e2c73 100644 --- a/Config.uk +++ b/Config.uk @@ -19,4 +19,15 @@ if LIBMIMALLOC config MIMALLOC_ASSERT bool "Enable assertions" default n + config LIBMIMALLOC_TEST + bool "Enable libmimalloc tests" + select LIBUKTEST + default n + help + Enables all libmimalloc tests. + if LIBMIMALLOC_TEST + config LIBMIMALLOC_TEST_API + bool "Enable libmimalloc api test suite" + default y + endif endif diff --git a/Makefile.uk b/Makefile.uk index 911ec7a..0e9fc37 100644 --- a/Makefile.uk +++ b/Makefile.uk @@ -93,3 +93,10 @@ LIBMIMALLOC_SRCS-y += $(LIBMIMALLOC)/src/options.c LIBMIMALLOC_SRCS-y += $(LIBMIMALLOC)/src/init.c #LIBMIMALLOC_SRCS-y += $(LIBMIMALLOC)/src/alloc-override.c #LIBMIMALLOC_SRCS-y += $(LIBMIMALLOC)/src/page-queue.c + +################################################################################ +# Tests +################################################################################ +ifneq ($(filter y, $(CONFIG_LIBMIMALLOC_TEST_API) $(CONFIG_LIBUKTEST_ALL)),) +LIBMIMALLOC_SRCS-y += $(LIBMIMALLOC)/test/test-api.c +endif diff --git a/patches/0001-test-use-uk-test.h-in-test-api.c.patch b/patches/0001-test-use-uk-test.h-in-test-api.c.patch new file mode 100644 index 0000000..ee31fb1 --- /dev/null +++ b/patches/0001-test-use-uk-test.h-in-test-api.c.patch @@ -0,0 +1,468 @@ +From 546538ef2fe5ddc519980624165872c27c6cb2e5 Mon Sep 17 00:00:00 2001 +From: Hamza Chandad +Date: Mon, 19 Sep 2022 17:39:16 +0000 +Subject: [PATCH] test: use uk/test.h in test-api.c + +Signed-off-by: Hamza Chandad +--- + test/test-api.c | 424 ++++++++++++++++++++++++++---------------------- + 1 file changed, 229 insertions(+), 195 deletions(-) + +diff --git a/test/test-api.c b/test/test-api.c +index 166cfca..5b0dcf6 100644 +--- a/test/test-api.c ++++ b/test/test-api.c +@@ -26,6 +26,8 @@ we therefore test the API over various inputs. Please add more tests :-) + #include + #include + ++#include ++ + #ifdef __cplusplus + #include + #endif +@@ -33,214 +35,246 @@ we therefore test the API over various inputs. Please add more tests :-) + #include "mimalloc.h" + // #include "mimalloc-internal.h" + +-// --------------------------------------------------------------------------- +-// Test macros: CHECK(name,predicate) and CHECK_BODY(name,body) +-// --------------------------------------------------------------------------- +-static int ok = 0; +-static int failed = 0; +- +-#define CHECK_BODY(name,body) \ +- do { \ +- fprintf(stderr,"test: %s... ", name ); \ +- bool result = true; \ +- do { body } while(false); \ +- if (!(result)) { \ +- failed++; \ +- fprintf(stderr, \ +- "\n FAILED: %s:%d:\n %s\n", \ +- __FILE__, \ +- __LINE__, \ +- #body); \ +- /* exit(1); */ \ +- } \ +- else { \ +- ok++; \ +- fprintf(stderr,"ok.\n"); \ +- } \ +- } while (false) +- +-#define CHECK(name,expr) CHECK_BODY(name,{ result = (expr); }) +- +-// --------------------------------------------------------------------------- +-// Test functions +-// --------------------------------------------------------------------------- +-bool test_heap1(); +-bool test_heap2(); +-bool test_stl_allocator1(); +-bool test_stl_allocator2(); +- +-// --------------------------------------------------------------------------- +-// Main testing +-// --------------------------------------------------------------------------- +-int main() { +- mi_option_disable(mi_option_verbose); +- +- // --------------------------------------------------- +- // Malloc +- // --------------------------------------------------- +- +- CHECK_BODY("malloc-zero",{ +- void* p = mi_malloc(0); mi_free(p); +- }); +- CHECK_BODY("malloc-nomem1",{ +- result = (mi_malloc(SIZE_MAX/2) == NULL); +- }); +- CHECK_BODY("malloc-null",{ +- mi_free(NULL); +- }); +- CHECK_BODY("calloc-overflow",{ ++// Declared as a variable, to get a readable testsuite log ++const int SHOULD_NOT_CRASH = 1; ++ ++// --------------------------------------------------- ++// Malloc ++// --------------------------------------------------- ++ ++UK_TESTCASE(libmimalloc_api_testsuite, malloc_zero) ++{ ++ void *p = &p; ++ ++ p = mi_malloc(0); ++ UK_TEST_EXPECT(p != &p); ++ mi_free(p); ++ ++ UK_TEST_EXPECT(SHOULD_NOT_CRASH); ++} ++ ++UK_TESTCASE(libmimalloc_api_testsuite, malloc_nomem1) ++{ ++ UK_TEST_EXPECT_PTR_EQ(mi_malloc(SIZE_MAX/2), NULL); ++} ++ ++UK_TESTCASE(libmimalloc_api_testsuite, malloc_null) ++{ ++ mi_free(NULL); ++ ++ UK_TEST_EXPECT(SHOULD_NOT_CRASH); ++} ++ ++UK_TESTCASE(libmimalloc_api_testsuite, calloc_overflow) ++{ + // use (size_t)&mi_calloc to get some number without triggering compiler warnings +- result = (mi_calloc((size_t)&mi_calloc,SIZE_MAX/1000) == NULL); +- }); +- CHECK_BODY("calloc0",{ +- result = (mi_usable_size(mi_calloc(0,1000)) <= 16); +- }); +- +- // --------------------------------------------------- +- // Extended +- // --------------------------------------------------- +- CHECK_BODY("posix_memalign1", { +- void* p = &p; +- int err = mi_posix_memalign(&p, sizeof(void*), 32); +- result = ((err==0 && (uintptr_t)p % sizeof(void*) == 0) || p==&p); +- mi_free(p); +- }); +- CHECK_BODY("posix_memalign_no_align", { +- void* p = &p; +- int err = mi_posix_memalign(&p, 3, 32); +- result = (err==EINVAL && p==&p); +- }); +- CHECK_BODY("posix_memalign_zero", { +- void* p = &p; +- int err = mi_posix_memalign(&p, sizeof(void*), 0); +- mi_free(p); +- result = (err==0); +- }); +- CHECK_BODY("posix_memalign_nopow2", { +- void* p = &p; +- int err = mi_posix_memalign(&p, 3*sizeof(void*), 32); +- result = (err==EINVAL && p==&p); +- }); +- CHECK_BODY("posix_memalign_nomem", { +- void* p = &p; +- int err = mi_posix_memalign(&p, sizeof(void*), SIZE_MAX); +- result = (err==ENOMEM && p==&p); +- }); +- +- // --------------------------------------------------- +- // Aligned API +- // --------------------------------------------------- +- CHECK_BODY("malloc-aligned1", { +- void* p = mi_malloc_aligned(32,32); result = (p != NULL && (uintptr_t)(p) % 32 == 0); mi_free(p); +- }); +- CHECK_BODY("malloc-aligned2", { +- void* p = mi_malloc_aligned(48,32); result = (p != NULL && (uintptr_t)(p) % 32 == 0); mi_free(p); +- }); +- CHECK_BODY("malloc-aligned3", { +- void* p1 = mi_malloc_aligned(48,32); bool result1 = (p1 != NULL && (uintptr_t)(p1) % 32 == 0); +- void* p2 = mi_malloc_aligned(48,32); bool result2 = (p2 != NULL && (uintptr_t)(p2) % 32 == 0); +- mi_free(p2); +- mi_free(p1); +- result = (result1&&result2); +- }); +- CHECK_BODY("malloc-aligned4", { +- void* p; +- bool ok = true; +- for (int i = 0; i < 8 && ok; i++) { +- p = mi_malloc_aligned(8, 16); +- ok = (p != NULL && (uintptr_t)(p) % 16 == 0); mi_free(p); +- } +- result = ok; +- }); +- CHECK_BODY("malloc-aligned-at1", { +- void* p = mi_malloc_aligned_at(48,32,0); result = (p != NULL && ((uintptr_t)(p) + 0) % 32 == 0); mi_free(p); +- }); +- CHECK_BODY("malloc-aligned-at2", { +- void* p = mi_malloc_aligned_at(50,32,8); result = (p != NULL && ((uintptr_t)(p) + 8) % 32 == 0); mi_free(p); +- }); +- CHECK_BODY("memalign1", { +- void* p; +- bool ok = true; +- for (int i = 0; i < 8 && ok; i++) { +- p = mi_memalign(16,8); +- ok = (p != NULL && (uintptr_t)(p) % 16 == 0); mi_free(p); +- } +- result = ok; +- }); +- +- // --------------------------------------------------- +- // Heaps +- // --------------------------------------------------- +- CHECK("heap_destroy", test_heap1()); +- CHECK("heap_delete", test_heap2()); +- +- //mi_stats_print(NULL); +- +- // --------------------------------------------------- +- // various +- // --------------------------------------------------- +- CHECK_BODY("realpath", { +- char* s = mi_realpath( ".", NULL ); +- // printf("realpath: %s\n",s); +- mi_free(s); +- }); +- +- CHECK("stl_allocator1", test_stl_allocator1()); +- CHECK("stl_allocator2", test_stl_allocator2()); +- +- // --------------------------------------------------- +- // Done +- // ---------------------------------------------------[] +- fprintf(stderr,"\n\n---------------------------------------------\n" +- "succeeded: %i\n" +- "failed : %i\n\n", ok, failed); +- return failed; ++ UK_TEST_EXPECT_PTR_EQ( ++ mi_calloc((size_t)&mi_calloc, SIZE_MAX/1000), ++ NULL ++ ); ++} ++ ++UK_TESTCASE(libmimalloc_api_testsuite, calloc0) ++{ ++ UK_TEST_EXPECT(mi_usable_size(mi_calloc(0, 1000)) <= 16); + } + + // --------------------------------------------------- +-// Larger test functions ++// Extended + // --------------------------------------------------- + +-bool test_heap1() { +- mi_heap_t* heap = mi_heap_new(); +- int* p1 = mi_heap_malloc_tp(heap,int); +- int* p2 = mi_heap_malloc_tp(heap,int); +- *p1 = *p2 = 43; +- mi_heap_destroy(heap); +- return true; ++UK_TESTCASE(libmimalloc_api_testsuite, posix_memalign1) ++{ ++ void *p = &p; ++ int err = mi_posix_memalign(&p, sizeof(void *), 32); ++ ++ UK_TEST_EXPECT( ++ (err == 0 && (uintptr_t)p % sizeof(void *) == 0) ++ || p == &p ++ ); ++ mi_free(p); + } + +-bool test_heap2() { +- mi_heap_t* heap = mi_heap_new(); +- int* p1 = mi_heap_malloc_tp(heap,int); +- int* p2 = mi_heap_malloc_tp(heap,int); +- mi_heap_delete(heap); +- *p1 = 42; +- mi_free(p1); +- mi_free(p2); +- return true; ++UK_TESTCASE(libmimalloc_api_testsuite, posix_memalign_no_align) ++{ ++ void *p = &p; ++ int err = mi_posix_memalign(&p, 3, 32); ++ ++ UK_TEST_EXPECT_SNUM_EQ(err, EINVAL); ++ UK_TEST_EXPECT_PTR_EQ(p, &p); + } + +-bool test_stl_allocator1() { +-#ifdef __cplusplus +- std::vector > vec; +- vec.push_back(1); +- vec.pop_back(); +- return vec.size() == 0; +-#else +- return true; +-#endif ++UK_TESTCASE(libmimalloc_api_testsuite, posix_memalign_zero) ++{ ++ void *p = &p; ++ int err = mi_posix_memalign(&p, sizeof(void *), 0); ++ ++ mi_free(p); ++ UK_TEST_EXPECT_SNUM_EQ(err, 0); + } + +-struct some_struct { int i; int j; double z; }; ++UK_TESTCASE(libmimalloc_api_testsuite, posix_memalign_nopow2) ++{ ++ void *p = &p; ++ int err = mi_posix_memalign(&p, 3 * sizeof(void *), 32); ++ ++ UK_TEST_EXPECT_SNUM_EQ(err, EINVAL); ++ UK_TEST_EXPECT_PTR_EQ(p, &p); ++} ++ ++UK_TESTCASE(libmimalloc_api_testsuite, posix_memalign_nomem) ++{ ++ void *p = &p; ++ int err = mi_posix_memalign(&p, sizeof(void *), SIZE_MAX); ++ ++ UK_TEST_EXPECT_SNUM_EQ(err, ENOMEM); ++ UK_TEST_EXPECT_PTR_EQ(p, &p); ++} ++ ++// --------------------------------------------------- ++// Aligned API ++// --------------------------------------------------- ++ ++UK_TESTCASE(libmimalloc_api_testsuite, malloc_aligned1) ++{ ++ void *p = mi_malloc_aligned(32, 32); ++ ++ UK_TEST_EXPECT(p != NULL); ++ UK_TEST_EXPECT((uintptr_t)(p) % 32 == 0); ++ mi_free(p); ++ ++} ++ ++UK_TESTCASE(libmimalloc_api_testsuite, malloc_aligned2) ++{ ++ void *p = mi_malloc_aligned(48, 32); ++ ++ UK_TEST_EXPECT(p != NULL); ++ UK_TEST_EXPECT((uintptr_t)(p) % 32 == 0); ++ mi_free(p); ++} ++ ++UK_TESTCASE(libmimalloc_api_testsuite, malloc_aligned3) ++{ ++ void *p1 = mi_malloc_aligned(48, 32); ++ ++ UK_TEST_EXPECT(p1 != NULL); ++ UK_TEST_EXPECT((uintptr_t)(p1) % 32 == 0); ++ ++ void *p2 = mi_malloc_aligned(48, 32); ++ ++ UK_TEST_EXPECT(p2 != NULL); ++ UK_TEST_EXPECT((uintptr_t)(p2) % 32 == 0); ++ mi_free(p2); ++ mi_free(p1); ++} ++ ++UK_TESTCASE(libmimalloc_api_testsuite, malloc_aligned4) ++{ ++ void *p; ++ bool ok = true; ++ ++ for (int i = 0; i < 8 && ok; i++) { ++ p = mi_malloc_aligned(8, 16); ++ ok = (p != NULL && (uintptr_t)(p) % 16 == 0); mi_free(p); ++ } ++ UK_TEST_EXPECT(ok); ++} ++ ++UK_TESTCASE(libmimalloc_api_testsuite, malloc_aligned_at1) ++{ ++ void *p = mi_malloc_aligned_at(48, 32, 0); ++ ++ UK_TEST_EXPECT(p != NULL); ++ UK_TEST_EXPECT(((uintptr_t)(p) + 0) % 32 == 0); ++ mi_free(p); ++} ++ ++UK_TESTCASE(libmimalloc_api_testsuite, malloc_aligned_at2) ++{ ++ void *p = mi_malloc_aligned_at(50, 32, 8); ++ ++ UK_TEST_EXPECT(p != NULL); ++ UK_TEST_EXPECT(((uintptr_t)(p) + 8) % 32 == 0); ++ mi_free(p); ++} ++ ++UK_TESTCASE(libmimalloc_api_testsuite, memalign1) ++{ ++ void *p; ++ bool ok = true; ++ ++ for (int i = 0; i < 8 && ok; i++) { ++ p = mi_memalign(16, 8); ++ ok = (p != NULL && (uintptr_t)(p) % 16 == 0); mi_free(p); ++ } ++ UK_TEST_EXPECT(ok); ++} ++ ++// --------------------------------------------------- ++// Heaps ++// --------------------------------------------------- ++UK_TESTCASE(libmimalloc_api_testsuite, heap_destroy) ++{ ++ mi_heap_t *heap = mi_heap_new(); ++ int *p1 = mi_heap_malloc_tp(heap, int); ++ int *p2 = mi_heap_malloc_tp(heap, int); ++ *p1 = *p2 = 43; ++ mi_heap_destroy(heap); ++ ++ UK_TEST_EXPECT(SHOULD_NOT_CRASH); ++} ++ ++UK_TESTCASE(libmimalloc_api_testsuite, heap_delete) ++{ ++ mi_heap_t *heap = mi_heap_new(); ++ int *p1 = mi_heap_malloc_tp(heap, int); ++ int *p2 = mi_heap_malloc_tp(heap, int); ++ ++ mi_heap_delete(heap); ++ *p1 = 42; ++ mi_free(p1); ++ mi_free(p2); ++ ++ UK_TEST_EXPECT(SHOULD_NOT_CRASH); ++} ++ ++// --------------------------------------------------- ++// various ++// --------------------------------------------------- ++UK_TESTCASE(libmimalloc_api_testsuite, realpath) ++{ ++ void *s = &s; ++ ++ s = (char *)mi_realpath(".", NULL); ++ UK_TEST_EXPECT(s != &s); ++ mi_free(s); ++ UK_TEST_EXPECT(SHOULD_NOT_CRASH); ++ ++} + +-bool test_stl_allocator2() { + #ifdef __cplusplus +- std::vector > vec; +- vec.push_back(some_struct()); +- vec.pop_back(); +- return vec.size() == 0; +-#else +- return true; ++UK_TESTCASE(libmimalloc_api_testsuite, stl_allocator1) ++{ ++ std::vector> vec; ++ vec.push_back(1); ++ vec.pop_back(); ++ UK_TEST_EXPECT_ZERO(vec.size()); ++} + #endif ++ ++#ifdef __cplusplus ++struct some_struct { int i; int j; double z; }; ++ ++UK_TESTCASE(libmimalloc_api_testsuite, stl_allocator2) ++{ ++ std::vector> vec; ++ vec.push_back(some_struct()); ++ vec.pop_back(); ++ UK_TEST_EXPECT_ZERO(vec.size()); + } ++#endif ++ ++#if defined(CONFIG_LIBMIMALLOC_TEST_API) ++uk_testsuite_register(libmimalloc_api_testsuite, NULL); ++#endif +-- +2.25.1 +