From: keescook@chromium.org (Kees Cook)
Subject: [PATCH v3 4/7] kselftest: Add test module framework header
Date: Tue, 2 Apr 2019 14:31:09 -0700 [thread overview]
Message-ID: <CAGXu5j+Ux+w5KMYvGV+N_ZC-+tMQ=TpM3i5z-p1kCFnF0Ld9eA@mail.gmail.com> (raw)
Message-ID: <20190402213109.F4_wLGVl3vTnKYhbjTvzKoWFNl2UCDZ5DNPLTiTRYd4@z> (raw)
In-Reply-To: <20190306214226.14598-5-tobin@kernel.org>
On Wed, Mar 6, 2019@1:43 PM Tobin C. Harding <tobin@kernel.org> wrote:
>
> kselftest runs as a userspace process. Sometimes we need to test things
> from kernel space. One way of doing this is by creating a test module.
> Currently doing so requires developers to write a bunch of boiler plate
> in the module if kselftest is to be used to run the tests. This means
> we currently have a load of duplicate code to achieve these ends. If we
> have a uniform method for implementing test modules then we can reduce
> code duplication, ensure uniformity in the test framework, ease code
> maintenance, and reduce the work required to create tests. This all
> helps to encourage developers to write and run tests.
>
> Add a C header file that can be included in test modules. This provides
> a single point for common test functions/macros. Implement a few macros
> that make up the start of the test framework.
>
> Add documentation for new kselftest header and script to kselftest
> documentation.
>
> Signed-off-by: Tobin C. Harding <tobin at kernel.org>
I like this!
Acked-by: Kees Cook <keescook at chromium.org>
-Kees
> ---
> Documentation/dev-tools/kselftest.rst | 108 ++++++++++++++++++++-
> tools/testing/selftests/kselftest_module.h | 48 +++++++++
> 2 files changed, 154 insertions(+), 2 deletions(-)
> create mode 100644 tools/testing/selftests/kselftest_module.h
>
> diff --git a/Documentation/dev-tools/kselftest.rst b/Documentation/dev-tools/kselftest.rst
> index 7756f7a7c23b..fb7790d47147 100644
> --- a/Documentation/dev-tools/kselftest.rst
> +++ b/Documentation/dev-tools/kselftest.rst
> @@ -14,6 +14,10 @@ in safe mode with a limited scope. In limited mode, cpu-hotplug test is
> run on a single cpu as opposed to all hotplug capable cpus, and memory
> hotplug test is run on 2% of hotplug capable memory instead of 10%.
>
> +kselftest runs as a userspace process. Tests that can be written/run in
> +userspace may wish to use the `Test Harness`_. Tests that need to be
> +run in kernel space may wish to use a `Test Module`_.
> +
> Running the selftests (hotplug tests are run in limited mode)
> =============================================================
>
> @@ -161,11 +165,111 @@ Contributing new tests (details)
>
> e.g: tools/testing/selftests/android/config
>
> +Test Module
> +===========
> +
> +Kselftest tests the kernel from userspace. Sometimes things need
> +testing from within the kernel, one method of doing this is to create a
> +test module. We can tie the module into the kselftest framework by
> +using a shell script test runner. ``kselftest_module.sh`` is designed
> +to facilitate this process. There is also a header file provided to
> +assist writing kernel modules that are for use with kselftest:
> +
> +- ``tools/testing/kselftest/kselftest_module.h``
> +- ``tools/testing/kselftest/kselftest_module.sh``
> +
> +How to use
> +----------
> +
> +Here we show the typical steps to create a test module and tie it into
> +kselftest. We use kselftests for lib/ as an example.
> +
> +1. Create the test module
> +
> +2. Create the test script that will run (load/unload) the module
> + e.g. ``tools/testing/selftests/lib/printf.sh``
> +
> +3. Add line to config file e.g. ``tools/testing/selftests/lib/config``
> +
> +4. Add test script to makefile e.g. ``tools/testing/selftests/lib/Makefile``
> +
> +5. Verify it works:
> +
> +.. code-block:: sh
> +
> + # Assumes you have booted a fresh build of this kernel tree
> + cd /path/to/linux/tree
> + make kselftest-merge
> + make modules
> + sudo make modules_install
> + make TARGETS=lib kselftest
> +
> +Example Module
> +--------------
> +
> +A bare bones test module might look like this:
> +
> +.. code-block:: c
> +
> + // SPDX-License-Identifier: GPL-2.0+
> +
> + #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
> +
> + #include "../tools/testing/selftests/kselftest_module.h"
> +
> + KSTM_MODULE_GLOBALS();
> +
> + /*
> + * Kernel module for testing the foobinator
> + */
> +
> + static int __init test_function()
> + {
> + ...
> + }
> +
> + static void __init selftest(void)
> + {
> + KSTM_CHECK_ZERO(do_test_case("", 0));
> + }
> +
> + KSTM_MODULE_LOADERS(test_foo);
> + MODULE_AUTHOR("John Developer <jd at fooman.org>");
> + MODULE_LICENSE("GPL");
> +
> +Example test script
> +-------------------
> +
> +.. code-block:: sh
> +
> + #!/bin/bash
> + # SPDX-License-Identifier: GPL-2.0+
> +
> + module_name="test_foo" # Module name (without the .ko).
> + description="foo" # Output prefix.
> +
> + #
> + # Shouldn't need to edit anything below here.
> + #
> +
> + file="kselftest_module.sh"
> + path="../$file"
> + if [[ ! $KBUILD_SRC == "" ]]; then
> + path="${KBUILD_SRC}/tools/testing/selftests/$file"
> + fi
> +
> + $path $module_name $description
> +
> +
> Test Harness
> ============
>
> -The kselftest_harness.h file contains useful helpers to build tests. The tests
> -from tools/testing/selftests/seccomp/seccomp_bpf.c can be used as example.
> +The kselftest_harness.h file contains useful helpers to build tests. The
> +test harness is for userspace testing, for kernel space testing see `Test
> +Module`_ above.
> +
> +The tests from tools/testing/selftests/seccomp/seccomp_bpf.c can be used as
> +example.
>
> Example
> -------
> diff --git a/tools/testing/selftests/kselftest_module.h b/tools/testing/selftests/kselftest_module.h
> new file mode 100644
> index 000000000000..e8eafaf0941a
> --- /dev/null
> +++ b/tools/testing/selftests/kselftest_module.h
> @@ -0,0 +1,48 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +#ifndef __KSELFTEST_MODULE_H
> +#define __KSELFTEST_MODULE_H
> +
> +#include <linux/module.h>
> +
> +/*
> + * Test framework for writing test modules to be loaded by kselftest.
> + * See Documentation/dev-tools/kselftest.rst for an example test module.
> + */
> +
> +#define KSTM_MODULE_GLOBALS() \
> +static unsigned int total_tests __initdata; \
> +static unsigned int failed_tests __initdata
> +
> +#define KSTM_CHECK_ZERO(x) do { \
> + total_tests++; \
> + if (x) { \
> + pr_warn("TC failed at %s:%d\n", __func__, __LINE__); \
> + failed_tests++; \
> + } \
> +} while (0)
> +
> +static inline int kstm_report(unsigned int total_tests, unsigned int failed_tests)
> +{
> + if (failed_tests == 0)
> + pr_info("all %u tests passed\n", total_tests);
> + else
> + pr_warn("failed %u out of %u tests\n", failed_tests, total_tests);
> +
> + return failed_tests ? -EINVAL : 0;
> +}
> +
> +#define KSTM_MODULE_LOADERS(__module) \
> +static int __init __module##_init(void) \
> +{ \
> + pr_info("loaded.\n"); \
> + selftest(); \
> + return kstm_report(total_tests, failed_tests); \
> +} \
> +static void __exit __module##_exit(void) \
> +{ \
> + pr_info("unloaded.\n"); \
> +} \
> +module_init(__module##_init); \
> +module_exit(__module##_exit)
> +
> +#endif /* __KSELFTEST_MODULE_H */
> --
> 2.20.1
>
--
Kees Cook
next prev parent reply other threads:[~2019-04-02 21:31 UTC|newest]
Thread overview: 54+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-03-06 21:42 [PATCH v3 0/7] lib/string: Add strscpy_pad() function tobin
2019-03-06 21:42 ` Tobin C. Harding
2019-03-06 21:42 ` [PATCH v3 1/7] lib/test_printf: Add empty module_exit function tobin
2019-03-06 21:42 ` Tobin C. Harding
2019-04-02 21:24 ` keescook
2019-04-02 21:24 ` Kees Cook
2019-03-06 21:42 ` [PATCH v3 2/7] kselftest: Add test runner creation script tobin
2019-03-06 21:42 ` Tobin C. Harding
2019-04-02 21:27 ` keescook
2019-04-02 21:27 ` Kees Cook
2019-04-02 21:33 ` rdunlap
2019-04-02 21:33 ` Randy Dunlap
2019-04-04 23:16 ` me
2019-04-04 23:16 ` Tobin C. Harding
2019-03-06 21:42 ` [PATCH v3 3/7] kselftest/lib: Use new shell runner to define tests tobin
2019-03-06 21:42 ` Tobin C. Harding
2019-04-02 21:29 ` keescook
2019-04-02 21:29 ` Kees Cook
2019-04-02 21:45 ` keescook
2019-04-02 21:45 ` Kees Cook
2019-04-02 21:51 ` keescook
2019-04-02 21:51 ` Kees Cook
2019-03-06 21:42 ` [PATCH v3 4/7] kselftest: Add test module framework header tobin
2019-03-06 21:42 ` Tobin C. Harding
2019-04-02 21:31 ` keescook [this message]
2019-04-02 21:31 ` Kees Cook
2019-03-06 21:42 ` [PATCH v3 5/7] lib: Use new kselftest header tobin
2019-03-06 21:42 ` Tobin C. Harding
2019-04-02 21:32 ` keescook
2019-04-02 21:32 ` Kees Cook
2019-03-06 21:42 ` [PATCH v3 6/7] lib/string: Add strscpy_pad() function tobin
2019-03-06 21:42 ` Tobin C. Harding
2019-04-02 21:35 ` keescook
2019-04-02 21:35 ` Kees Cook
2019-03-06 21:42 ` [PATCH v3 7/7] lib: Add test module for strscpy_pad tobin
2019-03-06 21:42 ` Tobin C. Harding
2019-04-02 21:36 ` keescook
2019-04-02 21:36 ` Kees Cook
2019-03-06 21:49 ` [PATCH v3 0/7] lib/string: Add strscpy_pad() function me
2019-03-06 21:49 ` Tobin C. Harding
2019-03-07 21:18 ` me
2019-03-07 21:18 ` Tobin C. Harding
2019-03-07 22:43 ` keescook
2019-03-07 22:43 ` Kees Cook
2019-03-08 5:23 ` me
2019-03-08 5:23 ` Tobin C. Harding
2019-03-08 16:18 ` keescook
2019-03-08 16:18 ` Kees Cook
2019-04-02 21:37 ` keescook
2019-04-02 21:37 ` Kees Cook
2019-04-03 0:25 ` me
2019-04-03 0:25 ` Tobin C. Harding
2019-04-03 0:29 ` shuah
2019-04-03 0:29 ` shuah
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='CAGXu5j+Ux+w5KMYvGV+N_ZC-+tMQ=TpM3i5z-p1kCFnF0Ld9eA@mail.gmail.com' \
--to=keescook@chromium.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).