aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xtools/testing/ktest/ktest.pl452
1 files changed, 226 insertions, 226 deletions
diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl
index c34f0dedad2d..52f558efdb0a 100755
--- a/tools/testing/ktest/ktest.pl
+++ b/tools/testing/ktest/ktest.pl
@@ -2784,12 +2784,17 @@ my %dependency;
2784sub assign_configs { 2784sub assign_configs {
2785 my ($hash, $config) = @_; 2785 my ($hash, $config) = @_;
2786 2786
2787 doprint "Reading configs from $config\n";
2788
2787 open (IN, $config) 2789 open (IN, $config)
2788 or dodie "Failed to read $config"; 2790 or dodie "Failed to read $config";
2789 2791
2790 while (<IN>) { 2792 while (<IN>) {
2793 chomp;
2791 if (/^((CONFIG\S*)=.*)/) { 2794 if (/^((CONFIG\S*)=.*)/) {
2792 ${$hash}{$2} = $1; 2795 ${$hash}{$2} = $1;
2796 } elsif (/^(# (CONFIG\S*) is not set)/) {
2797 ${$hash}{$2} = $1;
2793 } 2798 }
2794 } 2799 }
2795 2800
@@ -2841,53 +2846,97 @@ sub get_dependencies {
2841 return @deps; 2846 return @deps;
2842} 2847}
2843 2848
2849sub save_config {
2850 my ($pc, $file) = @_;
2851
2852 my %configs = %{$pc};
2853
2854 doprint "Saving configs into $file\n";
2855
2856 open(OUT, ">$file") or dodie "Can not write to $file";
2857
2858 foreach my $config (keys %configs) {
2859 print OUT "$configs{$config}\n";
2860 }
2861 close(OUT);
2862}
2863
2844sub create_config { 2864sub create_config {
2845 my @configs = @_; 2865 my ($name, $pc) = @_;
2846 2866
2847 open(OUT, ">$output_config") or dodie "Can not write to $output_config"; 2867 doprint "Creating old config from $name configs\n";
2848 2868
2849 foreach my $config (@configs) { 2869 save_config $pc, $output_config;
2850 print OUT "$config_set{$config}\n"; 2870
2851 my @deps = get_dependencies $config; 2871 make_oldconfig;
2852 foreach my $dep (@deps) { 2872}
2853 print OUT "$config_set{$dep}\n"; 2873
2874# compare two config hashes, and return configs with different vals.
2875# It returns B's config values, but you can use A to see what A was.
2876sub diff_config_vals {
2877 my ($pa, $pb) = @_;
2878
2879 # crappy Perl way to pass in hashes.
2880 my %a = %{$pa};
2881 my %b = %{$pb};
2882
2883 my %ret;
2884
2885 foreach my $item (keys %a) {
2886 if (defined($b{$item}) && $b{$item} ne $a{$item}) {
2887 $ret{$item} = $b{$item};
2854 } 2888 }
2855 } 2889 }
2856 2890
2857 # turn off configs to keep off 2891 return %ret;
2858 foreach my $config (keys %config_off) { 2892}
2859 print OUT "# $config is not set\n";
2860 }
2861 2893
2862 # turn off configs that should be off for now 2894# compare two config hashes and return the configs in B but not A
2863 foreach my $config (@config_off_tmp) { 2895sub diff_configs {
2864 print OUT "# $config is not set\n"; 2896 my ($pa, $pb) = @_;
2865 } 2897
2898 my %ret;
2899
2900 # crappy Perl way to pass in hashes.
2901 my %a = %{$pa};
2902 my %b = %{$pb};
2866 2903
2867 foreach my $config (keys %config_ignore) { 2904 foreach my $item (keys %b) {
2868 print OUT "$config_ignore{$config}\n"; 2905 if (!defined($a{$item})) {
2906 $ret{$item} = $b{$item};
2907 }
2869 } 2908 }
2870 close(OUT);
2871 2909
2872 make_oldconfig; 2910 return %ret;
2873} 2911}
2874 2912
2913# return if two configs are equal or not
2914# 0 is equal +1 b has something a does not
2915# +1 if a and b have a different item.
2916# -1 if a has something b does not
2875sub compare_configs { 2917sub compare_configs {
2876 my (%a, %b) = @_; 2918 my ($pa, $pb) = @_;
2877 2919
2878 foreach my $item (keys %a) { 2920 my %ret;
2879 if (!defined($b{$item})) { 2921
2880 print "diff $item\n"; 2922 # crappy Perl way to pass in hashes.
2923 my %a = %{$pa};
2924 my %b = %{$pb};
2925
2926 foreach my $item (keys %b) {
2927 if (!defined($a{$item})) {
2928 return 1;
2929 }
2930 if ($a{$item} ne $b{$item}) {
2881 return 1; 2931 return 1;
2882 } 2932 }
2883 delete $b{$item};
2884 } 2933 }
2885 2934
2886 my @keys = keys %b; 2935 foreach my $item (keys %a) {
2887 if ($#keys) { 2936 if (!defined($b{$item})) {
2888 print "diff2 $keys[0]\n"; 2937 return -1;
2938 }
2889 } 2939 }
2890 return -1 if ($#keys >= 0);
2891 2940
2892 return 0; 2941 return 0;
2893} 2942}
@@ -2923,253 +2972,204 @@ sub process_failed {
2923 doprint "***************************************\n\n"; 2972 doprint "***************************************\n\n";
2924} 2973}
2925 2974
2926sub run_config_bisect { 2975# used for config bisecting
2976my $good_config;
2977my $bad_config;
2927 2978
2928 my @start_list = keys %config_list; 2979sub process_new_config {
2980 my ($tc, $nc, $gc, $bc) = @_;
2929 2981
2930 if ($#start_list < 0) { 2982 my %tmp_config = %{$tc};
2931 doprint "No more configs to test!!!\n"; 2983 my %good_configs = %{$gc};
2932 return -1; 2984 my %bad_configs = %{$bc};
2933 }
2934 2985
2935 doprint "***** RUN TEST ***\n"; 2986 my %new_configs;
2936 my $type = $config_bisect_type;
2937 my $ret;
2938 my %current_config;
2939 2987
2940 my $count = $#start_list + 1; 2988 my $runtest = 1;
2941 doprint " $count configs to test\n"; 2989 my $ret;
2942 2990
2943 my $half = int($#start_list / 2); 2991 create_config "tmp_configs", \%tmp_config;
2992 assign_configs \%new_configs, $output_config;
2944 2993
2945 do { 2994 $ret = compare_configs \%new_configs, \%bad_configs;
2946 my @tophalf = @start_list[0 .. $half]; 2995 if (!$ret) {
2996 doprint "New config equals bad config, try next test\n";
2997 $runtest = 0;
2998 }
2947 2999
2948 # keep the bottom half off 3000 if ($runtest) {
2949 if ($half < $#start_list) { 3001 $ret = compare_configs \%new_configs, \%good_configs;
2950 @config_off_tmp = @start_list[$half + 1 .. $#start_list]; 3002 if (!$ret) {
2951 } else { 3003 doprint "New config equals good config, try next test\n";
2952 @config_off_tmp = (); 3004 $runtest = 0;
2953 } 3005 }
3006 }
2954 3007
2955 create_config @tophalf; 3008 %{$nc} = %new_configs;
2956 read_current_config \%current_config;
2957
2958 $count = $#tophalf + 1;
2959 doprint "Testing $count configs\n";
2960 my $found = 0;
2961 # make sure we test something
2962 foreach my $config (@tophalf) {
2963 if (defined($current_config{$config})) {
2964 logit " $config\n";
2965 $found = 1;
2966 }
2967 }
2968 if (!$found) {
2969 # try the other half
2970 doprint "Top half produced no set configs, trying bottom half\n";
2971
2972 # keep the top half off
2973 @config_off_tmp = @tophalf;
2974 @tophalf = @start_list[$half + 1 .. $#start_list];
2975
2976 create_config @tophalf;
2977 read_current_config \%current_config;
2978 foreach my $config (@tophalf) {
2979 if (defined($current_config{$config})) {
2980 logit " $config\n";
2981 $found = 1;
2982 }
2983 }
2984 if (!$found) {
2985 doprint "Failed: Can't make new config with current configs\n";
2986 foreach my $config (@start_list) {
2987 doprint " CONFIG: $config\n";
2988 }
2989 return -1;
2990 }
2991 $count = $#tophalf + 1;
2992 doprint "Testing $count configs\n";
2993 }
2994 3009
2995 $ret = run_config_bisect_test $type; 3010 return $runtest;
2996 if ($bisect_manual) { 3011}
2997 $ret = answer_bisect;
2998 }
2999 if ($ret) {
3000 process_passed %current_config;
3001 return 0;
3002 }
3003 3012
3004 doprint "This config had a failure.\n"; 3013sub run_config_bisect {
3005 doprint "Removing these configs that were not set in this config:\n"; 3014 my ($pgood, $pbad) = @_;
3006 doprint "config copied to $outputdir/config_bad\n";
3007 run_command "cp -f $output_config $outputdir/config_bad";
3008 3015
3009 # A config exists in this group that was bad. 3016 my $type = $config_bisect_type;
3010 foreach my $config (keys %config_list) {
3011 if (!defined($current_config{$config})) {
3012 doprint " removing $config\n";
3013 delete $config_list{$config};
3014 }
3015 }
3016 3017
3017 @start_list = @tophalf; 3018 my %good_configs = %{$pgood};
3019 my %bad_configs = %{$pbad};
3018 3020
3019 if ($#start_list == 0) { 3021 my %diff_configs = diff_config_vals \%good_configs, \%bad_configs;
3020 process_failed $start_list[0]; 3022 my %b_configs = diff_configs \%good_configs, \%bad_configs;
3021 return 1; 3023 my %g_configs = diff_configs \%bad_configs, \%good_configs;
3022 }
3023 3024
3024 # remove half the configs we are looking at and see if 3025 my @diff_arr = keys %diff_configs;
3025 # they are good. 3026 my $len_diff = $#diff_arr + 1;
3026 $half = int($#start_list / 2);
3027 } while ($#start_list > 0);
3028 3027
3029 # we found a single config, try it again unless we are running manually 3028 my @b_arr = keys %b_configs;
3029 my $len_b = $#b_arr + 1;
3030 3030
3031 if ($bisect_manual) { 3031 my @g_arr = keys %g_configs;
3032 process_failed $start_list[0]; 3032 my $len_g = $#g_arr + 1;
3033 return 1;
3034 }
3035 3033
3036 my @tophalf = @start_list[0 .. 0]; 3034 my $runtest = 1;
3035 my %new_configs;
3036 my $ret;
3037 3037
3038 $ret = run_config_bisect_test $type; 3038 # First, lets get it down to a single subset.
3039 if ($ret) { 3039 # Is the problem with a difference in values?
3040 process_passed %current_config; 3040 # Is the problem with a missing config?
3041 return 0; 3041 # Is the problem with a config that breaks things?
3042 }
3043 3042
3044 process_failed $start_list[0]; 3043 # Enable all of one set and see if we get a new bad
3045 return 1; 3044 # or good config.
3046}
3047 3045
3048sub config_bisect { 3046 # first set the good config to the bad values.
3049 my ($i) = @_;
3050 3047
3051 my $start_config = $config_bisect; 3048 doprint "d=$len_diff g=$len_g b=$len_b\n";
3052 3049
3053 my $tmpconfig = "$tmpdir/use_config"; 3050 # first lets enable things in bad config that are enabled in good config
3054 3051
3055 if (defined($config_bisect_good)) { 3052 if ($len_diff > 0) {
3056 process_config_ignore $config_bisect_good; 3053 if ($len_b > 0 || $len_g > 0) {
3057 } 3054 my %tmp_config = %bad_configs;
3058 3055
3059 # Make the file with the bad config and the min config 3056 doprint "Set tmp config to be bad config with good config values\n";
3060 if (defined($minconfig)) { 3057 foreach my $item (@diff_arr) {
3061 # read the min config for things to ignore 3058 $tmp_config{$item} = $good_configs{$item};
3062 run_command "cp $minconfig $tmpconfig" or 3059 }
3063 dodie "failed to copy $minconfig to $tmpconfig";
3064 } else {
3065 unlink $tmpconfig;
3066 }
3067 3060
3068 if (-f $tmpconfig) { 3061 $runtest = process_new_config \%tmp_config, \%new_configs,
3069 load_force_config($tmpconfig); 3062 \%good_configs, \%bad_configs;
3070 process_config_ignore $tmpconfig; 3063 }
3071 } 3064 }
3072 3065
3073 # now process the start config 3066 if (!$runtest && $len_diff > 0) {
3074 run_command "cp $start_config $output_config" or
3075 dodie "failed to copy $start_config to $output_config";
3076 3067
3077 # read directly what we want to check 3068 if ($len_diff == 1) {
3078 my %config_check; 3069 doprint "The bad config setting is: $diff_arr[0]\n";
3079 open (IN, $output_config) 3070 return 1;
3080 or dodie "failed to open $output_config"; 3071 }
3072 my %tmp_config = %bad_configs;
3081 3073
3082 while (<IN>) { 3074 my $half = int($#diff_arr / 2);
3083 if (/^((CONFIG\S*)=.*)/) { 3075 my @tophalf = @diff_arr[0 .. $half];
3084 $config_check{$2} = $1; 3076
3077 doprint "Settings bisect with top half:\n";
3078 doprint "Set tmp config to be bad config with some good config values\n";
3079 foreach my $item (@tophalf) {
3080 $tmp_config{$item} = $good_configs{$item};
3085 } 3081 }
3086 }
3087 close(IN);
3088 3082
3089 # Now run oldconfig with the minconfig 3083 $runtest = process_new_config \%tmp_config, \%new_configs,
3090 make_oldconfig; 3084 \%good_configs, \%bad_configs;
3091 3085
3092 # check to see what we lost (or gained) 3086 if (!$runtest) {
3093 open (IN, $output_config) 3087 my %tmp_config = %bad_configs;
3094 or dodie "Failed to read $start_config";
3095 3088
3096 my %removed_configs; 3089 doprint "Try bottom half\n";
3097 my %added_configs;
3098 3090
3099 while (<IN>) { 3091 my @bottomhalf = @diff_arr[$half+1 .. $#diff_arr];
3100 if (/^((CONFIG\S*)=.*)/) { 3092
3101 # save off all options 3093 foreach my $item (@bottomhalf) {
3102 $config_set{$2} = $1; 3094 $tmp_config{$item} = $good_configs{$item};
3103 if (defined($config_check{$2})) {
3104 if (defined($config_ignore{$2})) {
3105 $removed_configs{$2} = $1;
3106 } else {
3107 $config_list{$2} = $1;
3108 }
3109 } elsif (!defined($config_ignore{$2})) {
3110 $added_configs{$2} = $1;
3111 $config_list{$2} = $1;
3112 } 3095 }
3113 } elsif (/^# ((CONFIG\S*).*)/) {
3114 # Keep these configs disabled
3115 $config_set{$2} = $1;
3116 $config_off{$2} = $1;
3117 }
3118 }
3119 close(IN);
3120 3096
3121 my @confs = keys %removed_configs; 3097 $runtest = process_new_config \%tmp_config, \%new_configs,
3122 if ($#confs >= 0) { 3098 \%good_configs, \%bad_configs;
3123 doprint "Configs overridden by default configs and removed from check:\n";
3124 foreach my $config (@confs) {
3125 doprint " $config\n";
3126 } 3099 }
3127 } 3100 }
3128 @confs = keys %added_configs; 3101
3129 if ($#confs >= 0) { 3102 if ($runtest) {
3130 doprint "Configs appearing in make oldconfig and added:\n"; 3103 $ret = run_config_bisect_test $type;
3131 foreach my $config (@confs) { 3104 if ($ret) {
3132 doprint " $config\n"; 3105 doprint "NEW GOOD CONFIG\n";
3106 %good_configs = %new_configs;
3107 run_command "mv $good_config ${good_config}.last";
3108 save_config \%good_configs, $good_config;
3109 %{$pgood} = %good_configs;
3110 } else {
3111 doprint "NEW BAD CONFIG\n";
3112 %bad_configs = %new_configs;
3113 run_command "mv $bad_config ${bad_config}.last";
3114 save_config \%bad_configs, $bad_config;
3115 %{$pbad} = %bad_configs;
3133 } 3116 }
3117 return 0;
3134 } 3118 }
3135 3119
3136 my %config_test; 3120 fail "Hmm, need to do a mix match?\n";
3137 my $once = 0; 3121 return -1;
3122}
3138 3123
3139 @config_off_tmp = (); 3124sub config_bisect {
3125 my ($i) = @_;
3140 3126
3141 # Sometimes kconfig does weird things. We must make sure 3127 my $type = $config_bisect_type;
3142 # that the config we autocreate has everything we need
3143 # to test, otherwise we may miss testing configs, or
3144 # may not be able to create a new config.
3145 # Here we create a config with everything set.
3146 create_config (keys %config_list);
3147 read_current_config \%config_test;
3148 foreach my $config (keys %config_list) {
3149 if (!defined($config_test{$config})) {
3150 if (!$once) {
3151 $once = 1;
3152 doprint "Configs not produced by kconfig (will not be checked):\n";
3153 }
3154 doprint " $config\n";
3155 delete $config_list{$config};
3156 }
3157 }
3158 my $ret;
3159 3128
3160 if (defined($config_bisect_check) && $config_bisect_check) { 3129 $bad_config = $config_bisect;
3161 doprint " Checking to make sure bad config with min config fails\n"; 3130
3162 create_config keys %config_list; 3131 if (defined($config_bisect_good)) {
3163 $ret = run_config_bisect_test $config_bisect_type; 3132 $good_config = $config_bisect_good;
3164 if ($ret) { 3133 } elsif (defined($minconfig)) {
3165 doprint " FAILED! Bad config with min config boots fine\n"; 3134 $good_config = $minconfig;
3166 return -1; 3135 } else {
3136 doprint "No config specified, checking if defconfig works";
3137 my $ret = run_bisect_test $type, "defconfig";
3138 if (!$ret) {
3139 fail "Have no good config to compare with, please set CONFIG_BISECT_GOOD";
3140 return 1;
3167 } 3141 }
3168 doprint " Bad config with min config fails as expected\n"; 3142 $good_config = $output_config;
3169 } 3143 }
3170 3144
3145 # we don't want min configs to cause issues here.
3146 doprint "Disabling 'MIN_CONFIG' for this test\n";
3147 undef $minconfig;
3148
3149 my %good_configs;
3150 my %bad_configs;
3151 my %tmp_configs;
3152
3153 doprint "Run good configs through make oldconfig\n";
3154 assign_configs \%tmp_configs, $good_config;
3155 create_config "$good_config", \%tmp_configs;
3156 assign_configs \%good_configs, $output_config;
3157
3158 doprint "Run bad configs through make oldconfig\n";
3159 assign_configs \%tmp_configs, $bad_config;
3160 create_config "$bad_config", \%tmp_configs;
3161 assign_configs \%bad_configs, $output_config;
3162
3163 $good_config = "$tmpdir/good_config";
3164 $bad_config = "$tmpdir/bad_config";
3165
3166 save_config \%good_configs, $good_config;
3167 save_config \%bad_configs, $bad_config;
3168
3169 my $ret;
3170
3171 do { 3171 do {
3172 $ret = run_config_bisect; 3172 $ret = run_config_bisect \%good_configs, \%bad_configs;
3173 } while (!$ret); 3173 } while (!$ret);
3174 3174
3175 return $ret if ($ret < 0); 3175 return $ret if ($ret < 0);