summaryrefslogtreecommitdiff
path: root/tests/lib
diff options
context:
space:
mode:
authorJakub Czapiga <jacz@semihalf.com>2021-02-15 09:54:03 +0100
committerPatrick Georgi <pgeorgi@google.com>2021-02-26 07:29:57 +0000
commit7a18721cc75ee52cac6f96eec2d359bae72a51e1 (patch)
tree9ca94039e0c8d9daccf6be1c856ff54d801bd607 /tests/lib
parente8118acfbee788f1c45319970a6a10dfc8f30491 (diff)
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>
Diffstat (limited to 'tests/lib')
-rw-r--r--tests/lib/Makefile.inc4
-rw-r--r--tests/lib/malloc-test.c146
2 files changed, 150 insertions, 0 deletions
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 <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);
+}