aboutsummaryrefslogtreecommitdiffstats
path: root/tools/testing/ktest/ktest.pl
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2011-07-15 21:16:17 -0400
committerSteven Rostedt <rostedt@goodmis.org>2011-07-15 21:19:44 -0400
commit4c4ab1204fe4e201ece94c3062aa6b5eed670457 (patch)
tree7317f1cf06600e5cd14a849d4875e764af4b3c3e /tools/testing/ktest/ktest.pl
parent0df213ca31f43faf0b1d6c7108e190ff198b42d3 (diff)
ktest: Add test type make_min_config
After doing a make localyesconfig, your kernel configuration may not be the most useful minimum configuration. Having a true minimum config that you can use against other configs is very useful if someone else has a config that breaks on your code. By only forcing those configurations that are truly required to boot your machine will give you less of a chance that one of your set configurations will make the bug go away. This will give you a better chance to be able to reproduce the reported bug matching the broken config. Note, this does take some time, and may require you to run the test over night, or perhaps over the weekend. But it also allows you to interrupt it, and gives you the current minimum config that was found till that time. Note, this test automatically assumes a BUILD_TYPE of oldconfig and its test type acts like boot. TODO: add a test version that makes the config do more than just boot, like having network access. Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'tools/testing/ktest/ktest.pl')
-rwxr-xr-xtools/testing/ktest/ktest.pl255
1 files changed, 251 insertions, 4 deletions
diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl
index 6166f3a0f2ea..5323c6f9bf9b 100755
--- a/tools/testing/ktest/ktest.pl
+++ b/tools/testing/ktest/ktest.pl
@@ -86,6 +86,9 @@ my $make;
86my $post_install; 86my $post_install;
87my $noclean; 87my $noclean;
88my $minconfig; 88my $minconfig;
89my $start_minconfig;
90my $output_minconfig;
91my $ignore_config;
89my $addconfig; 92my $addconfig;
90my $in_bisect = 0; 93my $in_bisect = 0;
91my $bisect_bad = ""; 94my $bisect_bad = "";
@@ -1189,7 +1192,11 @@ sub apply_min_config {
1189 1192
1190sub make_oldconfig { 1193sub make_oldconfig {
1191 1194
1192 apply_min_config; 1195 my @force_list = keys %force_config;
1196
1197 if ($#force_list >= 0) {
1198 apply_min_config;
1199 }
1193 1200
1194 if (!run_command "$make oldnoconfig") { 1201 if (!run_command "$make oldnoconfig") {
1195 # Perhaps oldnoconfig doesn't exist in this version of the kernel 1202 # Perhaps oldnoconfig doesn't exist in this version of the kernel
@@ -1678,21 +1685,27 @@ my %null_config;
1678 1685
1679my %dependency; 1686my %dependency;
1680 1687
1681sub process_config_ignore { 1688sub assign_configs {
1682 my ($config) = @_; 1689 my ($hash, $config) = @_;
1683 1690
1684 open (IN, $config) 1691 open (IN, $config)
1685 or dodie "Failed to read $config"; 1692 or dodie "Failed to read $config";
1686 1693
1687 while (<IN>) { 1694 while (<IN>) {
1688 if (/^((CONFIG\S*)=.*)/) { 1695 if (/^((CONFIG\S*)=.*)/) {
1689 $config_ignore{$2} = $1; 1696 ${$hash}{$2} = $1;
1690 } 1697 }
1691 } 1698 }
1692 1699
1693 close(IN); 1700 close(IN);
1694} 1701}
1695 1702
1703sub process_config_ignore {
1704 my ($config) = @_;
1705
1706 assign_configs \%config_ignore, $config;
1707}
1708
1696sub read_current_config { 1709sub read_current_config {
1697 my ($config_ref) = @_; 1710 my ($config_ref) = @_;
1698 1711
@@ -2149,6 +2162,226 @@ sub patchcheck {
2149 return 1; 2162 return 1;
2150} 2163}
2151 2164
2165sub read_config_list {
2166 my ($config) = @_;
2167
2168 open (IN, $config)
2169 or dodie "Failed to read $config";
2170
2171 while (<IN>) {
2172 if (/^((CONFIG\S*)=.*)/) {
2173 if (!defined($config_ignore{$2})) {
2174 $config_list{$2} = $1;
2175 }
2176 }
2177 }
2178
2179 close(IN);
2180}
2181
2182sub read_output_config {
2183 my ($config) = @_;
2184
2185 assign_configs \%config_ignore, $config;
2186}
2187
2188sub make_new_config {
2189 my @configs = @_;
2190
2191 open (OUT, ">$output_config")
2192 or dodie "Failed to write $output_config";
2193
2194 foreach my $config (@configs) {
2195 print OUT "$config\n";
2196 }
2197 close OUT;
2198}
2199
2200sub make_min_config {
2201 my ($i) = @_;
2202
2203 if (!defined($output_minconfig)) {
2204 fail "OUTPUT_MIN_CONFIG not defined" and return;
2205 }
2206 if (!defined($start_minconfig)) {
2207 fail "START_MIN_CONFIG or MIN_CONFIG not defined" and return;
2208 }
2209
2210 # First things first. We build an allnoconfig to find
2211 # out what the defaults are that we can't touch.
2212 # Some are selections, but we really can't handle selections.
2213
2214 my $save_minconfig = $minconfig;
2215 undef $minconfig;
2216
2217 run_command "$make allnoconfig" or return 0;
2218
2219 process_config_ignore $output_config;
2220 my %keep_configs;
2221
2222 if (defined($ignore_config)) {
2223 # make sure the file exists
2224 `touch $ignore_config`;
2225 assign_configs \%keep_configs, $ignore_config;
2226 }
2227
2228 doprint "Load initial configs from $start_minconfig\n";
2229
2230 # Look at the current min configs, and save off all the
2231 # ones that were set via the allnoconfig
2232 my %min_configs;
2233 assign_configs \%min_configs, $start_minconfig;
2234
2235 my @config_keys = keys %min_configs;
2236
2237 # Remove anything that was set by the make allnoconfig
2238 # we shouldn't need them as they get set for us anyway.
2239 foreach my $config (@config_keys) {
2240 # Remove anything in the ignore_config
2241 if (defined($keep_configs{$config})) {
2242 my $file = $ignore_config;
2243 $file =~ s,.*/(.*?)$,$1,;
2244 doprint "$config set by $file ... ignored\n";
2245 delete $min_configs{$config};
2246 next;
2247 }
2248 # But make sure the settings are the same. If a min config
2249 # sets a selection, we do not want to get rid of it if
2250 # it is not the same as what we have. Just move it into
2251 # the keep configs.
2252 if (defined($config_ignore{$config})) {
2253 if ($config_ignore{$config} ne $min_configs{$config}) {
2254 doprint "$config is in allnoconfig as '$config_ignore{$config}'";
2255 doprint " but it is '$min_configs{$config}' in minconfig .. keeping\n";
2256 $keep_configs{$config} = $min_configs{$config};
2257 } else {
2258 doprint "$config set by allnoconfig ... ignored\n";
2259 }
2260 delete $min_configs{$config};
2261 }
2262 }
2263
2264 my %nochange_config;
2265
2266 my $done = 0;
2267
2268 while (!$done) {
2269
2270 my $config;
2271 my $found;
2272
2273 # Now disable each config one by one and do a make oldconfig
2274 # till we find a config that changes our list.
2275
2276 # Put configs that did not modify the config at the end.
2277 my @test_configs = keys %min_configs;
2278 my $reset = 1;
2279 for (my $i = 0; $i < $#test_configs; $i++) {
2280 if (!defined($nochange_config{$test_configs[0]})) {
2281 $reset = 0;
2282 last;
2283 }
2284 # This config didn't change the .config last time.
2285 # Place it at the end
2286 my $config = shift @test_configs;
2287 push @test_configs, $config;
2288 }
2289
2290 # if every test config has failed to modify the .config file
2291 # in the past, then reset and start over.
2292 if ($reset) {
2293 undef %nochange_config;
2294 }
2295
2296 foreach my $config (@test_configs) {
2297
2298 # Remove this config from the list of configs
2299 # do a make oldnoconfig and then read the resulting
2300 # .config to make sure it is missing the config that
2301 # we had before
2302 my %configs = %min_configs;
2303 delete $configs{$config};
2304 make_new_config ((values %configs), (values %keep_configs));
2305 make_oldconfig;
2306 undef %configs;
2307 assign_configs \%configs, $output_config;
2308
2309 if (!defined($configs{$config})) {
2310 $found = $config;
2311 last;
2312 }
2313
2314 doprint "disabling config $config did not change .config\n";
2315
2316 # oh well, try another config
2317 $nochange_config{$config} = 1;
2318 }
2319
2320 if (!defined($found)) {
2321 doprint "No more configs found that we can disable\n";
2322 $done = 1;
2323 last;
2324 }
2325
2326 $config = $found;
2327
2328 doprint "Test with $config disabled\n";
2329
2330 # set in_bisect to keep build and monitor from dieing
2331 $in_bisect = 1;
2332
2333 my $failed = 0;
2334 build "oldconfig";
2335 start_monitor_and_boot or $failed = 1;
2336 end_monitor;
2337
2338 $in_bisect = 0;
2339
2340 if ($failed) {
2341 doprint "$config is needed to boot the box... keeping\n";
2342 # this config is needed, add it to the ignore list.
2343 $keep_configs{$config} = $min_configs{$config};
2344 delete $min_configs{$config};
2345 } else {
2346 # We booted without this config, remove it from the minconfigs.
2347 doprint "$config is not needed, disabling\n";
2348
2349 delete $min_configs{$config};
2350
2351 # Also disable anything that is not enabled in this config
2352 my %configs;
2353 assign_configs \%configs, $output_config;
2354 my @config_keys = keys %min_configs;
2355 foreach my $config (@config_keys) {
2356 if (!defined($configs{$config})) {
2357 doprint "$config is not set, disabling\n";
2358 delete $min_configs{$config};
2359 }
2360 }
2361
2362 # Save off all the current mandidory configs
2363 open (OUT, ">$output_minconfig")
2364 or die "Can't write to $output_minconfig";
2365 foreach my $config (keys %keep_configs) {
2366 print OUT "$keep_configs{$config}\n";
2367 }
2368 foreach my $config (keys %min_configs) {
2369 print OUT "$min_configs{$config}\n";
2370 }
2371 close OUT;
2372 }
2373
2374 doprint "Reboot and wait $sleep_time seconds\n";
2375 reboot;
2376 start_monitor;
2377 wait_for_monitor $sleep_time;
2378 end_monitor;
2379 }
2380
2381 success $i;
2382 return 1;
2383}
2384
2152$#ARGV < 1 or die "ktest.pl version: $VERSION\n usage: ktest.pl config-file\n"; 2385$#ARGV < 1 or die "ktest.pl version: $VERSION\n usage: ktest.pl config-file\n";
2153 2386
2154if ($#ARGV == 0) { 2387if ($#ARGV == 0) {
@@ -2294,6 +2527,9 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
2294 $reboot = set_test_option("REBOOT", $i); 2527 $reboot = set_test_option("REBOOT", $i);
2295 $noclean = set_test_option("BUILD_NOCLEAN", $i); 2528 $noclean = set_test_option("BUILD_NOCLEAN", $i);
2296 $minconfig = set_test_option("MIN_CONFIG", $i); 2529 $minconfig = set_test_option("MIN_CONFIG", $i);
2530 $output_minconfig = set_test_option("OUTPUT_MIN_CONFIG", $i);
2531 $start_minconfig = set_test_option("START_MIN_CONFIG", $i);
2532 $ignore_config = set_test_option("IGNORE_CONFIG", $i);
2297 $run_test = set_test_option("TEST", $i); 2533 $run_test = set_test_option("TEST", $i);
2298 $addconfig = set_test_option("ADD_CONFIG", $i); 2534 $addconfig = set_test_option("ADD_CONFIG", $i);
2299 $reboot_type = set_test_option("REBOOT_TYPE", $i); 2535 $reboot_type = set_test_option("REBOOT_TYPE", $i);
@@ -2329,6 +2565,10 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
2329 $target_image = set_test_option("TARGET_IMAGE", $i); 2565 $target_image = set_test_option("TARGET_IMAGE", $i);
2330 $localversion = set_test_option("LOCALVERSION", $i); 2566 $localversion = set_test_option("LOCALVERSION", $i);
2331 2567
2568 if (!defined($start_minconfig)) {
2569 $start_minconfig = $minconfig;
2570 }
2571
2332 chdir $builddir || die "can't change directory to $builddir"; 2572 chdir $builddir || die "can't change directory to $builddir";
2333 2573
2334 if (!-d $tmpdir) { 2574 if (!-d $tmpdir) {
@@ -2361,6 +2601,10 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
2361 $run_type = $opt{"CONFIG_BISECT_TYPE[$i]"}; 2601 $run_type = $opt{"CONFIG_BISECT_TYPE[$i]"};
2362 } 2602 }
2363 2603
2604 if ($test_type eq "make_min_config") {
2605 $run_type = "";
2606 }
2607
2364 # mistake in config file? 2608 # mistake in config file?
2365 if (!defined($run_type)) { 2609 if (!defined($run_type)) {
2366 $run_type = "ERROR"; 2610 $run_type = "ERROR";
@@ -2396,6 +2640,9 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
2396 } elsif ($test_type eq "patchcheck") { 2640 } elsif ($test_type eq "patchcheck") {
2397 patchcheck $i; 2641 patchcheck $i;
2398 next; 2642 next;
2643 } elsif ($test_type eq "make_min_config") {
2644 make_min_config $i;
2645 next;
2399 } 2646 }
2400 2647
2401 if ($build_type ne "nobuild") { 2648 if ($build_type ne "nobuild") {