Merge tag 'linux_kselftest-kunit-6.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest

Pull kunit updates from Shuah Khan:

 - Enable qemu_config for riscv32, sparc 64-bit, PowerPC 32-bit BE and
   64-bit LE

 - Enable CONFIG_SPARC32 to clearly differentiate between sparc 32-bit
   and 64-bit configurations

 - Enable CONFIG_CPU_BIG_ENDIAN to clearly differentiate between powerpc
   LE and BE configurations

 - Add feature to list available architectures to kunit tool

 - Fixes to bugs and changes to documentation

* tag 'linux_kselftest-kunit-6.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest:
  kunit: Fix wrong parameter to kunit_deactivate_static_stub()
  kunit: tool: add test counts to JSON output
  Documentation: kunit: improve example on testing static functions
  kunit: executor: Remove const from kunit_filter_suites() allocation type
  kunit: qemu_configs: Disable faulting tests on 32-bit SPARC
  kunit: qemu_configs: Add 64-bit SPARC configuration
  kunit: qemu_configs: sparc: Explicitly enable CONFIG_SPARC32=y
  kunit: qemu_configs: Add PowerPC 32-bit BE and 64-bit LE
  kunit: qemu_configs: powerpc: Explicitly enable CONFIG_CPU_BIG_ENDIAN=y
  kunit: tool: Implement listing of available architectures
  kunit: qemu_configs: Add riscv32 config
  kunit: configs: Enable CONFIG_INIT_STACK_ALL_PATTERN in all_tests
This commit is contained in:
Linus Torvalds
2025-05-26 14:29:44 -07:00
13 changed files with 120 additions and 10 deletions

View File

@@ -182,6 +182,8 @@ via UML. To run tests on qemu, by default it requires two flags:
is ignored), the tests will run via UML. Non-UML architectures,
for example: i386, x86_64, arm and so on; run on qemu.
``--arch help`` lists all valid ``--arch`` values.
- ``--cross_compile``: Specifies the Kbuild toolchain. It passes the
same argument as passed to the ``CROSS_COMPILE`` variable used by
Kbuild. As a reminder, this will be the prefix for the toolchain

View File

@@ -670,28 +670,50 @@ with ``kunit_remove_action``.
Testing Static Functions
------------------------
If we do not want to expose functions or variables for testing, one option is to
conditionally export the used symbol. For example:
If you want to test static functions without exposing those functions outside of
testing, one option is conditionally export the symbol. When KUnit is enabled,
the symbol is exposed but remains static otherwise. To use this method, follow
the template below.
.. code-block:: c
/* In my_file.c */
/* In the file containing functions to test "my_file.c" */
VISIBLE_IF_KUNIT int do_interesting_thing();
#include <kunit/visibility.h>
#include <my_file.h>
...
VISIBLE_IF_KUNIT int do_interesting_thing()
{
...
}
EXPORT_SYMBOL_IF_KUNIT(do_interesting_thing);
/* In my_file.h */
/* In the header file "my_file.h" */
#if IS_ENABLED(CONFIG_KUNIT)
int do_interesting_thing(void);
#endif
Alternatively, you could conditionally ``#include`` the test file at the end of
your .c file. For example:
/* In the KUnit test file "my_file_test.c" */
#include <kunit/visibility.h>
#include <my_file.h>
...
MODULE_IMPORT_NS(EXPORTED_FOR_KUNIT_TESTING);
...
// Use do_interesting_thing() in tests
For a full example, see this `patch <https://lore.kernel.org/all/20221207014024.340230-3-rmoar@google.com/>`_
where a test is modified to conditionally expose static functions for testing
using the macros above.
As an **alternative** to the method above, you could conditionally ``#include``
the test file at the end of your .c file. This is not recommended but works
if needed. For example:
.. code-block:: c
/* In my_file.c */
/* In "my_file.c" */
static int do_interesting_thing();

View File

@@ -177,7 +177,7 @@ kunit_filter_suites(const struct kunit_suite_set *suite_set,
const size_t max = suite_set->end - suite_set->start;
copy = kcalloc(max, sizeof(*filtered.start), GFP_KERNEL);
copy = kcalloc(max, sizeof(*copy), GFP_KERNEL);
if (!copy) { /* won't be able to run anything, return an empty set */
return filtered;
}

View File

@@ -96,7 +96,7 @@ void __kunit_activate_static_stub(struct kunit *test,
/* If the replacement address is NULL, deactivate the stub. */
if (!replacement_addr) {
kunit_deactivate_static_stub(test, replacement_addr);
kunit_deactivate_static_stub(test, real_fn_addr);
return;
}

View File

@@ -10,6 +10,7 @@ CONFIG_KUNIT_EXAMPLE_TEST=y
CONFIG_KUNIT_ALL_TESTS=y
CONFIG_FORTIFY_SOURCE=y
CONFIG_INIT_STACK_ALL_PATTERN=y
CONFIG_IIO=y

View File

@@ -39,10 +39,20 @@ def _get_group_json(test: Test, common_fields: JsonObj) -> JsonObj:
status = _status_map.get(subtest.status, "FAIL")
test_cases.append({"name": subtest.name, "status": status})
test_counts = test.counts
counts_json = {
"tests": test_counts.total(),
"passed": test_counts.passed,
"failed": test_counts.failed,
"crashed": test_counts.crashed,
"skipped": test_counts.skipped,
"errors": test_counts.errors,
}
test_group = {
"name": test.name,
"sub_groups": sub_groups,
"test_cases": test_cases,
"misc": counts_json
}
test_group.update(common_fields)
return test_group

View File

@@ -14,6 +14,7 @@ import os
import shlex
import shutil
import signal
import sys
import threading
from typing import Iterator, List, Optional, Tuple
from types import FrameType
@@ -201,6 +202,13 @@ def _default_qemu_config_path(arch: str) -> str:
return config_path
options = [f[:-3] for f in os.listdir(QEMU_CONFIGS_DIR) if f.endswith('.py')]
if arch == 'help':
print('um')
for option in options:
print(option)
sys.exit()
raise ConfigError(arch + ' is not a valid arch, options are ' + str(sorted(options)))
def _get_qemu_ops(config_path: str,

View File

@@ -3,6 +3,7 @@ from ..qemu_config import QemuArchParams
QEMU_ARCH = QemuArchParams(linux_arch='powerpc',
kconfig='''
CONFIG_PPC64=y
CONFIG_CPU_BIG_ENDIAN=y
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_HVC_CONSOLE=y''',

View File

@@ -0,0 +1,17 @@
# SPDX-License-Identifier: GPL-2.0
from ..qemu_config import QemuArchParams
QEMU_ARCH = QemuArchParams(linux_arch='powerpc',
kconfig='''
CONFIG_PPC32=y
CONFIG_CPU_BIG_ENDIAN=y
CONFIG_ADB_CUDA=y
CONFIG_SERIAL_PMACZILOG=y
CONFIG_SERIAL_PMACZILOG_TTYS=y
CONFIG_SERIAL_PMACZILOG_CONSOLE=y
''',
qemu_arch='ppc',
kernel_path='vmlinux',
kernel_command_line='console=ttyS0',
extra_qemu_params=['-M', 'g3beige', '-cpu', 'max'])

View File

@@ -0,0 +1,14 @@
# SPDX-License-Identifier: GPL-2.0
from ..qemu_config import QemuArchParams
QEMU_ARCH = QemuArchParams(linux_arch='powerpc',
kconfig='''
CONFIG_PPC64=y
CONFIG_CPU_LITTLE_ENDIAN=y
CONFIG_HVC_CONSOLE=y
''',
qemu_arch='ppc64',
kernel_path='vmlinux',
kernel_command_line='console=ttyS0',
extra_qemu_params=['-M', 'pseries', '-cpu', 'power8'])

View File

@@ -0,0 +1,17 @@
# SPDX-License-Identifier: GPL-2.0
from ..qemu_config import QemuArchParams
QEMU_ARCH = QemuArchParams(linux_arch='riscv',
kconfig='''
CONFIG_NONPORTABLE=y
CONFIG_ARCH_RV32I=y
CONFIG_ARCH_VIRT=y
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_OF_PLATFORM=y
''',
qemu_arch='riscv32',
kernel_path='arch/riscv/boot/Image',
kernel_command_line='console=ttyS0',
extra_qemu_params=['-machine', 'virt'])

View File

@@ -2,6 +2,8 @@ from ..qemu_config import QemuArchParams
QEMU_ARCH = QemuArchParams(linux_arch='sparc',
kconfig='''
CONFIG_KUNIT_FAULT_TEST=n
CONFIG_SPARC32=y
CONFIG_SERIAL_SUNZILOG=y
CONFIG_SERIAL_SUNZILOG_CONSOLE=y
''',

View File

@@ -0,0 +1,16 @@
# SPDX-License-Identifier: GPL-2.0
from ..qemu_config import QemuArchParams
QEMU_ARCH = QemuArchParams(linux_arch='sparc',
kconfig='''
CONFIG_64BIT=y
CONFIG_SPARC64=y
CONFIG_PCI=y
CONFIG_SERIAL_SUNSU=y
CONFIG_SERIAL_SUNSU_CONSOLE=y
''',
qemu_arch='sparc64',
kernel_path='arch/sparc/boot/image',
kernel_command_line='console=ttyS0 kunit_shutdown=poweroff',
extra_qemu_params=[])