hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/tools/testing/selftests/kselftest_harness.h
....@@ -1,6 +1,6 @@
1
+/* SPDX-License-Identifier: GPL-2.0-only */
12 /*
23 * Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
3
- * Use of this source code is governed by the GPLv2 license.
44 *
55 * kselftest_harness.h: simple C unit test helper.
66 *
....@@ -50,7 +50,9 @@
5050 #ifndef __KSELFTEST_HARNESS_H
5151 #define __KSELFTEST_HARNESS_H
5252
53
+#ifndef _GNU_SOURCE
5354 #define _GNU_SOURCE
55
+#endif
5456 #include <asm/types.h>
5557 #include <errno.h>
5658 #include <stdbool.h>
....@@ -58,10 +60,14 @@
5860 #include <stdio.h>
5961 #include <stdlib.h>
6062 #include <string.h>
63
+#include <sys/mman.h>
6164 #include <sys/types.h>
6265 #include <sys/wait.h>
6366 #include <unistd.h>
6467
68
+#include "kselftest.h"
69
+
70
+#define TEST_TIMEOUT_DEFAULT 30
6571
6672 /* Utilities exposed to the test definitions */
6773 #ifndef TH_LOG_STREAM
....@@ -103,26 +109,28 @@
103109
104110 /* Unconditional logger for internal use. */
105111 #define __TH_LOG(fmt, ...) \
106
- fprintf(TH_LOG_STREAM, "%s:%d:%s:" fmt "\n", \
112
+ fprintf(TH_LOG_STREAM, "# %s:%d:%s:" fmt "\n", \
107113 __FILE__, __LINE__, _metadata->name, ##__VA_ARGS__)
108114
109115 /**
110
- * XFAIL(statement, fmt, ...)
116
+ * SKIP(statement, fmt, ...)
111117 *
112
- * @statement: statement to run after reporting XFAIL
118
+ * @statement: statement to run after reporting SKIP
113119 * @fmt: format string
114120 * @...: optional arguments
115121 *
116
- * This forces a "pass" after reporting a failure with an XFAIL prefix,
122
+ * This forces a "pass" after reporting why something is being skipped
117123 * and runs "statement", which is usually "return" or "goto skip".
118124 */
119
-#define XFAIL(statement, fmt, ...) do { \
125
+#define SKIP(statement, fmt, ...) do { \
126
+ snprintf(_metadata->results->reason, \
127
+ sizeof(_metadata->results->reason), fmt, ##__VA_ARGS__); \
120128 if (TH_LOG_ENABLED) { \
121
- fprintf(TH_LOG_STREAM, "[ XFAIL! ] " fmt "\n", \
122
- ##__VA_ARGS__); \
129
+ fprintf(TH_LOG_STREAM, "# SKIP %s\n", \
130
+ _metadata->results->reason); \
123131 } \
124
- /* TODO: find a way to pass xfail to test runner process. */ \
125132 _metadata->passed = 1; \
133
+ _metadata->skip = 1; \
126134 _metadata->trigger = 0; \
127135 statement; \
128136 } while (0)
....@@ -167,9 +175,18 @@
167175
168176 #define __TEST_IMPL(test_name, _signal) \
169177 static void test_name(struct __test_metadata *_metadata); \
178
+ static inline void wrapper_##test_name( \
179
+ struct __test_metadata *_metadata, \
180
+ struct __fixture_variant_metadata *variant) \
181
+ { \
182
+ test_name(_metadata); \
183
+ } \
170184 static struct __test_metadata _##test_name##_object = \
171
- { name: "global." #test_name, \
172
- fn: &test_name, termsig: _signal }; \
185
+ { .name = #test_name, \
186
+ .fn = &wrapper_##test_name, \
187
+ .fixture = &_fixture_global, \
188
+ .termsig = _signal, \
189
+ .timeout = TEST_TIMEOUT_DEFAULT, }; \
173190 static void __attribute__((constructor)) _register_##test_name(void) \
174191 { \
175192 __register_test(&_##test_name##_object); \
....@@ -185,8 +202,9 @@
185202 *
186203 * .. code-block:: c
187204 *
188
- * FIXTURE_DATA(datatype name)
205
+ * FIXTURE_DATA(datatype_name)
189206 *
207
+ * Almost always, you want just FIXTURE() instead (see below).
190208 * This call may be used when the type of the fixture data
191209 * is needed. In general, this should not be needed unless
192210 * the *self* is being passed to a helper directly.
....@@ -201,7 +219,7 @@
201219 *
202220 * .. code-block:: c
203221 *
204
- * FIXTURE(datatype name) {
222
+ * FIXTURE(fixture_name) {
205223 * type property1;
206224 * ...
207225 * };
....@@ -210,10 +228,13 @@
210228 * populated and cleaned up using FIXTURE_SETUP() and FIXTURE_TEARDOWN().
211229 */
212230 #define FIXTURE(fixture_name) \
231
+ FIXTURE_VARIANT(fixture_name); \
232
+ static struct __fixture_metadata _##fixture_name##_fixture_object = \
233
+ { .name = #fixture_name, }; \
213234 static void __attribute__((constructor)) \
214235 _register_##fixture_name##_data(void) \
215236 { \
216
- __fixture_count++; \
237
+ __register_fixture(&_##fixture_name##_fixture_object); \
217238 } \
218239 FIXTURE_DATA(fixture_name)
219240
....@@ -225,7 +246,7 @@
225246 *
226247 * .. code-block:: c
227248 *
228
- * FIXTURE_SETUP(fixture name) { implementation }
249
+ * FIXTURE_SETUP(fixture_name) { implementation }
229250 *
230251 * Populates the required "setup" function for a fixture. An instance of the
231252 * datatype defined with FIXTURE_DATA() will be exposed as *self* for the
....@@ -239,7 +260,10 @@
239260 #define FIXTURE_SETUP(fixture_name) \
240261 void fixture_name##_setup( \
241262 struct __test_metadata __attribute__((unused)) *_metadata, \
242
- FIXTURE_DATA(fixture_name) __attribute__((unused)) *self)
263
+ FIXTURE_DATA(fixture_name) __attribute__((unused)) *self, \
264
+ const FIXTURE_VARIANT(fixture_name) \
265
+ __attribute__((unused)) *variant)
266
+
243267 /**
244268 * FIXTURE_TEARDOWN(fixture_name)
245269 * *_metadata* is included so that EXPECT_* and ASSERT_* work correctly.
....@@ -248,7 +272,7 @@
248272 *
249273 * .. code-block:: c
250274 *
251
- * FIXTURE_TEARDOWN(fixture name) { implementation }
275
+ * FIXTURE_TEARDOWN(fixture_name) { implementation }
252276 *
253277 * Populates the required "teardown" function for a fixture. An instance of the
254278 * datatype defined with FIXTURE_DATA() will be exposed as *self* for the
....@@ -260,6 +284,59 @@
260284 void fixture_name##_teardown( \
261285 struct __test_metadata __attribute__((unused)) *_metadata, \
262286 FIXTURE_DATA(fixture_name) __attribute__((unused)) *self)
287
+
288
+/**
289
+ * FIXTURE_VARIANT(fixture_name) - Optionally called once per fixture
290
+ * to declare fixture variant
291
+ *
292
+ * @fixture_name: fixture name
293
+ *
294
+ * .. code-block:: c
295
+ *
296
+ * FIXTURE_VARIANT(fixture_name) {
297
+ * type property1;
298
+ * ...
299
+ * };
300
+ *
301
+ * Defines type of constant parameters provided to FIXTURE_SETUP() and TEST_F()
302
+ * as *variant*. Variants allow the same tests to be run with different
303
+ * arguments.
304
+ */
305
+#define FIXTURE_VARIANT(fixture_name) struct _fixture_variant_##fixture_name
306
+
307
+/**
308
+ * FIXTURE_VARIANT_ADD(fixture_name, variant_name) - Called once per fixture
309
+ * variant to setup and register the data
310
+ *
311
+ * @fixture_name: fixture name
312
+ * @variant_name: name of the parameter set
313
+ *
314
+ * .. code-block:: c
315
+ *
316
+ * FIXTURE_VARIANT_ADD(fixture_name, variant_name) {
317
+ * .property1 = val1,
318
+ * ...
319
+ * };
320
+ *
321
+ * Defines a variant of the test fixture, provided to FIXTURE_SETUP() and
322
+ * TEST_F() as *variant*. Tests of each fixture will be run once for each
323
+ * variant.
324
+ */
325
+#define FIXTURE_VARIANT_ADD(fixture_name, variant_name) \
326
+ extern FIXTURE_VARIANT(fixture_name) \
327
+ _##fixture_name##_##variant_name##_variant; \
328
+ static struct __fixture_variant_metadata \
329
+ _##fixture_name##_##variant_name##_object = \
330
+ { .name = #variant_name, \
331
+ .data = &_##fixture_name##_##variant_name##_variant}; \
332
+ static void __attribute__((constructor)) \
333
+ _register_##fixture_name##_##variant_name(void) \
334
+ { \
335
+ __register_fixture_variant(&_##fixture_name##_fixture_object, \
336
+ &_##fixture_name##_##variant_name##_object); \
337
+ } \
338
+ FIXTURE_VARIANT(fixture_name) \
339
+ _##fixture_name##_##variant_name##_variant =
263340
264341 /**
265342 * TEST_F(fixture_name, test_name) - Emits test registration and helpers for
....@@ -280,33 +357,40 @@
280357 */
281358 /* TODO(wad) register fixtures on dedicated test lists. */
282359 #define TEST_F(fixture_name, test_name) \
283
- __TEST_F_IMPL(fixture_name, test_name, -1)
360
+ __TEST_F_IMPL(fixture_name, test_name, -1, TEST_TIMEOUT_DEFAULT)
284361
285362 #define TEST_F_SIGNAL(fixture_name, test_name, signal) \
286
- __TEST_F_IMPL(fixture_name, test_name, signal)
363
+ __TEST_F_IMPL(fixture_name, test_name, signal, TEST_TIMEOUT_DEFAULT)
287364
288
-#define __TEST_F_IMPL(fixture_name, test_name, signal) \
365
+#define TEST_F_TIMEOUT(fixture_name, test_name, timeout) \
366
+ __TEST_F_IMPL(fixture_name, test_name, -1, timeout)
367
+
368
+#define __TEST_F_IMPL(fixture_name, test_name, signal, tmout) \
289369 static void fixture_name##_##test_name( \
290370 struct __test_metadata *_metadata, \
291
- FIXTURE_DATA(fixture_name) *self); \
371
+ FIXTURE_DATA(fixture_name) *self, \
372
+ const FIXTURE_VARIANT(fixture_name) *variant); \
292373 static inline void wrapper_##fixture_name##_##test_name( \
293
- struct __test_metadata *_metadata) \
374
+ struct __test_metadata *_metadata, \
375
+ struct __fixture_variant_metadata *variant) \
294376 { \
295377 /* fixture data is alloced, setup, and torn down per call. */ \
296378 FIXTURE_DATA(fixture_name) self; \
297379 memset(&self, 0, sizeof(FIXTURE_DATA(fixture_name))); \
298
- fixture_name##_setup(_metadata, &self); \
380
+ fixture_name##_setup(_metadata, &self, variant->data); \
299381 /* Let setup failure terminate early. */ \
300382 if (!_metadata->passed) \
301383 return; \
302
- fixture_name##_##test_name(_metadata, &self); \
384
+ fixture_name##_##test_name(_metadata, &self, variant->data); \
303385 fixture_name##_teardown(_metadata, &self); \
304386 } \
305387 static struct __test_metadata \
306388 _##fixture_name##_##test_name##_object = { \
307
- name: #fixture_name "." #test_name, \
308
- fn: &wrapper_##fixture_name##_##test_name, \
309
- termsig: signal, \
389
+ .name = #test_name, \
390
+ .fn = &wrapper_##fixture_name##_##test_name, \
391
+ .fixture = &_##fixture_name##_fixture_object, \
392
+ .termsig = signal, \
393
+ .timeout = tmout, \
310394 }; \
311395 static void __attribute__((constructor)) \
312396 _register_##fixture_name##_##test_name(void) \
....@@ -315,7 +399,9 @@
315399 } \
316400 static void fixture_name##_##test_name( \
317401 struct __test_metadata __attribute__((unused)) *_metadata, \
318
- FIXTURE_DATA(fixture_name) __attribute__((unused)) *self)
402
+ FIXTURE_DATA(fixture_name) __attribute__((unused)) *self, \
403
+ const FIXTURE_VARIANT(fixture_name) \
404
+ __attribute__((unused)) *variant)
319405
320406 /**
321407 * TEST_HARNESS_MAIN - Simple wrapper to run the test harness
....@@ -346,7 +432,7 @@
346432 */
347433
348434 /**
349
- * ASSERT_EQ(expected, seen)
435
+ * ASSERT_EQ()
350436 *
351437 * @expected: expected value
352438 * @seen: measured value
....@@ -357,7 +443,7 @@
357443 __EXPECT(expected, #expected, seen, #seen, ==, 1)
358444
359445 /**
360
- * ASSERT_NE(expected, seen)
446
+ * ASSERT_NE()
361447 *
362448 * @expected: expected value
363449 * @seen: measured value
....@@ -368,7 +454,7 @@
368454 __EXPECT(expected, #expected, seen, #seen, !=, 1)
369455
370456 /**
371
- * ASSERT_LT(expected, seen)
457
+ * ASSERT_LT()
372458 *
373459 * @expected: expected value
374460 * @seen: measured value
....@@ -379,7 +465,7 @@
379465 __EXPECT(expected, #expected, seen, #seen, <, 1)
380466
381467 /**
382
- * ASSERT_LE(expected, seen)
468
+ * ASSERT_LE()
383469 *
384470 * @expected: expected value
385471 * @seen: measured value
....@@ -390,7 +476,7 @@
390476 __EXPECT(expected, #expected, seen, #seen, <=, 1)
391477
392478 /**
393
- * ASSERT_GT(expected, seen)
479
+ * ASSERT_GT()
394480 *
395481 * @expected: expected value
396482 * @seen: measured value
....@@ -401,7 +487,7 @@
401487 __EXPECT(expected, #expected, seen, #seen, >, 1)
402488
403489 /**
404
- * ASSERT_GE(expected, seen)
490
+ * ASSERT_GE()
405491 *
406492 * @expected: expected value
407493 * @seen: measured value
....@@ -412,7 +498,7 @@
412498 __EXPECT(expected, #expected, seen, #seen, >=, 1)
413499
414500 /**
415
- * ASSERT_NULL(seen)
501
+ * ASSERT_NULL()
416502 *
417503 * @seen: measured value
418504 *
....@@ -422,7 +508,7 @@
422508 __EXPECT(NULL, "NULL", seen, #seen, ==, 1)
423509
424510 /**
425
- * ASSERT_TRUE(seen)
511
+ * ASSERT_TRUE()
426512 *
427513 * @seen: measured value
428514 *
....@@ -432,7 +518,7 @@
432518 __EXPECT(0, "0", seen, #seen, !=, 1)
433519
434520 /**
435
- * ASSERT_FALSE(seen)
521
+ * ASSERT_FALSE()
436522 *
437523 * @seen: measured value
438524 *
....@@ -442,7 +528,7 @@
442528 __EXPECT(0, "0", seen, #seen, ==, 1)
443529
444530 /**
445
- * ASSERT_STREQ(expected, seen)
531
+ * ASSERT_STREQ()
446532 *
447533 * @expected: expected value
448534 * @seen: measured value
....@@ -453,7 +539,7 @@
453539 __EXPECT_STR(expected, seen, ==, 1)
454540
455541 /**
456
- * ASSERT_STRNE(expected, seen)
542
+ * ASSERT_STRNE()
457543 *
458544 * @expected: expected value
459545 * @seen: measured value
....@@ -464,7 +550,7 @@
464550 __EXPECT_STR(expected, seen, !=, 1)
465551
466552 /**
467
- * EXPECT_EQ(expected, seen)
553
+ * EXPECT_EQ()
468554 *
469555 * @expected: expected value
470556 * @seen: measured value
....@@ -475,7 +561,7 @@
475561 __EXPECT(expected, #expected, seen, #seen, ==, 0)
476562
477563 /**
478
- * EXPECT_NE(expected, seen)
564
+ * EXPECT_NE()
479565 *
480566 * @expected: expected value
481567 * @seen: measured value
....@@ -486,7 +572,7 @@
486572 __EXPECT(expected, #expected, seen, #seen, !=, 0)
487573
488574 /**
489
- * EXPECT_LT(expected, seen)
575
+ * EXPECT_LT()
490576 *
491577 * @expected: expected value
492578 * @seen: measured value
....@@ -497,7 +583,7 @@
497583 __EXPECT(expected, #expected, seen, #seen, <, 0)
498584
499585 /**
500
- * EXPECT_LE(expected, seen)
586
+ * EXPECT_LE()
501587 *
502588 * @expected: expected value
503589 * @seen: measured value
....@@ -508,7 +594,7 @@
508594 __EXPECT(expected, #expected, seen, #seen, <=, 0)
509595
510596 /**
511
- * EXPECT_GT(expected, seen)
597
+ * EXPECT_GT()
512598 *
513599 * @expected: expected value
514600 * @seen: measured value
....@@ -519,7 +605,7 @@
519605 __EXPECT(expected, #expected, seen, #seen, >, 0)
520606
521607 /**
522
- * EXPECT_GE(expected, seen)
608
+ * EXPECT_GE()
523609 *
524610 * @expected: expected value
525611 * @seen: measured value
....@@ -530,7 +616,7 @@
530616 __EXPECT(expected, #expected, seen, #seen, >=, 0)
531617
532618 /**
533
- * EXPECT_NULL(seen)
619
+ * EXPECT_NULL()
534620 *
535621 * @seen: measured value
536622 *
....@@ -540,7 +626,7 @@
540626 __EXPECT(NULL, "NULL", seen, #seen, ==, 0)
541627
542628 /**
543
- * EXPECT_TRUE(seen)
629
+ * EXPECT_TRUE()
544630 *
545631 * @seen: measured value
546632 *
....@@ -550,7 +636,7 @@
550636 __EXPECT(0, "0", seen, #seen, !=, 0)
551637
552638 /**
553
- * EXPECT_FALSE(seen)
639
+ * EXPECT_FALSE()
554640 *
555641 * @seen: measured value
556642 *
....@@ -560,7 +646,7 @@
560646 __EXPECT(0, "0", seen, #seen, ==, 0)
561647
562648 /**
563
- * EXPECT_STREQ(expected, seen)
649
+ * EXPECT_STREQ()
564650 *
565651 * @expected: expected value
566652 * @seen: measured value
....@@ -571,7 +657,7 @@
571657 __EXPECT_STR(expected, seen, ==, 0)
572658
573659 /**
574
- * EXPECT_STRNE(expected, seen)
660
+ * EXPECT_STRNE()
575661 *
576662 * @expected: expected value
577663 * @seen: measured value
....@@ -594,8 +680,11 @@
594680 __bail(_assert, _metadata->no_print, _metadata->step))
595681
596682 #define __INC_STEP(_metadata) \
597
- if (_metadata->passed && _metadata->step < 255) \
683
+ /* Keep "step" below 255 (which is used for "SKIP" reporting). */ \
684
+ if (_metadata->passed && _metadata->step < 253) \
598685 _metadata->step++;
686
+
687
+#define is_signed_type(var) (!!(((__typeof__(var))(-1)) < (__typeof__(var))1))
599688
600689 #define __EXPECT(_expected, _expected_str, _seen, _seen_str, _t, _assert) do { \
601690 /* Avoid multiple evaluation of the cases */ \
....@@ -603,11 +692,41 @@
603692 __typeof__(_seen) __seen = (_seen); \
604693 if (_assert) __INC_STEP(_metadata); \
605694 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_str, __exp_print, #_t, \
610
- _seen_str, __seen_print); \
695
+ /* Report with actual signedness to avoid weird output. */ \
696
+ switch (is_signed_type(__exp) * 2 + is_signed_type(__seen)) { \
697
+ case 0: { \
698
+ unsigned long long __exp_print = (uintptr_t)__exp; \
699
+ unsigned long long __seen_print = (uintptr_t)__seen; \
700
+ __TH_LOG("Expected %s (%llu) %s %s (%llu)", \
701
+ _expected_str, __exp_print, #_t, \
702
+ _seen_str, __seen_print); \
703
+ break; \
704
+ } \
705
+ case 1: { \
706
+ unsigned long long __exp_print = (uintptr_t)__exp; \
707
+ long long __seen_print = (intptr_t)__seen; \
708
+ __TH_LOG("Expected %s (%llu) %s %s (%lld)", \
709
+ _expected_str, __exp_print, #_t, \
710
+ _seen_str, __seen_print); \
711
+ break; \
712
+ } \
713
+ case 2: { \
714
+ long long __exp_print = (intptr_t)__exp; \
715
+ unsigned long long __seen_print = (uintptr_t)__seen; \
716
+ __TH_LOG("Expected %s (%lld) %s %s (%llu)", \
717
+ _expected_str, __exp_print, #_t, \
718
+ _seen_str, __seen_print); \
719
+ break; \
720
+ } \
721
+ case 3: { \
722
+ long long __exp_print = (intptr_t)__exp; \
723
+ long long __seen_print = (intptr_t)__seen; \
724
+ __TH_LOG("Expected %s (%lld) %s %s (%lld)", \
725
+ _expected_str, __exp_print, #_t, \
726
+ _seen_str, __seen_print); \
727
+ break; \
728
+ } \
729
+ } \
611730 _metadata->passed = 0; \
612731 /* Ensure the optional handler is triggered */ \
613732 _metadata->trigger = 1; \
....@@ -625,26 +744,89 @@
625744 } \
626745 } while (0); OPTIONAL_HANDLER(_assert)
627746
628
-/* Contains all the information for test execution and status checking. */
629
-struct __test_metadata {
630
- const char *name;
631
- void (*fn)(struct __test_metadata *);
632
- int termsig;
633
- int passed;
634
- int trigger; /* extra handler after the evaluation */
635
- __u8 step;
636
- bool no_print; /* manual trigger when TH_LOG_STREAM is not available */
637
- struct __test_metadata *prev, *next;
747
+/* List helpers */
748
+#define __LIST_APPEND(head, item) \
749
+{ \
750
+ /* Circular linked list where only prev is circular. */ \
751
+ if (head == NULL) { \
752
+ head = item; \
753
+ item->next = NULL; \
754
+ item->prev = item; \
755
+ return; \
756
+ } \
757
+ if (__constructor_order == _CONSTRUCTOR_ORDER_FORWARD) { \
758
+ item->next = NULL; \
759
+ item->prev = head->prev; \
760
+ item->prev->next = item; \
761
+ head->prev = item; \
762
+ } else { \
763
+ item->next = head; \
764
+ item->next->prev = item; \
765
+ item->prev = item; \
766
+ head = item; \
767
+ } \
768
+}
769
+
770
+struct __test_results {
771
+ char reason[1024]; /* Reason for test result */
638772 };
639773
640
-/* Storage for the (global) tests to be run. */
641
-static struct __test_metadata *__test_list;
642
-static unsigned int __test_count;
643
-static unsigned int __fixture_count;
774
+struct __test_metadata;
775
+struct __fixture_variant_metadata;
776
+
777
+/* Contains all the information about a fixture. */
778
+struct __fixture_metadata {
779
+ const char *name;
780
+ struct __test_metadata *tests;
781
+ struct __fixture_variant_metadata *variant;
782
+ struct __fixture_metadata *prev, *next;
783
+} _fixture_global __attribute__((unused)) = {
784
+ .name = "global",
785
+ .prev = &_fixture_global,
786
+};
787
+
788
+static struct __fixture_metadata *__fixture_list = &_fixture_global;
644789 static int __constructor_order;
645790
646791 #define _CONSTRUCTOR_ORDER_FORWARD 1
647792 #define _CONSTRUCTOR_ORDER_BACKWARD -1
793
+
794
+static inline void __register_fixture(struct __fixture_metadata *f)
795
+{
796
+ __LIST_APPEND(__fixture_list, f);
797
+}
798
+
799
+struct __fixture_variant_metadata {
800
+ const char *name;
801
+ const void *data;
802
+ struct __fixture_variant_metadata *prev, *next;
803
+};
804
+
805
+static inline void
806
+__register_fixture_variant(struct __fixture_metadata *f,
807
+ struct __fixture_variant_metadata *variant)
808
+{
809
+ __LIST_APPEND(f->variant, variant);
810
+}
811
+
812
+/* Contains all the information for test execution and status checking. */
813
+struct __test_metadata {
814
+ const char *name;
815
+ void (*fn)(struct __test_metadata *,
816
+ struct __fixture_variant_metadata *);
817
+ pid_t pid; /* pid of test when being run */
818
+ struct __fixture_metadata *fixture;
819
+ int termsig;
820
+ int passed;
821
+ int skip; /* did SKIP get used? */
822
+ int trigger; /* extra handler after the evaluation */
823
+ int timeout; /* seconds to wait for test timeout */
824
+ bool timed_out; /* did this test timeout instead of exiting? */
825
+ __u8 step;
826
+ bool no_print; /* manual trigger when TH_LOG_STREAM is not available */
827
+ struct __test_results *results;
828
+ struct __test_metadata *prev, *next;
829
+};
648830
649831 /*
650832 * Since constructors are called in reverse order, reverse the test
....@@ -657,25 +839,7 @@
657839 */
658840 static inline void __register_test(struct __test_metadata *t)
659841 {
660
- __test_count++;
661
- /* Circular linked list where only prev is circular. */
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
- }
842
+ __LIST_APPEND(t->fixture->tests, t);
679843 }
680844
681845 static inline int __bail(int for_realz, bool no_print, __u8 step)
....@@ -688,86 +852,208 @@
688852 return 0;
689853 }
690854
691
-void __run_test(struct __test_metadata *t)
855
+struct __test_metadata *__active_test;
856
+static void __timeout_handler(int sig, siginfo_t *info, void *ucontext)
692857 {
693
- pid_t child_pid;
858
+ struct __test_metadata *t = __active_test;
859
+
860
+ /* Sanity check handler execution environment. */
861
+ if (!t) {
862
+ fprintf(TH_LOG_STREAM,
863
+ "# no active test in SIGALRM handler!?\n");
864
+ abort();
865
+ }
866
+ if (sig != SIGALRM || sig != info->si_signo) {
867
+ fprintf(TH_LOG_STREAM,
868
+ "# %s: SIGALRM handler caught signal %d!?\n",
869
+ t->name, sig != SIGALRM ? sig : info->si_signo);
870
+ abort();
871
+ }
872
+
873
+ t->timed_out = true;
874
+ // signal process group
875
+ kill(-(t->pid), SIGKILL);
876
+}
877
+
878
+void __wait_for_test(struct __test_metadata *t)
879
+{
880
+ struct sigaction action = {
881
+ .sa_sigaction = __timeout_handler,
882
+ .sa_flags = SA_SIGINFO,
883
+ };
884
+ struct sigaction saved_action;
694885 int status;
695886
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");
887
+ if (sigaction(SIGALRM, &action, &saved_action)) {
702888 t->passed = 0;
703
- } else if (child_pid == 0) {
704
- t->fn(t);
705
- /* return the step that failed or 0 */
706
- _exit(t->passed ? 0 : t->step);
707
- } else {
708
- /* TODO(wad) add timeout support. */
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)) {
889
+ fprintf(TH_LOG_STREAM,
890
+ "# %s: unable to install SIGALRM handler\n",
891
+ t->name);
892
+ return;
893
+ }
894
+ __active_test = t;
895
+ t->timed_out = false;
896
+ alarm(t->timeout);
897
+ waitpid(t->pid, &status, 0);
898
+ alarm(0);
899
+ if (sigaction(SIGALRM, &saved_action, NULL)) {
900
+ t->passed = 0;
901
+ fprintf(TH_LOG_STREAM,
902
+ "# %s: unable to uninstall SIGALRM handler\n",
903
+ t->name);
904
+ return;
905
+ }
906
+ __active_test = NULL;
907
+
908
+ if (t->timed_out) {
909
+ t->passed = 0;
910
+ fprintf(TH_LOG_STREAM,
911
+ "# %s: Test terminated by timeout\n", t->name);
912
+ } else if (WIFEXITED(status)) {
913
+ if (WEXITSTATUS(status) == 255) {
914
+ /* SKIP */
915
+ t->passed = 1;
916
+ t->skip = 1;
917
+ } else if (t->termsig != -1) {
725918 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) {
919
+ fprintf(TH_LOG_STREAM,
920
+ "# %s: Test exited normally instead of by signal (code: %d)\n",
921
+ t->name,
922
+ WEXITSTATUS(status));
923
+ } else {
924
+ switch (WEXITSTATUS(status)) {
925
+ /* Success */
926
+ case 0:
731927 t->passed = 1;
732
- } else {
928
+ break;
929
+ /* Other failure, assume step report. */
930
+ default:
931
+ t->passed = 0;
733932 fprintf(TH_LOG_STREAM,
734
- "%s: Test terminated unexpectedly "
735
- "by signal %d\n",
933
+ "# %s: Test failed at step #%d\n",
736934 t->name,
737
- WTERMSIG(status));
935
+ WEXITSTATUS(status));
738936 }
937
+ }
938
+ } else if (WIFSIGNALED(status)) {
939
+ t->passed = 0;
940
+ if (WTERMSIG(status) == SIGABRT) {
941
+ fprintf(TH_LOG_STREAM,
942
+ "# %s: Test terminated by assertion\n",
943
+ t->name);
944
+ } else if (WTERMSIG(status) == t->termsig) {
945
+ t->passed = 1;
739946 } else {
740947 fprintf(TH_LOG_STREAM,
741
- "%s: Test ended in some other way [%u]\n",
948
+ "# %s: Test terminated unexpectedly by signal %d\n",
742949 t->name,
743
- status);
950
+ WTERMSIG(status));
744951 }
952
+ } else {
953
+ fprintf(TH_LOG_STREAM,
954
+ "# %s: Test ended in some other way [%u]\n",
955
+ t->name,
956
+ status);
745957 }
746
- printf("[ %4s ] %s\n", (t->passed ? "OK" : "FAIL"), t->name);
958
+}
959
+
960
+void __run_test(struct __fixture_metadata *f,
961
+ struct __fixture_variant_metadata *variant,
962
+ struct __test_metadata *t)
963
+{
964
+ /* reset test struct */
965
+ t->passed = 1;
966
+ t->skip = 0;
967
+ t->trigger = 0;
968
+ t->step = 1;
969
+ t->no_print = 0;
970
+ memset(t->results->reason, 0, sizeof(t->results->reason));
971
+
972
+ ksft_print_msg(" RUN %s%s%s.%s ...\n",
973
+ f->name, variant->name[0] ? "." : "", variant->name, t->name);
974
+
975
+ /* Make sure output buffers are flushed before fork */
976
+ fflush(stdout);
977
+ fflush(stderr);
978
+
979
+ t->pid = fork();
980
+ if (t->pid < 0) {
981
+ ksft_print_msg("ERROR SPAWNING TEST CHILD\n");
982
+ t->passed = 0;
983
+ } else if (t->pid == 0) {
984
+ setpgrp();
985
+ t->fn(t, variant);
986
+ if (t->skip)
987
+ _exit(255);
988
+ /* Pass is exit 0 */
989
+ if (t->passed)
990
+ _exit(0);
991
+ /* Something else happened, report the step. */
992
+ _exit(t->step);
993
+ } else {
994
+ __wait_for_test(t);
995
+ }
996
+ ksft_print_msg(" %4s %s%s%s.%s\n", t->passed ? "OK" : "FAIL",
997
+ f->name, variant->name[0] ? "." : "", variant->name, t->name);
998
+
999
+ if (t->skip)
1000
+ ksft_test_result_skip("%s\n", t->results->reason[0] ?
1001
+ t->results->reason : "unknown");
1002
+ else
1003
+ ksft_test_result(t->passed, "%s%s%s.%s\n",
1004
+ f->name, variant->name[0] ? "." : "", variant->name, t->name);
7471005 }
7481006
7491007 static int test_harness_run(int __attribute__((unused)) argc,
7501008 char __attribute__((unused)) **argv)
7511009 {
1010
+ struct __fixture_variant_metadata no_variant = { .name = "", };
1011
+ struct __fixture_variant_metadata *v;
1012
+ struct __fixture_metadata *f;
1013
+ struct __test_results *results;
7521014 struct __test_metadata *t;
7531015 int ret = 0;
1016
+ unsigned int case_count = 0, test_count = 0;
7541017 unsigned int count = 0;
7551018 unsigned int pass_count = 0;
7561019
757
- /* TODO(wad) add optional arguments similar to gtest. */
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;
1020
+ for (f = __fixture_list; f; f = f->next) {
1021
+ for (v = f->variant ?: &no_variant; v; v = v->next) {
1022
+ case_count++;
1023
+ for (t = f->tests; t; t = t->next)
1024
+ test_count++;
1025
+ }
7671026 }
768
- printf("[==========] %u / %u tests passed.\n", pass_count, count);
769
- printf("[ %s ]\n", (ret ? "FAILED" : "PASSED"));
770
- return ret;
1027
+
1028
+ results = mmap(NULL, sizeof(*results), PROT_READ | PROT_WRITE,
1029
+ MAP_SHARED | MAP_ANONYMOUS, -1, 0);
1030
+
1031
+ ksft_print_header();
1032
+ ksft_set_plan(test_count);
1033
+ ksft_print_msg("Starting %u tests from %u test cases.\n",
1034
+ test_count, case_count);
1035
+ for (f = __fixture_list; f; f = f->next) {
1036
+ for (v = f->variant ?: &no_variant; v; v = v->next) {
1037
+ for (t = f->tests; t; t = t->next) {
1038
+ count++;
1039
+ t->results = results;
1040
+ __run_test(f, v, t);
1041
+ t->results = NULL;
1042
+ if (t->passed)
1043
+ pass_count++;
1044
+ else
1045
+ ret = 1;
1046
+ }
1047
+ }
1048
+ }
1049
+ munmap(results, sizeof(*results));
1050
+
1051
+ ksft_print_msg("%s: %u / %u tests passed.\n", ret ? "FAILED" : "PASSED",
1052
+ pass_count, count);
1053
+ ksft_exit(ret == 0);
1054
+
1055
+ /* unreachable */
1056
+ return KSFT_FAIL;
7711057 }
7721058
7731059 static void __attribute__((constructor)) __constructor_order_first(void)