diff options
-rw-r--r-- | tools/testing/ktest/examples/include/patchcheck.conf | 37 | ||||
-rwxr-xr-x | tools/testing/ktest/ktest.pl | 110 | ||||
-rw-r--r-- | tools/testing/ktest/sample.conf | 44 |
3 files changed, 185 insertions, 6 deletions
diff --git a/tools/testing/ktest/examples/include/patchcheck.conf b/tools/testing/ktest/examples/include/patchcheck.conf index 339d3e1..0eb0a5a 100644 --- a/tools/testing/ktest/examples/include/patchcheck.conf +++ b/tools/testing/ktest/examples/include/patchcheck.conf @@ -14,6 +14,16 @@ PATCH_START := HEAD~3 PATCH_END := HEAD +# Use the oldconfig if build_type wasn't defined +DEFAULTS IF NOT DEFINED BUILD_TYPE +DO_BUILD_TYPE := oldconfig + +DEFAULTS ELSE +DO_BUILD_TYPE := ${BUILD_TYPE} + +DEFAULTS + + # Change PATCH_CHECKOUT to be the branch you want to test. The test will # do a git checkout of this branch before starting. Obviously both # PATCH_START and PATCH_END must be in this branch (and PATCH_START must @@ -43,6 +53,31 @@ PATCH_TEST_TYPE := boot # (space delimited) #IGNORE_WARNINGS = 39eaf7ef884dcc44f7ff1bac803ca2a1dcf43544 6edb2a8a385f0cdef51dae37ff23e74d76d8a6ce +# Instead of just checking for warnings to files that are changed +# it can be advantageous to check for any new warnings. If a +# header file is changed, it could cause a warning in a file not +# touched by the commit. To detect these kinds of warnings, you +# can use the WARNINGS_FILE option. +# +# If the variable CREATE_WARNINGS_FILE is set, this config will +# enable the WARNINGS_FILE during the patchcheck test. Also, +# before running the patchcheck test, it will create the +# warnings file. +# +DEFAULTS IF DEFINED CREATE_WARNINGS_FILE +WARNINGS_FILE = ${OUTPUT_DIR}/warnings_file + +TEST_START IF DEFINED CREATE_WARNINGS_FILE +# WARNINGS_FILE is already set by the DEFAULTS above +TEST_TYPE = make_warnings_file +# Checkout the commit before the patches to test, +# and record all the warnings that exist before the patches +# to test are added +CHECKOUT = ${PATCHCHECK_START}~1 +# Force a full build +BUILD_NOCLEAN = 0 +BUILD_TYPE = ${DO_BUILD_TYPE} + # If you are running a multi test, and the test failed on the first # test but on, say the 5th patch. If you want to restart on the # fifth patch, set PATCH_START1. This will make the first test start @@ -61,6 +96,7 @@ PATCHCHECK_TYPE = ${PATCH_TEST_TYPE} PATCHCHECK_START = ${PATCH_START1} PATCHCHECK_END = ${PATCH_END} CHECKOUT = ${PATCH_CHECKOUT} +BUILD_TYPE = ${DO_BUILD_TYPE} TEST_START IF ${TEST} == patchcheck && ${MULTI} TEST_TYPE = patchcheck @@ -72,3 +108,4 @@ PATCHCHECK_END = ${PATCH_END} CHECKOUT = ${PATCH_CHECKOUT} # Use multi to test different compilers? MAKE_CMD = CC=gcc-4.5.1 make +BUILD_TYPE = ${DO_BUILD_TYPE} diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl index 3d19ee4..3fd768e 100755 --- a/tools/testing/ktest/ktest.pl +++ b/tools/testing/ktest/ktest.pl @@ -126,6 +126,7 @@ my $start_minconfig_defined; my $output_minconfig; my $minconfig_type; my $use_output_minconfig; +my $warnings_file; my $ignore_config; my $ignore_errors; my $addconfig; @@ -193,6 +194,9 @@ my $patchcheck_end; # which would require more options. my $buildonly = 1; +# tell build not to worry about warnings, even when WARNINGS_FILE is set +my $warnings_ok = 0; + # set when creating a new config my $newconfig = 0; @@ -235,6 +239,7 @@ my %option_map = ( "START_MIN_CONFIG" => \$start_minconfig, "MIN_CONFIG_TYPE" => \$minconfig_type, "USE_OUTPUT_MIN_CONFIG" => \$use_output_minconfig, + "WARNINGS_FILE" => \$warnings_file, "IGNORE_CONFIG" => \$ignore_config, "TEST" => \$run_test, "ADD_CONFIG" => \$addconfig, @@ -1924,7 +1929,60 @@ sub start_monitor_and_boot { return monitor; } +my $check_build_re = ".*:.*(warning|error|Error):.*"; +my $utf8_quote = "\\x{e2}\\x{80}(\\x{98}|\\x{99})"; + +# Read buildlog and check against warnings file for any +# new warnings. +# +# Returns 1 if OK +# 0 otherwise sub check_buildlog { + return 1 if (!defined $warnings_file); + + my %warnings_list; + + # Failed builds should not reboot the target + my $save_no_reboot = $no_reboot; + $no_reboot = 1; + + if (-f $warnings_file) { + open(IN, $warnings_file) or + dodie "Error opening $warnings_file"; + + while (<IN>) { + if (/$check_build_re/) { + chomp; + $warnings_list{$_} = 1; + } + } + close(IN); + } + + # If warnings file didn't exist, and WARNINGS_FILE exist, + # then we fail on any warning! + + open(IN, $buildlog) or dodie "Can't open $buildlog"; + while (<IN>) { + if (/$check_build_re/) { + + # Some compilers use UTF-8 extended for quotes + # for distcc heterogeneous systems, this causes issues + s/$utf8_quote/'/g; + + chomp; + if (!defined $warnings_list{$_}) { + fail "New warning found (not in $warnings_file)\n$_\n"; + $no_reboot = $save_no_reboot; + return 0; + } + } + } + $no_reboot = $save_no_reboot; + close(IN); +} + +sub check_patch_buildlog { my ($patch) = @_; my @files = `git show $patch | diffstat -l`; @@ -3080,11 +3138,13 @@ sub patchcheck { build "oldconfig" or return 0; } - - if (!defined($ignored_warnings{$sha1})) { - check_buildlog $sha1 or return 0; + # No need to do per patch checking if warnings file exists + if (!defined($warnings_file) && !defined($ignored_warnings{$sha1})) { + check_patch_buildlog $sha1 or return 0; } + check_buildlog or return 0; + next if ($type eq "build"); my $failed = 0; @@ -3642,6 +3702,39 @@ sub make_min_config { return 1; } +sub make_warnings_file { + my ($i) = @_; + + if (!defined($warnings_file)) { + dodie "Must define WARNINGS_FILE for make_warnings_file test"; + } + + if ($build_type eq "nobuild") { + dodie "BUILD_TYPE can not be 'nobuild' for make_warnings_file test"; + } + + build $build_type or dodie "Failed to build"; + + open(OUT, ">$warnings_file") or dodie "Can't create $warnings_file"; + + open(IN, $buildlog) or dodie "Can't open $buildlog"; + while (<IN>) { + + # Some compilers use UTF-8 extended for quotes + # for distcc heterogeneous systems, this causes issues + s/$utf8_quote/'/g; + + if (/$check_build_re/) { + print OUT; + } + } + close(IN); + + close(OUT); + + success $i; +} + $#ARGV < 1 or die "ktest.pl version: $VERSION\n usage: ktest.pl config-file\n"; if ($#ARGV == 0) { @@ -3843,9 +3936,9 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) { $run_type = $bisect_type; } elsif ($test_type eq "config_bisect") { $run_type = $config_bisect_type; - } - - if ($test_type eq "make_min_config") { + } elsif ($test_type eq "make_min_config") { + $run_type = ""; + } elsif ($test_type eq "make_warnings_file") { $run_type = ""; } @@ -3902,10 +3995,15 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) { } elsif ($test_type eq "make_min_config") { make_min_config $i; next; + } elsif ($test_type eq "make_warnings_file") { + $no_reboot = 1; + make_warnings_file $i; + next; } if ($build_type ne "nobuild") { build $build_type or next; + check_buildlog or next; } if ($test_type eq "install") { diff --git a/tools/testing/ktest/sample.conf b/tools/testing/ktest/sample.conf index 4012e93..0a290fb 100644 --- a/tools/testing/ktest/sample.conf +++ b/tools/testing/ktest/sample.conf @@ -793,6 +793,20 @@ # Example for a virtual guest call "Guest". #POWER_OFF = virsh destroy Guest +# To have the build fail on "new" warnings, create a file that +# contains a list of all known warnings (they must match exactly +# to the line with 'warning:', 'error:' or 'Error:'. If the option +# WARNINGS_FILE is set, then that file will be read, and if the +# build detects a warning, it will examine this file and if the +# warning does not exist in it, it will fail the build. +# +# Note, if this option is defined to a file that does not exist +# then any warning will fail the build. +# (see make_warnings_file below) +# +# (optional, default undefined) +#WARNINGS_FILE = ${OUTPUT_DIR}/warnings_file + # The way to execute a command on the target # (default ssh $SSH_USER@$MACHINE $SSH_COMMAND";) # The variables SSH_USER, MACHINE and SSH_COMMAND are defined @@ -1222,3 +1236,33 @@ # MIN_CONFIG_TYPE = test # TEST = ssh ${USER}@${MACHINE} echo hi # +# +# +# +# For TEST_TYPE = make_warnings_file +# +# If you want the build to fail when a new warning is discovered +# you set the WARNINGS_FILE to point to a file of known warnings. +# +# The test "make_warnings_file" will let you create a new warnings +# file before you run other tests, like patchcheck. +# +# What this test does is to run just a build, you still need to +# specify BUILD_TYPE to tell the test what type of config to use. +# A BUILD_TYPE of nobuild will fail this test. +# +# The test will do the build and scan for all warnings. Any warning +# it discovers will be saved in the WARNINGS_FILE (required) option. +# +# It is recommended (but not necessary) to make sure BUILD_NOCLEAN is +# off, so that a full build is done (make mrproper is performed). +# That way, all warnings will be captured. +# +# Example: +# +# TEST_TYPE = make_warnings_file +# WARNINGS_FILE = ${OUTPUT_DIR} +# BUILD_TYPE = useconfig:oldconfig +# CHECKOUT = v3.8 +# BUILD_NOCLEAN = 0 +# |