• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * Copyright (c) 2021 Google LLC
4  */
5 
6 #ifndef _TEST_FRAMEWORK_H
7 #define _TEST_FRAMEWORK_H
8 
9 #include <stdbool.h>
10 #include <stdio.h>
11 #include <linux/compiler.h>
12 
13 #ifdef __ANDROID__
14 static int test_case_pass;
15 static int test_case_fail;
16 #define ksft_print_msg			printf
17 #define ksft_test_result_pass(...)	({test_case_pass++; printf(__VA_ARGS__); })
18 #define ksft_test_result_fail(...)	({test_case_fail++; printf(__VA_ARGS__); })
19 #define ksft_exit_fail_msg(...)		printf(__VA_ARGS__)
20 #define ksft_print_header()
21 #define ksft_set_plan(cnt)
22 #define ksft_get_fail_cnt()		test_case_fail
23 #define ksft_exit_pass()		0
24 #define ksft_exit_fail()		1
25 #else
26 #include <kselftest.h>
27 #endif
28 
29 #define TEST_FAILURE 1
30 #define TEST_SUCCESS 0
31 
32 #define ptr_to_u64(p) ((__u64)p)
33 
34 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
35 #define le16_to_cpu(x)          (x)
36 #define le32_to_cpu(x)          (x)
37 #define le64_to_cpu(x)          (x)
38 #else
39 #error Big endian not supported!
40 #endif
41 
42 struct _test_options {
43 	int file;
44 	bool verbose;
45 };
46 
47 extern struct _test_options test_options;
48 
49 #define TESTCOND(condition)						\
50 	do {								\
51 		if (!(condition)) {					\
52 			ksft_print_msg("%s failed %d\n",		\
53 				       __func__, __LINE__);		\
54 			goto out;					\
55 		} else if (test_options.verbose)			\
56 			ksft_print_msg("%s succeeded %d\n",		\
57 				       __func__, __LINE__);		\
58 	} while (false)
59 
60 #define TESTCONDERR(condition)						\
61 	do {								\
62 		if (!(condition)) {					\
63 			ksft_print_msg("%s failed %d\n",		\
64 				       __func__, __LINE__);		\
65 			ksft_print_msg("Error %d (\"%s\")\n",		\
66 				       errno, strerror(errno));		\
67 			goto out;					\
68 		} else if (test_options.verbose)			\
69 			ksft_print_msg("%s succeeded %d\n",		\
70 				       __func__, __LINE__);		\
71 	} while (false)
72 
73 #define TEST(statement, condition)					\
74 	do {								\
75 		statement;						\
76 		TESTCOND(condition);					\
77 	} while (false)
78 
79 #define TESTERR(statement, condition)					\
80 	do {								\
81 		statement;						\
82 		TESTCONDERR(condition);					\
83 	} while (false)
84 
85 enum _operator {
86 	_eq,
87 	_ne,
88 	_ge,
89 };
90 
91 static const char * const _operator_name[] = {
92 	"==",
93 	"!=",
94 	">=",
95 };
96 
97 #define _TEST_OPERATOR(name, _type, format_specifier)			\
98 static inline int _test_operator_##name(const char *func, int line,	\
99 				_type a, _type b, enum _operator o)	\
100 {									\
101 	bool pass;							\
102 	switch (o) {							\
103 	case _eq:							\
104 		pass = a == b;						\
105 		break;							\
106 	case _ne:							\
107 		pass = a != b;						\
108 		break;							\
109 	case _ge:							\
110 		pass = a >= b;						\
111 		break;							\
112 	}								\
113 									\
114 	if (!pass)							\
115 		ksft_print_msg("Failed: %s at line %d, "		\
116 			       format_specifier " %s "			\
117 			       format_specifier	"\n",			\
118 			       func, line, a, _operator_name[o], b);	\
119 	else if (test_options.verbose)					\
120 		ksft_print_msg("Passed: %s at line %d, "		\
121 			       format_specifier " %s "			\
122 			       format_specifier "\n",			\
123 			       func, line, a, _operator_name[o], b);	\
124 									\
125 	return pass ? TEST_SUCCESS : TEST_FAILURE;			\
126 }
127 
128 _TEST_OPERATOR(i, int, "%d")
129 _TEST_OPERATOR(ui, unsigned int, "%u")
130 _TEST_OPERATOR(lui, unsigned long, "%lu")
131 _TEST_OPERATOR(ss, ssize_t, "%zd")
132 _TEST_OPERATOR(vp, void *, "%px")
133 _TEST_OPERATOR(cp, char *, "%px")
134 
135 #define _CALL_TO(_type, name, a, b, o)					\
136 	_test_operator_##name(__func__, __LINE__,			\
137 				  (_type) (long long) (a),		\
138 				  (_type) (long long) (b), o)
139 
140 #define TESTOPERATOR(a, b, o)						\
141 	do {								\
142 		if (_Generic((a),					\
143 			int : _CALL_TO(int, i, a, b, o),		\
144 			unsigned int : _CALL_TO(unsigned int, ui, a, b, o),	\
145 			unsigned long : _CALL_TO(unsigned long, lui, a, b, o),	\
146 			ssize_t : _CALL_TO(ssize_t, ss, a, b, o),		\
147 			void * : _CALL_TO(void *, vp, a, b, o),		\
148 			char * : _CALL_TO(char *, cp, a, b, o)		\
149 		))							\
150 			goto out;					\
151 	} while (false)
152 
153 #define TESTEQUAL(a, b) TESTOPERATOR(a, b, _eq)
154 #define TESTNE(a, b) TESTOPERATOR(a, b, _ne)
155 #define TESTGE(a, b) TESTOPERATOR(a, b, _ge)
156 
157 /* For testing a syscall that returns 0 on success and sets errno otherwise */
158 #define TESTSYSCALL(statement) TESTCONDERR((statement) == 0)
159 
print_bytes(const void * data,size_t size)160 static inline void print_bytes(const void *data, size_t size)
161 {
162 	const char *bytes = data;
163 	int i;
164 
165 	for (i = 0; i < size; ++i) {
166 		if (i % 0x10 == 0)
167 			printf("%08x:", i);
168 		printf("%02x ", (unsigned int) (unsigned char) bytes[i]);
169 		if (i % 0x10 == 0x0f)
170 			printf("\n");
171 	}
172 
173 	if (i % 0x10 != 0)
174 		printf("\n");
175 }
176 
177 
178 
179 #endif
180