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:
parent
e8118acfbe
commit
7a18721cc7
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
Loading…
Reference in New Issue