Commit | Line | Data |
---|---|---|
c99ee51a KC |
1 | /* |
2 | * Copyright (c) 2012 The Chromium OS Authors. All rights reserved. | |
3 | * Use of this source code is governed by the GPLv2 license. | |
4 | * | |
dfa47d31 | 5 | * kselftest_harness.h: simple C unit test helper. |
c99ee51a | 6 | * |
7e6a32ab | 7 | * See documentation in Documentation/dev-tools/kselftest.rst |
c99ee51a KC |
8 | * |
9 | * API inspired by code.google.com/p/googletest | |
10 | */ | |
dfa47d31 | 11 | |
7e6a32ab MS |
12 | /** |
13 | * DOC: example | |
14 | * | |
15 | * .. code-block:: c | |
16 | * | |
17 | * #include "../kselftest_harness.h" | |
18 | * | |
19 | * TEST(standalone_test) { | |
20 | * do_some_stuff; | |
21 | * EXPECT_GT(10, stuff) { | |
22 | * stuff_state_t state; | |
23 | * enumerate_stuff_state(&state); | |
24 | * TH_LOG("expectation failed with state: %s", state.msg); | |
25 | * } | |
26 | * more_stuff; | |
27 | * ASSERT_NE(some_stuff, NULL) TH_LOG("how did it happen?!"); | |
28 | * last_stuff; | |
29 | * EXPECT_EQ(0, last_stuff); | |
30 | * } | |
31 | * | |
32 | * FIXTURE(my_fixture) { | |
33 | * mytype_t *data; | |
34 | * int awesomeness_level; | |
35 | * }; | |
36 | * FIXTURE_SETUP(my_fixture) { | |
37 | * self->data = mytype_new(); | |
38 | * ASSERT_NE(NULL, self->data); | |
39 | * } | |
40 | * FIXTURE_TEARDOWN(my_fixture) { | |
41 | * mytype_free(self->data); | |
42 | * } | |
43 | * TEST_F(my_fixture, data_is_good) { | |
44 | * EXPECT_EQ(1, is_my_data_good(self->data)); | |
45 | * } | |
46 | * | |
47 | * TEST_HARNESS_MAIN | |
48 | */ | |
49 | ||
dfa47d31 MS |
50 | #ifndef __KSELFTEST_HARNESS_H |
51 | #define __KSELFTEST_HARNESS_H | |
c99ee51a KC |
52 | |
53 | #define _GNU_SOURCE | |
369130b6 MS |
54 | #include <asm/types.h> |
55 | #include <errno.h> | |
56 | #include <stdbool.h> | |
b5bb6d30 | 57 | #include <stdint.h> |
c99ee51a KC |
58 | #include <stdio.h> |
59 | #include <stdlib.h> | |
60 | #include <string.h> | |
61 | #include <sys/types.h> | |
62 | #include <sys/wait.h> | |
63 | #include <unistd.h> | |
64 | ||
c99ee51a | 65 | |
1256a525 MS |
66 | /* Utilities exposed to the test definitions */ |
67 | #ifndef TH_LOG_STREAM | |
68 | # define TH_LOG_STREAM stderr | |
69 | #endif | |
70 | ||
71 | #ifndef TH_LOG_ENABLED | |
72 | # define TH_LOG_ENABLED 1 | |
73 | #endif | |
74 | ||
7e6a32ab MS |
75 | /** |
76 | * TH_LOG(fmt, ...) | |
77 | * | |
78 | * @fmt: format string | |
79 | * @...: optional arguments | |
80 | * | |
81 | * .. code-block:: c | |
82 | * | |
83 | * TH_LOG(format, ...) | |
84 | * | |
1256a525 MS |
85 | * Optional debug logging function available for use in tests. |
86 | * Logging may be enabled or disabled by defining TH_LOG_ENABLED. | |
87 | * E.g., #define TH_LOG_ENABLED 1 | |
7e6a32ab | 88 | * |
1256a525 | 89 | * If no definition is provided, logging is enabled by default. |
369130b6 MS |
90 | * |
91 | * If there is no way to print an error message for the process running the | |
92 | * test (e.g. not allowed to write to stderr), it is still possible to get the | |
93 | * ASSERT_* number for which the test failed. This behavior can be enabled by | |
94 | * writing `_metadata->no_print = true;` before the check sequence that is | |
95 | * unable to print. When an error occur, instead of printing an error message | |
96 | * and calling `abort(3)`, the test process call `_exit(2)` with the assert | |
97 | * number as argument, which is then printed by the parent process. | |
c99ee51a | 98 | */ |
1256a525 MS |
99 | #define TH_LOG(fmt, ...) do { \ |
100 | if (TH_LOG_ENABLED) \ | |
101 | __TH_LOG(fmt, ##__VA_ARGS__); \ | |
102 | } while (0) | |
103 | ||
104 | /* Unconditional logger for internal use. */ | |
105 | #define __TH_LOG(fmt, ...) \ | |
106 | fprintf(TH_LOG_STREAM, "%s:%d:%s:" fmt "\n", \ | |
107 | __FILE__, __LINE__, _metadata->name, ##__VA_ARGS__) | |
c99ee51a | 108 | |
7e6a32ab MS |
109 | /** |
110 | * TEST(test_name) - Defines the test function and creates the registration | |
111 | * stub | |
112 | * | |
113 | * @test_name: test name | |
114 | * | |
115 | * .. code-block:: c | |
116 | * | |
117 | * TEST(name) { implementation } | |
118 | * | |
c99ee51a KC |
119 | * Defines a test by name. |
120 | * Names must be unique and tests must not be run in parallel. The | |
121 | * implementation containing block is a function and scoping should be treated | |
122 | * as such. Returning early may be performed with a bare "return;" statement. | |
123 | * | |
124 | * EXPECT_* and ASSERT_* are valid in a TEST() { } context. | |
125 | */ | |
1256a525 | 126 | #define TEST(test_name) __TEST_IMPL(test_name, -1) |
c99ee51a | 127 | |
7e6a32ab MS |
128 | /** |
129 | * TEST_SIGNAL(test_name, signal) | |
130 | * | |
131 | * @test_name: test name | |
132 | * @signal: signal number | |
133 | * | |
134 | * .. code-block:: c | |
135 | * | |
136 | * TEST_SIGNAL(name, signal) { implementation } | |
137 | * | |
c99ee51a KC |
138 | * Defines a test by name and the expected term signal. |
139 | * Names must be unique and tests must not be run in parallel. The | |
140 | * implementation containing block is a function and scoping should be treated | |
141 | * as such. Returning early may be performed with a bare "return;" statement. | |
142 | * | |
143 | * EXPECT_* and ASSERT_* are valid in a TEST() { } context. | |
144 | */ | |
1256a525 MS |
145 | #define TEST_SIGNAL(test_name, signal) __TEST_IMPL(test_name, signal) |
146 | ||
147 | #define __TEST_IMPL(test_name, _signal) \ | |
148 | static void test_name(struct __test_metadata *_metadata); \ | |
149 | static struct __test_metadata _##test_name##_object = \ | |
150 | { name: "global." #test_name, \ | |
151 | fn: &test_name, termsig: _signal }; \ | |
152 | static void __attribute__((constructor)) _register_##test_name(void) \ | |
153 | { \ | |
154 | __register_test(&_##test_name##_object); \ | |
155 | } \ | |
156 | static void test_name( \ | |
157 | struct __test_metadata __attribute__((unused)) *_metadata) | |
158 | ||
7e6a32ab MS |
159 | /** |
160 | * FIXTURE_DATA(datatype_name) - Wraps the struct name so we have one less | |
161 | * argument to pass around | |
162 | * | |
163 | * @datatype_name: datatype name | |
164 | * | |
165 | * .. code-block:: c | |
166 | * | |
167 | * FIXTURE_DATA(datatype name) | |
168 | * | |
1256a525 MS |
169 | * This call may be used when the type of the fixture data |
170 | * is needed. In general, this should not be needed unless | |
7e6a32ab | 171 | * the *self* is being passed to a helper directly. |
1256a525 | 172 | */ |
1256a525 | 173 | #define FIXTURE_DATA(datatype_name) struct _test_data_##datatype_name |
c99ee51a | 174 | |
7e6a32ab MS |
175 | /** |
176 | * FIXTURE(fixture_name) - Called once per fixture to setup the data and | |
177 | * register | |
178 | * | |
179 | * @fixture_name: fixture name | |
180 | * | |
181 | * .. code-block:: c | |
182 | * | |
183 | * FIXTURE(datatype name) { | |
184 | * type property1; | |
185 | * ... | |
186 | * }; | |
187 | * | |
188 | * Defines the data provided to TEST_F()-defined tests as *self*. It should be | |
189 | * populated and cleaned up using FIXTURE_SETUP() and FIXTURE_TEARDOWN(). | |
c99ee51a | 190 | */ |
1256a525 MS |
191 | #define FIXTURE(fixture_name) \ |
192 | static void __attribute__((constructor)) \ | |
193 | _register_##fixture_name##_data(void) \ | |
194 | { \ | |
195 | __fixture_count++; \ | |
196 | } \ | |
197 | FIXTURE_DATA(fixture_name) | |
c99ee51a | 198 | |
7e6a32ab MS |
199 | /** |
200 | * FIXTURE_SETUP(fixture_name) - Prepares the setup function for the fixture. | |
201 | * *_metadata* is included so that ASSERT_* work as a convenience | |
202 | * | |
203 | * @fixture_name: fixture name | |
204 | * | |
205 | * .. code-block:: c | |
206 | * | |
207 | * FIXTURE_SETUP(fixture name) { implementation } | |
208 | * | |
c99ee51a | 209 | * Populates the required "setup" function for a fixture. An instance of the |
7e6a32ab | 210 | * datatype defined with FIXTURE_DATA() will be exposed as *self* for the |
c99ee51a KC |
211 | * implementation. |
212 | * | |
213 | * ASSERT_* are valid for use in this context and will prempt the execution | |
214 | * of any dependent fixture tests. | |
215 | * | |
216 | * A bare "return;" statement may be used to return early. | |
217 | */ | |
1256a525 MS |
218 | #define FIXTURE_SETUP(fixture_name) \ |
219 | void fixture_name##_setup( \ | |
220 | struct __test_metadata __attribute__((unused)) *_metadata, \ | |
221 | FIXTURE_DATA(fixture_name) __attribute__((unused)) *self) | |
7e6a32ab MS |
222 | /** |
223 | * FIXTURE_TEARDOWN(fixture_name) | |
224 | * | |
225 | * @fixture_name: fixture name | |
226 | * | |
227 | * .. code-block:: c | |
228 | * | |
229 | * FIXTURE_TEARDOWN(fixture name) { implementation } | |
230 | * | |
c99ee51a | 231 | * Populates the required "teardown" function for a fixture. An instance of the |
7e6a32ab | 232 | * datatype defined with FIXTURE_DATA() will be exposed as *self* for the |
c99ee51a KC |
233 | * implementation to clean up. |
234 | * | |
235 | * A bare "return;" statement may be used to return early. | |
236 | */ | |
1256a525 MS |
237 | #define FIXTURE_TEARDOWN(fixture_name) \ |
238 | void fixture_name##_teardown( \ | |
239 | struct __test_metadata __attribute__((unused)) *_metadata, \ | |
240 | FIXTURE_DATA(fixture_name) __attribute__((unused)) *self) | |
c99ee51a | 241 | |
7e6a32ab MS |
242 | /** |
243 | * TEST_F(fixture_name, test_name) - Emits test registration and helpers for | |
244 | * fixture-based test cases | |
245 | * | |
246 | * @fixture_name: fixture name | |
247 | * @test_name: test name | |
248 | * | |
249 | * .. code-block:: c | |
250 | * | |
251 | * TEST_F(fixture, name) { implementation } | |
252 | * | |
c99ee51a | 253 | * Defines a test that depends on a fixture (e.g., is part of a test case). |
7e6a32ab | 254 | * Very similar to TEST() except that *self* is the setup instance of fixture's |
c99ee51a KC |
255 | * datatype exposed for use by the implementation. |
256 | */ | |
7e6a32ab | 257 | /* TODO(wad) register fixtures on dedicated test lists. */ |
1256a525 | 258 | #define TEST_F(fixture_name, test_name) \ |
c99ee51a KC |
259 | __TEST_F_IMPL(fixture_name, test_name, -1) |
260 | ||
1256a525 | 261 | #define TEST_F_SIGNAL(fixture_name, test_name, signal) \ |
c99ee51a KC |
262 | __TEST_F_IMPL(fixture_name, test_name, signal) |
263 | ||
264 | #define __TEST_F_IMPL(fixture_name, test_name, signal) \ | |
265 | static void fixture_name##_##test_name( \ | |
266 | struct __test_metadata *_metadata, \ | |
1256a525 | 267 | FIXTURE_DATA(fixture_name) *self); \ |
c99ee51a KC |
268 | static inline void wrapper_##fixture_name##_##test_name( \ |
269 | struct __test_metadata *_metadata) \ | |
270 | { \ | |
271 | /* fixture data is alloced, setup, and torn down per call. */ \ | |
1256a525 MS |
272 | FIXTURE_DATA(fixture_name) self; \ |
273 | memset(&self, 0, sizeof(FIXTURE_DATA(fixture_name))); \ | |
c99ee51a KC |
274 | fixture_name##_setup(_metadata, &self); \ |
275 | /* Let setup failure terminate early. */ \ | |
276 | if (!_metadata->passed) \ | |
277 | return; \ | |
278 | fixture_name##_##test_name(_metadata, &self); \ | |
279 | fixture_name##_teardown(_metadata, &self); \ | |
280 | } \ | |
281 | static struct __test_metadata \ | |
282 | _##fixture_name##_##test_name##_object = { \ | |
283 | name: #fixture_name "." #test_name, \ | |
284 | fn: &wrapper_##fixture_name##_##test_name, \ | |
285 | termsig: signal, \ | |
286 | }; \ | |
287 | static void __attribute__((constructor)) \ | |
288 | _register_##fixture_name##_##test_name(void) \ | |
289 | { \ | |
290 | __register_test(&_##fixture_name##_##test_name##_object); \ | |
291 | } \ | |
292 | static void fixture_name##_##test_name( \ | |
293 | struct __test_metadata __attribute__((unused)) *_metadata, \ | |
1256a525 | 294 | FIXTURE_DATA(fixture_name) __attribute__((unused)) *self) |
c99ee51a | 295 | |
7e6a32ab MS |
296 | /** |
297 | * TEST_HARNESS_MAIN - Simple wrapper to run the test harness | |
298 | * | |
299 | * .. code-block:: c | |
300 | * | |
301 | * TEST_HARNESS_MAIN | |
302 | * | |
303 | * Use once to append a main() to the test file. | |
1256a525 | 304 | */ |
1256a525 | 305 | #define TEST_HARNESS_MAIN \ |
c99ee51a KC |
306 | static void __attribute__((constructor)) \ |
307 | __constructor_order_last(void) \ | |
308 | { \ | |
309 | if (!__constructor_order) \ | |
310 | __constructor_order = _CONSTRUCTOR_ORDER_BACKWARD; \ | |
311 | } \ | |
312 | int main(int argc, char **argv) { \ | |
313 | return test_harness_run(argc, argv); \ | |
314 | } | |
315 | ||
7e6a32ab MS |
316 | /** |
317 | * DOC: operators | |
318 | * | |
319 | * Operators for use in TEST() and TEST_F(). | |
1256a525 MS |
320 | * ASSERT_* calls will stop test execution immediately. |
321 | * EXPECT_* calls will emit a failure warning, note it, and continue. | |
322 | */ | |
7e6a32ab MS |
323 | |
324 | /** | |
325 | * ASSERT_EQ(expected, seen) | |
326 | * | |
327 | * @expected: expected value | |
328 | * @seen: measured value | |
329 | * | |
330 | * ASSERT_EQ(expected, measured): expected == measured | |
331 | */ | |
1256a525 MS |
332 | #define ASSERT_EQ(expected, seen) \ |
333 | __EXPECT(expected, seen, ==, 1) | |
7e6a32ab MS |
334 | |
335 | /** | |
336 | * ASSERT_NE(expected, seen) | |
337 | * | |
338 | * @expected: expected value | |
339 | * @seen: measured value | |
340 | * | |
341 | * ASSERT_NE(expected, measured): expected != measured | |
342 | */ | |
1256a525 MS |
343 | #define ASSERT_NE(expected, seen) \ |
344 | __EXPECT(expected, seen, !=, 1) | |
7e6a32ab MS |
345 | |
346 | /** | |
347 | * ASSERT_LT(expected, seen) | |
348 | * | |
349 | * @expected: expected value | |
350 | * @seen: measured value | |
351 | * | |
352 | * ASSERT_LT(expected, measured): expected < measured | |
353 | */ | |
1256a525 MS |
354 | #define ASSERT_LT(expected, seen) \ |
355 | __EXPECT(expected, seen, <, 1) | |
7e6a32ab MS |
356 | |
357 | /** | |
358 | * ASSERT_LE(expected, seen) | |
359 | * | |
360 | * @expected: expected value | |
361 | * @seen: measured value | |
362 | * | |
363 | * ASSERT_LE(expected, measured): expected <= measured | |
364 | */ | |
1256a525 MS |
365 | #define ASSERT_LE(expected, seen) \ |
366 | __EXPECT(expected, seen, <=, 1) | |
7e6a32ab MS |
367 | |
368 | /** | |
369 | * ASSERT_GT(expected, seen) | |
370 | * | |
371 | * @expected: expected value | |
372 | * @seen: measured value | |
373 | * | |
374 | * ASSERT_GT(expected, measured): expected > measured | |
375 | */ | |
1256a525 MS |
376 | #define ASSERT_GT(expected, seen) \ |
377 | __EXPECT(expected, seen, >, 1) | |
7e6a32ab MS |
378 | |
379 | /** | |
380 | * ASSERT_GE(expected, seen) | |
381 | * | |
382 | * @expected: expected value | |
383 | * @seen: measured value | |
384 | * | |
385 | * ASSERT_GE(expected, measured): expected >= measured | |
386 | */ | |
1256a525 MS |
387 | #define ASSERT_GE(expected, seen) \ |
388 | __EXPECT(expected, seen, >=, 1) | |
7e6a32ab MS |
389 | |
390 | /** | |
391 | * ASSERT_NULL(seen) | |
392 | * | |
393 | * @seen: measured value | |
394 | * | |
395 | * ASSERT_NULL(measured): NULL == measured | |
396 | */ | |
1256a525 MS |
397 | #define ASSERT_NULL(seen) \ |
398 | __EXPECT(NULL, seen, ==, 1) | |
c99ee51a | 399 | |
7e6a32ab MS |
400 | /** |
401 | * ASSERT_TRUE(seen) | |
402 | * | |
403 | * @seen: measured value | |
404 | * | |
405 | * ASSERT_TRUE(measured): measured != 0 | |
406 | */ | |
1256a525 MS |
407 | #define ASSERT_TRUE(seen) \ |
408 | ASSERT_NE(0, seen) | |
7e6a32ab MS |
409 | |
410 | /** | |
411 | * ASSERT_FALSE(seen) | |
412 | * | |
413 | * @seen: measured value | |
414 | * | |
415 | * ASSERT_FALSE(measured): measured == 0 | |
416 | */ | |
1256a525 MS |
417 | #define ASSERT_FALSE(seen) \ |
418 | ASSERT_EQ(0, seen) | |
7e6a32ab MS |
419 | |
420 | /** | |
421 | * ASSERT_STREQ(expected, seen) | |
422 | * | |
423 | * @expected: expected value | |
424 | * @seen: measured value | |
425 | * | |
426 | * ASSERT_STREQ(expected, measured): !strcmp(expected, measured) | |
427 | */ | |
1256a525 MS |
428 | #define ASSERT_STREQ(expected, seen) \ |
429 | __EXPECT_STR(expected, seen, ==, 1) | |
7e6a32ab MS |
430 | |
431 | /** | |
432 | * ASSERT_STRNE(expected, seen) | |
433 | * | |
434 | * @expected: expected value | |
435 | * @seen: measured value | |
436 | * | |
437 | * ASSERT_STRNE(expected, measured): strcmp(expected, measured) | |
438 | */ | |
1256a525 MS |
439 | #define ASSERT_STRNE(expected, seen) \ |
440 | __EXPECT_STR(expected, seen, !=, 1) | |
c99ee51a | 441 | |
7e6a32ab MS |
442 | /** |
443 | * EXPECT_EQ(expected, seen) | |
444 | * | |
445 | * @expected: expected value | |
446 | * @seen: measured value | |
447 | * | |
448 | * EXPECT_EQ(expected, measured): expected == measured | |
449 | */ | |
1256a525 MS |
450 | #define EXPECT_EQ(expected, seen) \ |
451 | __EXPECT(expected, seen, ==, 0) | |
7e6a32ab MS |
452 | |
453 | /** | |
454 | * EXPECT_NE(expected, seen) | |
455 | * | |
456 | * @expected: expected value | |
457 | * @seen: measured value | |
458 | * | |
459 | * EXPECT_NE(expected, measured): expected != measured | |
460 | */ | |
1256a525 MS |
461 | #define EXPECT_NE(expected, seen) \ |
462 | __EXPECT(expected, seen, !=, 0) | |
7e6a32ab MS |
463 | |
464 | /** | |
465 | * EXPECT_LT(expected, seen) | |
466 | * | |
467 | * @expected: expected value | |
468 | * @seen: measured value | |
469 | * | |
470 | * EXPECT_LT(expected, measured): expected < measured | |
471 | */ | |
1256a525 MS |
472 | #define EXPECT_LT(expected, seen) \ |
473 | __EXPECT(expected, seen, <, 0) | |
7e6a32ab MS |
474 | |
475 | /** | |
476 | * EXPECT_LE(expected, seen) | |
477 | * | |
478 | * @expected: expected value | |
479 | * @seen: measured value | |
480 | * | |
481 | * EXPECT_LE(expected, measured): expected <= measured | |
482 | */ | |
1256a525 MS |
483 | #define EXPECT_LE(expected, seen) \ |
484 | __EXPECT(expected, seen, <=, 0) | |
7e6a32ab MS |
485 | |
486 | /** | |
487 | * EXPECT_GT(expected, seen) | |
488 | * | |
489 | * @expected: expected value | |
490 | * @seen: measured value | |
491 | * | |
492 | * EXPECT_GT(expected, measured): expected > measured | |
493 | */ | |
1256a525 MS |
494 | #define EXPECT_GT(expected, seen) \ |
495 | __EXPECT(expected, seen, >, 0) | |
7e6a32ab MS |
496 | |
497 | /** | |
498 | * EXPECT_GE(expected, seen) | |
499 | * | |
500 | * @expected: expected value | |
501 | * @seen: measured value | |
502 | * | |
503 | * EXPECT_GE(expected, measured): expected >= measured | |
504 | */ | |
1256a525 MS |
505 | #define EXPECT_GE(expected, seen) \ |
506 | __EXPECT(expected, seen, >=, 0) | |
c99ee51a | 507 | |
7e6a32ab MS |
508 | /** |
509 | * EXPECT_NULL(seen) | |
510 | * | |
511 | * @seen: measured value | |
512 | * | |
513 | * EXPECT_NULL(measured): NULL == measured | |
514 | */ | |
1256a525 MS |
515 | #define EXPECT_NULL(seen) \ |
516 | __EXPECT(NULL, seen, ==, 0) | |
7e6a32ab MS |
517 | |
518 | /** | |
519 | * EXPECT_TRUE(seen) | |
520 | * | |
521 | * @seen: measured value | |
522 | * | |
523 | * EXPECT_TRUE(measured): 0 != measured | |
524 | */ | |
1256a525 MS |
525 | #define EXPECT_TRUE(seen) \ |
526 | EXPECT_NE(0, seen) | |
7e6a32ab MS |
527 | |
528 | /** | |
529 | * EXPECT_FALSE(seen) | |
530 | * | |
531 | * @seen: measured value | |
532 | * | |
533 | * EXPECT_FALSE(measured): 0 == measured | |
534 | */ | |
1256a525 MS |
535 | #define EXPECT_FALSE(seen) \ |
536 | EXPECT_EQ(0, seen) | |
c99ee51a | 537 | |
7e6a32ab MS |
538 | /** |
539 | * EXPECT_STREQ(expected, seen) | |
540 | * | |
541 | * @expected: expected value | |
542 | * @seen: measured value | |
543 | * | |
544 | * EXPECT_STREQ(expected, measured): !strcmp(expected, measured) | |
545 | */ | |
1256a525 MS |
546 | #define EXPECT_STREQ(expected, seen) \ |
547 | __EXPECT_STR(expected, seen, ==, 0) | |
7e6a32ab MS |
548 | |
549 | /** | |
550 | * EXPECT_STRNE(expected, seen) | |
551 | * | |
552 | * @expected: expected value | |
553 | * @seen: measured value | |
554 | * | |
555 | * EXPECT_STRNE(expected, measured): strcmp(expected, measured) | |
556 | */ | |
1256a525 MS |
557 | #define EXPECT_STRNE(expected, seen) \ |
558 | __EXPECT_STR(expected, seen, !=, 0) | |
c99ee51a KC |
559 | |
560 | #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) | |
561 | ||
562 | /* Support an optional handler after and ASSERT_* or EXPECT_*. The approach is | |
563 | * not thread-safe, but it should be fine in most sane test scenarios. | |
564 | * | |
565 | * Using __bail(), which optionally abort()s, is the easiest way to early | |
566 | * return while still providing an optional block to the API consumer. | |
567 | */ | |
568 | #define OPTIONAL_HANDLER(_assert) \ | |
369130b6 MS |
569 | for (; _metadata->trigger; _metadata->trigger = \ |
570 | __bail(_assert, _metadata->no_print, _metadata->step)) | |
571 | ||
572 | #define __INC_STEP(_metadata) \ | |
573 | if (_metadata->passed && _metadata->step < 255) \ | |
574 | _metadata->step++; | |
c99ee51a KC |
575 | |
576 | #define __EXPECT(_expected, _seen, _t, _assert) do { \ | |
577 | /* Avoid multiple evaluation of the cases */ \ | |
578 | __typeof__(_expected) __exp = (_expected); \ | |
579 | __typeof__(_seen) __seen = (_seen); \ | |
369130b6 | 580 | if (_assert) __INC_STEP(_metadata); \ |
c99ee51a | 581 | if (!(__exp _t __seen)) { \ |
b5bb6d30 KC |
582 | unsigned long long __exp_print = (uintptr_t)__exp; \ |
583 | unsigned long long __seen_print = (uintptr_t)__seen; \ | |
c99ee51a KC |
584 | __TH_LOG("Expected %s (%llu) %s %s (%llu)", \ |
585 | #_expected, __exp_print, #_t, \ | |
586 | #_seen, __seen_print); \ | |
587 | _metadata->passed = 0; \ | |
588 | /* Ensure the optional handler is triggered */ \ | |
589 | _metadata->trigger = 1; \ | |
590 | } \ | |
591 | } while (0); OPTIONAL_HANDLER(_assert) | |
592 | ||
593 | #define __EXPECT_STR(_expected, _seen, _t, _assert) do { \ | |
594 | const char *__exp = (_expected); \ | |
595 | const char *__seen = (_seen); \ | |
369130b6 | 596 | if (_assert) __INC_STEP(_metadata); \ |
c99ee51a KC |
597 | if (!(strcmp(__exp, __seen) _t 0)) { \ |
598 | __TH_LOG("Expected '%s' %s '%s'.", __exp, #_t, __seen); \ | |
599 | _metadata->passed = 0; \ | |
600 | _metadata->trigger = 1; \ | |
601 | } \ | |
602 | } while (0); OPTIONAL_HANDLER(_assert) | |
603 | ||
604 | /* Contains all the information for test execution and status checking. */ | |
605 | struct __test_metadata { | |
606 | const char *name; | |
607 | void (*fn)(struct __test_metadata *); | |
608 | int termsig; | |
609 | int passed; | |
610 | int trigger; /* extra handler after the evaluation */ | |
369130b6 MS |
611 | __u8 step; |
612 | bool no_print; /* manual trigger when TH_LOG_STREAM is not available */ | |
c99ee51a KC |
613 | struct __test_metadata *prev, *next; |
614 | }; | |
615 | ||
616 | /* Storage for the (global) tests to be run. */ | |
617 | static struct __test_metadata *__test_list; | |
618 | static unsigned int __test_count; | |
619 | static unsigned int __fixture_count; | |
620 | static int __constructor_order; | |
621 | ||
622 | #define _CONSTRUCTOR_ORDER_FORWARD 1 | |
623 | #define _CONSTRUCTOR_ORDER_BACKWARD -1 | |
624 | ||
625 | /* | |
626 | * Since constructors are called in reverse order, reverse the test | |
627 | * list so tests are run in source declaration order. | |
628 | * https://gcc.gnu.org/onlinedocs/gccint/Initialization.html | |
629 | * However, it seems not all toolchains do this correctly, so use | |
630 | * __constructor_order to detect which direction is called first | |
631 | * and adjust list building logic to get things running in the right | |
632 | * direction. | |
633 | */ | |
634 | static inline void __register_test(struct __test_metadata *t) | |
635 | { | |
636 | __test_count++; | |
637 | /* Circular linked list where only prev is circular. */ | |
638 | if (__test_list == NULL) { | |
639 | __test_list = t; | |
640 | t->next = NULL; | |
641 | t->prev = t; | |
642 | return; | |
643 | } | |
644 | if (__constructor_order == _CONSTRUCTOR_ORDER_FORWARD) { | |
645 | t->next = NULL; | |
646 | t->prev = __test_list->prev; | |
647 | t->prev->next = t; | |
648 | __test_list->prev = t; | |
649 | } else { | |
650 | t->next = __test_list; | |
651 | t->next->prev = t; | |
652 | t->prev = t; | |
653 | __test_list = t; | |
654 | } | |
655 | } | |
656 | ||
369130b6 | 657 | static inline int __bail(int for_realz, bool no_print, __u8 step) |
c99ee51a | 658 | { |
369130b6 MS |
659 | if (for_realz) { |
660 | if (no_print) | |
661 | _exit(step); | |
c99ee51a | 662 | abort(); |
369130b6 | 663 | } |
c99ee51a KC |
664 | return 0; |
665 | } | |
666 | ||
667 | void __run_test(struct __test_metadata *t) | |
668 | { | |
669 | pid_t child_pid; | |
670 | int status; | |
671 | ||
672 | t->passed = 1; | |
673 | t->trigger = 0; | |
674 | printf("[ RUN ] %s\n", t->name); | |
675 | child_pid = fork(); | |
676 | if (child_pid < 0) { | |
677 | printf("ERROR SPAWNING TEST CHILD\n"); | |
678 | t->passed = 0; | |
679 | } else if (child_pid == 0) { | |
680 | t->fn(t); | |
369130b6 MS |
681 | /* return the step that failed or 0 */ |
682 | _exit(t->passed ? 0 : t->step); | |
c99ee51a KC |
683 | } else { |
684 | /* TODO(wad) add timeout support. */ | |
685 | waitpid(child_pid, &status, 0); | |
686 | if (WIFEXITED(status)) { | |
369130b6 | 687 | t->passed = t->termsig == -1 ? !WEXITSTATUS(status) : 0; |
c99ee51a KC |
688 | if (t->termsig != -1) { |
689 | fprintf(TH_LOG_STREAM, | |
690 | "%s: Test exited normally " | |
691 | "instead of by signal (code: %d)\n", | |
692 | t->name, | |
693 | WEXITSTATUS(status)); | |
369130b6 MS |
694 | } else if (!t->passed) { |
695 | fprintf(TH_LOG_STREAM, | |
696 | "%s: Test failed at step #%d\n", | |
697 | t->name, | |
698 | WEXITSTATUS(status)); | |
c99ee51a KC |
699 | } |
700 | } else if (WIFSIGNALED(status)) { | |
701 | t->passed = 0; | |
702 | if (WTERMSIG(status) == SIGABRT) { | |
703 | fprintf(TH_LOG_STREAM, | |
704 | "%s: Test terminated by assertion\n", | |
705 | t->name); | |
706 | } else if (WTERMSIG(status) == t->termsig) { | |
707 | t->passed = 1; | |
708 | } else { | |
709 | fprintf(TH_LOG_STREAM, | |
710 | "%s: Test terminated unexpectedly " | |
711 | "by signal %d\n", | |
712 | t->name, | |
713 | WTERMSIG(status)); | |
714 | } | |
715 | } else { | |
716 | fprintf(TH_LOG_STREAM, | |
717 | "%s: Test ended in some other way [%u]\n", | |
718 | t->name, | |
719 | status); | |
720 | } | |
721 | } | |
722 | printf("[ %4s ] %s\n", (t->passed ? "OK" : "FAIL"), t->name); | |
723 | } | |
724 | ||
725 | static int test_harness_run(int __attribute__((unused)) argc, | |
726 | char __attribute__((unused)) **argv) | |
727 | { | |
728 | struct __test_metadata *t; | |
729 | int ret = 0; | |
730 | unsigned int count = 0; | |
731 | unsigned int pass_count = 0; | |
732 | ||
733 | /* TODO(wad) add optional arguments similar to gtest. */ | |
734 | printf("[==========] Running %u tests from %u test cases.\n", | |
735 | __test_count, __fixture_count + 1); | |
736 | for (t = __test_list; t; t = t->next) { | |
737 | count++; | |
738 | __run_test(t); | |
739 | if (t->passed) | |
740 | pass_count++; | |
741 | else | |
742 | ret = 1; | |
743 | } | |
744 | printf("[==========] %u / %u tests passed.\n", pass_count, count); | |
745 | printf("[ %s ]\n", (ret ? "FAILED" : "PASSED")); | |
746 | return ret; | |
747 | } | |
748 | ||
749 | static void __attribute__((constructor)) __constructor_order_first(void) | |
750 | { | |
751 | if (!__constructor_order) | |
752 | __constructor_order = _CONSTRUCTOR_ORDER_FORWARD; | |
753 | } | |
754 | ||
dfa47d31 | 755 | #endif /* __KSELFTEST_HARNESS_H */ |