mirror of
https://github.com/torvalds/linux.git
synced 2025-12-01 07:26:02 +07:00
Merge tag 'linux_kselftest-kunit-6.17-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest
Pull kunit updates from Shuah Khan:
"Correct MODULE_IMPORT_NS() syntax documentation, make kunit_test
timeout configurable via a module parameter and a Kconfig option, fix
longest symbol length test, add a test for static stub, and adjust
kunit_test timeout based on test_{suite,case} speed"
* tag 'linux_kselftest-kunit-6.17-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest:
kunit: fix longest symbol length test
kunit: Make default kunit_test timeout configurable via both a module parameter and a Kconfig option
kunit: Adjust kunit_test timeout based on test_{suite,case} speed
kunit: Add test for static stub
Documentation: kunit: Correct MODULE_IMPORT_NS() syntax
This commit is contained in:
@@ -699,7 +699,7 @@ the template below.
|
||||
#include <kunit/visibility.h>
|
||||
#include <my_file.h>
|
||||
...
|
||||
MODULE_IMPORT_NS(EXPORTED_FOR_KUNIT_TESTING);
|
||||
MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING");
|
||||
...
|
||||
// Use do_interesting_thing() in tests
|
||||
|
||||
|
||||
@@ -47,6 +47,7 @@ struct kunit_try_catch {
|
||||
int try_result;
|
||||
kunit_try_catch_func_t try;
|
||||
kunit_try_catch_func_t catch;
|
||||
unsigned long timeout;
|
||||
void *context;
|
||||
};
|
||||
|
||||
|
||||
@@ -2894,6 +2894,7 @@ config FORTIFY_KUNIT_TEST
|
||||
config LONGEST_SYM_KUNIT_TEST
|
||||
tristate "Test the longest symbol possible" if !KUNIT_ALL_TESTS
|
||||
depends on KUNIT && KPROBES
|
||||
depends on !PREFIX_SYMBOLS && !CFI_CLANG && !GCOV_KERNEL
|
||||
default KUNIT_ALL_TESTS
|
||||
help
|
||||
Tests the longest symbol possible
|
||||
|
||||
@@ -93,4 +93,17 @@ config KUNIT_AUTORUN_ENABLED
|
||||
In most cases this should be left as Y. Only if additional opt-in
|
||||
behavior is needed should this be set to N.
|
||||
|
||||
config KUNIT_DEFAULT_TIMEOUT
|
||||
int "Default value of the timeout module parameter"
|
||||
default 300
|
||||
help
|
||||
Sets the default timeout, in seconds, for Kunit test cases. This value
|
||||
is further multiplied by a factor determined by the assigned speed
|
||||
setting: 1x for `DEFAULT`, 3x for `KUNIT_SPEED_SLOW`, and 12x for
|
||||
`KUNIT_SPEED_VERY_SLOW`. This allows slower tests on slower machines
|
||||
sufficient time to complete.
|
||||
|
||||
If unsure, the default timeout of 300 seconds is suitable for most
|
||||
cases.
|
||||
|
||||
endif # KUNIT
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "linux/gfp_types.h"
|
||||
#include <kunit/test.h>
|
||||
#include <kunit/test-bug.h>
|
||||
#include <kunit/static_stub.h>
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <kunit/device.h>
|
||||
@@ -43,7 +44,8 @@ static void kunit_test_try_catch_successful_try_no_catch(struct kunit *test)
|
||||
kunit_try_catch_init(try_catch,
|
||||
test,
|
||||
kunit_test_successful_try,
|
||||
kunit_test_no_catch);
|
||||
kunit_test_no_catch,
|
||||
300 * msecs_to_jiffies(MSEC_PER_SEC));
|
||||
kunit_try_catch_run(try_catch, test);
|
||||
|
||||
KUNIT_EXPECT_TRUE(test, ctx->function_called);
|
||||
@@ -75,7 +77,8 @@ static void kunit_test_try_catch_unsuccessful_try_does_catch(struct kunit *test)
|
||||
kunit_try_catch_init(try_catch,
|
||||
test,
|
||||
kunit_test_unsuccessful_try,
|
||||
kunit_test_catch);
|
||||
kunit_test_catch,
|
||||
300 * msecs_to_jiffies(MSEC_PER_SEC));
|
||||
kunit_try_catch_run(try_catch, test);
|
||||
|
||||
KUNIT_EXPECT_TRUE(test, ctx->function_called);
|
||||
@@ -129,7 +132,8 @@ static void kunit_test_fault_null_dereference(struct kunit *test)
|
||||
kunit_try_catch_init(try_catch,
|
||||
test,
|
||||
kunit_test_null_dereference,
|
||||
kunit_test_catch);
|
||||
kunit_test_catch,
|
||||
300 * msecs_to_jiffies(MSEC_PER_SEC));
|
||||
kunit_try_catch_run(try_catch, test);
|
||||
|
||||
KUNIT_EXPECT_EQ(test, try_catch->try_result, -EINTR);
|
||||
@@ -868,10 +872,53 @@ static struct kunit_suite kunit_current_test_suite = {
|
||||
.test_cases = kunit_current_test_cases,
|
||||
};
|
||||
|
||||
static void kunit_stub_test(struct kunit *test)
|
||||
{
|
||||
struct kunit fake_test;
|
||||
const unsigned long fake_real_fn_addr = 0x1234;
|
||||
const unsigned long fake_replacement_addr = 0x5678;
|
||||
struct kunit_resource *res;
|
||||
struct {
|
||||
void *real_fn_addr;
|
||||
void *replacement_addr;
|
||||
} *stub_ctx;
|
||||
|
||||
kunit_init_test(&fake_test, "kunit_stub_fake_test", NULL);
|
||||
KUNIT_ASSERT_EQ(test, fake_test.status, KUNIT_SUCCESS);
|
||||
KUNIT_ASSERT_EQ(test, list_count_nodes(&fake_test.resources), 0);
|
||||
|
||||
__kunit_activate_static_stub(&fake_test, (void *)fake_real_fn_addr,
|
||||
(void *)fake_replacement_addr);
|
||||
KUNIT_ASSERT_EQ(test, fake_test.status, KUNIT_SUCCESS);
|
||||
KUNIT_ASSERT_EQ(test, list_count_nodes(&fake_test.resources), 1);
|
||||
|
||||
res = list_first_entry(&fake_test.resources, struct kunit_resource, node);
|
||||
KUNIT_EXPECT_NOT_NULL(test, res);
|
||||
|
||||
stub_ctx = res->data;
|
||||
KUNIT_EXPECT_NOT_NULL(test, stub_ctx);
|
||||
KUNIT_EXPECT_EQ(test, (unsigned long)stub_ctx->real_fn_addr, fake_real_fn_addr);
|
||||
KUNIT_EXPECT_EQ(test, (unsigned long)stub_ctx->replacement_addr, fake_replacement_addr);
|
||||
|
||||
__kunit_activate_static_stub(&fake_test, (void *)fake_real_fn_addr, NULL);
|
||||
KUNIT_ASSERT_EQ(test, fake_test.status, KUNIT_SUCCESS);
|
||||
KUNIT_ASSERT_EQ(test, list_count_nodes(&fake_test.resources), 0);
|
||||
}
|
||||
|
||||
static struct kunit_case kunit_stub_test_cases[] = {
|
||||
KUNIT_CASE(kunit_stub_test),
|
||||
{}
|
||||
};
|
||||
|
||||
static struct kunit_suite kunit_stub_test_suite = {
|
||||
.name = "kunit_stub",
|
||||
.test_cases = kunit_stub_test_cases,
|
||||
};
|
||||
|
||||
kunit_test_suites(&kunit_try_catch_test_suite, &kunit_resource_test_suite,
|
||||
&kunit_log_test_suite, &kunit_status_test_suite,
|
||||
&kunit_current_test_suite, &kunit_device_test_suite,
|
||||
&kunit_fault_test_suite);
|
||||
&kunit_fault_test_suite, &kunit_stub_test_suite);
|
||||
|
||||
MODULE_DESCRIPTION("KUnit test for core test infrastructure");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
||||
@@ -69,6 +69,13 @@ static bool enable_param;
|
||||
module_param_named(enable, enable_param, bool, 0);
|
||||
MODULE_PARM_DESC(enable, "Enable KUnit tests");
|
||||
|
||||
/*
|
||||
* Configure the base timeout.
|
||||
*/
|
||||
static unsigned long kunit_base_timeout = CONFIG_KUNIT_DEFAULT_TIMEOUT;
|
||||
module_param_named(timeout, kunit_base_timeout, ulong, 0644);
|
||||
MODULE_PARM_DESC(timeout, "Set the base timeout for Kunit test cases");
|
||||
|
||||
/*
|
||||
* KUnit statistic mode:
|
||||
* 0 - disabled
|
||||
@@ -373,6 +380,40 @@ static void kunit_run_case_check_speed(struct kunit *test,
|
||||
duration.tv_sec, duration.tv_nsec);
|
||||
}
|
||||
|
||||
/* Returns timeout multiplier based on speed.
|
||||
* DEFAULT: 1
|
||||
* KUNIT_SPEED_SLOW: 3
|
||||
* KUNIT_SPEED_VERY_SLOW: 12
|
||||
*/
|
||||
static int kunit_timeout_mult(enum kunit_speed speed)
|
||||
{
|
||||
switch (speed) {
|
||||
case KUNIT_SPEED_SLOW:
|
||||
return 3;
|
||||
case KUNIT_SPEED_VERY_SLOW:
|
||||
return 12;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned long kunit_test_timeout(struct kunit_suite *suite, struct kunit_case *test_case)
|
||||
{
|
||||
int mult = 1;
|
||||
|
||||
/*
|
||||
* The default test timeout is 300 seconds and will be adjusted by mult
|
||||
* based on the test speed. The test speed will be overridden by the
|
||||
* innermost test component.
|
||||
*/
|
||||
if (suite->attr.speed != KUNIT_SPEED_UNSET)
|
||||
mult = kunit_timeout_mult(suite->attr.speed);
|
||||
if (test_case->attr.speed != KUNIT_SPEED_UNSET)
|
||||
mult = kunit_timeout_mult(test_case->attr.speed);
|
||||
return mult * kunit_base_timeout * msecs_to_jiffies(MSEC_PER_SEC);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Initializes and runs test case. Does not clean up or do post validations.
|
||||
*/
|
||||
@@ -527,7 +568,8 @@ static void kunit_run_case_catch_errors(struct kunit_suite *suite,
|
||||
kunit_try_catch_init(try_catch,
|
||||
test,
|
||||
kunit_try_run_case,
|
||||
kunit_catch_run_case);
|
||||
kunit_catch_run_case,
|
||||
kunit_test_timeout(suite, test_case));
|
||||
context.test = test;
|
||||
context.suite = suite;
|
||||
context.test_case = test_case;
|
||||
@@ -537,7 +579,8 @@ static void kunit_run_case_catch_errors(struct kunit_suite *suite,
|
||||
kunit_try_catch_init(try_catch,
|
||||
test,
|
||||
kunit_try_run_case_cleanup,
|
||||
kunit_catch_run_case_cleanup);
|
||||
kunit_catch_run_case_cleanup,
|
||||
kunit_test_timeout(suite, test_case));
|
||||
kunit_try_catch_run(try_catch, &context);
|
||||
|
||||
/* Propagate the parameter result to the test case. */
|
||||
|
||||
@@ -17,11 +17,13 @@ struct kunit;
|
||||
static inline void kunit_try_catch_init(struct kunit_try_catch *try_catch,
|
||||
struct kunit *test,
|
||||
kunit_try_catch_func_t try,
|
||||
kunit_try_catch_func_t catch)
|
||||
kunit_try_catch_func_t catch,
|
||||
unsigned long timeout)
|
||||
{
|
||||
try_catch->test = test;
|
||||
try_catch->try = try;
|
||||
try_catch->catch = catch;
|
||||
try_catch->timeout = timeout;
|
||||
}
|
||||
|
||||
#endif /* _KUNIT_TRY_CATCH_IMPL_H */
|
||||
|
||||
@@ -34,31 +34,6 @@ static int kunit_generic_run_threadfn_adapter(void *data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned long kunit_test_timeout(void)
|
||||
{
|
||||
/*
|
||||
* TODO(brendanhiggins@google.com): We should probably have some type of
|
||||
* variable timeout here. The only question is what that timeout value
|
||||
* should be.
|
||||
*
|
||||
* The intention has always been, at some point, to be able to label
|
||||
* tests with some type of size bucket (unit/small, integration/medium,
|
||||
* large/system/end-to-end, etc), where each size bucket would get a
|
||||
* default timeout value kind of like what Bazel does:
|
||||
* https://docs.bazel.build/versions/master/be/common-definitions.html#test.size
|
||||
* There is still some debate to be had on exactly how we do this. (For
|
||||
* one, we probably want to have some sort of test runner level
|
||||
* timeout.)
|
||||
*
|
||||
* For more background on this topic, see:
|
||||
* https://mike-bland.com/2011/11/01/small-medium-large.html
|
||||
*
|
||||
* If tests timeout due to exceeding sysctl_hung_task_timeout_secs,
|
||||
* the task will be killed and an oops generated.
|
||||
*/
|
||||
return 300 * msecs_to_jiffies(MSEC_PER_SEC); /* 5 min */
|
||||
}
|
||||
|
||||
void kunit_try_catch_run(struct kunit_try_catch *try_catch, void *context)
|
||||
{
|
||||
struct kunit *test = try_catch->test;
|
||||
@@ -85,8 +60,8 @@ void kunit_try_catch_run(struct kunit_try_catch *try_catch, void *context)
|
||||
task_done = task_struct->vfork_done;
|
||||
wake_up_process(task_struct);
|
||||
|
||||
time_remaining = wait_for_completion_timeout(task_done,
|
||||
kunit_test_timeout());
|
||||
time_remaining = wait_for_completion_timeout(
|
||||
task_done, try_catch->timeout);
|
||||
if (time_remaining == 0) {
|
||||
try_catch->try_result = -ETIMEDOUT;
|
||||
kthread_stop(task_struct);
|
||||
|
||||
@@ -3,8 +3,7 @@
|
||||
* Test the longest symbol length. Execute with:
|
||||
* ./tools/testing/kunit/kunit.py run longest-symbol
|
||||
* --arch=x86_64 --kconfig_add CONFIG_KPROBES=y --kconfig_add CONFIG_MODULES=y
|
||||
* --kconfig_add CONFIG_RETPOLINE=n --kconfig_add CONFIG_CFI_CLANG=n
|
||||
* --kconfig_add CONFIG_MITIGATION_RETPOLINE=n
|
||||
* --kconfig_add CONFIG_CPU_MITIGATIONS=n --kconfig_add CONFIG_GCOV_KERNEL=n
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
Reference in New Issue
Block a user