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