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