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 401*cccae1a6SSteven Rostedt my $type = $build_type; 402*cccae1a6SSteven Rostedt if ($type =~ /useconfig/) { 403*cccae1a6SSteven Rostedt $type = "useconfig"; 404*cccae1a6SSteven Rostedt } 405*cccae1a6SSteven Rostedt 406*cccae1a6SSteven Rostedt my $dir = "$machine-$test_type-$type-fail-$date"; 407a75fececSSteven Rostedt my $faildir = "$store_failures/$dir"; 4087faafbd6SSteven Rostedt 4097faafbd6SSteven Rostedt if (!-d $faildir) { 4107faafbd6SSteven Rostedt mkpath($faildir) or 411a75fececSSteven Rostedt die "can't create $faildir"; 4127faafbd6SSteven Rostedt } 41351ad1dd1SSteven Rostedt if (-f "$output_config") { 41451ad1dd1SSteven Rostedt cp "$output_config", "$faildir/config" or 4157faafbd6SSteven Rostedt die "failed to copy .config"; 4167faafbd6SSteven Rostedt } 4177faafbd6SSteven Rostedt if (-f $buildlog) { 4187faafbd6SSteven Rostedt cp $buildlog, "$faildir/buildlog" or 4197faafbd6SSteven Rostedt die "failed to move $buildlog"; 4207faafbd6SSteven Rostedt } 4217faafbd6SSteven Rostedt if (-f $dmesg) { 4227faafbd6SSteven Rostedt cp $dmesg, "$faildir/dmesg" or 4237faafbd6SSteven Rostedt die "failed to move $dmesg"; 4247faafbd6SSteven Rostedt } 4257faafbd6SSteven Rostedt 4267faafbd6SSteven Rostedt doprint "*** Saved info to $faildir ***\n"; 4277faafbd6SSteven Rostedt 4282b7d9b21SSteven Rostedt return 1; 4292b7d9b21SSteven Rostedt} 4302b7d9b21SSteven Rostedt 4312545eb61SSteven Rostedtsub run_command { 4322545eb61SSteven Rostedt my ($command) = @_; 433d6ce2a0bSSteven Rostedt my $dolog = 0; 434d6ce2a0bSSteven Rostedt my $dord = 0; 435d6ce2a0bSSteven Rostedt my $pid; 436d6ce2a0bSSteven Rostedt 437e48c5293SSteven Rostedt $command =~ s/\$SSH_USER/$ssh_user/g; 438e48c5293SSteven Rostedt $command =~ s/\$MACHINE/$machine/g; 439e48c5293SSteven Rostedt 440d6ce2a0bSSteven Rostedt doprint("$command ... "); 441d6ce2a0bSSteven Rostedt 442d6ce2a0bSSteven Rostedt $pid = open(CMD, "$command 2>&1 |") or 4432b7d9b21SSteven Rostedt (fail "unable to exec $command" and return 0); 4442545eb61SSteven Rostedt 4452545eb61SSteven Rostedt if (defined($opt{"LOG_FILE"})) { 446d6ce2a0bSSteven Rostedt open(LOG, ">>$opt{LOG_FILE}") or 447d6ce2a0bSSteven Rostedt dodie "failed to write to log"; 448d6ce2a0bSSteven Rostedt $dolog = 1; 4496c5ee0beSSteven Rostedt } 4506c5ee0beSSteven Rostedt 4516c5ee0beSSteven Rostedt if (defined($redirect)) { 452d6ce2a0bSSteven Rostedt open (RD, ">$redirect") or 453d6ce2a0bSSteven Rostedt dodie "failed to write to redirect $redirect"; 454d6ce2a0bSSteven Rostedt $dord = 1; 4552545eb61SSteven Rostedt } 4562545eb61SSteven Rostedt 457d6ce2a0bSSteven Rostedt while (<CMD>) { 458d6ce2a0bSSteven Rostedt print LOG if ($dolog); 459d6ce2a0bSSteven Rostedt print RD if ($dord); 460d6ce2a0bSSteven Rostedt } 4612545eb61SSteven Rostedt 462d6ce2a0bSSteven Rostedt waitpid($pid, 0); 4632545eb61SSteven Rostedt my $failed = $?; 4642545eb61SSteven Rostedt 465d6ce2a0bSSteven Rostedt close(CMD); 466d6ce2a0bSSteven Rostedt close(LOG) if ($dolog); 467d6ce2a0bSSteven Rostedt close(RD) if ($dord); 468d6ce2a0bSSteven Rostedt 4692545eb61SSteven Rostedt if ($failed) { 4702545eb61SSteven Rostedt doprint "FAILED!\n"; 4712545eb61SSteven Rostedt } else { 4722545eb61SSteven Rostedt doprint "SUCCESS\n"; 4732545eb61SSteven Rostedt } 4742545eb61SSteven Rostedt 4755f9b6cedSSteven Rostedt return !$failed; 4765f9b6cedSSteven Rostedt} 4775f9b6cedSSteven Rostedt 478e48c5293SSteven Rostedtsub run_ssh { 479e48c5293SSteven Rostedt my ($cmd) = @_; 480e48c5293SSteven Rostedt my $cp_exec = $ssh_exec; 481e48c5293SSteven Rostedt 482e48c5293SSteven Rostedt $cp_exec =~ s/\$SSH_COMMAND/$cmd/g; 483e48c5293SSteven Rostedt return run_command "$cp_exec"; 484e48c5293SSteven Rostedt} 485e48c5293SSteven Rostedt 486e48c5293SSteven Rostedtsub run_scp { 487e48c5293SSteven Rostedt my ($src, $dst) = @_; 488e48c5293SSteven Rostedt my $cp_scp = $scp_to_target; 489e48c5293SSteven Rostedt 490e48c5293SSteven Rostedt $cp_scp =~ s/\$SRC_FILE/$src/g; 491e48c5293SSteven Rostedt $cp_scp =~ s/\$DST_FILE/$dst/g; 492e48c5293SSteven Rostedt 493e48c5293SSteven Rostedt return run_command "$cp_scp"; 494e48c5293SSteven Rostedt} 495e48c5293SSteven Rostedt 4965f9b6cedSSteven Rostedtsub get_grub_index { 4975f9b6cedSSteven Rostedt 498a75fececSSteven Rostedt if ($reboot_type ne "grub") { 499a75fececSSteven Rostedt return; 500a75fececSSteven Rostedt } 5015a391fbfSSteven Rostedt return if (defined($grub_number)); 5025f9b6cedSSteven Rostedt 5035f9b6cedSSteven Rostedt doprint "Find grub menu ... "; 5045f9b6cedSSteven Rostedt $grub_number = -1; 505e48c5293SSteven Rostedt 506e48c5293SSteven Rostedt my $ssh_grub = $ssh_exec; 507e48c5293SSteven Rostedt $ssh_grub =~ s,\$SSH_COMMAND,cat /boot/grub/menu.lst,g; 508e48c5293SSteven Rostedt 509e48c5293SSteven Rostedt open(IN, "$ssh_grub |") 5105f9b6cedSSteven Rostedt or die "unable to get menu.lst"; 511e48c5293SSteven Rostedt 5125f9b6cedSSteven Rostedt while (<IN>) { 513a75fececSSteven Rostedt if (/^\s*title\s+$grub_menu\s*$/) { 5145f9b6cedSSteven Rostedt $grub_number++; 5155f9b6cedSSteven Rostedt last; 5165f9b6cedSSteven Rostedt } elsif (/^\s*title\s/) { 5175f9b6cedSSteven Rostedt $grub_number++; 5185f9b6cedSSteven Rostedt } 5195f9b6cedSSteven Rostedt } 5205f9b6cedSSteven Rostedt close(IN); 5215f9b6cedSSteven Rostedt 522a75fececSSteven Rostedt die "Could not find '$grub_menu' in /boot/grub/menu on $machine" 5235f9b6cedSSteven Rostedt if ($grub_number < 0); 5245f9b6cedSSteven Rostedt doprint "$grub_number\n"; 5252545eb61SSteven Rostedt} 5262545eb61SSteven Rostedt 5272545eb61SSteven Rostedtsub wait_for_input 5282545eb61SSteven Rostedt{ 5292545eb61SSteven Rostedt my ($fp, $time) = @_; 5302545eb61SSteven Rostedt my $rin; 5312545eb61SSteven Rostedt my $ready; 5322545eb61SSteven Rostedt my $line; 5332545eb61SSteven Rostedt my $ch; 5342545eb61SSteven Rostedt 5352545eb61SSteven Rostedt if (!defined($time)) { 5362545eb61SSteven Rostedt $time = $timeout; 5372545eb61SSteven Rostedt } 5382545eb61SSteven Rostedt 5392545eb61SSteven Rostedt $rin = ''; 5402545eb61SSteven Rostedt vec($rin, fileno($fp), 1) = 1; 5412545eb61SSteven Rostedt $ready = select($rin, undef, undef, $time); 5422545eb61SSteven Rostedt 5432545eb61SSteven Rostedt $line = ""; 5442545eb61SSteven Rostedt 5452545eb61SSteven Rostedt # try to read one char at a time 5462545eb61SSteven Rostedt while (sysread $fp, $ch, 1) { 5472545eb61SSteven Rostedt $line .= $ch; 5482545eb61SSteven Rostedt last if ($ch eq "\n"); 5492545eb61SSteven Rostedt } 5502545eb61SSteven Rostedt 5512545eb61SSteven Rostedt if (!length($line)) { 5522545eb61SSteven Rostedt return undef; 5532545eb61SSteven Rostedt } 5542545eb61SSteven Rostedt 5552545eb61SSteven Rostedt return $line; 5562545eb61SSteven Rostedt} 5572545eb61SSteven Rostedt 55875c3fda7SSteven Rostedtsub reboot_to { 559a75fececSSteven Rostedt if ($reboot_type eq "grub") { 560e48c5293SSteven Rostedt run_command "$ssh_exec '(echo \"savedefault --default=$grub_number --once\" | grub --batch; reboot)'"; 561a75fececSSteven Rostedt return; 562a75fececSSteven Rostedt } 563a75fececSSteven Rostedt 564a75fececSSteven Rostedt run_command "$reboot_script"; 5652545eb61SSteven Rostedt} 5662545eb61SSteven Rostedt 567a57419b3SSteven Rostedtsub get_sha1 { 568a57419b3SSteven Rostedt my ($commit) = @_; 569a57419b3SSteven Rostedt 570a57419b3SSteven Rostedt doprint "git rev-list --max-count=1 $commit ... "; 571a57419b3SSteven Rostedt my $sha1 = `git rev-list --max-count=1 $commit`; 572a57419b3SSteven Rostedt my $ret = $?; 573a57419b3SSteven Rostedt 574a57419b3SSteven Rostedt logit $sha1; 575a57419b3SSteven Rostedt 576a57419b3SSteven Rostedt if ($ret) { 577a57419b3SSteven Rostedt doprint "FAILED\n"; 578a57419b3SSteven Rostedt dodie "Failed to get git $commit"; 579a57419b3SSteven Rostedt } 580a57419b3SSteven Rostedt 581a57419b3SSteven Rostedt print "SUCCESS\n"; 582a57419b3SSteven Rostedt 583a57419b3SSteven Rostedt chomp $sha1; 584a57419b3SSteven Rostedt 585a57419b3SSteven Rostedt return $sha1; 586a57419b3SSteven Rostedt} 587a57419b3SSteven Rostedt 5885a391fbfSSteven Rostedtsub monitor { 5892545eb61SSteven Rostedt my $booted = 0; 5902545eb61SSteven Rostedt my $bug = 0; 5915c42fc5bSSteven Rostedt my $skip_call_trace = 0; 5922b7d9b21SSteven Rostedt my $loops; 5932545eb61SSteven Rostedt 5947faafbd6SSteven Rostedt wait_for_monitor 5; 5952545eb61SSteven Rostedt 5962545eb61SSteven Rostedt my $line; 5972545eb61SSteven Rostedt my $full_line = ""; 5982545eb61SSteven Rostedt 5997faafbd6SSteven Rostedt open(DMESG, "> $dmesg") or 6007faafbd6SSteven Rostedt die "unable to write to $dmesg"; 6012545eb61SSteven Rostedt 60275c3fda7SSteven Rostedt reboot_to; 6032545eb61SSteven Rostedt 6042545eb61SSteven Rostedt for (;;) { 6052545eb61SSteven Rostedt 6062b7d9b21SSteven Rostedt if ($booted) { 607a75fececSSteven Rostedt $line = wait_for_input($monitor_fp, $booted_timeout); 6082b7d9b21SSteven Rostedt } else { 6097faafbd6SSteven Rostedt $line = wait_for_input($monitor_fp); 6102b7d9b21SSteven Rostedt } 6112545eb61SSteven Rostedt 6122545eb61SSteven Rostedt last if (!defined($line)); 6132545eb61SSteven Rostedt 6142545eb61SSteven Rostedt doprint $line; 6157faafbd6SSteven Rostedt print DMESG $line; 6162545eb61SSteven Rostedt 6172545eb61SSteven Rostedt # we are not guaranteed to get a full line 6182545eb61SSteven Rostedt $full_line .= $line; 6192545eb61SSteven Rostedt 620a75fececSSteven Rostedt if ($full_line =~ /$success_line/) { 6212545eb61SSteven Rostedt $booted = 1; 6222545eb61SSteven Rostedt } 6232545eb61SSteven Rostedt 6245c42fc5bSSteven Rostedt if ($full_line =~ /\[ backtrace testing \]/) { 6255c42fc5bSSteven Rostedt $skip_call_trace = 1; 6265c42fc5bSSteven Rostedt } 6275c42fc5bSSteven Rostedt 6282545eb61SSteven Rostedt if ($full_line =~ /call trace:/i) { 6295c42fc5bSSteven Rostedt $bug = 1 if (!$skip_call_trace); 6305c42fc5bSSteven Rostedt } 6315c42fc5bSSteven Rostedt 6325c42fc5bSSteven Rostedt if ($full_line =~ /\[ end of backtrace testing \]/) { 6335c42fc5bSSteven Rostedt $skip_call_trace = 0; 6345c42fc5bSSteven Rostedt } 6355c42fc5bSSteven Rostedt 6365c42fc5bSSteven Rostedt if ($full_line =~ /Kernel panic -/) { 6372545eb61SSteven Rostedt $bug = 1; 6382545eb61SSteven Rostedt } 6392545eb61SSteven Rostedt 6402545eb61SSteven Rostedt if ($line =~ /\n/) { 6412545eb61SSteven Rostedt $full_line = ""; 6422545eb61SSteven Rostedt } 6432545eb61SSteven Rostedt } 6442545eb61SSteven Rostedt 6457faafbd6SSteven Rostedt close(DMESG); 6462545eb61SSteven Rostedt 6472545eb61SSteven Rostedt if ($bug) { 6482b7d9b21SSteven Rostedt return 0 if ($in_bisect); 649576f627cSSteven Rostedt fail "failed - got a bug report" and return 0; 6502545eb61SSteven Rostedt } 6515f9b6cedSSteven Rostedt 652a75fececSSteven Rostedt if (!$booted) { 653a75fececSSteven Rostedt return 0 if ($in_bisect); 654576f627cSSteven Rostedt fail "failed - never got a boot prompt." and return 0; 655a75fececSSteven Rostedt } 656a75fececSSteven Rostedt 6572b7d9b21SSteven Rostedt return 1; 6582545eb61SSteven Rostedt} 6592545eb61SSteven Rostedt 6602545eb61SSteven Rostedtsub install { 6612545eb61SSteven Rostedt 662e48c5293SSteven Rostedt run_scp "$outputdir/$build_target", "$target_image" or 6635c42fc5bSSteven Rostedt dodie "failed to copy image"; 6645f9b6cedSSteven Rostedt 6655f9b6cedSSteven Rostedt my $install_mods = 0; 6665f9b6cedSSteven Rostedt 6675f9b6cedSSteven Rostedt # should we process modules? 6685f9b6cedSSteven Rostedt $install_mods = 0; 66951ad1dd1SSteven Rostedt open(IN, "$output_config") or dodie("Can't read config file"); 6705f9b6cedSSteven Rostedt while (<IN>) { 6715f9b6cedSSteven Rostedt if (/CONFIG_MODULES(=y)?/) { 6725f9b6cedSSteven Rostedt $install_mods = 1 if (defined($1)); 6735f9b6cedSSteven Rostedt last; 6745f9b6cedSSteven Rostedt } 6755f9b6cedSSteven Rostedt } 6765f9b6cedSSteven Rostedt close(IN); 6775f9b6cedSSteven Rostedt 6785f9b6cedSSteven Rostedt if (!$install_mods) { 6795f9b6cedSSteven Rostedt doprint "No modules needed\n"; 6805f9b6cedSSteven Rostedt return; 6812545eb61SSteven Rostedt } 6822545eb61SSteven Rostedt 683a75fececSSteven Rostedt run_command "$make INSTALL_MOD_PATH=$tmpdir modules_install" or 6845f9b6cedSSteven Rostedt dodie "Failed to install modules"; 6855f9b6cedSSteven Rostedt 6862545eb61SSteven Rostedt my $modlib = "/lib/modules/$version"; 687a57419b3SSteven Rostedt my $modtar = "ktest-mods.tar.bz2"; 6882545eb61SSteven Rostedt 689e48c5293SSteven Rostedt run_ssh "rm -rf $modlib" or 6905c42fc5bSSteven Rostedt dodie "failed to remove old mods: $modlib"; 6912545eb61SSteven Rostedt 6925c42fc5bSSteven Rostedt # would be nice if scp -r did not follow symbolic links 693a75fececSSteven Rostedt run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or 6945c42fc5bSSteven Rostedt dodie "making tarball"; 6955c42fc5bSSteven Rostedt 696e48c5293SSteven Rostedt run_scp "$tmpdir/$modtar", "/tmp" or 6975c42fc5bSSteven Rostedt dodie "failed to copy modules"; 6985c42fc5bSSteven Rostedt 699a75fececSSteven Rostedt unlink "$tmpdir/$modtar"; 7005c42fc5bSSteven Rostedt 701e48c5293SSteven Rostedt run_ssh "'(cd / && tar xf /tmp/$modtar)'" or 7025c42fc5bSSteven Rostedt dodie "failed to tar modules"; 7035c42fc5bSSteven Rostedt 704e48c5293SSteven Rostedt run_ssh "rm -f /tmp/$modtar"; 7058b37ca8cSSteven Rostedt 7068b37ca8cSSteven Rostedt return if (!defined($post_install)); 7078b37ca8cSSteven Rostedt 708e48c5293SSteven Rostedt my $cp_post_install = $post_install; 709e48c5293SSteven Rostedt $cp_post_install = s/\$KERNEL_VERSION/$version/g; 710e48c5293SSteven Rostedt run_command "$cp_post_install" or 711576f627cSSteven Rostedt dodie "Failed to run post install"; 7122545eb61SSteven Rostedt} 7132545eb61SSteven Rostedt 7146c5ee0beSSteven Rostedtsub check_buildlog { 7156c5ee0beSSteven Rostedt my ($patch) = @_; 7166c5ee0beSSteven Rostedt 7176c5ee0beSSteven Rostedt my @files = `git show $patch | diffstat -l`; 7186c5ee0beSSteven Rostedt 7196c5ee0beSSteven Rostedt open(IN, "git show $patch |") or 7206c5ee0beSSteven Rostedt dodie "failed to show $patch"; 7216c5ee0beSSteven Rostedt while (<IN>) { 7226c5ee0beSSteven Rostedt if (m,^--- a/(.*),) { 7236c5ee0beSSteven Rostedt chomp $1; 7246c5ee0beSSteven Rostedt $files[$#files] = $1; 7256c5ee0beSSteven Rostedt } 7266c5ee0beSSteven Rostedt } 7276c5ee0beSSteven Rostedt close(IN); 7286c5ee0beSSteven Rostedt 7296c5ee0beSSteven Rostedt open(IN, $buildlog) or dodie "Can't open $buildlog"; 7306c5ee0beSSteven Rostedt while (<IN>) { 7316c5ee0beSSteven Rostedt if (/^\s*(.*?):.*(warning|error)/) { 7326c5ee0beSSteven Rostedt my $err = $1; 7336c5ee0beSSteven Rostedt foreach my $file (@files) { 734a75fececSSteven Rostedt my $fullpath = "$builddir/$file"; 7356c5ee0beSSteven Rostedt if ($file eq $err || $fullpath eq $err) { 7362b7d9b21SSteven Rostedt fail "$file built with warnings" and return 0; 7376c5ee0beSSteven Rostedt } 7386c5ee0beSSteven Rostedt } 7396c5ee0beSSteven Rostedt } 7406c5ee0beSSteven Rostedt } 7416c5ee0beSSteven Rostedt close(IN); 7422b7d9b21SSteven Rostedt 7432b7d9b21SSteven Rostedt return 1; 7446c5ee0beSSteven Rostedt} 7456c5ee0beSSteven Rostedt 7462545eb61SSteven Rostedtsub build { 7472545eb61SSteven Rostedt my ($type) = @_; 7485c42fc5bSSteven Rostedt my $defconfig = ""; 7492545eb61SSteven Rostedt 7507faafbd6SSteven Rostedt unlink $buildlog; 7517faafbd6SSteven Rostedt 75275c3fda7SSteven Rostedt if ($type =~ /^useconfig:(.*)/) { 75351ad1dd1SSteven Rostedt run_command "cp $1 $output_config" or 75475c3fda7SSteven Rostedt dodie "could not copy $1 to .config"; 7555f9b6cedSSteven Rostedt 75675c3fda7SSteven Rostedt $type = "oldconfig"; 75775c3fda7SSteven Rostedt } 75875c3fda7SSteven Rostedt 7595c42fc5bSSteven Rostedt # old config can ask questions 7605c42fc5bSSteven Rostedt if ($type eq "oldconfig") { 7619386c6abSSteven Rostedt $type = "oldnoconfig"; 76275c3fda7SSteven Rostedt 76375c3fda7SSteven Rostedt # allow for empty configs 76451ad1dd1SSteven Rostedt run_command "touch $output_config"; 76575c3fda7SSteven Rostedt 76651ad1dd1SSteven Rostedt run_command "mv $output_config $outputdir/config_temp" or 7675c42fc5bSSteven Rostedt dodie "moving .config"; 7685c42fc5bSSteven Rostedt 7695f9b6cedSSteven Rostedt if (!$noclean && !run_command "$make mrproper") { 7705c42fc5bSSteven Rostedt dodie "make mrproper"; 7715c42fc5bSSteven Rostedt } 7725c42fc5bSSteven Rostedt 77351ad1dd1SSteven Rostedt run_command "mv $outputdir/config_temp $output_config" or 7745c42fc5bSSteven Rostedt dodie "moving config_temp"; 7755c42fc5bSSteven Rostedt 7765c42fc5bSSteven Rostedt } elsif (!$noclean) { 77751ad1dd1SSteven Rostedt unlink "$output_config"; 7785f9b6cedSSteven Rostedt run_command "$make mrproper" or 7795c42fc5bSSteven Rostedt dodie "make mrproper"; 7805c42fc5bSSteven Rostedt } 7812545eb61SSteven Rostedt 7822545eb61SSteven Rostedt # add something to distinguish this build 783a75fececSSteven Rostedt open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file"); 784a75fececSSteven Rostedt print OUT "$localversion\n"; 7852545eb61SSteven Rostedt close(OUT); 7862545eb61SSteven Rostedt 7875f9b6cedSSteven Rostedt if (defined($minconfig)) { 7885f9b6cedSSteven Rostedt $defconfig = "KCONFIG_ALLCONFIG=$minconfig"; 7892545eb61SSteven Rostedt } 7902545eb61SSteven Rostedt 7919386c6abSSteven Rostedt run_command "$defconfig $make $type" or 7925c42fc5bSSteven Rostedt dodie "failed make config"; 7932545eb61SSteven Rostedt 794a75fececSSteven Rostedt $redirect = "$buildlog"; 795a75fececSSteven Rostedt if (!run_command "$make $build_options") { 7966c5ee0beSSteven Rostedt undef $redirect; 7975f9b6cedSSteven Rostedt # bisect may need this to pass 7982b7d9b21SSteven Rostedt return 0 if ($in_bisect); 7992b7d9b21SSteven Rostedt fail "failed build" and return 0; 8002545eb61SSteven Rostedt } 8016c5ee0beSSteven Rostedt undef $redirect; 8025f9b6cedSSteven Rostedt 8032b7d9b21SSteven Rostedt return 1; 8042545eb61SSteven Rostedt} 8052545eb61SSteven Rostedt 80675c3fda7SSteven Rostedtsub halt { 807e48c5293SSteven Rostedt if (!run_ssh "halt" or defined($power_off)) { 808576f627cSSteven Rostedt if (defined($poweroff_after_halt)) { 809576f627cSSteven Rostedt sleep $poweroff_after_halt; 810576f627cSSteven Rostedt run_command "$power_off"; 811576f627cSSteven Rostedt } 812576f627cSSteven Rostedt } else { 81375c3fda7SSteven Rostedt # nope? the zap it! 814a75fececSSteven Rostedt run_command "$power_off"; 81575c3fda7SSteven Rostedt } 81675c3fda7SSteven Rostedt} 81775c3fda7SSteven Rostedt 8185f9b6cedSSteven Rostedtsub success { 8195f9b6cedSSteven Rostedt my ($i) = @_; 8205f9b6cedSSteven Rostedt 821e48c5293SSteven Rostedt $successes++; 822e48c5293SSteven Rostedt 8235f9b6cedSSteven Rostedt doprint "\n\n*******************************************\n"; 8245f9b6cedSSteven Rostedt doprint "*******************************************\n"; 8257a849cd9SSteven Rostedt doprint "KTEST RESULT: TEST $i SUCCESS!!!! **\n"; 8265f9b6cedSSteven Rostedt doprint "*******************************************\n"; 8275f9b6cedSSteven Rostedt doprint "*******************************************\n"; 8285f9b6cedSSteven Rostedt 829576f627cSSteven Rostedt if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) { 830a75fececSSteven Rostedt doprint "Reboot and wait $sleep_time seconds\n"; 8315f9b6cedSSteven Rostedt reboot; 8327faafbd6SSteven Rostedt start_monitor; 833a75fececSSteven Rostedt wait_for_monitor $sleep_time; 8347faafbd6SSteven Rostedt end_monitor; 8355f9b6cedSSteven Rostedt } 8365f9b6cedSSteven Rostedt} 8375f9b6cedSSteven Rostedt 8385f9b6cedSSteven Rostedtsub get_version { 8395f9b6cedSSteven Rostedt # get the release name 8405f9b6cedSSteven Rostedt doprint "$make kernelrelease ... "; 8415f9b6cedSSteven Rostedt $version = `$make kernelrelease | tail -1`; 8425f9b6cedSSteven Rostedt chomp($version); 8435f9b6cedSSteven Rostedt doprint "$version\n"; 8445f9b6cedSSteven Rostedt} 8455f9b6cedSSteven Rostedt 8465a391fbfSSteven Rostedtsub child_run_test { 8477faafbd6SSteven Rostedt my $failed = 0; 8485a391fbfSSteven Rostedt 8497faafbd6SSteven Rostedt # child should have no power 850a75fececSSteven Rostedt $reboot_on_error = 0; 851a75fececSSteven Rostedt $poweroff_on_error = 0; 852a75fececSSteven Rostedt $die_on_failure = 1; 8537faafbd6SSteven Rostedt 8547faafbd6SSteven Rostedt run_command $run_test or $failed = 1; 8555a391fbfSSteven Rostedt exit $failed; 8565a391fbfSSteven Rostedt} 8575a391fbfSSteven Rostedt 8585a391fbfSSteven Rostedtmy $child_done; 8595a391fbfSSteven Rostedt 8605a391fbfSSteven Rostedtsub child_finished { 8615a391fbfSSteven Rostedt $child_done = 1; 8625a391fbfSSteven Rostedt} 8635a391fbfSSteven Rostedt 8645a391fbfSSteven Rostedtsub do_run_test { 8655a391fbfSSteven Rostedt my $child_pid; 8665a391fbfSSteven Rostedt my $child_exit; 8675a391fbfSSteven Rostedt my $line; 8685a391fbfSSteven Rostedt my $full_line; 8695a391fbfSSteven Rostedt my $bug = 0; 8705a391fbfSSteven Rostedt 8717faafbd6SSteven Rostedt wait_for_monitor 1; 8725a391fbfSSteven Rostedt 8737faafbd6SSteven Rostedt doprint "run test $run_test\n"; 8745a391fbfSSteven Rostedt 8755a391fbfSSteven Rostedt $child_done = 0; 8765a391fbfSSteven Rostedt 8775a391fbfSSteven Rostedt $SIG{CHLD} = qw(child_finished); 8785a391fbfSSteven Rostedt 8795a391fbfSSteven Rostedt $child_pid = fork; 8805a391fbfSSteven Rostedt 8815a391fbfSSteven Rostedt child_run_test if (!$child_pid); 8825a391fbfSSteven Rostedt 8835a391fbfSSteven Rostedt $full_line = ""; 8845a391fbfSSteven Rostedt 8855a391fbfSSteven Rostedt do { 8867faafbd6SSteven Rostedt $line = wait_for_input($monitor_fp, 1); 8875a391fbfSSteven Rostedt if (defined($line)) { 8885a391fbfSSteven Rostedt 8895a391fbfSSteven Rostedt # we are not guaranteed to get a full line 8905a391fbfSSteven Rostedt $full_line .= $line; 8915a391fbfSSteven Rostedt 8925a391fbfSSteven Rostedt if ($full_line =~ /call trace:/i) { 8935a391fbfSSteven Rostedt $bug = 1; 8945a391fbfSSteven Rostedt } 8955a391fbfSSteven Rostedt 8965a391fbfSSteven Rostedt if ($full_line =~ /Kernel panic -/) { 8975a391fbfSSteven Rostedt $bug = 1; 8985a391fbfSSteven Rostedt } 8995a391fbfSSteven Rostedt 9005a391fbfSSteven Rostedt if ($line =~ /\n/) { 9015a391fbfSSteven Rostedt $full_line = ""; 9025a391fbfSSteven Rostedt } 9035a391fbfSSteven Rostedt } 9045a391fbfSSteven Rostedt } while (!$child_done && !$bug); 9055a391fbfSSteven Rostedt 9065a391fbfSSteven Rostedt if ($bug) { 9075a391fbfSSteven Rostedt doprint "Detected kernel crash!\n"; 9085a391fbfSSteven Rostedt # kill the child with extreme prejudice 9095a391fbfSSteven Rostedt kill 9, $child_pid; 9105a391fbfSSteven Rostedt } 9115a391fbfSSteven Rostedt 9125a391fbfSSteven Rostedt waitpid $child_pid, 0; 9135a391fbfSSteven Rostedt $child_exit = $?; 9145a391fbfSSteven Rostedt 9155a391fbfSSteven Rostedt if ($bug || $child_exit) { 9162b7d9b21SSteven Rostedt return 0 if $in_bisect; 9172b7d9b21SSteven Rostedt fail "test failed" and return 0; 9185a391fbfSSteven Rostedt } 9192b7d9b21SSteven Rostedt return 1; 9205a391fbfSSteven Rostedt} 9215a391fbfSSteven Rostedt 922a75fececSSteven Rostedtsub run_git_bisect { 923a75fececSSteven Rostedt my ($command) = @_; 924a75fececSSteven Rostedt 925a75fececSSteven Rostedt doprint "$command ... "; 926a75fececSSteven Rostedt 927a75fececSSteven Rostedt my $output = `$command 2>&1`; 928a75fececSSteven Rostedt my $ret = $?; 929a75fececSSteven Rostedt 930a75fececSSteven Rostedt logit $output; 931a75fececSSteven Rostedt 932a75fececSSteven Rostedt if ($ret) { 933a75fececSSteven Rostedt doprint "FAILED\n"; 934a75fececSSteven Rostedt dodie "Failed to git bisect"; 935a75fececSSteven Rostedt } 936a75fececSSteven Rostedt 937a75fececSSteven Rostedt doprint "SUCCESS\n"; 938a75fececSSteven Rostedt if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) { 939a75fececSSteven Rostedt doprint "$1 [$2]\n"; 940a75fececSSteven Rostedt } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) { 941a75fececSSteven Rostedt $bisect_bad = $1; 942a75fececSSteven Rostedt doprint "Found bad commit... $1\n"; 943a75fececSSteven Rostedt return 0; 944a75fececSSteven Rostedt } else { 945a75fececSSteven Rostedt # we already logged it, just print it now. 946a75fececSSteven Rostedt print $output; 947a75fececSSteven Rostedt } 948a75fececSSteven Rostedt 949a75fececSSteven Rostedt return 1; 950a75fececSSteven Rostedt} 951a75fececSSteven Rostedt 9520a05c769SSteven Rostedt# returns 1 on success, 0 on failure 9530a05c769SSteven Rostedtsub run_bisect_test { 9540a05c769SSteven Rostedt my ($type, $buildtype) = @_; 9555f9b6cedSSteven Rostedt 9562b7d9b21SSteven Rostedt my $failed = 0; 9575f9b6cedSSteven Rostedt my $result; 9585f9b6cedSSteven Rostedt my $output; 9595f9b6cedSSteven Rostedt my $ret; 9605f9b6cedSSteven Rostedt 9610a05c769SSteven Rostedt $in_bisect = 1; 9620a05c769SSteven Rostedt 9630a05c769SSteven Rostedt build $buildtype or $failed = 1; 9645f9b6cedSSteven Rostedt 9655f9b6cedSSteven Rostedt if ($type ne "build") { 9667faafbd6SSteven Rostedt dodie "Failed on build" if $failed; 9675f9b6cedSSteven Rostedt 9685f9b6cedSSteven Rostedt # Now boot the box 9695f9b6cedSSteven Rostedt get_grub_index; 9705f9b6cedSSteven Rostedt get_version; 9715f9b6cedSSteven Rostedt install; 9727faafbd6SSteven Rostedt 9737faafbd6SSteven Rostedt start_monitor; 9742b7d9b21SSteven Rostedt monitor or $failed = 1; 9755f9b6cedSSteven Rostedt 9765f9b6cedSSteven Rostedt if ($type ne "boot") { 9777faafbd6SSteven Rostedt dodie "Failed on boot" if $failed; 9785a391fbfSSteven Rostedt 9792b7d9b21SSteven Rostedt do_run_test or $failed = 1; 9805f9b6cedSSteven Rostedt } 9817faafbd6SSteven Rostedt end_monitor; 9825f9b6cedSSteven Rostedt } 9835f9b6cedSSteven Rostedt 9845f9b6cedSSteven Rostedt if ($failed) { 9850a05c769SSteven Rostedt $result = 0; 9865a391fbfSSteven Rostedt 9875a391fbfSSteven Rostedt # reboot the box to a good kernel 988a75fececSSteven Rostedt if ($type ne "build") { 989a75fececSSteven Rostedt doprint "Reboot and sleep $bisect_sleep_time seconds\n"; 9905a391fbfSSteven Rostedt reboot; 9917faafbd6SSteven Rostedt start_monitor; 992a75fececSSteven Rostedt wait_for_monitor $bisect_sleep_time; 9937faafbd6SSteven Rostedt end_monitor; 9945a391fbfSSteven Rostedt } 9955f9b6cedSSteven Rostedt } else { 9960a05c769SSteven Rostedt $result = 1; 9975f9b6cedSSteven Rostedt } 9980a05c769SSteven Rostedt $in_bisect = 0; 9990a05c769SSteven Rostedt 10000a05c769SSteven Rostedt return $result; 10010a05c769SSteven Rostedt} 10020a05c769SSteven Rostedt 10030a05c769SSteven Rostedtsub run_bisect { 10040a05c769SSteven Rostedt my ($type) = @_; 10050a05c769SSteven Rostedt my $buildtype = "oldconfig"; 10060a05c769SSteven Rostedt 10070a05c769SSteven Rostedt # We should have a minconfig to use? 10080a05c769SSteven Rostedt if (defined($minconfig)) { 10090a05c769SSteven Rostedt $buildtype = "useconfig:$minconfig"; 10100a05c769SSteven Rostedt } 10110a05c769SSteven Rostedt 10120a05c769SSteven Rostedt my $ret = run_bisect_test $type, $buildtype; 10130a05c769SSteven Rostedt 10145f9b6cedSSteven Rostedt 1015d6ce2a0bSSteven Rostedt # Are we looking for where it worked, not failed? 1016d6ce2a0bSSteven Rostedt if ($reverse_bisect) { 10170a05c769SSteven Rostedt $ret = !$ret; 1018d6ce2a0bSSteven Rostedt } 1019d6ce2a0bSSteven Rostedt 10200a05c769SSteven Rostedt if ($ret) { 10210a05c769SSteven Rostedt return "good"; 10220a05c769SSteven Rostedt } else { 10230a05c769SSteven Rostedt return "bad"; 10240a05c769SSteven Rostedt } 10255f9b6cedSSteven Rostedt} 10265f9b6cedSSteven Rostedt 10275f9b6cedSSteven Rostedtsub bisect { 10285f9b6cedSSteven Rostedt my ($i) = @_; 10295f9b6cedSSteven Rostedt 10305f9b6cedSSteven Rostedt my $result; 10315f9b6cedSSteven Rostedt 10325f9b6cedSSteven Rostedt die "BISECT_GOOD[$i] not defined\n" if (!defined($opt{"BISECT_GOOD[$i]"})); 10335f9b6cedSSteven Rostedt die "BISECT_BAD[$i] not defined\n" if (!defined($opt{"BISECT_BAD[$i]"})); 10345f9b6cedSSteven Rostedt die "BISECT_TYPE[$i] not defined\n" if (!defined($opt{"BISECT_TYPE[$i]"})); 10355f9b6cedSSteven Rostedt 10365f9b6cedSSteven Rostedt my $good = $opt{"BISECT_GOOD[$i]"}; 10375f9b6cedSSteven Rostedt my $bad = $opt{"BISECT_BAD[$i]"}; 10385f9b6cedSSteven Rostedt my $type = $opt{"BISECT_TYPE[$i]"}; 1039a75fececSSteven Rostedt my $start = $opt{"BISECT_START[$i]"}; 1040a75fececSSteven Rostedt my $replay = $opt{"BISECT_REPLAY[$i]"}; 10415f9b6cedSSteven Rostedt 1042a57419b3SSteven Rostedt # convert to true sha1's 1043a57419b3SSteven Rostedt $good = get_sha1($good); 1044a57419b3SSteven Rostedt $bad = get_sha1($bad); 1045a57419b3SSteven Rostedt 1046d6ce2a0bSSteven Rostedt if (defined($opt{"BISECT_REVERSE[$i]"}) && 1047d6ce2a0bSSteven Rostedt $opt{"BISECT_REVERSE[$i]"} == 1) { 1048d6ce2a0bSSteven Rostedt doprint "Performing a reverse bisect (bad is good, good is bad!)\n"; 1049d6ce2a0bSSteven Rostedt $reverse_bisect = 1; 1050d6ce2a0bSSteven Rostedt } else { 1051d6ce2a0bSSteven Rostedt $reverse_bisect = 0; 1052d6ce2a0bSSteven Rostedt } 1053d6ce2a0bSSteven Rostedt 10545a391fbfSSteven Rostedt # Can't have a test without having a test to run 10555a391fbfSSteven Rostedt if ($type eq "test" && !defined($run_test)) { 10565a391fbfSSteven Rostedt $type = "boot"; 10575a391fbfSSteven Rostedt } 10585a391fbfSSteven Rostedt 1059a75fececSSteven Rostedt my $check = $opt{"BISECT_CHECK[$i]"}; 1060a75fececSSteven Rostedt if (defined($check) && $check ne "0") { 1061a75fececSSteven Rostedt 1062a75fececSSteven Rostedt # get current HEAD 1063a57419b3SSteven Rostedt my $head = get_sha1("HEAD"); 1064a75fececSSteven Rostedt 1065a75fececSSteven Rostedt if ($check ne "good") { 1066a75fececSSteven Rostedt doprint "TESTING BISECT BAD [$bad]\n"; 1067a75fececSSteven Rostedt run_command "git checkout $bad" or 1068a75fececSSteven Rostedt die "Failed to checkout $bad"; 1069a75fececSSteven Rostedt 1070a75fececSSteven Rostedt $result = run_bisect $type; 1071a75fececSSteven Rostedt 1072a75fececSSteven Rostedt if ($result ne "bad") { 1073a75fececSSteven Rostedt fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0; 1074a75fececSSteven Rostedt } 1075a75fececSSteven Rostedt } 1076a75fececSSteven Rostedt 1077a75fececSSteven Rostedt if ($check ne "bad") { 1078a75fececSSteven Rostedt doprint "TESTING BISECT GOOD [$good]\n"; 1079a75fececSSteven Rostedt run_command "git checkout $good" or 1080a75fececSSteven Rostedt die "Failed to checkout $good"; 1081a75fececSSteven Rostedt 1082a75fececSSteven Rostedt $result = run_bisect $type; 1083a75fececSSteven Rostedt 1084a75fececSSteven Rostedt if ($result ne "good") { 1085a75fececSSteven Rostedt fail "Tested BISECT_GOOD [$good] and it failed" and return 0; 1086a75fececSSteven Rostedt } 1087a75fececSSteven Rostedt } 1088a75fececSSteven Rostedt 1089a75fececSSteven Rostedt # checkout where we started 1090a75fececSSteven Rostedt run_command "git checkout $head" or 1091a75fececSSteven Rostedt die "Failed to checkout $head"; 1092a75fececSSteven Rostedt } 1093a75fececSSteven Rostedt 1094a75fececSSteven Rostedt run_command "git bisect start" or 1095a75fececSSteven Rostedt dodie "could not start bisect"; 1096a75fececSSteven Rostedt 1097a75fececSSteven Rostedt run_command "git bisect good $good" or 1098a75fececSSteven Rostedt dodie "could not set bisect good to $good"; 1099a75fececSSteven Rostedt 1100a75fececSSteven Rostedt run_git_bisect "git bisect bad $bad" or 1101a75fececSSteven Rostedt dodie "could not set bisect bad to $bad"; 1102a75fececSSteven Rostedt 1103a75fececSSteven Rostedt if (defined($replay)) { 1104a75fececSSteven Rostedt run_command "git bisect replay $replay" or 1105a75fececSSteven Rostedt dodie "failed to run replay"; 1106a75fececSSteven Rostedt } 1107a75fececSSteven Rostedt 1108a75fececSSteven Rostedt if (defined($start)) { 1109a75fececSSteven Rostedt run_command "git checkout $start" or 1110a75fececSSteven Rostedt dodie "failed to checkout $start"; 1111a75fececSSteven Rostedt } 1112a75fececSSteven Rostedt 1113a75fececSSteven Rostedt my $test; 11145f9b6cedSSteven Rostedt do { 11155f9b6cedSSteven Rostedt $result = run_bisect $type; 1116a75fececSSteven Rostedt $test = run_git_bisect "git bisect $result"; 1117a75fececSSteven Rostedt } while ($test); 11185f9b6cedSSteven Rostedt 11195f9b6cedSSteven Rostedt run_command "git bisect log" or 11205f9b6cedSSteven Rostedt dodie "could not capture git bisect log"; 11215f9b6cedSSteven Rostedt 11225f9b6cedSSteven Rostedt run_command "git bisect reset" or 11235f9b6cedSSteven Rostedt dodie "could not reset git bisect"; 11245f9b6cedSSteven Rostedt 11255f9b6cedSSteven Rostedt doprint "Bad commit was [$bisect_bad]\n"; 11265f9b6cedSSteven Rostedt 11270a05c769SSteven Rostedt success $i; 11280a05c769SSteven Rostedt} 11290a05c769SSteven Rostedt 11300a05c769SSteven Rostedtmy %config_ignore; 11310a05c769SSteven Rostedtmy %config_set; 11320a05c769SSteven Rostedt 11330a05c769SSteven Rostedtmy %config_list; 11340a05c769SSteven Rostedtmy %null_config; 11350a05c769SSteven Rostedt 11360a05c769SSteven Rostedtmy %dependency; 11370a05c769SSteven Rostedt 11380a05c769SSteven Rostedtsub process_config_ignore { 11390a05c769SSteven Rostedt my ($config) = @_; 11400a05c769SSteven Rostedt 11410a05c769SSteven Rostedt open (IN, $config) 11420a05c769SSteven Rostedt or dodie "Failed to read $config"; 11430a05c769SSteven Rostedt 11440a05c769SSteven Rostedt while (<IN>) { 11450a05c769SSteven Rostedt if (/^(.*?(CONFIG\S*)(=.*| is not set))/) { 11460a05c769SSteven Rostedt $config_ignore{$2} = $1; 11470a05c769SSteven Rostedt } 11480a05c769SSteven Rostedt } 11490a05c769SSteven Rostedt 11500a05c769SSteven Rostedt close(IN); 11510a05c769SSteven Rostedt} 11520a05c769SSteven Rostedt 11530a05c769SSteven Rostedtsub read_current_config { 11540a05c769SSteven Rostedt my ($config_ref) = @_; 11550a05c769SSteven Rostedt 11560a05c769SSteven Rostedt %{$config_ref} = (); 11570a05c769SSteven Rostedt undef %{$config_ref}; 11580a05c769SSteven Rostedt 11590a05c769SSteven Rostedt my @key = keys %{$config_ref}; 11600a05c769SSteven Rostedt if ($#key >= 0) { 11610a05c769SSteven Rostedt print "did not delete!\n"; 11620a05c769SSteven Rostedt exit; 11630a05c769SSteven Rostedt } 11640a05c769SSteven Rostedt open (IN, "$output_config"); 11650a05c769SSteven Rostedt 11660a05c769SSteven Rostedt while (<IN>) { 11670a05c769SSteven Rostedt if (/^(CONFIG\S+)=(.*)/) { 11680a05c769SSteven Rostedt ${$config_ref}{$1} = $2; 11690a05c769SSteven Rostedt } 11700a05c769SSteven Rostedt } 11710a05c769SSteven Rostedt close(IN); 11720a05c769SSteven Rostedt} 11730a05c769SSteven Rostedt 11740a05c769SSteven Rostedtsub get_dependencies { 11750a05c769SSteven Rostedt my ($config) = @_; 11760a05c769SSteven Rostedt 11770a05c769SSteven Rostedt my $arr = $dependency{$config}; 11780a05c769SSteven Rostedt if (!defined($arr)) { 11790a05c769SSteven Rostedt return (); 11800a05c769SSteven Rostedt } 11810a05c769SSteven Rostedt 11820a05c769SSteven Rostedt my @deps = @{$arr}; 11830a05c769SSteven Rostedt 11840a05c769SSteven Rostedt foreach my $dep (@{$arr}) { 11850a05c769SSteven Rostedt print "ADD DEP $dep\n"; 11860a05c769SSteven Rostedt @deps = (@deps, get_dependencies $dep); 11870a05c769SSteven Rostedt } 11880a05c769SSteven Rostedt 11890a05c769SSteven Rostedt return @deps; 11900a05c769SSteven Rostedt} 11910a05c769SSteven Rostedt 11920a05c769SSteven Rostedtsub create_config { 11930a05c769SSteven Rostedt my @configs = @_; 11940a05c769SSteven Rostedt 11950a05c769SSteven Rostedt open(OUT, ">$output_config") or dodie "Can not write to $output_config"; 11960a05c769SSteven Rostedt 11970a05c769SSteven Rostedt foreach my $config (@configs) { 11980a05c769SSteven Rostedt print OUT "$config_set{$config}\n"; 11990a05c769SSteven Rostedt my @deps = get_dependencies $config; 12000a05c769SSteven Rostedt foreach my $dep (@deps) { 12010a05c769SSteven Rostedt print OUT "$config_set{$dep}\n"; 12020a05c769SSteven Rostedt } 12030a05c769SSteven Rostedt } 12040a05c769SSteven Rostedt 12050a05c769SSteven Rostedt foreach my $config (keys %config_ignore) { 12060a05c769SSteven Rostedt print OUT "$config_ignore{$config}\n"; 12070a05c769SSteven Rostedt } 12080a05c769SSteven Rostedt close(OUT); 12090a05c769SSteven Rostedt 12100a05c769SSteven Rostedt# exit; 12110a05c769SSteven Rostedt run_command "$make oldnoconfig" or 12120a05c769SSteven Rostedt dodie "failed make config oldconfig"; 12130a05c769SSteven Rostedt 12140a05c769SSteven Rostedt} 12150a05c769SSteven Rostedt 12160a05c769SSteven Rostedtsub compare_configs { 12170a05c769SSteven Rostedt my (%a, %b) = @_; 12180a05c769SSteven Rostedt 12190a05c769SSteven Rostedt foreach my $item (keys %a) { 12200a05c769SSteven Rostedt if (!defined($b{$item})) { 12210a05c769SSteven Rostedt print "diff $item\n"; 12220a05c769SSteven Rostedt return 1; 12230a05c769SSteven Rostedt } 12240a05c769SSteven Rostedt delete $b{$item}; 12250a05c769SSteven Rostedt } 12260a05c769SSteven Rostedt 12270a05c769SSteven Rostedt my @keys = keys %b; 12280a05c769SSteven Rostedt if ($#keys) { 12290a05c769SSteven Rostedt print "diff2 $keys[0]\n"; 12300a05c769SSteven Rostedt } 12310a05c769SSteven Rostedt return -1 if ($#keys >= 0); 12320a05c769SSteven Rostedt 12330a05c769SSteven Rostedt return 0; 12340a05c769SSteven Rostedt} 12350a05c769SSteven Rostedt 12360a05c769SSteven Rostedtsub run_config_bisect_test { 12370a05c769SSteven Rostedt my ($type) = @_; 12380a05c769SSteven Rostedt 12390a05c769SSteven Rostedt return run_bisect_test $type, "oldconfig"; 12400a05c769SSteven Rostedt} 12410a05c769SSteven Rostedt 12420a05c769SSteven Rostedtsub process_passed { 12430a05c769SSteven Rostedt my (%configs) = @_; 12440a05c769SSteven Rostedt 12450a05c769SSteven Rostedt doprint "These configs had no failure: (Enabling them for further compiles)\n"; 12460a05c769SSteven Rostedt # Passed! All these configs are part of a good compile. 12470a05c769SSteven Rostedt # Add them to the min options. 12480a05c769SSteven Rostedt foreach my $config (keys %configs) { 12490a05c769SSteven Rostedt if (defined($config_list{$config})) { 12500a05c769SSteven Rostedt doprint " removing $config\n"; 12510a05c769SSteven Rostedt $config_ignore{$config} = $config_list{$config}; 12520a05c769SSteven Rostedt delete $config_list{$config}; 12530a05c769SSteven Rostedt } 12540a05c769SSteven Rostedt } 12550a05c769SSteven Rostedt} 12560a05c769SSteven Rostedt 12570a05c769SSteven Rostedtsub process_failed { 12580a05c769SSteven Rostedt my ($config) = @_; 12590a05c769SSteven Rostedt 12600a05c769SSteven Rostedt doprint "\n\n***************************************\n"; 12610a05c769SSteven Rostedt doprint "Found bad config: $config\n"; 12620a05c769SSteven Rostedt doprint "***************************************\n\n"; 12630a05c769SSteven Rostedt} 12640a05c769SSteven Rostedt 12650a05c769SSteven Rostedtsub run_config_bisect { 12660a05c769SSteven Rostedt 12670a05c769SSteven Rostedt my @start_list = keys %config_list; 12680a05c769SSteven Rostedt 12690a05c769SSteven Rostedt if ($#start_list < 0) { 12700a05c769SSteven Rostedt doprint "No more configs to test!!!\n"; 12710a05c769SSteven Rostedt return -1; 12720a05c769SSteven Rostedt } 12730a05c769SSteven Rostedt 12740a05c769SSteven Rostedt doprint "***** RUN TEST ***\n"; 12750a05c769SSteven Rostedt my $type = $opt{"CONFIG_BISECT_TYPE[$iteration]"}; 12760a05c769SSteven Rostedt my $ret; 12770a05c769SSteven Rostedt my %current_config; 12780a05c769SSteven Rostedt 12790a05c769SSteven Rostedt my $count = $#start_list + 1; 12800a05c769SSteven Rostedt doprint " $count configs to test\n"; 12810a05c769SSteven Rostedt 12820a05c769SSteven Rostedt my $half = int($#start_list / 2); 12830a05c769SSteven Rostedt 12840a05c769SSteven Rostedt do { 12850a05c769SSteven Rostedt my @tophalf = @start_list[0 .. $half]; 12860a05c769SSteven Rostedt 12870a05c769SSteven Rostedt create_config @tophalf; 12880a05c769SSteven Rostedt read_current_config \%current_config; 12890a05c769SSteven Rostedt 12900a05c769SSteven Rostedt $count = $#tophalf + 1; 12910a05c769SSteven Rostedt doprint "Testing $count configs\n"; 12920a05c769SSteven Rostedt my $found = 0; 12930a05c769SSteven Rostedt # make sure we test something 12940a05c769SSteven Rostedt foreach my $config (@tophalf) { 12950a05c769SSteven Rostedt if (defined($current_config{$config})) { 12960a05c769SSteven Rostedt logit " $config\n"; 12970a05c769SSteven Rostedt $found = 1; 12980a05c769SSteven Rostedt } 12990a05c769SSteven Rostedt } 13000a05c769SSteven Rostedt if (!$found) { 13010a05c769SSteven Rostedt # try the other half 13020a05c769SSteven Rostedt doprint "Top half produced no set configs, trying bottom half\n"; 13030a05c769SSteven Rostedt @tophalf = @start_list[$half .. $#start_list]; 13040a05c769SSteven Rostedt create_config @tophalf; 13050a05c769SSteven Rostedt read_current_config \%current_config; 13060a05c769SSteven Rostedt foreach my $config (@tophalf) { 13070a05c769SSteven Rostedt if (defined($current_config{$config})) { 13080a05c769SSteven Rostedt logit " $config\n"; 13090a05c769SSteven Rostedt $found = 1; 13100a05c769SSteven Rostedt } 13110a05c769SSteven Rostedt } 13120a05c769SSteven Rostedt if (!$found) { 13130a05c769SSteven Rostedt doprint "Failed: Can't make new config with current configs\n"; 13140a05c769SSteven Rostedt foreach my $config (@start_list) { 13150a05c769SSteven Rostedt doprint " CONFIG: $config\n"; 13160a05c769SSteven Rostedt } 13170a05c769SSteven Rostedt return -1; 13180a05c769SSteven Rostedt } 13190a05c769SSteven Rostedt $count = $#tophalf + 1; 13200a05c769SSteven Rostedt doprint "Testing $count configs\n"; 13210a05c769SSteven Rostedt } 13220a05c769SSteven Rostedt 13230a05c769SSteven Rostedt $ret = run_config_bisect_test $type; 13240a05c769SSteven Rostedt 13250a05c769SSteven Rostedt if ($ret) { 13260a05c769SSteven Rostedt process_passed %current_config; 13270a05c769SSteven Rostedt return 0; 13280a05c769SSteven Rostedt } 13290a05c769SSteven Rostedt 13300a05c769SSteven Rostedt doprint "This config had a failure.\n"; 13310a05c769SSteven Rostedt doprint "Removing these configs that were not set in this config:\n"; 13320a05c769SSteven Rostedt 13330a05c769SSteven Rostedt # A config exists in this group that was bad. 13340a05c769SSteven Rostedt foreach my $config (keys %config_list) { 13350a05c769SSteven Rostedt if (!defined($current_config{$config})) { 13360a05c769SSteven Rostedt doprint " removing $config\n"; 13370a05c769SSteven Rostedt delete $config_list{$config}; 13380a05c769SSteven Rostedt } 13390a05c769SSteven Rostedt } 13400a05c769SSteven Rostedt 13410a05c769SSteven Rostedt @start_list = @tophalf; 13420a05c769SSteven Rostedt 13430a05c769SSteven Rostedt if ($#start_list == 0) { 13440a05c769SSteven Rostedt process_failed $start_list[0]; 13450a05c769SSteven Rostedt return 1; 13460a05c769SSteven Rostedt } 13470a05c769SSteven Rostedt 13480a05c769SSteven Rostedt # remove half the configs we are looking at and see if 13490a05c769SSteven Rostedt # they are good. 13500a05c769SSteven Rostedt $half = int($#start_list / 2); 13510a05c769SSteven Rostedt } while ($half > 0); 13520a05c769SSteven Rostedt 13530a05c769SSteven Rostedt # we found a single config, try it again 13540a05c769SSteven Rostedt my @tophalf = @start_list[0 .. 0]; 13550a05c769SSteven Rostedt 13560a05c769SSteven Rostedt $ret = run_config_bisect_test $type; 13570a05c769SSteven Rostedt if ($ret) { 13580a05c769SSteven Rostedt process_passed %current_config; 13590a05c769SSteven Rostedt return 0; 13600a05c769SSteven Rostedt } 13610a05c769SSteven Rostedt 13620a05c769SSteven Rostedt process_failed $start_list[0]; 13630a05c769SSteven Rostedt return 1; 13640a05c769SSteven Rostedt} 13650a05c769SSteven Rostedt 13660a05c769SSteven Rostedtsub config_bisect { 13670a05c769SSteven Rostedt my ($i) = @_; 13680a05c769SSteven Rostedt 13690a05c769SSteven Rostedt my $start_config = $opt{"CONFIG_BISECT[$i]"}; 13700a05c769SSteven Rostedt 13710a05c769SSteven Rostedt my $tmpconfig = "$tmpdir/use_config"; 13720a05c769SSteven Rostedt 13730a05c769SSteven Rostedt # Make the file with the bad config and the min config 13740a05c769SSteven Rostedt if (defined($minconfig)) { 13750a05c769SSteven Rostedt # read the min config for things to ignore 13760a05c769SSteven Rostedt run_command "cp $minconfig $tmpconfig" or 13770a05c769SSteven Rostedt dodie "failed to copy $minconfig to $tmpconfig"; 13780a05c769SSteven Rostedt } else { 13790a05c769SSteven Rostedt unlink $tmpconfig; 13800a05c769SSteven Rostedt } 13810a05c769SSteven Rostedt 13820a05c769SSteven Rostedt # Add other configs 13830a05c769SSteven Rostedt if (defined($addconfig)) { 13840a05c769SSteven Rostedt run_command "cat $addconfig >> $tmpconfig" or 13850a05c769SSteven Rostedt dodie "failed to append $addconfig"; 13860a05c769SSteven Rostedt } 13870a05c769SSteven Rostedt 13880a05c769SSteven Rostedt my $defconfig = ""; 13890a05c769SSteven Rostedt if (-f $tmpconfig) { 13900a05c769SSteven Rostedt $defconfig = "KCONFIG_ALLCONFIG=$tmpconfig"; 13910a05c769SSteven Rostedt process_config_ignore $tmpconfig; 13920a05c769SSteven Rostedt } 13930a05c769SSteven Rostedt 13940a05c769SSteven Rostedt # now process the start config 13950a05c769SSteven Rostedt run_command "cp $start_config $output_config" or 13960a05c769SSteven Rostedt dodie "failed to copy $start_config to $output_config"; 13970a05c769SSteven Rostedt 13980a05c769SSteven Rostedt # read directly what we want to check 13990a05c769SSteven Rostedt my %config_check; 14000a05c769SSteven Rostedt open (IN, $output_config) 14010a05c769SSteven Rostedt or dodie "faied to open $output_config"; 14020a05c769SSteven Rostedt 14030a05c769SSteven Rostedt while (<IN>) { 14040a05c769SSteven Rostedt if (/^((CONFIG\S*)=.*)/) { 14050a05c769SSteven Rostedt $config_check{$2} = $1; 14060a05c769SSteven Rostedt } 14070a05c769SSteven Rostedt } 14080a05c769SSteven Rostedt close(IN); 14090a05c769SSteven Rostedt 14100a05c769SSteven Rostedt # Now run oldconfig with the minconfig (and addconfigs) 14110a05c769SSteven Rostedt run_command "$defconfig $make oldnoconfig" or 14120a05c769SSteven Rostedt dodie "failed make config oldconfig"; 14130a05c769SSteven Rostedt 14140a05c769SSteven Rostedt # check to see what we lost (or gained) 14150a05c769SSteven Rostedt open (IN, $output_config) 14160a05c769SSteven Rostedt or dodie "Failed to read $start_config"; 14170a05c769SSteven Rostedt 14180a05c769SSteven Rostedt my %removed_configs; 14190a05c769SSteven Rostedt my %added_configs; 14200a05c769SSteven Rostedt 14210a05c769SSteven Rostedt while (<IN>) { 14220a05c769SSteven Rostedt if (/^((CONFIG\S*)=.*)/) { 14230a05c769SSteven Rostedt # save off all options 14240a05c769SSteven Rostedt $config_set{$2} = $1; 14250a05c769SSteven Rostedt if (defined($config_check{$2})) { 14260a05c769SSteven Rostedt if (defined($config_ignore{$2})) { 14270a05c769SSteven Rostedt $removed_configs{$2} = $1; 14280a05c769SSteven Rostedt } else { 14290a05c769SSteven Rostedt $config_list{$2} = $1; 14300a05c769SSteven Rostedt } 14310a05c769SSteven Rostedt } elsif (!defined($config_ignore{$2})) { 14320a05c769SSteven Rostedt $added_configs{$2} = $1; 14330a05c769SSteven Rostedt $config_list{$2} = $1; 14340a05c769SSteven Rostedt } 14350a05c769SSteven Rostedt } 14360a05c769SSteven Rostedt } 14370a05c769SSteven Rostedt close(IN); 14380a05c769SSteven Rostedt 14390a05c769SSteven Rostedt my @confs = keys %removed_configs; 14400a05c769SSteven Rostedt if ($#confs >= 0) { 14410a05c769SSteven Rostedt doprint "Configs overridden by default configs and removed from check:\n"; 14420a05c769SSteven Rostedt foreach my $config (@confs) { 14430a05c769SSteven Rostedt doprint " $config\n"; 14440a05c769SSteven Rostedt } 14450a05c769SSteven Rostedt } 14460a05c769SSteven Rostedt @confs = keys %added_configs; 14470a05c769SSteven Rostedt if ($#confs >= 0) { 14480a05c769SSteven Rostedt doprint "Configs appearing in make oldconfig and added:\n"; 14490a05c769SSteven Rostedt foreach my $config (@confs) { 14500a05c769SSteven Rostedt doprint " $config\n"; 14510a05c769SSteven Rostedt } 14520a05c769SSteven Rostedt } 14530a05c769SSteven Rostedt 14540a05c769SSteven Rostedt my %config_test; 14550a05c769SSteven Rostedt my $once = 0; 14560a05c769SSteven Rostedt 14570a05c769SSteven Rostedt # Sometimes kconfig does weird things. We must make sure 14580a05c769SSteven Rostedt # that the config we autocreate has everything we need 14590a05c769SSteven Rostedt # to test, otherwise we may miss testing configs, or 14600a05c769SSteven Rostedt # may not be able to create a new config. 14610a05c769SSteven Rostedt # Here we create a config with everything set. 14620a05c769SSteven Rostedt create_config (keys %config_list); 14630a05c769SSteven Rostedt read_current_config \%config_test; 14640a05c769SSteven Rostedt foreach my $config (keys %config_list) { 14650a05c769SSteven Rostedt if (!defined($config_test{$config})) { 14660a05c769SSteven Rostedt if (!$once) { 14670a05c769SSteven Rostedt $once = 1; 14680a05c769SSteven Rostedt doprint "Configs not produced by kconfig (will not be checked):\n"; 14690a05c769SSteven Rostedt } 14700a05c769SSteven Rostedt doprint " $config\n"; 14710a05c769SSteven Rostedt delete $config_list{$config}; 14720a05c769SSteven Rostedt } 14730a05c769SSteven Rostedt } 14740a05c769SSteven Rostedt my $ret; 14750a05c769SSteven Rostedt do { 14760a05c769SSteven Rostedt $ret = run_config_bisect; 14770a05c769SSteven Rostedt } while (!$ret); 14780a05c769SSteven Rostedt 14790a05c769SSteven Rostedt return $ret if ($ret < 0); 14805f9b6cedSSteven Rostedt 14815f9b6cedSSteven Rostedt success $i; 14825f9b6cedSSteven Rostedt} 14835f9b6cedSSteven Rostedt 14846c5ee0beSSteven Rostedtsub patchcheck { 14856c5ee0beSSteven Rostedt my ($i) = @_; 14866c5ee0beSSteven Rostedt 14876c5ee0beSSteven Rostedt die "PATCHCHECK_START[$i] not defined\n" 14886c5ee0beSSteven Rostedt if (!defined($opt{"PATCHCHECK_START[$i]"})); 14896c5ee0beSSteven Rostedt die "PATCHCHECK_TYPE[$i] not defined\n" 14906c5ee0beSSteven Rostedt if (!defined($opt{"PATCHCHECK_TYPE[$i]"})); 14916c5ee0beSSteven Rostedt 14926c5ee0beSSteven Rostedt my $start = $opt{"PATCHCHECK_START[$i]"}; 14936c5ee0beSSteven Rostedt 14946c5ee0beSSteven Rostedt my $end = "HEAD"; 14956c5ee0beSSteven Rostedt if (defined($opt{"PATCHCHECK_END[$i]"})) { 14966c5ee0beSSteven Rostedt $end = $opt{"PATCHCHECK_END[$i]"}; 14976c5ee0beSSteven Rostedt } 14986c5ee0beSSteven Rostedt 1499a57419b3SSteven Rostedt # Get the true sha1's since we can use things like HEAD~3 1500a57419b3SSteven Rostedt $start = get_sha1($start); 1501a57419b3SSteven Rostedt $end = get_sha1($end); 1502a57419b3SSteven Rostedt 15036c5ee0beSSteven Rostedt my $type = $opt{"PATCHCHECK_TYPE[$i]"}; 15046c5ee0beSSteven Rostedt 15056c5ee0beSSteven Rostedt # Can't have a test without having a test to run 15066c5ee0beSSteven Rostedt if ($type eq "test" && !defined($run_test)) { 15076c5ee0beSSteven Rostedt $type = "boot"; 15086c5ee0beSSteven Rostedt } 15096c5ee0beSSteven Rostedt 15106c5ee0beSSteven Rostedt open (IN, "git log --pretty=oneline $end|") or 15116c5ee0beSSteven Rostedt dodie "could not get git list"; 15126c5ee0beSSteven Rostedt 15136c5ee0beSSteven Rostedt my @list; 15146c5ee0beSSteven Rostedt 15156c5ee0beSSteven Rostedt while (<IN>) { 15166c5ee0beSSteven Rostedt chomp; 15176c5ee0beSSteven Rostedt $list[$#list+1] = $_; 15186c5ee0beSSteven Rostedt last if (/^$start/); 15196c5ee0beSSteven Rostedt } 15206c5ee0beSSteven Rostedt close(IN); 15216c5ee0beSSteven Rostedt 15226c5ee0beSSteven Rostedt if ($list[$#list] !~ /^$start/) { 15232b7d9b21SSteven Rostedt fail "SHA1 $start not found"; 15246c5ee0beSSteven Rostedt } 15256c5ee0beSSteven Rostedt 15266c5ee0beSSteven Rostedt # go backwards in the list 15276c5ee0beSSteven Rostedt @list = reverse @list; 15286c5ee0beSSteven Rostedt 15296c5ee0beSSteven Rostedt my $save_clean = $noclean; 15306c5ee0beSSteven Rostedt 15316c5ee0beSSteven Rostedt $in_patchcheck = 1; 15326c5ee0beSSteven Rostedt foreach my $item (@list) { 15336c5ee0beSSteven Rostedt my $sha1 = $item; 15346c5ee0beSSteven Rostedt $sha1 =~ s/^([[:xdigit:]]+).*/$1/; 15356c5ee0beSSteven Rostedt 15366c5ee0beSSteven Rostedt doprint "\nProcessing commit $item\n\n"; 15376c5ee0beSSteven Rostedt 15386c5ee0beSSteven Rostedt run_command "git checkout $sha1" or 15396c5ee0beSSteven Rostedt die "Failed to checkout $sha1"; 15406c5ee0beSSteven Rostedt 15416c5ee0beSSteven Rostedt # only clean on the first and last patch 15426c5ee0beSSteven Rostedt if ($item eq $list[0] || 15436c5ee0beSSteven Rostedt $item eq $list[$#list]) { 15446c5ee0beSSteven Rostedt $noclean = $save_clean; 15456c5ee0beSSteven Rostedt } else { 15466c5ee0beSSteven Rostedt $noclean = 1; 15476c5ee0beSSteven Rostedt } 15486c5ee0beSSteven Rostedt 15496c5ee0beSSteven Rostedt if (defined($minconfig)) { 15502b7d9b21SSteven Rostedt build "useconfig:$minconfig" or return 0; 15516c5ee0beSSteven Rostedt } else { 15526c5ee0beSSteven Rostedt # ?? no config to use? 15532b7d9b21SSteven Rostedt build "oldconfig" or return 0; 15546c5ee0beSSteven Rostedt } 15556c5ee0beSSteven Rostedt 15562b7d9b21SSteven Rostedt check_buildlog $sha1 or return 0; 15576c5ee0beSSteven Rostedt 15586c5ee0beSSteven Rostedt next if ($type eq "build"); 15596c5ee0beSSteven Rostedt 15606c5ee0beSSteven Rostedt get_grub_index; 15616c5ee0beSSteven Rostedt get_version; 15626c5ee0beSSteven Rostedt install; 15636c5ee0beSSteven Rostedt 15647faafbd6SSteven Rostedt my $failed = 0; 15657faafbd6SSteven Rostedt 15667faafbd6SSteven Rostedt start_monitor; 15677faafbd6SSteven Rostedt monitor or $failed = 1; 15687faafbd6SSteven Rostedt 15697faafbd6SSteven Rostedt if (!$failed && $type ne "boot"){ 15707faafbd6SSteven Rostedt do_run_test or $failed = 1; 15717faafbd6SSteven Rostedt } 15727faafbd6SSteven Rostedt end_monitor; 15737faafbd6SSteven Rostedt return 0 if ($failed); 15747faafbd6SSteven Rostedt 15756c5ee0beSSteven Rostedt } 15766c5ee0beSSteven Rostedt $in_patchcheck = 0; 15776c5ee0beSSteven Rostedt success $i; 15782b7d9b21SSteven Rostedt 15792b7d9b21SSteven Rostedt return 1; 15806c5ee0beSSteven Rostedt} 15816c5ee0beSSteven Rostedt 15822545eb61SSteven Rostedtread_config $ARGV[0]; 15832545eb61SSteven Rostedt 15842545eb61SSteven Rostedt# mandatory configs 15852545eb61SSteven Rostedtdie "MACHINE not defined\n" if (!defined($opt{"MACHINE"})); 15862545eb61SSteven Rostedtdie "SSH_USER not defined\n" if (!defined($opt{"SSH_USER"})); 15872545eb61SSteven Rostedtdie "BUILD_DIR not defined\n" if (!defined($opt{"BUILD_DIR"})); 15882545eb61SSteven Rostedtdie "OUTPUT_DIR not defined\n" if (!defined($opt{"OUTPUT_DIR"})); 15892545eb61SSteven Rostedtdie "BUILD_TARGET not defined\n" if (!defined($opt{"BUILD_TARGET"})); 159075c3fda7SSteven Rostedtdie "TARGET_IMAGE not defined\n" if (!defined($opt{"TARGET_IMAGE"})); 15912545eb61SSteven Rostedtdie "POWER_CYCLE not defined\n" if (!defined($opt{"POWER_CYCLE"})); 15922545eb61SSteven Rostedtdie "CONSOLE not defined\n" if (!defined($opt{"CONSOLE"})); 15932545eb61SSteven Rostedtdie "LOCALVERSION not defined\n" if (!defined($opt{"LOCALVERSION"})); 15942545eb61SSteven Rostedt 15952b7d9b21SSteven Rostedtif ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) { 15962b7d9b21SSteven Rostedt unlink $opt{"LOG_FILE"}; 15972b7d9b21SSteven Rostedt} 15982545eb61SSteven Rostedt 15992b7d9b21SSteven Rostedtdoprint "\n\nSTARTING AUTOMATED TESTS\n\n"; 16002b7d9b21SSteven Rostedt 1601a57419b3SSteven Rostedtfor (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) { 1602a57419b3SSteven Rostedt 1603a57419b3SSteven Rostedt if (!$i) { 1604a57419b3SSteven Rostedt doprint "DEFAULT OPTIONS:\n"; 1605a57419b3SSteven Rostedt } else { 1606a57419b3SSteven Rostedt doprint "\nTEST $i OPTIONS"; 1607a57419b3SSteven Rostedt if (defined($repeat_tests{$i})) { 1608a57419b3SSteven Rostedt $repeat = $repeat_tests{$i}; 1609a57419b3SSteven Rostedt doprint " ITERATE $repeat"; 1610a57419b3SSteven Rostedt } 1611a57419b3SSteven Rostedt doprint "\n"; 1612a57419b3SSteven Rostedt } 1613a57419b3SSteven Rostedt 16142b7d9b21SSteven Rostedt foreach my $option (sort keys %opt) { 1615a57419b3SSteven Rostedt 1616a57419b3SSteven Rostedt if ($option =~ /\[(\d+)\]$/) { 1617a57419b3SSteven Rostedt next if ($i != $1); 1618a57419b3SSteven Rostedt } else { 1619a57419b3SSteven Rostedt next if ($i); 1620a57419b3SSteven Rostedt } 1621a57419b3SSteven Rostedt 16222b7d9b21SSteven Rostedt doprint "$option = $opt{$option}\n"; 16232b7d9b21SSteven Rostedt } 1624a57419b3SSteven Rostedt} 16252545eb61SSteven Rostedt 1626a75fececSSteven Rostedtsub set_test_option { 16275a391fbfSSteven Rostedt my ($name, $i) = @_; 16285a391fbfSSteven Rostedt 16295a391fbfSSteven Rostedt my $option = "$name\[$i\]"; 16305a391fbfSSteven Rostedt 16315a391fbfSSteven Rostedt if (defined($opt{$option})) { 16325a391fbfSSteven Rostedt return $opt{$option}; 16335a391fbfSSteven Rostedt } 16345a391fbfSSteven Rostedt 1635a57419b3SSteven Rostedt foreach my $test (keys %repeat_tests) { 1636a57419b3SSteven Rostedt if ($i >= $test && 1637a57419b3SSteven Rostedt $i < $test + $repeat_tests{$test}) { 1638a57419b3SSteven Rostedt $option = "$name\[$test\]"; 1639a57419b3SSteven Rostedt if (defined($opt{$option})) { 1640a57419b3SSteven Rostedt return $opt{$option}; 1641a57419b3SSteven Rostedt } 1642a57419b3SSteven Rostedt } 1643a57419b3SSteven Rostedt } 1644a57419b3SSteven Rostedt 16455a391fbfSSteven Rostedt if (defined($opt{$name})) { 16465a391fbfSSteven Rostedt return $opt{$name}; 16475a391fbfSSteven Rostedt } 16485a391fbfSSteven Rostedt 16495a391fbfSSteven Rostedt return undef; 16505a391fbfSSteven Rostedt} 16515a391fbfSSteven Rostedt 16522545eb61SSteven Rostedt# First we need to do is the builds 1653a75fececSSteven Rostedtfor (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) { 16542545eb61SSteven Rostedt 1655576f627cSSteven Rostedt $iteration = $i; 1656576f627cSSteven Rostedt 1657a75fececSSteven Rostedt my $makecmd = set_test_option("MAKE_CMD", $i); 1658a75fececSSteven Rostedt 1659a75fececSSteven Rostedt $machine = set_test_option("MACHINE", $i); 1660e48c5293SSteven Rostedt $ssh_user = set_test_option("SSH_USER", $i); 1661a75fececSSteven Rostedt $tmpdir = set_test_option("TMP_DIR", $i); 1662a75fececSSteven Rostedt $outputdir = set_test_option("OUTPUT_DIR", $i); 1663a75fececSSteven Rostedt $builddir = set_test_option("BUILD_DIR", $i); 1664a75fececSSteven Rostedt $test_type = set_test_option("TEST_TYPE", $i); 1665a75fececSSteven Rostedt $build_type = set_test_option("BUILD_TYPE", $i); 1666a75fececSSteven Rostedt $build_options = set_test_option("BUILD_OPTIONS", $i); 1667a75fececSSteven Rostedt $power_cycle = set_test_option("POWER_CYCLE", $i); 1668e48c5293SSteven Rostedt $reboot = set_test_option("REBOOT", $i); 1669a75fececSSteven Rostedt $noclean = set_test_option("BUILD_NOCLEAN", $i); 1670a75fececSSteven Rostedt $minconfig = set_test_option("MIN_CONFIG", $i); 1671a75fececSSteven Rostedt $run_test = set_test_option("TEST", $i); 1672a75fececSSteven Rostedt $addconfig = set_test_option("ADD_CONFIG", $i); 1673a75fececSSteven Rostedt $reboot_type = set_test_option("REBOOT_TYPE", $i); 1674a75fececSSteven Rostedt $grub_menu = set_test_option("GRUB_MENU", $i); 16758b37ca8cSSteven Rostedt $post_install = set_test_option("POST_INSTALL", $i); 1676a75fececSSteven Rostedt $reboot_script = set_test_option("REBOOT_SCRIPT", $i); 1677a75fececSSteven Rostedt $reboot_on_error = set_test_option("REBOOT_ON_ERROR", $i); 1678a75fececSSteven Rostedt $poweroff_on_error = set_test_option("POWEROFF_ON_ERROR", $i); 1679a75fececSSteven Rostedt $die_on_failure = set_test_option("DIE_ON_FAILURE", $i); 1680a75fececSSteven Rostedt $power_off = set_test_option("POWER_OFF", $i); 1681576f627cSSteven Rostedt $powercycle_after_reboot = set_test_option("POWERCYCLE_AFTER_REBOOT", $i); 1682576f627cSSteven Rostedt $poweroff_after_halt = set_test_option("POWEROFF_AFTER_HALT", $i); 1683a75fececSSteven Rostedt $sleep_time = set_test_option("SLEEP_TIME", $i); 1684a75fececSSteven Rostedt $bisect_sleep_time = set_test_option("BISECT_SLEEP_TIME", $i); 1685a75fececSSteven Rostedt $store_failures = set_test_option("STORE_FAILURES", $i); 1686a75fececSSteven Rostedt $timeout = set_test_option("TIMEOUT", $i); 1687a75fececSSteven Rostedt $booted_timeout = set_test_option("BOOTED_TIMEOUT", $i); 1688a75fececSSteven Rostedt $console = set_test_option("CONSOLE", $i); 1689a75fececSSteven Rostedt $success_line = set_test_option("SUCCESS_LINE", $i); 1690a75fececSSteven Rostedt $build_target = set_test_option("BUILD_TARGET", $i); 1691e48c5293SSteven Rostedt $ssh_exec = set_test_option("SSH_EXEC", $i); 1692e48c5293SSteven Rostedt $scp_to_target = set_test_option("SCP_TO_TARGET", $i); 1693a75fececSSteven Rostedt $target_image = set_test_option("TARGET_IMAGE", $i); 1694a75fececSSteven Rostedt $localversion = set_test_option("LOCALVERSION", $i); 1695a75fececSSteven Rostedt 1696a75fececSSteven Rostedt chdir $builddir || die "can't change directory to $builddir"; 1697a75fececSSteven Rostedt 1698a75fececSSteven Rostedt if (!-d $tmpdir) { 1699a75fececSSteven Rostedt mkpath($tmpdir) or 1700a75fececSSteven Rostedt die "can't create $tmpdir"; 1701a75fececSSteven Rostedt } 1702a75fececSSteven Rostedt 1703e48c5293SSteven Rostedt $ENV{"SSH_USER"} = $ssh_user; 1704e48c5293SSteven Rostedt $ENV{"MACHINE"} = $machine; 1705e48c5293SSteven Rostedt 1706a75fececSSteven Rostedt $target = "$ssh_user\@$machine"; 1707a75fececSSteven Rostedt 1708a75fececSSteven Rostedt $buildlog = "$tmpdir/buildlog-$machine"; 1709a75fececSSteven Rostedt $dmesg = "$tmpdir/dmesg-$machine"; 1710a75fececSSteven Rostedt $make = "$makecmd O=$outputdir"; 171151ad1dd1SSteven Rostedt $output_config = "$outputdir/.config"; 1712a75fececSSteven Rostedt 1713a75fececSSteven Rostedt if ($reboot_type eq "grub") { 1714576f627cSSteven Rostedt dodie "GRUB_MENU not defined" if (!defined($grub_menu)); 1715a75fececSSteven Rostedt } elsif (!defined($reboot_script)) { 1716576f627cSSteven Rostedt dodie "REBOOT_SCRIPT not defined" 1717a75fececSSteven Rostedt } 1718a75fececSSteven Rostedt 1719a75fececSSteven Rostedt my $run_type = $build_type; 1720a75fececSSteven Rostedt if ($test_type eq "patchcheck") { 1721a75fececSSteven Rostedt $run_type = $opt{"PATCHCHECK_TYPE[$i]"}; 1722a75fececSSteven Rostedt } elsif ($test_type eq "bisect") { 1723a75fececSSteven Rostedt $run_type = $opt{"BISECT_TYPE[$i]"}; 17240a05c769SSteven Rostedt } elsif ($test_type eq "config_bisect") { 17250a05c769SSteven Rostedt $run_type = $opt{"CONFIG_BISECT_TYPE[$i]"}; 1726a75fececSSteven Rostedt } 1727a75fececSSteven Rostedt 1728a75fececSSteven Rostedt # mistake in config file? 1729a75fececSSteven Rostedt if (!defined($run_type)) { 1730a75fececSSteven Rostedt $run_type = "ERROR"; 1731a75fececSSteven Rostedt } 17322545eb61SSteven Rostedt 17332545eb61SSteven Rostedt doprint "\n\n"; 1734a75fececSSteven Rostedt doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type\n\n"; 17357faafbd6SSteven Rostedt 17367faafbd6SSteven Rostedt unlink $dmesg; 17377faafbd6SSteven Rostedt unlink $buildlog; 17382545eb61SSteven Rostedt 17392b7d9b21SSteven Rostedt if (!defined($minconfig)) { 17402b7d9b21SSteven Rostedt $minconfig = $addconfig; 17412b7d9b21SSteven Rostedt 17422b7d9b21SSteven Rostedt } elsif (defined($addconfig)) { 17439be2e6b5SSteven Rostedt run_command "cat $addconfig $minconfig > $tmpdir/add_config" or 17442b7d9b21SSteven Rostedt dodie "Failed to create temp config"; 17459be2e6b5SSteven Rostedt $minconfig = "$tmpdir/add_config"; 17462b7d9b21SSteven Rostedt } 17472b7d9b21SSteven Rostedt 17486c5ee0beSSteven Rostedt my $checkout = $opt{"CHECKOUT[$i]"}; 17496c5ee0beSSteven Rostedt if (defined($checkout)) { 17506c5ee0beSSteven Rostedt run_command "git checkout $checkout" or 17516c5ee0beSSteven Rostedt die "failed to checkout $checkout"; 17526c5ee0beSSteven Rostedt } 17536c5ee0beSSteven Rostedt 1754a75fececSSteven Rostedt if ($test_type eq "bisect") { 17555f9b6cedSSteven Rostedt bisect $i; 17565f9b6cedSSteven Rostedt next; 17570a05c769SSteven Rostedt } elsif ($test_type eq "config_bisect") { 17580a05c769SSteven Rostedt config_bisect $i; 17590a05c769SSteven Rostedt next; 1760a75fececSSteven Rostedt } elsif ($test_type eq "patchcheck") { 17616c5ee0beSSteven Rostedt patchcheck $i; 17626c5ee0beSSteven Rostedt next; 17635f9b6cedSSteven Rostedt } 17645f9b6cedSSteven Rostedt 17657faafbd6SSteven Rostedt if ($build_type ne "nobuild") { 17667faafbd6SSteven Rostedt build $build_type or next; 17672545eb61SSteven Rostedt } 17682545eb61SSteven Rostedt 1769a75fececSSteven Rostedt if ($test_type ne "build") { 17705f9b6cedSSteven Rostedt get_grub_index; 17715f9b6cedSSteven Rostedt get_version; 17722545eb61SSteven Rostedt install; 17735a391fbfSSteven Rostedt 17747faafbd6SSteven Rostedt my $failed = 0; 17757faafbd6SSteven Rostedt start_monitor; 17767faafbd6SSteven Rostedt monitor or $failed = 1;; 1777a75fececSSteven Rostedt 1778a75fececSSteven Rostedt if (!$failed && $test_type ne "boot" && defined($run_test)) { 17797faafbd6SSteven Rostedt do_run_test or $failed = 1; 17805a391fbfSSteven Rostedt } 17817faafbd6SSteven Rostedt end_monitor; 17827faafbd6SSteven Rostedt next if ($failed); 1783a75fececSSteven Rostedt } 17845a391fbfSSteven Rostedt 17855f9b6cedSSteven Rostedt success $i; 178675c3fda7SSteven Rostedt} 17872545eb61SSteven Rostedt 17885c42fc5bSSteven Rostedtif ($opt{"POWEROFF_ON_SUCCESS"}) { 178975c3fda7SSteven Rostedt halt; 1790576f627cSSteven Rostedt} elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot) { 179175c3fda7SSteven Rostedt reboot; 17925c42fc5bSSteven Rostedt} 179375c3fda7SSteven Rostedt 1794e48c5293SSteven Rostedtdoprint "\n $successes of $opt{NUM_TESTS} tests were successful\n\n"; 1795e48c5293SSteven Rostedt 17962545eb61SSteven Rostedtexit 0; 1797