linux-kselftest.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
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

  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).