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:
		
				
					committed by
					
						
						Patrick Georgi
					
				
			
			
				
	
			
			
			
						parent
						
							e8118acfbe
						
					
				
				
					commit
					7a18721cc7
				
			@@ -18,6 +18,7 @@ tests-y += memset-test
 | 
				
			|||||||
tests-y += memcmp-test
 | 
					tests-y += memcmp-test
 | 
				
			||||||
tests-y += memchr-test
 | 
					tests-y += memchr-test
 | 
				
			||||||
tests-y += memcpy-test
 | 
					tests-y += memcpy-test
 | 
				
			||||||
 | 
					tests-y += malloc-test
 | 
				
			||||||
 | 
					
 | 
				
			||||||
string-test-srcs += tests/lib/string-test.c
 | 
					string-test-srcs += tests/lib/string-test.c
 | 
				
			||||||
string-test-srcs += src/lib/string.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
 | 
					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
									
								
							
							
						
						
									
										146
									
								
								tests/lib/malloc-test.c
									
									
									
									
									
										Normal 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);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user