When running multiple tests, e.g. by using unit-tests target, it is hard to differentiate, which output comes from which file and/or configuration. This patch makes the output easier to analyze and understand by using new wrapper macro cb_run_group_tests(). This macro uses __TEST_NAME__ value (containing test path and Makefile test name) as a group name when calling cmocka group runner. Example: Test path: tests/lib/ Makefile test name: cbmem_stage_cache-test Test group array name: tests Result: tests/lib/cbmem_stage_cache-test(tests) Signed-off-by: Jakub Czapiga <jacz@semihalf.com> Change-Id: I4fd936d00d77cbe2637b857ba03b4a208428ea0d Reviewed-on: https://review.coreboot.org/c/coreboot/+/57144 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Paul Fagerburg <pfagerburg@chromium.org> Reviewed-by: Julius Werner <jwerner@chromium.org>
		
			
				
	
	
		
			169 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			169 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /* SPDX-License-Identifier: GPL-2.0-only */
 | |
| 
 | |
| /* Include malloc() and memalign() source code and alter its name to indicate the functions
 | |
|    source origin. */
 | |
| #define calloc cb_calloc
 | |
| #define malloc cb_malloc
 | |
| #define free cb_free
 | |
| #define memalign cb_memalign
 | |
| #undef __noreturn
 | |
| #define __noreturn
 | |
| 
 | |
| #include "../lib/malloc.c"
 | |
| 
 | |
| #undef calloc
 | |
| #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 int setup_calloc_test(void **state)
 | |
| {
 | |
| 	memset(_test_heap, 0xFF, TEST_HEAP_SZ);
 | |
| 	return setup_test(state);
 | |
| }
 | |
| 
 | |
| 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);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| static void test_calloc_memory_is_zeroed(void **state)
 | |
| {
 | |
| 	const size_t nitems = 42;
 | |
| 	const size_t size = sizeof(uint32_t);
 | |
| 	void *ptr = cb_calloc(nitems, size);
 | |
| 	assert_non_null(ptr);
 | |
| 
 | |
| 	for (size_t i = 0; i < nitems; i++) {
 | |
| 		const uint32_t *p = (const uint32_t *)ptr + i;
 | |
| 		assert_int_equal(*p, 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),
 | |
| 		cmocka_unit_test_setup(test_calloc_memory_is_zeroed, setup_calloc_test),
 | |
| 	};
 | |
| 
 | |
| 	return cb_run_group_tests(tests, NULL, NULL);
 | |
| }
 |