From 7a18721cc75ee52cac6f96eec2d359bae72a51e1 Mon Sep 17 00:00:00 2001 From: Jakub Czapiga Date: Mon, 15 Feb 2021 09:54:03 +0100 Subject: tests: Add lib/malloc-test test case Signed-off-by: Jakub Czapiga Change-Id: Ic6b10ec382cc807772689e852bad300c75da1fe2 Reviewed-on: https://review.coreboot.org/c/coreboot/+/50715 Tested-by: build bot (Jenkins) Reviewed-by: Paul Fagerburg --- tests/lib/Makefile.inc | 4 ++ tests/lib/malloc-test.c | 146 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 150 insertions(+) create mode 100644 tests/lib/malloc-test.c (limited to 'tests') diff --git a/tests/lib/Makefile.inc b/tests/lib/Makefile.inc index 1640ce0f88..d31608c3d0 100644 --- a/tests/lib/Makefile.inc +++ b/tests/lib/Makefile.inc @@ -18,6 +18,7 @@ tests-y += memset-test tests-y += memcmp-test tests-y += memchr-test tests-y += memcpy-test +tests-y += malloc-test string-test-srcs += tests/lib/string-test.c string-test-srcs += src/lib/string.c @@ -91,3 +92,6 @@ memchr-test-srcs += src/lib/memchr.c memcpy-test-srcs += tests/lib/memcpy-test.c +malloc-test-srcs += tests/lib/malloc-test.c +malloc-test-srcs += tests/stubs/console.c + diff --git a/tests/lib/malloc-test.c b/tests/lib/malloc-test.c new file mode 100644 index 0000000000..e358fffd3b --- /dev/null +++ b/tests/lib/malloc-test.c @@ -0,0 +1,146 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +/* Include malloc() and memalign() source code and alter its name to indicate the functions + source origin. */ +#define malloc cb_malloc +#define free cb_free +#define memalign cb_memalign +#undef __noreturn +#define __noreturn + +#include "../lib/malloc.c" + +#undef malloc +#undef free +#undef memalign +#undef __noreturn +#define __noreturn __attribute__((noreturn)) + +#include +#include +#include +#include +#include + +/* 4 MiB */ +#define TEST_HEAP_SZ 0x400000 + +/* Heap region setup */ +__weak extern uint8_t _test_heap[]; +__weak extern uint8_t _etest_heap[]; +TEST_REGION(test_heap, TEST_HEAP_SZ); +TEST_SYMBOL(_heap, _test_heap); +TEST_SYMBOL(_eheap, _etest_heap); + +void die(const char *msg, ...) +{ + function_called(); +} + +static int setup_test(void **state) +{ + free_mem_ptr = &_heap; + free_mem_end_ptr = &_eheap; + free_last_alloc_ptr = &_heap; + + return 0; +} + +static void test_malloc_out_of_memory(void **state) +{ + /* Expect die() call if out of memory */ + expect_function_call(die); + cb_malloc(TEST_HEAP_SZ); +} + +static void test_malloc_zero(void **state) +{ + void *ptr1 = cb_malloc(0); + void *ptr2 = cb_malloc(0); + void *ptr3 = cb_malloc(0); + + /* Expect malloc(0) to return the same pointer as there are no bytes + to be added to the heap */ + assert_ptr_equal(ptr1, ptr2); + assert_ptr_equal(ptr2, ptr3); +} + +static void test_malloc_multiple_small_allocations(void **state) +{ + /* Make multiple small allocations (smaller than alignment) + Expect no call to die(), as this allocations should be small + enough to fit in provided memory */ + void *prev; + void *curr = cb_malloc(3); + assert_non_null(curr); + for (int i = 0; i < 1000; ++i) { + prev = curr; + curr = cb_malloc(3); + assert_non_null(curr); + assert_true(prev < curr); + } +} + +static void test_memalign_different_alignments(void **state) +{ + void *ptr1 = cb_memalign(4, 30); + void *ptr2 = cb_memalign(16, 22); + void *ptr3 = cb_memalign(8, 64); + + assert_true((uintptr_t)ptr1 % 4 == 0); + assert_true((uintptr_t)ptr2 % 16 == 0); + assert_true((uintptr_t)ptr3 % 8 == 0); +} + +static void test_memalign_out_of_memory(void **state) +{ + expect_function_call(die); + cb_memalign(16, TEST_HEAP_SZ); +} + +static void test_memalign_zero(void **state) +{ + void *ptr1 = cb_memalign(16, 0); + void *ptr2 = cb_memalign(7, 0); + void *ptr3 = cb_memalign(11, 0); + + /* Expect memalign(x, 0) to return the same pointer as there are no bytes + to be added to the heap */ + assert_ptr_equal(ptr1, ptr2); + assert_ptr_equal(ptr2, ptr3); +} + +static void test_memalign_multiple_small_allocations(void **state) +{ + /* Make multiple small allocations (smaller than alignment) + Expect no call to die(), as this allocations should be small + enough to fit in provided memory. There should also be no error + when allocating memory with different align values. */ + void *prev; + void *curr = cb_memalign(3, 3); + assert_non_null(curr); + for (int i = 0; i < 1000; ++i) { + /* Expect new pointer larger than previously allocated and aligned to provided + value. Alignment has to be power of 2 to be applied correctly. */ + prev = curr; + curr = cb_memalign(2u << (i % 6), 3); + assert_non_null(curr); + assert_true(prev < curr); + assert_true((uintptr_t)curr % (2u << (i % 6)) == 0); + } +} + +int main(void) +{ + const struct CMUnitTest tests[] = { + cmocka_unit_test_setup(test_malloc_out_of_memory, setup_test), + cmocka_unit_test_setup(test_malloc_zero, setup_test), + cmocka_unit_test_setup(test_malloc_multiple_small_allocations, setup_test), + cmocka_unit_test_setup(test_memalign_different_alignments, setup_test), + cmocka_unit_test_setup(test_memalign_out_of_memory, setup_test), + cmocka_unit_test_setup(test_memalign_zero, setup_test), + cmocka_unit_test_setup(test_memalign_multiple_small_allocations, setup_test), + }; + + return cmocka_run_group_tests(tests, NULL, NULL); +} -- cgit v1.2.3