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 inline void wrapper_##test_name( \
172 struct __test_metadata *_metadata, \
173 struct __fixture_variant_metadata *variant) \
174 { \
175 test_name(_metadata); \
176 } \
177 static struct __test_metadata _##test_name##_object = \
178 { .name = #test_name, \
179 .fn = &wrapper_##test_name, \
180 .fixture = &_fixture_global, \
181 .termsig = _signal, \
182 .timeout = TEST_TIMEOUT_DEFAULT, }; \
183 static void __attribute__((constructor)) _register_##test_name(void) \
184 { \
185 __register_test(&_##test_name##_object); \
186 } \
187 static void test_name( \
188 struct __test_metadata __attribute__((unused)) *_metadata)
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204#define FIXTURE_DATA(datatype_name) struct _test_data_##datatype_name
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222#define FIXTURE(fixture_name) \
223 FIXTURE_VARIANT(fixture_name); \
224 static struct __fixture_metadata _##fixture_name##_fixture_object = \
225 { .name = #fixture_name, }; \
226 static void __attribute__((constructor)) \
227 _register_##fixture_name##_data(void) \
228 { \
229 __register_fixture(&_##fixture_name##_fixture_object); \
230 } \
231 FIXTURE_DATA(fixture_name)
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252#define FIXTURE_SETUP(fixture_name) \
253 void fixture_name##_setup( \
254 struct __test_metadata __attribute__((unused)) *_metadata, \
255 FIXTURE_DATA(fixture_name) __attribute__((unused)) *self, \
256 const FIXTURE_VARIANT(fixture_name) \
257 __attribute__((unused)) *variant)
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275#define FIXTURE_TEARDOWN(fixture_name) \
276 void fixture_name##_teardown( \
277 struct __test_metadata __attribute__((unused)) *_metadata, \
278 FIXTURE_DATA(fixture_name) __attribute__((unused)) *self)
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297#define FIXTURE_VARIANT(fixture_name) struct _fixture_variant_##fixture_name
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317#define FIXTURE_VARIANT_ADD(fixture_name, variant_name) \
318 extern FIXTURE_VARIANT(fixture_name) \
319 _##fixture_name##_##variant_name##_variant; \
320 static struct __fixture_variant_metadata \
321 _##fixture_name##_##variant_name##_object = \
322 { .name = #variant_name, \
323 .data = &_##fixture_name##_##variant_name##_variant}; \
324 static void __attribute__((constructor)) \
325 _register_##fixture_name##_##variant_name(void) \
326 { \
327 __register_fixture_variant(&_##fixture_name##_fixture_object, \
328 &_##fixture_name##_##variant_name##_object); \
329 } \
330 FIXTURE_VARIANT(fixture_name) \
331 _##fixture_name##_##variant_name##_variant =
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351#define TEST_F(fixture_name, test_name) \
352 __TEST_F_IMPL(fixture_name, test_name, -1, TEST_TIMEOUT_DEFAULT)
353
354#define TEST_F_SIGNAL(fixture_name, test_name, signal) \
355 __TEST_F_IMPL(fixture_name, test_name, signal, TEST_TIMEOUT_DEFAULT)
356
357#define TEST_F_TIMEOUT(fixture_name, test_name, timeout) \
358 __TEST_F_IMPL(fixture_name, test_name, -1, timeout)
359
360#define __TEST_F_IMPL(fixture_name, test_name, signal, tmout) \
361 static void fixture_name##_##test_name( \
362 struct __test_metadata *_metadata, \
363 FIXTURE_DATA(fixture_name) *self, \
364 const FIXTURE_VARIANT(fixture_name) *variant); \
365 static inline void wrapper_##fixture_name##_##test_name( \
366 struct __test_metadata *_metadata, \
367 struct __fixture_variant_metadata *variant) \
368 { \
369 \
370 FIXTURE_DATA(fixture_name) self; \
371 memset(&self, 0, sizeof(FIXTURE_DATA(fixture_name))); \
372 fixture_name##_setup(_metadata, &self, variant->data); \
373 \
374 if (!_metadata->passed) \
375 return; \
376 fixture_name##_##test_name(_metadata, &self, variant->data); \
377 fixture_name##_teardown(_metadata, &self); \
378 } \
379 static struct __test_metadata \
380 _##fixture_name##_##test_name##_object = { \
381 .name = #test_name, \
382 .fn = &wrapper_##fixture_name##_##test_name, \
383 .fixture = &_##fixture_name##_fixture_object, \
384 .termsig = signal, \
385 .timeout = tmout, \
386 }; \
387 static void __attribute__((constructor)) \
388 _register_##fixture_name##_##test_name(void) \
389 { \
390 __register_test(&_##fixture_name##_##test_name##_object); \
391 } \
392 static void fixture_name##_##test_name( \
393 struct __test_metadata __attribute__((unused)) *_metadata, \
394 FIXTURE_DATA(fixture_name) __attribute__((unused)) *self, \
395 const FIXTURE_VARIANT(fixture_name) \
396 __attribute__((unused)) *variant)
397
398
399
400
401
402
403
404
405
406
407#define TEST_HARNESS_MAIN \
408 static void __attribute__((constructor)) \
409 __constructor_order_last(void) \
410 { \
411 if (!__constructor_order) \
412 __constructor_order = _CONSTRUCTOR_ORDER_BACKWARD; \
413 } \
414 int main(int argc, char **argv) { \
415 return test_harness_run(argc, argv); \
416 }
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434#define ASSERT_EQ(expected, seen) \
435 __EXPECT(expected, #expected, seen, #seen, ==, 1)
436
437
438
439
440
441
442
443
444
445#define ASSERT_NE(expected, seen) \
446 __EXPECT(expected, #expected, seen, #seen, !=, 1)
447
448
449
450
451
452
453
454
455
456#define ASSERT_LT(expected, seen) \
457 __EXPECT(expected, #expected, seen, #seen, <, 1)
458
459
460
461
462
463
464
465
466
467#define ASSERT_LE(expected, seen) \
468 __EXPECT(expected, #expected, seen, #seen, <=, 1)
469
470
471
472
473
474
475
476
477
478#define ASSERT_GT(expected, seen) \
479 __EXPECT(expected, #expected, seen, #seen, >, 1)
480
481
482
483
484
485
486
487
488
489#define ASSERT_GE(expected, seen) \
490 __EXPECT(expected, #expected, seen, #seen, >=, 1)
491
492
493
494
495
496
497
498
499#define ASSERT_NULL(seen) \
500 __EXPECT(NULL, "NULL", seen, #seen, ==, 1)
501
502
503
504
505
506
507
508
509#define ASSERT_TRUE(seen) \
510 __EXPECT(0, "0", seen, #seen, !=, 1)
511
512
513
514
515
516
517
518
519#define ASSERT_FALSE(seen) \
520 __EXPECT(0, "0", seen, #seen, ==, 1)
521
522
523
524
525
526
527
528
529
530#define ASSERT_STREQ(expected, seen) \
531 __EXPECT_STR(expected, seen, ==, 1)
532
533
534
535
536
537
538
539
540
541#define ASSERT_STRNE(expected, seen) \
542 __EXPECT_STR(expected, seen, !=, 1)
543
544
545
546
547
548
549
550
551
552#define EXPECT_EQ(expected, seen) \
553 __EXPECT(expected, #expected, seen, #seen, ==, 0)
554
555
556
557
558
559
560
561
562
563#define EXPECT_NE(expected, seen) \
564 __EXPECT(expected, #expected, seen, #seen, !=, 0)
565
566
567
568
569
570
571
572
573
574#define EXPECT_LT(expected, seen) \
575 __EXPECT(expected, #expected, seen, #seen, <, 0)
576
577
578
579
580
581
582
583
584
585#define EXPECT_LE(expected, seen) \
586 __EXPECT(expected, #expected, seen, #seen, <=, 0)
587
588
589
590
591
592
593
594
595
596#define EXPECT_GT(expected, seen) \
597 __EXPECT(expected, #expected, seen, #seen, >, 0)
598
599
600
601
602
603
604
605
606
607#define EXPECT_GE(expected, seen) \
608 __EXPECT(expected, #expected, seen, #seen, >=, 0)
609
610
611
612
613
614
615
616
617#define EXPECT_NULL(seen) \
618 __EXPECT(NULL, "NULL", seen, #seen, ==, 0)
619
620
621
622
623
624
625
626
627#define EXPECT_TRUE(seen) \
628 __EXPECT(0, "0", seen, #seen, !=, 0)
629
630
631
632
633
634
635
636
637#define EXPECT_FALSE(seen) \
638 __EXPECT(0, "0", seen, #seen, ==, 0)
639
640
641
642
643
644
645
646
647
648#define EXPECT_STREQ(expected, seen) \
649 __EXPECT_STR(expected, seen, ==, 0)
650
651
652
653
654
655
656
657
658
659#define EXPECT_STRNE(expected, seen) \
660 __EXPECT_STR(expected, seen, !=, 0)
661
662#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
663
664
665
666
667
668
669
670#define OPTIONAL_HANDLER(_assert) \
671 for (; _metadata->trigger; _metadata->trigger = \
672 __bail(_assert, _metadata->no_print, _metadata->step))
673
674#define __INC_STEP(_metadata) \
675 if (_metadata->passed && _metadata->step < 255) \
676 _metadata->step++;
677
678#define __EXPECT(_expected, _expected_str, _seen, _seen_str, _t, _assert) do { \
679 \
680 __typeof__(_expected) __exp = (_expected); \
681 __typeof__(_seen) __seen = (_seen); \
682 if (_assert) __INC_STEP(_metadata); \
683 if (!(__exp _t __seen)) { \
684 unsigned long long __exp_print = (uintptr_t)__exp; \
685 unsigned long long __seen_print = (uintptr_t)__seen; \
686 __TH_LOG("Expected %s (%llu) %s %s (%llu)", \
687 _expected_str, __exp_print, #_t, \
688 _seen_str, __seen_print); \
689 _metadata->passed = 0; \
690 \
691 _metadata->trigger = 1; \
692 } \
693} while (0); OPTIONAL_HANDLER(_assert)
694
695#define __EXPECT_STR(_expected, _seen, _t, _assert) do { \
696 const char *__exp = (_expected); \
697 const char *__seen = (_seen); \
698 if (_assert) __INC_STEP(_metadata); \
699 if (!(strcmp(__exp, __seen) _t 0)) { \
700 __TH_LOG("Expected '%s' %s '%s'.", __exp, #_t, __seen); \
701 _metadata->passed = 0; \
702 _metadata->trigger = 1; \
703 } \
704} while (0); OPTIONAL_HANDLER(_assert)
705
706
707#define __LIST_APPEND(head, item) \
708{ \
709 \
710 if (head == NULL) { \
711 head = item; \
712 item->next = NULL; \
713 item->prev = item; \
714 return; \
715 } \
716 if (__constructor_order == _CONSTRUCTOR_ORDER_FORWARD) { \
717 item->next = NULL; \
718 item->prev = head->prev; \
719 item->prev->next = item; \
720 head->prev = item; \
721 } else { \
722 item->next = head; \
723 item->next->prev = item; \
724 item->prev = item; \
725 head = item; \
726 } \
727}
728
729struct __test_metadata;
730struct __fixture_variant_metadata;
731
732
733struct __fixture_metadata {
734 const char *name;
735 struct __test_metadata *tests;
736 struct __fixture_variant_metadata *variant;
737 struct __fixture_metadata *prev, *next;
738} _fixture_global __attribute__((unused)) = {
739 .name = "global",
740 .prev = &_fixture_global,
741};
742
743static struct __fixture_metadata *__fixture_list = &_fixture_global;
744static int __constructor_order;
745
746#define _CONSTRUCTOR_ORDER_FORWARD 1
747#define _CONSTRUCTOR_ORDER_BACKWARD -1
748
749static inline void __register_fixture(struct __fixture_metadata *f)
750{
751 __LIST_APPEND(__fixture_list, f);
752}
753
754struct __fixture_variant_metadata {
755 const char *name;
756 const void *data;
757 struct __fixture_variant_metadata *prev, *next;
758};
759
760static inline void
761__register_fixture_variant(struct __fixture_metadata *f,
762 struct __fixture_variant_metadata *variant)
763{
764 __LIST_APPEND(f->variant, variant);
765}
766
767
768struct __test_metadata {
769 const char *name;
770 void (*fn)(struct __test_metadata *,
771 struct __fixture_variant_metadata *);
772 pid_t pid;
773 struct __fixture_metadata *fixture;
774 int termsig;
775 int passed;
776 int trigger;
777 int timeout;
778 bool timed_out;
779 __u8 step;
780 bool no_print;
781 struct __test_metadata *prev, *next;
782};
783
784
785
786
787
788
789
790
791
792
793static inline void __register_test(struct __test_metadata *t)
794{
795 __LIST_APPEND(t->fixture->tests, t);
796}
797
798static inline int __bail(int for_realz, bool no_print, __u8 step)
799{
800 if (for_realz) {
801 if (no_print)
802 _exit(step);
803 abort();
804 }
805 return 0;
806}
807
808struct __test_metadata *__active_test;
809static void __timeout_handler(int sig, siginfo_t *info, void *ucontext)
810{
811 struct __test_metadata *t = __active_test;
812
813
814 if (!t) {
815 fprintf(TH_LOG_STREAM,
816 "no active test in SIGALRM handler!?\n");
817 abort();
818 }
819 if (sig != SIGALRM || sig != info->si_signo) {
820 fprintf(TH_LOG_STREAM,
821 "%s: SIGALRM handler caught signal %d!?\n",
822 t->name, sig != SIGALRM ? sig : info->si_signo);
823 abort();
824 }
825
826 t->timed_out = true;
827 kill(t->pid, SIGKILL);
828}
829
830void __wait_for_test(struct __test_metadata *t)
831{
832 struct sigaction action = {
833 .sa_sigaction = __timeout_handler,
834 .sa_flags = SA_SIGINFO,
835 };
836 struct sigaction saved_action;
837 int status;
838
839 if (sigaction(SIGALRM, &action, &saved_action)) {
840 t->passed = 0;
841 fprintf(TH_LOG_STREAM,
842 "%s: unable to install SIGALRM handler\n",
843 t->name);
844 return;
845 }
846 __active_test = t;
847 t->timed_out = false;
848 alarm(t->timeout);
849 waitpid(t->pid, &status, 0);
850 alarm(0);
851 if (sigaction(SIGALRM, &saved_action, NULL)) {
852 t->passed = 0;
853 fprintf(TH_LOG_STREAM,
854 "%s: unable to uninstall SIGALRM handler\n",
855 t->name);
856 return;
857 }
858 __active_test = NULL;
859
860 if (t->timed_out) {
861 t->passed = 0;
862 fprintf(TH_LOG_STREAM,
863 "%s: Test terminated by timeout\n", t->name);
864 } else if (WIFEXITED(status)) {
865 t->passed = t->termsig == -1 ? !WEXITSTATUS(status) : 0;
866 if (t->termsig != -1) {
867 fprintf(TH_LOG_STREAM,
868 "%s: Test exited normally "
869 "instead of by signal (code: %d)\n",
870 t->name,
871 WEXITSTATUS(status));
872 } else if (!t->passed) {
873 fprintf(TH_LOG_STREAM,
874 "%s: Test failed at step #%d\n",
875 t->name,
876 WEXITSTATUS(status));
877 }
878 } else if (WIFSIGNALED(status)) {
879 t->passed = 0;
880 if (WTERMSIG(status) == SIGABRT) {
881 fprintf(TH_LOG_STREAM,
882 "%s: Test terminated by assertion\n",
883 t->name);
884 } else if (WTERMSIG(status) == t->termsig) {
885 t->passed = 1;
886 } else {
887 fprintf(TH_LOG_STREAM,
888 "%s: Test terminated unexpectedly "
889 "by signal %d\n",
890 t->name,
891 WTERMSIG(status));
892 }
893 } else {
894 fprintf(TH_LOG_STREAM,
895 "%s: Test ended in some other way [%u]\n",
896 t->name,
897 status);
898 }
899}
900
901void __run_test(struct __fixture_metadata *f,
902 struct __fixture_variant_metadata *variant,
903 struct __test_metadata *t)
904{
905
906 t->passed = 1;
907 t->trigger = 0;
908 t->step = 0;
909 t->no_print = 0;
910
911 printf("[ RUN ] %s%s%s.%s\n",
912 f->name, variant->name[0] ? "." : "", variant->name, t->name);
913 t->pid = fork();
914 if (t->pid < 0) {
915 printf("ERROR SPAWNING TEST CHILD\n");
916 t->passed = 0;
917 } else if (t->pid == 0) {
918 t->fn(t, variant);
919
920 _exit(t->passed ? 0 : t->step);
921 } else {
922 __wait_for_test(t);
923 }
924 printf("[ %4s ] %s%s%s.%s\n", (t->passed ? "OK" : "FAIL"),
925 f->name, variant->name[0] ? "." : "", variant->name, t->name);
926}
927
928static int test_harness_run(int __attribute__((unused)) argc,
929 char __attribute__((unused)) **argv)
930{
931 struct __fixture_variant_metadata no_variant = { .name = "", };
932 struct __fixture_variant_metadata *v;
933 struct __fixture_metadata *f;
934 struct __test_metadata *t;
935 int ret = 0;
936 unsigned int case_count = 0, test_count = 0;
937 unsigned int count = 0;
938 unsigned int pass_count = 0;
939
940 for (f = __fixture_list; f; f = f->next) {
941 for (v = f->variant ?: &no_variant; v; v = v->next) {
942 case_count++;
943 for (t = f->tests; t; t = t->next)
944 test_count++;
945 }
946 }
947
948
949 printf("[==========] Running %u tests from %u test cases.\n",
950 test_count, case_count);
951 for (f = __fixture_list; f; f = f->next) {
952 for (v = f->variant ?: &no_variant; v; v = v->next) {
953 for (t = f->tests; t; t = t->next) {
954 count++;
955 __run_test(f, v, t);
956 if (t->passed)
957 pass_count++;
958 else
959 ret = 1;
960 }
961 }
962 }
963 printf("[==========] %u / %u tests passed.\n", pass_count, count);
964 printf("[ %s ]\n", (ret ? "FAILED" : "PASSED"));
965 return ret;
966}
967
968static void __attribute__((constructor)) __constructor_order_first(void)
969{
970 if (!__constructor_order)
971 __constructor_order = _CONSTRUCTOR_ORDER_FORWARD;
972}
973
974#endif
975