Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

kselftest: add fixture variants

Allow users to build parameterized variants of fixtures.

If fixtures want variants, they call FIXTURE_VARIANT() to declare
the structure to fill for each variant. Each fixture will be re-run
for each of the variants defined by calling FIXTURE_VARIANT_ADD()
with the differing parameters initializing the structure.

Since tests are being re-run, additional initialization (steps,
no_print) is also added.

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Acked-by: Kees Cook <keescook@chromium.org>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Jakub Kicinski and committed by
David S. Miller
74bc7c97 e7f30460

+124 -27
+2 -1
Documentation/dev-tools/kselftest.rst
··· 301 301 302 302 .. kernel-doc:: tools/testing/selftests/kselftest_harness.h 303 303 :functions: TH_LOG TEST TEST_SIGNAL FIXTURE FIXTURE_DATA FIXTURE_SETUP 304 - FIXTURE_TEARDOWN TEST_F TEST_HARNESS_MAIN 304 + FIXTURE_TEARDOWN TEST_F TEST_HARNESS_MAIN FIXTURE_VARIANT 305 + FIXTURE_VARIANT_ADD 305 306 306 307 Operators 307 308 ---------
+122 -26
tools/testing/selftests/kselftest_harness.h
··· 168 168 169 169 #define __TEST_IMPL(test_name, _signal) \ 170 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 + } \ 171 177 static struct __test_metadata _##test_name##_object = \ 172 178 { .name = #test_name, \ 173 - .fn = &test_name, \ 179 + .fn = &wrapper_##test_name, \ 174 180 .fixture = &_fixture_global, \ 175 181 .termsig = _signal, \ 176 182 .timeout = TEST_TIMEOUT_DEFAULT, }; \ ··· 220 214 * populated and cleaned up using FIXTURE_SETUP() and FIXTURE_TEARDOWN(). 221 215 */ 222 216 #define FIXTURE(fixture_name) \ 217 + FIXTURE_VARIANT(fixture_name); \ 223 218 static struct __fixture_metadata _##fixture_name##_fixture_object = \ 224 219 { .name = #fixture_name, }; \ 225 220 static void __attribute__((constructor)) \ ··· 252 245 #define FIXTURE_SETUP(fixture_name) \ 253 246 void fixture_name##_setup( \ 254 247 struct __test_metadata __attribute__((unused)) *_metadata, \ 255 - FIXTURE_DATA(fixture_name) __attribute__((unused)) *self) 248 + FIXTURE_DATA(fixture_name) __attribute__((unused)) *self, \ 249 + const FIXTURE_VARIANT(fixture_name) \ 250 + __attribute__((unused)) *variant) 251 + 256 252 /** 257 253 * FIXTURE_TEARDOWN(fixture_name) 258 254 * *_metadata* is included so that EXPECT_* and ASSERT_* work correctly. ··· 276 266 void fixture_name##_teardown( \ 277 267 struct __test_metadata __attribute__((unused)) *_metadata, \ 278 268 FIXTURE_DATA(fixture_name) __attribute__((unused)) *self) 269 + 270 + /** 271 + * FIXTURE_VARIANT(fixture_name) - Optionally called once per fixture 272 + * to declare fixture variant 273 + * 274 + * @fixture_name: fixture name 275 + * 276 + * .. code-block:: c 277 + * 278 + * FIXTURE_VARIANT(datatype name) { 279 + * type property1; 280 + * ... 281 + * }; 282 + * 283 + * Defines type of constant parameters provided to FIXTURE_SETUP() and TEST_F() 284 + * as *variant*. Variants allow the same tests to be run with different 285 + * arguments. 286 + */ 287 + #define FIXTURE_VARIANT(fixture_name) struct _fixture_variant_##fixture_name 288 + 289 + /** 290 + * FIXTURE_VARIANT_ADD(fixture_name, variant_name) - Called once per fixture 291 + * variant to setup and register the data 292 + * 293 + * @fixture_name: fixture name 294 + * @variant_name: name of the parameter set 295 + * 296 + * .. code-block:: c 297 + * 298 + * FIXTURE_ADD(datatype name) { 299 + * .property1 = val1; 300 + * ... 301 + * }; 302 + * 303 + * Defines a variant of the test fixture, provided to FIXTURE_SETUP() and 304 + * TEST_F() as *variant*. Tests of each fixture will be run once for each 305 + * variant. 306 + */ 307 + #define FIXTURE_VARIANT_ADD(fixture_name, variant_name) \ 308 + extern FIXTURE_VARIANT(fixture_name) \ 309 + _##fixture_name##_##variant_name##_variant; \ 310 + static struct __fixture_variant_metadata \ 311 + _##fixture_name##_##variant_name##_object = \ 312 + { .name = #variant_name, \ 313 + .data = &_##fixture_name##_##variant_name##_variant}; \ 314 + static void __attribute__((constructor)) \ 315 + _register_##fixture_name##_##variant_name(void) \ 316 + { \ 317 + __register_fixture_variant(&_##fixture_name##_fixture_object, \ 318 + &_##fixture_name##_##variant_name##_object); \ 319 + } \ 320 + FIXTURE_VARIANT(fixture_name) \ 321 + _##fixture_name##_##variant_name##_variant = 279 322 280 323 /** 281 324 * TEST_F(fixture_name, test_name) - Emits test registration and helpers for ··· 360 297 #define __TEST_F_IMPL(fixture_name, test_name, signal, tmout) \ 361 298 static void fixture_name##_##test_name( \ 362 299 struct __test_metadata *_metadata, \ 363 - FIXTURE_DATA(fixture_name) *self); \ 300 + FIXTURE_DATA(fixture_name) *self, \ 301 + const FIXTURE_VARIANT(fixture_name) *variant); \ 364 302 static inline void wrapper_##fixture_name##_##test_name( \ 365 - struct __test_metadata *_metadata) \ 303 + struct __test_metadata *_metadata, \ 304 + struct __fixture_variant_metadata *variant) \ 366 305 { \ 367 306 /* fixture data is alloced, setup, and torn down per call. */ \ 368 307 FIXTURE_DATA(fixture_name) self; \ 369 308 memset(&self, 0, sizeof(FIXTURE_DATA(fixture_name))); \ 370 - fixture_name##_setup(_metadata, &self); \ 309 + fixture_name##_setup(_metadata, &self, variant->data); \ 371 310 /* Let setup failure terminate early. */ \ 372 311 if (!_metadata->passed) \ 373 312 return; \ 374 - fixture_name##_##test_name(_metadata, &self); \ 313 + fixture_name##_##test_name(_metadata, &self, variant->data); \ 375 314 fixture_name##_teardown(_metadata, &self); \ 376 315 } \ 377 316 static struct __test_metadata \ ··· 391 326 } \ 392 327 static void fixture_name##_##test_name( \ 393 328 struct __test_metadata __attribute__((unused)) *_metadata, \ 394 - FIXTURE_DATA(fixture_name) __attribute__((unused)) *self) 329 + FIXTURE_DATA(fixture_name) __attribute__((unused)) *self, \ 330 + const FIXTURE_VARIANT(fixture_name) \ 331 + __attribute__((unused)) *variant) 395 332 396 333 /** 397 334 * TEST_HARNESS_MAIN - Simple wrapper to run the test harness ··· 727 660 } 728 661 729 662 struct __test_metadata; 663 + struct __fixture_variant_metadata; 730 664 731 665 /* Contains all the information about a fixture. */ 732 666 struct __fixture_metadata { 733 667 const char *name; 734 668 struct __test_metadata *tests; 669 + struct __fixture_variant_metadata *variant; 735 670 struct __fixture_metadata *prev, *next; 736 671 } _fixture_global __attribute__((unused)) = { 737 672 .name = "global", ··· 741 672 }; 742 673 743 674 static struct __fixture_metadata *__fixture_list = &_fixture_global; 744 - static unsigned int __fixture_count; 745 675 static int __constructor_order; 746 676 747 677 #define _CONSTRUCTOR_ORDER_FORWARD 1 ··· 748 680 749 681 static inline void __register_fixture(struct __fixture_metadata *f) 750 682 { 751 - __fixture_count++; 752 683 __LIST_APPEND(__fixture_list, f); 684 + } 685 + 686 + struct __fixture_variant_metadata { 687 + const char *name; 688 + const void *data; 689 + struct __fixture_variant_metadata *prev, *next; 690 + }; 691 + 692 + static inline void 693 + __register_fixture_variant(struct __fixture_metadata *f, 694 + struct __fixture_variant_metadata *variant) 695 + { 696 + __LIST_APPEND(f->variant, variant); 753 697 } 754 698 755 699 /* Contains all the information for test execution and status checking. */ 756 700 struct __test_metadata { 757 701 const char *name; 758 - void (*fn)(struct __test_metadata *); 702 + void (*fn)(struct __test_metadata *, 703 + struct __fixture_variant_metadata *); 759 704 pid_t pid; /* pid of test when being run */ 760 705 struct __fixture_metadata *fixture; 761 706 int termsig; ··· 781 700 struct __test_metadata *prev, *next; 782 701 }; 783 702 784 - /* Storage for the (global) tests to be run. */ 785 - static unsigned int __test_count; 786 - 787 703 /* 788 704 * Since constructors are called in reverse order, reverse the test 789 705 * list so tests are run in source declaration order. ··· 792 714 */ 793 715 static inline void __register_test(struct __test_metadata *t) 794 716 { 795 - __test_count++; 796 717 __LIST_APPEND(t->fixture->tests, t); 797 718 } 798 719 ··· 899 822 } 900 823 901 824 void __run_test(struct __fixture_metadata *f, 825 + struct __fixture_variant_metadata *variant, 902 826 struct __test_metadata *t) 903 827 { 828 + /* reset test struct */ 904 829 t->passed = 1; 905 830 t->trigger = 0; 906 - printf("[ RUN ] %s.%s\n", f->name, t->name); 831 + t->step = 0; 832 + t->no_print = 0; 833 + 834 + printf("[ RUN ] %s%s%s.%s\n", 835 + f->name, variant->name[0] ? "." : "", variant->name, t->name); 907 836 t->pid = fork(); 908 837 if (t->pid < 0) { 909 838 printf("ERROR SPAWNING TEST CHILD\n"); 910 839 t->passed = 0; 911 840 } else if (t->pid == 0) { 912 - t->fn(t); 841 + t->fn(t, variant); 913 842 /* return the step that failed or 0 */ 914 843 _exit(t->passed ? 0 : t->step); 915 844 } else { 916 845 __wait_for_test(t); 917 846 } 918 - printf("[ %4s ] %s.%s\n", (t->passed ? "OK" : "FAIL"), 919 - f->name, t->name); 847 + printf("[ %4s ] %s%s%s.%s\n", (t->passed ? "OK" : "FAIL"), 848 + f->name, variant->name[0] ? "." : "", variant->name, t->name); 920 849 } 921 850 922 851 static int test_harness_run(int __attribute__((unused)) argc, 923 852 char __attribute__((unused)) **argv) 924 853 { 854 + struct __fixture_variant_metadata no_variant = { .name = "", }; 855 + struct __fixture_variant_metadata *v; 925 856 struct __fixture_metadata *f; 926 857 struct __test_metadata *t; 927 858 int ret = 0; 859 + unsigned int case_count = 0, test_count = 0; 928 860 unsigned int count = 0; 929 861 unsigned int pass_count = 0; 930 862 863 + for (f = __fixture_list; f; f = f->next) { 864 + for (v = f->variant ?: &no_variant; v; v = v->next) { 865 + case_count++; 866 + for (t = f->tests; t; t = t->next) 867 + test_count++; 868 + } 869 + } 870 + 931 871 /* TODO(wad) add optional arguments similar to gtest. */ 932 872 printf("[==========] Running %u tests from %u test cases.\n", 933 - __test_count, __fixture_count + 1); 873 + test_count, case_count); 934 874 for (f = __fixture_list; f; f = f->next) { 935 - for (t = f->tests; t; t = t->next) { 936 - count++; 937 - __run_test(f, t); 938 - if (t->passed) 939 - pass_count++; 940 - else 941 - ret = 1; 875 + for (v = f->variant ?: &no_variant; v; v = v->next) { 876 + for (t = f->tests; t; t = t->next) { 877 + count++; 878 + __run_test(f, v, t); 879 + if (t->passed) 880 + pass_count++; 881 + else 882 + ret = 1; 883 + } 942 884 } 943 885 } 944 886 printf("[==========] %u / %u tests passed.\n", pass_count, count);