forked from Mirrors/opensbi
		
	lib: Add SBIUnit testing macros and functions
This patch introduces all of the SBIUnit macros and functions which can be used during the test development process. Also, it defines the 'run_all_tests' function, which is being called during the 'init_coldboot' right after printing the boot hart information. Also, add the CONFIG_SBIUNIT Kconfig entry in order to be able to turn the tests on and off. When the CONFIG_SBIUNIT is disabled, the tests and all related code is excluded completely on the compilation stage. Signed-off-by: Ivan Orlov <ivan.orlov0322@gmail.com> Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
This commit is contained in:
		
							
								
								
									
										71
									
								
								include/sbi/sbi_unit_test.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								include/sbi/sbi_unit_test.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,71 @@
 | 
			
		||||
/*
 | 
			
		||||
 * SPDX-License-Identifier: BSD-2-Clause
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Ivan Orlov <ivan.orlov0322@gmail.com>
 | 
			
		||||
 */
 | 
			
		||||
#ifdef CONFIG_SBIUNIT
 | 
			
		||||
#ifndef __SBI_UNIT_H__
 | 
			
		||||
#define __SBI_UNIT_H__
 | 
			
		||||
 | 
			
		||||
#include <sbi/sbi_types.h>
 | 
			
		||||
#include <sbi/sbi_console.h>
 | 
			
		||||
#include <sbi/sbi_string.h>
 | 
			
		||||
 | 
			
		||||
struct sbiunit_test_case {
 | 
			
		||||
	const char *name;
 | 
			
		||||
	bool failed;
 | 
			
		||||
	void (*test_func)(struct sbiunit_test_case *test);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct sbiunit_test_suite {
 | 
			
		||||
	const char *name;
 | 
			
		||||
	struct sbiunit_test_case *cases;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define SBIUNIT_TEST_CASE(func)		\
 | 
			
		||||
	{				\
 | 
			
		||||
		.name = #func,		\
 | 
			
		||||
		.failed = false,	\
 | 
			
		||||
		.test_func = (func)	\
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
#define SBIUNIT_END_CASE { }
 | 
			
		||||
 | 
			
		||||
#define SBIUNIT_TEST_SUITE(suite_name, cases_arr)		\
 | 
			
		||||
	struct sbiunit_test_suite suite_name = {		\
 | 
			
		||||
		.name = #suite_name,				\
 | 
			
		||||
		.cases = cases_arr				\
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
#define _sbiunit_msg(test, msg) "[SBIUnit] [%s:%d]: %s: %s", __FILE__,	\
 | 
			
		||||
				__LINE__, test->name, msg
 | 
			
		||||
 | 
			
		||||
#define SBIUNIT_INFO(test, msg) sbi_printf(_sbiunit_msg(test, msg))
 | 
			
		||||
#define SBIUNIT_PANIC(test, msg) sbi_panic(_sbiunit_msg(test, msg))
 | 
			
		||||
 | 
			
		||||
#define SBIUNIT_EXPECT(test, cond) do {							\
 | 
			
		||||
	if (!(cond)) {									\
 | 
			
		||||
		test->failed = true;							\
 | 
			
		||||
		SBIUNIT_INFO(test, "Condition \"" #cond "\" expected to be true!\n");	\
 | 
			
		||||
	}										\
 | 
			
		||||
} while (0)
 | 
			
		||||
 | 
			
		||||
#define SBIUNIT_ASSERT(test, cond) do {						\
 | 
			
		||||
	if (!(cond))								\
 | 
			
		||||
		SBIUNIT_PANIC(test, "Condition \"" #cond "\" must be true!\n");	\
 | 
			
		||||
} while (0)
 | 
			
		||||
 | 
			
		||||
#define SBIUNIT_EXPECT_EQ(test, a, b) SBIUNIT_EXPECT(test, (a) == (b))
 | 
			
		||||
#define SBIUNIT_ASSERT_EQ(test, a, b) SBIUNIT_ASSERT(test, (a) == (b))
 | 
			
		||||
#define SBIUNIT_EXPECT_NE(test, a, b) SBIUNIT_EXPECT(test, (a) != (b))
 | 
			
		||||
#define SBIUNIT_ASSERT_NE(test, a, b) SBIUNIT_ASSERT(test, (a) != (b))
 | 
			
		||||
#define SBIUNIT_EXPECT_MEMEQ(test, a, b, len) SBIUNIT_EXPECT(test, !sbi_memcmp(a, b, len))
 | 
			
		||||
#define SBIUNIT_ASSERT_MEMEQ(test, a, b, len) SBIUNIT_ASSERT(test, !sbi_memcmp(a, b, len))
 | 
			
		||||
#define SBIUNIT_EXPECT_STREQ(test, a, b, len) SBIUNIT_EXPECT(test, !sbi_strncmp(a, b, len))
 | 
			
		||||
#define SBIUNIT_ASSERT_STREQ(test, a, b, len) SBIUNIT_ASSERT(test, !sbi_strncmp(a, b, len))
 | 
			
		||||
 | 
			
		||||
void run_all_tests(void);
 | 
			
		||||
#endif
 | 
			
		||||
#else
 | 
			
		||||
#define run_all_tests()
 | 
			
		||||
#endif
 | 
			
		||||
@@ -50,4 +50,8 @@ config SBI_ECALL_DBTR
 | 
			
		||||
	bool "Debug Trigger Extension"
 | 
			
		||||
	default y
 | 
			
		||||
 | 
			
		||||
config SBIUNIT
 | 
			
		||||
	bool "Enable SBIUNIT tests"
 | 
			
		||||
	default n
 | 
			
		||||
 | 
			
		||||
endmenu
 | 
			
		||||
 
 | 
			
		||||
@@ -11,6 +11,8 @@ libsbi-objs-y += riscv_asm.o
 | 
			
		||||
libsbi-objs-y += riscv_atomic.o
 | 
			
		||||
libsbi-objs-y += riscv_hardfp.o
 | 
			
		||||
libsbi-objs-y += riscv_locks.o
 | 
			
		||||
libsbi-objs-$(CONFIG_SBIUNIT) += sbi_unit_test.o
 | 
			
		||||
libsbi-objs-$(CONFIG_SBIUNIT) += sbi_unit_tests.o
 | 
			
		||||
 | 
			
		||||
libsbi-objs-y += sbi_ecall.o
 | 
			
		||||
libsbi-objs-y += sbi_ecall_exts.o
 | 
			
		||||
 
 | 
			
		||||
@@ -29,6 +29,7 @@
 | 
			
		||||
#include <sbi/sbi_timer.h>
 | 
			
		||||
#include <sbi/sbi_tlb.h>
 | 
			
		||||
#include <sbi/sbi_version.h>
 | 
			
		||||
#include <sbi/sbi_unit_test.h>
 | 
			
		||||
 | 
			
		||||
#define BANNER                                              \
 | 
			
		||||
	"   ____                    _____ ____ _____\n"     \
 | 
			
		||||
@@ -398,6 +399,8 @@ static void __noreturn init_coldboot(struct sbi_scratch *scratch, u32 hartid)
 | 
			
		||||
 | 
			
		||||
	sbi_boot_print_hart(scratch, hartid);
 | 
			
		||||
 | 
			
		||||
	run_all_tests();
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * Configure PMP at last because if SMEPMP is detected,
 | 
			
		||||
	 * M-mode access to the S/U space will be rescinded.
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										43
									
								
								lib/sbi/sbi_unit_test.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								lib/sbi/sbi_unit_test.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,43 @@
 | 
			
		||||
/*
 | 
			
		||||
 * SPDX-License-Identifier: BSD-2-Clause
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Ivan Orlov <ivan.orlov0322@gmail.com>
 | 
			
		||||
 */
 | 
			
		||||
#include <sbi/sbi_unit_test.h>
 | 
			
		||||
#include <sbi/sbi_types.h>
 | 
			
		||||
#include <sbi/sbi_console.h>
 | 
			
		||||
 | 
			
		||||
extern struct sbiunit_test_suite *sbi_unit_tests[];
 | 
			
		||||
extern unsigned long sbi_unit_tests_size;
 | 
			
		||||
 | 
			
		||||
static void run_test_suite(struct sbiunit_test_suite *suite)
 | 
			
		||||
{
 | 
			
		||||
	struct sbiunit_test_case *s_case;
 | 
			
		||||
	u32 count_pass = 0, count_fail = 0;
 | 
			
		||||
 | 
			
		||||
	sbi_printf("## Running test suite: %s\n", suite->name);
 | 
			
		||||
 | 
			
		||||
	s_case = suite->cases;
 | 
			
		||||
	while (s_case->test_func) {
 | 
			
		||||
		s_case->test_func(s_case);
 | 
			
		||||
		if (s_case->failed)
 | 
			
		||||
			count_fail++;
 | 
			
		||||
		else
 | 
			
		||||
			count_pass++;
 | 
			
		||||
		sbi_printf("[%s] %s\n", s_case->failed ? "FAILED" : "PASSED",
 | 
			
		||||
			   s_case->name);
 | 
			
		||||
		s_case++;
 | 
			
		||||
	}
 | 
			
		||||
	sbi_printf("%u PASSED / %u FAILED / %u TOTAL\n", count_pass, count_fail,
 | 
			
		||||
		   count_pass + count_fail);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void run_all_tests(void)
 | 
			
		||||
{
 | 
			
		||||
	u32 i;
 | 
			
		||||
 | 
			
		||||
	sbi_printf("\n# Running SBIUNIT tests #\n");
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < sbi_unit_tests_size; i++)
 | 
			
		||||
		run_test_suite(sbi_unit_tests[i]);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										3
									
								
								lib/sbi/sbi_unit_tests.carray
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								lib/sbi/sbi_unit_tests.carray
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
			
		||||
HEADER: sbi/sbi_unit_test.h
 | 
			
		||||
TYPE: struct sbiunit_test_suite
 | 
			
		||||
NAME: sbi_unit_tests
 | 
			
		||||
		Reference in New Issue
	
	Block a user