1 /*
2 * Copyright (c) 2013, Google, Inc. All rights reserved
3 * Copyright 2016 The Fuchsia Authors
4 *
5 * Use of this source code is governed by a MIT-style
6 * license that can be found in the LICENSE file or at
7 * https://opensource.org/licenses/MIT
8 */
9 #pragma once
10 /*
11 * Macros for writing unit tests.
12 *
13 * Sample usage:
14 *
15 * A test case runs a collection of tests like this, with
16 * BEGIN_TEST_CASE and END_TEST_CASE and the beginning and end of the
17 * function and RUN_TEST to call each individual test, as follows:
18 *
19 * BEGIN_TEST_CASE(foo_tests);
20 *
21 * RUN_TEST(test_foo);
22 * RUN_TEST(test_bar);
23 * RUN_TEST(test_baz);
24 *
25 * END_TEST_CASE;
26 *
27 * This creates a static function foo_tests() and registers it with the
28 * unit test framework. foo_tests() can be executed either by a shell
29 * command or by a call to run_all_tests(), which runs all registered
30 * unit tests.
31 *
32 * A test looks like this, using the BEGIN_TEST and END_TEST macros at
33 * the beginning and end of the test and the EXPECT_* macros to
34 * validate test results, as shown:
35 *
36 * static bool test_foo(void)
37 * {
38 * BEGIN_TEST;
39 *
40 * ...declare variables and do stuff...
41 * int foo_value = foo_func();
42 * ...See if the stuff produced the correct value...
43 * EXPECT_EQ(1, foo_value, "foo_func failed");
44 * ... there are EXPECT_* macros for many conditions...
45 * EXPECT_TRUE(foo_condition(), "condition should be true");
46 * EXPECT_NEQ(ERR_TIMED_OUT, foo_event(), "event timed out");
47 *
48 * END_TEST;
49 * }
50 *
51 * To your rules.mk file, add lib/unittest to MODULE_DEPS:
52 *
53 * MODULE_DEPS += \
54 * lib/unittest \
55 */
56 #include <lk/compiler.h>
57 #include <printf.h>
58 #include <stdbool.h>
59 #include <stdio.h>
60 #include <stddef.h>
61 #include <stdint.h>
62 #include <string.h>
63 #include <stdarg.h>
64
65 __BEGIN_CDECLS
66
67 /*
68 * Printf dedicated to the unittest library
69 * the default output is the printf
70 */
71 void unittest_printf (const char *format, ...) __PRINTFLIKE(1, 2);
72
73 /*
74 * Function to set the callback for printing
75 * the unit test output
76 */
77 void unittest_set_output_function (_printf_engine_output_func fun, void *arg);
78
79 __END_CDECLS
80
81 /*
82 * Macros to format the error string
83 */
84 #define EXPECTED_STRING "%s\n expected "
85 #define UNITTEST_FAIL_TRACEF_FORMAT "\n [FAILED]\n %s:%d: "
86 #define UNITTEST_FAIL_TRACEF(str, x...) \
87 do { \
88 unittest_printf(UNITTEST_FAIL_TRACEF_FORMAT str, __PRETTY_FUNCTION__, __LINE__, ##x); \
89 } while (0)
90
91 /*
92 * BEGIN_TEST_CASE and END_TEST_CASE define a function that calls
93 * RUN_TEST.
94 */
95 #define BEGIN_TEST_CASE(case_name) \
96 bool case_name(void); \
97 bool case_name(void) \
98 { \
99 bool all_ok = true; \
100 unittest_printf("\nCASE %-49s [STARTED] \n", #case_name);
101
102 #define DEFINE_REGISTER_TEST_CASE(case_name) \
103 static void _register_##case_name(void) \
104 { \
105 unittest_register_test_case(&_##case_name##_element); \
106 } \
107 void (*_register_##case_name##_ptr)(void) __SECTION(".ctors") = \
108 _register_##case_name;
109
110 #define END_TEST_CASE(case_name) \
111 if (all_ok) { \
112 unittest_printf("CASE %-59s [PASSED]\n", #case_name); \
113 } else { \
114 unittest_printf("CASE %-59s [FAILED]\n", #case_name); \
115 } \
116 return all_ok; \
117 } \
118 static struct test_case_element _##case_name##_element = { \
119 .next = NULL, \
120 .failed_next = NULL, \
121 .name = #case_name, \
122 .test_case = case_name, \
123 }; \
124 DEFINE_REGISTER_TEST_CASE(case_name);
125
126 #define RUN_TEST(test) \
127 unittest_printf(" %-50s [RUNNING]", #test ); \
128 if (! test ()) { \
129 all_ok = false; \
130 } else { \
131 unittest_printf(" [PASSED] \n"); \
132 }
133
134 #define RUN_NAMED_TEST(name, test) \
135 unittest_printf(" %-50s [RUNNING]", name ); \
136 if (! test ()) { \
137 all_ok = false; \
138 } else { \
139 unittest_printf(" [PASSED] \n"); \
140 }
141
142
143 /*
144 * BEGIN_TEST and END_TEST go in a function that is called by RUN_TEST
145 * and that call the EXPECT_ macros.
146 */
147 #define BEGIN_TEST bool all_ok = true
148 #define END_TEST return all_ok
149
150 #ifdef __cplusplus
151 #define AUTO_TYPE_VAR(type) auto&
152 #else
153 #define AUTO_TYPE_VAR(type) __typeof__(type)
154 #endif
155
156 // The following helper function makes the "msg" argument optional in
157 // C++, so that you can write either of the following:
158 // ASSERT_EQ(x, y, "Check that x equals y");
159 // ASSERT_EQ(x, y);
160 // (We could allow the latter in C by making unittest_get_msg() a
161 // var-args function, but that would be less type safe.)
unittest_get_msg(const char * arg)162 static inline const char* unittest_get_msg(const char* arg) {
163 return arg;
164 }
165 #ifdef __cplusplus
unittest_get_msg()166 static inline constexpr const char* unittest_get_msg() {
167 return "<no message>";
168 }
169 #endif
170
171 /*
172 * UTCHECK_* macros are used to check test results. Generally, one should
173 * prefer to use either the EXPECT_* (non-terminating) or ASSERT_*
174 * (terminating) forms of the macros. See below.
175 *
176 * The parameter after |term| is an optional message (const char*) to be printed
177 * if the check fails.
178 */
179 #define UTCHECK_EQ(expected, actual, term, ...) \
180 { \
181 const AUTO_TYPE_VAR(actual) _e = expected; \
182 const AUTO_TYPE_VAR(actual) _a = actual; \
183 if (_e != _a) { \
184 UNITTEST_FAIL_TRACEF (EXPECTED_STRING "%s (%ld), " \
185 "actual %s (%ld)\n", \
186 unittest_get_msg(__VA_ARGS__), #expected, (long)_e, #actual, (long)_a); \
187 if (term) { \
188 return false; \
189 } \
190 all_ok = false; \
191 } \
192 }
193
194 #define UTCHECK_NE(expected, actual, term, ...) \
195 { \
196 const AUTO_TYPE_VAR(expected) _e = expected; \
197 const AUTO_TYPE_VAR(actual) _a = actual; \
198 if (_e == _a) { \
199 UNITTEST_FAIL_TRACEF(EXPECTED_STRING "%s (%ld), %s" \
200 " to differ, but they are the same\n", \
201 unittest_get_msg(__VA_ARGS__), #expected, (long)_e, #actual); \
202 if (term) { \
203 return false; \
204 } \
205 all_ok = false; \
206 } \
207 }
208
209 #define UTCHECK_LE(expected, actual, term, ...) \
210 { \
211 const AUTO_TYPE_VAR(actual) _e = expected; \
212 const AUTO_TYPE_VAR(actual) _a = actual; \
213 if (_e > _a) { \
214 UNITTEST_FAIL_TRACEF(EXPECTED_STRING "%s (%ld) to be" \
215 " less-than-or-equal-to actual %s (%ld)\n", \
216 unittest_get_msg(__VA_ARGS__), #expected, (long)_e, #actual, (long)_a); \
217 if (term) { \
218 return false; \
219 } \
220 all_ok = false; \
221 } \
222 }
223
224 #define UTCHECK_LT(expected, actual, term, ...) \
225 { \
226 const AUTO_TYPE_VAR(actual) _e = expected; \
227 const AUTO_TYPE_VAR(actual) _a = actual; \
228 if (_e >= _a) { \
229 UNITTEST_FAIL_TRACEF(EXPECTED_STRING "%s (%ld) to be" \
230 " less-than actual %s (%ld)\n", \
231 unittest_get_msg(__VA_ARGS__), #expected, (long)_e, #actual, (long)_a); \
232 if (term) { \
233 return false; \
234 } \
235 all_ok = false; \
236 } \
237 }
238
239 #define UTCHECK_GE(expected, actual, term, ...) \
240 { \
241 const AUTO_TYPE_VAR(actual) _e = expected; \
242 const AUTO_TYPE_VAR(actual) _a = actual; \
243 if (_e < _a) { \
244 UNITTEST_FAIL_TRACEF(EXPECTED_STRING "%s (%ld) to be" \
245 " greater-than-or-equal-to actual %s (%ld)\n", \
246 unittest_get_msg(__VA_ARGS__), #expected, (long)_e, #actual, (long)_a); \
247 if (term) { \
248 return false; \
249 } \
250 all_ok = false; \
251 } \
252 }
253
254 #define UTCHECK_GT(expected, actual, term, ...) \
255 { \
256 const AUTO_TYPE_VAR(actual) _e = expected; \
257 const AUTO_TYPE_VAR(actual) _a = actual; \
258 if (_e <= _a) { \
259 UNITTEST_FAIL_TRACEF(EXPECTED_STRING "%s (%ld) to be" \
260 " greater-than actual %s (%ld)\n", \
261 unittest_get_msg(__VA_ARGS__), #expected, (long)_e, #actual, (long)_a); \
262 if (term) { \
263 return false; \
264 } \
265 all_ok = false; \
266 } \
267 }
268
269 #define UTCHECK_TRUE(actual, term, ...) \
270 if (!(actual)) { \
271 UNITTEST_FAIL_TRACEF("%s: %s is false\n", unittest_get_msg(__VA_ARGS__), #actual); \
272 if (term) { \
273 return false; \
274 } \
275 all_ok = false; \
276 }
277
278 #define UTCHECK_FALSE(actual, term, ...) \
279 if (actual) { \
280 UNITTEST_FAIL_TRACEF("%s: %s is true\n", unittest_get_msg(__VA_ARGS__), #actual); \
281 if (term) { \
282 return false; \
283 } \
284 all_ok = false; \
285 }
286
287 #define UTCHECK_NULL(actual, term, ...) \
288 if (actual != NULL) { \
289 UNITTEST_FAIL_TRACEF("%s: %s is non-null\n", unittest_get_msg(__VA_ARGS__), #actual); \
290 if (term) { \
291 return false; \
292 } \
293 all_ok = false; \
294 }
295
296 #define UTCHECK_NONNULL(actual, term, ...) \
297 if (actual == NULL) { \
298 UNITTEST_FAIL_TRACEF("%s: %s is null\n", unittest_get_msg(__VA_ARGS__), #actual); \
299 if (term) { \
300 return false; \
301 } \
302 all_ok = false; \
303 }
304
305
306 #define UTCHECK_BYTES_EQ(expected, actual, length, term, ...) \
307 if (!expect_bytes_eq(expected, actual, length, unittest_get_msg(__VA_ARGS__))) { \
308 if (term) { \
309 return false; \
310 } \
311 all_ok = false; \
312 }
313
314 #define UTCHECK_BYTES_NE(bytes1, bytes2, length, term, ...) \
315 if (!memcmp(bytes1, bytes2, length)) { \
316 UNITTEST_FAIL_TRACEF("%s and %s are the same; " \
317 "expected different\n", #bytes1, #bytes2); \
318 hexdump8(bytes1, length); \
319 if (term) { \
320 return false; \
321 } \
322 all_ok = false; \
323 }
324
325 /* For comparing uint64_t, like hw_id_t. */
326 #define UTCHECK_EQ_LL(expected, actual, term, ...) \
327 { \
328 const AUTO_TYPE_VAR(actual) _e = expected; \
329 const AUTO_TYPE_VAR(actual) _a = actual; \
330 if (_e != _a) { \
331 UNITTEST_FAIL_TRACEF("%s: expected %llu, actual %llu\n", \
332 unittest_get_msg(__VA_ARGS__), _e, _a); \
333 if (term) { \
334 return false; \
335 } \
336 all_ok = false; \
337 } \
338 }
339
340 /* EXPECT_* macros check the supplied condition and will print a diagnostic
341 * message and flag the test as having failed if the condition fails. The test
342 * will continue to run, even if the condition fails.
343 *
344 * The last parameter is an optional const char* message to be included in the
345 * print diagnostic message.
346 */
347 #define EXPECT_EQ(expected, actual, ...) UTCHECK_EQ(expected, actual, false, __VA_ARGS__)
348 #define EXPECT_NE(expected, actual, ...) UTCHECK_NE(expected, actual, false, __VA_ARGS__)
349 #define EXPECT_LE(expected, actual, ...) UTCHECK_LE(expected, actual, false, __VA_ARGS__)
350 #define EXPECT_LT(expected, actual, ...) UTCHECK_LT(expected, actual, false, __VA_ARGS__)
351 #define EXPECT_GE(expected, actual, ...) UTCHECK_GE(expected, actual, false, __VA_ARGS__)
352 #define EXPECT_GT(expected, actual, ...) UTCHECK_GT(expected, actual, false, __VA_ARGS__)
353 #define EXPECT_TRUE(actual, ...) UTCHECK_TRUE(actual, false, __VA_ARGS__)
354 #define EXPECT_FALSE(actual, ...) UTCHECK_FALSE(actual, false, __VA_ARGS__)
355 #define EXPECT_BYTES_EQ(expected, actual, length, ...) \
356 UTCHECK_BYTES_EQ(expected, actual, length, false, __VA_ARGS__)
357 #define EXPECT_BYTES_NE(bytes1, bytes2, length, ...) \
358 UTCHECK_BYTES_NE(bytes1, bytes2, length, false, __VA_ARGS__)
359 #define EXPECT_EQ_LL(expected, actual, ...) UTCHECK_EQ_LL(expected, actual, false, __VA_ARGS__)
360 #define EXPECT_NULL(actual, ...) UTCHECK_NULL(actual, false, __VA_ARGS__)
361 #define EXPECT_NONNULL(actual, ...) UTCHECK_NONNULL(actual, false, __VA_ARGS__)
362 #define EXPECT_OK(actual, ...) UTCHECK_EQ(ZX_OK, actual, false, __VA_ARGS__)
363
364 /* ASSERT_* macros check the condition and will print a message and immediately
365 * abort a test with a filure status if the condition fails.
366 */
367 #define ASSERT_EQ(expected, actual, ...) UTCHECK_EQ(expected, actual, true, __VA_ARGS__)
368 #define ASSERT_NE(expected, actual, ...) UTCHECK_NE(expected, actual, true, __VA_ARGS__)
369 #define ASSERT_LE(expected, actual, ...) UTCHECK_LE(expected, actual, true, __VA_ARGS__)
370 #define ASSERT_LT(expected, actual, ...) UTCHECK_LT(expected, actual, true, __VA_ARGS__)
371 #define ASSERT_GE(expected, actual, ...) UTCHECK_GE(expected, actual, true, __VA_ARGS__)
372 #define ASSERT_GT(expected, actual, ...) UTCHECK_GT(expected, actual, true, __VA_ARGS__)
373 #define ASSERT_TRUE(actual, ...) UTCHECK_TRUE(actual, true, __VA_ARGS__)
374 #define ASSERT_FALSE(actual, ...) UTCHECK_FALSE(actual, true, __VA_ARGS__)
375 #define ASSERT_BYTES_EQ(expected, actual, length, ...) \
376 UTCHECK_BYTES_EQ(expected, actual, length, true, __VA_ARGS__)
377 #define ASSERT_BYTES_NE(bytes1, bytes2, length, ...) \
378 UTCHECK_BYTES_NE(bytes1, bytes2, length, true, __VA_ARGS__)
379 #define ASSERT_EQ_LL(expected, actual, ...) UTCHECK_EQ_LL(expected, actual, true, __VA_ARGS__)
380 #define ASSERT_NULL(actual, ...) UTCHECK_NULL(actual, true, __VA_ARGS__)
381 #define ASSERT_NONNULL(actual, ...) UTCHECK_NONNULL(actual, true, __VA_ARGS__)
382 #define ASSERT_OK(actual, ...) UTCHECK_EQ(ZX_OK, actual, true, __VA_ARGS__)
383
384 __BEGIN_CDECLS
385
386 /*
387 * The list of test cases is made up of these elements.
388 */
389 struct test_case_element {
390 struct test_case_element *next;
391 struct test_case_element *failed_next;
392 const char *name;
393 bool (*test_case)(void);
394 };
395
396
397 /*
398 * Registers a test case with the unit test framework.
399 */
400 void unittest_register_test_case(struct test_case_element *elem);
401
402 /*
403 * Runs all registered test cases.
404 */
405 bool run_all_tests(void);
406
407 /*
408 * Returns false if expected does not equal actual and prints msg and a hexdump8
409 * of the input buffers.
410 */
411 bool expect_bytes_eq(const uint8_t *expected, const uint8_t *actual, size_t len,
412 const char *msg);
413
414 __END_CDECLS
415