This source file includes following definitions.
- __register_test
- __bail
- __run_test
- test_harness_run
- __constructor_order_first
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50 #ifndef __KSELFTEST_HARNESS_H
51 #define __KSELFTEST_HARNESS_H
52
53 #define _GNU_SOURCE
54 #include <asm/types.h>
55 #include <errno.h>
56 #include <stdbool.h>
57 #include <stdint.h>
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
65 #define TEST_TIMEOUT_DEFAULT 30
66
67
68 #ifndef TH_LOG_STREAM
69 # define TH_LOG_STREAM stderr
70 #endif
71
72 #ifndef TH_LOG_ENABLED
73 # define TH_LOG_ENABLED 1
74 #endif
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100 #define TH_LOG(fmt, ...) do { \
101 if (TH_LOG_ENABLED) \
102 __TH_LOG(fmt, ##__VA_ARGS__); \
103 } while (0)
104
105
106 #define __TH_LOG(fmt, ...) \
107 fprintf(TH_LOG_STREAM, "%s:%d:%s:" fmt "\n", \
108 __FILE__, __LINE__, _metadata->name, ##__VA_ARGS__)
109
110
111
112
113
114
115
116
117
118
119
120 #define XFAIL(statement, fmt, ...) do { \
121 if (TH_LOG_ENABLED) { \
122 fprintf(TH_LOG_STREAM, "[ XFAIL! ] " fmt "\n", \
123 ##__VA_ARGS__); \
124 } \
125 \
126 _metadata->passed = 1; \
127 _metadata->trigger = 0; \
128 statement; \
129 } while (0)
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148 #define TEST(test_name) __TEST_IMPL(test_name, -1)
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167 #define TEST_SIGNAL(test_name, signal) __TEST_IMPL(test_name, signal)
168
169 #define __TEST_IMPL(test_name, _signal) \
170 static void test_name(struct __test_metadata *_metadata); \
171 static struct __test_metadata _##test_name##_object = \
172 { .name = "global." #test_name, \
173 .fn = &test_name, .termsig = _signal, \
174 .timeout = TEST_TIMEOUT_DEFAULT, }; \
175 static void __attribute__((constructor)) _register_##test_name(void) \
176 { \
177 __register_test(&_##test_name##_object); \
178 } \
179 static void test_name( \
180 struct __test_metadata __attribute__((unused)) *_metadata)
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196 #define FIXTURE_DATA(datatype_name) struct _test_data_##datatype_name
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214 #define FIXTURE(fixture_name) \
215 static void __attribute__((constructor)) \
216 _register_##fixture_name##_data(void) \
217 { \
218 __fixture_count++; \
219 } \
220 FIXTURE_DATA(fixture_name)
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241 #define FIXTURE_SETUP(fixture_name) \
242 void fixture_name##_setup( \
243 struct __test_metadata __attribute__((unused)) *_metadata, \
244 FIXTURE_DATA(fixture_name) __attribute__((unused)) *self)
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261 #define FIXTURE_TEARDOWN(fixture_name) \
262 void fixture_name##_teardown( \
263 struct __test_metadata __attribute__((unused)) *_metadata, \
264 FIXTURE_DATA(fixture_name) __attribute__((unused)) *self)
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284 #define TEST_F(fixture_name, test_name) \
285 __TEST_F_IMPL(fixture_name, test_name, -1, TEST_TIMEOUT_DEFAULT)
286
287 #define TEST_F_SIGNAL(fixture_name, test_name, signal) \
288 __TEST_F_IMPL(fixture_name, test_name, signal, TEST_TIMEOUT_DEFAULT)
289
290 #define TEST_F_TIMEOUT(fixture_name, test_name, timeout) \
291 __TEST_F_IMPL(fixture_name, test_name, -1, timeout)
292
293 #define __TEST_F_IMPL(fixture_name, test_name, signal, tmout) \
294 static void fixture_name##_##test_name( \
295 struct __test_metadata *_metadata, \
296 FIXTURE_DATA(fixture_name) *self); \
297 static inline void wrapper_##fixture_name##_##test_name( \
298 struct __test_metadata *_metadata) \
299 { \
300 \
301 FIXTURE_DATA(fixture_name) self; \
302 memset(&self, 0, sizeof(FIXTURE_DATA(fixture_name))); \
303 fixture_name##_setup(_metadata, &self); \
304 \
305 if (!_metadata->passed) \
306 return; \
307 fixture_name##_##test_name(_metadata, &self); \
308 fixture_name##_teardown(_metadata, &self); \
309 } \
310 static struct __test_metadata \
311 _##fixture_name##_##test_name##_object = { \
312 .name = #fixture_name "." #test_name, \
313 .fn = &wrapper_##fixture_name##_##test_name, \
314 .termsig = signal, \
315 .timeout = tmout, \
316 }; \
317 static void __attribute__((constructor)) \
318 _register_##fixture_name##_##test_name(void) \
319 { \
320 __register_test(&_##fixture_name##_##test_name##_object); \
321 } \
322 static void fixture_name##_##test_name( \
323 struct __test_metadata __attribute__((unused)) *_metadata, \
324 FIXTURE_DATA(fixture_name) __attribute__((unused)) *self)
325
326
327
328
329
330
331
332
333
334
335 #define TEST_HARNESS_MAIN \
336 static void __attribute__((constructor)) \
337 __constructor_order_last(void) \
338 { \
339 if (!__constructor_order) \
340 __constructor_order = _CONSTRUCTOR_ORDER_BACKWARD; \
341 } \
342 int main(int argc, char **argv) { \
343 return test_harness_run(argc, argv); \
344 }
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362 #define ASSERT_EQ(expected, seen) \
363 __EXPECT(expected, #expected, seen, #seen, ==, 1)
364
365
366
367
368
369
370
371
372
373 #define ASSERT_NE(expected, seen) \
374 __EXPECT(expected, #expected, seen, #seen, !=, 1)
375
376
377
378
379
380
381
382
383
384 #define ASSERT_LT(expected, seen) \
385 __EXPECT(expected, #expected, seen, #seen, <, 1)
386
387
388
389
390
391
392
393
394
395 #define ASSERT_LE(expected, seen) \
396 __EXPECT(expected, #expected, seen, #seen, <=, 1)
397
398
399
400
401
402
403
404
405
406 #define ASSERT_GT(expected, seen) \
407 __EXPECT(expected, #expected, seen, #seen, >, 1)
408
409
410
411
412
413
414
415
416
417 #define ASSERT_GE(expected, seen) \
418 __EXPECT(expected, #expected, seen, #seen, >=, 1)
419
420
421
422
423
424
425
426
427 #define ASSERT_NULL(seen) \
428 __EXPECT(NULL, "NULL", seen, #seen, ==, 1)
429
430
431
432
433
434
435
436
437 #define ASSERT_TRUE(seen) \
438 __EXPECT(0, "0", seen, #seen, !=, 1)
439
440
441
442
443
444
445
446
447 #define ASSERT_FALSE(seen) \
448 __EXPECT(0, "0", seen, #seen, ==, 1)
449
450
451
452
453
454
455
456
457
458 #define ASSERT_STREQ(expected, seen) \
459 __EXPECT_STR(expected, seen, ==, 1)
460
461
462
463
464
465
466
467
468
469 #define ASSERT_STRNE(expected, seen) \
470 __EXPECT_STR(expected, seen, !=, 1)
471
472
473
474
475
476
477
478
479
480 #define EXPECT_EQ(expected, seen) \
481 __EXPECT(expected, #expected, seen, #seen, ==, 0)
482
483
484
485
486
487
488
489
490
491 #define EXPECT_NE(expected, seen) \
492 __EXPECT(expected, #expected, seen, #seen, !=, 0)
493
494
495
496
497
498
499
500
501
502 #define EXPECT_LT(expected, seen) \
503 __EXPECT(expected, #expected, seen, #seen, <, 0)
504
505
506
507
508
509
510
511
512
513 #define EXPECT_LE(expected, seen) \
514 __EXPECT(expected, #expected, seen, #seen, <=, 0)
515
516
517
518
519
520
521
522
523
524 #define EXPECT_GT(expected, seen) \
525 __EXPECT(expected, #expected, seen, #seen, >, 0)
526
527
528
529
530
531
532
533
534
535 #define EXPECT_GE(expected, seen) \
536 __EXPECT(expected, #expected, seen, #seen, >=, 0)
537
538
539
540
541
542
543
544
545 #define EXPECT_NULL(seen) \
546 __EXPECT(NULL, "NULL", seen, #seen, ==, 0)
547
548
549
550
551
552
553
554
555 #define EXPECT_TRUE(seen) \
556 __EXPECT(0, "0", seen, #seen, !=, 0)
557
558
559
560
561
562
563
564
565 #define EXPECT_FALSE(seen) \
566 __EXPECT(0, "0", seen, #seen, ==, 0)
567
568
569
570
571
572
573
574
575
576 #define EXPECT_STREQ(expected, seen) \
577 __EXPECT_STR(expected, seen, ==, 0)
578
579
580
581
582
583
584
585
586
587 #define EXPECT_STRNE(expected, seen) \
588 __EXPECT_STR(expected, seen, !=, 0)
589
590 #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
591
592
593
594
595
596
597
598 #define OPTIONAL_HANDLER(_assert) \
599 for (; _metadata->trigger; _metadata->trigger = \
600 __bail(_assert, _metadata->no_print, _metadata->step))
601
602 #define __INC_STEP(_metadata) \
603 if (_metadata->passed && _metadata->step < 255) \
604 _metadata->step++;
605
606 #define __EXPECT(_expected, _expected_str, _seen, _seen_str, _t, _assert) do { \
607 \
608 __typeof__(_expected) __exp = (_expected); \
609 __typeof__(_seen) __seen = (_seen); \
610 if (_assert) __INC_STEP(_metadata); \
611 if (!(__exp _t __seen)) { \
612 unsigned long long __exp_print = (uintptr_t)__exp; \
613 unsigned long long __seen_print = (uintptr_t)__seen; \
614 __TH_LOG("Expected %s (%llu) %s %s (%llu)", \
615 _expected_str, __exp_print, #_t, \
616 _seen_str, __seen_print); \
617 _metadata->passed = 0; \
618 \
619 _metadata->trigger = 1; \
620 } \
621 } while (0); OPTIONAL_HANDLER(_assert)
622
623 #define __EXPECT_STR(_expected, _seen, _t, _assert) do { \
624 const char *__exp = (_expected); \
625 const char *__seen = (_seen); \
626 if (_assert) __INC_STEP(_metadata); \
627 if (!(strcmp(__exp, __seen) _t 0)) { \
628 __TH_LOG("Expected '%s' %s '%s'.", __exp, #_t, __seen); \
629 _metadata->passed = 0; \
630 _metadata->trigger = 1; \
631 } \
632 } while (0); OPTIONAL_HANDLER(_assert)
633
634
635 struct __test_metadata {
636 const char *name;
637 void (*fn)(struct __test_metadata *);
638 int termsig;
639 int passed;
640 int trigger;
641 int timeout;
642 __u8 step;
643 bool no_print;
644 struct __test_metadata *prev, *next;
645 };
646
647
648 static struct __test_metadata *__test_list;
649 static unsigned int __test_count;
650 static unsigned int __fixture_count;
651 static int __constructor_order;
652
653 #define _CONSTRUCTOR_ORDER_FORWARD 1
654 #define _CONSTRUCTOR_ORDER_BACKWARD -1
655
656
657
658
659
660
661
662
663
664
665 static inline void __register_test(struct __test_metadata *t)
666 {
667 __test_count++;
668
669 if (__test_list == NULL) {
670 __test_list = t;
671 t->next = NULL;
672 t->prev = t;
673 return;
674 }
675 if (__constructor_order == _CONSTRUCTOR_ORDER_FORWARD) {
676 t->next = NULL;
677 t->prev = __test_list->prev;
678 t->prev->next = t;
679 __test_list->prev = t;
680 } else {
681 t->next = __test_list;
682 t->next->prev = t;
683 t->prev = t;
684 __test_list = t;
685 }
686 }
687
688 static inline int __bail(int for_realz, bool no_print, __u8 step)
689 {
690 if (for_realz) {
691 if (no_print)
692 _exit(step);
693 abort();
694 }
695 return 0;
696 }
697
698 void __run_test(struct __test_metadata *t)
699 {
700 pid_t child_pid;
701 int status;
702
703 t->passed = 1;
704 t->trigger = 0;
705 printf("[ RUN ] %s\n", t->name);
706 alarm(t->timeout);
707 child_pid = fork();
708 if (child_pid < 0) {
709 printf("ERROR SPAWNING TEST CHILD\n");
710 t->passed = 0;
711 } else if (child_pid == 0) {
712 t->fn(t);
713
714 _exit(t->passed ? 0 : t->step);
715 } else {
716
717 waitpid(child_pid, &status, 0);
718 if (WIFEXITED(status)) {
719 t->passed = t->termsig == -1 ? !WEXITSTATUS(status) : 0;
720 if (t->termsig != -1) {
721 fprintf(TH_LOG_STREAM,
722 "%s: Test exited normally "
723 "instead of by signal (code: %d)\n",
724 t->name,
725 WEXITSTATUS(status));
726 } else if (!t->passed) {
727 fprintf(TH_LOG_STREAM,
728 "%s: Test failed at step #%d\n",
729 t->name,
730 WEXITSTATUS(status));
731 }
732 } else if (WIFSIGNALED(status)) {
733 t->passed = 0;
734 if (WTERMSIG(status) == SIGABRT) {
735 fprintf(TH_LOG_STREAM,
736 "%s: Test terminated by assertion\n",
737 t->name);
738 } else if (WTERMSIG(status) == t->termsig) {
739 t->passed = 1;
740 } else {
741 fprintf(TH_LOG_STREAM,
742 "%s: Test terminated unexpectedly "
743 "by signal %d\n",
744 t->name,
745 WTERMSIG(status));
746 }
747 } else {
748 fprintf(TH_LOG_STREAM,
749 "%s: Test ended in some other way [%u]\n",
750 t->name,
751 status);
752 }
753 }
754 printf("[ %4s ] %s\n", (t->passed ? "OK" : "FAIL"), t->name);
755 alarm(0);
756 }
757
758 static int test_harness_run(int __attribute__((unused)) argc,
759 char __attribute__((unused)) **argv)
760 {
761 struct __test_metadata *t;
762 int ret = 0;
763 unsigned int count = 0;
764 unsigned int pass_count = 0;
765
766
767 printf("[==========] Running %u tests from %u test cases.\n",
768 __test_count, __fixture_count + 1);
769 for (t = __test_list; t; t = t->next) {
770 count++;
771 __run_test(t);
772 if (t->passed)
773 pass_count++;
774 else
775 ret = 1;
776 }
777 printf("[==========] %u / %u tests passed.\n", pass_count, count);
778 printf("[ %s ]\n", (ret ? "FAILED" : "PASSED"));
779 return ret;
780 }
781
782 static void __attribute__((constructor)) __constructor_order_first(void)
783 {
784 if (!__constructor_order)
785 __constructor_order = _CONSTRUCTOR_ORDER_FORWARD;
786 }
787
788 #endif