Skip to content

Commit 815c24a

Browse files
committed
Merge tag 'linux-kselftest-kunit-6.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest
Pull kunit updates from Shuah Khan: - add support for running Rust documentation tests as KUnit tests - make init, str, sync, types doctests compilable/testable - add support for attributes API which include speed, modules attributes, ability to filter and report attributes - add support for marking tests slow using attributes API - add attributes API documentation - fix a wild-memory-access bug in kunit_filter_suites() and a possible memory leak in kunit_filter_suites() - add support for counting number of test suites in a module, list action to kunit test modules, and test filtering on module tests * tag 'linux-kselftest-kunit-6.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest: (25 commits) kunit: fix struct kunit_attr header kunit: replace KUNIT_TRIGGER_STATIC_STUB maro with KUNIT_STATIC_STUB_REDIRECT kunit: Allow kunit test modules to use test filtering kunit: Make 'list' action available to kunit test modules kunit: Report the count of test suites in a module kunit: fix uninitialized variables bug in attributes filtering kunit: fix possible memory leak in kunit_filter_suites() kunit: fix wild-memory-access bug in kunit_filter_suites() kunit: Add documentation of KUnit test attributes kunit: add tests for filtering attributes kunit: time: Mark test as slow using test attributes kunit: memcpy: Mark tests as slow using test attributes kunit: tool: Add command line interface to filter and report attributes kunit: Add ability to filter attributes kunit: Add module attribute kunit: Add speed attribute kunit: Add test attributes API structure MAINTAINERS: add Rust KUnit files to the KUnit entry rust: support running Rust documentation tests as KUnit ones rust: types: make doctests compilable/testable ...
2 parents 5a31cc7 + 25e324b commit 815c24a

38 files changed

Lines changed: 1801 additions & 144 deletions

Documentation/dev-tools/kunit/run_wrapper.rst

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,3 +321,15 @@ command line arguments:
321321

322322
- ``--json``: If set, stores the test results in a JSON format and prints to `stdout` or
323323
saves to a file if a filename is specified.
324+
325+
- ``--filter``: Specifies filters on test attributes, for example, ``speed!=slow``.
326+
Multiple filters can be used by wrapping input in quotes and separating filters
327+
by commas. Example: ``--filter "speed>slow, module=example"``.
328+
329+
- ``--filter_action``: If set to ``skip``, filtered tests will be shown as skipped
330+
in the output rather than showing no output.
331+
332+
- ``--list_tests``: If set, lists all tests that will be run.
333+
334+
- ``--list_tests_attr``: If set, lists all tests that will be run and all of their
335+
attributes.

Documentation/dev-tools/kunit/running_tips.rst

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,3 +262,169 @@ other code executed during boot, e.g.
262262
# Reset coverage counters before running the test.
263263
$ echo 0 > /sys/kernel/debug/gcov/reset
264264
$ modprobe kunit-example-test
265+
266+
267+
Test Attributes and Filtering
268+
=============================
269+
270+
Test suites and cases can be marked with test attributes, such as speed of
271+
test. These attributes will later be printed in test output and can be used to
272+
filter test execution.
273+
274+
Marking Test Attributes
275+
-----------------------
276+
277+
Tests are marked with an attribute by including a ``kunit_attributes`` object
278+
in the test definition.
279+
280+
Test cases can be marked using the ``KUNIT_CASE_ATTR(test_name, attributes)``
281+
macro to define the test case instead of ``KUNIT_CASE(test_name)``.
282+
283+
.. code-block:: c
284+
285+
static const struct kunit_attributes example_attr = {
286+
.speed = KUNIT_VERY_SLOW,
287+
};
288+
289+
static struct kunit_case example_test_cases[] = {
290+
KUNIT_CASE_ATTR(example_test, example_attr),
291+
};
292+
293+
.. note::
294+
To mark a test case as slow, you can also use ``KUNIT_CASE_SLOW(test_name)``.
295+
This is a helpful macro as the slow attribute is the most commonly used.
296+
297+
Test suites can be marked with an attribute by setting the "attr" field in the
298+
suite definition.
299+
300+
.. code-block:: c
301+
302+
static const struct kunit_attributes example_attr = {
303+
.speed = KUNIT_VERY_SLOW,
304+
};
305+
306+
static struct kunit_suite example_test_suite = {
307+
...,
308+
.attr = example_attr,
309+
};
310+
311+
.. note::
312+
Not all attributes need to be set in a ``kunit_attributes`` object. Unset
313+
attributes will remain uninitialized and act as though the attribute is set
314+
to 0 or NULL. Thus, if an attribute is set to 0, it is treated as unset.
315+
These unset attributes will not be reported and may act as a default value
316+
for filtering purposes.
317+
318+
Reporting Attributes
319+
--------------------
320+
321+
When a user runs tests, attributes will be present in the raw kernel output (in
322+
KTAP format). Note that attributes will be hidden by default in kunit.py output
323+
for all passing tests but the raw kernel output can be accessed using the
324+
``--raw_output`` flag. This is an example of how test attributes for test cases
325+
will be formatted in kernel output:
326+
327+
.. code-block:: none
328+
329+
# example_test.speed: slow
330+
ok 1 example_test
331+
332+
This is an example of how test attributes for test suites will be formatted in
333+
kernel output:
334+
335+
.. code-block:: none
336+
337+
KTAP version 2
338+
# Subtest: example_suite
339+
# module: kunit_example_test
340+
1..3
341+
...
342+
ok 1 example_suite
343+
344+
Additionally, users can output a full attribute report of tests with their
345+
attributes, using the command line flag ``--list_tests_attr``:
346+
347+
.. code-block:: bash
348+
349+
kunit.py run "example" --list_tests_attr
350+
351+
.. note::
352+
This report can be accessed when running KUnit manually by passing in the
353+
module_param ``kunit.action=list_attr``.
354+
355+
Filtering
356+
---------
357+
358+
Users can filter tests using the ``--filter`` command line flag when running
359+
tests. As an example:
360+
361+
.. code-block:: bash
362+
363+
kunit.py run --filter speed=slow
364+
365+
366+
You can also use the following operations on filters: "<", ">", "<=", ">=",
367+
"!=", and "=". Example:
368+
369+
.. code-block:: bash
370+
371+
kunit.py run --filter "speed>slow"
372+
373+
This example will run all tests with speeds faster than slow. Note that the
374+
characters < and > are often interpreted by the shell, so they may need to be
375+
quoted or escaped, as above.
376+
377+
Additionally, you can use multiple filters at once. Simply separate filters
378+
using commas. Example:
379+
380+
.. code-block:: bash
381+
382+
kunit.py run --filter "speed>slow, module=kunit_example_test"
383+
384+
.. note::
385+
You can use this filtering feature when running KUnit manually by passing
386+
the filter as a module param: ``kunit.filter="speed>slow, speed<=normal"``.
387+
388+
Filtered tests will not run or show up in the test output. You can use the
389+
``--filter_action=skip`` flag to skip filtered tests instead. These tests will be
390+
shown in the test output in the test but will not run. To use this feature when
391+
running KUnit manually, use the module param ``kunit.filter_action=skip``.
392+
393+
Rules of Filtering Procedure
394+
----------------------------
395+
396+
Since both suites and test cases can have attributes, there may be conflicts
397+
between attributes during filtering. The process of filtering follows these
398+
rules:
399+
400+
- Filtering always operates at a per-test level.
401+
402+
- If a test has an attribute set, then the test's value is filtered on.
403+
404+
- Otherwise, the value falls back to the suite's value.
405+
406+
- If neither are set, the attribute has a global "default" value, which is used.
407+
408+
List of Current Attributes
409+
--------------------------
410+
411+
``speed``
412+
413+
This attribute indicates the speed of a test's execution (how slow or fast the
414+
test is).
415+
416+
This attribute is saved as an enum with the following categories: "normal",
417+
"slow", or "very_slow". The assumed default speed for tests is "normal". This
418+
indicates that the test takes a relatively trivial amount of time (less than
419+
1 second), regardless of the machine it is running on. Any test slower than
420+
this could be marked as "slow" or "very_slow".
421+
422+
The macro ``KUNIT_CASE_SLOW(test_name)`` can be easily used to set the speed
423+
of a test case to "slow".
424+
425+
``module``
426+
427+
This attribute indicates the name of the module associated with the test.
428+
429+
This attribute is automatically saved as a string and is printed for each suite.
430+
Tests can also be filtered using this attribute.

MAINTAINERS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11394,6 +11394,8 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest.git k
1139411394
F: Documentation/dev-tools/kunit/
1139511395
F: include/kunit/
1139611396
F: lib/kunit/
11397+
F: rust/kernel/kunit.rs
11398+
F: scripts/rustdoc_test_*
1139711399
F: tools/testing/kunit/
1139811400

1139911401
KERNEL USERMODE HELPER

include/kunit/attributes.h

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
/*
3+
* KUnit API to save and access test attributes
4+
*
5+
* Copyright (C) 2023, Google LLC.
6+
* Author: Rae Moar <rmoar@google.com>
7+
*/
8+
9+
#ifndef _KUNIT_ATTRIBUTES_H
10+
#define _KUNIT_ATTRIBUTES_H
11+
12+
/*
13+
* struct kunit_attr_filter - representation of attributes filter with the
14+
* attribute object and string input
15+
*/
16+
struct kunit_attr_filter {
17+
struct kunit_attr *attr;
18+
char *input;
19+
};
20+
21+
/*
22+
* Returns the name of the filter's attribute.
23+
*/
24+
const char *kunit_attr_filter_name(struct kunit_attr_filter filter);
25+
26+
/*
27+
* Print all test attributes for a test case or suite.
28+
* Output format for test cases: "# <test_name>.<attribute>: <value>"
29+
* Output format for test suites: "# <attribute>: <value>"
30+
*/
31+
void kunit_print_attr(void *test_or_suite, bool is_test, unsigned int test_level);
32+
33+
/*
34+
* Returns the number of fitlers in input.
35+
*/
36+
int kunit_get_filter_count(char *input);
37+
38+
/*
39+
* Parse attributes filter input and return an objects containing the
40+
* attribute object and the string input of the next filter.
41+
*/
42+
struct kunit_attr_filter kunit_next_attr_filter(char **filters, int *err);
43+
44+
/*
45+
* Returns a copy of the suite containing only tests that pass the filter.
46+
*/
47+
struct kunit_suite *kunit_filter_attr_tests(const struct kunit_suite *const suite,
48+
struct kunit_attr_filter filter, char *action, int *err);
49+
50+
#endif /* _KUNIT_ATTRIBUTES_H */

include/kunit/static_stub.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
#if !IS_ENABLED(CONFIG_KUNIT)
1212

1313
/* If CONFIG_KUNIT is not enabled, these stubs quietly disappear. */
14-
#define KUNIT_TRIGGER_STATIC_STUB(real_fn_name, args...) do {} while (0)
14+
#define KUNIT_STATIC_STUB_REDIRECT(real_fn_name, args...) do {} while (0)
1515

1616
#else
1717

@@ -30,7 +30,7 @@
3030
* This is a function prologue which is used to allow calls to the current
3131
* function to be redirected by a KUnit test. KUnit tests can call
3232
* kunit_activate_static_stub() to pass a replacement function in. The
33-
* replacement function will be called by KUNIT_TRIGGER_STATIC_STUB(), which
33+
* replacement function will be called by KUNIT_STATIC_STUB_REDIRECT(), which
3434
* will then return from the function. If the caller is not in a KUnit context,
3535
* the function will continue execution as normal.
3636
*
@@ -87,7 +87,7 @@ void __kunit_activate_static_stub(struct kunit *test,
8787
* When activated, calls to real_fn_addr from within this test (even if called
8888
* indirectly) will instead call replacement_addr. The function pointed to by
8989
* real_fn_addr must begin with the static stub prologue in
90-
* KUNIT_TRIGGER_STATIC_STUB() for this to work. real_fn_addr and
90+
* KUNIT_STATIC_STUB_REDIRECT() for this to work. real_fn_addr and
9191
* replacement_addr must have the same type.
9292
*
9393
* The redirection can be disabled again with kunit_deactivate_static_stub().

include/kunit/test-bug.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
#ifndef _KUNIT_TEST_BUG_H
1010
#define _KUNIT_TEST_BUG_H
1111

12+
#include <linux/stddef.h> /* for NULL */
13+
1214
#if IS_ENABLED(CONFIG_KUNIT)
1315

1416
#include <linux/jump_label.h> /* For static branch */

0 commit comments

Comments
 (0)