linux/lib/kunit/executor_test.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * KUnit test for the KUnit executor.
   4 *
   5 * Copyright (C) 2021, Google LLC.
   6 * Author: Daniel Latypov <dlatypov@google.com>
   7 */
   8
   9#include <kunit/test.h>
  10
  11static void kfree_at_end(struct kunit *test, const void *to_free);
  12static struct kunit_suite *alloc_fake_suite(struct kunit *test,
  13                                            const char *suite_name,
  14                                            struct kunit_case *test_cases);
  15
  16static void dummy_test(struct kunit *test) {}
  17
  18static struct kunit_case dummy_test_cases[] = {
  19        /* .run_case is not important, just needs to be non-NULL */
  20        { .name = "test1", .run_case = dummy_test },
  21        { .name = "test2", .run_case = dummy_test },
  22        {},
  23};
  24
  25static void parse_filter_test(struct kunit *test)
  26{
  27        struct kunit_test_filter filter = {NULL, NULL};
  28
  29        kunit_parse_filter_glob(&filter, "suite");
  30        KUNIT_EXPECT_STREQ(test, filter.suite_glob, "suite");
  31        KUNIT_EXPECT_FALSE(test, filter.test_glob);
  32        kfree(filter.suite_glob);
  33        kfree(filter.test_glob);
  34
  35        kunit_parse_filter_glob(&filter, "suite.test");
  36        KUNIT_EXPECT_STREQ(test, filter.suite_glob, "suite");
  37        KUNIT_EXPECT_STREQ(test, filter.test_glob, "test");
  38        kfree(filter.suite_glob);
  39        kfree(filter.test_glob);
  40}
  41
  42static void filter_suites_test(struct kunit *test)
  43{
  44        struct kunit_suite *subsuite[3] = {NULL, NULL};
  45        struct suite_set suite_set = {.start = subsuite, .end = &subsuite[2]};
  46        struct suite_set got;
  47        int err = 0;
  48
  49        subsuite[0] = alloc_fake_suite(test, "suite1", dummy_test_cases);
  50        subsuite[1] = alloc_fake_suite(test, "suite2", dummy_test_cases);
  51
  52        /* Want: suite1, suite2, NULL -> suite2, NULL */
  53        got = kunit_filter_suites(&suite_set, "suite2", &err);
  54        KUNIT_ASSERT_NOT_ERR_OR_NULL(test, got.start);
  55        KUNIT_ASSERT_EQ(test, err, 0);
  56        kfree_at_end(test, got.start);
  57
  58        /* Validate we just have suite2 */
  59        KUNIT_ASSERT_NOT_ERR_OR_NULL(test, got.start[0]);
  60        KUNIT_EXPECT_STREQ(test, (const char *)got.start[0]->name, "suite2");
  61
  62        /* Contains one element (end is 1 past end) */
  63        KUNIT_ASSERT_EQ(test, got.end - got.start, 1);
  64}
  65
  66static void filter_suites_test_glob_test(struct kunit *test)
  67{
  68        struct kunit_suite *subsuite[3] = {NULL, NULL};
  69        struct suite_set suite_set = {.start = subsuite, .end = &subsuite[2]};
  70        struct suite_set got;
  71        int err = 0;
  72
  73        subsuite[0] = alloc_fake_suite(test, "suite1", dummy_test_cases);
  74        subsuite[1] = alloc_fake_suite(test, "suite2", dummy_test_cases);
  75
  76        /* Want: suite1, suite2, NULL -> suite2 (just test1), NULL */
  77        got = kunit_filter_suites(&suite_set, "suite2.test2", &err);
  78        KUNIT_ASSERT_NOT_ERR_OR_NULL(test, got.start);
  79        KUNIT_ASSERT_EQ(test, err, 0);
  80        kfree_at_end(test, got.start);
  81
  82        /* Validate we just have suite2 */
  83        KUNIT_ASSERT_NOT_ERR_OR_NULL(test, got.start[0]);
  84        KUNIT_EXPECT_STREQ(test, (const char *)got.start[0]->name, "suite2");
  85        KUNIT_ASSERT_EQ(test, got.end - got.start, 1);
  86
  87        /* Now validate we just have test2 */
  88        KUNIT_ASSERT_NOT_ERR_OR_NULL(test, got.start[0]->test_cases);
  89        KUNIT_EXPECT_STREQ(test, (const char *)got.start[0]->test_cases[0].name, "test2");
  90        KUNIT_EXPECT_FALSE(test, got.start[0]->test_cases[1].name);
  91}
  92
  93static void filter_suites_to_empty_test(struct kunit *test)
  94{
  95        struct kunit_suite *subsuite[3] = {NULL, NULL};
  96        struct suite_set suite_set = {.start = subsuite, .end = &subsuite[2]};
  97        struct suite_set got;
  98        int err = 0;
  99
 100        subsuite[0] = alloc_fake_suite(test, "suite1", dummy_test_cases);
 101        subsuite[1] = alloc_fake_suite(test, "suite2", dummy_test_cases);
 102
 103        got = kunit_filter_suites(&suite_set, "not_found", &err);
 104        KUNIT_ASSERT_EQ(test, err, 0);
 105        kfree_at_end(test, got.start); /* just in case */
 106
 107        KUNIT_EXPECT_PTR_EQ_MSG(test, got.start, got.end,
 108                                "should be empty to indicate no match");
 109}
 110
 111static struct kunit_case executor_test_cases[] = {
 112        KUNIT_CASE(parse_filter_test),
 113        KUNIT_CASE(filter_suites_test),
 114        KUNIT_CASE(filter_suites_test_glob_test),
 115        KUNIT_CASE(filter_suites_to_empty_test),
 116        {}
 117};
 118
 119static struct kunit_suite executor_test_suite = {
 120        .name = "kunit_executor_test",
 121        .test_cases = executor_test_cases,
 122};
 123
 124kunit_test_suites(&executor_test_suite);
 125
 126/* Test helpers */
 127
 128static void kfree_res_free(struct kunit_resource *res)
 129{
 130        kfree(res->data);
 131}
 132
 133/* Use the resource API to register a call to kfree(to_free).
 134 * Since we never actually use the resource, it's safe to use on const data.
 135 */
 136static void kfree_at_end(struct kunit *test, const void *to_free)
 137{
 138        /* kfree() handles NULL already, but avoid allocating a no-op cleanup. */
 139        if (IS_ERR_OR_NULL(to_free))
 140                return;
 141        kunit_alloc_resource(test, NULL, kfree_res_free, GFP_KERNEL,
 142                             (void *)to_free);
 143}
 144
 145static struct kunit_suite *alloc_fake_suite(struct kunit *test,
 146                                            const char *suite_name,
 147                                            struct kunit_case *test_cases)
 148{
 149        struct kunit_suite *suite;
 150
 151        /* We normally never expect to allocate suites, hence the non-const cast. */
 152        suite = kunit_kzalloc(test, sizeof(*suite), GFP_KERNEL);
 153        strncpy((char *)suite->name, suite_name, sizeof(suite->name) - 1);
 154        suite->test_cases = test_cases;
 155
 156        return suite;
 157}
 158