0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050 #ifndef __KSELFTEST_HARNESS_H
0051 #define __KSELFTEST_HARNESS_H
0052
0053 #ifndef _GNU_SOURCE
0054 #define _GNU_SOURCE
0055 #endif
0056 #include <asm/types.h>
0057 #include <errno.h>
0058 #include <stdbool.h>
0059 #include <stdint.h>
0060 #include <stdio.h>
0061 #include <stdlib.h>
0062 #include <string.h>
0063 #include <sys/mman.h>
0064 #include <sys/types.h>
0065 #include <sys/wait.h>
0066 #include <unistd.h>
0067 #include <setjmp.h>
0068
0069 #include "kselftest.h"
0070
0071 #define TEST_TIMEOUT_DEFAULT 30
0072
0073
0074 #ifndef TH_LOG_STREAM
0075 # define TH_LOG_STREAM stderr
0076 #endif
0077
0078 #ifndef TH_LOG_ENABLED
0079 # define TH_LOG_ENABLED 1
0080 #endif
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106 #define TH_LOG(fmt, ...) do { \
0107 if (TH_LOG_ENABLED) \
0108 __TH_LOG(fmt, ##__VA_ARGS__); \
0109 } while (0)
0110
0111
0112 #define __TH_LOG(fmt, ...) \
0113 fprintf(TH_LOG_STREAM, "# %s:%d:%s:" fmt "\n", \
0114 __FILE__, __LINE__, _metadata->name, ##__VA_ARGS__)
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130 #define SKIP(statement, fmt, ...) do { \
0131 snprintf(_metadata->results->reason, \
0132 sizeof(_metadata->results->reason), fmt, ##__VA_ARGS__); \
0133 if (TH_LOG_ENABLED) { \
0134 fprintf(TH_LOG_STREAM, "# SKIP %s\n", \
0135 _metadata->results->reason); \
0136 } \
0137 _metadata->passed = 1; \
0138 _metadata->skip = 1; \
0139 _metadata->trigger = 0; \
0140 statement; \
0141 } while (0)
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160 #define TEST(test_name) __TEST_IMPL(test_name, -1)
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179 #define TEST_SIGNAL(test_name, signal) __TEST_IMPL(test_name, signal)
0180
0181 #define __TEST_IMPL(test_name, _signal) \
0182 static void test_name(struct __test_metadata *_metadata); \
0183 static inline void wrapper_##test_name( \
0184 struct __test_metadata *_metadata, \
0185 struct __fixture_variant_metadata *variant) \
0186 { \
0187 _metadata->setup_completed = true; \
0188 if (setjmp(_metadata->env) == 0) \
0189 test_name(_metadata); \
0190 __test_check_assert(_metadata); \
0191 } \
0192 static struct __test_metadata _##test_name##_object = \
0193 { .name = #test_name, \
0194 .fn = &wrapper_##test_name, \
0195 .fixture = &_fixture_global, \
0196 .termsig = _signal, \
0197 .timeout = TEST_TIMEOUT_DEFAULT, }; \
0198 static void __attribute__((constructor)) _register_##test_name(void) \
0199 { \
0200 __register_test(&_##test_name##_object); \
0201 } \
0202 static void test_name( \
0203 struct __test_metadata __attribute__((unused)) *_metadata)
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219
0220 #define FIXTURE_DATA(datatype_name) struct _test_data_##datatype_name
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234
0235
0236
0237
0238 #define FIXTURE(fixture_name) \
0239 FIXTURE_VARIANT(fixture_name); \
0240 static struct __fixture_metadata _##fixture_name##_fixture_object = \
0241 { .name = #fixture_name, }; \
0242 static void __attribute__((constructor)) \
0243 _register_##fixture_name##_data(void) \
0244 { \
0245 __register_fixture(&_##fixture_name##_fixture_object); \
0246 } \
0247 FIXTURE_DATA(fixture_name)
0248
0249
0250
0251
0252
0253
0254
0255
0256
0257
0258
0259
0260
0261
0262
0263
0264
0265
0266
0267
0268 #define FIXTURE_SETUP(fixture_name) \
0269 void fixture_name##_setup( \
0270 struct __test_metadata __attribute__((unused)) *_metadata, \
0271 FIXTURE_DATA(fixture_name) __attribute__((unused)) *self, \
0272 const FIXTURE_VARIANT(fixture_name) \
0273 __attribute__((unused)) *variant)
0274
0275
0276
0277
0278
0279
0280
0281
0282
0283
0284
0285
0286
0287
0288
0289
0290
0291 #define FIXTURE_TEARDOWN(fixture_name) \
0292 void fixture_name##_teardown( \
0293 struct __test_metadata __attribute__((unused)) *_metadata, \
0294 FIXTURE_DATA(fixture_name) __attribute__((unused)) *self, \
0295 const FIXTURE_VARIANT(fixture_name) \
0296 __attribute__((unused)) *variant)
0297
0298
0299
0300
0301
0302
0303
0304
0305
0306
0307
0308
0309
0310
0311
0312
0313
0314
0315 #define FIXTURE_VARIANT(fixture_name) struct _fixture_variant_##fixture_name
0316
0317
0318
0319
0320
0321
0322
0323
0324
0325
0326
0327
0328
0329
0330
0331
0332
0333
0334
0335 #define FIXTURE_VARIANT_ADD(fixture_name, variant_name) \
0336 extern FIXTURE_VARIANT(fixture_name) \
0337 _##fixture_name##_##variant_name##_variant; \
0338 static struct __fixture_variant_metadata \
0339 _##fixture_name##_##variant_name##_object = \
0340 { .name = #variant_name, \
0341 .data = &_##fixture_name##_##variant_name##_variant}; \
0342 static void __attribute__((constructor)) \
0343 _register_##fixture_name##_##variant_name(void) \
0344 { \
0345 __register_fixture_variant(&_##fixture_name##_fixture_object, \
0346 &_##fixture_name##_##variant_name##_object); \
0347 } \
0348 FIXTURE_VARIANT(fixture_name) \
0349 _##fixture_name##_##variant_name##_variant =
0350
0351
0352
0353
0354
0355
0356
0357
0358
0359
0360
0361
0362
0363
0364
0365
0366 #define TEST_F(fixture_name, test_name) \
0367 __TEST_F_IMPL(fixture_name, test_name, -1, TEST_TIMEOUT_DEFAULT)
0368
0369 #define TEST_F_SIGNAL(fixture_name, test_name, signal) \
0370 __TEST_F_IMPL(fixture_name, test_name, signal, TEST_TIMEOUT_DEFAULT)
0371
0372 #define TEST_F_TIMEOUT(fixture_name, test_name, timeout) \
0373 __TEST_F_IMPL(fixture_name, test_name, -1, timeout)
0374
0375 #define __TEST_F_IMPL(fixture_name, test_name, signal, tmout) \
0376 static void fixture_name##_##test_name( \
0377 struct __test_metadata *_metadata, \
0378 FIXTURE_DATA(fixture_name) *self, \
0379 const FIXTURE_VARIANT(fixture_name) *variant); \
0380 static inline void wrapper_##fixture_name##_##test_name( \
0381 struct __test_metadata *_metadata, \
0382 struct __fixture_variant_metadata *variant) \
0383 { \
0384 \
0385 FIXTURE_DATA(fixture_name) self; \
0386 memset(&self, 0, sizeof(FIXTURE_DATA(fixture_name))); \
0387 if (setjmp(_metadata->env) == 0) { \
0388 fixture_name##_setup(_metadata, &self, variant->data); \
0389 \
0390 if (!_metadata->passed) \
0391 return; \
0392 _metadata->setup_completed = true; \
0393 fixture_name##_##test_name(_metadata, &self, variant->data); \
0394 } \
0395 if (_metadata->setup_completed) \
0396 fixture_name##_teardown(_metadata, &self, variant->data); \
0397 __test_check_assert(_metadata); \
0398 } \
0399 static struct __test_metadata \
0400 _##fixture_name##_##test_name##_object = { \
0401 .name = #test_name, \
0402 .fn = &wrapper_##fixture_name##_##test_name, \
0403 .fixture = &_##fixture_name##_fixture_object, \
0404 .termsig = signal, \
0405 .timeout = tmout, \
0406 }; \
0407 static void __attribute__((constructor)) \
0408 _register_##fixture_name##_##test_name(void) \
0409 { \
0410 __register_test(&_##fixture_name##_##test_name##_object); \
0411 } \
0412 static void fixture_name##_##test_name( \
0413 struct __test_metadata __attribute__((unused)) *_metadata, \
0414 FIXTURE_DATA(fixture_name) __attribute__((unused)) *self, \
0415 const FIXTURE_VARIANT(fixture_name) \
0416 __attribute__((unused)) *variant)
0417
0418
0419
0420
0421
0422
0423
0424
0425
0426
0427 #define TEST_HARNESS_MAIN \
0428 static void __attribute__((constructor)) \
0429 __constructor_order_last(void) \
0430 { \
0431 if (!__constructor_order) \
0432 __constructor_order = _CONSTRUCTOR_ORDER_BACKWARD; \
0433 } \
0434 int main(int argc, char **argv) { \
0435 return test_harness_run(argc, argv); \
0436 }
0437
0438
0439
0440
0441
0442
0443
0444
0445
0446
0447
0448
0449
0450
0451
0452
0453
0454 #define ASSERT_EQ(expected, seen) \
0455 __EXPECT(expected, #expected, seen, #seen, ==, 1)
0456
0457
0458
0459
0460
0461
0462
0463
0464
0465 #define ASSERT_NE(expected, seen) \
0466 __EXPECT(expected, #expected, seen, #seen, !=, 1)
0467
0468
0469
0470
0471
0472
0473
0474
0475
0476 #define ASSERT_LT(expected, seen) \
0477 __EXPECT(expected, #expected, seen, #seen, <, 1)
0478
0479
0480
0481
0482
0483
0484
0485
0486
0487 #define ASSERT_LE(expected, seen) \
0488 __EXPECT(expected, #expected, seen, #seen, <=, 1)
0489
0490
0491
0492
0493
0494
0495
0496
0497
0498 #define ASSERT_GT(expected, seen) \
0499 __EXPECT(expected, #expected, seen, #seen, >, 1)
0500
0501
0502
0503
0504
0505
0506
0507
0508
0509 #define ASSERT_GE(expected, seen) \
0510 __EXPECT(expected, #expected, seen, #seen, >=, 1)
0511
0512
0513
0514
0515
0516
0517
0518
0519 #define ASSERT_NULL(seen) \
0520 __EXPECT(NULL, "NULL", seen, #seen, ==, 1)
0521
0522
0523
0524
0525
0526
0527
0528
0529 #define ASSERT_TRUE(seen) \
0530 __EXPECT(0, "0", seen, #seen, !=, 1)
0531
0532
0533
0534
0535
0536
0537
0538
0539 #define ASSERT_FALSE(seen) \
0540 __EXPECT(0, "0", seen, #seen, ==, 1)
0541
0542
0543
0544
0545
0546
0547
0548
0549
0550 #define ASSERT_STREQ(expected, seen) \
0551 __EXPECT_STR(expected, seen, ==, 1)
0552
0553
0554
0555
0556
0557
0558
0559
0560
0561 #define ASSERT_STRNE(expected, seen) \
0562 __EXPECT_STR(expected, seen, !=, 1)
0563
0564
0565
0566
0567
0568
0569
0570
0571
0572 #define EXPECT_EQ(expected, seen) \
0573 __EXPECT(expected, #expected, seen, #seen, ==, 0)
0574
0575
0576
0577
0578
0579
0580
0581
0582
0583 #define EXPECT_NE(expected, seen) \
0584 __EXPECT(expected, #expected, seen, #seen, !=, 0)
0585
0586
0587
0588
0589
0590
0591
0592
0593
0594 #define EXPECT_LT(expected, seen) \
0595 __EXPECT(expected, #expected, seen, #seen, <, 0)
0596
0597
0598
0599
0600
0601
0602
0603
0604
0605 #define EXPECT_LE(expected, seen) \
0606 __EXPECT(expected, #expected, seen, #seen, <=, 0)
0607
0608
0609
0610
0611
0612
0613
0614
0615
0616 #define EXPECT_GT(expected, seen) \
0617 __EXPECT(expected, #expected, seen, #seen, >, 0)
0618
0619
0620
0621
0622
0623
0624
0625
0626
0627 #define EXPECT_GE(expected, seen) \
0628 __EXPECT(expected, #expected, seen, #seen, >=, 0)
0629
0630
0631
0632
0633
0634
0635
0636
0637 #define EXPECT_NULL(seen) \
0638 __EXPECT(NULL, "NULL", seen, #seen, ==, 0)
0639
0640
0641
0642
0643
0644
0645
0646
0647 #define EXPECT_TRUE(seen) \
0648 __EXPECT(0, "0", seen, #seen, !=, 0)
0649
0650
0651
0652
0653
0654
0655
0656
0657 #define EXPECT_FALSE(seen) \
0658 __EXPECT(0, "0", seen, #seen, ==, 0)
0659
0660
0661
0662
0663
0664
0665
0666
0667
0668 #define EXPECT_STREQ(expected, seen) \
0669 __EXPECT_STR(expected, seen, ==, 0)
0670
0671
0672
0673
0674
0675
0676
0677
0678
0679 #define EXPECT_STRNE(expected, seen) \
0680 __EXPECT_STR(expected, seen, !=, 0)
0681
0682 #ifndef ARRAY_SIZE
0683 #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
0684 #endif
0685
0686
0687
0688
0689
0690
0691
0692 #define OPTIONAL_HANDLER(_assert) \
0693 for (; _metadata->trigger; _metadata->trigger = \
0694 __bail(_assert, _metadata))
0695
0696 #define __INC_STEP(_metadata) \
0697 \
0698 if (_metadata->passed && _metadata->step < 253) \
0699 _metadata->step++;
0700
0701 #define is_signed_type(var) (!!(((__typeof__(var))(-1)) < (__typeof__(var))1))
0702
0703 #define __EXPECT(_expected, _expected_str, _seen, _seen_str, _t, _assert) do { \
0704 \
0705 __typeof__(_expected) __exp = (_expected); \
0706 __typeof__(_seen) __seen = (_seen); \
0707 if (_assert) __INC_STEP(_metadata); \
0708 if (!(__exp _t __seen)) { \
0709 \
0710 switch (is_signed_type(__exp) * 2 + is_signed_type(__seen)) { \
0711 case 0: { \
0712 unsigned long long __exp_print = (uintptr_t)__exp; \
0713 unsigned long long __seen_print = (uintptr_t)__seen; \
0714 __TH_LOG("Expected %s (%llu) %s %s (%llu)", \
0715 _expected_str, __exp_print, #_t, \
0716 _seen_str, __seen_print); \
0717 break; \
0718 } \
0719 case 1: { \
0720 unsigned long long __exp_print = (uintptr_t)__exp; \
0721 long long __seen_print = (intptr_t)__seen; \
0722 __TH_LOG("Expected %s (%llu) %s %s (%lld)", \
0723 _expected_str, __exp_print, #_t, \
0724 _seen_str, __seen_print); \
0725 break; \
0726 } \
0727 case 2: { \
0728 long long __exp_print = (intptr_t)__exp; \
0729 unsigned long long __seen_print = (uintptr_t)__seen; \
0730 __TH_LOG("Expected %s (%lld) %s %s (%llu)", \
0731 _expected_str, __exp_print, #_t, \
0732 _seen_str, __seen_print); \
0733 break; \
0734 } \
0735 case 3: { \
0736 long long __exp_print = (intptr_t)__exp; \
0737 long long __seen_print = (intptr_t)__seen; \
0738 __TH_LOG("Expected %s (%lld) %s %s (%lld)", \
0739 _expected_str, __exp_print, #_t, \
0740 _seen_str, __seen_print); \
0741 break; \
0742 } \
0743 } \
0744 _metadata->passed = 0; \
0745 \
0746 _metadata->trigger = 1; \
0747 } \
0748 } while (0); OPTIONAL_HANDLER(_assert)
0749
0750 #define __EXPECT_STR(_expected, _seen, _t, _assert) do { \
0751 const char *__exp = (_expected); \
0752 const char *__seen = (_seen); \
0753 if (_assert) __INC_STEP(_metadata); \
0754 if (!(strcmp(__exp, __seen) _t 0)) { \
0755 __TH_LOG("Expected '%s' %s '%s'.", __exp, #_t, __seen); \
0756 _metadata->passed = 0; \
0757 _metadata->trigger = 1; \
0758 } \
0759 } while (0); OPTIONAL_HANDLER(_assert)
0760
0761
0762 #define __LIST_APPEND(head, item) \
0763 { \
0764 \
0765 if (head == NULL) { \
0766 head = item; \
0767 item->next = NULL; \
0768 item->prev = item; \
0769 return; \
0770 } \
0771 if (__constructor_order == _CONSTRUCTOR_ORDER_FORWARD) { \
0772 item->next = NULL; \
0773 item->prev = head->prev; \
0774 item->prev->next = item; \
0775 head->prev = item; \
0776 } else { \
0777 item->next = head; \
0778 item->next->prev = item; \
0779 item->prev = item; \
0780 head = item; \
0781 } \
0782 }
0783
0784 struct __test_results {
0785 char reason[1024];
0786 };
0787
0788 struct __test_metadata;
0789 struct __fixture_variant_metadata;
0790
0791
0792 struct __fixture_metadata {
0793 const char *name;
0794 struct __test_metadata *tests;
0795 struct __fixture_variant_metadata *variant;
0796 struct __fixture_metadata *prev, *next;
0797 } _fixture_global __attribute__((unused)) = {
0798 .name = "global",
0799 .prev = &_fixture_global,
0800 };
0801
0802 static struct __fixture_metadata *__fixture_list = &_fixture_global;
0803 static int __constructor_order;
0804
0805 #define _CONSTRUCTOR_ORDER_FORWARD 1
0806 #define _CONSTRUCTOR_ORDER_BACKWARD -1
0807
0808 static inline void __register_fixture(struct __fixture_metadata *f)
0809 {
0810 __LIST_APPEND(__fixture_list, f);
0811 }
0812
0813 struct __fixture_variant_metadata {
0814 const char *name;
0815 const void *data;
0816 struct __fixture_variant_metadata *prev, *next;
0817 };
0818
0819 static inline void
0820 __register_fixture_variant(struct __fixture_metadata *f,
0821 struct __fixture_variant_metadata *variant)
0822 {
0823 __LIST_APPEND(f->variant, variant);
0824 }
0825
0826
0827 struct __test_metadata {
0828 const char *name;
0829 void (*fn)(struct __test_metadata *,
0830 struct __fixture_variant_metadata *);
0831 pid_t pid;
0832 struct __fixture_metadata *fixture;
0833 int termsig;
0834 int passed;
0835 int skip;
0836 int trigger;
0837 int timeout;
0838 bool timed_out;
0839 __u8 step;
0840 bool no_print;
0841 bool aborted;
0842 bool setup_completed;
0843 jmp_buf env;
0844 struct __test_results *results;
0845 struct __test_metadata *prev, *next;
0846 };
0847
0848
0849
0850
0851
0852
0853
0854
0855
0856
0857 static inline void __register_test(struct __test_metadata *t)
0858 {
0859 __LIST_APPEND(t->fixture->tests, t);
0860 }
0861
0862 static inline int __bail(int for_realz, struct __test_metadata *t)
0863 {
0864
0865 if (for_realz) {
0866 t->aborted = true;
0867 longjmp(t->env, 1);
0868 }
0869
0870 return 0;
0871 }
0872
0873 static inline void __test_check_assert(struct __test_metadata *t)
0874 {
0875 if (t->aborted) {
0876 if (t->no_print)
0877 _exit(t->step);
0878 abort();
0879 }
0880 }
0881
0882 struct __test_metadata *__active_test;
0883 static void __timeout_handler(int sig, siginfo_t *info, void *ucontext)
0884 {
0885 struct __test_metadata *t = __active_test;
0886
0887
0888 if (!t) {
0889 fprintf(TH_LOG_STREAM,
0890 "# no active test in SIGALRM handler!?\n");
0891 abort();
0892 }
0893 if (sig != SIGALRM || sig != info->si_signo) {
0894 fprintf(TH_LOG_STREAM,
0895 "# %s: SIGALRM handler caught signal %d!?\n",
0896 t->name, sig != SIGALRM ? sig : info->si_signo);
0897 abort();
0898 }
0899
0900 t->timed_out = true;
0901
0902 kill(-(t->pid), SIGKILL);
0903 }
0904
0905 void __wait_for_test(struct __test_metadata *t)
0906 {
0907 struct sigaction action = {
0908 .sa_sigaction = __timeout_handler,
0909 .sa_flags = SA_SIGINFO,
0910 };
0911 struct sigaction saved_action;
0912 int status;
0913
0914 if (sigaction(SIGALRM, &action, &saved_action)) {
0915 t->passed = 0;
0916 fprintf(TH_LOG_STREAM,
0917 "# %s: unable to install SIGALRM handler\n",
0918 t->name);
0919 return;
0920 }
0921 __active_test = t;
0922 t->timed_out = false;
0923 alarm(t->timeout);
0924 waitpid(t->pid, &status, 0);
0925 alarm(0);
0926 if (sigaction(SIGALRM, &saved_action, NULL)) {
0927 t->passed = 0;
0928 fprintf(TH_LOG_STREAM,
0929 "# %s: unable to uninstall SIGALRM handler\n",
0930 t->name);
0931 return;
0932 }
0933 __active_test = NULL;
0934
0935 if (t->timed_out) {
0936 t->passed = 0;
0937 fprintf(TH_LOG_STREAM,
0938 "# %s: Test terminated by timeout\n", t->name);
0939 } else if (WIFEXITED(status)) {
0940 if (t->termsig != -1) {
0941 t->passed = 0;
0942 fprintf(TH_LOG_STREAM,
0943 "# %s: Test exited normally instead of by signal (code: %d)\n",
0944 t->name,
0945 WEXITSTATUS(status));
0946 } else {
0947 switch (WEXITSTATUS(status)) {
0948
0949 case 0:
0950 t->passed = 1;
0951 break;
0952
0953 case 255:
0954 t->passed = 1;
0955 t->skip = 1;
0956 break;
0957
0958 default:
0959 t->passed = 0;
0960 fprintf(TH_LOG_STREAM,
0961 "# %s: Test failed at step #%d\n",
0962 t->name,
0963 WEXITSTATUS(status));
0964 }
0965 }
0966 } else if (WIFSIGNALED(status)) {
0967 t->passed = 0;
0968 if (WTERMSIG(status) == SIGABRT) {
0969 fprintf(TH_LOG_STREAM,
0970 "# %s: Test terminated by assertion\n",
0971 t->name);
0972 } else if (WTERMSIG(status) == t->termsig) {
0973 t->passed = 1;
0974 } else {
0975 fprintf(TH_LOG_STREAM,
0976 "# %s: Test terminated unexpectedly by signal %d\n",
0977 t->name,
0978 WTERMSIG(status));
0979 }
0980 } else {
0981 fprintf(TH_LOG_STREAM,
0982 "# %s: Test ended in some other way [%u]\n",
0983 t->name,
0984 status);
0985 }
0986 }
0987
0988 void __run_test(struct __fixture_metadata *f,
0989 struct __fixture_variant_metadata *variant,
0990 struct __test_metadata *t)
0991 {
0992
0993 t->passed = 1;
0994 t->skip = 0;
0995 t->trigger = 0;
0996 t->step = 1;
0997 t->no_print = 0;
0998 memset(t->results->reason, 0, sizeof(t->results->reason));
0999
1000 ksft_print_msg(" RUN %s%s%s.%s ...\n",
1001 f->name, variant->name[0] ? "." : "", variant->name, t->name);
1002
1003
1004 fflush(stdout);
1005 fflush(stderr);
1006
1007 t->pid = fork();
1008 if (t->pid < 0) {
1009 ksft_print_msg("ERROR SPAWNING TEST CHILD\n");
1010 t->passed = 0;
1011 } else if (t->pid == 0) {
1012 setpgrp();
1013 t->fn(t, variant);
1014 if (t->skip)
1015 _exit(255);
1016
1017 if (t->passed)
1018 _exit(0);
1019
1020 _exit(t->step);
1021 } else {
1022 __wait_for_test(t);
1023 }
1024 ksft_print_msg(" %4s %s%s%s.%s\n", t->passed ? "OK" : "FAIL",
1025 f->name, variant->name[0] ? "." : "", variant->name, t->name);
1026
1027 if (t->skip)
1028 ksft_test_result_skip("%s\n", t->results->reason[0] ?
1029 t->results->reason : "unknown");
1030 else
1031 ksft_test_result(t->passed, "%s%s%s.%s\n",
1032 f->name, variant->name[0] ? "." : "", variant->name, t->name);
1033 }
1034
1035 static int test_harness_run(int __attribute__((unused)) argc,
1036 char __attribute__((unused)) **argv)
1037 {
1038 struct __fixture_variant_metadata no_variant = { .name = "", };
1039 struct __fixture_variant_metadata *v;
1040 struct __fixture_metadata *f;
1041 struct __test_results *results;
1042 struct __test_metadata *t;
1043 int ret = 0;
1044 unsigned int case_count = 0, test_count = 0;
1045 unsigned int count = 0;
1046 unsigned int pass_count = 0;
1047
1048 for (f = __fixture_list; f; f = f->next) {
1049 for (v = f->variant ?: &no_variant; v; v = v->next) {
1050 case_count++;
1051 for (t = f->tests; t; t = t->next)
1052 test_count++;
1053 }
1054 }
1055
1056 results = mmap(NULL, sizeof(*results), PROT_READ | PROT_WRITE,
1057 MAP_SHARED | MAP_ANONYMOUS, -1, 0);
1058
1059 ksft_print_header();
1060 ksft_set_plan(test_count);
1061 ksft_print_msg("Starting %u tests from %u test cases.\n",
1062 test_count, case_count);
1063 for (f = __fixture_list; f; f = f->next) {
1064 for (v = f->variant ?: &no_variant; v; v = v->next) {
1065 for (t = f->tests; t; t = t->next) {
1066 count++;
1067 t->results = results;
1068 __run_test(f, v, t);
1069 t->results = NULL;
1070 if (t->passed)
1071 pass_count++;
1072 else
1073 ret = 1;
1074 }
1075 }
1076 }
1077 munmap(results, sizeof(*results));
1078
1079 ksft_print_msg("%s: %u / %u tests passed.\n", ret ? "FAILED" : "PASSED",
1080 pass_count, count);
1081 ksft_exit(ret == 0);
1082
1083
1084 return KSFT_FAIL;
1085 }
1086
1087 static void __attribute__((constructor)) __constructor_order_first(void)
1088 {
1089 if (!__constructor_order)
1090 __constructor_order = _CONSTRUCTOR_ORDER_FORWARD;
1091 }
1092
1093 #endif