Currently, kselftests does not have a generalised mechanism to skip compilation and run tests when required kernel configuration options are disabled.
This patch series adresses this issue by checking whether all required configs from selftest/<test>/config are enabled in the current kernel
Siddharth Menon (2): selftests: Introduce script to validate required dependencies selftests/lib.mk: Introduce check to validate required dependencies
.../testing/selftests/check_kselftest_deps.pl | 170 ++++++++++++++++++ tools/testing/selftests/lib.mk | 15 +- 2 files changed, 183 insertions(+), 2 deletions(-) create mode 100755 tools/testing/selftests/check_kselftest_deps.pl
This patch adds a script to validate that the current kernel configuration satisfies the requirements for selftests by comparing the current kernel configs against the required selftest configs.
The script also runs kselftest_deps.sh to check for any missing libraries required by the selftest.
A config mismatch exits with error value 1 while matching configs or missing config files exit with value 0. In order to silence missing dependency output, set the environment variable SILENCE=1.
The code for extracting the current kernel configs is adapted from scripts/kconfig/streamline_config.pl.
Suggested-by: Petr Mladek pmladek@suse.com Suggested-by: Miroslav Benes mbenes@suse.cz Signed-off-by: Siddharth Menon simeddon@gmail.com --- v1->v2: - check selftest/config directly rather than a separate set in the test makefile v2->v3: - Integrate kselftest_deps.sh to check for missing libraries (I have not set it to skip the tests here, as it sometimes throws outputs such as missing $(LIB) or $(MNL_LDLIBS)) - Replaced spaces with tabs, removed trailing spaces and other minor formatting changes - Introduced flag to silence the missing dependencies debug statements - Rename script to a more meaningful name
.../testing/selftests/check_kselftest_deps.pl | 170 ++++++++++++++++++ 1 file changed, 170 insertions(+) create mode 100755 tools/testing/selftests/check_kselftest_deps.pl
diff --git a/tools/testing/selftests/check_kselftest_deps.pl b/tools/testing/selftests/check_kselftest_deps.pl new file mode 100755 index 000000000000..ef1a5fe8c321 --- /dev/null +++ b/tools/testing/selftests/check_kselftest_deps.pl @@ -0,0 +1,170 @@ +#!/usr/bin/env perl +# SPDX-License-Identifier: GPL-2.0 +use warnings; +use strict; +use Getopt::Long; +use File::Spec; +use File::Basename; + +# set the environment variable SILENCE to silence +# debug output. + +# Check if required arguments are provided +die "Usage: $0 <selftest_path> <compiler>\n" unless @ARGV >= 2; + +my $test_path = $ARGV[0]; +my $cc = join(' ', @ARGV[1..$#ARGV]); +my $script_dir = dirname(__FILE__); + +my $silenceprint; +$silenceprint = 1 if (defined($ENV{SILENCE})); + +sub dprint { + return if ($silenceprint); + print STDERR @_; +} + +my $uname = `uname -r`; +chomp $uname; + +my @searchconfigs = ( + { + "file" => ".config", + "exec" => "cat", + }, + { + "file" => "/proc/config.gz", + "exec" => "zcat", + }, + { + "file" => "/boot/config-$uname", + "exec" => "cat", + }, + { + "file" => "/boot/vmlinuz-$uname", + "exec" => "scripts/extract-ikconfig", + "test" => "scripts/extract-ikconfig", + }, + { + "file" => "vmlinux", + "exec" => "scripts/extract-ikconfig", + "test" => "scripts/extract-ikconfig", + }, + { + "file" => "/lib/modules/$uname/kernel/kernel/configs.ko", + "exec" => "scripts/extract-ikconfig", + "test" => "scripts/extract-ikconfig", + }, + { + "file" => "/lib/modules/$uname/build/.config", + "exec" => "cat", + }, + { + "file" => "kernel/configs.ko", + "exec" => "scripts/extract-ikconfig", + "test" => "scripts/extract-ikconfig", + }, + { + "file" => "kernel/configs.o", + "exec" => "scripts/extract-ikconfig", + "test" => "scripts/extract-ikconfig", + }, +); + +sub read_config { + foreach my $conf (@searchconfigs) { + my $file = $conf->{"file"}; + + next unless -f $file; + + if (defined $conf->{"test"}) { + `$conf->{"test"} $file 2>/dev/null`; + next if $?; + } + + my $exec = $conf->{"exec"}; + + # dprint "Kernel config: '$file'\n"; + + open(my $infile, '-|', "$exec $file") or die "Failed to run $exec $file"; + my @config_content = <$infile>; + close $infile; + + return @config_content; + } + + dprint "Unable to find kernel config file, skipping check\n"; + exit 0; +} + +sub check_libs { + my $command = "cd $script_dir && ./kselftest_deps.sh "$cc" $test_path"; + my $lib_test = `$command 2>&1`; + my $exit_code = $? >> 8; + + if ($exit_code != 0) { + die "Error: Failed to run kselftest_deps.sh with exit code $exit_code\n"; + } + + return $lib_test; +} + +# Check for missing libraries +my $lib_test = check_libs(); +my $fail_libs; + +if ($lib_test =~ +/(--------------------------------------------------------\s +*Missing libraries system.*? +--------------------------------------------------------)/s) { + $fail_libs = $1; +} + +dprint("$fail_libs\n") if $fail_libs; + +# Read and parse kernel config +my @config_file = read_config(); +my %kern_configs; +foreach my $line (@config_file) { + chomp $line; + next if $line =~ /^\s*$/ || $line =~ /^#/; + + if ($line =~ /^(CONFIG_\w+)=(.+)$/) { + $kern_configs{$1} = $2; + } +} + +# Read and parse test config +my %test_configs; +open(my $fh, '<', "$test_path/config") or exit 0; + +while (my $line = <$fh>) { + chomp $line; + next if $line =~ /^\s*$/ || $line =~ /^#/; + + if ($line =~ /^(CONFIG_\w+)=(.+)$/) { + $test_configs{$1} = $2; + } +} +close $fh; + +# Compare selftest configs with kernel configs +my $all_match = 1; +my @missing_or_mismatched; + +foreach my $key (keys %test_configs) { + if (!exists $kern_configs{$key} || $kern_configs{$key} ne $test_configs{$key}) { + push @missing_or_mismatched, "Required: $key=$test_configs{$key}"; + $all_match = 0; + } +} + +if ($all_match && !$fail_libs) { + exit 0; +} else { + dprint("--------------------------------------------------------\n") unless $fail_libs; + dprint("$_\n") for @missing_or_mismatched; + dprint("--------------------------------------------------------\n") if @missing_or_mismatched; + + exit 1; +}
Currently, kselftests does not have a generalised mechanism to skip compilation and run tests when required kernel configuration flags are missing.
This patch introduces a check to validate the presence of required config flags specified in the selftest config files. In case scripts/config or the current kernel config is not found, this check is skipped.
In order to skip checking for config options required to compile the test, set the environment variable SKIP_CHECKS=1.
example usage: ``` make SKIP_CHECKS=1 -C livepatch/ ```
Suggested-by: Petr Mladek pmladek@suse.com Suggested-by: Miroslav Benes mbenes@suse.cz Signed-off-by: Siddharth Menon simeddon@gmail.com --- v1->v2: - Moved the logic to check for required configurations to an external script v2 -> v3: - Add SKIP_CHECKS flag to skip checking the dependencies if required - Updated the test skip statement to be more meaningful
tools/testing/selftests/lib.mk | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/lib.mk b/tools/testing/selftests/lib.mk index d6edcfcb5be8..0e11d1d3bab8 100644 --- a/tools/testing/selftests/lib.mk +++ b/tools/testing/selftests/lib.mk @@ -97,7 +97,18 @@ TEST_GEN_PROGS := $(patsubst %,$(OUTPUT)/%,$(TEST_GEN_PROGS)) TEST_GEN_PROGS_EXTENDED := $(patsubst %,$(OUTPUT)/%,$(TEST_GEN_PROGS_EXTENDED)) TEST_GEN_FILES := $(patsubst %,$(OUTPUT)/%,$(TEST_GEN_FILES))
-all: $(TEST_GEN_PROGS) $(TEST_GEN_PROGS_EXTENDED) $(TEST_GEN_FILES) \ +TEST_DIR := $(shell pwd) + +check_kselftest_deps: +ifneq ($(SKIP_CHECKS),1) + @$(selfdir)/check_kselftest_deps.pl $(TEST_DIR) $(CC) || { \ + echo "Skipping test: $(notdir $(TEST_DIR)) (missing required kernel features)"; \ + exit 1; \ + } +endif + + +all: check_kselftest_deps $(TEST_GEN_PROGS) $(TEST_GEN_PROGS_EXTENDED) $(TEST_GEN_FILES) \ $(if $(TEST_GEN_MODS_DIR),gen_mods_dir)
define RUN_TESTS @@ -228,4 +239,4 @@ $(OUTPUT)/%:%.S $(LINK.S) $^ $(LDLIBS) -o $@ endif
-.PHONY: run_tests all clean install emit_tests gen_mods_dir clean_mods_dir +.PHONY: run_tests all clean install emit_tests gen_mods_dir clean_mods_dir check_kselftest_deps
On 2/26/25 22:29, Siddharth Menon wrote:
Currently, kselftests does not have a generalised mechanism to skip compilation and run tests when required kernel configuration options are disabled.
Skipping compile by default is not what we want to do. Tests are supposed to compile and run even when config options are not enabled.
There is something wrong if the test doesn't compile when a config option isn't enabled in the kernel.
This patch series adresses this issue by checking whether all required configs from selftest/<test>/config are enabled in the current kernel
Siddharth Menon (2): selftests: Introduce script to validate required dependencies selftests/lib.mk: Introduce check to validate required dependencies
.../testing/selftests/check_kselftest_deps.pl | 170 ++++++++++++++++++ tools/testing/selftests/lib.mk | 15 +- 2 files changed, 183 insertions(+), 2 deletions(-) create mode 100755 tools/testing/selftests/check_kselftest_deps.pl
thanks, -- Shuah
linux-kselftest-mirror@lists.linaro.org