mirror of
https://github.com/tbsdtv/linux_media.git
synced 2025-07-23 12:43:29 +02:00
Merge tag 'linux-kselftest-kunit-5.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest
Pull KUnit updates from Shuah Khan - support for filtering test suites using glob from Daniel Latypov. "kunit_filter.glob" command line option is passed to the UML kernel, which currently only supports filtering by suite name. This support allows running different subsets of tests, e.g. $ ./tools/testing/kunit/kunit.py build $ ./tools/testing/kunit/kunit.py exec 'list*' $ ./tools/testing/kunit/kunit.py exec 'kunit*' - several fixes and cleanups also from Daniel Latypov. * tag 'linux-kselftest-kunit-5.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest: kunit: tool: fix unintentional statefulness in run_kernel() kunit: tool: add support for filtering suites by glob kunit: add kunit.filter_glob cmdline option to filter suites kunit: don't show `1 == 1` in failed assertion messages kunit: make kunit_tool accept optional path to .kunitconfig fragment Documentation: kunit: add tips.rst for small examples KUnit: Docs: make start.rst example Kconfig follow style.rst kunit: tool: simplify kconfig is_subset_of() logic minor: kunit: tool: fix unit test so it can run from non-root dir kunit: tool: use `with open()` in unit test kunit: tool: stop using bare asserts in unit test kunit: tool: fix unit test cleanup handling
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
|
||||
menuconfig KUNIT
|
||||
tristate "KUnit - Enable support for unit tests"
|
||||
select GLOB if KUNIT=y
|
||||
help
|
||||
Enables support for kernel unit tests (KUnit), a lightweight unit
|
||||
testing and mocking framework for the Linux kernel. These tests are
|
||||
|
@@ -85,6 +85,29 @@ void kunit_ptr_not_err_assert_format(const struct kunit_assert *assert,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(kunit_ptr_not_err_assert_format);
|
||||
|
||||
/* Checks if `text` is a literal representing `value`, e.g. "5" and 5 */
|
||||
static bool is_literal(struct kunit *test, const char *text, long long value,
|
||||
gfp_t gfp)
|
||||
{
|
||||
char *buffer;
|
||||
int len;
|
||||
bool ret;
|
||||
|
||||
len = snprintf(NULL, 0, "%lld", value);
|
||||
if (strlen(text) != len)
|
||||
return false;
|
||||
|
||||
buffer = kunit_kmalloc(test, len+1, gfp);
|
||||
if (!buffer)
|
||||
return false;
|
||||
|
||||
snprintf(buffer, len+1, "%lld", value);
|
||||
ret = strncmp(buffer, text, len) == 0;
|
||||
|
||||
kunit_kfree(test, buffer);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void kunit_binary_assert_format(const struct kunit_assert *assert,
|
||||
struct string_stream *stream)
|
||||
{
|
||||
@@ -97,12 +120,16 @@ void kunit_binary_assert_format(const struct kunit_assert *assert,
|
||||
binary_assert->left_text,
|
||||
binary_assert->operation,
|
||||
binary_assert->right_text);
|
||||
string_stream_add(stream, KUNIT_SUBSUBTEST_INDENT "%s == %lld\n",
|
||||
binary_assert->left_text,
|
||||
binary_assert->left_value);
|
||||
string_stream_add(stream, KUNIT_SUBSUBTEST_INDENT "%s == %lld",
|
||||
binary_assert->right_text,
|
||||
binary_assert->right_value);
|
||||
if (!is_literal(stream->test, binary_assert->left_text,
|
||||
binary_assert->left_value, stream->gfp))
|
||||
string_stream_add(stream, KUNIT_SUBSUBTEST_INDENT "%s == %lld\n",
|
||||
binary_assert->left_text,
|
||||
binary_assert->left_value);
|
||||
if (!is_literal(stream->test, binary_assert->right_text,
|
||||
binary_assert->right_value, stream->gfp))
|
||||
string_stream_add(stream, KUNIT_SUBSUBTEST_INDENT "%s == %lld",
|
||||
binary_assert->right_text,
|
||||
binary_assert->right_value);
|
||||
kunit_assert_print_msg(assert, stream);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(kunit_binary_assert_format);
|
||||
|
@@ -1,6 +1,8 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
#include <kunit/test.h>
|
||||
#include <linux/glob.h>
|
||||
#include <linux/moduleparam.h>
|
||||
|
||||
/*
|
||||
* These symbols point to the .kunit_test_suites section and are defined in
|
||||
@@ -11,14 +13,81 @@ extern struct kunit_suite * const * const __kunit_suites_end[];
|
||||
|
||||
#if IS_BUILTIN(CONFIG_KUNIT)
|
||||
|
||||
static void kunit_print_tap_header(void)
|
||||
static char *filter_glob;
|
||||
module_param(filter_glob, charp, 0);
|
||||
MODULE_PARM_DESC(filter_glob,
|
||||
"Filter which KUnit test suites run at boot-time, e.g. list*");
|
||||
|
||||
static struct kunit_suite * const *
|
||||
kunit_filter_subsuite(struct kunit_suite * const * const subsuite)
|
||||
{
|
||||
int i, n = 0;
|
||||
struct kunit_suite **filtered;
|
||||
|
||||
n = 0;
|
||||
for (i = 0; subsuite[i] != NULL; ++i) {
|
||||
if (glob_match(filter_glob, subsuite[i]->name))
|
||||
++n;
|
||||
}
|
||||
|
||||
if (n == 0)
|
||||
return NULL;
|
||||
|
||||
filtered = kmalloc_array(n + 1, sizeof(*filtered), GFP_KERNEL);
|
||||
if (!filtered)
|
||||
return NULL;
|
||||
|
||||
n = 0;
|
||||
for (i = 0; subsuite[i] != NULL; ++i) {
|
||||
if (glob_match(filter_glob, subsuite[i]->name))
|
||||
filtered[n++] = subsuite[i];
|
||||
}
|
||||
filtered[n] = NULL;
|
||||
|
||||
return filtered;
|
||||
}
|
||||
|
||||
struct suite_set {
|
||||
struct kunit_suite * const * const *start;
|
||||
struct kunit_suite * const * const *end;
|
||||
};
|
||||
|
||||
static struct suite_set kunit_filter_suites(void)
|
||||
{
|
||||
int i;
|
||||
struct kunit_suite * const **copy, * const *filtered_subsuite;
|
||||
struct suite_set filtered;
|
||||
|
||||
const size_t max = __kunit_suites_end - __kunit_suites_start;
|
||||
|
||||
if (!filter_glob) {
|
||||
filtered.start = __kunit_suites_start;
|
||||
filtered.end = __kunit_suites_end;
|
||||
return filtered;
|
||||
}
|
||||
|
||||
copy = kmalloc_array(max, sizeof(*filtered.start), GFP_KERNEL);
|
||||
filtered.start = copy;
|
||||
if (!copy) { /* won't be able to run anything, return an empty set */
|
||||
filtered.end = copy;
|
||||
return filtered;
|
||||
}
|
||||
|
||||
for (i = 0; i < max; ++i) {
|
||||
filtered_subsuite = kunit_filter_subsuite(__kunit_suites_start[i]);
|
||||
if (filtered_subsuite)
|
||||
*copy++ = filtered_subsuite;
|
||||
}
|
||||
filtered.end = copy;
|
||||
return filtered;
|
||||
}
|
||||
|
||||
static void kunit_print_tap_header(struct suite_set *suite_set)
|
||||
{
|
||||
struct kunit_suite * const * const *suites, * const *subsuite;
|
||||
int num_of_suites = 0;
|
||||
|
||||
for (suites = __kunit_suites_start;
|
||||
suites < __kunit_suites_end;
|
||||
suites++)
|
||||
for (suites = suite_set->start; suites < suite_set->end; suites++)
|
||||
for (subsuite = *suites; *subsuite != NULL; subsuite++)
|
||||
num_of_suites++;
|
||||
|
||||
@@ -30,12 +99,18 @@ int kunit_run_all_tests(void)
|
||||
{
|
||||
struct kunit_suite * const * const *suites;
|
||||
|
||||
kunit_print_tap_header();
|
||||
struct suite_set suite_set = kunit_filter_suites();
|
||||
|
||||
for (suites = __kunit_suites_start;
|
||||
suites < __kunit_suites_end;
|
||||
suites++)
|
||||
__kunit_test_suites_init(*suites);
|
||||
kunit_print_tap_header(&suite_set);
|
||||
|
||||
for (suites = suite_set.start; suites < suite_set.end; suites++)
|
||||
__kunit_test_suites_init(*suites);
|
||||
|
||||
if (filter_glob) { /* a copy was made of each array */
|
||||
for (suites = suite_set.start; suites < suite_set.end; suites++)
|
||||
kfree(*suites);
|
||||
kfree(suite_set.start);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Reference in New Issue
Block a user