tests: Add lib/malloc-test test case

Signed-off-by: Jakub Czapiga <jacz@semihalf.com>
Change-Id: Ic6b10ec382cc807772689e852bad300c75da1fe2
Reviewed-on: https://review.coreboot.org/c/coreboot/+/50715
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Paul Fagerburg <pfagerburg@chromium.org>
This commit is contained in:
Jakub Czapiga 2021-02-15 09:54:03 +01:00 committed by Patrick Georgi
parent e8118acfbe
commit 7a18721cc7
2 changed files with 150 additions and 0 deletions

View File

@ -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

146
tests/lib/malloc-test.c Normal file
View File

@ -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 <stdlib.h>
#include <tests/test.h>
#include <commonlib/helpers.h>
#include <types.h>
#include <symbols.h>
/* 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);
}