]> Pileus Git - ~andy/linux/blobdiff - tools/testing/ktest/ktest.pl
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt...
[~andy/linux] / tools / testing / ktest / ktest.pl
index ba7c63af6f3b2bc8a53a91de50ff9ad669468fb8..8ce792ea08e9f782d3e661dbbb99798839a08ed4 100755 (executable)
@@ -37,6 +37,8 @@ $default{"POWEROFF_ON_SUCCESS"}       = 0;
 $default{"BUILD_OPTIONS"}      = "";
 $default{"BISECT_SLEEP_TIME"}  = 60;   # sleep time between bisects
 $default{"CLEAR_LOG"}          = 0;
+$default{"BISECT_MANUAL"}      = 0;
+$default{"BISECT_SKIP"}                = 1;
 $default{"SUCCESS_LINE"}       = "login:";
 $default{"BOOTED_TIMEOUT"}     = 1;
 $default{"DIE_ON_FAILURE"}     = 1;
@@ -45,6 +47,7 @@ $default{"SCP_TO_TARGET"}     = "scp \$SRC_FILE \$SSH_USER\@\$MACHINE:\$DST_FILE";
 $default{"REBOOT"}             = "ssh \$SSH_USER\@\$MACHINE reboot";
 $default{"STOP_AFTER_SUCCESS"} = 10;
 $default{"STOP_AFTER_FAILURE"} = 60;
+$default{"STOP_TEST_AFTER"}    = 600;
 $default{"LOCALVERSION"}       = "-test";
 
 my $ktest_config;
@@ -81,6 +84,8 @@ my $addconfig;
 my $in_bisect = 0;
 my $bisect_bad = "";
 my $reverse_bisect;
+my $bisect_manual;
+my $bisect_skip;
 my $in_patchcheck = 0;
 my $run_test;
 my $redirect;
@@ -98,6 +103,7 @@ my $console;
 my $success_line;
 my $stop_after_success;
 my $stop_after_failure;
+my $stop_test_after;
 my $build_target;
 my $target_image;
 my $localversion;
@@ -462,6 +468,10 @@ sub dodie {
        `$power_off`;
     }
 
+    if (defined($opt{"LOG_FILE"})) {
+       print " See $opt{LOG_FILE} for more info.\n";
+    }
+
     die @_, "\n";
 }
 
@@ -760,8 +770,10 @@ sub monitor {
 
     my $success_start;
     my $failure_start;
+    my $monitor_start = time;
+    my $done = 0;
 
-    for (;;) {
+    while (!$done) {
 
        if ($booted) {
            $line = wait_for_input($monitor_fp, $booted_timeout);
@@ -796,7 +808,7 @@ sub monitor {
        }
 
        if ($full_line =~ /call trace:/i) {
-           if (!$skip_call_trace) {
+           if (!$bug && !$skip_call_trace) {
                $bug = 1;
                $failure_start = time;
            }
@@ -816,12 +828,19 @@ sub monitor {
        }
 
        if ($full_line =~ /Kernel panic -/) {
+           $failure_start = time;
            $bug = 1;
        }
 
        if ($line =~ /\n/) {
            $full_line = "";
        }
+
+       if ($stop_test_after > 0 && !$booted && !$bug) {
+           if (time - $monitor_start > $stop_test_after) {
+               $done = 1;
+           }
+       }
     }
 
     close(DMESG);
@@ -925,6 +944,18 @@ sub check_buildlog {
     return 1;
 }
 
+sub make_oldconfig {
+    my ($defconfig) = @_;
+
+    if (!run_command "$defconfig $make oldnoconfig") {
+       # Perhaps oldnoconfig doesn't exist in this version of the kernel
+       # try a yes '' | oldconfig
+       doprint "oldnoconfig failed, trying yes '' | make oldconfig\n";
+       run_command "yes '' | $defconfig $make oldconfig" or
+           dodie "failed make config oldconfig";
+    }
+}
+
 sub build {
     my ($type) = @_;
     my $defconfig = "";
@@ -970,8 +1001,12 @@ sub build {
        $defconfig = "KCONFIG_ALLCONFIG=$minconfig";
     }
 
-    run_command "$defconfig $make $type" or
-       dodie "failed make config";
+    if ($type eq "oldnoconfig") {
+       make_oldconfig $defconfig;
+    } else {
+       run_command "$defconfig $make $type" or
+           dodie "failed make config";
+    }
 
     $redirect = "$buildlog";
     if (!run_command "$make $build_options") {
@@ -1025,6 +1060,21 @@ sub get_version {
     doprint "$version\n";
 }
 
+sub answer_bisect {
+    for (;;) {
+       doprint "Pass or fail? [p/f]";
+       my $ans = <STDIN>;
+       chomp $ans;
+       if ($ans eq "p" || $ans eq "P") {
+           return 1;
+       } elsif ($ans eq "f" || $ans eq "F") {
+           return 0;
+       } else {
+           print "Please answer 'P' or 'F'\n";
+       }
+    }
+}
+
 sub child_run_test {
     my $failed = 0;
 
@@ -1070,6 +1120,7 @@ sub do_run_test {
 
            # we are not guaranteed to get a full line
            $full_line .= $line;
+           doprint $line;
 
            if ($full_line =~ /call trace:/i) {
                $bug = 1;
@@ -1086,6 +1137,19 @@ sub do_run_test {
     } while (!$child_done && !$bug);
 
     if ($bug) {
+       my $failure_start = time;
+       my $now;
+       do {
+           $line = wait_for_input($monitor_fp, 1);
+           if (defined($line)) {
+               doprint $line;
+           }
+           $now = time;
+           if ($now - $failure_start >= $stop_after_failure) {
+               last;
+           }
+       } while (defined($line));
+
        doprint "Detected kernel crash!\n";
        # kill the child with extreme prejudice
        kill 9, $child_pid;
@@ -1131,7 +1195,15 @@ sub run_git_bisect {
     return 1;
 }
 
-# returns 1 on success, 0 on failure
+sub bisect_reboot {
+    doprint "Reboot and sleep $bisect_sleep_time seconds\n";
+    reboot;
+    start_monitor;
+    wait_for_monitor $bisect_sleep_time;
+    end_monitor;
+}
+
+# returns 1 on success, 0 on failure, -1 on skip
 sub run_bisect_test {
     my ($type, $buildtype) = @_;
 
@@ -1145,6 +1217,10 @@ sub run_bisect_test {
     build $buildtype or $failed = 1;
 
     if ($type ne "build") {
+       if ($failed && $bisect_skip) {
+           $in_bisect = 0;
+           return -1;
+       }
        dodie "Failed on build" if $failed;
 
        # Now boot the box
@@ -1156,6 +1232,12 @@ sub run_bisect_test {
        monitor or $failed = 1;
 
        if ($type ne "boot") {
+           if ($failed && $bisect_skip) {
+               end_monitor;
+               bisect_reboot;
+               $in_bisect = 0;
+               return -1;
+           }
            dodie "Failed on boot" if $failed;
 
            do_run_test or $failed = 1;
@@ -1168,11 +1250,7 @@ sub run_bisect_test {
 
        # reboot the box to a good kernel
        if ($type ne "build") {
-           doprint "Reboot and sleep $bisect_sleep_time seconds\n";
-           reboot;
-           start_monitor;
-           wait_for_monitor $bisect_sleep_time;
-           end_monitor;
+           bisect_reboot;
        }
     } else {
        $result = 1;
@@ -1193,16 +1271,22 @@ sub run_bisect {
 
     my $ret = run_bisect_test $type, $buildtype;
 
+    if ($bisect_manual) {
+       $ret = answer_bisect;
+    }
 
     # Are we looking for where it worked, not failed?
     if ($reverse_bisect) {
        $ret = !$ret;
     }
 
-    if ($ret) {
+    if ($ret > 0) {
        return "good";
-    } else {
+    } elsif ($ret == 0) {
        return  "bad";
+    } elsif ($bisect_skip) {
+       doprint "HIT A BAD COMMIT ... SKIPPING\n";
+       return "skip";
     }
 }
 
@@ -1220,6 +1304,13 @@ sub bisect {
     my $type = $opt{"BISECT_TYPE[$i]"};
     my $start = $opt{"BISECT_START[$i]"};
     my $replay = $opt{"BISECT_REPLAY[$i]"};
+    my $start_files = $opt{"BISECT_FILES[$i]"};
+
+    if (defined($start_files)) {
+       $start_files = " -- " . $start_files;
+    } else {
+       $start_files = "";
+    }
 
     # convert to true sha1's
     $good = get_sha1($good);
@@ -1273,7 +1364,7 @@ sub bisect {
            die "Failed to checkout $head";
     }
 
-    run_command "git bisect start" or
+    run_command "git bisect start$start_files" or
        dodie "could not start bisect";
 
     run_command "git bisect good $good" or
@@ -1390,9 +1481,7 @@ sub create_config {
     close(OUT);
 
 #    exit;
-    run_command "$make oldnoconfig" or
-       dodie "failed make config oldconfig";
-
+    make_oldconfig "";
 }
 
 sub compare_configs {
@@ -1505,7 +1594,9 @@ sub run_config_bisect {
        }
 
        $ret = run_config_bisect_test $type;
-
+       if ($bisect_manual) {
+           $ret = answer_bisect;
+       }
        if ($ret) {
            process_passed %current_config;
            return 0;
@@ -1536,7 +1627,13 @@ sub run_config_bisect {
        $half = int($#start_list / 2);
     } while ($half > 0);
 
-    # we found a single config, try it again
+    # we found a single config, try it again unless we are running manually
+
+    if ($bisect_manual) {
+       process_failed $start_list[0];
+       return 1;
+    }
+
     my @tophalf = @start_list[0 .. 0];
 
     $ret = run_config_bisect_test $type;
@@ -1594,8 +1691,7 @@ sub config_bisect {
     close(IN);
 
     # Now run oldconfig with the minconfig (and addconfigs)
-    run_command "$defconfig $make oldnoconfig" or
-       dodie "failed make config oldconfig";
+    make_oldconfig $defconfig;
 
     # check to see what we lost (or gained)
     open (IN, $output_config)
@@ -1907,6 +2003,8 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
     $poweroff_after_halt = set_test_option("POWEROFF_AFTER_HALT", $i);
     $sleep_time = set_test_option("SLEEP_TIME", $i);
     $bisect_sleep_time = set_test_option("BISECT_SLEEP_TIME", $i);
+    $bisect_manual = set_test_option("BISECT_MANUAL", $i);
+    $bisect_skip = set_test_option("BISECT_SKIP", $i);
     $store_failures = set_test_option("STORE_FAILURES", $i);
     $timeout = set_test_option("TIMEOUT", $i);
     $booted_timeout = set_test_option("BOOTED_TIMEOUT", $i);
@@ -1914,6 +2012,7 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
     $success_line = set_test_option("SUCCESS_LINE", $i);
     $stop_after_success = set_test_option("STOP_AFTER_SUCCESS", $i);
     $stop_after_failure = set_test_option("STOP_AFTER_FAILURE", $i);
+    $stop_test_after = set_test_option("STOP_TEST_AFTER", $i);
     $build_target = set_test_option("BUILD_TARGET", $i);
     $ssh_exec = set_test_option("SSH_EXEC", $i);
     $scp_to_target = set_test_option("SCP_TO_TARGET", $i);