2021-04-21 02:04:27 +00:00
|
|
|
// SPDX-License-Identifier: GPL-2.0
|
|
|
|
/*
|
|
|
|
* KUnit test for the KUnit executor.
|
|
|
|
*
|
|
|
|
* Copyright (C) 2021, Google LLC.
|
|
|
|
* Author: Daniel Latypov <dlatypov@google.com>
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <kunit/test.h>
|
2023-07-25 21:25:19 +00:00
|
|
|
#include <kunit/attributes.h>
|
2021-04-21 02:04:27 +00:00
|
|
|
|
|
|
|
static void kfree_at_end(struct kunit *test, const void *to_free);
|
|
|
|
static struct kunit_suite *alloc_fake_suite(struct kunit *test,
|
2021-09-14 21:03:48 +00:00
|
|
|
const char *suite_name,
|
|
|
|
struct kunit_case *test_cases);
|
|
|
|
|
|
|
|
static void dummy_test(struct kunit *test) {}
|
|
|
|
|
|
|
|
static struct kunit_case dummy_test_cases[] = {
|
|
|
|
/* .run_case is not important, just needs to be non-NULL */
|
|
|
|
{ .name = "test1", .run_case = dummy_test },
|
|
|
|
{ .name = "test2", .run_case = dummy_test },
|
|
|
|
{},
|
|
|
|
};
|
|
|
|
|
|
|
|
static void parse_filter_test(struct kunit *test)
|
|
|
|
{
|
kunit: Add ability to filter attributes
Add filtering of test attributes. Users can filter tests using the
module_param called "filter".
Filters are imputed in the format: <attribute_name><operation><value>
Example: kunit.filter="speed>slow"
Operations include: >, <, >=, <=, !=, and =. These operations will act the
same for attributes of the same type but may not between types.
Note multiple filters can be inputted by separating them with a comma.
Example: kunit.filter="speed=slow, module!=example"
Since both suites and test cases can have attributes, there may be
conflicts. The process of filtering follows these rules:
- Filtering always operates at a per-test level.
- If a test has an attribute set, then the test's value is filtered on.
- Otherwise, the value falls back to the suite's value.
- If neither are set, the attribute has a global "default" value, which
is used.
Filtered tests will not be run or show in output. The tests can instead be
skipped using the configurable option "kunit.filter_action=skip".
Note the default settings for running tests remains unfiltered.
Finally, add "filter" methods for the speed and module attributes to parse
and compare attribute values.
Note this filtering functionality will be added to kunit.py in the next
patch.
Reviewed-by: David Gow <davidgow@google.com>
Signed-off-by: Rae Moar <rmoar@google.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2023-07-25 21:25:15 +00:00
|
|
|
struct kunit_glob_filter filter = {NULL, NULL};
|
2021-09-14 21:03:48 +00:00
|
|
|
|
kunit: Add ability to filter attributes
Add filtering of test attributes. Users can filter tests using the
module_param called "filter".
Filters are imputed in the format: <attribute_name><operation><value>
Example: kunit.filter="speed>slow"
Operations include: >, <, >=, <=, !=, and =. These operations will act the
same for attributes of the same type but may not between types.
Note multiple filters can be inputted by separating them with a comma.
Example: kunit.filter="speed=slow, module!=example"
Since both suites and test cases can have attributes, there may be
conflicts. The process of filtering follows these rules:
- Filtering always operates at a per-test level.
- If a test has an attribute set, then the test's value is filtered on.
- Otherwise, the value falls back to the suite's value.
- If neither are set, the attribute has a global "default" value, which
is used.
Filtered tests will not be run or show in output. The tests can instead be
skipped using the configurable option "kunit.filter_action=skip".
Note the default settings for running tests remains unfiltered.
Finally, add "filter" methods for the speed and module attributes to parse
and compare attribute values.
Note this filtering functionality will be added to kunit.py in the next
patch.
Reviewed-by: David Gow <davidgow@google.com>
Signed-off-by: Rae Moar <rmoar@google.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2023-07-25 21:25:15 +00:00
|
|
|
kunit_parse_glob_filter(&filter, "suite");
|
2021-09-14 21:03:48 +00:00
|
|
|
KUNIT_EXPECT_STREQ(test, filter.suite_glob, "suite");
|
|
|
|
KUNIT_EXPECT_FALSE(test, filter.test_glob);
|
|
|
|
kfree(filter.suite_glob);
|
|
|
|
kfree(filter.test_glob);
|
|
|
|
|
kunit: Add ability to filter attributes
Add filtering of test attributes. Users can filter tests using the
module_param called "filter".
Filters are imputed in the format: <attribute_name><operation><value>
Example: kunit.filter="speed>slow"
Operations include: >, <, >=, <=, !=, and =. These operations will act the
same for attributes of the same type but may not between types.
Note multiple filters can be inputted by separating them with a comma.
Example: kunit.filter="speed=slow, module!=example"
Since both suites and test cases can have attributes, there may be
conflicts. The process of filtering follows these rules:
- Filtering always operates at a per-test level.
- If a test has an attribute set, then the test's value is filtered on.
- Otherwise, the value falls back to the suite's value.
- If neither are set, the attribute has a global "default" value, which
is used.
Filtered tests will not be run or show in output. The tests can instead be
skipped using the configurable option "kunit.filter_action=skip".
Note the default settings for running tests remains unfiltered.
Finally, add "filter" methods for the speed and module attributes to parse
and compare attribute values.
Note this filtering functionality will be added to kunit.py in the next
patch.
Reviewed-by: David Gow <davidgow@google.com>
Signed-off-by: Rae Moar <rmoar@google.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2023-07-25 21:25:15 +00:00
|
|
|
kunit_parse_glob_filter(&filter, "suite.test");
|
2021-09-14 21:03:48 +00:00
|
|
|
KUNIT_EXPECT_STREQ(test, filter.suite_glob, "suite");
|
|
|
|
KUNIT_EXPECT_STREQ(test, filter.test_glob, "test");
|
|
|
|
kfree(filter.suite_glob);
|
|
|
|
kfree(filter.test_glob);
|
|
|
|
}
|
2021-04-21 02:04:27 +00:00
|
|
|
|
2022-07-09 03:19:58 +00:00
|
|
|
static void filter_suites_test(struct kunit *test)
|
2021-04-21 02:04:27 +00:00
|
|
|
{
|
2022-07-09 03:19:58 +00:00
|
|
|
struct kunit_suite *subsuite[3] = {NULL, NULL};
|
kunit: Report the count of test suites in a module
According to KTAP specification[1], results should always start from a
header that provides a TAP protocol version, followed by a test plan with
a count of items to be executed. That pattern should be followed at each
nesting level. In the current implementation of the top-most, i.e., test
suite level, those rules apply only for test suites built into the kernel,
executed and reported on boot. Results submitted to dmesg from kunit test
modules loaded later are missing those top-level headers.
As a consequence, if a kunit test module provides more than one test suite
then, without the top level test plan, external tools that are parsing
dmesg for kunit test output are not able to tell how many test suites
should be expected and whether to continue parsing after complete output
from the first test suite is collected.
Submit the top-level headers also from the kunit test module notifier
initialization callback.
v3: Fix new name of a structure moved to kunit namespace not updated in
executor_test functions (lkp@intel.com).
v2: Use kunit_exec_run_tests() (Mauro, Rae), but prevent it from
emitting the headers when called on load of non-test modules.
[1] https://docs.kernel.org/dev-tools/ktap.html#
Signed-off-by: Janusz Krzysztofik <janusz.krzysztofik@linux.intel.com>
Cc: Mauro Carvalho Chehab <mchehab@kernel.org>
Cc: Rae Moar <rmoar@google.com>
Reviewed-by: Rae Moar <rmoar@google.com>
Reviewed-by: David Gow <davidgow@google.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2023-08-07 10:23:54 +00:00
|
|
|
struct kunit_suite_set suite_set = {
|
|
|
|
.start = subsuite, .end = &subsuite[2],
|
|
|
|
};
|
|
|
|
struct kunit_suite_set got;
|
2022-07-09 03:19:58 +00:00
|
|
|
int err = 0;
|
2021-04-21 02:04:27 +00:00
|
|
|
|
2021-09-14 21:03:48 +00:00
|
|
|
subsuite[0] = alloc_fake_suite(test, "suite1", dummy_test_cases);
|
|
|
|
subsuite[1] = alloc_fake_suite(test, "suite2", dummy_test_cases);
|
2021-04-21 02:04:27 +00:00
|
|
|
|
|
|
|
/* Want: suite1, suite2, NULL -> suite2, NULL */
|
kunit: Add ability to filter attributes
Add filtering of test attributes. Users can filter tests using the
module_param called "filter".
Filters are imputed in the format: <attribute_name><operation><value>
Example: kunit.filter="speed>slow"
Operations include: >, <, >=, <=, !=, and =. These operations will act the
same for attributes of the same type but may not between types.
Note multiple filters can be inputted by separating them with a comma.
Example: kunit.filter="speed=slow, module!=example"
Since both suites and test cases can have attributes, there may be
conflicts. The process of filtering follows these rules:
- Filtering always operates at a per-test level.
- If a test has an attribute set, then the test's value is filtered on.
- Otherwise, the value falls back to the suite's value.
- If neither are set, the attribute has a global "default" value, which
is used.
Filtered tests will not be run or show in output. The tests can instead be
skipped using the configurable option "kunit.filter_action=skip".
Note the default settings for running tests remains unfiltered.
Finally, add "filter" methods for the speed and module attributes to parse
and compare attribute values.
Note this filtering functionality will be added to kunit.py in the next
patch.
Reviewed-by: David Gow <davidgow@google.com>
Signed-off-by: Rae Moar <rmoar@google.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2023-07-25 21:25:15 +00:00
|
|
|
got = kunit_filter_suites(&suite_set, "suite2", NULL, NULL, &err);
|
2022-07-09 03:19:58 +00:00
|
|
|
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, got.start);
|
|
|
|
KUNIT_ASSERT_EQ(test, err, 0);
|
|
|
|
kfree_at_end(test, got.start);
|
2021-04-21 02:04:27 +00:00
|
|
|
|
2021-09-14 21:03:48 +00:00
|
|
|
/* Validate we just have suite2 */
|
2022-07-09 03:19:58 +00:00
|
|
|
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, got.start[0]);
|
|
|
|
KUNIT_EXPECT_STREQ(test, (const char *)got.start[0]->name, "suite2");
|
|
|
|
|
|
|
|
/* Contains one element (end is 1 past end) */
|
|
|
|
KUNIT_ASSERT_EQ(test, got.end - got.start, 1);
|
2021-09-14 21:03:48 +00:00
|
|
|
}
|
|
|
|
|
2022-07-09 03:19:58 +00:00
|
|
|
static void filter_suites_test_glob_test(struct kunit *test)
|
2021-09-14 21:03:48 +00:00
|
|
|
{
|
2022-07-09 03:19:58 +00:00
|
|
|
struct kunit_suite *subsuite[3] = {NULL, NULL};
|
kunit: Report the count of test suites in a module
According to KTAP specification[1], results should always start from a
header that provides a TAP protocol version, followed by a test plan with
a count of items to be executed. That pattern should be followed at each
nesting level. In the current implementation of the top-most, i.e., test
suite level, those rules apply only for test suites built into the kernel,
executed and reported on boot. Results submitted to dmesg from kunit test
modules loaded later are missing those top-level headers.
As a consequence, if a kunit test module provides more than one test suite
then, without the top level test plan, external tools that are parsing
dmesg for kunit test output are not able to tell how many test suites
should be expected and whether to continue parsing after complete output
from the first test suite is collected.
Submit the top-level headers also from the kunit test module notifier
initialization callback.
v3: Fix new name of a structure moved to kunit namespace not updated in
executor_test functions (lkp@intel.com).
v2: Use kunit_exec_run_tests() (Mauro, Rae), but prevent it from
emitting the headers when called on load of non-test modules.
[1] https://docs.kernel.org/dev-tools/ktap.html#
Signed-off-by: Janusz Krzysztofik <janusz.krzysztofik@linux.intel.com>
Cc: Mauro Carvalho Chehab <mchehab@kernel.org>
Cc: Rae Moar <rmoar@google.com>
Reviewed-by: Rae Moar <rmoar@google.com>
Reviewed-by: David Gow <davidgow@google.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2023-08-07 10:23:54 +00:00
|
|
|
struct kunit_suite_set suite_set = {
|
|
|
|
.start = subsuite, .end = &subsuite[2],
|
|
|
|
};
|
|
|
|
struct kunit_suite_set got;
|
2022-07-09 03:19:58 +00:00
|
|
|
int err = 0;
|
2021-09-14 21:03:48 +00:00
|
|
|
|
|
|
|
subsuite[0] = alloc_fake_suite(test, "suite1", dummy_test_cases);
|
|
|
|
subsuite[1] = alloc_fake_suite(test, "suite2", dummy_test_cases);
|
2021-04-21 02:04:27 +00:00
|
|
|
|
2021-09-14 21:03:48 +00:00
|
|
|
/* Want: suite1, suite2, NULL -> suite2 (just test1), NULL */
|
kunit: Add ability to filter attributes
Add filtering of test attributes. Users can filter tests using the
module_param called "filter".
Filters are imputed in the format: <attribute_name><operation><value>
Example: kunit.filter="speed>slow"
Operations include: >, <, >=, <=, !=, and =. These operations will act the
same for attributes of the same type but may not between types.
Note multiple filters can be inputted by separating them with a comma.
Example: kunit.filter="speed=slow, module!=example"
Since both suites and test cases can have attributes, there may be
conflicts. The process of filtering follows these rules:
- Filtering always operates at a per-test level.
- If a test has an attribute set, then the test's value is filtered on.
- Otherwise, the value falls back to the suite's value.
- If neither are set, the attribute has a global "default" value, which
is used.
Filtered tests will not be run or show in output. The tests can instead be
skipped using the configurable option "kunit.filter_action=skip".
Note the default settings for running tests remains unfiltered.
Finally, add "filter" methods for the speed and module attributes to parse
and compare attribute values.
Note this filtering functionality will be added to kunit.py in the next
patch.
Reviewed-by: David Gow <davidgow@google.com>
Signed-off-by: Rae Moar <rmoar@google.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2023-07-25 21:25:15 +00:00
|
|
|
got = kunit_filter_suites(&suite_set, "suite2.test2", NULL, NULL, &err);
|
2022-07-09 03:19:58 +00:00
|
|
|
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, got.start);
|
|
|
|
KUNIT_ASSERT_EQ(test, err, 0);
|
|
|
|
kfree_at_end(test, got.start);
|
2021-09-14 21:03:48 +00:00
|
|
|
|
|
|
|
/* Validate we just have suite2 */
|
2022-07-09 03:19:58 +00:00
|
|
|
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, got.start[0]);
|
|
|
|
KUNIT_EXPECT_STREQ(test, (const char *)got.start[0]->name, "suite2");
|
|
|
|
KUNIT_ASSERT_EQ(test, got.end - got.start, 1);
|
2021-09-14 21:03:48 +00:00
|
|
|
|
|
|
|
/* Now validate we just have test2 */
|
2022-07-09 03:19:58 +00:00
|
|
|
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, got.start[0]->test_cases);
|
|
|
|
KUNIT_EXPECT_STREQ(test, (const char *)got.start[0]->test_cases[0].name, "test2");
|
|
|
|
KUNIT_EXPECT_FALSE(test, got.start[0]->test_cases[1].name);
|
2021-04-21 02:04:27 +00:00
|
|
|
}
|
|
|
|
|
2022-07-09 03:19:58 +00:00
|
|
|
static void filter_suites_to_empty_test(struct kunit *test)
|
2021-04-21 02:04:27 +00:00
|
|
|
{
|
2022-07-09 03:19:58 +00:00
|
|
|
struct kunit_suite *subsuite[3] = {NULL, NULL};
|
kunit: Report the count of test suites in a module
According to KTAP specification[1], results should always start from a
header that provides a TAP protocol version, followed by a test plan with
a count of items to be executed. That pattern should be followed at each
nesting level. In the current implementation of the top-most, i.e., test
suite level, those rules apply only for test suites built into the kernel,
executed and reported on boot. Results submitted to dmesg from kunit test
modules loaded later are missing those top-level headers.
As a consequence, if a kunit test module provides more than one test suite
then, without the top level test plan, external tools that are parsing
dmesg for kunit test output are not able to tell how many test suites
should be expected and whether to continue parsing after complete output
from the first test suite is collected.
Submit the top-level headers also from the kunit test module notifier
initialization callback.
v3: Fix new name of a structure moved to kunit namespace not updated in
executor_test functions (lkp@intel.com).
v2: Use kunit_exec_run_tests() (Mauro, Rae), but prevent it from
emitting the headers when called on load of non-test modules.
[1] https://docs.kernel.org/dev-tools/ktap.html#
Signed-off-by: Janusz Krzysztofik <janusz.krzysztofik@linux.intel.com>
Cc: Mauro Carvalho Chehab <mchehab@kernel.org>
Cc: Rae Moar <rmoar@google.com>
Reviewed-by: Rae Moar <rmoar@google.com>
Reviewed-by: David Gow <davidgow@google.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2023-08-07 10:23:54 +00:00
|
|
|
struct kunit_suite_set suite_set = {
|
|
|
|
.start = subsuite, .end = &subsuite[2],
|
|
|
|
};
|
|
|
|
struct kunit_suite_set got;
|
2022-07-09 03:19:58 +00:00
|
|
|
int err = 0;
|
2021-04-21 02:04:27 +00:00
|
|
|
|
2021-09-14 21:03:48 +00:00
|
|
|
subsuite[0] = alloc_fake_suite(test, "suite1", dummy_test_cases);
|
|
|
|
subsuite[1] = alloc_fake_suite(test, "suite2", dummy_test_cases);
|
2021-04-21 02:04:27 +00:00
|
|
|
|
kunit: Add ability to filter attributes
Add filtering of test attributes. Users can filter tests using the
module_param called "filter".
Filters are imputed in the format: <attribute_name><operation><value>
Example: kunit.filter="speed>slow"
Operations include: >, <, >=, <=, !=, and =. These operations will act the
same for attributes of the same type but may not between types.
Note multiple filters can be inputted by separating them with a comma.
Example: kunit.filter="speed=slow, module!=example"
Since both suites and test cases can have attributes, there may be
conflicts. The process of filtering follows these rules:
- Filtering always operates at a per-test level.
- If a test has an attribute set, then the test's value is filtered on.
- Otherwise, the value falls back to the suite's value.
- If neither are set, the attribute has a global "default" value, which
is used.
Filtered tests will not be run or show in output. The tests can instead be
skipped using the configurable option "kunit.filter_action=skip".
Note the default settings for running tests remains unfiltered.
Finally, add "filter" methods for the speed and module attributes to parse
and compare attribute values.
Note this filtering functionality will be added to kunit.py in the next
patch.
Reviewed-by: David Gow <davidgow@google.com>
Signed-off-by: Rae Moar <rmoar@google.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2023-07-25 21:25:15 +00:00
|
|
|
got = kunit_filter_suites(&suite_set, "not_found", NULL, NULL, &err);
|
2022-07-09 03:19:58 +00:00
|
|
|
KUNIT_ASSERT_EQ(test, err, 0);
|
|
|
|
kfree_at_end(test, got.start); /* just in case */
|
2021-04-21 02:04:27 +00:00
|
|
|
|
2022-07-09 03:19:58 +00:00
|
|
|
KUNIT_EXPECT_PTR_EQ_MSG(test, got.start, got.end,
|
|
|
|
"should be empty to indicate no match");
|
2021-04-21 02:04:27 +00:00
|
|
|
}
|
|
|
|
|
2023-07-25 21:25:19 +00:00
|
|
|
static void parse_filter_attr_test(struct kunit *test)
|
|
|
|
{
|
|
|
|
int j, filter_count;
|
|
|
|
struct kunit_attr_filter *parsed_filters;
|
2023-08-30 00:21:15 +00:00
|
|
|
char filters[] = "speed>slow, module!=example", *filter = filters;
|
2023-07-25 21:25:19 +00:00
|
|
|
int err = 0;
|
|
|
|
|
|
|
|
filter_count = kunit_get_filter_count(filters);
|
|
|
|
KUNIT_EXPECT_EQ(test, filter_count, 2);
|
|
|
|
|
2023-08-03 19:36:35 +00:00
|
|
|
parsed_filters = kunit_kcalloc(test, filter_count, sizeof(*parsed_filters),
|
2023-07-25 21:25:19 +00:00
|
|
|
GFP_KERNEL);
|
|
|
|
for (j = 0; j < filter_count; j++) {
|
2023-08-30 00:21:15 +00:00
|
|
|
parsed_filters[j] = kunit_next_attr_filter(&filter, &err);
|
2023-07-25 21:25:19 +00:00
|
|
|
KUNIT_ASSERT_EQ_MSG(test, err, 0, "failed to parse filter '%s'", filters[j]);
|
|
|
|
}
|
|
|
|
|
|
|
|
KUNIT_EXPECT_STREQ(test, kunit_attr_filter_name(parsed_filters[0]), "speed");
|
|
|
|
KUNIT_EXPECT_STREQ(test, parsed_filters[0].input, ">slow");
|
|
|
|
|
|
|
|
KUNIT_EXPECT_STREQ(test, kunit_attr_filter_name(parsed_filters[1]), "module");
|
|
|
|
KUNIT_EXPECT_STREQ(test, parsed_filters[1].input, "!=example");
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct kunit_case dummy_attr_test_cases[] = {
|
|
|
|
/* .run_case is not important, just needs to be non-NULL */
|
|
|
|
{ .name = "slow", .run_case = dummy_test, .module_name = "dummy",
|
|
|
|
.attr.speed = KUNIT_SPEED_SLOW },
|
|
|
|
{ .name = "normal", .run_case = dummy_test, .module_name = "dummy" },
|
|
|
|
{},
|
|
|
|
};
|
|
|
|
|
|
|
|
static void filter_attr_test(struct kunit *test)
|
|
|
|
{
|
|
|
|
struct kunit_suite *subsuite[3] = {NULL, NULL};
|
kunit: Report the count of test suites in a module
According to KTAP specification[1], results should always start from a
header that provides a TAP protocol version, followed by a test plan with
a count of items to be executed. That pattern should be followed at each
nesting level. In the current implementation of the top-most, i.e., test
suite level, those rules apply only for test suites built into the kernel,
executed and reported on boot. Results submitted to dmesg from kunit test
modules loaded later are missing those top-level headers.
As a consequence, if a kunit test module provides more than one test suite
then, without the top level test plan, external tools that are parsing
dmesg for kunit test output are not able to tell how many test suites
should be expected and whether to continue parsing after complete output
from the first test suite is collected.
Submit the top-level headers also from the kunit test module notifier
initialization callback.
v3: Fix new name of a structure moved to kunit namespace not updated in
executor_test functions (lkp@intel.com).
v2: Use kunit_exec_run_tests() (Mauro, Rae), but prevent it from
emitting the headers when called on load of non-test modules.
[1] https://docs.kernel.org/dev-tools/ktap.html#
Signed-off-by: Janusz Krzysztofik <janusz.krzysztofik@linux.intel.com>
Cc: Mauro Carvalho Chehab <mchehab@kernel.org>
Cc: Rae Moar <rmoar@google.com>
Reviewed-by: Rae Moar <rmoar@google.com>
Reviewed-by: David Gow <davidgow@google.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2023-08-07 10:23:54 +00:00
|
|
|
struct kunit_suite_set suite_set = {
|
|
|
|
.start = subsuite, .end = &subsuite[2],
|
|
|
|
};
|
|
|
|
struct kunit_suite_set got;
|
2023-08-30 00:21:15 +00:00
|
|
|
char filter[] = "speed>slow";
|
2023-07-25 21:25:19 +00:00
|
|
|
int err = 0;
|
|
|
|
|
|
|
|
subsuite[0] = alloc_fake_suite(test, "normal_suite", dummy_attr_test_cases);
|
|
|
|
subsuite[1] = alloc_fake_suite(test, "slow_suite", dummy_attr_test_cases);
|
|
|
|
subsuite[1]->attr.speed = KUNIT_SPEED_SLOW; // Set suite attribute
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Want: normal_suite(slow, normal), slow_suite(slow, normal),
|
|
|
|
* NULL -> normal_suite(normal), NULL
|
|
|
|
*
|
|
|
|
* The normal test in slow_suite is filtered out because the speed
|
|
|
|
* attribute is unset and thus, the filtering is based on the parent attribute
|
|
|
|
* of slow.
|
|
|
|
*/
|
2023-08-30 00:21:15 +00:00
|
|
|
got = kunit_filter_suites(&suite_set, NULL, filter, NULL, &err);
|
2023-07-25 21:25:19 +00:00
|
|
|
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, got.start);
|
|
|
|
KUNIT_ASSERT_EQ(test, err, 0);
|
|
|
|
kfree_at_end(test, got.start);
|
|
|
|
|
|
|
|
/* Validate we just have normal_suite */
|
|
|
|
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, got.start[0]);
|
|
|
|
KUNIT_EXPECT_STREQ(test, got.start[0]->name, "normal_suite");
|
|
|
|
KUNIT_ASSERT_EQ(test, got.end - got.start, 1);
|
|
|
|
|
|
|
|
/* Now validate we just have normal test case */
|
|
|
|
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, got.start[0]->test_cases);
|
|
|
|
KUNIT_EXPECT_STREQ(test, got.start[0]->test_cases[0].name, "normal");
|
|
|
|
KUNIT_EXPECT_FALSE(test, got.start[0]->test_cases[1].name);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void filter_attr_empty_test(struct kunit *test)
|
|
|
|
{
|
|
|
|
struct kunit_suite *subsuite[3] = {NULL, NULL};
|
kunit: Report the count of test suites in a module
According to KTAP specification[1], results should always start from a
header that provides a TAP protocol version, followed by a test plan with
a count of items to be executed. That pattern should be followed at each
nesting level. In the current implementation of the top-most, i.e., test
suite level, those rules apply only for test suites built into the kernel,
executed and reported on boot. Results submitted to dmesg from kunit test
modules loaded later are missing those top-level headers.
As a consequence, if a kunit test module provides more than one test suite
then, without the top level test plan, external tools that are parsing
dmesg for kunit test output are not able to tell how many test suites
should be expected and whether to continue parsing after complete output
from the first test suite is collected.
Submit the top-level headers also from the kunit test module notifier
initialization callback.
v3: Fix new name of a structure moved to kunit namespace not updated in
executor_test functions (lkp@intel.com).
v2: Use kunit_exec_run_tests() (Mauro, Rae), but prevent it from
emitting the headers when called on load of non-test modules.
[1] https://docs.kernel.org/dev-tools/ktap.html#
Signed-off-by: Janusz Krzysztofik <janusz.krzysztofik@linux.intel.com>
Cc: Mauro Carvalho Chehab <mchehab@kernel.org>
Cc: Rae Moar <rmoar@google.com>
Reviewed-by: Rae Moar <rmoar@google.com>
Reviewed-by: David Gow <davidgow@google.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2023-08-07 10:23:54 +00:00
|
|
|
struct kunit_suite_set suite_set = {
|
|
|
|
.start = subsuite, .end = &subsuite[2],
|
|
|
|
};
|
|
|
|
struct kunit_suite_set got;
|
2023-08-30 00:21:15 +00:00
|
|
|
char filter[] = "module!=dummy";
|
2023-07-25 21:25:19 +00:00
|
|
|
int err = 0;
|
|
|
|
|
|
|
|
subsuite[0] = alloc_fake_suite(test, "suite1", dummy_attr_test_cases);
|
|
|
|
subsuite[1] = alloc_fake_suite(test, "suite2", dummy_attr_test_cases);
|
|
|
|
|
2023-08-30 00:21:15 +00:00
|
|
|
got = kunit_filter_suites(&suite_set, NULL, filter, NULL, &err);
|
2023-07-25 21:25:19 +00:00
|
|
|
KUNIT_ASSERT_EQ(test, err, 0);
|
|
|
|
kfree_at_end(test, got.start); /* just in case */
|
|
|
|
|
|
|
|
KUNIT_EXPECT_PTR_EQ_MSG(test, got.start, got.end,
|
|
|
|
"should be empty to indicate no match");
|
|
|
|
}
|
|
|
|
|
|
|
|
static void filter_attr_skip_test(struct kunit *test)
|
|
|
|
{
|
|
|
|
struct kunit_suite *subsuite[2] = {NULL};
|
kunit: Report the count of test suites in a module
According to KTAP specification[1], results should always start from a
header that provides a TAP protocol version, followed by a test plan with
a count of items to be executed. That pattern should be followed at each
nesting level. In the current implementation of the top-most, i.e., test
suite level, those rules apply only for test suites built into the kernel,
executed and reported on boot. Results submitted to dmesg from kunit test
modules loaded later are missing those top-level headers.
As a consequence, if a kunit test module provides more than one test suite
then, without the top level test plan, external tools that are parsing
dmesg for kunit test output are not able to tell how many test suites
should be expected and whether to continue parsing after complete output
from the first test suite is collected.
Submit the top-level headers also from the kunit test module notifier
initialization callback.
v3: Fix new name of a structure moved to kunit namespace not updated in
executor_test functions (lkp@intel.com).
v2: Use kunit_exec_run_tests() (Mauro, Rae), but prevent it from
emitting the headers when called on load of non-test modules.
[1] https://docs.kernel.org/dev-tools/ktap.html#
Signed-off-by: Janusz Krzysztofik <janusz.krzysztofik@linux.intel.com>
Cc: Mauro Carvalho Chehab <mchehab@kernel.org>
Cc: Rae Moar <rmoar@google.com>
Reviewed-by: Rae Moar <rmoar@google.com>
Reviewed-by: David Gow <davidgow@google.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2023-08-07 10:23:54 +00:00
|
|
|
struct kunit_suite_set suite_set = {
|
|
|
|
.start = subsuite, .end = &subsuite[1],
|
|
|
|
};
|
|
|
|
struct kunit_suite_set got;
|
2023-08-30 00:21:15 +00:00
|
|
|
char filter[] = "speed>slow";
|
2023-07-25 21:25:19 +00:00
|
|
|
int err = 0;
|
|
|
|
|
|
|
|
subsuite[0] = alloc_fake_suite(test, "suite", dummy_attr_test_cases);
|
|
|
|
|
|
|
|
/* Want: suite(slow, normal), NULL -> suite(slow with SKIP, normal), NULL */
|
2023-08-30 00:21:15 +00:00
|
|
|
got = kunit_filter_suites(&suite_set, NULL, filter, "skip", &err);
|
2023-07-25 21:25:19 +00:00
|
|
|
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, got.start);
|
|
|
|
KUNIT_ASSERT_EQ(test, err, 0);
|
|
|
|
kfree_at_end(test, got.start);
|
|
|
|
|
|
|
|
/* Validate we have both the slow and normal test */
|
|
|
|
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, got.start[0]->test_cases);
|
|
|
|
KUNIT_ASSERT_EQ(test, kunit_suite_num_test_cases(got.start[0]), 2);
|
|
|
|
KUNIT_EXPECT_STREQ(test, got.start[0]->test_cases[0].name, "slow");
|
|
|
|
KUNIT_EXPECT_STREQ(test, got.start[0]->test_cases[1].name, "normal");
|
|
|
|
|
|
|
|
/* Now ensure slow is skipped and normal is not */
|
|
|
|
KUNIT_EXPECT_EQ(test, got.start[0]->test_cases[0].status, KUNIT_SKIPPED);
|
|
|
|
KUNIT_EXPECT_FALSE(test, got.start[0]->test_cases[1].status);
|
|
|
|
}
|
|
|
|
|
2021-04-21 02:04:27 +00:00
|
|
|
static struct kunit_case executor_test_cases[] = {
|
2021-09-14 21:03:48 +00:00
|
|
|
KUNIT_CASE(parse_filter_test),
|
2021-04-21 02:04:27 +00:00
|
|
|
KUNIT_CASE(filter_suites_test),
|
2022-07-09 03:19:58 +00:00
|
|
|
KUNIT_CASE(filter_suites_test_glob_test),
|
|
|
|
KUNIT_CASE(filter_suites_to_empty_test),
|
2023-07-25 21:25:19 +00:00
|
|
|
KUNIT_CASE(parse_filter_attr_test),
|
|
|
|
KUNIT_CASE(filter_attr_test),
|
|
|
|
KUNIT_CASE(filter_attr_empty_test),
|
|
|
|
KUNIT_CASE(filter_attr_skip_test),
|
2021-04-21 02:04:27 +00:00
|
|
|
{}
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct kunit_suite executor_test_suite = {
|
|
|
|
.name = "kunit_executor_test",
|
|
|
|
.test_cases = executor_test_cases,
|
|
|
|
};
|
|
|
|
|
|
|
|
kunit_test_suites(&executor_test_suite);
|
|
|
|
|
|
|
|
/* Test helpers */
|
|
|
|
|
|
|
|
/* Use the resource API to register a call to kfree(to_free).
|
|
|
|
* Since we never actually use the resource, it's safe to use on const data.
|
|
|
|
*/
|
|
|
|
static void kfree_at_end(struct kunit *test, const void *to_free)
|
|
|
|
{
|
|
|
|
/* kfree() handles NULL already, but avoid allocating a no-op cleanup. */
|
|
|
|
if (IS_ERR_OR_NULL(to_free))
|
|
|
|
return;
|
2023-05-25 04:21:29 +00:00
|
|
|
|
|
|
|
kunit_add_action(test,
|
|
|
|
(kunit_action_t *)kfree,
|
|
|
|
(void *)to_free);
|
2021-04-21 02:04:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static struct kunit_suite *alloc_fake_suite(struct kunit *test,
|
2021-09-14 21:03:48 +00:00
|
|
|
const char *suite_name,
|
|
|
|
struct kunit_case *test_cases)
|
2021-04-21 02:04:27 +00:00
|
|
|
{
|
|
|
|
struct kunit_suite *suite;
|
|
|
|
|
|
|
|
/* We normally never expect to allocate suites, hence the non-const cast. */
|
|
|
|
suite = kunit_kzalloc(test, sizeof(*suite), GFP_KERNEL);
|
|
|
|
strncpy((char *)suite->name, suite_name, sizeof(suite->name) - 1);
|
2021-09-14 21:03:48 +00:00
|
|
|
suite->test_cases = test_cases;
|
2021-04-21 02:04:27 +00:00
|
|
|
|
|
|
|
return suite;
|
|
|
|
}
|