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 14a57419b3SSteven Rostedt$#ARGV >= 0 || die "usage: ktest.pl config-file\n"; 152545eb61SSteven Rostedt 162545eb61SSteven Rostedt$| = 1; 172545eb61SSteven Rostedt 182545eb61SSteven Rostedtmy %opt; 19a57419b3SSteven Rostedtmy %repeat_tests; 20a57419b3SSteven Rostedtmy %repeats; 21a75fececSSteven Rostedtmy %default; 222545eb61SSteven Rostedt 232545eb61SSteven Rostedt#default opts 24a57419b3SSteven Rostedt$default{"NUM_TESTS"} = 1; 25a75fececSSteven Rostedt$default{"REBOOT_TYPE"} = "grub"; 26a75fececSSteven Rostedt$default{"TEST_TYPE"} = "test"; 27a75fececSSteven Rostedt$default{"BUILD_TYPE"} = "randconfig"; 28a75fececSSteven Rostedt$default{"MAKE_CMD"} = "make"; 29a75fececSSteven Rostedt$default{"TIMEOUT"} = 120; 30a57419b3SSteven Rostedt$default{"TMP_DIR"} = "/tmp/ktest"; 31a75fececSSteven Rostedt$default{"SLEEP_TIME"} = 60; # sleep time between tests 32a75fececSSteven Rostedt$default{"BUILD_NOCLEAN"} = 0; 33a75fececSSteven Rostedt$default{"REBOOT_ON_ERROR"} = 0; 34a75fececSSteven Rostedt$default{"POWEROFF_ON_ERROR"} = 0; 35a75fececSSteven Rostedt$default{"REBOOT_ON_SUCCESS"} = 1; 36a75fececSSteven Rostedt$default{"POWEROFF_ON_SUCCESS"} = 0; 37a75fececSSteven Rostedt$default{"BUILD_OPTIONS"} = ""; 38a75fececSSteven Rostedt$default{"BISECT_SLEEP_TIME"} = 60; # sleep time between bisects 39a75fececSSteven Rostedt$default{"CLEAR_LOG"} = 0; 40a75fececSSteven Rostedt$default{"SUCCESS_LINE"} = "login:"; 41a75fececSSteven Rostedt$default{"BOOTED_TIMEOUT"} = 1; 42a75fececSSteven Rostedt$default{"DIE_ON_FAILURE"} = 1; 432545eb61SSteven Rostedt 442545eb61SSteven Rostedtmy $version; 45a75fececSSteven Rostedtmy $machine; 46a75fececSSteven Rostedtmy $tmpdir; 47a75fececSSteven Rostedtmy $builddir; 48a75fececSSteven Rostedtmy $outputdir; 49a75fececSSteven Rostedtmy $test_type; 507faafbd6SSteven Rostedtmy $build_type; 51a75fececSSteven Rostedtmy $build_options; 52a75fececSSteven Rostedtmy $reboot_type; 53a75fececSSteven Rostedtmy $reboot_script; 54a75fececSSteven Rostedtmy $power_cycle; 55a75fececSSteven Rostedtmy $reboot_on_error; 56a75fececSSteven Rostedtmy $poweroff_on_error; 57a75fececSSteven Rostedtmy $die_on_failure; 58576f627cSSteven Rostedtmy $powercycle_after_reboot; 59576f627cSSteven Rostedtmy $poweroff_after_halt; 60a75fececSSteven Rostedtmy $power_off; 61a75fececSSteven Rostedtmy $grub_menu; 622545eb61SSteven Rostedtmy $grub_number; 632545eb61SSteven Rostedtmy $target; 642545eb61SSteven Rostedtmy $make; 658b37ca8cSSteven Rostedtmy $post_install; 665c42fc5bSSteven Rostedtmy $noclean; 675f9b6cedSSteven Rostedtmy $minconfig; 682b7d9b21SSteven Rostedtmy $addconfig; 695f9b6cedSSteven Rostedtmy $in_bisect = 0; 705f9b6cedSSteven Rostedtmy $bisect_bad = ""; 71d6ce2a0bSSteven Rostedtmy $reverse_bisect; 726c5ee0beSSteven Rostedtmy $in_patchcheck = 0; 735a391fbfSSteven Rostedtmy $run_test; 746c5ee0beSSteven Rostedtmy $redirect; 757faafbd6SSteven Rostedtmy $buildlog; 767faafbd6SSteven Rostedtmy $dmesg; 777faafbd6SSteven Rostedtmy $monitor_fp; 787faafbd6SSteven Rostedtmy $monitor_pid; 797faafbd6SSteven Rostedtmy $monitor_cnt = 0; 80a75fececSSteven Rostedtmy $sleep_time; 81a75fececSSteven Rostedtmy $bisect_sleep_time; 82a75fececSSteven Rostedtmy $store_failures; 83a75fececSSteven Rostedtmy $timeout; 84a75fececSSteven Rostedtmy $booted_timeout; 85a75fececSSteven Rostedtmy $console; 86a75fececSSteven Rostedtmy $success_line; 87a75fececSSteven Rostedtmy $build_target; 88a75fececSSteven Rostedtmy $target_image; 89a75fececSSteven Rostedtmy $localversion; 90576f627cSSteven Rostedtmy $iteration = 0; 912545eb61SSteven Rostedt 92a57419b3SSteven Rostedtsub set_value { 93a57419b3SSteven Rostedt my ($lvalue, $rvalue) = @_; 942545eb61SSteven Rostedt 95a75fececSSteven Rostedt if (defined($opt{$lvalue})) { 96a75fececSSteven Rostedt die "Error: Option $lvalue defined more than once!\n"; 97a75fececSSteven Rostedt } 982545eb61SSteven Rostedt $opt{$lvalue} = $rvalue; 992545eb61SSteven Rostedt} 100a57419b3SSteven Rostedt 101a57419b3SSteven Rostedtsub read_config { 102a57419b3SSteven Rostedt my ($config) = @_; 103a57419b3SSteven Rostedt 104a57419b3SSteven Rostedt open(IN, $config) || die "can't read file $config"; 105a57419b3SSteven Rostedt 106a57419b3SSteven Rostedt my $name = $config; 107a57419b3SSteven Rostedt $name =~ s,.*/(.*),$1,; 108a57419b3SSteven Rostedt 109a57419b3SSteven Rostedt my $test_num = 0; 110a57419b3SSteven Rostedt my $default = 1; 111a57419b3SSteven Rostedt my $repeat = 1; 112a57419b3SSteven Rostedt my $num_tests_set = 0; 113a57419b3SSteven Rostedt my $skip = 0; 114a57419b3SSteven Rostedt my $rest; 115a57419b3SSteven Rostedt 116a57419b3SSteven Rostedt while (<IN>) { 117a57419b3SSteven Rostedt 118a57419b3SSteven Rostedt # ignore blank lines and comments 119a57419b3SSteven Rostedt next if (/^\s*$/ || /\s*\#/); 120a57419b3SSteven Rostedt 121a57419b3SSteven Rostedt if (/^\s*TEST_START(.*)/) { 122a57419b3SSteven Rostedt 123a57419b3SSteven Rostedt $rest = $1; 124a57419b3SSteven Rostedt 125a57419b3SSteven Rostedt if ($num_tests_set) { 126a57419b3SSteven Rostedt die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n"; 127a57419b3SSteven Rostedt } 128a57419b3SSteven Rostedt 129a57419b3SSteven Rostedt my $old_test_num = $test_num; 130a57419b3SSteven Rostedt 131a57419b3SSteven Rostedt $test_num += $repeat; 132a57419b3SSteven Rostedt $default = 0; 133a57419b3SSteven Rostedt $repeat = 1; 134a57419b3SSteven Rostedt 135a57419b3SSteven Rostedt if ($rest =~ /\s+SKIP(.*)/) { 136a57419b3SSteven Rostedt $rest = $1; 137a57419b3SSteven Rostedt $skip = 1; 138a57419b3SSteven Rostedt } else { 139a57419b3SSteven Rostedt $skip = 0; 140a57419b3SSteven Rostedt } 141a57419b3SSteven Rostedt 142a57419b3SSteven Rostedt if ($rest =~ /\s+ITERATE\s+(\d+)(.*)$/) { 143a57419b3SSteven Rostedt $repeat = $1; 144a57419b3SSteven Rostedt $rest = $2; 145a57419b3SSteven Rostedt $repeat_tests{"$test_num"} = $repeat; 146a57419b3SSteven Rostedt } 147a57419b3SSteven Rostedt 148a57419b3SSteven Rostedt if ($rest =~ /\s+SKIP(.*)/) { 149a57419b3SSteven Rostedt $rest = $1; 150a57419b3SSteven Rostedt $skip = 1; 151a57419b3SSteven Rostedt } 152a57419b3SSteven Rostedt 153a57419b3SSteven Rostedt if ($rest !~ /^\s*$/) { 154a57419b3SSteven Rostedt die "$name: $.: Gargbage found after TEST_START\n$_"; 155a57419b3SSteven Rostedt } 156a57419b3SSteven Rostedt 157a57419b3SSteven Rostedt if ($skip) { 158a57419b3SSteven Rostedt $test_num = $old_test_num; 159a57419b3SSteven Rostedt $repeat = 1; 160a57419b3SSteven Rostedt } 161a57419b3SSteven Rostedt 162a57419b3SSteven Rostedt } elsif (/^\s*DEFAULTS(.*)$/) { 163a57419b3SSteven Rostedt $default = 1; 164a57419b3SSteven Rostedt 165a57419b3SSteven Rostedt $rest = $1; 166a57419b3SSteven Rostedt 167a57419b3SSteven Rostedt if ($rest =~ /\s+SKIP(.*)/) { 168a57419b3SSteven Rostedt $rest = $1; 169a57419b3SSteven Rostedt $skip = 1; 170a57419b3SSteven Rostedt } else { 171a57419b3SSteven Rostedt $skip = 0; 172a57419b3SSteven Rostedt } 173a57419b3SSteven Rostedt 174a57419b3SSteven Rostedt if ($rest !~ /^\s*$/) { 175a57419b3SSteven Rostedt die "$name: $.: Gargbage found after DEFAULTS\n$_"; 176a57419b3SSteven Rostedt } 177a57419b3SSteven Rostedt 178a57419b3SSteven Rostedt } elsif (/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) { 179a57419b3SSteven Rostedt 180a57419b3SSteven Rostedt next if ($skip); 181a57419b3SSteven Rostedt 182a57419b3SSteven Rostedt my $lvalue = $1; 183a57419b3SSteven Rostedt my $rvalue = $2; 184a57419b3SSteven Rostedt 185a57419b3SSteven Rostedt if (!$default && 186a57419b3SSteven Rostedt ($lvalue eq "NUM_TESTS" || 187a57419b3SSteven Rostedt $lvalue eq "LOG_FILE" || 188a57419b3SSteven Rostedt $lvalue eq "CLEAR_LOG")) { 189a57419b3SSteven Rostedt die "$name: $.: $lvalue must be set in DEFAULTS section\n"; 190a57419b3SSteven Rostedt } 191a57419b3SSteven Rostedt 192a57419b3SSteven Rostedt if ($lvalue eq "NUM_TESTS") { 193a57419b3SSteven Rostedt if ($test_num) { 194a57419b3SSteven Rostedt die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n"; 195a57419b3SSteven Rostedt } 196a57419b3SSteven Rostedt if (!$default) { 197a57419b3SSteven Rostedt die "$name: $.: NUM_TESTS must be set in default section\n"; 198a57419b3SSteven Rostedt } 199a57419b3SSteven Rostedt $num_tests_set = 1; 200a57419b3SSteven Rostedt } 201a57419b3SSteven Rostedt 202a57419b3SSteven Rostedt if ($default || $lvalue =~ /\[\d+\]$/) { 203a57419b3SSteven Rostedt set_value($lvalue, $rvalue); 204a57419b3SSteven Rostedt } else { 205a57419b3SSteven Rostedt my $val = "$lvalue\[$test_num\]"; 206a57419b3SSteven Rostedt set_value($val, $rvalue); 207a57419b3SSteven Rostedt 208a57419b3SSteven Rostedt if ($repeat > 1) { 209a57419b3SSteven Rostedt $repeats{$val} = $repeat; 210a57419b3SSteven Rostedt } 211a57419b3SSteven Rostedt } 212a57419b3SSteven Rostedt } else { 213a57419b3SSteven Rostedt die "$name: $.: Garbage found in config\n$_"; 214a57419b3SSteven Rostedt } 2152545eb61SSteven Rostedt } 2162545eb61SSteven Rostedt 2172545eb61SSteven Rostedt close(IN); 218a75fececSSteven Rostedt 219a57419b3SSteven Rostedt if ($test_num) { 220a57419b3SSteven Rostedt $test_num += $repeat - 1; 221a57419b3SSteven Rostedt $opt{"NUM_TESTS"} = $test_num; 222a57419b3SSteven Rostedt } 223a57419b3SSteven Rostedt 224a75fececSSteven Rostedt # set any defaults 225a75fececSSteven Rostedt 226a75fececSSteven Rostedt foreach my $default (keys %default) { 227a75fececSSteven Rostedt if (!defined($opt{$default})) { 228a75fececSSteven Rostedt $opt{$default} = $default{$default}; 229a75fececSSteven Rostedt } 230a75fececSSteven Rostedt } 2312545eb61SSteven Rostedt} 2322545eb61SSteven Rostedt 233*d1e2f22aSSteven Rostedtsub _logit { 2342545eb61SSteven Rostedt if (defined($opt{"LOG_FILE"})) { 2352545eb61SSteven Rostedt open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}"; 2362545eb61SSteven Rostedt print OUT @_; 2372545eb61SSteven Rostedt close(OUT); 2382545eb61SSteven Rostedt } 2392545eb61SSteven Rostedt} 2402545eb61SSteven Rostedt 241*d1e2f22aSSteven Rostedtsub logit { 242*d1e2f22aSSteven Rostedt if (defined($opt{"LOG_FILE"})) { 243*d1e2f22aSSteven Rostedt _logit @_; 244*d1e2f22aSSteven Rostedt } else { 245*d1e2f22aSSteven Rostedt print @_; 246*d1e2f22aSSteven Rostedt } 247*d1e2f22aSSteven Rostedt} 248*d1e2f22aSSteven Rostedt 2495f9b6cedSSteven Rostedtsub doprint { 2505f9b6cedSSteven Rostedt print @_; 251*d1e2f22aSSteven Rostedt _logit @_; 2525f9b6cedSSteven Rostedt} 2535f9b6cedSSteven Rostedt 2547faafbd6SSteven Rostedtsub run_command; 2557faafbd6SSteven Rostedt 2567faafbd6SSteven Rostedtsub reboot { 2577faafbd6SSteven Rostedt # try to reboot normally 258576f627cSSteven Rostedt if (run_command "ssh $target reboot") { 259576f627cSSteven Rostedt if (defined($powercycle_after_reboot)) { 260576f627cSSteven Rostedt sleep $powercycle_after_reboot; 261576f627cSSteven Rostedt run_command "$power_cycle"; 262576f627cSSteven Rostedt } 263576f627cSSteven Rostedt } else { 2647faafbd6SSteven Rostedt # nope? power cycle it. 265a75fececSSteven Rostedt run_command "$power_cycle"; 2667faafbd6SSteven Rostedt } 2677faafbd6SSteven Rostedt} 2687faafbd6SSteven Rostedt 269576f627cSSteven Rostedtsub do_not_reboot { 270576f627cSSteven Rostedt my $i = $iteration; 271576f627cSSteven Rostedt 272576f627cSSteven Rostedt return $test_type eq "build" || 273576f627cSSteven Rostedt ($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") || 274576f627cSSteven Rostedt ($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build"); 275576f627cSSteven Rostedt} 276576f627cSSteven Rostedt 2775c42fc5bSSteven Rostedtsub dodie { 2785a391fbfSSteven Rostedt doprint "CRITICAL FAILURE... ", @_, "\n"; 2795c42fc5bSSteven Rostedt 280576f627cSSteven Rostedt my $i = $iteration; 281576f627cSSteven Rostedt 282576f627cSSteven Rostedt if ($reboot_on_error && !do_not_reboot) { 283576f627cSSteven Rostedt 28475c3fda7SSteven Rostedt doprint "REBOOTING\n"; 2857faafbd6SSteven Rostedt reboot; 28675c3fda7SSteven Rostedt 287a75fececSSteven Rostedt } elsif ($poweroff_on_error && defined($power_off)) { 2885c42fc5bSSteven Rostedt doprint "POWERING OFF\n"; 289a75fececSSteven Rostedt `$power_off`; 2905c42fc5bSSteven Rostedt } 29175c3fda7SSteven Rostedt 292576f627cSSteven Rostedt die @_, "\n"; 2935c42fc5bSSteven Rostedt} 2945c42fc5bSSteven Rostedt 2957faafbd6SSteven Rostedtsub open_console { 2967faafbd6SSteven Rostedt my ($fp) = @_; 2977faafbd6SSteven Rostedt 2987faafbd6SSteven Rostedt my $flags; 2997faafbd6SSteven Rostedt 300a75fececSSteven Rostedt my $pid = open($fp, "$console|") or 301a75fececSSteven Rostedt dodie "Can't open console $console"; 3027faafbd6SSteven Rostedt 3037faafbd6SSteven Rostedt $flags = fcntl($fp, F_GETFL, 0) or 304576f627cSSteven Rostedt dodie "Can't get flags for the socket: $!"; 3057faafbd6SSteven Rostedt $flags = fcntl($fp, F_SETFL, $flags | O_NONBLOCK) or 306576f627cSSteven Rostedt dodie "Can't set flags for the socket: $!"; 3077faafbd6SSteven Rostedt 3087faafbd6SSteven Rostedt return $pid; 3097faafbd6SSteven Rostedt} 3107faafbd6SSteven Rostedt 3117faafbd6SSteven Rostedtsub close_console { 3127faafbd6SSteven Rostedt my ($fp, $pid) = @_; 3137faafbd6SSteven Rostedt 3147faafbd6SSteven Rostedt doprint "kill child process $pid\n"; 3157faafbd6SSteven Rostedt kill 2, $pid; 3167faafbd6SSteven Rostedt 3177faafbd6SSteven Rostedt print "closing!\n"; 3187faafbd6SSteven Rostedt close($fp); 3197faafbd6SSteven Rostedt} 3207faafbd6SSteven Rostedt 3217faafbd6SSteven Rostedtsub start_monitor { 3227faafbd6SSteven Rostedt if ($monitor_cnt++) { 3237faafbd6SSteven Rostedt return; 3247faafbd6SSteven Rostedt } 3257faafbd6SSteven Rostedt $monitor_fp = \*MONFD; 3267faafbd6SSteven Rostedt $monitor_pid = open_console $monitor_fp; 327a75fececSSteven Rostedt 328a75fececSSteven Rostedt return; 329a75fececSSteven Rostedt 330a75fececSSteven Rostedt open(MONFD, "Stop perl from warning about single use of MONFD"); 3317faafbd6SSteven Rostedt} 3327faafbd6SSteven Rostedt 3337faafbd6SSteven Rostedtsub end_monitor { 3347faafbd6SSteven Rostedt if (--$monitor_cnt) { 3357faafbd6SSteven Rostedt return; 3367faafbd6SSteven Rostedt } 3377faafbd6SSteven Rostedt close_console($monitor_fp, $monitor_pid); 3387faafbd6SSteven Rostedt} 3397faafbd6SSteven Rostedt 3407faafbd6SSteven Rostedtsub wait_for_monitor { 3417faafbd6SSteven Rostedt my ($time) = @_; 3427faafbd6SSteven Rostedt my $line; 3437faafbd6SSteven Rostedt 344a75fececSSteven Rostedt doprint "** Wait for monitor to settle down **\n"; 3457faafbd6SSteven Rostedt 3467faafbd6SSteven Rostedt # read the monitor and wait for the system to calm down 3477faafbd6SSteven Rostedt do { 3487faafbd6SSteven Rostedt $line = wait_for_input($monitor_fp, $time); 349a75fececSSteven Rostedt print "$line" if (defined($line)); 3507faafbd6SSteven Rostedt } while (defined($line)); 351a75fececSSteven Rostedt print "** Monitor flushed **\n"; 3527faafbd6SSteven Rostedt} 3537faafbd6SSteven Rostedt 3542b7d9b21SSteven Rostedtsub fail { 3552b7d9b21SSteven Rostedt 356a75fececSSteven Rostedt if ($die_on_failure) { 3572b7d9b21SSteven Rostedt dodie @_; 3582b7d9b21SSteven Rostedt } 3592b7d9b21SSteven Rostedt 360a75fececSSteven Rostedt doprint "FAILED\n"; 3617faafbd6SSteven Rostedt 362576f627cSSteven Rostedt my $i = $iteration; 363576f627cSSteven Rostedt 364a75fececSSteven Rostedt # no need to reboot for just building. 365576f627cSSteven Rostedt if (!do_not_reboot) { 3667faafbd6SSteven Rostedt doprint "REBOOTING\n"; 3677faafbd6SSteven Rostedt reboot; 3687faafbd6SSteven Rostedt start_monitor; 369a75fececSSteven Rostedt wait_for_monitor $sleep_time; 3707faafbd6SSteven Rostedt end_monitor; 371a75fececSSteven Rostedt } 3727faafbd6SSteven Rostedt 373576f627cSSteven Rostedt doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; 374576f627cSSteven Rostedt doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; 375a75fececSSteven Rostedt doprint "**** Failed: ", @_, " ****\n"; 376576f627cSSteven Rostedt doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; 377576f627cSSteven Rostedt doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; 378a75fececSSteven Rostedt 379a75fececSSteven Rostedt return 1 if (!defined($store_failures)); 3807faafbd6SSteven Rostedt 3817faafbd6SSteven Rostedt my @t = localtime; 3827faafbd6SSteven Rostedt my $date = sprintf "%04d%02d%02d%02d%02d%02d", 3837faafbd6SSteven Rostedt 1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0]; 3847faafbd6SSteven Rostedt 385a75fececSSteven Rostedt my $dir = "$machine-$test_type-$build_type-fail-$date"; 386a75fececSSteven Rostedt my $faildir = "$store_failures/$dir"; 3877faafbd6SSteven Rostedt 3887faafbd6SSteven Rostedt if (!-d $faildir) { 3897faafbd6SSteven Rostedt mkpath($faildir) or 390a75fececSSteven Rostedt die "can't create $faildir"; 3917faafbd6SSteven Rostedt } 392a75fececSSteven Rostedt if (-f "$outputdir/.config") { 393a75fececSSteven Rostedt cp "$outputdir/.config", "$faildir/config" or 3947faafbd6SSteven Rostedt die "failed to copy .config"; 3957faafbd6SSteven Rostedt } 3967faafbd6SSteven Rostedt if (-f $buildlog) { 3977faafbd6SSteven Rostedt cp $buildlog, "$faildir/buildlog" or 3987faafbd6SSteven Rostedt die "failed to move $buildlog"; 3997faafbd6SSteven Rostedt } 4007faafbd6SSteven Rostedt if (-f $dmesg) { 4017faafbd6SSteven Rostedt cp $dmesg, "$faildir/dmesg" or 4027faafbd6SSteven Rostedt die "failed to move $dmesg"; 4037faafbd6SSteven Rostedt } 4047faafbd6SSteven Rostedt 4057faafbd6SSteven Rostedt doprint "*** Saved info to $faildir ***\n"; 4067faafbd6SSteven Rostedt 4072b7d9b21SSteven Rostedt return 1; 4082b7d9b21SSteven Rostedt} 4092b7d9b21SSteven Rostedt 4102545eb61SSteven Rostedtsub run_command { 4112545eb61SSteven Rostedt my ($command) = @_; 412d6ce2a0bSSteven Rostedt my $dolog = 0; 413d6ce2a0bSSteven Rostedt my $dord = 0; 414d6ce2a0bSSteven Rostedt my $pid; 415d6ce2a0bSSteven Rostedt 416d6ce2a0bSSteven Rostedt doprint("$command ... "); 417d6ce2a0bSSteven Rostedt 418d6ce2a0bSSteven Rostedt $pid = open(CMD, "$command 2>&1 |") or 4192b7d9b21SSteven Rostedt (fail "unable to exec $command" and return 0); 4202545eb61SSteven Rostedt 4212545eb61SSteven Rostedt if (defined($opt{"LOG_FILE"})) { 422d6ce2a0bSSteven Rostedt open(LOG, ">>$opt{LOG_FILE}") or 423d6ce2a0bSSteven Rostedt dodie "failed to write to log"; 424d6ce2a0bSSteven Rostedt $dolog = 1; 4256c5ee0beSSteven Rostedt } 4266c5ee0beSSteven Rostedt 4276c5ee0beSSteven Rostedt if (defined($redirect)) { 428d6ce2a0bSSteven Rostedt open (RD, ">$redirect") or 429d6ce2a0bSSteven Rostedt dodie "failed to write to redirect $redirect"; 430d6ce2a0bSSteven Rostedt $dord = 1; 4312545eb61SSteven Rostedt } 4322545eb61SSteven Rostedt 433d6ce2a0bSSteven Rostedt while (<CMD>) { 434d6ce2a0bSSteven Rostedt print LOG if ($dolog); 435d6ce2a0bSSteven Rostedt print RD if ($dord); 436d6ce2a0bSSteven Rostedt } 4372545eb61SSteven Rostedt 438d6ce2a0bSSteven Rostedt waitpid($pid, 0); 4392545eb61SSteven Rostedt my $failed = $?; 4402545eb61SSteven Rostedt 441d6ce2a0bSSteven Rostedt close(CMD); 442d6ce2a0bSSteven Rostedt close(LOG) if ($dolog); 443d6ce2a0bSSteven Rostedt close(RD) if ($dord); 444d6ce2a0bSSteven Rostedt 4452545eb61SSteven Rostedt if ($failed) { 4462545eb61SSteven Rostedt doprint "FAILED!\n"; 4472545eb61SSteven Rostedt } else { 4482545eb61SSteven Rostedt doprint "SUCCESS\n"; 4492545eb61SSteven Rostedt } 4502545eb61SSteven Rostedt 4515f9b6cedSSteven Rostedt return !$failed; 4525f9b6cedSSteven Rostedt} 4535f9b6cedSSteven Rostedt 4545f9b6cedSSteven Rostedtsub get_grub_index { 4555f9b6cedSSteven Rostedt 456a75fececSSteven Rostedt if ($reboot_type ne "grub") { 457a75fececSSteven Rostedt return; 458a75fececSSteven Rostedt } 4595a391fbfSSteven Rostedt return if (defined($grub_number)); 4605f9b6cedSSteven Rostedt 4615f9b6cedSSteven Rostedt doprint "Find grub menu ... "; 4625f9b6cedSSteven Rostedt $grub_number = -1; 4635f9b6cedSSteven Rostedt open(IN, "ssh $target cat /boot/grub/menu.lst |") 4645f9b6cedSSteven Rostedt or die "unable to get menu.lst"; 4655f9b6cedSSteven Rostedt while (<IN>) { 466a75fececSSteven Rostedt if (/^\s*title\s+$grub_menu\s*$/) { 4675f9b6cedSSteven Rostedt $grub_number++; 4685f9b6cedSSteven Rostedt last; 4695f9b6cedSSteven Rostedt } elsif (/^\s*title\s/) { 4705f9b6cedSSteven Rostedt $grub_number++; 4715f9b6cedSSteven Rostedt } 4725f9b6cedSSteven Rostedt } 4735f9b6cedSSteven Rostedt close(IN); 4745f9b6cedSSteven Rostedt 475a75fececSSteven Rostedt die "Could not find '$grub_menu' in /boot/grub/menu on $machine" 4765f9b6cedSSteven Rostedt if ($grub_number < 0); 4775f9b6cedSSteven Rostedt doprint "$grub_number\n"; 4782545eb61SSteven Rostedt} 4792545eb61SSteven Rostedt 4802545eb61SSteven Rostedtsub wait_for_input 4812545eb61SSteven Rostedt{ 4822545eb61SSteven Rostedt my ($fp, $time) = @_; 4832545eb61SSteven Rostedt my $rin; 4842545eb61SSteven Rostedt my $ready; 4852545eb61SSteven Rostedt my $line; 4862545eb61SSteven Rostedt my $ch; 4872545eb61SSteven Rostedt 4882545eb61SSteven Rostedt if (!defined($time)) { 4892545eb61SSteven Rostedt $time = $timeout; 4902545eb61SSteven Rostedt } 4912545eb61SSteven Rostedt 4922545eb61SSteven Rostedt $rin = ''; 4932545eb61SSteven Rostedt vec($rin, fileno($fp), 1) = 1; 4942545eb61SSteven Rostedt $ready = select($rin, undef, undef, $time); 4952545eb61SSteven Rostedt 4962545eb61SSteven Rostedt $line = ""; 4972545eb61SSteven Rostedt 4982545eb61SSteven Rostedt # try to read one char at a time 4992545eb61SSteven Rostedt while (sysread $fp, $ch, 1) { 5002545eb61SSteven Rostedt $line .= $ch; 5012545eb61SSteven Rostedt last if ($ch eq "\n"); 5022545eb61SSteven Rostedt } 5032545eb61SSteven Rostedt 5042545eb61SSteven Rostedt if (!length($line)) { 5052545eb61SSteven Rostedt return undef; 5062545eb61SSteven Rostedt } 5072545eb61SSteven Rostedt 5082545eb61SSteven Rostedt return $line; 5092545eb61SSteven Rostedt} 5102545eb61SSteven Rostedt 51175c3fda7SSteven Rostedtsub reboot_to { 512a75fececSSteven Rostedt if ($reboot_type eq "grub") { 5132545eb61SSteven Rostedt run_command "ssh $target '(echo \"savedefault --default=$grub_number --once\" | grub --batch; reboot)'"; 514a75fececSSteven Rostedt return; 515a75fececSSteven Rostedt } 516a75fececSSteven Rostedt 517a75fececSSteven Rostedt run_command "$reboot_script"; 5182545eb61SSteven Rostedt} 5192545eb61SSteven Rostedt 520a57419b3SSteven Rostedtsub get_sha1 { 521a57419b3SSteven Rostedt my ($commit) = @_; 522a57419b3SSteven Rostedt 523a57419b3SSteven Rostedt doprint "git rev-list --max-count=1 $commit ... "; 524a57419b3SSteven Rostedt my $sha1 = `git rev-list --max-count=1 $commit`; 525a57419b3SSteven Rostedt my $ret = $?; 526a57419b3SSteven Rostedt 527a57419b3SSteven Rostedt logit $sha1; 528a57419b3SSteven Rostedt 529a57419b3SSteven Rostedt if ($ret) { 530a57419b3SSteven Rostedt doprint "FAILED\n"; 531a57419b3SSteven Rostedt dodie "Failed to get git $commit"; 532a57419b3SSteven Rostedt } 533a57419b3SSteven Rostedt 534a57419b3SSteven Rostedt print "SUCCESS\n"; 535a57419b3SSteven Rostedt 536a57419b3SSteven Rostedt chomp $sha1; 537a57419b3SSteven Rostedt 538a57419b3SSteven Rostedt return $sha1; 539a57419b3SSteven Rostedt} 540a57419b3SSteven Rostedt 5415a391fbfSSteven Rostedtsub monitor { 5422545eb61SSteven Rostedt my $booted = 0; 5432545eb61SSteven Rostedt my $bug = 0; 5445c42fc5bSSteven Rostedt my $skip_call_trace = 0; 5452b7d9b21SSteven Rostedt my $loops; 5462545eb61SSteven Rostedt 5477faafbd6SSteven Rostedt wait_for_monitor 5; 5482545eb61SSteven Rostedt 5492545eb61SSteven Rostedt my $line; 5502545eb61SSteven Rostedt my $full_line = ""; 5512545eb61SSteven Rostedt 5527faafbd6SSteven Rostedt open(DMESG, "> $dmesg") or 5537faafbd6SSteven Rostedt die "unable to write to $dmesg"; 5542545eb61SSteven Rostedt 55575c3fda7SSteven Rostedt reboot_to; 5562545eb61SSteven Rostedt 5572545eb61SSteven Rostedt for (;;) { 5582545eb61SSteven Rostedt 5592b7d9b21SSteven Rostedt if ($booted) { 560a75fececSSteven Rostedt $line = wait_for_input($monitor_fp, $booted_timeout); 5612b7d9b21SSteven Rostedt } else { 5627faafbd6SSteven Rostedt $line = wait_for_input($monitor_fp); 5632b7d9b21SSteven Rostedt } 5642545eb61SSteven Rostedt 5652545eb61SSteven Rostedt last if (!defined($line)); 5662545eb61SSteven Rostedt 5672545eb61SSteven Rostedt doprint $line; 5687faafbd6SSteven Rostedt print DMESG $line; 5692545eb61SSteven Rostedt 5702545eb61SSteven Rostedt # we are not guaranteed to get a full line 5712545eb61SSteven Rostedt $full_line .= $line; 5722545eb61SSteven Rostedt 573a75fececSSteven Rostedt if ($full_line =~ /$success_line/) { 5742545eb61SSteven Rostedt $booted = 1; 5752545eb61SSteven Rostedt } 5762545eb61SSteven Rostedt 5775c42fc5bSSteven Rostedt if ($full_line =~ /\[ backtrace testing \]/) { 5785c42fc5bSSteven Rostedt $skip_call_trace = 1; 5795c42fc5bSSteven Rostedt } 5805c42fc5bSSteven Rostedt 5812545eb61SSteven Rostedt if ($full_line =~ /call trace:/i) { 5825c42fc5bSSteven Rostedt $bug = 1 if (!$skip_call_trace); 5835c42fc5bSSteven Rostedt } 5845c42fc5bSSteven Rostedt 5855c42fc5bSSteven Rostedt if ($full_line =~ /\[ end of backtrace testing \]/) { 5865c42fc5bSSteven Rostedt $skip_call_trace = 0; 5875c42fc5bSSteven Rostedt } 5885c42fc5bSSteven Rostedt 5895c42fc5bSSteven Rostedt if ($full_line =~ /Kernel panic -/) { 5902545eb61SSteven Rostedt $bug = 1; 5912545eb61SSteven Rostedt } 5922545eb61SSteven Rostedt 5932545eb61SSteven Rostedt if ($line =~ /\n/) { 5942545eb61SSteven Rostedt $full_line = ""; 5952545eb61SSteven Rostedt } 5962545eb61SSteven Rostedt } 5972545eb61SSteven Rostedt 5987faafbd6SSteven Rostedt close(DMESG); 5992545eb61SSteven Rostedt 6002545eb61SSteven Rostedt if ($bug) { 6012b7d9b21SSteven Rostedt return 0 if ($in_bisect); 602576f627cSSteven Rostedt fail "failed - got a bug report" and return 0; 6032545eb61SSteven Rostedt } 6045f9b6cedSSteven Rostedt 605a75fececSSteven Rostedt if (!$booted) { 606a75fececSSteven Rostedt return 0 if ($in_bisect); 607576f627cSSteven Rostedt fail "failed - never got a boot prompt." and return 0; 608a75fececSSteven Rostedt } 609a75fececSSteven Rostedt 6102b7d9b21SSteven Rostedt return 1; 6112545eb61SSteven Rostedt} 6122545eb61SSteven Rostedt 6132545eb61SSteven Rostedtsub install { 6142545eb61SSteven Rostedt 615a75fececSSteven Rostedt run_command "scp $outputdir/$build_target $target:$target_image" or 6165c42fc5bSSteven Rostedt dodie "failed to copy image"; 6175f9b6cedSSteven Rostedt 6185f9b6cedSSteven Rostedt my $install_mods = 0; 6195f9b6cedSSteven Rostedt 6205f9b6cedSSteven Rostedt # should we process modules? 6215f9b6cedSSteven Rostedt $install_mods = 0; 622a75fececSSteven Rostedt open(IN, "$outputdir/.config") or dodie("Can't read config file"); 6235f9b6cedSSteven Rostedt while (<IN>) { 6245f9b6cedSSteven Rostedt if (/CONFIG_MODULES(=y)?/) { 6255f9b6cedSSteven Rostedt $install_mods = 1 if (defined($1)); 6265f9b6cedSSteven Rostedt last; 6275f9b6cedSSteven Rostedt } 6285f9b6cedSSteven Rostedt } 6295f9b6cedSSteven Rostedt close(IN); 6305f9b6cedSSteven Rostedt 6315f9b6cedSSteven Rostedt if (!$install_mods) { 6325f9b6cedSSteven Rostedt doprint "No modules needed\n"; 6335f9b6cedSSteven Rostedt return; 6342545eb61SSteven Rostedt } 6352545eb61SSteven Rostedt 636a75fececSSteven Rostedt run_command "$make INSTALL_MOD_PATH=$tmpdir modules_install" or 6375f9b6cedSSteven Rostedt dodie "Failed to install modules"; 6385f9b6cedSSteven Rostedt 6392545eb61SSteven Rostedt my $modlib = "/lib/modules/$version"; 640a57419b3SSteven Rostedt my $modtar = "ktest-mods.tar.bz2"; 6412545eb61SSteven Rostedt 6425f9b6cedSSteven Rostedt run_command "ssh $target rm -rf $modlib" or 6435c42fc5bSSteven Rostedt dodie "failed to remove old mods: $modlib"; 6442545eb61SSteven Rostedt 6455c42fc5bSSteven Rostedt # would be nice if scp -r did not follow symbolic links 646a75fececSSteven Rostedt run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or 6475c42fc5bSSteven Rostedt dodie "making tarball"; 6485c42fc5bSSteven Rostedt 649a75fececSSteven Rostedt run_command "scp $tmpdir/$modtar $target:/tmp" or 6505c42fc5bSSteven Rostedt dodie "failed to copy modules"; 6515c42fc5bSSteven Rostedt 652a75fececSSteven Rostedt unlink "$tmpdir/$modtar"; 6535c42fc5bSSteven Rostedt 6545f9b6cedSSteven Rostedt run_command "ssh $target '(cd / && tar xf /tmp/$modtar)'" or 6555c42fc5bSSteven Rostedt dodie "failed to tar modules"; 6565c42fc5bSSteven Rostedt 6575c42fc5bSSteven Rostedt run_command "ssh $target rm -f /tmp/$modtar"; 6588b37ca8cSSteven Rostedt 6598b37ca8cSSteven Rostedt return if (!defined($post_install)); 6608b37ca8cSSteven Rostedt 6618b37ca8cSSteven Rostedt my $save_env = $ENV{KERNEL_VERSION}; 6628b37ca8cSSteven Rostedt 6638b37ca8cSSteven Rostedt $ENV{KERNEL_VERSION} = $version; 664576f627cSSteven Rostedt run_command "$post_install" or 665576f627cSSteven Rostedt dodie "Failed to run post install"; 6668b37ca8cSSteven Rostedt 6678b37ca8cSSteven Rostedt $ENV{KERNEL_VERSION} = $save_env; 6682545eb61SSteven Rostedt} 6692545eb61SSteven Rostedt 6706c5ee0beSSteven Rostedtsub check_buildlog { 6716c5ee0beSSteven Rostedt my ($patch) = @_; 6726c5ee0beSSteven Rostedt 6736c5ee0beSSteven Rostedt my @files = `git show $patch | diffstat -l`; 6746c5ee0beSSteven Rostedt 6756c5ee0beSSteven Rostedt open(IN, "git show $patch |") or 6766c5ee0beSSteven Rostedt dodie "failed to show $patch"; 6776c5ee0beSSteven Rostedt while (<IN>) { 6786c5ee0beSSteven Rostedt if (m,^--- a/(.*),) { 6796c5ee0beSSteven Rostedt chomp $1; 6806c5ee0beSSteven Rostedt $files[$#files] = $1; 6816c5ee0beSSteven Rostedt } 6826c5ee0beSSteven Rostedt } 6836c5ee0beSSteven Rostedt close(IN); 6846c5ee0beSSteven Rostedt 6856c5ee0beSSteven Rostedt open(IN, $buildlog) or dodie "Can't open $buildlog"; 6866c5ee0beSSteven Rostedt while (<IN>) { 6876c5ee0beSSteven Rostedt if (/^\s*(.*?):.*(warning|error)/) { 6886c5ee0beSSteven Rostedt my $err = $1; 6896c5ee0beSSteven Rostedt foreach my $file (@files) { 690a75fececSSteven Rostedt my $fullpath = "$builddir/$file"; 6916c5ee0beSSteven Rostedt if ($file eq $err || $fullpath eq $err) { 6922b7d9b21SSteven Rostedt fail "$file built with warnings" and return 0; 6936c5ee0beSSteven Rostedt } 6946c5ee0beSSteven Rostedt } 6956c5ee0beSSteven Rostedt } 6966c5ee0beSSteven Rostedt } 6976c5ee0beSSteven Rostedt close(IN); 6982b7d9b21SSteven Rostedt 6992b7d9b21SSteven Rostedt return 1; 7006c5ee0beSSteven Rostedt} 7016c5ee0beSSteven Rostedt 7022545eb61SSteven Rostedtsub build { 7032545eb61SSteven Rostedt my ($type) = @_; 7045c42fc5bSSteven Rostedt my $defconfig = ""; 7052545eb61SSteven Rostedt 7067faafbd6SSteven Rostedt unlink $buildlog; 7077faafbd6SSteven Rostedt 70875c3fda7SSteven Rostedt if ($type =~ /^useconfig:(.*)/) { 709a75fececSSteven Rostedt run_command "cp $1 $outputdir/.config" or 71075c3fda7SSteven Rostedt dodie "could not copy $1 to .config"; 7115f9b6cedSSteven Rostedt 71275c3fda7SSteven Rostedt $type = "oldconfig"; 71375c3fda7SSteven Rostedt } 71475c3fda7SSteven Rostedt 7155c42fc5bSSteven Rostedt # old config can ask questions 7165c42fc5bSSteven Rostedt if ($type eq "oldconfig") { 7179386c6abSSteven Rostedt $type = "oldnoconfig"; 71875c3fda7SSteven Rostedt 71975c3fda7SSteven Rostedt # allow for empty configs 720a75fececSSteven Rostedt run_command "touch $outputdir/.config"; 72175c3fda7SSteven Rostedt 722a75fececSSteven Rostedt run_command "mv $outputdir/.config $outputdir/config_temp" or 7235c42fc5bSSteven Rostedt dodie "moving .config"; 7245c42fc5bSSteven Rostedt 7255f9b6cedSSteven Rostedt if (!$noclean && !run_command "$make mrproper") { 7265c42fc5bSSteven Rostedt dodie "make mrproper"; 7275c42fc5bSSteven Rostedt } 7285c42fc5bSSteven Rostedt 729a75fececSSteven Rostedt run_command "mv $outputdir/config_temp $outputdir/.config" or 7305c42fc5bSSteven Rostedt dodie "moving config_temp"; 7315c42fc5bSSteven Rostedt 7325c42fc5bSSteven Rostedt } elsif (!$noclean) { 733a75fececSSteven Rostedt unlink "$outputdir/.config"; 7345f9b6cedSSteven Rostedt run_command "$make mrproper" or 7355c42fc5bSSteven Rostedt dodie "make mrproper"; 7365c42fc5bSSteven Rostedt } 7372545eb61SSteven Rostedt 7382545eb61SSteven Rostedt # add something to distinguish this build 739a75fececSSteven Rostedt open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file"); 740a75fececSSteven Rostedt print OUT "$localversion\n"; 7412545eb61SSteven Rostedt close(OUT); 7422545eb61SSteven Rostedt 7435f9b6cedSSteven Rostedt if (defined($minconfig)) { 7445f9b6cedSSteven Rostedt $defconfig = "KCONFIG_ALLCONFIG=$minconfig"; 7452545eb61SSteven Rostedt } 7462545eb61SSteven Rostedt 7479386c6abSSteven Rostedt run_command "$defconfig $make $type" or 7485c42fc5bSSteven Rostedt dodie "failed make config"; 7492545eb61SSteven Rostedt 750a75fececSSteven Rostedt $redirect = "$buildlog"; 751a75fececSSteven Rostedt if (!run_command "$make $build_options") { 7526c5ee0beSSteven Rostedt undef $redirect; 7535f9b6cedSSteven Rostedt # bisect may need this to pass 7542b7d9b21SSteven Rostedt return 0 if ($in_bisect); 7552b7d9b21SSteven Rostedt fail "failed build" and return 0; 7562545eb61SSteven Rostedt } 7576c5ee0beSSteven Rostedt undef $redirect; 7585f9b6cedSSteven Rostedt 7592b7d9b21SSteven Rostedt return 1; 7602545eb61SSteven Rostedt} 7612545eb61SSteven Rostedt 76275c3fda7SSteven Rostedtsub halt { 763a75fececSSteven Rostedt if (!run_command "ssh $target halt" or defined($power_off)) { 764576f627cSSteven Rostedt if (defined($poweroff_after_halt)) { 765576f627cSSteven Rostedt sleep $poweroff_after_halt; 766576f627cSSteven Rostedt run_command "$power_off"; 767576f627cSSteven Rostedt } 768576f627cSSteven Rostedt } else { 76975c3fda7SSteven Rostedt # nope? the zap it! 770a75fececSSteven Rostedt run_command "$power_off"; 77175c3fda7SSteven Rostedt } 77275c3fda7SSteven Rostedt} 77375c3fda7SSteven Rostedt 7745f9b6cedSSteven Rostedtsub success { 7755f9b6cedSSteven Rostedt my ($i) = @_; 7765f9b6cedSSteven Rostedt 7775f9b6cedSSteven Rostedt doprint "\n\n*******************************************\n"; 7785f9b6cedSSteven Rostedt doprint "*******************************************\n"; 779a75fececSSteven Rostedt doprint "** TEST $i SUCCESS!!!! **\n"; 7805f9b6cedSSteven Rostedt doprint "*******************************************\n"; 7815f9b6cedSSteven Rostedt doprint "*******************************************\n"; 7825f9b6cedSSteven Rostedt 783576f627cSSteven Rostedt if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) { 784a75fececSSteven Rostedt doprint "Reboot and wait $sleep_time seconds\n"; 7855f9b6cedSSteven Rostedt reboot; 7867faafbd6SSteven Rostedt start_monitor; 787a75fececSSteven Rostedt wait_for_monitor $sleep_time; 7887faafbd6SSteven Rostedt end_monitor; 7895f9b6cedSSteven Rostedt } 7905f9b6cedSSteven Rostedt} 7915f9b6cedSSteven Rostedt 7925f9b6cedSSteven Rostedtsub get_version { 7935f9b6cedSSteven Rostedt # get the release name 7945f9b6cedSSteven Rostedt doprint "$make kernelrelease ... "; 7955f9b6cedSSteven Rostedt $version = `$make kernelrelease | tail -1`; 7965f9b6cedSSteven Rostedt chomp($version); 7975f9b6cedSSteven Rostedt doprint "$version\n"; 7985f9b6cedSSteven Rostedt} 7995f9b6cedSSteven Rostedt 8005a391fbfSSteven Rostedtsub child_run_test { 8017faafbd6SSteven Rostedt my $failed = 0; 8025a391fbfSSteven Rostedt 8037faafbd6SSteven Rostedt # child should have no power 804a75fececSSteven Rostedt $reboot_on_error = 0; 805a75fececSSteven Rostedt $poweroff_on_error = 0; 806a75fececSSteven Rostedt $die_on_failure = 1; 8077faafbd6SSteven Rostedt 8087faafbd6SSteven Rostedt run_command $run_test or $failed = 1; 8095a391fbfSSteven Rostedt exit $failed; 8105a391fbfSSteven Rostedt} 8115a391fbfSSteven Rostedt 8125a391fbfSSteven Rostedtmy $child_done; 8135a391fbfSSteven Rostedt 8145a391fbfSSteven Rostedtsub child_finished { 8155a391fbfSSteven Rostedt $child_done = 1; 8165a391fbfSSteven Rostedt} 8175a391fbfSSteven Rostedt 8185a391fbfSSteven Rostedtsub do_run_test { 8195a391fbfSSteven Rostedt my $child_pid; 8205a391fbfSSteven Rostedt my $child_exit; 8215a391fbfSSteven Rostedt my $line; 8225a391fbfSSteven Rostedt my $full_line; 8235a391fbfSSteven Rostedt my $bug = 0; 8245a391fbfSSteven Rostedt 8257faafbd6SSteven Rostedt wait_for_monitor 1; 8265a391fbfSSteven Rostedt 8277faafbd6SSteven Rostedt doprint "run test $run_test\n"; 8285a391fbfSSteven Rostedt 8295a391fbfSSteven Rostedt $child_done = 0; 8305a391fbfSSteven Rostedt 8315a391fbfSSteven Rostedt $SIG{CHLD} = qw(child_finished); 8325a391fbfSSteven Rostedt 8335a391fbfSSteven Rostedt $child_pid = fork; 8345a391fbfSSteven Rostedt 8355a391fbfSSteven Rostedt child_run_test if (!$child_pid); 8365a391fbfSSteven Rostedt 8375a391fbfSSteven Rostedt $full_line = ""; 8385a391fbfSSteven Rostedt 8395a391fbfSSteven Rostedt do { 8407faafbd6SSteven Rostedt $line = wait_for_input($monitor_fp, 1); 8415a391fbfSSteven Rostedt if (defined($line)) { 8425a391fbfSSteven Rostedt 8435a391fbfSSteven Rostedt # we are not guaranteed to get a full line 8445a391fbfSSteven Rostedt $full_line .= $line; 8455a391fbfSSteven Rostedt 8465a391fbfSSteven Rostedt if ($full_line =~ /call trace:/i) { 8475a391fbfSSteven Rostedt $bug = 1; 8485a391fbfSSteven Rostedt } 8495a391fbfSSteven Rostedt 8505a391fbfSSteven Rostedt if ($full_line =~ /Kernel panic -/) { 8515a391fbfSSteven Rostedt $bug = 1; 8525a391fbfSSteven Rostedt } 8535a391fbfSSteven Rostedt 8545a391fbfSSteven Rostedt if ($line =~ /\n/) { 8555a391fbfSSteven Rostedt $full_line = ""; 8565a391fbfSSteven Rostedt } 8575a391fbfSSteven Rostedt } 8585a391fbfSSteven Rostedt } while (!$child_done && !$bug); 8595a391fbfSSteven Rostedt 8605a391fbfSSteven Rostedt if ($bug) { 8615a391fbfSSteven Rostedt doprint "Detected kernel crash!\n"; 8625a391fbfSSteven Rostedt # kill the child with extreme prejudice 8635a391fbfSSteven Rostedt kill 9, $child_pid; 8645a391fbfSSteven Rostedt } 8655a391fbfSSteven Rostedt 8665a391fbfSSteven Rostedt waitpid $child_pid, 0; 8675a391fbfSSteven Rostedt $child_exit = $?; 8685a391fbfSSteven Rostedt 8695a391fbfSSteven Rostedt if ($bug || $child_exit) { 8702b7d9b21SSteven Rostedt return 0 if $in_bisect; 8712b7d9b21SSteven Rostedt fail "test failed" and return 0; 8725a391fbfSSteven Rostedt } 8732b7d9b21SSteven Rostedt return 1; 8745a391fbfSSteven Rostedt} 8755a391fbfSSteven Rostedt 876a75fececSSteven Rostedtsub run_git_bisect { 877a75fececSSteven Rostedt my ($command) = @_; 878a75fececSSteven Rostedt 879a75fececSSteven Rostedt doprint "$command ... "; 880a75fececSSteven Rostedt 881a75fececSSteven Rostedt my $output = `$command 2>&1`; 882a75fececSSteven Rostedt my $ret = $?; 883a75fececSSteven Rostedt 884a75fececSSteven Rostedt logit $output; 885a75fececSSteven Rostedt 886a75fececSSteven Rostedt if ($ret) { 887a75fececSSteven Rostedt doprint "FAILED\n"; 888a75fececSSteven Rostedt dodie "Failed to git bisect"; 889a75fececSSteven Rostedt } 890a75fececSSteven Rostedt 891a75fececSSteven Rostedt doprint "SUCCESS\n"; 892a75fececSSteven Rostedt if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) { 893a75fececSSteven Rostedt doprint "$1 [$2]\n"; 894a75fececSSteven Rostedt } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) { 895a75fececSSteven Rostedt $bisect_bad = $1; 896a75fececSSteven Rostedt doprint "Found bad commit... $1\n"; 897a75fececSSteven Rostedt return 0; 898a75fececSSteven Rostedt } else { 899a75fececSSteven Rostedt # we already logged it, just print it now. 900a75fececSSteven Rostedt print $output; 901a75fececSSteven Rostedt } 902a75fececSSteven Rostedt 903a75fececSSteven Rostedt return 1; 904a75fececSSteven Rostedt} 905a75fececSSteven Rostedt 9065f9b6cedSSteven Rostedtsub run_bisect { 9075f9b6cedSSteven Rostedt my ($type) = @_; 9085f9b6cedSSteven Rostedt 9092b7d9b21SSteven Rostedt my $failed = 0; 9105f9b6cedSSteven Rostedt my $result; 9115f9b6cedSSteven Rostedt my $output; 9125f9b6cedSSteven Rostedt my $ret; 9135f9b6cedSSteven Rostedt 9145f9b6cedSSteven Rostedt if (defined($minconfig)) { 9152b7d9b21SSteven Rostedt build "useconfig:$minconfig" or $failed = 1; 9165f9b6cedSSteven Rostedt } else { 9175f9b6cedSSteven Rostedt # ?? no config to use? 9182b7d9b21SSteven Rostedt build "oldconfig" or $failed = 1; 9195f9b6cedSSteven Rostedt } 9205f9b6cedSSteven Rostedt 9215f9b6cedSSteven Rostedt if ($type ne "build") { 9227faafbd6SSteven Rostedt dodie "Failed on build" if $failed; 9235f9b6cedSSteven Rostedt 9245f9b6cedSSteven Rostedt # Now boot the box 9255f9b6cedSSteven Rostedt get_grub_index; 9265f9b6cedSSteven Rostedt get_version; 9275f9b6cedSSteven Rostedt install; 9287faafbd6SSteven Rostedt 9297faafbd6SSteven Rostedt start_monitor; 9302b7d9b21SSteven Rostedt monitor or $failed = 1; 9315f9b6cedSSteven Rostedt 9325f9b6cedSSteven Rostedt if ($type ne "boot") { 9337faafbd6SSteven Rostedt dodie "Failed on boot" if $failed; 9345a391fbfSSteven Rostedt 9352b7d9b21SSteven Rostedt do_run_test or $failed = 1; 9365f9b6cedSSteven Rostedt } 9377faafbd6SSteven Rostedt end_monitor; 9385f9b6cedSSteven Rostedt } 9395f9b6cedSSteven Rostedt 9405f9b6cedSSteven Rostedt if ($failed) { 9415f9b6cedSSteven Rostedt $result = "bad"; 9425a391fbfSSteven Rostedt 9435a391fbfSSteven Rostedt # reboot the box to a good kernel 944a75fececSSteven Rostedt if ($type ne "build") { 945a75fececSSteven Rostedt doprint "Reboot and sleep $bisect_sleep_time seconds\n"; 9465a391fbfSSteven Rostedt reboot; 9477faafbd6SSteven Rostedt start_monitor; 948a75fececSSteven Rostedt wait_for_monitor $bisect_sleep_time; 9497faafbd6SSteven Rostedt end_monitor; 9505a391fbfSSteven Rostedt } 9515f9b6cedSSteven Rostedt } else { 9525f9b6cedSSteven Rostedt $result = "good"; 9535f9b6cedSSteven Rostedt } 9545f9b6cedSSteven Rostedt 955d6ce2a0bSSteven Rostedt # Are we looking for where it worked, not failed? 956d6ce2a0bSSteven Rostedt if ($reverse_bisect) { 957d6ce2a0bSSteven Rostedt if ($failed) { 958d6ce2a0bSSteven Rostedt $result = "good"; 959d6ce2a0bSSteven Rostedt } else { 960d6ce2a0bSSteven Rostedt $result = "bad"; 961d6ce2a0bSSteven Rostedt } 962d6ce2a0bSSteven Rostedt } 963d6ce2a0bSSteven Rostedt 964a75fececSSteven Rostedt return $result; 9655f9b6cedSSteven Rostedt} 9665f9b6cedSSteven Rostedt 9675f9b6cedSSteven Rostedtsub bisect { 9685f9b6cedSSteven Rostedt my ($i) = @_; 9695f9b6cedSSteven Rostedt 9705f9b6cedSSteven Rostedt my $result; 9715f9b6cedSSteven Rostedt 9725f9b6cedSSteven Rostedt die "BISECT_GOOD[$i] not defined\n" if (!defined($opt{"BISECT_GOOD[$i]"})); 9735f9b6cedSSteven Rostedt die "BISECT_BAD[$i] not defined\n" if (!defined($opt{"BISECT_BAD[$i]"})); 9745f9b6cedSSteven Rostedt die "BISECT_TYPE[$i] not defined\n" if (!defined($opt{"BISECT_TYPE[$i]"})); 9755f9b6cedSSteven Rostedt 9765f9b6cedSSteven Rostedt my $good = $opt{"BISECT_GOOD[$i]"}; 9775f9b6cedSSteven Rostedt my $bad = $opt{"BISECT_BAD[$i]"}; 9785f9b6cedSSteven Rostedt my $type = $opt{"BISECT_TYPE[$i]"}; 979a75fececSSteven Rostedt my $start = $opt{"BISECT_START[$i]"}; 980a75fececSSteven Rostedt my $replay = $opt{"BISECT_REPLAY[$i]"}; 9815f9b6cedSSteven Rostedt 982a57419b3SSteven Rostedt # convert to true sha1's 983a57419b3SSteven Rostedt $good = get_sha1($good); 984a57419b3SSteven Rostedt $bad = get_sha1($bad); 985a57419b3SSteven Rostedt 986d6ce2a0bSSteven Rostedt if (defined($opt{"BISECT_REVERSE[$i]"}) && 987d6ce2a0bSSteven Rostedt $opt{"BISECT_REVERSE[$i]"} == 1) { 988d6ce2a0bSSteven Rostedt doprint "Performing a reverse bisect (bad is good, good is bad!)\n"; 989d6ce2a0bSSteven Rostedt $reverse_bisect = 1; 990d6ce2a0bSSteven Rostedt } else { 991d6ce2a0bSSteven Rostedt $reverse_bisect = 0; 992d6ce2a0bSSteven Rostedt } 993d6ce2a0bSSteven Rostedt 9945f9b6cedSSteven Rostedt $in_bisect = 1; 9955f9b6cedSSteven Rostedt 9965a391fbfSSteven Rostedt # Can't have a test without having a test to run 9975a391fbfSSteven Rostedt if ($type eq "test" && !defined($run_test)) { 9985a391fbfSSteven Rostedt $type = "boot"; 9995a391fbfSSteven Rostedt } 10005a391fbfSSteven Rostedt 1001a75fececSSteven Rostedt my $check = $opt{"BISECT_CHECK[$i]"}; 1002a75fececSSteven Rostedt if (defined($check) && $check ne "0") { 1003a75fececSSteven Rostedt 1004a75fececSSteven Rostedt # get current HEAD 1005a57419b3SSteven Rostedt my $head = get_sha1("HEAD"); 1006a75fececSSteven Rostedt 1007a75fececSSteven Rostedt if ($check ne "good") { 1008a75fececSSteven Rostedt doprint "TESTING BISECT BAD [$bad]\n"; 1009a75fececSSteven Rostedt run_command "git checkout $bad" or 1010a75fececSSteven Rostedt die "Failed to checkout $bad"; 1011a75fececSSteven Rostedt 1012a75fececSSteven Rostedt $result = run_bisect $type; 1013a75fececSSteven Rostedt 1014a75fececSSteven Rostedt if ($result ne "bad") { 1015a75fececSSteven Rostedt fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0; 1016a75fececSSteven Rostedt } 1017a75fececSSteven Rostedt } 1018a75fececSSteven Rostedt 1019a75fececSSteven Rostedt if ($check ne "bad") { 1020a75fececSSteven Rostedt doprint "TESTING BISECT GOOD [$good]\n"; 1021a75fececSSteven Rostedt run_command "git checkout $good" or 1022a75fececSSteven Rostedt die "Failed to checkout $good"; 1023a75fececSSteven Rostedt 1024a75fececSSteven Rostedt $result = run_bisect $type; 1025a75fececSSteven Rostedt 1026a75fececSSteven Rostedt if ($result ne "good") { 1027a75fececSSteven Rostedt fail "Tested BISECT_GOOD [$good] and it failed" and return 0; 1028a75fececSSteven Rostedt } 1029a75fececSSteven Rostedt } 1030a75fececSSteven Rostedt 1031a75fececSSteven Rostedt # checkout where we started 1032a75fececSSteven Rostedt run_command "git checkout $head" or 1033a75fececSSteven Rostedt die "Failed to checkout $head"; 1034a75fececSSteven Rostedt } 1035a75fececSSteven Rostedt 1036a75fececSSteven Rostedt run_command "git bisect start" or 1037a75fececSSteven Rostedt dodie "could not start bisect"; 1038a75fececSSteven Rostedt 1039a75fececSSteven Rostedt run_command "git bisect good $good" or 1040a75fececSSteven Rostedt dodie "could not set bisect good to $good"; 1041a75fececSSteven Rostedt 1042a75fececSSteven Rostedt run_git_bisect "git bisect bad $bad" or 1043a75fececSSteven Rostedt dodie "could not set bisect bad to $bad"; 1044a75fececSSteven Rostedt 1045a75fececSSteven Rostedt if (defined($replay)) { 1046a75fececSSteven Rostedt run_command "git bisect replay $replay" or 1047a75fececSSteven Rostedt dodie "failed to run replay"; 1048a75fececSSteven Rostedt } 1049a75fececSSteven Rostedt 1050a75fececSSteven Rostedt if (defined($start)) { 1051a75fececSSteven Rostedt run_command "git checkout $start" or 1052a75fececSSteven Rostedt dodie "failed to checkout $start"; 1053a75fececSSteven Rostedt } 1054a75fececSSteven Rostedt 1055a75fececSSteven Rostedt my $test; 10565f9b6cedSSteven Rostedt do { 10575f9b6cedSSteven Rostedt $result = run_bisect $type; 1058a75fececSSteven Rostedt $test = run_git_bisect "git bisect $result"; 1059a75fececSSteven Rostedt } while ($test); 10605f9b6cedSSteven Rostedt 10615f9b6cedSSteven Rostedt run_command "git bisect log" or 10625f9b6cedSSteven Rostedt dodie "could not capture git bisect log"; 10635f9b6cedSSteven Rostedt 10645f9b6cedSSteven Rostedt run_command "git bisect reset" or 10655f9b6cedSSteven Rostedt dodie "could not reset git bisect"; 10665f9b6cedSSteven Rostedt 10675f9b6cedSSteven Rostedt doprint "Bad commit was [$bisect_bad]\n"; 10685f9b6cedSSteven Rostedt 10695f9b6cedSSteven Rostedt $in_bisect = 0; 10705f9b6cedSSteven Rostedt 10715f9b6cedSSteven Rostedt success $i; 10725f9b6cedSSteven Rostedt} 10735f9b6cedSSteven Rostedt 10746c5ee0beSSteven Rostedtsub patchcheck { 10756c5ee0beSSteven Rostedt my ($i) = @_; 10766c5ee0beSSteven Rostedt 10776c5ee0beSSteven Rostedt die "PATCHCHECK_START[$i] not defined\n" 10786c5ee0beSSteven Rostedt if (!defined($opt{"PATCHCHECK_START[$i]"})); 10796c5ee0beSSteven Rostedt die "PATCHCHECK_TYPE[$i] not defined\n" 10806c5ee0beSSteven Rostedt if (!defined($opt{"PATCHCHECK_TYPE[$i]"})); 10816c5ee0beSSteven Rostedt 10826c5ee0beSSteven Rostedt my $start = $opt{"PATCHCHECK_START[$i]"}; 10836c5ee0beSSteven Rostedt 10846c5ee0beSSteven Rostedt my $end = "HEAD"; 10856c5ee0beSSteven Rostedt if (defined($opt{"PATCHCHECK_END[$i]"})) { 10866c5ee0beSSteven Rostedt $end = $opt{"PATCHCHECK_END[$i]"}; 10876c5ee0beSSteven Rostedt } 10886c5ee0beSSteven Rostedt 1089a57419b3SSteven Rostedt # Get the true sha1's since we can use things like HEAD~3 1090a57419b3SSteven Rostedt $start = get_sha1($start); 1091a57419b3SSteven Rostedt $end = get_sha1($end); 1092a57419b3SSteven Rostedt 10936c5ee0beSSteven Rostedt my $type = $opt{"PATCHCHECK_TYPE[$i]"}; 10946c5ee0beSSteven Rostedt 10956c5ee0beSSteven Rostedt # Can't have a test without having a test to run 10966c5ee0beSSteven Rostedt if ($type eq "test" && !defined($run_test)) { 10976c5ee0beSSteven Rostedt $type = "boot"; 10986c5ee0beSSteven Rostedt } 10996c5ee0beSSteven Rostedt 11006c5ee0beSSteven Rostedt open (IN, "git log --pretty=oneline $end|") or 11016c5ee0beSSteven Rostedt dodie "could not get git list"; 11026c5ee0beSSteven Rostedt 11036c5ee0beSSteven Rostedt my @list; 11046c5ee0beSSteven Rostedt 11056c5ee0beSSteven Rostedt while (<IN>) { 11066c5ee0beSSteven Rostedt chomp; 11076c5ee0beSSteven Rostedt $list[$#list+1] = $_; 11086c5ee0beSSteven Rostedt last if (/^$start/); 11096c5ee0beSSteven Rostedt } 11106c5ee0beSSteven Rostedt close(IN); 11116c5ee0beSSteven Rostedt 11126c5ee0beSSteven Rostedt if ($list[$#list] !~ /^$start/) { 11132b7d9b21SSteven Rostedt fail "SHA1 $start not found"; 11146c5ee0beSSteven Rostedt } 11156c5ee0beSSteven Rostedt 11166c5ee0beSSteven Rostedt # go backwards in the list 11176c5ee0beSSteven Rostedt @list = reverse @list; 11186c5ee0beSSteven Rostedt 11196c5ee0beSSteven Rostedt my $save_clean = $noclean; 11206c5ee0beSSteven Rostedt 11216c5ee0beSSteven Rostedt $in_patchcheck = 1; 11226c5ee0beSSteven Rostedt foreach my $item (@list) { 11236c5ee0beSSteven Rostedt my $sha1 = $item; 11246c5ee0beSSteven Rostedt $sha1 =~ s/^([[:xdigit:]]+).*/$1/; 11256c5ee0beSSteven Rostedt 11266c5ee0beSSteven Rostedt doprint "\nProcessing commit $item\n\n"; 11276c5ee0beSSteven Rostedt 11286c5ee0beSSteven Rostedt run_command "git checkout $sha1" or 11296c5ee0beSSteven Rostedt die "Failed to checkout $sha1"; 11306c5ee0beSSteven Rostedt 11316c5ee0beSSteven Rostedt # only clean on the first and last patch 11326c5ee0beSSteven Rostedt if ($item eq $list[0] || 11336c5ee0beSSteven Rostedt $item eq $list[$#list]) { 11346c5ee0beSSteven Rostedt $noclean = $save_clean; 11356c5ee0beSSteven Rostedt } else { 11366c5ee0beSSteven Rostedt $noclean = 1; 11376c5ee0beSSteven Rostedt } 11386c5ee0beSSteven Rostedt 11396c5ee0beSSteven Rostedt if (defined($minconfig)) { 11402b7d9b21SSteven Rostedt build "useconfig:$minconfig" or return 0; 11416c5ee0beSSteven Rostedt } else { 11426c5ee0beSSteven Rostedt # ?? no config to use? 11432b7d9b21SSteven Rostedt build "oldconfig" or return 0; 11446c5ee0beSSteven Rostedt } 11456c5ee0beSSteven Rostedt 11462b7d9b21SSteven Rostedt check_buildlog $sha1 or return 0; 11476c5ee0beSSteven Rostedt 11486c5ee0beSSteven Rostedt next if ($type eq "build"); 11496c5ee0beSSteven Rostedt 11506c5ee0beSSteven Rostedt get_grub_index; 11516c5ee0beSSteven Rostedt get_version; 11526c5ee0beSSteven Rostedt install; 11536c5ee0beSSteven Rostedt 11547faafbd6SSteven Rostedt my $failed = 0; 11557faafbd6SSteven Rostedt 11567faafbd6SSteven Rostedt start_monitor; 11577faafbd6SSteven Rostedt monitor or $failed = 1; 11587faafbd6SSteven Rostedt 11597faafbd6SSteven Rostedt if (!$failed && $type ne "boot"){ 11607faafbd6SSteven Rostedt do_run_test or $failed = 1; 11617faafbd6SSteven Rostedt } 11627faafbd6SSteven Rostedt end_monitor; 11637faafbd6SSteven Rostedt return 0 if ($failed); 11647faafbd6SSteven Rostedt 11656c5ee0beSSteven Rostedt } 11666c5ee0beSSteven Rostedt $in_patchcheck = 0; 11676c5ee0beSSteven Rostedt success $i; 11682b7d9b21SSteven Rostedt 11692b7d9b21SSteven Rostedt return 1; 11706c5ee0beSSteven Rostedt} 11716c5ee0beSSteven Rostedt 11722545eb61SSteven Rostedtread_config $ARGV[0]; 11732545eb61SSteven Rostedt 11742545eb61SSteven Rostedt# mandatory configs 11752545eb61SSteven Rostedtdie "MACHINE not defined\n" if (!defined($opt{"MACHINE"})); 11762545eb61SSteven Rostedtdie "SSH_USER not defined\n" if (!defined($opt{"SSH_USER"})); 11772545eb61SSteven Rostedtdie "BUILD_DIR not defined\n" if (!defined($opt{"BUILD_DIR"})); 11782545eb61SSteven Rostedtdie "OUTPUT_DIR not defined\n" if (!defined($opt{"OUTPUT_DIR"})); 11792545eb61SSteven Rostedtdie "BUILD_TARGET not defined\n" if (!defined($opt{"BUILD_TARGET"})); 118075c3fda7SSteven Rostedtdie "TARGET_IMAGE not defined\n" if (!defined($opt{"TARGET_IMAGE"})); 11812545eb61SSteven Rostedtdie "POWER_CYCLE not defined\n" if (!defined($opt{"POWER_CYCLE"})); 11822545eb61SSteven Rostedtdie "CONSOLE not defined\n" if (!defined($opt{"CONSOLE"})); 11832545eb61SSteven Rostedtdie "LOCALVERSION not defined\n" if (!defined($opt{"LOCALVERSION"})); 11842545eb61SSteven Rostedt 11852b7d9b21SSteven Rostedtif ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) { 11862b7d9b21SSteven Rostedt unlink $opt{"LOG_FILE"}; 11872b7d9b21SSteven Rostedt} 11882545eb61SSteven Rostedt 11892b7d9b21SSteven Rostedtdoprint "\n\nSTARTING AUTOMATED TESTS\n\n"; 11902b7d9b21SSteven Rostedt 1191a57419b3SSteven Rostedtfor (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) { 1192a57419b3SSteven Rostedt 1193a57419b3SSteven Rostedt if (!$i) { 1194a57419b3SSteven Rostedt doprint "DEFAULT OPTIONS:\n"; 1195a57419b3SSteven Rostedt } else { 1196a57419b3SSteven Rostedt doprint "\nTEST $i OPTIONS"; 1197a57419b3SSteven Rostedt if (defined($repeat_tests{$i})) { 1198a57419b3SSteven Rostedt $repeat = $repeat_tests{$i}; 1199a57419b3SSteven Rostedt doprint " ITERATE $repeat"; 1200a57419b3SSteven Rostedt } 1201a57419b3SSteven Rostedt doprint "\n"; 1202a57419b3SSteven Rostedt } 1203a57419b3SSteven Rostedt 12042b7d9b21SSteven Rostedt foreach my $option (sort keys %opt) { 1205a57419b3SSteven Rostedt 1206a57419b3SSteven Rostedt if ($option =~ /\[(\d+)\]$/) { 1207a57419b3SSteven Rostedt next if ($i != $1); 1208a57419b3SSteven Rostedt } else { 1209a57419b3SSteven Rostedt next if ($i); 1210a57419b3SSteven Rostedt } 1211a57419b3SSteven Rostedt 12122b7d9b21SSteven Rostedt doprint "$option = $opt{$option}\n"; 12132b7d9b21SSteven Rostedt } 1214a57419b3SSteven Rostedt} 12152545eb61SSteven Rostedt 1216a75fececSSteven Rostedtsub set_test_option { 12175a391fbfSSteven Rostedt my ($name, $i) = @_; 12185a391fbfSSteven Rostedt 12195a391fbfSSteven Rostedt my $option = "$name\[$i\]"; 12205a391fbfSSteven Rostedt 12215a391fbfSSteven Rostedt if (defined($opt{$option})) { 12225a391fbfSSteven Rostedt return $opt{$option}; 12235a391fbfSSteven Rostedt } 12245a391fbfSSteven Rostedt 1225a57419b3SSteven Rostedt foreach my $test (keys %repeat_tests) { 1226a57419b3SSteven Rostedt if ($i >= $test && 1227a57419b3SSteven Rostedt $i < $test + $repeat_tests{$test}) { 1228a57419b3SSteven Rostedt $option = "$name\[$test\]"; 1229a57419b3SSteven Rostedt if (defined($opt{$option})) { 1230a57419b3SSteven Rostedt return $opt{$option}; 1231a57419b3SSteven Rostedt } 1232a57419b3SSteven Rostedt } 1233a57419b3SSteven Rostedt } 1234a57419b3SSteven Rostedt 12355a391fbfSSteven Rostedt if (defined($opt{$name})) { 12365a391fbfSSteven Rostedt return $opt{$name}; 12375a391fbfSSteven Rostedt } 12385a391fbfSSteven Rostedt 12395a391fbfSSteven Rostedt return undef; 12405a391fbfSSteven Rostedt} 12415a391fbfSSteven Rostedt 12422545eb61SSteven Rostedt# First we need to do is the builds 1243a75fececSSteven Rostedtfor (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) { 12442545eb61SSteven Rostedt 1245576f627cSSteven Rostedt $iteration = $i; 1246576f627cSSteven Rostedt 1247a75fececSSteven Rostedt my $ssh_user = set_test_option("SSH_USER", $i); 1248a75fececSSteven Rostedt my $makecmd = set_test_option("MAKE_CMD", $i); 1249a75fececSSteven Rostedt 1250a75fececSSteven Rostedt $machine = set_test_option("MACHINE", $i); 1251a75fececSSteven Rostedt $tmpdir = set_test_option("TMP_DIR", $i); 1252a75fececSSteven Rostedt $outputdir = set_test_option("OUTPUT_DIR", $i); 1253a75fececSSteven Rostedt $builddir = set_test_option("BUILD_DIR", $i); 1254a75fececSSteven Rostedt $test_type = set_test_option("TEST_TYPE", $i); 1255a75fececSSteven Rostedt $build_type = set_test_option("BUILD_TYPE", $i); 1256a75fececSSteven Rostedt $build_options = set_test_option("BUILD_OPTIONS", $i); 1257a75fececSSteven Rostedt $power_cycle = set_test_option("POWER_CYCLE", $i); 1258a75fececSSteven Rostedt $noclean = set_test_option("BUILD_NOCLEAN", $i); 1259a75fececSSteven Rostedt $minconfig = set_test_option("MIN_CONFIG", $i); 1260a75fececSSteven Rostedt $run_test = set_test_option("TEST", $i); 1261a75fececSSteven Rostedt $addconfig = set_test_option("ADD_CONFIG", $i); 1262a75fececSSteven Rostedt $reboot_type = set_test_option("REBOOT_TYPE", $i); 1263a75fececSSteven Rostedt $grub_menu = set_test_option("GRUB_MENU", $i); 12648b37ca8cSSteven Rostedt $post_install = set_test_option("POST_INSTALL", $i); 1265a75fececSSteven Rostedt $reboot_script = set_test_option("REBOOT_SCRIPT", $i); 1266a75fececSSteven Rostedt $reboot_on_error = set_test_option("REBOOT_ON_ERROR", $i); 1267a75fececSSteven Rostedt $poweroff_on_error = set_test_option("POWEROFF_ON_ERROR", $i); 1268a75fececSSteven Rostedt $die_on_failure = set_test_option("DIE_ON_FAILURE", $i); 1269a75fececSSteven Rostedt $power_off = set_test_option("POWER_OFF", $i); 1270576f627cSSteven Rostedt $powercycle_after_reboot = set_test_option("POWERCYCLE_AFTER_REBOOT", $i); 1271576f627cSSteven Rostedt $poweroff_after_halt = set_test_option("POWEROFF_AFTER_HALT", $i); 1272a75fececSSteven Rostedt $sleep_time = set_test_option("SLEEP_TIME", $i); 1273a75fececSSteven Rostedt $bisect_sleep_time = set_test_option("BISECT_SLEEP_TIME", $i); 1274a75fececSSteven Rostedt $store_failures = set_test_option("STORE_FAILURES", $i); 1275a75fececSSteven Rostedt $timeout = set_test_option("TIMEOUT", $i); 1276a75fececSSteven Rostedt $booted_timeout = set_test_option("BOOTED_TIMEOUT", $i); 1277a75fececSSteven Rostedt $console = set_test_option("CONSOLE", $i); 1278a75fececSSteven Rostedt $success_line = set_test_option("SUCCESS_LINE", $i); 1279a75fececSSteven Rostedt $build_target = set_test_option("BUILD_TARGET", $i); 1280a75fececSSteven Rostedt $target_image = set_test_option("TARGET_IMAGE", $i); 1281a75fececSSteven Rostedt $localversion = set_test_option("LOCALVERSION", $i); 1282a75fececSSteven Rostedt 1283a75fececSSteven Rostedt chdir $builddir || die "can't change directory to $builddir"; 1284a75fececSSteven Rostedt 1285a75fececSSteven Rostedt if (!-d $tmpdir) { 1286a75fececSSteven Rostedt mkpath($tmpdir) or 1287a75fececSSteven Rostedt die "can't create $tmpdir"; 1288a75fececSSteven Rostedt } 1289a75fececSSteven Rostedt 1290a75fececSSteven Rostedt $target = "$ssh_user\@$machine"; 1291a75fececSSteven Rostedt 1292a75fececSSteven Rostedt $buildlog = "$tmpdir/buildlog-$machine"; 1293a75fececSSteven Rostedt $dmesg = "$tmpdir/dmesg-$machine"; 1294a75fececSSteven Rostedt $make = "$makecmd O=$outputdir"; 1295a75fececSSteven Rostedt 1296a75fececSSteven Rostedt if ($reboot_type eq "grub") { 1297576f627cSSteven Rostedt dodie "GRUB_MENU not defined" if (!defined($grub_menu)); 1298a75fececSSteven Rostedt } elsif (!defined($reboot_script)) { 1299576f627cSSteven Rostedt dodie "REBOOT_SCRIPT not defined" 1300a75fececSSteven Rostedt } 1301a75fececSSteven Rostedt 1302a75fececSSteven Rostedt my $run_type = $build_type; 1303a75fececSSteven Rostedt if ($test_type eq "patchcheck") { 1304a75fececSSteven Rostedt $run_type = $opt{"PATCHCHECK_TYPE[$i]"}; 1305a75fececSSteven Rostedt } elsif ($test_type eq "bisect") { 1306a75fececSSteven Rostedt $run_type = $opt{"BISECT_TYPE[$i]"}; 1307a75fececSSteven Rostedt } 1308a75fececSSteven Rostedt 1309a75fececSSteven Rostedt # mistake in config file? 1310a75fececSSteven Rostedt if (!defined($run_type)) { 1311a75fececSSteven Rostedt $run_type = "ERROR"; 1312a75fececSSteven Rostedt } 13132545eb61SSteven Rostedt 13142545eb61SSteven Rostedt doprint "\n\n"; 1315a75fececSSteven Rostedt doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type\n\n"; 13167faafbd6SSteven Rostedt 13177faafbd6SSteven Rostedt unlink $dmesg; 13187faafbd6SSteven Rostedt unlink $buildlog; 13192545eb61SSteven Rostedt 13202b7d9b21SSteven Rostedt if (!defined($minconfig)) { 13212b7d9b21SSteven Rostedt $minconfig = $addconfig; 13222b7d9b21SSteven Rostedt 13232b7d9b21SSteven Rostedt } elsif (defined($addconfig)) { 1324a75fececSSteven Rostedt run_command "cat $addconfig $minconfig > $tmpdir/use_config" or 13252b7d9b21SSteven Rostedt dodie "Failed to create temp config"; 1326a75fececSSteven Rostedt $minconfig = "$tmpdir/use_config"; 13272b7d9b21SSteven Rostedt } 13282b7d9b21SSteven Rostedt 13296c5ee0beSSteven Rostedt my $checkout = $opt{"CHECKOUT[$i]"}; 13306c5ee0beSSteven Rostedt if (defined($checkout)) { 13316c5ee0beSSteven Rostedt run_command "git checkout $checkout" or 13326c5ee0beSSteven Rostedt die "failed to checkout $checkout"; 13336c5ee0beSSteven Rostedt } 13346c5ee0beSSteven Rostedt 1335a75fececSSteven Rostedt if ($test_type eq "bisect") { 13365f9b6cedSSteven Rostedt bisect $i; 13375f9b6cedSSteven Rostedt next; 1338a75fececSSteven Rostedt } elsif ($test_type eq "patchcheck") { 13396c5ee0beSSteven Rostedt patchcheck $i; 13406c5ee0beSSteven Rostedt next; 13415f9b6cedSSteven Rostedt } 13425f9b6cedSSteven Rostedt 13437faafbd6SSteven Rostedt if ($build_type ne "nobuild") { 13447faafbd6SSteven Rostedt build $build_type or next; 13452545eb61SSteven Rostedt } 13462545eb61SSteven Rostedt 1347a75fececSSteven Rostedt if ($test_type ne "build") { 13485f9b6cedSSteven Rostedt get_grub_index; 13495f9b6cedSSteven Rostedt get_version; 13502545eb61SSteven Rostedt install; 13515a391fbfSSteven Rostedt 13527faafbd6SSteven Rostedt my $failed = 0; 13537faafbd6SSteven Rostedt start_monitor; 13547faafbd6SSteven Rostedt monitor or $failed = 1;; 1355a75fececSSteven Rostedt 1356a75fececSSteven Rostedt if (!$failed && $test_type ne "boot" && defined($run_test)) { 13577faafbd6SSteven Rostedt do_run_test or $failed = 1; 13585a391fbfSSteven Rostedt } 13597faafbd6SSteven Rostedt end_monitor; 13607faafbd6SSteven Rostedt next if ($failed); 1361a75fececSSteven Rostedt } 13625a391fbfSSteven Rostedt 13635f9b6cedSSteven Rostedt success $i; 136475c3fda7SSteven Rostedt} 13652545eb61SSteven Rostedt 13665c42fc5bSSteven Rostedtif ($opt{"POWEROFF_ON_SUCCESS"}) { 136775c3fda7SSteven Rostedt halt; 1368576f627cSSteven Rostedt} elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot) { 136975c3fda7SSteven Rostedt reboot; 13705c42fc5bSSteven Rostedt} 137175c3fda7SSteven Rostedt 13722545eb61SSteven Rostedtexit 0; 1373