Skip to content

Commit

Permalink
Merge tag 'linux_kselftest-kunit-6.15-rc1' of git://git.kernel.org/pu…
Browse files Browse the repository at this point in the history
…b/scm/linux/kernel/git/shuah/linux-kselftest

Pull kunit updates from Shuah Khan:
 "kunit tool:
   - Changes to kunit tool to use qboot on QEMU x86_64, and build GDB
     scripts
   - Fixes kunit tool bug in parsing test plan
   - Adds test to kunit tool to check parsing late test plan

  kunit:
   - Clarifies kunit_skip() argument name
   - Adds Kunit check for the longest symbol length
   - Changes qemu_configs for sparc to use Zilog console"

* tag 'linux_kselftest-kunit-6.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest:
  kunit: tool: add test to check parsing late test plan
  kunit: tool: Fix bug in parsing test plan
  Kunit to check the longest symbol length
  kunit: Clarify kunit_skip() argument name
  kunit: tool: Build GDB scripts
  kunit: qemu_configs: sparc: use Zilog console
  kunit: tool: Use qboot on QEMU x86_64
  • Loading branch information
Linus Torvalds committed Mar 28, 2025
2 parents 8e324a5 + 2e0cf2b commit a10c794
Show file tree
Hide file tree
Showing 10 changed files with 130 additions and 21 deletions.
3 changes: 2 additions & 1 deletion arch/x86/tools/insn_decoder_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <assert.h>
#include <unistd.h>
#include <stdarg.h>
#include <linux/kallsyms.h>

#define unlikely(cond) (cond)

Expand Down Expand Up @@ -106,7 +107,7 @@ static void parse_args(int argc, char **argv)
}
}

#define BUFSIZE 256
#define BUFSIZE (256 + KSYM_NAME_LEN)

int main(int argc, char **argv)
{
Expand Down
20 changes: 10 additions & 10 deletions include/kunit/test.h
Original file line number Diff line number Diff line change
Expand Up @@ -553,39 +553,39 @@ void kunit_cleanup(struct kunit *test);
void __printf(2, 3) kunit_log_append(struct string_stream *log, const char *fmt, ...);

/**
* kunit_mark_skipped() - Marks @test_or_suite as skipped
* kunit_mark_skipped() - Marks @test as skipped
*
* @test_or_suite: The test context object.
* @test: The test context object.
* @fmt: A printk() style format string.
*
* Marks the test as skipped. @fmt is given output as the test status
* comment, typically the reason the test was skipped.
*
* Test execution continues after kunit_mark_skipped() is called.
*/
#define kunit_mark_skipped(test_or_suite, fmt, ...) \
#define kunit_mark_skipped(test, fmt, ...) \
do { \
WRITE_ONCE((test_or_suite)->status, KUNIT_SKIPPED); \
scnprintf((test_or_suite)->status_comment, \
WRITE_ONCE((test)->status, KUNIT_SKIPPED); \
scnprintf((test)->status_comment, \
KUNIT_STATUS_COMMENT_SIZE, \
fmt, ##__VA_ARGS__); \
} while (0)

/**
* kunit_skip() - Marks @test_or_suite as skipped
* kunit_skip() - Marks @test as skipped
*
* @test_or_suite: The test context object.
* @test: The test context object.
* @fmt: A printk() style format string.
*
* Skips the test. @fmt is given output as the test status
* comment, typically the reason the test was skipped.
*
* Test execution is halted after kunit_skip() is called.
*/
#define kunit_skip(test_or_suite, fmt, ...) \
#define kunit_skip(test, fmt, ...) \
do { \
kunit_mark_skipped((test_or_suite), fmt, ##__VA_ARGS__);\
kunit_try_catch_throw(&((test_or_suite)->try_catch)); \
kunit_mark_skipped((test), fmt, ##__VA_ARGS__); \
kunit_try_catch_throw(&((test)->try_catch)); \
} while (0)

/*
Expand Down
9 changes: 9 additions & 0 deletions lib/Kconfig.debug
Original file line number Diff line number Diff line change
Expand Up @@ -2866,6 +2866,15 @@ config FORTIFY_KUNIT_TEST
by the str*() and mem*() family of functions. For testing runtime
traps of FORTIFY_SOURCE, see LKDTM's "FORTIFY_*" tests.

config LONGEST_SYM_KUNIT_TEST
tristate "Test the longest symbol possible" if !KUNIT_ALL_TESTS
depends on KUNIT && KPROBES
default KUNIT_ALL_TESTS
help
Tests the longest symbol possible

If unsure, say N.

config HW_BREAKPOINT_KUNIT_TEST
bool "Test hw_breakpoint constraints accounting" if !KUNIT_ALL_TESTS
depends on HAVE_HW_BREAKPOINT
Expand Down
4 changes: 4 additions & 0 deletions lib/tests/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ obj-$(CONFIG_LIST_KUNIT_TEST) += list-test.o
obj-$(CONFIG_KFIFO_KUNIT_TEST) += kfifo_kunit.o
obj-$(CONFIG_TEST_LIST_SORT) += test_list_sort.o
obj-$(CONFIG_LINEAR_RANGES_TEST) += test_linear_ranges.o

CFLAGS_longest_symbol_kunit.o += $(call cc-disable-warning, missing-prototypes)
obj-$(CONFIG_LONGEST_SYM_KUNIT_TEST) += longest_symbol_kunit.o

obj-$(CONFIG_MEMCPY_KUNIT_TEST) += memcpy_kunit.o
CFLAGS_overflow_kunit.o = $(call cc-disable-warning, tautological-constant-out-of-range-compare)
obj-$(CONFIG_OVERFLOW_KUNIT_TEST) += overflow_kunit.o
Expand Down
82 changes: 82 additions & 0 deletions lib/tests/longest_symbol_kunit.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
// SPDX-License-Identifier: GPL-2.0
/*
* 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
*/

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <kunit/test.h>
#include <linux/stringify.h>
#include <linux/kprobes.h>
#include <linux/kallsyms.h>

#define DI(name) s##name##name
#define DDI(name) DI(n##name##name)
#define DDDI(name) DDI(n##name##name)
#define DDDDI(name) DDDI(n##name##name)
#define DDDDDI(name) DDDDI(n##name##name)

/*Generate a symbol whose name length is 511 */
#define LONGEST_SYM_NAME DDDDDI(g1h2i3j4k5l6m7n)

#define RETURN_LONGEST_SYM 0xAAAAA

noinline int LONGEST_SYM_NAME(void);
noinline int LONGEST_SYM_NAME(void)
{
return RETURN_LONGEST_SYM;
}

_Static_assert(sizeof(__stringify(LONGEST_SYM_NAME)) == KSYM_NAME_LEN,
"Incorrect symbol length found. Expected KSYM_NAME_LEN: "
__stringify(KSYM_NAME_LEN) ", but found: "
__stringify(sizeof(LONGEST_SYM_NAME)));

static void test_longest_symbol(struct kunit *test)
{
KUNIT_EXPECT_EQ(test, RETURN_LONGEST_SYM, LONGEST_SYM_NAME());
};

static void test_longest_symbol_kallsyms(struct kunit *test)
{
unsigned long (*kallsyms_lookup_name)(const char *name);
static int (*longest_sym)(void);

struct kprobe kp = {
.symbol_name = "kallsyms_lookup_name",
};

if (register_kprobe(&kp) < 0) {
pr_info("%s: kprobe not registered", __func__);
KUNIT_FAIL(test, "test_longest_symbol kallsyms: kprobe not registered\n");
return;
}

kunit_warn(test, "test_longest_symbol kallsyms: kprobe registered\n");
kallsyms_lookup_name = (unsigned long (*)(const char *name))kp.addr;
unregister_kprobe(&kp);

longest_sym =
(void *) kallsyms_lookup_name(__stringify(LONGEST_SYM_NAME));
KUNIT_EXPECT_EQ(test, RETURN_LONGEST_SYM, longest_sym());
};

static struct kunit_case longest_symbol_test_cases[] = {
KUNIT_CASE(test_longest_symbol),
KUNIT_CASE(test_longest_symbol_kallsyms),
{}
};

static struct kunit_suite longest_symbol_test_suite = {
.name = "longest-symbol",
.test_cases = longest_symbol_test_cases,
};
kunit_test_suite(longest_symbol_test_suite);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Test the longest symbol length");
MODULE_AUTHOR("Sergio González Collado");
4 changes: 2 additions & 2 deletions tools/testing/kunit/kunit_kernel.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,8 @@ def make_olddefconfig(self, build_dir: str, make_options: Optional[List[str]]) -
raise ConfigError(e.output.decode())

def make(self, jobs: int, build_dir: str, make_options: Optional[List[str]]) -> None:
command = ['make', 'all', 'compile_commands.json', 'ARCH=' + self._linux_arch,
'O=' + build_dir, '--jobs=' + str(jobs)]
command = ['make', 'all', 'compile_commands.json', 'scripts_gdb',
'ARCH=' + self._linux_arch, 'O=' + build_dir, '--jobs=' + str(jobs)]
if make_options:
command.extend(make_options)
if self._cross_compile:
Expand Down
9 changes: 4 additions & 5 deletions tools/testing/kunit/kunit_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -759,7 +759,7 @@ def parse_test(lines: LineStream, expected_num: int, log: List[str], is_subtest:
# If parsing the main/top-level test, parse KTAP version line and
# test plan
test.name = "main"
ktap_line = parse_ktap_header(lines, test, printer)
parse_ktap_header(lines, test, printer)
test.log.extend(parse_diagnostic(lines))
parse_test_plan(lines, test)
parent_test = True
Expand All @@ -768,13 +768,12 @@ def parse_test(lines: LineStream, expected_num: int, log: List[str], is_subtest:
# the KTAP version line and/or subtest header line
ktap_line = parse_ktap_header(lines, test, printer)
subtest_line = parse_test_header(lines, test)
test.log.extend(parse_diagnostic(lines))
parse_test_plan(lines, test)
parent_test = (ktap_line or subtest_line)
if parent_test:
# If KTAP version line and/or subtest header is found, attempt
# to parse test plan and print test header
test.log.extend(parse_diagnostic(lines))
parse_test_plan(lines, test)
print_test_header(test, printer)

expected_count = test.expected_count
subtests = []
test_num = 1
Expand Down
11 changes: 11 additions & 0 deletions tools/testing/kunit/kunit_tool_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,17 @@ def test_show_test_output_on_failure(self):
self.print_mock.assert_any_call(StrContains(' Indented more.'))
self.noPrintCallContains('not ok 1 test1')

def test_parse_late_test_plan(self):
output = """
TAP version 13
ok 4 test4
1..4
"""
result = kunit_parser.parse_run_tests(output.splitlines(), stdout)
# Missing test results after test plan should alert a suspected test crash.
self.assertEqual(kunit_parser.TestStatus.TEST_CRASHED, result.status)
self.assertEqual(result.counts, kunit_parser.TestCounts(passed=1, crashed=1, errors=1))

def line_stream_from_strs(strs: Iterable[str]) -> kunit_parser.LineStream:
return kunit_parser.LineStream(enumerate(strs, start=1))

Expand Down
5 changes: 3 additions & 2 deletions tools/testing/kunit/qemu_configs/sparc.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@

QEMU_ARCH = QemuArchParams(linux_arch='sparc',
kconfig='''
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y''',
CONFIG_SERIAL_SUNZILOG=y
CONFIG_SERIAL_SUNZILOG_CONSOLE=y
''',
qemu_arch='sparc',
kernel_path='arch/sparc/boot/zImage',
kernel_command_line='console=ttyS0 mem=256M',
Expand Down
4 changes: 3 additions & 1 deletion tools/testing/kunit/qemu_configs/x86_64.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,6 @@
qemu_arch='x86_64',
kernel_path='arch/x86/boot/bzImage',
kernel_command_line='console=ttyS0',
extra_qemu_params=[])
# qboot is faster than SeaBIOS and doesn't mess up
# the terminal.
extra_qemu_params=['-bios', 'qboot.rom'])

0 comments on commit a10c794

Please sign in to comment.