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