1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
2 | /* |
3 | * Copyright (c) 2012 The Chromium OS Authors. All rights reserved. |
4 | * |
5 | * kselftest_harness.h: simple C unit test helper. |
6 | * |
7 | * See documentation in Documentation/dev-tools/kselftest.rst |
8 | * |
9 | * API inspired by code.google.com/p/googletest |
10 | */ |
11 | |
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 | |
50 | #ifndef __KSELFTEST_HARNESS_H |
51 | #define __KSELFTEST_HARNESS_H |
52 | |
53 | #ifndef _GNU_SOURCE |
54 | #define _GNU_SOURCE |
55 | #endif |
56 | #include <asm/types.h> |
57 | #include <ctype.h> |
58 | #include <errno.h> |
59 | #include <stdbool.h> |
60 | #include <stdint.h> |
61 | #include <stdio.h> |
62 | #include <stdlib.h> |
63 | #include <string.h> |
64 | #include <sys/mman.h> |
65 | #include <sys/types.h> |
66 | #include <sys/wait.h> |
67 | #include <unistd.h> |
68 | #include <setjmp.h> |
69 | |
70 | #include "kselftest.h" |
71 | |
72 | #define TEST_TIMEOUT_DEFAULT 30 |
73 | |
74 | /* Utilities exposed to the test definitions */ |
75 | #ifndef TH_LOG_STREAM |
76 | # define TH_LOG_STREAM stderr |
77 | #endif |
78 | |
79 | #ifndef TH_LOG_ENABLED |
80 | # define TH_LOG_ENABLED 1 |
81 | #endif |
82 | |
83 | /** |
84 | * TH_LOG() |
85 | * |
86 | * @fmt: format string |
87 | * @...: optional arguments |
88 | * |
89 | * .. code-block:: c |
90 | * |
91 | * TH_LOG(format, ...) |
92 | * |
93 | * Optional debug logging function available for use in tests. |
94 | * Logging may be enabled or disabled by defining TH_LOG_ENABLED. |
95 | * E.g., #define TH_LOG_ENABLED 1 |
96 | * |
97 | * If no definition is provided, logging is enabled by default. |
98 | * |
99 | * If there is no way to print an error message for the process running the |
100 | * test (e.g. not allowed to write to stderr), it is still possible to get the |
101 | * ASSERT_* number for which the test failed. This behavior can be enabled by |
102 | * writing `_metadata->no_print = true;` before the check sequence that is |
103 | * unable to print. When an error occur, instead of printing an error message |
104 | * and calling `abort(3)`, the test process call `_exit(2)` with the assert |
105 | * number as argument, which is then printed by the parent process. |
106 | */ |
107 | #define TH_LOG(fmt, ...) do { \ |
108 | if (TH_LOG_ENABLED) \ |
109 | __TH_LOG(fmt, ##__VA_ARGS__); \ |
110 | } while (0) |
111 | |
112 | /* Unconditional logger for internal use. */ |
113 | #define __TH_LOG(fmt, ...) \ |
114 | fprintf(TH_LOG_STREAM, "# %s:%d:%s:" fmt "\n", \ |
115 | __FILE__, __LINE__, _metadata->name, ##__VA_ARGS__) |
116 | |
117 | /** |
118 | * SKIP() |
119 | * |
120 | * @statement: statement to run after reporting SKIP |
121 | * @fmt: format string |
122 | * @...: optional arguments |
123 | * |
124 | * .. code-block:: c |
125 | * |
126 | * SKIP(statement, fmt, ...); |
127 | * |
128 | * This forces a "pass" after reporting why something is being skipped |
129 | * and runs "statement", which is usually "return" or "goto skip". |
130 | */ |
131 | #define SKIP(statement, fmt, ...) do { \ |
132 | snprintf(_metadata->results->reason, \ |
133 | sizeof(_metadata->results->reason), fmt, ##__VA_ARGS__); \ |
134 | if (TH_LOG_ENABLED) { \ |
135 | fprintf(TH_LOG_STREAM, "# SKIP %s\n", \ |
136 | _metadata->results->reason); \ |
137 | } \ |
138 | _metadata->passed = 1; \ |
139 | _metadata->skip = 1; \ |
140 | _metadata->trigger = 0; \ |
141 | statement; \ |
142 | } while (0) |
143 | |
144 | /** |
145 | * TEST() - Defines the test function and creates the registration |
146 | * stub |
147 | * |
148 | * @test_name: test name |
149 | * |
150 | * .. code-block:: c |
151 | * |
152 | * TEST(name) { implementation } |
153 | * |
154 | * Defines a test by name. |
155 | * Names must be unique and tests must not be run in parallel. The |
156 | * implementation containing block is a function and scoping should be treated |
157 | * as such. Returning early may be performed with a bare "return;" statement. |
158 | * |
159 | * EXPECT_* and ASSERT_* are valid in a TEST() { } context. |
160 | */ |
161 | #define TEST(test_name) __TEST_IMPL(test_name, -1) |
162 | |
163 | /** |
164 | * TEST_SIGNAL() |
165 | * |
166 | * @test_name: test name |
167 | * @signal: signal number |
168 | * |
169 | * .. code-block:: c |
170 | * |
171 | * TEST_SIGNAL(name, signal) { implementation } |
172 | * |
173 | * Defines a test by name and the expected term signal. |
174 | * Names must be unique and tests must not be run in parallel. The |
175 | * implementation containing block is a function and scoping should be treated |
176 | * as such. Returning early may be performed with a bare "return;" statement. |
177 | * |
178 | * EXPECT_* and ASSERT_* are valid in a TEST() { } context. |
179 | */ |
180 | #define TEST_SIGNAL(test_name, signal) __TEST_IMPL(test_name, signal) |
181 | |
182 | #define __TEST_IMPL(test_name, _signal) \ |
183 | static void test_name(struct __test_metadata *_metadata); \ |
184 | static inline void wrapper_##test_name( \ |
185 | struct __test_metadata *_metadata, \ |
186 | struct __fixture_variant_metadata *variant) \ |
187 | { \ |
188 | _metadata->setup_completed = true; \ |
189 | if (setjmp(_metadata->env) == 0) \ |
190 | test_name(_metadata); \ |
191 | __test_check_assert(_metadata); \ |
192 | } \ |
193 | static struct __test_metadata _##test_name##_object = \ |
194 | { .name = #test_name, \ |
195 | .fn = &wrapper_##test_name, \ |
196 | .fixture = &_fixture_global, \ |
197 | .termsig = _signal, \ |
198 | .timeout = TEST_TIMEOUT_DEFAULT, }; \ |
199 | static void __attribute__((constructor)) _register_##test_name(void) \ |
200 | { \ |
201 | __register_test(&_##test_name##_object); \ |
202 | } \ |
203 | static void test_name( \ |
204 | struct __test_metadata __attribute__((unused)) *_metadata) |
205 | |
206 | /** |
207 | * FIXTURE_DATA() - Wraps the struct name so we have one less |
208 | * argument to pass around |
209 | * |
210 | * @datatype_name: datatype name |
211 | * |
212 | * .. code-block:: c |
213 | * |
214 | * FIXTURE_DATA(datatype_name) |
215 | * |
216 | * Almost always, you want just FIXTURE() instead (see below). |
217 | * This call may be used when the type of the fixture data |
218 | * is needed. In general, this should not be needed unless |
219 | * the *self* is being passed to a helper directly. |
220 | */ |
221 | #define FIXTURE_DATA(datatype_name) struct _test_data_##datatype_name |
222 | |
223 | /** |
224 | * FIXTURE() - Called once per fixture to setup the data and |
225 | * register |
226 | * |
227 | * @fixture_name: fixture name |
228 | * |
229 | * .. code-block:: c |
230 | * |
231 | * FIXTURE(fixture_name) { |
232 | * type property1; |
233 | * ... |
234 | * }; |
235 | * |
236 | * Defines the data provided to TEST_F()-defined tests as *self*. It should be |
237 | * populated and cleaned up using FIXTURE_SETUP() and FIXTURE_TEARDOWN(). |
238 | */ |
239 | #define FIXTURE(fixture_name) \ |
240 | FIXTURE_VARIANT(fixture_name); \ |
241 | static struct __fixture_metadata _##fixture_name##_fixture_object = \ |
242 | { .name = #fixture_name, }; \ |
243 | static void __attribute__((constructor)) \ |
244 | _register_##fixture_name##_data(void) \ |
245 | { \ |
246 | __register_fixture(&_##fixture_name##_fixture_object); \ |
247 | } \ |
248 | FIXTURE_DATA(fixture_name) |
249 | |
250 | /** |
251 | * FIXTURE_SETUP() - Prepares the setup function for the fixture. |
252 | * *_metadata* is included so that EXPECT_*, ASSERT_* etc. work correctly. |
253 | * |
254 | * @fixture_name: fixture name |
255 | * |
256 | * .. code-block:: c |
257 | * |
258 | * FIXTURE_SETUP(fixture_name) { implementation } |
259 | * |
260 | * Populates the required "setup" function for a fixture. An instance of the |
261 | * datatype defined with FIXTURE_DATA() will be exposed as *self* for the |
262 | * implementation. |
263 | * |
264 | * ASSERT_* are valid for use in this context and will prempt the execution |
265 | * of any dependent fixture tests. |
266 | * |
267 | * A bare "return;" statement may be used to return early. |
268 | */ |
269 | #define FIXTURE_SETUP(fixture_name) \ |
270 | void fixture_name##_setup( \ |
271 | struct __test_metadata __attribute__((unused)) *_metadata, \ |
272 | FIXTURE_DATA(fixture_name) __attribute__((unused)) *self, \ |
273 | const FIXTURE_VARIANT(fixture_name) \ |
274 | __attribute__((unused)) *variant) |
275 | |
276 | /** |
277 | * FIXTURE_TEARDOWN() |
278 | * *_metadata* is included so that EXPECT_*, ASSERT_* etc. work correctly. |
279 | * |
280 | * @fixture_name: fixture name |
281 | * |
282 | * .. code-block:: c |
283 | * |
284 | * FIXTURE_TEARDOWN(fixture_name) { implementation } |
285 | * |
286 | * Populates the required "teardown" function for a fixture. An instance of the |
287 | * datatype defined with FIXTURE_DATA() will be exposed as *self* for the |
288 | * implementation to clean up. |
289 | * |
290 | * A bare "return;" statement may be used to return early. |
291 | */ |
292 | #define FIXTURE_TEARDOWN(fixture_name) \ |
293 | void fixture_name##_teardown( \ |
294 | struct __test_metadata __attribute__((unused)) *_metadata, \ |
295 | FIXTURE_DATA(fixture_name) __attribute__((unused)) *self, \ |
296 | const FIXTURE_VARIANT(fixture_name) \ |
297 | __attribute__((unused)) *variant) |
298 | |
299 | /** |
300 | * FIXTURE_VARIANT() - Optionally called once per fixture |
301 | * to declare fixture variant |
302 | * |
303 | * @fixture_name: fixture name |
304 | * |
305 | * .. code-block:: c |
306 | * |
307 | * FIXTURE_VARIANT(fixture_name) { |
308 | * type property1; |
309 | * ... |
310 | * }; |
311 | * |
312 | * Defines type of constant parameters provided to FIXTURE_SETUP(), TEST_F() and |
313 | * FIXTURE_TEARDOWN as *variant*. Variants allow the same tests to be run with |
314 | * different arguments. |
315 | */ |
316 | #define FIXTURE_VARIANT(fixture_name) struct _fixture_variant_##fixture_name |
317 | |
318 | /** |
319 | * FIXTURE_VARIANT_ADD() - Called once per fixture |
320 | * variant to setup and register the data |
321 | * |
322 | * @fixture_name: fixture name |
323 | * @variant_name: name of the parameter set |
324 | * |
325 | * .. code-block:: c |
326 | * |
327 | * FIXTURE_VARIANT_ADD(fixture_name, variant_name) { |
328 | * .property1 = val1, |
329 | * ... |
330 | * }; |
331 | * |
332 | * Defines a variant of the test fixture, provided to FIXTURE_SETUP() and |
333 | * TEST_F() as *variant*. Tests of each fixture will be run once for each |
334 | * variant. |
335 | */ |
336 | #define FIXTURE_VARIANT_ADD(fixture_name, variant_name) \ |
337 | extern FIXTURE_VARIANT(fixture_name) \ |
338 | _##fixture_name##_##variant_name##_variant; \ |
339 | static struct __fixture_variant_metadata \ |
340 | _##fixture_name##_##variant_name##_object = \ |
341 | { .name = #variant_name, \ |
342 | .data = &_##fixture_name##_##variant_name##_variant}; \ |
343 | static void __attribute__((constructor)) \ |
344 | _register_##fixture_name##_##variant_name(void) \ |
345 | { \ |
346 | __register_fixture_variant(&_##fixture_name##_fixture_object, \ |
347 | &_##fixture_name##_##variant_name##_object); \ |
348 | } \ |
349 | FIXTURE_VARIANT(fixture_name) \ |
350 | _##fixture_name##_##variant_name##_variant = |
351 | |
352 | /** |
353 | * TEST_F() - Emits test registration and helpers for |
354 | * fixture-based test cases |
355 | * |
356 | * @fixture_name: fixture name |
357 | * @test_name: test name |
358 | * |
359 | * .. code-block:: c |
360 | * |
361 | * TEST_F(fixture, name) { implementation } |
362 | * |
363 | * Defines a test that depends on a fixture (e.g., is part of a test case). |
364 | * Very similar to TEST() except that *self* is the setup instance of fixture's |
365 | * datatype exposed for use by the implementation. |
366 | */ |
367 | #define TEST_F(fixture_name, test_name) \ |
368 | __TEST_F_IMPL(fixture_name, test_name, -1, TEST_TIMEOUT_DEFAULT) |
369 | |
370 | #define TEST_F_SIGNAL(fixture_name, test_name, signal) \ |
371 | __TEST_F_IMPL(fixture_name, test_name, signal, TEST_TIMEOUT_DEFAULT) |
372 | |
373 | #define TEST_F_TIMEOUT(fixture_name, test_name, timeout) \ |
374 | __TEST_F_IMPL(fixture_name, test_name, -1, timeout) |
375 | |
376 | #define __TEST_F_IMPL(fixture_name, test_name, signal, tmout) \ |
377 | static void fixture_name##_##test_name( \ |
378 | struct __test_metadata *_metadata, \ |
379 | FIXTURE_DATA(fixture_name) *self, \ |
380 | const FIXTURE_VARIANT(fixture_name) *variant); \ |
381 | static inline void wrapper_##fixture_name##_##test_name( \ |
382 | struct __test_metadata *_metadata, \ |
383 | struct __fixture_variant_metadata *variant) \ |
384 | { \ |
385 | /* fixture data is alloced, setup, and torn down per call. */ \ |
386 | FIXTURE_DATA(fixture_name) self; \ |
387 | memset(&self, 0, sizeof(FIXTURE_DATA(fixture_name))); \ |
388 | if (setjmp(_metadata->env) == 0) { \ |
389 | fixture_name##_setup(_metadata, &self, variant->data); \ |
390 | /* Let setup failure terminate early. */ \ |
391 | if (!_metadata->passed || _metadata->skip) \ |
392 | return; \ |
393 | _metadata->setup_completed = true; \ |
394 | fixture_name##_##test_name(_metadata, &self, variant->data); \ |
395 | } \ |
396 | if (_metadata->setup_completed) \ |
397 | fixture_name##_teardown(_metadata, &self, variant->data); \ |
398 | __test_check_assert(_metadata); \ |
399 | } \ |
400 | static struct __test_metadata \ |
401 | _##fixture_name##_##test_name##_object = { \ |
402 | .name = #test_name, \ |
403 | .fn = &wrapper_##fixture_name##_##test_name, \ |
404 | .fixture = &_##fixture_name##_fixture_object, \ |
405 | .termsig = signal, \ |
406 | .timeout = tmout, \ |
407 | }; \ |
408 | static void __attribute__((constructor)) \ |
409 | _register_##fixture_name##_##test_name(void) \ |
410 | { \ |
411 | __register_test(&_##fixture_name##_##test_name##_object); \ |
412 | } \ |
413 | static void fixture_name##_##test_name( \ |
414 | struct __test_metadata __attribute__((unused)) *_metadata, \ |
415 | FIXTURE_DATA(fixture_name) __attribute__((unused)) *self, \ |
416 | const FIXTURE_VARIANT(fixture_name) \ |
417 | __attribute__((unused)) *variant) |
418 | |
419 | /** |
420 | * TEST_HARNESS_MAIN - Simple wrapper to run the test harness |
421 | * |
422 | * .. code-block:: c |
423 | * |
424 | * TEST_HARNESS_MAIN |
425 | * |
426 | * Use once to append a main() to the test file. |
427 | */ |
428 | #define TEST_HARNESS_MAIN \ |
429 | static void __attribute__((constructor)) \ |
430 | __constructor_order_last(void) \ |
431 | { \ |
432 | if (!__constructor_order) \ |
433 | __constructor_order = _CONSTRUCTOR_ORDER_BACKWARD; \ |
434 | } \ |
435 | int main(int argc, char **argv) { \ |
436 | return test_harness_run(argc, argv); \ |
437 | } |
438 | |
439 | /** |
440 | * DOC: operators |
441 | * |
442 | * Operators for use in TEST() and TEST_F(). |
443 | * ASSERT_* calls will stop test execution immediately. |
444 | * EXPECT_* calls will emit a failure warning, note it, and continue. |
445 | */ |
446 | |
447 | /** |
448 | * ASSERT_EQ() |
449 | * |
450 | * @expected: expected value |
451 | * @seen: measured value |
452 | * |
453 | * ASSERT_EQ(expected, measured): expected == measured |
454 | */ |
455 | #define ASSERT_EQ(expected, seen) \ |
456 | __EXPECT(expected, #expected, seen, #seen, ==, 1) |
457 | |
458 | /** |
459 | * ASSERT_NE() |
460 | * |
461 | * @expected: expected value |
462 | * @seen: measured value |
463 | * |
464 | * ASSERT_NE(expected, measured): expected != measured |
465 | */ |
466 | #define ASSERT_NE(expected, seen) \ |
467 | __EXPECT(expected, #expected, seen, #seen, !=, 1) |
468 | |
469 | /** |
470 | * ASSERT_LT() |
471 | * |
472 | * @expected: expected value |
473 | * @seen: measured value |
474 | * |
475 | * ASSERT_LT(expected, measured): expected < measured |
476 | */ |
477 | #define ASSERT_LT(expected, seen) \ |
478 | __EXPECT(expected, #expected, seen, #seen, <, 1) |
479 | |
480 | /** |
481 | * ASSERT_LE() |
482 | * |
483 | * @expected: expected value |
484 | * @seen: measured value |
485 | * |
486 | * ASSERT_LE(expected, measured): expected <= measured |
487 | */ |
488 | #define ASSERT_LE(expected, seen) \ |
489 | __EXPECT(expected, #expected, seen, #seen, <=, 1) |
490 | |
491 | /** |
492 | * ASSERT_GT() |
493 | * |
494 | * @expected: expected value |
495 | * @seen: measured value |
496 | * |
497 | * ASSERT_GT(expected, measured): expected > measured |
498 | */ |
499 | #define ASSERT_GT(expected, seen) \ |
500 | __EXPECT(expected, #expected, seen, #seen, >, 1) |
501 | |
502 | /** |
503 | * ASSERT_GE() |
504 | * |
505 | * @expected: expected value |
506 | * @seen: measured value |
507 | * |
508 | * ASSERT_GE(expected, measured): expected >= measured |
509 | */ |
510 | #define ASSERT_GE(expected, seen) \ |
511 | __EXPECT(expected, #expected, seen, #seen, >=, 1) |
512 | |
513 | /** |
514 | * ASSERT_NULL() |
515 | * |
516 | * @seen: measured value |
517 | * |
518 | * ASSERT_NULL(measured): NULL == measured |
519 | */ |
520 | #define ASSERT_NULL(seen) \ |
521 | __EXPECT(NULL, "NULL", seen, #seen, ==, 1) |
522 | |
523 | /** |
524 | * ASSERT_TRUE() |
525 | * |
526 | * @seen: measured value |
527 | * |
528 | * ASSERT_TRUE(measured): measured != 0 |
529 | */ |
530 | #define ASSERT_TRUE(seen) \ |
531 | __EXPECT(0, "0", seen, #seen, !=, 1) |
532 | |
533 | /** |
534 | * ASSERT_FALSE() |
535 | * |
536 | * @seen: measured value |
537 | * |
538 | * ASSERT_FALSE(measured): measured == 0 |
539 | */ |
540 | #define ASSERT_FALSE(seen) \ |
541 | __EXPECT(0, "0", seen, #seen, ==, 1) |
542 | |
543 | /** |
544 | * ASSERT_STREQ() |
545 | * |
546 | * @expected: expected value |
547 | * @seen: measured value |
548 | * |
549 | * ASSERT_STREQ(expected, measured): !strcmp(expected, measured) |
550 | */ |
551 | #define ASSERT_STREQ(expected, seen) \ |
552 | __EXPECT_STR(expected, seen, ==, 1) |
553 | |
554 | /** |
555 | * ASSERT_STRNE() |
556 | * |
557 | * @expected: expected value |
558 | * @seen: measured value |
559 | * |
560 | * ASSERT_STRNE(expected, measured): strcmp(expected, measured) |
561 | */ |
562 | #define ASSERT_STRNE(expected, seen) \ |
563 | __EXPECT_STR(expected, seen, !=, 1) |
564 | |
565 | /** |
566 | * EXPECT_EQ() |
567 | * |
568 | * @expected: expected value |
569 | * @seen: measured value |
570 | * |
571 | * EXPECT_EQ(expected, measured): expected == measured |
572 | */ |
573 | #define EXPECT_EQ(expected, seen) \ |
574 | __EXPECT(expected, #expected, seen, #seen, ==, 0) |
575 | |
576 | /** |
577 | * EXPECT_NE() |
578 | * |
579 | * @expected: expected value |
580 | * @seen: measured value |
581 | * |
582 | * EXPECT_NE(expected, measured): expected != measured |
583 | */ |
584 | #define EXPECT_NE(expected, seen) \ |
585 | __EXPECT(expected, #expected, seen, #seen, !=, 0) |
586 | |
587 | /** |
588 | * EXPECT_LT() |
589 | * |
590 | * @expected: expected value |
591 | * @seen: measured value |
592 | * |
593 | * EXPECT_LT(expected, measured): expected < measured |
594 | */ |
595 | #define EXPECT_LT(expected, seen) \ |
596 | __EXPECT(expected, #expected, seen, #seen, <, 0) |
597 | |
598 | /** |
599 | * EXPECT_LE() |
600 | * |
601 | * @expected: expected value |
602 | * @seen: measured value |
603 | * |
604 | * EXPECT_LE(expected, measured): expected <= measured |
605 | */ |
606 | #define EXPECT_LE(expected, seen) \ |
607 | __EXPECT(expected, #expected, seen, #seen, <=, 0) |
608 | |
609 | /** |
610 | * EXPECT_GT() |
611 | * |
612 | * @expected: expected value |
613 | * @seen: measured value |
614 | * |
615 | * EXPECT_GT(expected, measured): expected > measured |
616 | */ |
617 | #define EXPECT_GT(expected, seen) \ |
618 | __EXPECT(expected, #expected, seen, #seen, >, 0) |
619 | |
620 | /** |
621 | * EXPECT_GE() |
622 | * |
623 | * @expected: expected value |
624 | * @seen: measured value |
625 | * |
626 | * EXPECT_GE(expected, measured): expected >= measured |
627 | */ |
628 | #define EXPECT_GE(expected, seen) \ |
629 | __EXPECT(expected, #expected, seen, #seen, >=, 0) |
630 | |
631 | /** |
632 | * EXPECT_NULL() |
633 | * |
634 | * @seen: measured value |
635 | * |
636 | * EXPECT_NULL(measured): NULL == measured |
637 | */ |
638 | #define EXPECT_NULL(seen) \ |
639 | __EXPECT(NULL, "NULL", seen, #seen, ==, 0) |
640 | |
641 | /** |
642 | * EXPECT_TRUE() |
643 | * |
644 | * @seen: measured value |
645 | * |
646 | * EXPECT_TRUE(measured): 0 != measured |
647 | */ |
648 | #define EXPECT_TRUE(seen) \ |
649 | __EXPECT(0, "0", seen, #seen, !=, 0) |
650 | |
651 | /** |
652 | * EXPECT_FALSE() |
653 | * |
654 | * @seen: measured value |
655 | * |
656 | * EXPECT_FALSE(measured): 0 == measured |
657 | */ |
658 | #define EXPECT_FALSE(seen) \ |
659 | __EXPECT(0, "0", seen, #seen, ==, 0) |
660 | |
661 | /** |
662 | * EXPECT_STREQ() |
663 | * |
664 | * @expected: expected value |
665 | * @seen: measured value |
666 | * |
667 | * EXPECT_STREQ(expected, measured): !strcmp(expected, measured) |
668 | */ |
669 | #define EXPECT_STREQ(expected, seen) \ |
670 | __EXPECT_STR(expected, seen, ==, 0) |
671 | |
672 | /** |
673 | * EXPECT_STRNE() |
674 | * |
675 | * @expected: expected value |
676 | * @seen: measured value |
677 | * |
678 | * EXPECT_STRNE(expected, measured): strcmp(expected, measured) |
679 | */ |
680 | #define EXPECT_STRNE(expected, seen) \ |
681 | __EXPECT_STR(expected, seen, !=, 0) |
682 | |
683 | #ifndef ARRAY_SIZE |
684 | #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) |
685 | #endif |
686 | |
687 | /* Support an optional handler after and ASSERT_* or EXPECT_*. The approach is |
688 | * not thread-safe, but it should be fine in most sane test scenarios. |
689 | * |
690 | * Using __bail(), which optionally abort()s, is the easiest way to early |
691 | * return while still providing an optional block to the API consumer. |
692 | */ |
693 | #define OPTIONAL_HANDLER(_assert) \ |
694 | for (; _metadata->trigger; _metadata->trigger = \ |
695 | __bail(_assert, _metadata)) |
696 | |
697 | #define __INC_STEP(_metadata) \ |
698 | /* Keep "step" below 255 (which is used for "SKIP" reporting). */ \ |
699 | if (_metadata->passed && _metadata->step < 253) \ |
700 | _metadata->step++; |
701 | |
702 | #define is_signed_type(var) (!!(((__typeof__(var))(-1)) < (__typeof__(var))1)) |
703 | |
704 | #define __EXPECT(_expected, _expected_str, _seen, _seen_str, _t, _assert) do { \ |
705 | /* Avoid multiple evaluation of the cases */ \ |
706 | __typeof__(_expected) __exp = (_expected); \ |
707 | __typeof__(_seen) __seen = (_seen); \ |
708 | if (_assert) __INC_STEP(_metadata); \ |
709 | if (!(__exp _t __seen)) { \ |
710 | /* Report with actual signedness to avoid weird output. */ \ |
711 | switch (is_signed_type(__exp) * 2 + is_signed_type(__seen)) { \ |
712 | case 0: { \ |
713 | unsigned long long __exp_print = (uintptr_t)__exp; \ |
714 | unsigned long long __seen_print = (uintptr_t)__seen; \ |
715 | __TH_LOG("Expected %s (%llu) %s %s (%llu)", \ |
716 | _expected_str, __exp_print, #_t, \ |
717 | _seen_str, __seen_print); \ |
718 | break; \ |
719 | } \ |
720 | case 1: { \ |
721 | unsigned long long __exp_print = (uintptr_t)__exp; \ |
722 | long long __seen_print = (intptr_t)__seen; \ |
723 | __TH_LOG("Expected %s (%llu) %s %s (%lld)", \ |
724 | _expected_str, __exp_print, #_t, \ |
725 | _seen_str, __seen_print); \ |
726 | break; \ |
727 | } \ |
728 | case 2: { \ |
729 | long long __exp_print = (intptr_t)__exp; \ |
730 | unsigned long long __seen_print = (uintptr_t)__seen; \ |
731 | __TH_LOG("Expected %s (%lld) %s %s (%llu)", \ |
732 | _expected_str, __exp_print, #_t, \ |
733 | _seen_str, __seen_print); \ |
734 | break; \ |
735 | } \ |
736 | case 3: { \ |
737 | long long __exp_print = (intptr_t)__exp; \ |
738 | long long __seen_print = (intptr_t)__seen; \ |
739 | __TH_LOG("Expected %s (%lld) %s %s (%lld)", \ |
740 | _expected_str, __exp_print, #_t, \ |
741 | _seen_str, __seen_print); \ |
742 | break; \ |
743 | } \ |
744 | } \ |
745 | _metadata->passed = 0; \ |
746 | /* Ensure the optional handler is triggered */ \ |
747 | _metadata->trigger = 1; \ |
748 | } \ |
749 | } while (0); OPTIONAL_HANDLER(_assert) |
750 | |
751 | #define __EXPECT_STR(_expected, _seen, _t, _assert) do { \ |
752 | const char *__exp = (_expected); \ |
753 | const char *__seen = (_seen); \ |
754 | if (_assert) __INC_STEP(_metadata); \ |
755 | if (!(strcmp(__exp, __seen) _t 0)) { \ |
756 | __TH_LOG("Expected '%s' %s '%s'.", __exp, #_t, __seen); \ |
757 | _metadata->passed = 0; \ |
758 | _metadata->trigger = 1; \ |
759 | } \ |
760 | } while (0); OPTIONAL_HANDLER(_assert) |
761 | |
762 | /* List helpers */ |
763 | #define __LIST_APPEND(head, item) \ |
764 | { \ |
765 | /* Circular linked list where only prev is circular. */ \ |
766 | if (head == NULL) { \ |
767 | head = item; \ |
768 | item->next = NULL; \ |
769 | item->prev = item; \ |
770 | return; \ |
771 | } \ |
772 | if (__constructor_order == _CONSTRUCTOR_ORDER_FORWARD) { \ |
773 | item->next = NULL; \ |
774 | item->prev = head->prev; \ |
775 | item->prev->next = item; \ |
776 | head->prev = item; \ |
777 | } else { \ |
778 | item->next = head; \ |
779 | item->next->prev = item; \ |
780 | item->prev = item; \ |
781 | head = item; \ |
782 | } \ |
783 | } |
784 | |
785 | struct __test_results { |
786 | char reason[1024]; /* Reason for test result */ |
787 | }; |
788 | |
789 | struct __test_metadata; |
790 | struct __fixture_variant_metadata; |
791 | |
792 | /* Contains all the information about a fixture. */ |
793 | struct __fixture_metadata { |
794 | const char *name; |
795 | struct __test_metadata *tests; |
796 | struct __fixture_variant_metadata *variant; |
797 | struct __fixture_metadata *prev, *next; |
798 | } _fixture_global __attribute__((unused)) = { |
799 | .name = "global" , |
800 | .prev = &_fixture_global, |
801 | }; |
802 | |
803 | static struct __fixture_metadata *__fixture_list = &_fixture_global; |
804 | static int __constructor_order; |
805 | |
806 | #define _CONSTRUCTOR_ORDER_FORWARD 1 |
807 | #define _CONSTRUCTOR_ORDER_BACKWARD -1 |
808 | |
809 | static inline void __register_fixture(struct __fixture_metadata *f) |
810 | { |
811 | __LIST_APPEND(__fixture_list, f); |
812 | } |
813 | |
814 | struct __fixture_variant_metadata { |
815 | const char *name; |
816 | const void *data; |
817 | struct __fixture_variant_metadata *prev, *next; |
818 | }; |
819 | |
820 | static inline void |
821 | __register_fixture_variant(struct __fixture_metadata *f, |
822 | struct __fixture_variant_metadata *variant) |
823 | { |
824 | __LIST_APPEND(f->variant, variant); |
825 | } |
826 | |
827 | /* Contains all the information for test execution and status checking. */ |
828 | struct __test_metadata { |
829 | const char *name; |
830 | void (*fn)(struct __test_metadata *, |
831 | struct __fixture_variant_metadata *); |
832 | pid_t pid; /* pid of test when being run */ |
833 | struct __fixture_metadata *fixture; |
834 | int termsig; |
835 | int passed; |
836 | int skip; /* did SKIP get used? */ |
837 | int trigger; /* extra handler after the evaluation */ |
838 | int timeout; /* seconds to wait for test timeout */ |
839 | bool timed_out; /* did this test timeout instead of exiting? */ |
840 | __u8 step; |
841 | bool no_print; /* manual trigger when TH_LOG_STREAM is not available */ |
842 | bool aborted; /* stopped test due to failed ASSERT */ |
843 | bool setup_completed; /* did setup finish? */ |
844 | jmp_buf env; /* for exiting out of test early */ |
845 | struct __test_results *results; |
846 | struct __test_metadata *prev, *next; |
847 | }; |
848 | |
849 | /* |
850 | * Since constructors are called in reverse order, reverse the test |
851 | * list so tests are run in source declaration order. |
852 | * https://gcc.gnu.org/onlinedocs/gccint/Initialization.html |
853 | * However, it seems not all toolchains do this correctly, so use |
854 | * __constructor_order to detect which direction is called first |
855 | * and adjust list building logic to get things running in the right |
856 | * direction. |
857 | */ |
858 | static inline void __register_test(struct __test_metadata *t) |
859 | { |
860 | __LIST_APPEND(t->fixture->tests, t); |
861 | } |
862 | |
863 | static inline int __bail(int for_realz, struct __test_metadata *t) |
864 | { |
865 | /* if this is ASSERT, return immediately. */ |
866 | if (for_realz) { |
867 | t->aborted = true; |
868 | longjmp(t->env, 1); |
869 | } |
870 | /* otherwise, end the for loop and continue. */ |
871 | return 0; |
872 | } |
873 | |
874 | static inline void __test_check_assert(struct __test_metadata *t) |
875 | { |
876 | if (t->aborted) { |
877 | if (t->no_print) |
878 | _exit(t->step); |
879 | abort(); |
880 | } |
881 | } |
882 | |
883 | struct __test_metadata *__active_test; |
884 | static void __timeout_handler(int sig, siginfo_t *info, void *ucontext) |
885 | { |
886 | struct __test_metadata *t = __active_test; |
887 | |
888 | /* Sanity check handler execution environment. */ |
889 | if (!t) { |
890 | fprintf(TH_LOG_STREAM, |
891 | "# no active test in SIGALRM handler!?\n" ); |
892 | abort(); |
893 | } |
894 | if (sig != SIGALRM || sig != info->si_signo) { |
895 | fprintf(TH_LOG_STREAM, |
896 | "# %s: SIGALRM handler caught signal %d!?\n" , |
897 | t->name, sig != SIGALRM ? sig : info->si_signo); |
898 | abort(); |
899 | } |
900 | |
901 | t->timed_out = true; |
902 | // signal process group |
903 | kill(-(t->pid), SIGKILL); |
904 | } |
905 | |
906 | void __wait_for_test(struct __test_metadata *t) |
907 | { |
908 | struct sigaction action = { |
909 | .sa_sigaction = __timeout_handler, |
910 | .sa_flags = SA_SIGINFO, |
911 | }; |
912 | struct sigaction saved_action; |
913 | int status; |
914 | |
915 | if (sigaction(SIGALRM, &action, &saved_action)) { |
916 | t->passed = 0; |
917 | fprintf(TH_LOG_STREAM, |
918 | "# %s: unable to install SIGALRM handler\n" , |
919 | t->name); |
920 | return; |
921 | } |
922 | __active_test = t; |
923 | t->timed_out = false; |
924 | alarm(t->timeout); |
925 | waitpid(t->pid, &status, 0); |
926 | alarm(0); |
927 | if (sigaction(SIGALRM, &saved_action, NULL)) { |
928 | t->passed = 0; |
929 | fprintf(TH_LOG_STREAM, |
930 | "# %s: unable to uninstall SIGALRM handler\n" , |
931 | t->name); |
932 | return; |
933 | } |
934 | __active_test = NULL; |
935 | |
936 | if (t->timed_out) { |
937 | t->passed = 0; |
938 | fprintf(TH_LOG_STREAM, |
939 | "# %s: Test terminated by timeout\n" , t->name); |
940 | } else if (WIFEXITED(status)) { |
941 | if (WEXITSTATUS(status) == 255) { |
942 | /* SKIP */ |
943 | t->passed = 1; |
944 | t->skip = 1; |
945 | } else if (t->termsig != -1) { |
946 | t->passed = 0; |
947 | fprintf(TH_LOG_STREAM, |
948 | "# %s: Test exited normally instead of by signal (code: %d)\n" , |
949 | t->name, |
950 | WEXITSTATUS(status)); |
951 | } else { |
952 | switch (WEXITSTATUS(status)) { |
953 | /* Success */ |
954 | case 0: |
955 | t->passed = 1; |
956 | break; |
957 | /* Other failure, assume step report. */ |
958 | default: |
959 | t->passed = 0; |
960 | fprintf(TH_LOG_STREAM, |
961 | "# %s: Test failed at step #%d\n" , |
962 | t->name, |
963 | WEXITSTATUS(status)); |
964 | } |
965 | } |
966 | } else if (WIFSIGNALED(status)) { |
967 | t->passed = 0; |
968 | if (WTERMSIG(status) == SIGABRT) { |
969 | fprintf(TH_LOG_STREAM, |
970 | "# %s: Test terminated by assertion\n" , |
971 | t->name); |
972 | } else if (WTERMSIG(status) == t->termsig) { |
973 | t->passed = 1; |
974 | } else { |
975 | fprintf(TH_LOG_STREAM, |
976 | "# %s: Test terminated unexpectedly by signal %d\n" , |
977 | t->name, |
978 | WTERMSIG(status)); |
979 | } |
980 | } else { |
981 | fprintf(TH_LOG_STREAM, |
982 | "# %s: Test ended in some other way [%u]\n" , |
983 | t->name, |
984 | status); |
985 | } |
986 | } |
987 | |
988 | static void test_harness_list_tests(void) |
989 | { |
990 | struct __fixture_variant_metadata *v; |
991 | struct __fixture_metadata *f; |
992 | struct __test_metadata *t; |
993 | |
994 | for (f = __fixture_list; f; f = f->next) { |
995 | v = f->variant; |
996 | t = f->tests; |
997 | |
998 | if (f == __fixture_list) |
999 | fprintf(stderr, "%-20s %-25s %s\n" , |
1000 | "# FIXTURE" , "VARIANT" , "TEST" ); |
1001 | else |
1002 | fprintf(stderr, "--------------------------------------------------------------------------------\n" ); |
1003 | |
1004 | do { |
1005 | fprintf(stderr, "%-20s %-25s %s\n" , |
1006 | t == f->tests ? f->name : "" , |
1007 | v ? v->name : "" , |
1008 | t ? t->name : "" ); |
1009 | |
1010 | v = v ? v->next : NULL; |
1011 | t = t ? t->next : NULL; |
1012 | } while (v || t); |
1013 | } |
1014 | } |
1015 | |
1016 | static int test_harness_argv_check(int argc, char **argv) |
1017 | { |
1018 | int opt; |
1019 | |
1020 | while ((opt = getopt(argc, argv, "hlF:f:V:v:t:T:r:" )) != -1) { |
1021 | switch (opt) { |
1022 | case 'f': |
1023 | case 'F': |
1024 | case 'v': |
1025 | case 'V': |
1026 | case 't': |
1027 | case 'T': |
1028 | case 'r': |
1029 | break; |
1030 | case 'l': |
1031 | test_harness_list_tests(); |
1032 | return KSFT_SKIP; |
1033 | case 'h': |
1034 | default: |
1035 | fprintf(stderr, |
1036 | "Usage: %s [-h|-l] [-t|-T|-v|-V|-f|-F|-r name]\n" |
1037 | "\t-h print help\n" |
1038 | "\t-l list all tests\n" |
1039 | "\n" |
1040 | "\t-t name include test\n" |
1041 | "\t-T name exclude test\n" |
1042 | "\t-v name include variant\n" |
1043 | "\t-V name exclude variant\n" |
1044 | "\t-f name include fixture\n" |
1045 | "\t-F name exclude fixture\n" |
1046 | "\t-r name run specified test\n" |
1047 | "\n" |
1048 | "Test filter options can be specified " |
1049 | "multiple times. The filtering stops\n" |
1050 | "at the first match. For example to " |
1051 | "include all tests from variant 'bla'\n" |
1052 | "but not test 'foo' specify '-T foo -v bla'.\n" |
1053 | "" , argv[0]); |
1054 | return opt == 'h' ? KSFT_SKIP : KSFT_FAIL; |
1055 | } |
1056 | } |
1057 | |
1058 | return KSFT_PASS; |
1059 | } |
1060 | |
1061 | static bool test_enabled(int argc, char **argv, |
1062 | struct __fixture_metadata *f, |
1063 | struct __fixture_variant_metadata *v, |
1064 | struct __test_metadata *t) |
1065 | { |
1066 | unsigned int flen = 0, vlen = 0, tlen = 0; |
1067 | bool has_positive = false; |
1068 | int opt; |
1069 | |
1070 | optind = 1; |
1071 | while ((opt = getopt(argc, argv, "F:f:V:v:t:T:r:" )) != -1) { |
1072 | has_positive |= islower(opt); |
1073 | |
1074 | switch (tolower(opt)) { |
1075 | case 't': |
1076 | if (!strcmp(t->name, optarg)) |
1077 | return islower(opt); |
1078 | break; |
1079 | case 'f': |
1080 | if (!strcmp(f->name, optarg)) |
1081 | return islower(opt); |
1082 | break; |
1083 | case 'v': |
1084 | if (!strcmp(v->name, optarg)) |
1085 | return islower(opt); |
1086 | break; |
1087 | case 'r': |
1088 | if (!tlen) { |
1089 | flen = strlen(f->name); |
1090 | vlen = strlen(v->name); |
1091 | tlen = strlen(t->name); |
1092 | } |
1093 | if (strlen(optarg) == flen + 1 + vlen + !!vlen + tlen && |
1094 | !strncmp(f->name, &optarg[0], flen) && |
1095 | !strncmp(v->name, &optarg[flen + 1], vlen) && |
1096 | !strncmp(t->name, &optarg[flen + 1 + vlen + !!vlen], tlen)) |
1097 | return true; |
1098 | break; |
1099 | } |
1100 | } |
1101 | |
1102 | /* |
1103 | * If there are no positive tests then we assume user just wants |
1104 | * exclusions and everything else is a pass. |
1105 | */ |
1106 | return !has_positive; |
1107 | } |
1108 | |
1109 | void __run_test(struct __fixture_metadata *f, |
1110 | struct __fixture_variant_metadata *variant, |
1111 | struct __test_metadata *t) |
1112 | { |
1113 | /* reset test struct */ |
1114 | t->passed = 1; |
1115 | t->skip = 0; |
1116 | t->trigger = 0; |
1117 | t->step = 1; |
1118 | t->no_print = 0; |
1119 | memset(t->results->reason, 0, sizeof(t->results->reason)); |
1120 | |
1121 | ksft_print_msg(msg: " RUN %s%s%s.%s ...\n" , |
1122 | f->name, variant->name[0] ? "." : "" , variant->name, t->name); |
1123 | |
1124 | /* Make sure output buffers are flushed before fork */ |
1125 | fflush(stdout); |
1126 | fflush(stderr); |
1127 | |
1128 | t->pid = fork(); |
1129 | if (t->pid < 0) { |
1130 | ksft_print_msg(msg: "ERROR SPAWNING TEST CHILD\n" ); |
1131 | t->passed = 0; |
1132 | } else if (t->pid == 0) { |
1133 | setpgrp(); |
1134 | t->fn(t, variant); |
1135 | if (t->skip) |
1136 | _exit(255); |
1137 | /* Pass is exit 0 */ |
1138 | if (t->passed) |
1139 | _exit(0); |
1140 | /* Something else happened, report the step. */ |
1141 | _exit(t->step); |
1142 | } else { |
1143 | __wait_for_test(t); |
1144 | } |
1145 | ksft_print_msg(msg: " %4s %s%s%s.%s\n" , t->passed ? "OK" : "FAIL" , |
1146 | f->name, variant->name[0] ? "." : "" , variant->name, t->name); |
1147 | |
1148 | if (t->skip) |
1149 | ksft_test_result_skip(msg: "%s\n" , t->results->reason[0] ? |
1150 | t->results->reason : "unknown" ); |
1151 | else |
1152 | ksft_test_result(t->passed, "%s%s%s.%s\n" , |
1153 | f->name, variant->name[0] ? "." : "" , variant->name, t->name); |
1154 | } |
1155 | |
1156 | static int test_harness_run(int argc, char **argv) |
1157 | { |
1158 | struct __fixture_variant_metadata no_variant = { .name = "" , }; |
1159 | struct __fixture_variant_metadata *v; |
1160 | struct __fixture_metadata *f; |
1161 | struct __test_results *results; |
1162 | struct __test_metadata *t; |
1163 | int ret; |
1164 | unsigned int case_count = 0, test_count = 0; |
1165 | unsigned int count = 0; |
1166 | unsigned int pass_count = 0; |
1167 | |
1168 | ret = test_harness_argv_check(argc, argv); |
1169 | if (ret != KSFT_PASS) |
1170 | return ret; |
1171 | |
1172 | for (f = __fixture_list; f; f = f->next) { |
1173 | for (v = f->variant ?: &no_variant; v; v = v->next) { |
1174 | unsigned int old_tests = test_count; |
1175 | |
1176 | for (t = f->tests; t; t = t->next) |
1177 | if (test_enabled(argc, argv, f, v, t)) |
1178 | test_count++; |
1179 | |
1180 | if (old_tests != test_count) |
1181 | case_count++; |
1182 | } |
1183 | } |
1184 | |
1185 | results = mmap(NULL, sizeof(*results), PROT_READ | PROT_WRITE, |
1186 | MAP_SHARED | MAP_ANONYMOUS, -1, 0); |
1187 | |
1188 | ksft_print_header(); |
1189 | ksft_set_plan(plan: test_count); |
1190 | ksft_print_msg(msg: "Starting %u tests from %u test cases.\n" , |
1191 | test_count, case_count); |
1192 | for (f = __fixture_list; f; f = f->next) { |
1193 | for (v = f->variant ?: &no_variant; v; v = v->next) { |
1194 | for (t = f->tests; t; t = t->next) { |
1195 | if (!test_enabled(argc, argv, f, v, t)) |
1196 | continue; |
1197 | count++; |
1198 | t->results = results; |
1199 | __run_test(f, variant: v, t); |
1200 | t->results = NULL; |
1201 | if (t->passed) |
1202 | pass_count++; |
1203 | else |
1204 | ret = 1; |
1205 | } |
1206 | } |
1207 | } |
1208 | munmap(results, sizeof(*results)); |
1209 | |
1210 | ksft_print_msg(msg: "%s: %u / %u tests passed.\n" , ret ? "FAILED" : "PASSED" , |
1211 | pass_count, count); |
1212 | ksft_exit(ret == 0); |
1213 | |
1214 | /* unreachable */ |
1215 | return KSFT_FAIL; |
1216 | } |
1217 | |
1218 | static void __attribute__((constructor)) __constructor_order_first(void) |
1219 | { |
1220 | if (!__constructor_order) |
1221 | __constructor_order = _CONSTRUCTOR_ORDER_FORWARD; |
1222 | } |
1223 | |
1224 | #endif /* __KSELFTEST_HARNESS_H */ |
1225 | |