1 // Copyright 2016 The Fuchsia Authors 2 // Copyright (c) 2013, Google, Inc. All rights reserved 3 // 4 // Use of this source code is governed by a MIT-style 5 // license that can be found in the LICENSE file or at 6 // https://opensource.org/licenses/MIT 7 8 #pragma once 9 /* 10 * Macros for writing unit tests. 11 * 12 * Sample usage: 13 * 14 * A test case runs a collection of unittests, with 15 * UNITTEST_START_TESTCASE and UNITTEST_END_TESTCASE 16 * BEGIN_TEST_CASE and END_TEST_CASE at the beginning and end of the list of 17 * unitests, and UNITTEST for each individual test, as follows: 18 * 19 * UNITTEST_START_TESTCASE(foo_tests) 20 * 21 * UNITTEST(test_foo); 22 * UNITTEST(test_bar); 23 * UNITTEST(test_baz); 24 * 25 * UNITTEST_END_TESTCASE(foo_tests, 26 * "footest", 27 * "Test to be sure that your foos have proper bars"); 28 * 29 * This creates an entry in the global unittest table and registers it with the 30 * unit test framework. 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() 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_NE(ZX_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 <stdarg.h> 57 #include <stdbool.h> 58 #include <stddef.h> 59 #include <stdint.h> 60 #include <stdio.h> 61 #include <string.h> 62 63 #include <zircon/compiler.h> 64 #include <zircon/types.h> 65 #include <trace.h> 66 67 __BEGIN_CDECLS 68 69 /* 70 * Printf dedicated to the unittest library 71 * the default output is the printf 72 */ 73 int unittest_printf(const char* format, ...) __PRINTFLIKE(1, 2); 74 75 /* 76 * Macros to format the error string 77 */ 78 #define EXPECTED_STRING "%s:\n expected " 79 #define UNITTEST_FAIL_TRACEF_FORMAT "\n [FAILED]\n %s:%d:\n " 80 #define UNITTEST_FAIL_TRACEF(str, x...) \ 81 do { \ 82 unittest_printf(UNITTEST_FAIL_TRACEF_FORMAT str, \ 83 __PRETTY_FUNCTION__, __LINE__, ##x); \ 84 } while (0) 85 86 /* 87 * BEGIN_TEST and END_TEST go in a function that is called by RUN_TEST 88 * and that call the EXPECT_ macros. 89 */ 90 91 #define BEGIN_TEST bool all_ok = true 92 #define END_TEST return all_ok 93 94 #ifdef __cplusplus 95 #define AUTO_TYPE_VAR(type) auto& 96 #else 97 #define AUTO_TYPE_VAR(type) __typeof__(type) 98 #endif 99 100 /* 101 * UTCHECK_* macros are used to check test results. Generally, one should 102 * prefer to use either the EXPECT_* (non-terminating) or ASSERT_* 103 * (terminating) forms of the macros. See below. 104 */ 105 #define UTCHECK_EQ(expected, actual, msg, term) \ 106 do { \ 107 const AUTO_TYPE_VAR(expected) _e = (expected); \ 108 const AUTO_TYPE_VAR(actual) _a = (actual); \ 109 if (_e != _a) { \ 110 UNITTEST_FAIL_TRACEF(EXPECTED_STRING \ 111 "%s (%ld), " \ 112 "actual %s (%ld)\n", \ 113 msg, #expected, (long)_e, #actual, (long)_a); \ 114 if (term) return false; else all_ok = false; \ 115 } \ 116 } while (0) 117 118 #define UTCHECK_NE(expected, actual, msg, term) \ 119 do { \ 120 const AUTO_TYPE_VAR(expected) _e = (expected); \ 121 const AUTO_TYPE_VAR(actual) _a = (actual); \ 122 if (_e == (_a)) { \ 123 UNITTEST_FAIL_TRACEF(EXPECTED_STRING \ 124 "%s (%ld), %s" \ 125 " to differ, but they are the same %ld\n", \ 126 msg, #expected, (long)_e, #actual, (long)_a); \ 127 if (term) return false; else all_ok = false; \ 128 } \ 129 } while (0) 130 131 #define UTCHECK_LE(expected, actual, msg, term) \ 132 do { \ 133 const AUTO_TYPE_VAR(expected) _e = (expected); \ 134 const AUTO_TYPE_VAR(actual) _a = (actual); \ 135 if (_e > _a) { \ 136 UNITTEST_FAIL_TRACEF(EXPECTED_STRING \ 137 "%s (%ld) to be" \ 138 " less-than-or-equal-to actual %s (%ld)\n", \ 139 msg, #expected, (long)_e, #actual, (long)_a); \ 140 if (term) return false; else all_ok = false; \ 141 } \ 142 } while (0) 143 144 #define UTCHECK_LT(expected, actual, msg, term) \ 145 do { \ 146 const AUTO_TYPE_VAR(expected) _e = (expected); \ 147 const AUTO_TYPE_VAR(actual) _a = (actual); \ 148 if (_e >= _a) { \ 149 UNITTEST_FAIL_TRACEF(EXPECTED_STRING \ 150 "%s (%ld) to be" \ 151 " less-than actual %s (%ld)\n", \ 152 msg, #expected, (long)_e, #actual, (long)_a); \ 153 if (term) return false; else all_ok = false; \ 154 } \ 155 } while (0) 156 157 #define UTCHECK_GE(expected, actual, msg, term) \ 158 do { \ 159 const AUTO_TYPE_VAR(expected) _e = (expected); \ 160 const AUTO_TYPE_VAR(actual) _a = (actual); \ 161 if (_e < _a) { \ 162 UNITTEST_FAIL_TRACEF(EXPECTED_STRING \ 163 "%s (%ld) to be" \ 164 " greater-than-or-equal-to actual %s (%ld)\n", \ 165 msg, #expected, (long)_e, #actual, (long)_a); \ 166 if (term) return false; else all_ok = false; \ 167 } \ 168 } while (0) 169 170 #define UTCHECK_GT(expected, actual, msg, term) \ 171 do { \ 172 const AUTO_TYPE_VAR(expected) _e = (expected); \ 173 const AUTO_TYPE_VAR(actual) _a = (actual); \ 174 if (_e <= _a) { \ 175 UNITTEST_FAIL_TRACEF(EXPECTED_STRING \ 176 "%s (%ld) to be" \ 177 " greater-than actual %s (%ld)\n", \ 178 msg, #expected, (long)_e, #actual, (long)_a); \ 179 if (term) return false; else all_ok = false; \ 180 } \ 181 } while (0) 182 183 #define UTCHECK_TRUE(actual, msg, term) \ 184 if (!(actual)) { \ 185 UNITTEST_FAIL_TRACEF("%s: %s is false\n", msg, #actual); \ 186 if (term) return false; else all_ok = false; \ 187 } 188 189 #define UTCHECK_FALSE(actual, msg, term) \ 190 if (actual) { \ 191 UNITTEST_FAIL_TRACEF("%s: %s is true\n", msg, #actual); \ 192 if (term) return false; else all_ok = false; \ 193 } 194 195 #define UTCHECK_NULL(actual, msg, term) \ 196 if (actual != NULL) { \ 197 UNITTEST_FAIL_TRACEF("%s: %s is non-null!\n", msg, #actual); \ 198 if (term) return false; else all_ok = false; \ 199 } 200 201 #define UTCHECK_NONNULL(actual, msg, term) \ 202 if (actual == NULL) { \ 203 UNITTEST_FAIL_TRACEF("%s: %s is null!\n", msg, #actual); \ 204 if (term) return false; else all_ok = false; \ 205 } 206 207 #define UTCHECK_BYTES_EQ(expected, actual, length, msg, term) \ 208 if (!unittest_expect_bytes((expected), #expected, \ 209 (actual), #actual, \ 210 (length), msg, __PRETTY_FUNCTION__, __LINE__, \ 211 true)) { \ 212 if (term) return false; else all_ok = false; \ 213 } 214 215 #define UTCHECK_BYTES_NE(expected, actual, length, msg, term) \ 216 if (!unittest_expect_bytes((expected), #expected, \ 217 (actual), #actual, \ 218 (length), msg, __PRETTY_FUNCTION__, __LINE__, \ 219 false)) { \ 220 if (term) return false; else all_ok = false; \ 221 } 222 223 /* EXPECT_* macros check the supplied condition and will print a message and flag the test 224 * as having failed if the condition fails. The test will continue to run, even 225 * if the condition fails. 226 */ 227 #define EXPECT_EQ(expected, actual, msg) UTCHECK_EQ(expected, actual, msg, false) 228 #define EXPECT_NE(expected, actual, msg) UTCHECK_NE(expected, actual, msg, false) 229 #define EXPECT_LE(expected, actual, msg) UTCHECK_LE(expected, actual, msg, false) 230 #define EXPECT_LT(expected, actual, msg) UTCHECK_LT(expected, actual, msg, false) 231 #define EXPECT_GE(expected, actual, msg) UTCHECK_GE(expected, actual, msg, false) 232 #define EXPECT_GT(expected, actual, msg) UTCHECK_GT(expected, actual, msg, false) 233 #define EXPECT_TRUE(actual, msg) UTCHECK_TRUE(actual, msg, false) 234 #define EXPECT_FALSE(actual, msg) UTCHECK_FALSE(actual, msg, false) 235 #define EXPECT_BYTES_EQ(expected, actual, length, msg) UTCHECK_BYTES_EQ(expected, actual, length, msg, false) 236 #define EXPECT_BYTES_NE(bytes1, bytes2, length, msg) UTCHECK_BYTES_NE(bytes1, bytes2, length, msg, false) 237 #define EXPECT_EQ_LL(expected, actual, msg) UTCHECK_EQ_LL(expected, actual, msg, false) 238 #define EXPECT_EQ_LL(expected, actual, msg) UTCHECK_EQ_LL(expected, actual, msg, false) 239 #define EXPECT_NULL(actual, msg) UTCHECK_NULL(actual, msg, false) 240 #define EXPECT_NONNULL(actual, msg) UTCHECK_NONNULL(actual, msg, false) 241 242 /* ASSERT_* macros check the condition and will print a message and immediately 243 * abort a test with a filure status if the condition fails. 244 */ 245 #define ASSERT_EQ(expected, actual, msg) UTCHECK_EQ(expected, actual, msg, true) 246 #define ASSERT_NE(expected, actual, msg) UTCHECK_NE(expected, actual, msg, true) 247 #define ASSERT_LE(expected, actual, msg) UTCHECK_LE(expected, actual, msg, true) 248 #define ASSERT_LT(expected, actual, msg) UTCHECK_LT(expected, actual, msg, true) 249 #define ASSERT_GE(expected, actual, msg) UTCHECK_GE(expected, actual, msg, true) 250 #define ASSERT_GT(expected, actual, msg) UTCHECK_GT(expected, actual, msg, true) 251 #define ASSERT_TRUE(actual, msg) UTCHECK_TRUE(actual, msg, true) 252 #define ASSERT_FALSE(actual, msg) UTCHECK_FALSE(actual, msg, true) 253 #define ASSERT_BYTES_EQ(expected, actual, length, msg) UTCHECK_BYTES_EQ(expected, actual, length, msg, true) 254 #define ASSERT_BYTES_NE(bytes1, bytes2, length, msg) UTCHECK_BYTES_NE(bytes1, bytes2, length, msg, true) 255 #define ASSERT_EQ_LL(expected, actual, msg) UTCHECK_EQ_LL(expected, actual, msg, true) 256 #define ASSERT_EQ_LL(expected, actual, msg) UTCHECK_EQ_LL(expected, actual, msg, true) 257 #define ASSERT_NULL(actual, msg) UTCHECK_NULL(actual, msg, true) 258 #define ASSERT_NONNULL(actual, msg) UTCHECK_NONNULL(actual, msg, true) 259 260 /* 261 * The list of test cases is made up of these elements. 262 */ 263 struct test_case_element { 264 struct test_case_element* next; 265 struct test_case_element* failed_next; 266 const char* name; 267 bool (*test_case)(void); 268 }; 269 270 /* 271 * Registers a test case with the unit test framework. 272 */ 273 void unittest_register_test_case(struct test_case_element* elem); 274 275 /* 276 * Runs all registered test cases. 277 */ 278 bool run_all_tests(void); 279 280 /* 281 * Returns false if expected does or does not equal actual (based on expect_eq). 282 * Will print msg and a hexdump8 of the input buffers if the check fails. 283 */ 284 bool unittest_expect_bytes(const uint8_t* expected, 285 const char* expected_name, 286 const uint8_t* actual, 287 const char* actual_name, 288 size_t len, 289 const char *msg, 290 const char* func, 291 int line, 292 bool expect_eq); 293 294 typedef bool (*unitest_fn_t)(void); 295 296 typedef struct unitest_registration { 297 const char* name; 298 unitest_fn_t fn; 299 } unittest_registration_t; 300 301 typedef struct unitest_testcase_registration { 302 const char* name; 303 const char* desc; 304 const unittest_registration_t* tests; 305 size_t test_cnt; 306 } unittest_testcase_registration_t; 307 308 #define UNITTEST_START_TESTCASE(_global_id) \ 309 static const unittest_registration_t __unittest_table_##_global_id[] = { 310 311 #define UNITTEST(_name, _fn) \ 312 { .name = _name, .fn = _fn }, 313 314 #define UNITTEST_END_TESTCASE(_global_id, _name, _desc) \ 315 }; /* __unittest_table_##_global_id */ \ 316 __ALIGNED(sizeof(void *)) __USED __SECTION(".data.rel.ro.unittest_testcases") \ 317 static const unittest_testcase_registration_t __unittest_case_##_global_id = \ 318 { \ 319 .name = _name, \ 320 .desc = _desc, \ 321 .tests = __unittest_table_##_global_id, \ 322 .test_cnt = countof(__unittest_table_##_global_id), \ 323 } 324 325 __END_CDECLS 326