Patrick Georgi submitted this change.

View Change

Approvals: build bot (Jenkins): Verified Paul Fagerburg: Looks good to me, approved
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>
---
M tests/lib/Makefile.inc
A tests/lib/malloc-test.c
2 files changed, 150 insertions(+), 0 deletions(-)

diff --git a/tests/lib/Makefile.inc b/tests/lib/Makefile.inc
index 1640ce0..d31608c 100644
--- a/tests/lib/Makefile.inc
+++ b/tests/lib/Makefile.inc
@@ -18,6 +18,7 @@
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 @@

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 0000000..e358fff
--- /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);
+}

To view, visit change 50715. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Change-Id: Ic6b10ec382cc807772689e852bad300c75da1fe2
Gerrit-Change-Number: 50715
Gerrit-PatchSet: 5
Gerrit-Owner: jacz@semihalf.com
Gerrit-Reviewer: Jan Dabros <jsd@semihalf.com>
Gerrit-Reviewer: Julius Werner <jwerner@chromium.org>
Gerrit-Reviewer: Martin Roth <martinroth@google.com>
Gerrit-Reviewer: Patrick Georgi <pgeorgi@google.com>
Gerrit-Reviewer: Paul Fagerburg <pfagerburg@chromium.org>
Gerrit-Reviewer: build bot (Jenkins) <no-reply@coreboot.org>
Gerrit-CC: Paul Menzel <paulepanter@users.sourceforge.net>
Gerrit-MessageType: merged