12545eb61SSteven Rostedt#!/usr/bin/perl -w 2d6ce2a0bSSteven Rostedt# 3d6ce2a0bSSteven Rostedt# Copywrite 2010 - Steven Rostedt <srostedt@redhat.com>, Red Hat Inc. 4d6ce2a0bSSteven Rostedt# Licensed under the terms of the GNU GPL License version 2 5d6ce2a0bSSteven Rostedt# 62545eb61SSteven Rostedt 72545eb61SSteven Rostedtuse strict; 82545eb61SSteven Rostedtuse IPC::Open2; 92545eb61SSteven Rostedtuse Fcntl qw(F_GETFL F_SETFL O_NONBLOCK); 107faafbd6SSteven Rostedtuse File::Path qw(mkpath); 117faafbd6SSteven Rostedtuse File::Copy qw(cp); 122545eb61SSteven Rostedtuse FileHandle; 132545eb61SSteven Rostedt 14e48c5293SSteven Rostedtmy $VERSION = "0.2"; 15e48c5293SSteven Rostedt 16e48c5293SSteven Rostedt$#ARGV >= 0 || die "ktest.pl version: $VERSION\n usage: ktest.pl config-file\n"; 172545eb61SSteven Rostedt 182545eb61SSteven Rostedt$| = 1; 192545eb61SSteven Rostedt 202545eb61SSteven Rostedtmy %opt; 21a57419b3SSteven Rostedtmy %repeat_tests; 22a57419b3SSteven Rostedtmy %repeats; 23a75fececSSteven Rostedtmy %default; 242545eb61SSteven Rostedt 252545eb61SSteven Rostedt#default opts 26a57419b3SSteven Rostedt$default{"NUM_TESTS"} = 1; 27a75fececSSteven Rostedt$default{"REBOOT_TYPE"} = "grub"; 28a75fececSSteven Rostedt$default{"TEST_TYPE"} = "test"; 29a75fececSSteven Rostedt$default{"BUILD_TYPE"} = "randconfig"; 30a75fececSSteven Rostedt$default{"MAKE_CMD"} = "make"; 31a75fececSSteven Rostedt$default{"TIMEOUT"} = 120; 32a57419b3SSteven Rostedt$default{"TMP_DIR"} = "/tmp/ktest"; 33a75fececSSteven Rostedt$default{"SLEEP_TIME"} = 60; # sleep time between tests 34a75fececSSteven Rostedt$default{"BUILD_NOCLEAN"} = 0; 35a75fececSSteven Rostedt$default{"REBOOT_ON_ERROR"} = 0; 36a75fececSSteven Rostedt$default{"POWEROFF_ON_ERROR"} = 0; 37a75fececSSteven Rostedt$default{"REBOOT_ON_SUCCESS"} = 1; 38a75fececSSteven Rostedt$default{"POWEROFF_ON_SUCCESS"} = 0; 39a75fececSSteven Rostedt$default{"BUILD_OPTIONS"} = ""; 40a75fececSSteven Rostedt$default{"BISECT_SLEEP_TIME"} = 60; # sleep time between bisects 41a75fececSSteven Rostedt$default{"CLEAR_LOG"} = 0; 42a75fececSSteven Rostedt$default{"SUCCESS_LINE"} = "login:"; 43a75fececSSteven Rostedt$default{"BOOTED_TIMEOUT"} = 1; 44a75fececSSteven Rostedt$default{"DIE_ON_FAILURE"} = 1; 45e48c5293SSteven Rostedt$default{"SSH_EXEC"} = "ssh \$SSH_USER\@\$MACHINE \$SSH_COMMAND"; 46e48c5293SSteven Rostedt$default{"SCP_TO_TARGET"} = "scp \$SRC_FILE \$SSH_USER\@\$MACHINE:\$DST_FILE"; 47e48c5293SSteven Rostedt$default{"REBOOT"} = "ssh \$SSH_USER\@\$MACHINE reboot"; 482545eb61SSteven Rostedt 492545eb61SSteven Rostedtmy $version; 50a75fececSSteven Rostedtmy $machine; 51e48c5293SSteven Rostedtmy $ssh_user; 52a75fececSSteven Rostedtmy $tmpdir; 53a75fececSSteven Rostedtmy $builddir; 54a75fececSSteven Rostedtmy $outputdir; 5551ad1dd1SSteven Rostedtmy $output_config; 56a75fececSSteven Rostedtmy $test_type; 577faafbd6SSteven Rostedtmy $build_type; 58a75fececSSteven Rostedtmy $build_options; 59a75fececSSteven Rostedtmy $reboot_type; 60a75fececSSteven Rostedtmy $reboot_script; 61a75fececSSteven Rostedtmy $power_cycle; 62e48c5293SSteven Rostedtmy $reboot; 63a75fececSSteven Rostedtmy $reboot_on_error; 64a75fececSSteven Rostedtmy $poweroff_on_error; 65a75fececSSteven Rostedtmy $die_on_failure; 66576f627cSSteven Rostedtmy $powercycle_after_reboot; 67576f627cSSteven Rostedtmy $poweroff_after_halt; 68e48c5293SSteven Rostedtmy $ssh_exec; 69e48c5293SSteven Rostedtmy $scp_to_target; 70a75fececSSteven Rostedtmy $power_off; 71a75fececSSteven Rostedtmy $grub_menu; 722545eb61SSteven Rostedtmy $grub_number; 732545eb61SSteven Rostedtmy $target; 742545eb61SSteven Rostedtmy $make; 758b37ca8cSSteven Rostedtmy $post_install; 765c42fc5bSSteven Rostedtmy $noclean; 775f9b6cedSSteven Rostedtmy $minconfig; 782b7d9b21SSteven Rostedtmy $addconfig; 795f9b6cedSSteven Rostedtmy $in_bisect = 0; 805f9b6cedSSteven Rostedtmy $bisect_bad = ""; 81d6ce2a0bSSteven Rostedtmy $reverse_bisect; 826c5ee0beSSteven Rostedtmy $in_patchcheck = 0; 835a391fbfSSteven Rostedtmy $run_test; 846c5ee0beSSteven Rostedtmy $redirect; 857faafbd6SSteven Rostedtmy $buildlog; 867faafbd6SSteven Rostedtmy $dmesg; 877faafbd6SSteven Rostedtmy $monitor_fp; 887faafbd6SSteven Rostedtmy $monitor_pid; 897faafbd6SSteven Rostedtmy $monitor_cnt = 0; 90a75fececSSteven Rostedtmy $sleep_time; 91a75fececSSteven Rostedtmy $bisect_sleep_time; 92a75fececSSteven Rostedtmy $store_failures; 93a75fececSSteven Rostedtmy $timeout; 94a75fececSSteven Rostedtmy $booted_timeout; 95a75fececSSteven Rostedtmy $console; 96a75fececSSteven Rostedtmy $success_line; 97a75fececSSteven Rostedtmy $build_target; 98a75fececSSteven Rostedtmy $target_image; 99a75fececSSteven Rostedtmy $localversion; 100576f627cSSteven Rostedtmy $iteration = 0; 101e48c5293SSteven Rostedtmy $successes = 0; 1022545eb61SSteven Rostedt 103a57419b3SSteven Rostedtsub set_value { 104a57419b3SSteven Rostedt my ($lvalue, $rvalue) = @_; 1052545eb61SSteven Rostedt 106a75fececSSteven Rostedt if (defined($opt{$lvalue})) { 107a75fececSSteven Rostedt die "Error: Option $lvalue defined more than once!\n"; 108a75fececSSteven Rostedt } 10921a9679fSSteven Rostedt if ($rvalue =~ /^\s*$/) { 11021a9679fSSteven Rostedt delete $opt{$lvalue}; 11121a9679fSSteven Rostedt } else { 11221a9679fSSteven Rostedt $opt{$lvalue} = $rvalue; 11321a9679fSSteven Rostedt } 1142545eb61SSteven Rostedt} 115a57419b3SSteven Rostedt 116a57419b3SSteven Rostedtsub read_config { 117a57419b3SSteven Rostedt my ($config) = @_; 118a57419b3SSteven Rostedt 119a57419b3SSteven Rostedt open(IN, $config) || die "can't read file $config"; 120a57419b3SSteven Rostedt 121a57419b3SSteven Rostedt my $name = $config; 122a57419b3SSteven Rostedt $name =~ s,.*/(.*),$1,; 123a57419b3SSteven Rostedt 124a57419b3SSteven Rostedt my $test_num = 0; 125a57419b3SSteven Rostedt my $default = 1; 126a57419b3SSteven Rostedt my $repeat = 1; 127a57419b3SSteven Rostedt my $num_tests_set = 0; 128a57419b3SSteven Rostedt my $skip = 0; 129a57419b3SSteven Rostedt my $rest; 130a57419b3SSteven Rostedt 131a57419b3SSteven Rostedt while (<IN>) { 132a57419b3SSteven Rostedt 133a57419b3SSteven Rostedt # ignore blank lines and comments 134a57419b3SSteven Rostedt next if (/^\s*$/ || /\s*\#/); 135a57419b3SSteven Rostedt 136a57419b3SSteven Rostedt if (/^\s*TEST_START(.*)/) { 137a57419b3SSteven Rostedt 138a57419b3SSteven Rostedt $rest = $1; 139a57419b3SSteven Rostedt 140a57419b3SSteven Rostedt if ($num_tests_set) { 141a57419b3SSteven Rostedt die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n"; 142a57419b3SSteven Rostedt } 143a57419b3SSteven Rostedt 144a57419b3SSteven Rostedt my $old_test_num = $test_num; 145e48c5293SSteven Rostedt my $old_repeat = $repeat; 146a57419b3SSteven Rostedt 147a57419b3SSteven Rostedt $test_num += $repeat; 148a57419b3SSteven Rostedt $default = 0; 149a57419b3SSteven Rostedt $repeat = 1; 150a57419b3SSteven Rostedt 151a57419b3SSteven Rostedt if ($rest =~ /\s+SKIP(.*)/) { 152a57419b3SSteven Rostedt $rest = $1; 153a57419b3SSteven Rostedt $skip = 1; 154a57419b3SSteven Rostedt } else { 155a57419b3SSteven Rostedt $skip = 0; 156a57419b3SSteven Rostedt } 157a57419b3SSteven Rostedt 158a57419b3SSteven Rostedt if ($rest =~ /\s+ITERATE\s+(\d+)(.*)$/) { 159a57419b3SSteven Rostedt $repeat = $1; 160a57419b3SSteven Rostedt $rest = $2; 161a57419b3SSteven Rostedt $repeat_tests{"$test_num"} = $repeat; 162a57419b3SSteven Rostedt } 163a57419b3SSteven Rostedt 164a57419b3SSteven Rostedt if ($rest =~ /\s+SKIP(.*)/) { 165a57419b3SSteven Rostedt $rest = $1; 166a57419b3SSteven Rostedt $skip = 1; 167a57419b3SSteven Rostedt } 168a57419b3SSteven Rostedt 169a57419b3SSteven Rostedt if ($rest !~ /^\s*$/) { 170a57419b3SSteven Rostedt die "$name: $.: Gargbage found after TEST_START\n$_"; 171a57419b3SSteven Rostedt } 172a57419b3SSteven Rostedt 173a57419b3SSteven Rostedt if ($skip) { 174a57419b3SSteven Rostedt $test_num = $old_test_num; 175e48c5293SSteven Rostedt $repeat = $old_repeat; 176a57419b3SSteven Rostedt } 177a57419b3SSteven Rostedt 178a57419b3SSteven Rostedt } elsif (/^\s*DEFAULTS(.*)$/) { 179a57419b3SSteven Rostedt $default = 1; 180a57419b3SSteven Rostedt 181a57419b3SSteven Rostedt $rest = $1; 182a57419b3SSteven Rostedt 183a57419b3SSteven Rostedt if ($rest =~ /\s+SKIP(.*)/) { 184a57419b3SSteven Rostedt $rest = $1; 185a57419b3SSteven Rostedt $skip = 1; 186a57419b3SSteven Rostedt } else { 187a57419b3SSteven Rostedt $skip = 0; 188a57419b3SSteven Rostedt } 189a57419b3SSteven Rostedt 190a57419b3SSteven Rostedt if ($rest !~ /^\s*$/) { 191a57419b3SSteven Rostedt die "$name: $.: Gargbage found after DEFAULTS\n$_"; 192a57419b3SSteven Rostedt } 193a57419b3SSteven Rostedt 194a57419b3SSteven Rostedt } elsif (/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) { 195a57419b3SSteven Rostedt 196a57419b3SSteven Rostedt next if ($skip); 197a57419b3SSteven Rostedt 198a57419b3SSteven Rostedt my $lvalue = $1; 199a57419b3SSteven Rostedt my $rvalue = $2; 200a57419b3SSteven Rostedt 201a57419b3SSteven Rostedt if (!$default && 202a57419b3SSteven Rostedt ($lvalue eq "NUM_TESTS" || 203a57419b3SSteven Rostedt $lvalue eq "LOG_FILE" || 204a57419b3SSteven Rostedt $lvalue eq "CLEAR_LOG")) { 205a57419b3SSteven Rostedt die "$name: $.: $lvalue must be set in DEFAULTS section\n"; 206a57419b3SSteven Rostedt } 207a57419b3SSteven Rostedt 208a57419b3SSteven Rostedt if ($lvalue eq "NUM_TESTS") { 209a57419b3SSteven Rostedt if ($test_num) { 210a57419b3SSteven Rostedt die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n"; 211a57419b3SSteven Rostedt } 212a57419b3SSteven Rostedt if (!$default) { 213a57419b3SSteven Rostedt die "$name: $.: NUM_TESTS must be set in default section\n"; 214a57419b3SSteven Rostedt } 215a57419b3SSteven Rostedt $num_tests_set = 1; 216a57419b3SSteven Rostedt } 217a57419b3SSteven Rostedt 218a57419b3SSteven Rostedt if ($default || $lvalue =~ /\[\d+\]$/) { 219a57419b3SSteven Rostedt set_value($lvalue, $rvalue); 220a57419b3SSteven Rostedt } else { 221a57419b3SSteven Rostedt my $val = "$lvalue\[$test_num\]"; 222a57419b3SSteven Rostedt set_value($val, $rvalue); 223a57419b3SSteven Rostedt 224a57419b3SSteven Rostedt if ($repeat > 1) { 225a57419b3SSteven Rostedt $repeats{$val} = $repeat; 226a57419b3SSteven Rostedt } 227a57419b3SSteven Rostedt } 228a57419b3SSteven Rostedt } else { 229a57419b3SSteven Rostedt die "$name: $.: Garbage found in config\n$_"; 230a57419b3SSteven Rostedt } 2312545eb61SSteven Rostedt } 2322545eb61SSteven Rostedt 2332545eb61SSteven Rostedt close(IN); 234a75fececSSteven Rostedt 235a57419b3SSteven Rostedt if ($test_num) { 236a57419b3SSteven Rostedt $test_num += $repeat - 1; 237a57419b3SSteven Rostedt $opt{"NUM_TESTS"} = $test_num; 238a57419b3SSteven Rostedt } 239a57419b3SSteven Rostedt 240a75fececSSteven Rostedt # set any defaults 241a75fececSSteven Rostedt 242a75fececSSteven Rostedt foreach my $default (keys %default) { 243a75fececSSteven Rostedt if (!defined($opt{$default})) { 244a75fececSSteven Rostedt $opt{$default} = $default{$default}; 245a75fececSSteven Rostedt } 246a75fececSSteven Rostedt } 2472545eb61SSteven Rostedt} 2482545eb61SSteven Rostedt 249d1e2f22aSSteven Rostedtsub _logit { 2502545eb61SSteven Rostedt if (defined($opt{"LOG_FILE"})) { 2512545eb61SSteven Rostedt open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}"; 2522545eb61SSteven Rostedt print OUT @_; 2532545eb61SSteven Rostedt close(OUT); 2542545eb61SSteven Rostedt } 2552545eb61SSteven Rostedt} 2562545eb61SSteven Rostedt 257d1e2f22aSSteven Rostedtsub logit { 258d1e2f22aSSteven Rostedt if (defined($opt{"LOG_FILE"})) { 259d1e2f22aSSteven Rostedt _logit @_; 260d1e2f22aSSteven Rostedt } else { 261d1e2f22aSSteven Rostedt print @_; 262d1e2f22aSSteven Rostedt } 263d1e2f22aSSteven Rostedt} 264d1e2f22aSSteven Rostedt 2655f9b6cedSSteven Rostedtsub doprint { 2665f9b6cedSSteven Rostedt print @_; 267d1e2f22aSSteven Rostedt _logit @_; 2685f9b6cedSSteven Rostedt} 2695f9b6cedSSteven Rostedt 2707faafbd6SSteven Rostedtsub run_command; 2717faafbd6SSteven Rostedt 2727faafbd6SSteven Rostedtsub reboot { 2737faafbd6SSteven Rostedt # try to reboot normally 274e48c5293SSteven Rostedt if (run_command $reboot) { 275576f627cSSteven Rostedt if (defined($powercycle_after_reboot)) { 276576f627cSSteven Rostedt sleep $powercycle_after_reboot; 277576f627cSSteven Rostedt run_command "$power_cycle"; 278576f627cSSteven Rostedt } 279576f627cSSteven Rostedt } else { 2807faafbd6SSteven Rostedt # nope? power cycle it. 281a75fececSSteven Rostedt run_command "$power_cycle"; 2827faafbd6SSteven Rostedt } 2837faafbd6SSteven Rostedt} 2847faafbd6SSteven Rostedt 285576f627cSSteven Rostedtsub do_not_reboot { 286576f627cSSteven Rostedt my $i = $iteration; 287576f627cSSteven Rostedt 288576f627cSSteven Rostedt return $test_type eq "build" || 289576f627cSSteven Rostedt ($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") || 290576f627cSSteven Rostedt ($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build"); 291576f627cSSteven Rostedt} 292576f627cSSteven Rostedt 2935c42fc5bSSteven Rostedtsub dodie { 2945a391fbfSSteven Rostedt doprint "CRITICAL FAILURE... ", @_, "\n"; 2955c42fc5bSSteven Rostedt 296576f627cSSteven Rostedt my $i = $iteration; 297576f627cSSteven Rostedt 298576f627cSSteven Rostedt if ($reboot_on_error && !do_not_reboot) { 299576f627cSSteven Rostedt 30075c3fda7SSteven Rostedt doprint "REBOOTING\n"; 3017faafbd6SSteven Rostedt reboot; 30275c3fda7SSteven Rostedt 303a75fececSSteven Rostedt } elsif ($poweroff_on_error && defined($power_off)) { 3045c42fc5bSSteven Rostedt doprint "POWERING OFF\n"; 305a75fececSSteven Rostedt `$power_off`; 3065c42fc5bSSteven Rostedt } 30775c3fda7SSteven Rostedt 308576f627cSSteven Rostedt die @_, "\n"; 3095c42fc5bSSteven Rostedt} 3105c42fc5bSSteven Rostedt 3117faafbd6SSteven Rostedtsub open_console { 3127faafbd6SSteven Rostedt my ($fp) = @_; 3137faafbd6SSteven Rostedt 3147faafbd6SSteven Rostedt my $flags; 3157faafbd6SSteven Rostedt 316a75fececSSteven Rostedt my $pid = open($fp, "$console|") or 317a75fececSSteven Rostedt dodie "Can't open console $console"; 3187faafbd6SSteven Rostedt 3197faafbd6SSteven Rostedt $flags = fcntl($fp, F_GETFL, 0) or 320576f627cSSteven Rostedt dodie "Can't get flags for the socket: $!"; 3217faafbd6SSteven Rostedt $flags = fcntl($fp, F_SETFL, $flags | O_NONBLOCK) or 322576f627cSSteven Rostedt dodie "Can't set flags for the socket: $!"; 3237faafbd6SSteven Rostedt 3247faafbd6SSteven Rostedt return $pid; 3257faafbd6SSteven Rostedt} 3267faafbd6SSteven Rostedt 3277faafbd6SSteven Rostedtsub close_console { 3287faafbd6SSteven Rostedt my ($fp, $pid) = @_; 3297faafbd6SSteven Rostedt 3307faafbd6SSteven Rostedt doprint "kill child process $pid\n"; 3317faafbd6SSteven Rostedt kill 2, $pid; 3327faafbd6SSteven Rostedt 3337faafbd6SSteven Rostedt print "closing!\n"; 3347faafbd6SSteven Rostedt close($fp); 3357faafbd6SSteven Rostedt} 3367faafbd6SSteven Rostedt 3377faafbd6SSteven Rostedtsub start_monitor { 3387faafbd6SSteven Rostedt if ($monitor_cnt++) { 3397faafbd6SSteven Rostedt return; 3407faafbd6SSteven Rostedt } 3417faafbd6SSteven Rostedt $monitor_fp = \*MONFD; 3427faafbd6SSteven Rostedt $monitor_pid = open_console $monitor_fp; 343a75fececSSteven Rostedt 344a75fececSSteven Rostedt return; 345a75fececSSteven Rostedt 346a75fececSSteven Rostedt open(MONFD, "Stop perl from warning about single use of MONFD"); 3477faafbd6SSteven Rostedt} 3487faafbd6SSteven Rostedt 3497faafbd6SSteven Rostedtsub end_monitor { 3507faafbd6SSteven Rostedt if (--$monitor_cnt) { 3517faafbd6SSteven Rostedt return; 3527faafbd6SSteven Rostedt } 3537faafbd6SSteven Rostedt close_console($monitor_fp, $monitor_pid); 3547faafbd6SSteven Rostedt} 3557faafbd6SSteven Rostedt 3567faafbd6SSteven Rostedtsub wait_for_monitor { 3577faafbd6SSteven Rostedt my ($time) = @_; 3587faafbd6SSteven Rostedt my $line; 3597faafbd6SSteven Rostedt 360a75fececSSteven Rostedt doprint "** Wait for monitor to settle down **\n"; 3617faafbd6SSteven Rostedt 3627faafbd6SSteven Rostedt # read the monitor and wait for the system to calm down 3637faafbd6SSteven Rostedt do { 3647faafbd6SSteven Rostedt $line = wait_for_input($monitor_fp, $time); 365a75fececSSteven Rostedt print "$line" if (defined($line)); 3667faafbd6SSteven Rostedt } while (defined($line)); 367a75fececSSteven Rostedt print "** Monitor flushed **\n"; 3687faafbd6SSteven Rostedt} 3697faafbd6SSteven Rostedt 3702b7d9b21SSteven Rostedtsub fail { 3712b7d9b21SSteven Rostedt 372a75fececSSteven Rostedt if ($die_on_failure) { 3732b7d9b21SSteven Rostedt dodie @_; 3742b7d9b21SSteven Rostedt } 3752b7d9b21SSteven Rostedt 376a75fececSSteven Rostedt doprint "FAILED\n"; 3777faafbd6SSteven Rostedt 378576f627cSSteven Rostedt my $i = $iteration; 379576f627cSSteven Rostedt 380a75fececSSteven Rostedt # no need to reboot for just building. 381576f627cSSteven Rostedt if (!do_not_reboot) { 3827faafbd6SSteven Rostedt doprint "REBOOTING\n"; 3837faafbd6SSteven Rostedt reboot; 3847faafbd6SSteven Rostedt start_monitor; 385a75fececSSteven Rostedt wait_for_monitor $sleep_time; 3867faafbd6SSteven Rostedt end_monitor; 387a75fececSSteven Rostedt } 3887faafbd6SSteven Rostedt 389576f627cSSteven Rostedt doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; 390576f627cSSteven Rostedt doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; 3917a849cd9SSteven Rostedt doprint "KTEST RESULT: TEST $i Failed: ", @_, "\n"; 392576f627cSSteven Rostedt doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; 393576f627cSSteven Rostedt doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; 394a75fececSSteven Rostedt 395a75fececSSteven Rostedt return 1 if (!defined($store_failures)); 3967faafbd6SSteven Rostedt 3977faafbd6SSteven Rostedt my @t = localtime; 3987faafbd6SSteven Rostedt my $date = sprintf "%04d%02d%02d%02d%02d%02d", 3997faafbd6SSteven Rostedt 1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0]; 4007faafbd6SSteven Rostedt 401a75fececSSteven Rostedt my $dir = "$machine-$test_type-$build_type-fail-$date"; 402a75fececSSteven Rostedt my $faildir = "$store_failures/$dir"; 4037faafbd6SSteven Rostedt 4047faafbd6SSteven Rostedt if (!-d $faildir) { 4057faafbd6SSteven Rostedt mkpath($faildir) or 406a75fececSSteven Rostedt die "can't create $faildir"; 4077faafbd6SSteven Rostedt } 40851ad1dd1SSteven Rostedt if (-f "$output_config") { 40951ad1dd1SSteven Rostedt cp "$output_config", "$faildir/config" or 4107faafbd6SSteven Rostedt die "failed to copy .config"; 4117faafbd6SSteven Rostedt } 4127faafbd6SSteven Rostedt if (-f $buildlog) { 4137faafbd6SSteven Rostedt cp $buildlog, "$faildir/buildlog" or 4147faafbd6SSteven Rostedt die "failed to move $buildlog"; 4157faafbd6SSteven Rostedt } 4167faafbd6SSteven Rostedt if (-f $dmesg) { 4177faafbd6SSteven Rostedt cp $dmesg, "$faildir/dmesg" or 4187faafbd6SSteven Rostedt die "failed to move $dmesg"; 4197faafbd6SSteven Rostedt } 4207faafbd6SSteven Rostedt 4217faafbd6SSteven Rostedt doprint "*** Saved info to $faildir ***\n"; 4227faafbd6SSteven Rostedt 4232b7d9b21SSteven Rostedt return 1; 4242b7d9b21SSteven Rostedt} 4252b7d9b21SSteven Rostedt 4262545eb61SSteven Rostedtsub run_command { 4272545eb61SSteven Rostedt my ($command) = @_; 428d6ce2a0bSSteven Rostedt my $dolog = 0; 429d6ce2a0bSSteven Rostedt my $dord = 0; 430d6ce2a0bSSteven Rostedt my $pid; 431d6ce2a0bSSteven Rostedt 432e48c5293SSteven Rostedt $command =~ s/\$SSH_USER/$ssh_user/g; 433e48c5293SSteven Rostedt $command =~ s/\$MACHINE/$machine/g; 434e48c5293SSteven Rostedt 435d6ce2a0bSSteven Rostedt doprint("$command ... "); 436d6ce2a0bSSteven Rostedt 437d6ce2a0bSSteven Rostedt $pid = open(CMD, "$command 2>&1 |") or 4382b7d9b21SSteven Rostedt (fail "unable to exec $command" and return 0); 4392545eb61SSteven Rostedt 4402545eb61SSteven Rostedt if (defined($opt{"LOG_FILE"})) { 441d6ce2a0bSSteven Rostedt open(LOG, ">>$opt{LOG_FILE}") or 442d6ce2a0bSSteven Rostedt dodie "failed to write to log"; 443d6ce2a0bSSteven Rostedt $dolog = 1; 4446c5ee0beSSteven Rostedt } 4456c5ee0beSSteven Rostedt 4466c5ee0beSSteven Rostedt if (defined($redirect)) { 447d6ce2a0bSSteven Rostedt open (RD, ">$redirect") or 448d6ce2a0bSSteven Rostedt dodie "failed to write to redirect $redirect"; 449d6ce2a0bSSteven Rostedt $dord = 1; 4502545eb61SSteven Rostedt } 4512545eb61SSteven Rostedt 452d6ce2a0bSSteven Rostedt while (<CMD>) { 453d6ce2a0bSSteven Rostedt print LOG if ($dolog); 454d6ce2a0bSSteven Rostedt print RD if ($dord); 455d6ce2a0bSSteven Rostedt } 4562545eb61SSteven Rostedt 457d6ce2a0bSSteven Rostedt waitpid($pid, 0); 4582545eb61SSteven Rostedt my $failed = $?; 4592545eb61SSteven Rostedt 460d6ce2a0bSSteven Rostedt close(CMD); 461d6ce2a0bSSteven Rostedt close(LOG) if ($dolog); 462d6ce2a0bSSteven Rostedt close(RD) if ($dord); 463d6ce2a0bSSteven Rostedt 4642545eb61SSteven Rostedt if ($failed) { 4652545eb61SSteven Rostedt doprint "FAILED!\n"; 4662545eb61SSteven Rostedt } else { 4672545eb61SSteven Rostedt doprint "SUCCESS\n"; 4682545eb61SSteven Rostedt } 4692545eb61SSteven Rostedt 4705f9b6cedSSteven Rostedt return !$failed; 4715f9b6cedSSteven Rostedt} 4725f9b6cedSSteven Rostedt 473e48c5293SSteven Rostedtsub run_ssh { 474e48c5293SSteven Rostedt my ($cmd) = @_; 475e48c5293SSteven Rostedt my $cp_exec = $ssh_exec; 476e48c5293SSteven Rostedt 477e48c5293SSteven Rostedt $cp_exec =~ s/\$SSH_COMMAND/$cmd/g; 478e48c5293SSteven Rostedt return run_command "$cp_exec"; 479e48c5293SSteven Rostedt} 480e48c5293SSteven Rostedt 481e48c5293SSteven Rostedtsub run_scp { 482e48c5293SSteven Rostedt my ($src, $dst) = @_; 483e48c5293SSteven Rostedt my $cp_scp = $scp_to_target; 484e48c5293SSteven Rostedt 485e48c5293SSteven Rostedt $cp_scp =~ s/\$SRC_FILE/$src/g; 486e48c5293SSteven Rostedt $cp_scp =~ s/\$DST_FILE/$dst/g; 487e48c5293SSteven Rostedt 488e48c5293SSteven Rostedt return run_command "$cp_scp"; 489e48c5293SSteven Rostedt} 490e48c5293SSteven Rostedt 4915f9b6cedSSteven Rostedtsub get_grub_index { 4925f9b6cedSSteven Rostedt 493a75fececSSteven Rostedt if ($reboot_type ne "grub") { 494a75fececSSteven Rostedt return; 495a75fececSSteven Rostedt } 4965a391fbfSSteven Rostedt return if (defined($grub_number)); 4975f9b6cedSSteven Rostedt 4985f9b6cedSSteven Rostedt doprint "Find grub menu ... "; 4995f9b6cedSSteven Rostedt $grub_number = -1; 500e48c5293SSteven Rostedt 501e48c5293SSteven Rostedt my $ssh_grub = $ssh_exec; 502e48c5293SSteven Rostedt $ssh_grub =~ s,\$SSH_COMMAND,cat /boot/grub/menu.lst,g; 503e48c5293SSteven Rostedt 504e48c5293SSteven Rostedt open(IN, "$ssh_grub |") 5055f9b6cedSSteven Rostedt or die "unable to get menu.lst"; 506e48c5293SSteven Rostedt 5075f9b6cedSSteven Rostedt while (<IN>) { 508a75fececSSteven Rostedt if (/^\s*title\s+$grub_menu\s*$/) { 5095f9b6cedSSteven Rostedt $grub_number++; 5105f9b6cedSSteven Rostedt last; 5115f9b6cedSSteven Rostedt } elsif (/^\s*title\s/) { 5125f9b6cedSSteven Rostedt $grub_number++; 5135f9b6cedSSteven Rostedt } 5145f9b6cedSSteven Rostedt } 5155f9b6cedSSteven Rostedt close(IN); 5165f9b6cedSSteven Rostedt 517a75fececSSteven Rostedt die "Could not find '$grub_menu' in /boot/grub/menu on $machine" 5185f9b6cedSSteven Rostedt if ($grub_number < 0); 5195f9b6cedSSteven Rostedt doprint "$grub_number\n"; 5202545eb61SSteven Rostedt} 5212545eb61SSteven Rostedt 5222545eb61SSteven Rostedtsub wait_for_input 5232545eb61SSteven Rostedt{ 5242545eb61SSteven Rostedt my ($fp, $time) = @_; 5252545eb61SSteven Rostedt my $rin; 5262545eb61SSteven Rostedt my $ready; 5272545eb61SSteven Rostedt my $line; 5282545eb61SSteven Rostedt my $ch; 5292545eb61SSteven Rostedt 5302545eb61SSteven Rostedt if (!defined($time)) { 5312545eb61SSteven Rostedt $time = $timeout; 5322545eb61SSteven Rostedt } 5332545eb61SSteven Rostedt 5342545eb61SSteven Rostedt $rin = ''; 5352545eb61SSteven Rostedt vec($rin, fileno($fp), 1) = 1; 5362545eb61SSteven Rostedt $ready = select($rin, undef, undef, $time); 5372545eb61SSteven Rostedt 5382545eb61SSteven Rostedt $line = ""; 5392545eb61SSteven Rostedt 5402545eb61SSteven Rostedt # try to read one char at a time 5412545eb61SSteven Rostedt while (sysread $fp, $ch, 1) { 5422545eb61SSteven Rostedt $line .= $ch; 5432545eb61SSteven Rostedt last if ($ch eq "\n"); 5442545eb61SSteven Rostedt } 5452545eb61SSteven Rostedt 5462545eb61SSteven Rostedt if (!length($line)) { 5472545eb61SSteven Rostedt return undef; 5482545eb61SSteven Rostedt } 5492545eb61SSteven Rostedt 5502545eb61SSteven Rostedt return $line; 5512545eb61SSteven Rostedt} 5522545eb61SSteven Rostedt 55375c3fda7SSteven Rostedtsub reboot_to { 554a75fececSSteven Rostedt if ($reboot_type eq "grub") { 555e48c5293SSteven Rostedt run_command "$ssh_exec '(echo \"savedefault --default=$grub_number --once\" | grub --batch; reboot)'"; 556a75fececSSteven Rostedt return; 557a75fececSSteven Rostedt } 558a75fececSSteven Rostedt 559a75fececSSteven Rostedt run_command "$reboot_script"; 5602545eb61SSteven Rostedt} 5612545eb61SSteven Rostedt 562a57419b3SSteven Rostedtsub get_sha1 { 563a57419b3SSteven Rostedt my ($commit) = @_; 564a57419b3SSteven Rostedt 565a57419b3SSteven Rostedt doprint "git rev-list --max-count=1 $commit ... "; 566a57419b3SSteven Rostedt my $sha1 = `git rev-list --max-count=1 $commit`; 567a57419b3SSteven Rostedt my $ret = $?; 568a57419b3SSteven Rostedt 569a57419b3SSteven Rostedt logit $sha1; 570a57419b3SSteven Rostedt 571a57419b3SSteven Rostedt if ($ret) { 572a57419b3SSteven Rostedt doprint "FAILED\n"; 573a57419b3SSteven Rostedt dodie "Failed to get git $commit"; 574a57419b3SSteven Rostedt } 575a57419b3SSteven Rostedt 576a57419b3SSteven Rostedt print "SUCCESS\n"; 577a57419b3SSteven Rostedt 578a57419b3SSteven Rostedt chomp $sha1; 579a57419b3SSteven Rostedt 580a57419b3SSteven Rostedt return $sha1; 581a57419b3SSteven Rostedt} 582a57419b3SSteven Rostedt 5835a391fbfSSteven Rostedtsub monitor { 5842545eb61SSteven Rostedt my $booted = 0; 5852545eb61SSteven Rostedt my $bug = 0; 5865c42fc5bSSteven Rostedt my $skip_call_trace = 0; 5872b7d9b21SSteven Rostedt my $loops; 5882545eb61SSteven Rostedt 5897faafbd6SSteven Rostedt wait_for_monitor 5; 5902545eb61SSteven Rostedt 5912545eb61SSteven Rostedt my $line; 5922545eb61SSteven Rostedt my $full_line = ""; 5932545eb61SSteven Rostedt 5947faafbd6SSteven Rostedt open(DMESG, "> $dmesg") or 5957faafbd6SSteven Rostedt die "unable to write to $dmesg"; 5962545eb61SSteven Rostedt 59775c3fda7SSteven Rostedt reboot_to; 5982545eb61SSteven Rostedt 5992545eb61SSteven Rostedt for (;;) { 6002545eb61SSteven Rostedt 6012b7d9b21SSteven Rostedt if ($booted) { 602a75fececSSteven Rostedt $line = wait_for_input($monitor_fp, $booted_timeout); 6032b7d9b21SSteven Rostedt } else { 6047faafbd6SSteven Rostedt $line = wait_for_input($monitor_fp); 6052b7d9b21SSteven Rostedt } 6062545eb61SSteven Rostedt 6072545eb61SSteven Rostedt last if (!defined($line)); 6082545eb61SSteven Rostedt 6092545eb61SSteven Rostedt doprint $line; 6107faafbd6SSteven Rostedt print DMESG $line; 6112545eb61SSteven Rostedt 6122545eb61SSteven Rostedt # we are not guaranteed to get a full line 6132545eb61SSteven Rostedt $full_line .= $line; 6142545eb61SSteven Rostedt 615a75fececSSteven Rostedt if ($full_line =~ /$success_line/) { 6162545eb61SSteven Rostedt $booted = 1; 6172545eb61SSteven Rostedt } 6182545eb61SSteven Rostedt 6195c42fc5bSSteven Rostedt if ($full_line =~ /\[ backtrace testing \]/) { 6205c42fc5bSSteven Rostedt $skip_call_trace = 1; 6215c42fc5bSSteven Rostedt } 6225c42fc5bSSteven Rostedt 6232545eb61SSteven Rostedt if ($full_line =~ /call trace:/i) { 6245c42fc5bSSteven Rostedt $bug = 1 if (!$skip_call_trace); 6255c42fc5bSSteven Rostedt } 6265c42fc5bSSteven Rostedt 6275c42fc5bSSteven Rostedt if ($full_line =~ /\[ end of backtrace testing \]/) { 6285c42fc5bSSteven Rostedt $skip_call_trace = 0; 6295c42fc5bSSteven Rostedt } 6305c42fc5bSSteven Rostedt 6315c42fc5bSSteven Rostedt if ($full_line =~ /Kernel panic -/) { 6322545eb61SSteven Rostedt $bug = 1; 6332545eb61SSteven Rostedt } 6342545eb61SSteven Rostedt 6352545eb61SSteven Rostedt if ($line =~ /\n/) { 6362545eb61SSteven Rostedt $full_line = ""; 6372545eb61SSteven Rostedt } 6382545eb61SSteven Rostedt } 6392545eb61SSteven Rostedt 6407faafbd6SSteven Rostedt close(DMESG); 6412545eb61SSteven Rostedt 6422545eb61SSteven Rostedt if ($bug) { 6432b7d9b21SSteven Rostedt return 0 if ($in_bisect); 644576f627cSSteven Rostedt fail "failed - got a bug report" and return 0; 6452545eb61SSteven Rostedt } 6465f9b6cedSSteven Rostedt 647a75fececSSteven Rostedt if (!$booted) { 648a75fececSSteven Rostedt return 0 if ($in_bisect); 649576f627cSSteven Rostedt fail "failed - never got a boot prompt." and return 0; 650a75fececSSteven Rostedt } 651a75fececSSteven Rostedt 6522b7d9b21SSteven Rostedt return 1; 6532545eb61SSteven Rostedt} 6542545eb61SSteven Rostedt 6552545eb61SSteven Rostedtsub install { 6562545eb61SSteven Rostedt 657e48c5293SSteven Rostedt run_scp "$outputdir/$build_target", "$target_image" or 6585c42fc5bSSteven Rostedt dodie "failed to copy image"; 6595f9b6cedSSteven Rostedt 6605f9b6cedSSteven Rostedt my $install_mods = 0; 6615f9b6cedSSteven Rostedt 6625f9b6cedSSteven Rostedt # should we process modules? 6635f9b6cedSSteven Rostedt $install_mods = 0; 66451ad1dd1SSteven Rostedt open(IN, "$output_config") or dodie("Can't read config file"); 6655f9b6cedSSteven Rostedt while (<IN>) { 6665f9b6cedSSteven Rostedt if (/CONFIG_MODULES(=y)?/) { 6675f9b6cedSSteven Rostedt $install_mods = 1 if (defined($1)); 6685f9b6cedSSteven Rostedt last; 6695f9b6cedSSteven Rostedt } 6705f9b6cedSSteven Rostedt } 6715f9b6cedSSteven Rostedt close(IN); 6725f9b6cedSSteven Rostedt 6735f9b6cedSSteven Rostedt if (!$install_mods) { 6745f9b6cedSSteven Rostedt doprint "No modules needed\n"; 6755f9b6cedSSteven Rostedt return; 6762545eb61SSteven Rostedt } 6772545eb61SSteven Rostedt 678a75fececSSteven Rostedt run_command "$make INSTALL_MOD_PATH=$tmpdir modules_install" or 6795f9b6cedSSteven Rostedt dodie "Failed to install modules"; 6805f9b6cedSSteven Rostedt 6812545eb61SSteven Rostedt my $modlib = "/lib/modules/$version"; 682a57419b3SSteven Rostedt my $modtar = "ktest-mods.tar.bz2"; 6832545eb61SSteven Rostedt 684e48c5293SSteven Rostedt run_ssh "rm -rf $modlib" or 6855c42fc5bSSteven Rostedt dodie "failed to remove old mods: $modlib"; 6862545eb61SSteven Rostedt 6875c42fc5bSSteven Rostedt # would be nice if scp -r did not follow symbolic links 688a75fececSSteven Rostedt run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or 6895c42fc5bSSteven Rostedt dodie "making tarball"; 6905c42fc5bSSteven Rostedt 691e48c5293SSteven Rostedt run_scp "$tmpdir/$modtar", "/tmp" or 6925c42fc5bSSteven Rostedt dodie "failed to copy modules"; 6935c42fc5bSSteven Rostedt 694a75fececSSteven Rostedt unlink "$tmpdir/$modtar"; 6955c42fc5bSSteven Rostedt 696e48c5293SSteven Rostedt run_ssh "'(cd / && tar xf /tmp/$modtar)'" or 6975c42fc5bSSteven Rostedt dodie "failed to tar modules"; 6985c42fc5bSSteven Rostedt 699e48c5293SSteven Rostedt run_ssh "rm -f /tmp/$modtar"; 7008b37ca8cSSteven Rostedt 7018b37ca8cSSteven Rostedt return if (!defined($post_install)); 7028b37ca8cSSteven Rostedt 703e48c5293SSteven Rostedt my $cp_post_install = $post_install; 704e48c5293SSteven Rostedt $cp_post_install = s/\$KERNEL_VERSION/$version/g; 705e48c5293SSteven Rostedt run_command "$cp_post_install" or 706576f627cSSteven Rostedt dodie "Failed to run post install"; 7072545eb61SSteven Rostedt} 7082545eb61SSteven Rostedt 7096c5ee0beSSteven Rostedtsub check_buildlog { 7106c5ee0beSSteven Rostedt my ($patch) = @_; 7116c5ee0beSSteven Rostedt 7126c5ee0beSSteven Rostedt my @files = `git show $patch | diffstat -l`; 7136c5ee0beSSteven Rostedt 7146c5ee0beSSteven Rostedt open(IN, "git show $patch |") or 7156c5ee0beSSteven Rostedt dodie "failed to show $patch"; 7166c5ee0beSSteven Rostedt while (<IN>) { 7176c5ee0beSSteven Rostedt if (m,^--- a/(.*),) { 7186c5ee0beSSteven Rostedt chomp $1; 7196c5ee0beSSteven Rostedt $files[$#files] = $1; 7206c5ee0beSSteven Rostedt } 7216c5ee0beSSteven Rostedt } 7226c5ee0beSSteven Rostedt close(IN); 7236c5ee0beSSteven Rostedt 7246c5ee0beSSteven Rostedt open(IN, $buildlog) or dodie "Can't open $buildlog"; 7256c5ee0beSSteven Rostedt while (<IN>) { 7266c5ee0beSSteven Rostedt if (/^\s*(.*?):.*(warning|error)/) { 7276c5ee0beSSteven Rostedt my $err = $1; 7286c5ee0beSSteven Rostedt foreach my $file (@files) { 729a75fececSSteven Rostedt my $fullpath = "$builddir/$file"; 7306c5ee0beSSteven Rostedt if ($file eq $err || $fullpath eq $err) { 7312b7d9b21SSteven Rostedt fail "$file built with warnings" and return 0; 7326c5ee0beSSteven Rostedt } 7336c5ee0beSSteven Rostedt } 7346c5ee0beSSteven Rostedt } 7356c5ee0beSSteven Rostedt } 7366c5ee0beSSteven Rostedt close(IN); 7372b7d9b21SSteven Rostedt 7382b7d9b21SSteven Rostedt return 1; 7396c5ee0beSSteven Rostedt} 7406c5ee0beSSteven Rostedt 7412545eb61SSteven Rostedtsub build { 7422545eb61SSteven Rostedt my ($type) = @_; 7435c42fc5bSSteven Rostedt my $defconfig = ""; 7442545eb61SSteven Rostedt 7457faafbd6SSteven Rostedt unlink $buildlog; 7467faafbd6SSteven Rostedt 74775c3fda7SSteven Rostedt if ($type =~ /^useconfig:(.*)/) { 74851ad1dd1SSteven Rostedt run_command "cp $1 $output_config" or 74975c3fda7SSteven Rostedt dodie "could not copy $1 to .config"; 7505f9b6cedSSteven Rostedt 75175c3fda7SSteven Rostedt $type = "oldconfig"; 75275c3fda7SSteven Rostedt } 75375c3fda7SSteven Rostedt 7545c42fc5bSSteven Rostedt # old config can ask questions 7555c42fc5bSSteven Rostedt if ($type eq "oldconfig") { 7569386c6abSSteven Rostedt $type = "oldnoconfig"; 75775c3fda7SSteven Rostedt 75875c3fda7SSteven Rostedt # allow for empty configs 75951ad1dd1SSteven Rostedt run_command "touch $output_config"; 76075c3fda7SSteven Rostedt 76151ad1dd1SSteven Rostedt run_command "mv $output_config $outputdir/config_temp" or 7625c42fc5bSSteven Rostedt dodie "moving .config"; 7635c42fc5bSSteven Rostedt 7645f9b6cedSSteven Rostedt if (!$noclean && !run_command "$make mrproper") { 7655c42fc5bSSteven Rostedt dodie "make mrproper"; 7665c42fc5bSSteven Rostedt } 7675c42fc5bSSteven Rostedt 76851ad1dd1SSteven Rostedt run_command "mv $outputdir/config_temp $output_config" or 7695c42fc5bSSteven Rostedt dodie "moving config_temp"; 7705c42fc5bSSteven Rostedt 7715c42fc5bSSteven Rostedt } elsif (!$noclean) { 77251ad1dd1SSteven Rostedt unlink "$output_config"; 7735f9b6cedSSteven Rostedt run_command "$make mrproper" or 7745c42fc5bSSteven Rostedt dodie "make mrproper"; 7755c42fc5bSSteven Rostedt } 7762545eb61SSteven Rostedt 7772545eb61SSteven Rostedt # add something to distinguish this build 778a75fececSSteven Rostedt open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file"); 779a75fececSSteven Rostedt print OUT "$localversion\n"; 7802545eb61SSteven Rostedt close(OUT); 7812545eb61SSteven Rostedt 7825f9b6cedSSteven Rostedt if (defined($minconfig)) { 7835f9b6cedSSteven Rostedt $defconfig = "KCONFIG_ALLCONFIG=$minconfig"; 7842545eb61SSteven Rostedt } 7852545eb61SSteven Rostedt 7869386c6abSSteven Rostedt run_command "$defconfig $make $type" or 7875c42fc5bSSteven Rostedt dodie "failed make config"; 7882545eb61SSteven Rostedt 789a75fececSSteven Rostedt $redirect = "$buildlog"; 790a75fececSSteven Rostedt if (!run_command "$make $build_options") { 7916c5ee0beSSteven Rostedt undef $redirect; 7925f9b6cedSSteven Rostedt # bisect may need this to pass 7932b7d9b21SSteven Rostedt return 0 if ($in_bisect); 7942b7d9b21SSteven Rostedt fail "failed build" and return 0; 7952545eb61SSteven Rostedt } 7966c5ee0beSSteven Rostedt undef $redirect; 7975f9b6cedSSteven Rostedt 7982b7d9b21SSteven Rostedt return 1; 7992545eb61SSteven Rostedt} 8002545eb61SSteven Rostedt 80175c3fda7SSteven Rostedtsub halt { 802e48c5293SSteven Rostedt if (!run_ssh "halt" or defined($power_off)) { 803576f627cSSteven Rostedt if (defined($poweroff_after_halt)) { 804576f627cSSteven Rostedt sleep $poweroff_after_halt; 805576f627cSSteven Rostedt run_command "$power_off"; 806576f627cSSteven Rostedt } 807576f627cSSteven Rostedt } else { 80875c3fda7SSteven Rostedt # nope? the zap it! 809a75fececSSteven Rostedt run_command "$power_off"; 81075c3fda7SSteven Rostedt } 81175c3fda7SSteven Rostedt} 81275c3fda7SSteven Rostedt 8135f9b6cedSSteven Rostedtsub success { 8145f9b6cedSSteven Rostedt my ($i) = @_; 8155f9b6cedSSteven Rostedt 816e48c5293SSteven Rostedt $successes++; 817e48c5293SSteven Rostedt 8185f9b6cedSSteven Rostedt doprint "\n\n*******************************************\n"; 8195f9b6cedSSteven Rostedt doprint "*******************************************\n"; 8207a849cd9SSteven Rostedt doprint "KTEST RESULT: TEST $i SUCCESS!!!! **\n"; 8215f9b6cedSSteven Rostedt doprint "*******************************************\n"; 8225f9b6cedSSteven Rostedt doprint "*******************************************\n"; 8235f9b6cedSSteven Rostedt 824576f627cSSteven Rostedt if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) { 825a75fececSSteven Rostedt doprint "Reboot and wait $sleep_time seconds\n"; 8265f9b6cedSSteven Rostedt reboot; 8277faafbd6SSteven Rostedt start_monitor; 828a75fececSSteven Rostedt wait_for_monitor $sleep_time; 8297faafbd6SSteven Rostedt end_monitor; 8305f9b6cedSSteven Rostedt } 8315f9b6cedSSteven Rostedt} 8325f9b6cedSSteven Rostedt 8335f9b6cedSSteven Rostedtsub get_version { 8345f9b6cedSSteven Rostedt # get the release name 8355f9b6cedSSteven Rostedt doprint "$make kernelrelease ... "; 8365f9b6cedSSteven Rostedt $version = `$make kernelrelease | tail -1`; 8375f9b6cedSSteven Rostedt chomp($version); 8385f9b6cedSSteven Rostedt doprint "$version\n"; 8395f9b6cedSSteven Rostedt} 8405f9b6cedSSteven Rostedt 8415a391fbfSSteven Rostedtsub child_run_test { 8427faafbd6SSteven Rostedt my $failed = 0; 8435a391fbfSSteven Rostedt 8447faafbd6SSteven Rostedt # child should have no power 845a75fececSSteven Rostedt $reboot_on_error = 0; 846a75fececSSteven Rostedt $poweroff_on_error = 0; 847a75fececSSteven Rostedt $die_on_failure = 1; 8487faafbd6SSteven Rostedt 8497faafbd6SSteven Rostedt run_command $run_test or $failed = 1; 8505a391fbfSSteven Rostedt exit $failed; 8515a391fbfSSteven Rostedt} 8525a391fbfSSteven Rostedt 8535a391fbfSSteven Rostedtmy $child_done; 8545a391fbfSSteven Rostedt 8555a391fbfSSteven Rostedtsub child_finished { 8565a391fbfSSteven Rostedt $child_done = 1; 8575a391fbfSSteven Rostedt} 8585a391fbfSSteven Rostedt 8595a391fbfSSteven Rostedtsub do_run_test { 8605a391fbfSSteven Rostedt my $child_pid; 8615a391fbfSSteven Rostedt my $child_exit; 8625a391fbfSSteven Rostedt my $line; 8635a391fbfSSteven Rostedt my $full_line; 8645a391fbfSSteven Rostedt my $bug = 0; 8655a391fbfSSteven Rostedt 8667faafbd6SSteven Rostedt wait_for_monitor 1; 8675a391fbfSSteven Rostedt 8687faafbd6SSteven Rostedt doprint "run test $run_test\n"; 8695a391fbfSSteven Rostedt 8705a391fbfSSteven Rostedt $child_done = 0; 8715a391fbfSSteven Rostedt 8725a391fbfSSteven Rostedt $SIG{CHLD} = qw(child_finished); 8735a391fbfSSteven Rostedt 8745a391fbfSSteven Rostedt $child_pid = fork; 8755a391fbfSSteven Rostedt 8765a391fbfSSteven Rostedt child_run_test if (!$child_pid); 8775a391fbfSSteven Rostedt 8785a391fbfSSteven Rostedt $full_line = ""; 8795a391fbfSSteven Rostedt 8805a391fbfSSteven Rostedt do { 8817faafbd6SSteven Rostedt $line = wait_for_input($monitor_fp, 1); 8825a391fbfSSteven Rostedt if (defined($line)) { 8835a391fbfSSteven Rostedt 8845a391fbfSSteven Rostedt # we are not guaranteed to get a full line 8855a391fbfSSteven Rostedt $full_line .= $line; 8865a391fbfSSteven Rostedt 8875a391fbfSSteven Rostedt if ($full_line =~ /call trace:/i) { 8885a391fbfSSteven Rostedt $bug = 1; 8895a391fbfSSteven Rostedt } 8905a391fbfSSteven Rostedt 8915a391fbfSSteven Rostedt if ($full_line =~ /Kernel panic -/) { 8925a391fbfSSteven Rostedt $bug = 1; 8935a391fbfSSteven Rostedt } 8945a391fbfSSteven Rostedt 8955a391fbfSSteven Rostedt if ($line =~ /\n/) { 8965a391fbfSSteven Rostedt $full_line = ""; 8975a391fbfSSteven Rostedt } 8985a391fbfSSteven Rostedt } 8995a391fbfSSteven Rostedt } while (!$child_done && !$bug); 9005a391fbfSSteven Rostedt 9015a391fbfSSteven Rostedt if ($bug) { 9025a391fbfSSteven Rostedt doprint "Detected kernel crash!\n"; 9035a391fbfSSteven Rostedt # kill the child with extreme prejudice 9045a391fbfSSteven Rostedt kill 9, $child_pid; 9055a391fbfSSteven Rostedt } 9065a391fbfSSteven Rostedt 9075a391fbfSSteven Rostedt waitpid $child_pid, 0; 9085a391fbfSSteven Rostedt $child_exit = $?; 9095a391fbfSSteven Rostedt 9105a391fbfSSteven Rostedt if ($bug || $child_exit) { 9112b7d9b21SSteven Rostedt return 0 if $in_bisect; 9122b7d9b21SSteven Rostedt fail "test failed" and return 0; 9135a391fbfSSteven Rostedt } 9142b7d9b21SSteven Rostedt return 1; 9155a391fbfSSteven Rostedt} 9165a391fbfSSteven Rostedt 917a75fececSSteven Rostedtsub run_git_bisect { 918a75fececSSteven Rostedt my ($command) = @_; 919a75fececSSteven Rostedt 920a75fececSSteven Rostedt doprint "$command ... "; 921a75fececSSteven Rostedt 922a75fececSSteven Rostedt my $output = `$command 2>&1`; 923a75fececSSteven Rostedt my $ret = $?; 924a75fececSSteven Rostedt 925a75fececSSteven Rostedt logit $output; 926a75fececSSteven Rostedt 927a75fececSSteven Rostedt if ($ret) { 928a75fececSSteven Rostedt doprint "FAILED\n"; 929a75fececSSteven Rostedt dodie "Failed to git bisect"; 930a75fececSSteven Rostedt } 931a75fececSSteven Rostedt 932a75fececSSteven Rostedt doprint "SUCCESS\n"; 933a75fececSSteven Rostedt if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) { 934a75fececSSteven Rostedt doprint "$1 [$2]\n"; 935a75fececSSteven Rostedt } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) { 936a75fececSSteven Rostedt $bisect_bad = $1; 937a75fececSSteven Rostedt doprint "Found bad commit... $1\n"; 938a75fececSSteven Rostedt return 0; 939a75fececSSteven Rostedt } else { 940a75fececSSteven Rostedt # we already logged it, just print it now. 941a75fececSSteven Rostedt print $output; 942a75fececSSteven Rostedt } 943a75fececSSteven Rostedt 944a75fececSSteven Rostedt return 1; 945a75fececSSteven Rostedt} 946a75fececSSteven Rostedt 9470a05c769SSteven Rostedt# returns 1 on success, 0 on failure 9480a05c769SSteven Rostedtsub run_bisect_test { 9490a05c769SSteven Rostedt my ($type, $buildtype) = @_; 9505f9b6cedSSteven Rostedt 9512b7d9b21SSteven Rostedt my $failed = 0; 9525f9b6cedSSteven Rostedt my $result; 9535f9b6cedSSteven Rostedt my $output; 9545f9b6cedSSteven Rostedt my $ret; 9555f9b6cedSSteven Rostedt 9560a05c769SSteven Rostedt $in_bisect = 1; 9570a05c769SSteven Rostedt 9580a05c769SSteven Rostedt build $buildtype or $failed = 1; 9595f9b6cedSSteven Rostedt 9605f9b6cedSSteven Rostedt if ($type ne "build") { 9617faafbd6SSteven Rostedt dodie "Failed on build" if $failed; 9625f9b6cedSSteven Rostedt 9635f9b6cedSSteven Rostedt # Now boot the box 9645f9b6cedSSteven Rostedt get_grub_index; 9655f9b6cedSSteven Rostedt get_version; 9665f9b6cedSSteven Rostedt install; 9677faafbd6SSteven Rostedt 9687faafbd6SSteven Rostedt start_monitor; 9692b7d9b21SSteven Rostedt monitor or $failed = 1; 9705f9b6cedSSteven Rostedt 9715f9b6cedSSteven Rostedt if ($type ne "boot") { 9727faafbd6SSteven Rostedt dodie "Failed on boot" if $failed; 9735a391fbfSSteven Rostedt 9742b7d9b21SSteven Rostedt do_run_test or $failed = 1; 9755f9b6cedSSteven Rostedt } 9767faafbd6SSteven Rostedt end_monitor; 9775f9b6cedSSteven Rostedt } 9785f9b6cedSSteven Rostedt 9795f9b6cedSSteven Rostedt if ($failed) { 9800a05c769SSteven Rostedt $result = 0; 9815a391fbfSSteven Rostedt 9825a391fbfSSteven Rostedt # reboot the box to a good kernel 983a75fececSSteven Rostedt if ($type ne "build") { 984a75fececSSteven Rostedt doprint "Reboot and sleep $bisect_sleep_time seconds\n"; 9855a391fbfSSteven Rostedt reboot; 9867faafbd6SSteven Rostedt start_monitor; 987a75fececSSteven Rostedt wait_for_monitor $bisect_sleep_time; 9887faafbd6SSteven Rostedt end_monitor; 9895a391fbfSSteven Rostedt } 9905f9b6cedSSteven Rostedt } else { 9910a05c769SSteven Rostedt $result = 1; 9925f9b6cedSSteven Rostedt } 9930a05c769SSteven Rostedt $in_bisect = 0; 9940a05c769SSteven Rostedt 9950a05c769SSteven Rostedt return $result; 9960a05c769SSteven Rostedt} 9970a05c769SSteven Rostedt 9980a05c769SSteven Rostedtsub run_bisect { 9990a05c769SSteven Rostedt my ($type) = @_; 10000a05c769SSteven Rostedt my $buildtype = "oldconfig"; 10010a05c769SSteven Rostedt 10020a05c769SSteven Rostedt # We should have a minconfig to use? 10030a05c769SSteven Rostedt if (defined($minconfig)) { 10040a05c769SSteven Rostedt $buildtype = "useconfig:$minconfig"; 10050a05c769SSteven Rostedt } 10060a05c769SSteven Rostedt 10070a05c769SSteven Rostedt my $ret = run_bisect_test $type, $buildtype; 10080a05c769SSteven Rostedt 10095f9b6cedSSteven Rostedt 1010d6ce2a0bSSteven Rostedt # Are we looking for where it worked, not failed? 1011d6ce2a0bSSteven Rostedt if ($reverse_bisect) { 10120a05c769SSteven Rostedt $ret = !$ret; 1013d6ce2a0bSSteven Rostedt } 1014d6ce2a0bSSteven Rostedt 10150a05c769SSteven Rostedt if ($ret) { 10160a05c769SSteven Rostedt return "good"; 10170a05c769SSteven Rostedt } else { 10180a05c769SSteven Rostedt return "bad"; 10190a05c769SSteven Rostedt } 10205f9b6cedSSteven Rostedt} 10215f9b6cedSSteven Rostedt 10225f9b6cedSSteven Rostedtsub bisect { 10235f9b6cedSSteven Rostedt my ($i) = @_; 10245f9b6cedSSteven Rostedt 10255f9b6cedSSteven Rostedt my $result; 10265f9b6cedSSteven Rostedt 10275f9b6cedSSteven Rostedt die "BISECT_GOOD[$i] not defined\n" if (!defined($opt{"BISECT_GOOD[$i]"})); 10285f9b6cedSSteven Rostedt die "BISECT_BAD[$i] not defined\n" if (!defined($opt{"BISECT_BAD[$i]"})); 10295f9b6cedSSteven Rostedt die "BISECT_TYPE[$i] not defined\n" if (!defined($opt{"BISECT_TYPE[$i]"})); 10305f9b6cedSSteven Rostedt 10315f9b6cedSSteven Rostedt my $good = $opt{"BISECT_GOOD[$i]"}; 10325f9b6cedSSteven Rostedt my $bad = $opt{"BISECT_BAD[$i]"}; 10335f9b6cedSSteven Rostedt my $type = $opt{"BISECT_TYPE[$i]"}; 1034a75fececSSteven Rostedt my $start = $opt{"BISECT_START[$i]"}; 1035a75fececSSteven Rostedt my $replay = $opt{"BISECT_REPLAY[$i]"}; 10365f9b6cedSSteven Rostedt 1037a57419b3SSteven Rostedt # convert to true sha1's 1038a57419b3SSteven Rostedt $good = get_sha1($good); 1039a57419b3SSteven Rostedt $bad = get_sha1($bad); 1040a57419b3SSteven Rostedt 1041d6ce2a0bSSteven Rostedt if (defined($opt{"BISECT_REVERSE[$i]"}) && 1042d6ce2a0bSSteven Rostedt $opt{"BISECT_REVERSE[$i]"} == 1) { 1043d6ce2a0bSSteven Rostedt doprint "Performing a reverse bisect (bad is good, good is bad!)\n"; 1044d6ce2a0bSSteven Rostedt $reverse_bisect = 1; 1045d6ce2a0bSSteven Rostedt } else { 1046d6ce2a0bSSteven Rostedt $reverse_bisect = 0; 1047d6ce2a0bSSteven Rostedt } 1048d6ce2a0bSSteven Rostedt 10495a391fbfSSteven Rostedt # Can't have a test without having a test to run 10505a391fbfSSteven Rostedt if ($type eq "test" && !defined($run_test)) { 10515a391fbfSSteven Rostedt $type = "boot"; 10525a391fbfSSteven Rostedt } 10535a391fbfSSteven Rostedt 1054a75fececSSteven Rostedt my $check = $opt{"BISECT_CHECK[$i]"}; 1055a75fececSSteven Rostedt if (defined($check) && $check ne "0") { 1056a75fececSSteven Rostedt 1057a75fececSSteven Rostedt # get current HEAD 1058a57419b3SSteven Rostedt my $head = get_sha1("HEAD"); 1059a75fececSSteven Rostedt 1060a75fececSSteven Rostedt if ($check ne "good") { 1061a75fececSSteven Rostedt doprint "TESTING BISECT BAD [$bad]\n"; 1062a75fececSSteven Rostedt run_command "git checkout $bad" or 1063a75fececSSteven Rostedt die "Failed to checkout $bad"; 1064a75fececSSteven Rostedt 1065a75fececSSteven Rostedt $result = run_bisect $type; 1066a75fececSSteven Rostedt 1067a75fececSSteven Rostedt if ($result ne "bad") { 1068a75fececSSteven Rostedt fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0; 1069a75fececSSteven Rostedt } 1070a75fececSSteven Rostedt } 1071a75fececSSteven Rostedt 1072a75fececSSteven Rostedt if ($check ne "bad") { 1073a75fececSSteven Rostedt doprint "TESTING BISECT GOOD [$good]\n"; 1074a75fececSSteven Rostedt run_command "git checkout $good" or 1075a75fececSSteven Rostedt die "Failed to checkout $good"; 1076a75fececSSteven Rostedt 1077a75fececSSteven Rostedt $result = run_bisect $type; 1078a75fececSSteven Rostedt 1079a75fececSSteven Rostedt if ($result ne "good") { 1080a75fececSSteven Rostedt fail "Tested BISECT_GOOD [$good] and it failed" and return 0; 1081a75fececSSteven Rostedt } 1082a75fececSSteven Rostedt } 1083a75fececSSteven Rostedt 1084a75fececSSteven Rostedt # checkout where we started 1085a75fececSSteven Rostedt run_command "git checkout $head" or 1086a75fececSSteven Rostedt die "Failed to checkout $head"; 1087a75fececSSteven Rostedt } 1088a75fececSSteven Rostedt 1089a75fececSSteven Rostedt run_command "git bisect start" or 1090a75fececSSteven Rostedt dodie "could not start bisect"; 1091a75fececSSteven Rostedt 1092a75fececSSteven Rostedt run_command "git bisect good $good" or 1093a75fececSSteven Rostedt dodie "could not set bisect good to $good"; 1094a75fececSSteven Rostedt 1095a75fececSSteven Rostedt run_git_bisect "git bisect bad $bad" or 1096a75fececSSteven Rostedt dodie "could not set bisect bad to $bad"; 1097a75fececSSteven Rostedt 1098a75fececSSteven Rostedt if (defined($replay)) { 1099a75fececSSteven Rostedt run_command "git bisect replay $replay" or 1100a75fececSSteven Rostedt dodie "failed to run replay"; 1101a75fececSSteven Rostedt } 1102a75fececSSteven Rostedt 1103a75fececSSteven Rostedt if (defined($start)) { 1104a75fececSSteven Rostedt run_command "git checkout $start" or 1105a75fececSSteven Rostedt dodie "failed to checkout $start"; 1106a75fececSSteven Rostedt } 1107a75fececSSteven Rostedt 1108a75fececSSteven Rostedt my $test; 11095f9b6cedSSteven Rostedt do { 11105f9b6cedSSteven Rostedt $result = run_bisect $type; 1111a75fececSSteven Rostedt $test = run_git_bisect "git bisect $result"; 1112a75fececSSteven Rostedt } while ($test); 11135f9b6cedSSteven Rostedt 11145f9b6cedSSteven Rostedt run_command "git bisect log" or 11155f9b6cedSSteven Rostedt dodie "could not capture git bisect log"; 11165f9b6cedSSteven Rostedt 11175f9b6cedSSteven Rostedt run_command "git bisect reset" or 11185f9b6cedSSteven Rostedt dodie "could not reset git bisect"; 11195f9b6cedSSteven Rostedt 11205f9b6cedSSteven Rostedt doprint "Bad commit was [$bisect_bad]\n"; 11215f9b6cedSSteven Rostedt 11220a05c769SSteven Rostedt success $i; 11230a05c769SSteven Rostedt} 11240a05c769SSteven Rostedt 11250a05c769SSteven Rostedtmy %config_ignore; 11260a05c769SSteven Rostedtmy %config_set; 11270a05c769SSteven Rostedt 11280a05c769SSteven Rostedtmy %config_list; 11290a05c769SSteven Rostedtmy %null_config; 11300a05c769SSteven Rostedt 11310a05c769SSteven Rostedtmy %dependency; 11320a05c769SSteven Rostedt 11330a05c769SSteven Rostedtsub process_config_ignore { 11340a05c769SSteven Rostedt my ($config) = @_; 11350a05c769SSteven Rostedt 11360a05c769SSteven Rostedt open (IN, $config) 11370a05c769SSteven Rostedt or dodie "Failed to read $config"; 11380a05c769SSteven Rostedt 11390a05c769SSteven Rostedt while (<IN>) { 11400a05c769SSteven Rostedt if (/^(.*?(CONFIG\S*)(=.*| is not set))/) { 11410a05c769SSteven Rostedt $config_ignore{$2} = $1; 11420a05c769SSteven Rostedt } 11430a05c769SSteven Rostedt } 11440a05c769SSteven Rostedt 11450a05c769SSteven Rostedt close(IN); 11460a05c769SSteven Rostedt} 11470a05c769SSteven Rostedt 11480a05c769SSteven Rostedtsub read_current_config { 11490a05c769SSteven Rostedt my ($config_ref) = @_; 11500a05c769SSteven Rostedt 11510a05c769SSteven Rostedt %{$config_ref} = (); 11520a05c769SSteven Rostedt undef %{$config_ref}; 11530a05c769SSteven Rostedt 11540a05c769SSteven Rostedt my @key = keys %{$config_ref}; 11550a05c769SSteven Rostedt if ($#key >= 0) { 11560a05c769SSteven Rostedt print "did not delete!\n"; 11570a05c769SSteven Rostedt exit; 11580a05c769SSteven Rostedt } 11590a05c769SSteven Rostedt open (IN, "$output_config"); 11600a05c769SSteven Rostedt 11610a05c769SSteven Rostedt while (<IN>) { 11620a05c769SSteven Rostedt if (/^(CONFIG\S+)=(.*)/) { 11630a05c769SSteven Rostedt ${$config_ref}{$1} = $2; 11640a05c769SSteven Rostedt } 11650a05c769SSteven Rostedt } 11660a05c769SSteven Rostedt close(IN); 11670a05c769SSteven Rostedt} 11680a05c769SSteven Rostedt 11690a05c769SSteven Rostedtsub get_dependencies { 11700a05c769SSteven Rostedt my ($config) = @_; 11710a05c769SSteven Rostedt 11720a05c769SSteven Rostedt my $arr = $dependency{$config}; 11730a05c769SSteven Rostedt if (!defined($arr)) { 11740a05c769SSteven Rostedt return (); 11750a05c769SSteven Rostedt } 11760a05c769SSteven Rostedt 11770a05c769SSteven Rostedt my @deps = @{$arr}; 11780a05c769SSteven Rostedt 11790a05c769SSteven Rostedt foreach my $dep (@{$arr}) { 11800a05c769SSteven Rostedt print "ADD DEP $dep\n"; 11810a05c769SSteven Rostedt @deps = (@deps, get_dependencies $dep); 11820a05c769SSteven Rostedt } 11830a05c769SSteven Rostedt 11840a05c769SSteven Rostedt return @deps; 11850a05c769SSteven Rostedt} 11860a05c769SSteven Rostedt 11870a05c769SSteven Rostedtsub create_config { 11880a05c769SSteven Rostedt my @configs = @_; 11890a05c769SSteven Rostedt 11900a05c769SSteven Rostedt open(OUT, ">$output_config") or dodie "Can not write to $output_config"; 11910a05c769SSteven Rostedt 11920a05c769SSteven Rostedt foreach my $config (@configs) { 11930a05c769SSteven Rostedt print OUT "$config_set{$config}\n"; 11940a05c769SSteven Rostedt my @deps = get_dependencies $config; 11950a05c769SSteven Rostedt foreach my $dep (@deps) { 11960a05c769SSteven Rostedt print OUT "$config_set{$dep}\n"; 11970a05c769SSteven Rostedt } 11980a05c769SSteven Rostedt } 11990a05c769SSteven Rostedt 12000a05c769SSteven Rostedt foreach my $config (keys %config_ignore) { 12010a05c769SSteven Rostedt print OUT "$config_ignore{$config}\n"; 12020a05c769SSteven Rostedt } 12030a05c769SSteven Rostedt close(OUT); 12040a05c769SSteven Rostedt 12050a05c769SSteven Rostedt# exit; 12060a05c769SSteven Rostedt run_command "$make oldnoconfig" or 12070a05c769SSteven Rostedt dodie "failed make config oldconfig"; 12080a05c769SSteven Rostedt 12090a05c769SSteven Rostedt} 12100a05c769SSteven Rostedt 12110a05c769SSteven Rostedtsub compare_configs { 12120a05c769SSteven Rostedt my (%a, %b) = @_; 12130a05c769SSteven Rostedt 12140a05c769SSteven Rostedt foreach my $item (keys %a) { 12150a05c769SSteven Rostedt if (!defined($b{$item})) { 12160a05c769SSteven Rostedt print "diff $item\n"; 12170a05c769SSteven Rostedt return 1; 12180a05c769SSteven Rostedt } 12190a05c769SSteven Rostedt delete $b{$item}; 12200a05c769SSteven Rostedt } 12210a05c769SSteven Rostedt 12220a05c769SSteven Rostedt my @keys = keys %b; 12230a05c769SSteven Rostedt if ($#keys) { 12240a05c769SSteven Rostedt print "diff2 $keys[0]\n"; 12250a05c769SSteven Rostedt } 12260a05c769SSteven Rostedt return -1 if ($#keys >= 0); 12270a05c769SSteven Rostedt 12280a05c769SSteven Rostedt return 0; 12290a05c769SSteven Rostedt} 12300a05c769SSteven Rostedt 12310a05c769SSteven Rostedtsub run_config_bisect_test { 12320a05c769SSteven Rostedt my ($type) = @_; 12330a05c769SSteven Rostedt 12340a05c769SSteven Rostedt return run_bisect_test $type, "oldconfig"; 12350a05c769SSteven Rostedt} 12360a05c769SSteven Rostedt 12370a05c769SSteven Rostedtsub process_passed { 12380a05c769SSteven Rostedt my (%configs) = @_; 12390a05c769SSteven Rostedt 12400a05c769SSteven Rostedt doprint "These configs had no failure: (Enabling them for further compiles)\n"; 12410a05c769SSteven Rostedt # Passed! All these configs are part of a good compile. 12420a05c769SSteven Rostedt # Add them to the min options. 12430a05c769SSteven Rostedt foreach my $config (keys %configs) { 12440a05c769SSteven Rostedt if (defined($config_list{$config})) { 12450a05c769SSteven Rostedt doprint " removing $config\n"; 12460a05c769SSteven Rostedt $config_ignore{$config} = $config_list{$config}; 12470a05c769SSteven Rostedt delete $config_list{$config}; 12480a05c769SSteven Rostedt } 12490a05c769SSteven Rostedt } 12500a05c769SSteven Rostedt} 12510a05c769SSteven Rostedt 12520a05c769SSteven Rostedtsub process_failed { 12530a05c769SSteven Rostedt my ($config) = @_; 12540a05c769SSteven Rostedt 12550a05c769SSteven Rostedt doprint "\n\n***************************************\n"; 12560a05c769SSteven Rostedt doprint "Found bad config: $config\n"; 12570a05c769SSteven Rostedt doprint "***************************************\n\n"; 12580a05c769SSteven Rostedt} 12590a05c769SSteven Rostedt 12600a05c769SSteven Rostedtsub run_config_bisect { 12610a05c769SSteven Rostedt 12620a05c769SSteven Rostedt my @start_list = keys %config_list; 12630a05c769SSteven Rostedt 12640a05c769SSteven Rostedt if ($#start_list < 0) { 12650a05c769SSteven Rostedt doprint "No more configs to test!!!\n"; 12660a05c769SSteven Rostedt return -1; 12670a05c769SSteven Rostedt } 12680a05c769SSteven Rostedt 12690a05c769SSteven Rostedt doprint "***** RUN TEST ***\n"; 12700a05c769SSteven Rostedt my $type = $opt{"CONFIG_BISECT_TYPE[$iteration]"}; 12710a05c769SSteven Rostedt my $ret; 12720a05c769SSteven Rostedt my %current_config; 12730a05c769SSteven Rostedt 12740a05c769SSteven Rostedt my $count = $#start_list + 1; 12750a05c769SSteven Rostedt doprint " $count configs to test\n"; 12760a05c769SSteven Rostedt 12770a05c769SSteven Rostedt my $half = int($#start_list / 2); 12780a05c769SSteven Rostedt 12790a05c769SSteven Rostedt do { 12800a05c769SSteven Rostedt my @tophalf = @start_list[0 .. $half]; 12810a05c769SSteven Rostedt 12820a05c769SSteven Rostedt create_config @tophalf; 12830a05c769SSteven Rostedt read_current_config \%current_config; 12840a05c769SSteven Rostedt 12850a05c769SSteven Rostedt $count = $#tophalf + 1; 12860a05c769SSteven Rostedt doprint "Testing $count configs\n"; 12870a05c769SSteven Rostedt my $found = 0; 12880a05c769SSteven Rostedt # make sure we test something 12890a05c769SSteven Rostedt foreach my $config (@tophalf) { 12900a05c769SSteven Rostedt if (defined($current_config{$config})) { 12910a05c769SSteven Rostedt logit " $config\n"; 12920a05c769SSteven Rostedt $found = 1; 12930a05c769SSteven Rostedt } 12940a05c769SSteven Rostedt } 12950a05c769SSteven Rostedt if (!$found) { 12960a05c769SSteven Rostedt # try the other half 12970a05c769SSteven Rostedt doprint "Top half produced no set configs, trying bottom half\n"; 12980a05c769SSteven Rostedt @tophalf = @start_list[$half .. $#start_list]; 12990a05c769SSteven Rostedt create_config @tophalf; 13000a05c769SSteven Rostedt read_current_config \%current_config; 13010a05c769SSteven Rostedt foreach my $config (@tophalf) { 13020a05c769SSteven Rostedt if (defined($current_config{$config})) { 13030a05c769SSteven Rostedt logit " $config\n"; 13040a05c769SSteven Rostedt $found = 1; 13050a05c769SSteven Rostedt } 13060a05c769SSteven Rostedt } 13070a05c769SSteven Rostedt if (!$found) { 13080a05c769SSteven Rostedt doprint "Failed: Can't make new config with current configs\n"; 13090a05c769SSteven Rostedt foreach my $config (@start_list) { 13100a05c769SSteven Rostedt doprint " CONFIG: $config\n"; 13110a05c769SSteven Rostedt } 13120a05c769SSteven Rostedt return -1; 13130a05c769SSteven Rostedt } 13140a05c769SSteven Rostedt $count = $#tophalf + 1; 13150a05c769SSteven Rostedt doprint "Testing $count configs\n"; 13160a05c769SSteven Rostedt } 13170a05c769SSteven Rostedt 13180a05c769SSteven Rostedt $ret = run_config_bisect_test $type; 13190a05c769SSteven Rostedt 13200a05c769SSteven Rostedt if ($ret) { 13210a05c769SSteven Rostedt process_passed %current_config; 13220a05c769SSteven Rostedt return 0; 13230a05c769SSteven Rostedt } 13240a05c769SSteven Rostedt 13250a05c769SSteven Rostedt doprint "This config had a failure.\n"; 13260a05c769SSteven Rostedt doprint "Removing these configs that were not set in this config:\n"; 13270a05c769SSteven Rostedt 13280a05c769SSteven Rostedt # A config exists in this group that was bad. 13290a05c769SSteven Rostedt foreach my $config (keys %config_list) { 13300a05c769SSteven Rostedt if (!defined($current_config{$config})) { 13310a05c769SSteven Rostedt doprint " removing $config\n"; 13320a05c769SSteven Rostedt delete $config_list{$config}; 13330a05c769SSteven Rostedt } 13340a05c769SSteven Rostedt } 13350a05c769SSteven Rostedt 13360a05c769SSteven Rostedt @start_list = @tophalf; 13370a05c769SSteven Rostedt 13380a05c769SSteven Rostedt if ($#start_list == 0) { 13390a05c769SSteven Rostedt process_failed $start_list[0]; 13400a05c769SSteven Rostedt return 1; 13410a05c769SSteven Rostedt } 13420a05c769SSteven Rostedt 13430a05c769SSteven Rostedt # remove half the configs we are looking at and see if 13440a05c769SSteven Rostedt # they are good. 13450a05c769SSteven Rostedt $half = int($#start_list / 2); 13460a05c769SSteven Rostedt } while ($half > 0); 13470a05c769SSteven Rostedt 13480a05c769SSteven Rostedt # we found a single config, try it again 13490a05c769SSteven Rostedt my @tophalf = @start_list[0 .. 0]; 13500a05c769SSteven Rostedt 13510a05c769SSteven Rostedt $ret = run_config_bisect_test $type; 13520a05c769SSteven Rostedt if ($ret) { 13530a05c769SSteven Rostedt process_passed %current_config; 13540a05c769SSteven Rostedt return 0; 13550a05c769SSteven Rostedt } 13560a05c769SSteven Rostedt 13570a05c769SSteven Rostedt process_failed $start_list[0]; 13580a05c769SSteven Rostedt return 1; 13590a05c769SSteven Rostedt} 13600a05c769SSteven Rostedt 13610a05c769SSteven Rostedtsub config_bisect { 13620a05c769SSteven Rostedt my ($i) = @_; 13630a05c769SSteven Rostedt 13640a05c769SSteven Rostedt my $start_config = $opt{"CONFIG_BISECT[$i]"}; 13650a05c769SSteven Rostedt 13660a05c769SSteven Rostedt my $tmpconfig = "$tmpdir/use_config"; 13670a05c769SSteven Rostedt 13680a05c769SSteven Rostedt # Make the file with the bad config and the min config 13690a05c769SSteven Rostedt if (defined($minconfig)) { 13700a05c769SSteven Rostedt # read the min config for things to ignore 13710a05c769SSteven Rostedt run_command "cp $minconfig $tmpconfig" or 13720a05c769SSteven Rostedt dodie "failed to copy $minconfig to $tmpconfig"; 13730a05c769SSteven Rostedt } else { 13740a05c769SSteven Rostedt unlink $tmpconfig; 13750a05c769SSteven Rostedt } 13760a05c769SSteven Rostedt 13770a05c769SSteven Rostedt # Add other configs 13780a05c769SSteven Rostedt if (defined($addconfig)) { 13790a05c769SSteven Rostedt run_command "cat $addconfig >> $tmpconfig" or 13800a05c769SSteven Rostedt dodie "failed to append $addconfig"; 13810a05c769SSteven Rostedt } 13820a05c769SSteven Rostedt 13830a05c769SSteven Rostedt my $defconfig = ""; 13840a05c769SSteven Rostedt if (-f $tmpconfig) { 13850a05c769SSteven Rostedt $defconfig = "KCONFIG_ALLCONFIG=$tmpconfig"; 13860a05c769SSteven Rostedt process_config_ignore $tmpconfig; 13870a05c769SSteven Rostedt } 13880a05c769SSteven Rostedt 13890a05c769SSteven Rostedt # now process the start config 13900a05c769SSteven Rostedt run_command "cp $start_config $output_config" or 13910a05c769SSteven Rostedt dodie "failed to copy $start_config to $output_config"; 13920a05c769SSteven Rostedt 13930a05c769SSteven Rostedt # read directly what we want to check 13940a05c769SSteven Rostedt my %config_check; 13950a05c769SSteven Rostedt open (IN, $output_config) 13960a05c769SSteven Rostedt or dodie "faied to open $output_config"; 13970a05c769SSteven Rostedt 13980a05c769SSteven Rostedt while (<IN>) { 13990a05c769SSteven Rostedt if (/^((CONFIG\S*)=.*)/) { 14000a05c769SSteven Rostedt $config_check{$2} = $1; 14010a05c769SSteven Rostedt } 14020a05c769SSteven Rostedt } 14030a05c769SSteven Rostedt close(IN); 14040a05c769SSteven Rostedt 14050a05c769SSteven Rostedt # Now run oldconfig with the minconfig (and addconfigs) 14060a05c769SSteven Rostedt run_command "$defconfig $make oldnoconfig" or 14070a05c769SSteven Rostedt dodie "failed make config oldconfig"; 14080a05c769SSteven Rostedt 14090a05c769SSteven Rostedt # check to see what we lost (or gained) 14100a05c769SSteven Rostedt open (IN, $output_config) 14110a05c769SSteven Rostedt or dodie "Failed to read $start_config"; 14120a05c769SSteven Rostedt 14130a05c769SSteven Rostedt my %removed_configs; 14140a05c769SSteven Rostedt my %added_configs; 14150a05c769SSteven Rostedt 14160a05c769SSteven Rostedt while (<IN>) { 14170a05c769SSteven Rostedt if (/^((CONFIG\S*)=.*)/) { 14180a05c769SSteven Rostedt # save off all options 14190a05c769SSteven Rostedt $config_set{$2} = $1; 14200a05c769SSteven Rostedt if (defined($config_check{$2})) { 14210a05c769SSteven Rostedt if (defined($config_ignore{$2})) { 14220a05c769SSteven Rostedt $removed_configs{$2} = $1; 14230a05c769SSteven Rostedt } else { 14240a05c769SSteven Rostedt $config_list{$2} = $1; 14250a05c769SSteven Rostedt } 14260a05c769SSteven Rostedt } elsif (!defined($config_ignore{$2})) { 14270a05c769SSteven Rostedt $added_configs{$2} = $1; 14280a05c769SSteven Rostedt $config_list{$2} = $1; 14290a05c769SSteven Rostedt } 14300a05c769SSteven Rostedt } 14310a05c769SSteven Rostedt } 14320a05c769SSteven Rostedt close(IN); 14330a05c769SSteven Rostedt 14340a05c769SSteven Rostedt my @confs = keys %removed_configs; 14350a05c769SSteven Rostedt if ($#confs >= 0) { 14360a05c769SSteven Rostedt doprint "Configs overridden by default configs and removed from check:\n"; 14370a05c769SSteven Rostedt foreach my $config (@confs) { 14380a05c769SSteven Rostedt doprint " $config\n"; 14390a05c769SSteven Rostedt } 14400a05c769SSteven Rostedt } 14410a05c769SSteven Rostedt @confs = keys %added_configs; 14420a05c769SSteven Rostedt if ($#confs >= 0) { 14430a05c769SSteven Rostedt doprint "Configs appearing in make oldconfig and added:\n"; 14440a05c769SSteven Rostedt foreach my $config (@confs) { 14450a05c769SSteven Rostedt doprint " $config\n"; 14460a05c769SSteven Rostedt } 14470a05c769SSteven Rostedt } 14480a05c769SSteven Rostedt 14490a05c769SSteven Rostedt my %config_test; 14500a05c769SSteven Rostedt my $once = 0; 14510a05c769SSteven Rostedt 14520a05c769SSteven Rostedt # Sometimes kconfig does weird things. We must make sure 14530a05c769SSteven Rostedt # that the config we autocreate has everything we need 14540a05c769SSteven Rostedt # to test, otherwise we may miss testing configs, or 14550a05c769SSteven Rostedt # may not be able to create a new config. 14560a05c769SSteven Rostedt # Here we create a config with everything set. 14570a05c769SSteven Rostedt create_config (keys %config_list); 14580a05c769SSteven Rostedt read_current_config \%config_test; 14590a05c769SSteven Rostedt foreach my $config (keys %config_list) { 14600a05c769SSteven Rostedt if (!defined($config_test{$config})) { 14610a05c769SSteven Rostedt if (!$once) { 14620a05c769SSteven Rostedt $once = 1; 14630a05c769SSteven Rostedt doprint "Configs not produced by kconfig (will not be checked):\n"; 14640a05c769SSteven Rostedt } 14650a05c769SSteven Rostedt doprint " $config\n"; 14660a05c769SSteven Rostedt delete $config_list{$config}; 14670a05c769SSteven Rostedt } 14680a05c769SSteven Rostedt } 14690a05c769SSteven Rostedt my $ret; 14700a05c769SSteven Rostedt do { 14710a05c769SSteven Rostedt $ret = run_config_bisect; 14720a05c769SSteven Rostedt } while (!$ret); 14730a05c769SSteven Rostedt 14740a05c769SSteven Rostedt return $ret if ($ret < 0); 14755f9b6cedSSteven Rostedt 14765f9b6cedSSteven Rostedt success $i; 14775f9b6cedSSteven Rostedt} 14785f9b6cedSSteven Rostedt 14796c5ee0beSSteven Rostedtsub patchcheck { 14806c5ee0beSSteven Rostedt my ($i) = @_; 14816c5ee0beSSteven Rostedt 14826c5ee0beSSteven Rostedt die "PATCHCHECK_START[$i] not defined\n" 14836c5ee0beSSteven Rostedt if (!defined($opt{"PATCHCHECK_START[$i]"})); 14846c5ee0beSSteven Rostedt die "PATCHCHECK_TYPE[$i] not defined\n" 14856c5ee0beSSteven Rostedt if (!defined($opt{"PATCHCHECK_TYPE[$i]"})); 14866c5ee0beSSteven Rostedt 14876c5ee0beSSteven Rostedt my $start = $opt{"PATCHCHECK_START[$i]"}; 14886c5ee0beSSteven Rostedt 14896c5ee0beSSteven Rostedt my $end = "HEAD"; 14906c5ee0beSSteven Rostedt if (defined($opt{"PATCHCHECK_END[$i]"})) { 14916c5ee0beSSteven Rostedt $end = $opt{"PATCHCHECK_END[$i]"}; 14926c5ee0beSSteven Rostedt } 14936c5ee0beSSteven Rostedt 1494a57419b3SSteven Rostedt # Get the true sha1's since we can use things like HEAD~3 1495a57419b3SSteven Rostedt $start = get_sha1($start); 1496a57419b3SSteven Rostedt $end = get_sha1($end); 1497a57419b3SSteven Rostedt 14986c5ee0beSSteven Rostedt my $type = $opt{"PATCHCHECK_TYPE[$i]"}; 14996c5ee0beSSteven Rostedt 15006c5ee0beSSteven Rostedt # Can't have a test without having a test to run 15016c5ee0beSSteven Rostedt if ($type eq "test" && !defined($run_test)) { 15026c5ee0beSSteven Rostedt $type = "boot"; 15036c5ee0beSSteven Rostedt } 15046c5ee0beSSteven Rostedt 15056c5ee0beSSteven Rostedt open (IN, "git log --pretty=oneline $end|") or 15066c5ee0beSSteven Rostedt dodie "could not get git list"; 15076c5ee0beSSteven Rostedt 15086c5ee0beSSteven Rostedt my @list; 15096c5ee0beSSteven Rostedt 15106c5ee0beSSteven Rostedt while (<IN>) { 15116c5ee0beSSteven Rostedt chomp; 15126c5ee0beSSteven Rostedt $list[$#list+1] = $_; 15136c5ee0beSSteven Rostedt last if (/^$start/); 15146c5ee0beSSteven Rostedt } 15156c5ee0beSSteven Rostedt close(IN); 15166c5ee0beSSteven Rostedt 15176c5ee0beSSteven Rostedt if ($list[$#list] !~ /^$start/) { 15182b7d9b21SSteven Rostedt fail "SHA1 $start not found"; 15196c5ee0beSSteven Rostedt } 15206c5ee0beSSteven Rostedt 15216c5ee0beSSteven Rostedt # go backwards in the list 15226c5ee0beSSteven Rostedt @list = reverse @list; 15236c5ee0beSSteven Rostedt 15246c5ee0beSSteven Rostedt my $save_clean = $noclean; 15256c5ee0beSSteven Rostedt 15266c5ee0beSSteven Rostedt $in_patchcheck = 1; 15276c5ee0beSSteven Rostedt foreach my $item (@list) { 15286c5ee0beSSteven Rostedt my $sha1 = $item; 15296c5ee0beSSteven Rostedt $sha1 =~ s/^([[:xdigit:]]+).*/$1/; 15306c5ee0beSSteven Rostedt 15316c5ee0beSSteven Rostedt doprint "\nProcessing commit $item\n\n"; 15326c5ee0beSSteven Rostedt 15336c5ee0beSSteven Rostedt run_command "git checkout $sha1" or 15346c5ee0beSSteven Rostedt die "Failed to checkout $sha1"; 15356c5ee0beSSteven Rostedt 15366c5ee0beSSteven Rostedt # only clean on the first and last patch 15376c5ee0beSSteven Rostedt if ($item eq $list[0] || 15386c5ee0beSSteven Rostedt $item eq $list[$#list]) { 15396c5ee0beSSteven Rostedt $noclean = $save_clean; 15406c5ee0beSSteven Rostedt } else { 15416c5ee0beSSteven Rostedt $noclean = 1; 15426c5ee0beSSteven Rostedt } 15436c5ee0beSSteven Rostedt 15446c5ee0beSSteven Rostedt if (defined($minconfig)) { 15452b7d9b21SSteven Rostedt build "useconfig:$minconfig" or return 0; 15466c5ee0beSSteven Rostedt } else { 15476c5ee0beSSteven Rostedt # ?? no config to use? 15482b7d9b21SSteven Rostedt build "oldconfig" or return 0; 15496c5ee0beSSteven Rostedt } 15506c5ee0beSSteven Rostedt 15512b7d9b21SSteven Rostedt check_buildlog $sha1 or return 0; 15526c5ee0beSSteven Rostedt 15536c5ee0beSSteven Rostedt next if ($type eq "build"); 15546c5ee0beSSteven Rostedt 15556c5ee0beSSteven Rostedt get_grub_index; 15566c5ee0beSSteven Rostedt get_version; 15576c5ee0beSSteven Rostedt install; 15586c5ee0beSSteven Rostedt 15597faafbd6SSteven Rostedt my $failed = 0; 15607faafbd6SSteven Rostedt 15617faafbd6SSteven Rostedt start_monitor; 15627faafbd6SSteven Rostedt monitor or $failed = 1; 15637faafbd6SSteven Rostedt 15647faafbd6SSteven Rostedt if (!$failed && $type ne "boot"){ 15657faafbd6SSteven Rostedt do_run_test or $failed = 1; 15667faafbd6SSteven Rostedt } 15677faafbd6SSteven Rostedt end_monitor; 15687faafbd6SSteven Rostedt return 0 if ($failed); 15697faafbd6SSteven Rostedt 15706c5ee0beSSteven Rostedt } 15716c5ee0beSSteven Rostedt $in_patchcheck = 0; 15726c5ee0beSSteven Rostedt success $i; 15732b7d9b21SSteven Rostedt 15742b7d9b21SSteven Rostedt return 1; 15756c5ee0beSSteven Rostedt} 15766c5ee0beSSteven Rostedt 15772545eb61SSteven Rostedtread_config $ARGV[0]; 15782545eb61SSteven Rostedt 15792545eb61SSteven Rostedt# mandatory configs 15802545eb61SSteven Rostedtdie "MACHINE not defined\n" if (!defined($opt{"MACHINE"})); 15812545eb61SSteven Rostedtdie "SSH_USER not defined\n" if (!defined($opt{"SSH_USER"})); 15822545eb61SSteven Rostedtdie "BUILD_DIR not defined\n" if (!defined($opt{"BUILD_DIR"})); 15832545eb61SSteven Rostedtdie "OUTPUT_DIR not defined\n" if (!defined($opt{"OUTPUT_DIR"})); 15842545eb61SSteven Rostedtdie "BUILD_TARGET not defined\n" if (!defined($opt{"BUILD_TARGET"})); 158575c3fda7SSteven Rostedtdie "TARGET_IMAGE not defined\n" if (!defined($opt{"TARGET_IMAGE"})); 15862545eb61SSteven Rostedtdie "POWER_CYCLE not defined\n" if (!defined($opt{"POWER_CYCLE"})); 15872545eb61SSteven Rostedtdie "CONSOLE not defined\n" if (!defined($opt{"CONSOLE"})); 15882545eb61SSteven Rostedtdie "LOCALVERSION not defined\n" if (!defined($opt{"LOCALVERSION"})); 15892545eb61SSteven Rostedt 15902b7d9b21SSteven Rostedtif ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) { 15912b7d9b21SSteven Rostedt unlink $opt{"LOG_FILE"}; 15922b7d9b21SSteven Rostedt} 15932545eb61SSteven Rostedt 15942b7d9b21SSteven Rostedtdoprint "\n\nSTARTING AUTOMATED TESTS\n\n"; 15952b7d9b21SSteven Rostedt 1596a57419b3SSteven Rostedtfor (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) { 1597a57419b3SSteven Rostedt 1598a57419b3SSteven Rostedt if (!$i) { 1599a57419b3SSteven Rostedt doprint "DEFAULT OPTIONS:\n"; 1600a57419b3SSteven Rostedt } else { 1601a57419b3SSteven Rostedt doprint "\nTEST $i OPTIONS"; 1602a57419b3SSteven Rostedt if (defined($repeat_tests{$i})) { 1603a57419b3SSteven Rostedt $repeat = $repeat_tests{$i}; 1604a57419b3SSteven Rostedt doprint " ITERATE $repeat"; 1605a57419b3SSteven Rostedt } 1606a57419b3SSteven Rostedt doprint "\n"; 1607a57419b3SSteven Rostedt } 1608a57419b3SSteven Rostedt 16092b7d9b21SSteven Rostedt foreach my $option (sort keys %opt) { 1610a57419b3SSteven Rostedt 1611a57419b3SSteven Rostedt if ($option =~ /\[(\d+)\]$/) { 1612a57419b3SSteven Rostedt next if ($i != $1); 1613a57419b3SSteven Rostedt } else { 1614a57419b3SSteven Rostedt next if ($i); 1615a57419b3SSteven Rostedt } 1616a57419b3SSteven Rostedt 16172b7d9b21SSteven Rostedt doprint "$option = $opt{$option}\n"; 16182b7d9b21SSteven Rostedt } 1619a57419b3SSteven Rostedt} 16202545eb61SSteven Rostedt 1621a75fececSSteven Rostedtsub set_test_option { 16225a391fbfSSteven Rostedt my ($name, $i) = @_; 16235a391fbfSSteven Rostedt 16245a391fbfSSteven Rostedt my $option = "$name\[$i\]"; 16255a391fbfSSteven Rostedt 16265a391fbfSSteven Rostedt if (defined($opt{$option})) { 16275a391fbfSSteven Rostedt return $opt{$option}; 16285a391fbfSSteven Rostedt } 16295a391fbfSSteven Rostedt 1630a57419b3SSteven Rostedt foreach my $test (keys %repeat_tests) { 1631a57419b3SSteven Rostedt if ($i >= $test && 1632a57419b3SSteven Rostedt $i < $test + $repeat_tests{$test}) { 1633a57419b3SSteven Rostedt $option = "$name\[$test\]"; 1634a57419b3SSteven Rostedt if (defined($opt{$option})) { 1635a57419b3SSteven Rostedt return $opt{$option}; 1636a57419b3SSteven Rostedt } 1637a57419b3SSteven Rostedt } 1638a57419b3SSteven Rostedt } 1639a57419b3SSteven Rostedt 16405a391fbfSSteven Rostedt if (defined($opt{$name})) { 16415a391fbfSSteven Rostedt return $opt{$name}; 16425a391fbfSSteven Rostedt } 16435a391fbfSSteven Rostedt 16445a391fbfSSteven Rostedt return undef; 16455a391fbfSSteven Rostedt} 16465a391fbfSSteven Rostedt 16472545eb61SSteven Rostedt# First we need to do is the builds 1648a75fececSSteven Rostedtfor (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) { 16492545eb61SSteven Rostedt 1650576f627cSSteven Rostedt $iteration = $i; 1651576f627cSSteven Rostedt 1652a75fececSSteven Rostedt my $makecmd = set_test_option("MAKE_CMD", $i); 1653a75fececSSteven Rostedt 1654a75fececSSteven Rostedt $machine = set_test_option("MACHINE", $i); 1655e48c5293SSteven Rostedt $ssh_user = set_test_option("SSH_USER", $i); 1656a75fececSSteven Rostedt $tmpdir = set_test_option("TMP_DIR", $i); 1657a75fececSSteven Rostedt $outputdir = set_test_option("OUTPUT_DIR", $i); 1658a75fececSSteven Rostedt $builddir = set_test_option("BUILD_DIR", $i); 1659a75fececSSteven Rostedt $test_type = set_test_option("TEST_TYPE", $i); 1660a75fececSSteven Rostedt $build_type = set_test_option("BUILD_TYPE", $i); 1661a75fececSSteven Rostedt $build_options = set_test_option("BUILD_OPTIONS", $i); 1662a75fececSSteven Rostedt $power_cycle = set_test_option("POWER_CYCLE", $i); 1663e48c5293SSteven Rostedt $reboot = set_test_option("REBOOT", $i); 1664a75fececSSteven Rostedt $noclean = set_test_option("BUILD_NOCLEAN", $i); 1665a75fececSSteven Rostedt $minconfig = set_test_option("MIN_CONFIG", $i); 1666a75fececSSteven Rostedt $run_test = set_test_option("TEST", $i); 1667a75fececSSteven Rostedt $addconfig = set_test_option("ADD_CONFIG", $i); 1668a75fececSSteven Rostedt $reboot_type = set_test_option("REBOOT_TYPE", $i); 1669a75fececSSteven Rostedt $grub_menu = set_test_option("GRUB_MENU", $i); 16708b37ca8cSSteven Rostedt $post_install = set_test_option("POST_INSTALL", $i); 1671a75fececSSteven Rostedt $reboot_script = set_test_option("REBOOT_SCRIPT", $i); 1672a75fececSSteven Rostedt $reboot_on_error = set_test_option("REBOOT_ON_ERROR", $i); 1673a75fececSSteven Rostedt $poweroff_on_error = set_test_option("POWEROFF_ON_ERROR", $i); 1674a75fececSSteven Rostedt $die_on_failure = set_test_option("DIE_ON_FAILURE", $i); 1675a75fececSSteven Rostedt $power_off = set_test_option("POWER_OFF", $i); 1676576f627cSSteven Rostedt $powercycle_after_reboot = set_test_option("POWERCYCLE_AFTER_REBOOT", $i); 1677576f627cSSteven Rostedt $poweroff_after_halt = set_test_option("POWEROFF_AFTER_HALT", $i); 1678a75fececSSteven Rostedt $sleep_time = set_test_option("SLEEP_TIME", $i); 1679a75fececSSteven Rostedt $bisect_sleep_time = set_test_option("BISECT_SLEEP_TIME", $i); 1680a75fececSSteven Rostedt $store_failures = set_test_option("STORE_FAILURES", $i); 1681a75fececSSteven Rostedt $timeout = set_test_option("TIMEOUT", $i); 1682a75fececSSteven Rostedt $booted_timeout = set_test_option("BOOTED_TIMEOUT", $i); 1683a75fececSSteven Rostedt $console = set_test_option("CONSOLE", $i); 1684a75fececSSteven Rostedt $success_line = set_test_option("SUCCESS_LINE", $i); 1685a75fececSSteven Rostedt $build_target = set_test_option("BUILD_TARGET", $i); 1686e48c5293SSteven Rostedt $ssh_exec = set_test_option("SSH_EXEC", $i); 1687e48c5293SSteven Rostedt $scp_to_target = set_test_option("SCP_TO_TARGET", $i); 1688a75fececSSteven Rostedt $target_image = set_test_option("TARGET_IMAGE", $i); 1689a75fececSSteven Rostedt $localversion = set_test_option("LOCALVERSION", $i); 1690a75fececSSteven Rostedt 1691a75fececSSteven Rostedt chdir $builddir || die "can't change directory to $builddir"; 1692a75fececSSteven Rostedt 1693a75fececSSteven Rostedt if (!-d $tmpdir) { 1694a75fececSSteven Rostedt mkpath($tmpdir) or 1695a75fececSSteven Rostedt die "can't create $tmpdir"; 1696a75fececSSteven Rostedt } 1697a75fececSSteven Rostedt 1698e48c5293SSteven Rostedt $ENV{"SSH_USER"} = $ssh_user; 1699e48c5293SSteven Rostedt $ENV{"MACHINE"} = $machine; 1700e48c5293SSteven Rostedt 1701a75fececSSteven Rostedt $target = "$ssh_user\@$machine"; 1702a75fececSSteven Rostedt 1703a75fececSSteven Rostedt $buildlog = "$tmpdir/buildlog-$machine"; 1704a75fececSSteven Rostedt $dmesg = "$tmpdir/dmesg-$machine"; 1705a75fececSSteven Rostedt $make = "$makecmd O=$outputdir"; 170651ad1dd1SSteven Rostedt $output_config = "$outputdir/.config"; 1707a75fececSSteven Rostedt 1708a75fececSSteven Rostedt if ($reboot_type eq "grub") { 1709576f627cSSteven Rostedt dodie "GRUB_MENU not defined" if (!defined($grub_menu)); 1710a75fececSSteven Rostedt } elsif (!defined($reboot_script)) { 1711576f627cSSteven Rostedt dodie "REBOOT_SCRIPT not defined" 1712a75fececSSteven Rostedt } 1713a75fececSSteven Rostedt 1714a75fececSSteven Rostedt my $run_type = $build_type; 1715a75fececSSteven Rostedt if ($test_type eq "patchcheck") { 1716a75fececSSteven Rostedt $run_type = $opt{"PATCHCHECK_TYPE[$i]"}; 1717a75fececSSteven Rostedt } elsif ($test_type eq "bisect") { 1718a75fececSSteven Rostedt $run_type = $opt{"BISECT_TYPE[$i]"}; 17190a05c769SSteven Rostedt } elsif ($test_type eq "config_bisect") { 17200a05c769SSteven Rostedt $run_type = $opt{"CONFIG_BISECT_TYPE[$i]"}; 1721a75fececSSteven Rostedt } 1722a75fececSSteven Rostedt 1723a75fececSSteven Rostedt # mistake in config file? 1724a75fececSSteven Rostedt if (!defined($run_type)) { 1725a75fececSSteven Rostedt $run_type = "ERROR"; 1726a75fececSSteven Rostedt } 17272545eb61SSteven Rostedt 17282545eb61SSteven Rostedt doprint "\n\n"; 1729a75fececSSteven Rostedt doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type\n\n"; 17307faafbd6SSteven Rostedt 17317faafbd6SSteven Rostedt unlink $dmesg; 17327faafbd6SSteven Rostedt unlink $buildlog; 17332545eb61SSteven Rostedt 17342b7d9b21SSteven Rostedt if (!defined($minconfig)) { 17352b7d9b21SSteven Rostedt $minconfig = $addconfig; 17362b7d9b21SSteven Rostedt 17372b7d9b21SSteven Rostedt } elsif (defined($addconfig)) { 1738*9be2e6b5SSteven Rostedt run_command "cat $addconfig $minconfig > $tmpdir/add_config" or 17392b7d9b21SSteven Rostedt dodie "Failed to create temp config"; 1740*9be2e6b5SSteven Rostedt $minconfig = "$tmpdir/add_config"; 17412b7d9b21SSteven Rostedt } 17422b7d9b21SSteven Rostedt 17436c5ee0beSSteven Rostedt my $checkout = $opt{"CHECKOUT[$i]"}; 17446c5ee0beSSteven Rostedt if (defined($checkout)) { 17456c5ee0beSSteven Rostedt run_command "git checkout $checkout" or 17466c5ee0beSSteven Rostedt die "failed to checkout $checkout"; 17476c5ee0beSSteven Rostedt } 17486c5ee0beSSteven Rostedt 1749a75fececSSteven Rostedt if ($test_type eq "bisect") { 17505f9b6cedSSteven Rostedt bisect $i; 17515f9b6cedSSteven Rostedt next; 17520a05c769SSteven Rostedt } elsif ($test_type eq "config_bisect") { 17530a05c769SSteven Rostedt config_bisect $i; 17540a05c769SSteven Rostedt next; 1755a75fececSSteven Rostedt } elsif ($test_type eq "patchcheck") { 17566c5ee0beSSteven Rostedt patchcheck $i; 17576c5ee0beSSteven Rostedt next; 17585f9b6cedSSteven Rostedt } 17595f9b6cedSSteven Rostedt 17607faafbd6SSteven Rostedt if ($build_type ne "nobuild") { 17617faafbd6SSteven Rostedt build $build_type or next; 17622545eb61SSteven Rostedt } 17632545eb61SSteven Rostedt 1764a75fececSSteven Rostedt if ($test_type ne "build") { 17655f9b6cedSSteven Rostedt get_grub_index; 17665f9b6cedSSteven Rostedt get_version; 17672545eb61SSteven Rostedt install; 17685a391fbfSSteven Rostedt 17697faafbd6SSteven Rostedt my $failed = 0; 17707faafbd6SSteven Rostedt start_monitor; 17717faafbd6SSteven Rostedt monitor or $failed = 1;; 1772a75fececSSteven Rostedt 1773a75fececSSteven Rostedt if (!$failed && $test_type ne "boot" && defined($run_test)) { 17747faafbd6SSteven Rostedt do_run_test or $failed = 1; 17755a391fbfSSteven Rostedt } 17767faafbd6SSteven Rostedt end_monitor; 17777faafbd6SSteven Rostedt next if ($failed); 1778a75fececSSteven Rostedt } 17795a391fbfSSteven Rostedt 17805f9b6cedSSteven Rostedt success $i; 178175c3fda7SSteven Rostedt} 17822545eb61SSteven Rostedt 17835c42fc5bSSteven Rostedtif ($opt{"POWEROFF_ON_SUCCESS"}) { 178475c3fda7SSteven Rostedt halt; 1785576f627cSSteven Rostedt} elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot) { 178675c3fda7SSteven Rostedt reboot; 17875c42fc5bSSteven Rostedt} 178875c3fda7SSteven Rostedt 1789e48c5293SSteven Rostedtdoprint "\n $successes of $opt{NUM_TESTS} tests were successful\n\n"; 1790e48c5293SSteven Rostedt 17912545eb61SSteven Rostedtexit 0; 1792