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; 4951ad1dd1SSteven Rostedtmy $output_config; 50a75fececSSteven Rostedtmy $test_type; 517faafbd6SSteven Rostedtmy $build_type; 52a75fececSSteven Rostedtmy $build_options; 53a75fececSSteven Rostedtmy $reboot_type; 54a75fececSSteven Rostedtmy $reboot_script; 55a75fececSSteven Rostedtmy $power_cycle; 56a75fececSSteven Rostedtmy $reboot_on_error; 57a75fececSSteven Rostedtmy $poweroff_on_error; 58a75fececSSteven Rostedtmy $die_on_failure; 59576f627cSSteven Rostedtmy $powercycle_after_reboot; 60576f627cSSteven Rostedtmy $poweroff_after_halt; 61a75fececSSteven Rostedtmy $power_off; 62a75fececSSteven Rostedtmy $grub_menu; 632545eb61SSteven Rostedtmy $grub_number; 642545eb61SSteven Rostedtmy $target; 652545eb61SSteven Rostedtmy $make; 668b37ca8cSSteven Rostedtmy $post_install; 675c42fc5bSSteven Rostedtmy $noclean; 685f9b6cedSSteven Rostedtmy $minconfig; 692b7d9b21SSteven Rostedtmy $addconfig; 705f9b6cedSSteven Rostedtmy $in_bisect = 0; 715f9b6cedSSteven Rostedtmy $bisect_bad = ""; 72d6ce2a0bSSteven Rostedtmy $reverse_bisect; 736c5ee0beSSteven Rostedtmy $in_patchcheck = 0; 745a391fbfSSteven Rostedtmy $run_test; 756c5ee0beSSteven Rostedtmy $redirect; 767faafbd6SSteven Rostedtmy $buildlog; 777faafbd6SSteven Rostedtmy $dmesg; 787faafbd6SSteven Rostedtmy $monitor_fp; 797faafbd6SSteven Rostedtmy $monitor_pid; 807faafbd6SSteven Rostedtmy $monitor_cnt = 0; 81a75fececSSteven Rostedtmy $sleep_time; 82a75fececSSteven Rostedtmy $bisect_sleep_time; 83a75fececSSteven Rostedtmy $store_failures; 84a75fececSSteven Rostedtmy $timeout; 85a75fececSSteven Rostedtmy $booted_timeout; 86a75fececSSteven Rostedtmy $console; 87a75fececSSteven Rostedtmy $success_line; 88a75fececSSteven Rostedtmy $build_target; 89a75fececSSteven Rostedtmy $target_image; 90a75fececSSteven Rostedtmy $localversion; 91576f627cSSteven Rostedtmy $iteration = 0; 922545eb61SSteven Rostedt 93a57419b3SSteven Rostedtsub set_value { 94a57419b3SSteven Rostedt my ($lvalue, $rvalue) = @_; 952545eb61SSteven Rostedt 96a75fececSSteven Rostedt if (defined($opt{$lvalue})) { 97a75fececSSteven Rostedt die "Error: Option $lvalue defined more than once!\n"; 98a75fececSSteven Rostedt } 992545eb61SSteven Rostedt $opt{$lvalue} = $rvalue; 100*21a9679fSSteven Rostedt if ($rvalue =~ /^\s*$/) { 101*21a9679fSSteven Rostedt delete $opt{$lvalue}; 102*21a9679fSSteven Rostedt } else { 103*21a9679fSSteven Rostedt $opt{$lvalue} = $rvalue; 104*21a9679fSSteven Rostedt } 1052545eb61SSteven Rostedt} 106a57419b3SSteven Rostedt 107a57419b3SSteven Rostedtsub read_config { 108a57419b3SSteven Rostedt my ($config) = @_; 109a57419b3SSteven Rostedt 110a57419b3SSteven Rostedt open(IN, $config) || die "can't read file $config"; 111a57419b3SSteven Rostedt 112a57419b3SSteven Rostedt my $name = $config; 113a57419b3SSteven Rostedt $name =~ s,.*/(.*),$1,; 114a57419b3SSteven Rostedt 115a57419b3SSteven Rostedt my $test_num = 0; 116a57419b3SSteven Rostedt my $default = 1; 117a57419b3SSteven Rostedt my $repeat = 1; 118a57419b3SSteven Rostedt my $num_tests_set = 0; 119a57419b3SSteven Rostedt my $skip = 0; 120a57419b3SSteven Rostedt my $rest; 121a57419b3SSteven Rostedt 122a57419b3SSteven Rostedt while (<IN>) { 123a57419b3SSteven Rostedt 124a57419b3SSteven Rostedt # ignore blank lines and comments 125a57419b3SSteven Rostedt next if (/^\s*$/ || /\s*\#/); 126a57419b3SSteven Rostedt 127a57419b3SSteven Rostedt if (/^\s*TEST_START(.*)/) { 128a57419b3SSteven Rostedt 129a57419b3SSteven Rostedt $rest = $1; 130a57419b3SSteven Rostedt 131a57419b3SSteven Rostedt if ($num_tests_set) { 132a57419b3SSteven Rostedt die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n"; 133a57419b3SSteven Rostedt } 134a57419b3SSteven Rostedt 135a57419b3SSteven Rostedt my $old_test_num = $test_num; 136a57419b3SSteven Rostedt 137a57419b3SSteven Rostedt $test_num += $repeat; 138a57419b3SSteven Rostedt $default = 0; 139a57419b3SSteven Rostedt $repeat = 1; 140a57419b3SSteven Rostedt 141a57419b3SSteven Rostedt if ($rest =~ /\s+SKIP(.*)/) { 142a57419b3SSteven Rostedt $rest = $1; 143a57419b3SSteven Rostedt $skip = 1; 144a57419b3SSteven Rostedt } else { 145a57419b3SSteven Rostedt $skip = 0; 146a57419b3SSteven Rostedt } 147a57419b3SSteven Rostedt 148a57419b3SSteven Rostedt if ($rest =~ /\s+ITERATE\s+(\d+)(.*)$/) { 149a57419b3SSteven Rostedt $repeat = $1; 150a57419b3SSteven Rostedt $rest = $2; 151a57419b3SSteven Rostedt $repeat_tests{"$test_num"} = $repeat; 152a57419b3SSteven Rostedt } 153a57419b3SSteven Rostedt 154a57419b3SSteven Rostedt if ($rest =~ /\s+SKIP(.*)/) { 155a57419b3SSteven Rostedt $rest = $1; 156a57419b3SSteven Rostedt $skip = 1; 157a57419b3SSteven Rostedt } 158a57419b3SSteven Rostedt 159a57419b3SSteven Rostedt if ($rest !~ /^\s*$/) { 160a57419b3SSteven Rostedt die "$name: $.: Gargbage found after TEST_START\n$_"; 161a57419b3SSteven Rostedt } 162a57419b3SSteven Rostedt 163a57419b3SSteven Rostedt if ($skip) { 164a57419b3SSteven Rostedt $test_num = $old_test_num; 165a57419b3SSteven Rostedt $repeat = 1; 166a57419b3SSteven Rostedt } 167a57419b3SSteven Rostedt 168a57419b3SSteven Rostedt } elsif (/^\s*DEFAULTS(.*)$/) { 169a57419b3SSteven Rostedt $default = 1; 170a57419b3SSteven Rostedt 171a57419b3SSteven Rostedt $rest = $1; 172a57419b3SSteven Rostedt 173a57419b3SSteven Rostedt if ($rest =~ /\s+SKIP(.*)/) { 174a57419b3SSteven Rostedt $rest = $1; 175a57419b3SSteven Rostedt $skip = 1; 176a57419b3SSteven Rostedt } else { 177a57419b3SSteven Rostedt $skip = 0; 178a57419b3SSteven Rostedt } 179a57419b3SSteven Rostedt 180a57419b3SSteven Rostedt if ($rest !~ /^\s*$/) { 181a57419b3SSteven Rostedt die "$name: $.: Gargbage found after DEFAULTS\n$_"; 182a57419b3SSteven Rostedt } 183a57419b3SSteven Rostedt 184a57419b3SSteven Rostedt } elsif (/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) { 185a57419b3SSteven Rostedt 186a57419b3SSteven Rostedt next if ($skip); 187a57419b3SSteven Rostedt 188a57419b3SSteven Rostedt my $lvalue = $1; 189a57419b3SSteven Rostedt my $rvalue = $2; 190a57419b3SSteven Rostedt 191a57419b3SSteven Rostedt if (!$default && 192a57419b3SSteven Rostedt ($lvalue eq "NUM_TESTS" || 193a57419b3SSteven Rostedt $lvalue eq "LOG_FILE" || 194a57419b3SSteven Rostedt $lvalue eq "CLEAR_LOG")) { 195a57419b3SSteven Rostedt die "$name: $.: $lvalue must be set in DEFAULTS section\n"; 196a57419b3SSteven Rostedt } 197a57419b3SSteven Rostedt 198a57419b3SSteven Rostedt if ($lvalue eq "NUM_TESTS") { 199a57419b3SSteven Rostedt if ($test_num) { 200a57419b3SSteven Rostedt die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n"; 201a57419b3SSteven Rostedt } 202a57419b3SSteven Rostedt if (!$default) { 203a57419b3SSteven Rostedt die "$name: $.: NUM_TESTS must be set in default section\n"; 204a57419b3SSteven Rostedt } 205a57419b3SSteven Rostedt $num_tests_set = 1; 206a57419b3SSteven Rostedt } 207a57419b3SSteven Rostedt 208a57419b3SSteven Rostedt if ($default || $lvalue =~ /\[\d+\]$/) { 209a57419b3SSteven Rostedt set_value($lvalue, $rvalue); 210a57419b3SSteven Rostedt } else { 211a57419b3SSteven Rostedt my $val = "$lvalue\[$test_num\]"; 212a57419b3SSteven Rostedt set_value($val, $rvalue); 213a57419b3SSteven Rostedt 214a57419b3SSteven Rostedt if ($repeat > 1) { 215a57419b3SSteven Rostedt $repeats{$val} = $repeat; 216a57419b3SSteven Rostedt } 217a57419b3SSteven Rostedt } 218a57419b3SSteven Rostedt } else { 219a57419b3SSteven Rostedt die "$name: $.: Garbage found in config\n$_"; 220a57419b3SSteven Rostedt } 2212545eb61SSteven Rostedt } 2222545eb61SSteven Rostedt 2232545eb61SSteven Rostedt close(IN); 224a75fececSSteven Rostedt 225a57419b3SSteven Rostedt if ($test_num) { 226a57419b3SSteven Rostedt $test_num += $repeat - 1; 227a57419b3SSteven Rostedt $opt{"NUM_TESTS"} = $test_num; 228a57419b3SSteven Rostedt } 229a57419b3SSteven Rostedt 230a75fececSSteven Rostedt # set any defaults 231a75fececSSteven Rostedt 232a75fececSSteven Rostedt foreach my $default (keys %default) { 233a75fececSSteven Rostedt if (!defined($opt{$default})) { 234a75fececSSteven Rostedt $opt{$default} = $default{$default}; 235a75fececSSteven Rostedt } 236a75fececSSteven Rostedt } 2372545eb61SSteven Rostedt} 2382545eb61SSteven Rostedt 239d1e2f22aSSteven Rostedtsub _logit { 2402545eb61SSteven Rostedt if (defined($opt{"LOG_FILE"})) { 2412545eb61SSteven Rostedt open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}"; 2422545eb61SSteven Rostedt print OUT @_; 2432545eb61SSteven Rostedt close(OUT); 2442545eb61SSteven Rostedt } 2452545eb61SSteven Rostedt} 2462545eb61SSteven Rostedt 247d1e2f22aSSteven Rostedtsub logit { 248d1e2f22aSSteven Rostedt if (defined($opt{"LOG_FILE"})) { 249d1e2f22aSSteven Rostedt _logit @_; 250d1e2f22aSSteven Rostedt } else { 251d1e2f22aSSteven Rostedt print @_; 252d1e2f22aSSteven Rostedt } 253d1e2f22aSSteven Rostedt} 254d1e2f22aSSteven Rostedt 2555f9b6cedSSteven Rostedtsub doprint { 2565f9b6cedSSteven Rostedt print @_; 257d1e2f22aSSteven Rostedt _logit @_; 2585f9b6cedSSteven Rostedt} 2595f9b6cedSSteven Rostedt 2607faafbd6SSteven Rostedtsub run_command; 2617faafbd6SSteven Rostedt 2627faafbd6SSteven Rostedtsub reboot { 2637faafbd6SSteven Rostedt # try to reboot normally 264576f627cSSteven Rostedt if (run_command "ssh $target reboot") { 265576f627cSSteven Rostedt if (defined($powercycle_after_reboot)) { 266576f627cSSteven Rostedt sleep $powercycle_after_reboot; 267576f627cSSteven Rostedt run_command "$power_cycle"; 268576f627cSSteven Rostedt } 269576f627cSSteven Rostedt } else { 2707faafbd6SSteven Rostedt # nope? power cycle it. 271a75fececSSteven Rostedt run_command "$power_cycle"; 2727faafbd6SSteven Rostedt } 2737faafbd6SSteven Rostedt} 2747faafbd6SSteven Rostedt 275576f627cSSteven Rostedtsub do_not_reboot { 276576f627cSSteven Rostedt my $i = $iteration; 277576f627cSSteven Rostedt 278576f627cSSteven Rostedt return $test_type eq "build" || 279576f627cSSteven Rostedt ($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") || 280576f627cSSteven Rostedt ($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build"); 281576f627cSSteven Rostedt} 282576f627cSSteven Rostedt 2835c42fc5bSSteven Rostedtsub dodie { 2845a391fbfSSteven Rostedt doprint "CRITICAL FAILURE... ", @_, "\n"; 2855c42fc5bSSteven Rostedt 286576f627cSSteven Rostedt my $i = $iteration; 287576f627cSSteven Rostedt 288576f627cSSteven Rostedt if ($reboot_on_error && !do_not_reboot) { 289576f627cSSteven Rostedt 29075c3fda7SSteven Rostedt doprint "REBOOTING\n"; 2917faafbd6SSteven Rostedt reboot; 29275c3fda7SSteven Rostedt 293a75fececSSteven Rostedt } elsif ($poweroff_on_error && defined($power_off)) { 2945c42fc5bSSteven Rostedt doprint "POWERING OFF\n"; 295a75fececSSteven Rostedt `$power_off`; 2965c42fc5bSSteven Rostedt } 29775c3fda7SSteven Rostedt 298576f627cSSteven Rostedt die @_, "\n"; 2995c42fc5bSSteven Rostedt} 3005c42fc5bSSteven Rostedt 3017faafbd6SSteven Rostedtsub open_console { 3027faafbd6SSteven Rostedt my ($fp) = @_; 3037faafbd6SSteven Rostedt 3047faafbd6SSteven Rostedt my $flags; 3057faafbd6SSteven Rostedt 306a75fececSSteven Rostedt my $pid = open($fp, "$console|") or 307a75fececSSteven Rostedt dodie "Can't open console $console"; 3087faafbd6SSteven Rostedt 3097faafbd6SSteven Rostedt $flags = fcntl($fp, F_GETFL, 0) or 310576f627cSSteven Rostedt dodie "Can't get flags for the socket: $!"; 3117faafbd6SSteven Rostedt $flags = fcntl($fp, F_SETFL, $flags | O_NONBLOCK) or 312576f627cSSteven Rostedt dodie "Can't set flags for the socket: $!"; 3137faafbd6SSteven Rostedt 3147faafbd6SSteven Rostedt return $pid; 3157faafbd6SSteven Rostedt} 3167faafbd6SSteven Rostedt 3177faafbd6SSteven Rostedtsub close_console { 3187faafbd6SSteven Rostedt my ($fp, $pid) = @_; 3197faafbd6SSteven Rostedt 3207faafbd6SSteven Rostedt doprint "kill child process $pid\n"; 3217faafbd6SSteven Rostedt kill 2, $pid; 3227faafbd6SSteven Rostedt 3237faafbd6SSteven Rostedt print "closing!\n"; 3247faafbd6SSteven Rostedt close($fp); 3257faafbd6SSteven Rostedt} 3267faafbd6SSteven Rostedt 3277faafbd6SSteven Rostedtsub start_monitor { 3287faafbd6SSteven Rostedt if ($monitor_cnt++) { 3297faafbd6SSteven Rostedt return; 3307faafbd6SSteven Rostedt } 3317faafbd6SSteven Rostedt $monitor_fp = \*MONFD; 3327faafbd6SSteven Rostedt $monitor_pid = open_console $monitor_fp; 333a75fececSSteven Rostedt 334a75fececSSteven Rostedt return; 335a75fececSSteven Rostedt 336a75fececSSteven Rostedt open(MONFD, "Stop perl from warning about single use of MONFD"); 3377faafbd6SSteven Rostedt} 3387faafbd6SSteven Rostedt 3397faafbd6SSteven Rostedtsub end_monitor { 3407faafbd6SSteven Rostedt if (--$monitor_cnt) { 3417faafbd6SSteven Rostedt return; 3427faafbd6SSteven Rostedt } 3437faafbd6SSteven Rostedt close_console($monitor_fp, $monitor_pid); 3447faafbd6SSteven Rostedt} 3457faafbd6SSteven Rostedt 3467faafbd6SSteven Rostedtsub wait_for_monitor { 3477faafbd6SSteven Rostedt my ($time) = @_; 3487faafbd6SSteven Rostedt my $line; 3497faafbd6SSteven Rostedt 350a75fececSSteven Rostedt doprint "** Wait for monitor to settle down **\n"; 3517faafbd6SSteven Rostedt 3527faafbd6SSteven Rostedt # read the monitor and wait for the system to calm down 3537faafbd6SSteven Rostedt do { 3547faafbd6SSteven Rostedt $line = wait_for_input($monitor_fp, $time); 355a75fececSSteven Rostedt print "$line" if (defined($line)); 3567faafbd6SSteven Rostedt } while (defined($line)); 357a75fececSSteven Rostedt print "** Monitor flushed **\n"; 3587faafbd6SSteven Rostedt} 3597faafbd6SSteven Rostedt 3602b7d9b21SSteven Rostedtsub fail { 3612b7d9b21SSteven Rostedt 362a75fececSSteven Rostedt if ($die_on_failure) { 3632b7d9b21SSteven Rostedt dodie @_; 3642b7d9b21SSteven Rostedt } 3652b7d9b21SSteven Rostedt 366a75fececSSteven Rostedt doprint "FAILED\n"; 3677faafbd6SSteven Rostedt 368576f627cSSteven Rostedt my $i = $iteration; 369576f627cSSteven Rostedt 370a75fececSSteven Rostedt # no need to reboot for just building. 371576f627cSSteven Rostedt if (!do_not_reboot) { 3727faafbd6SSteven Rostedt doprint "REBOOTING\n"; 3737faafbd6SSteven Rostedt reboot; 3747faafbd6SSteven Rostedt start_monitor; 375a75fececSSteven Rostedt wait_for_monitor $sleep_time; 3767faafbd6SSteven Rostedt end_monitor; 377a75fececSSteven Rostedt } 3787faafbd6SSteven Rostedt 379576f627cSSteven Rostedt doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; 380576f627cSSteven Rostedt doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; 381a75fececSSteven Rostedt doprint "**** Failed: ", @_, " ****\n"; 382576f627cSSteven Rostedt doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; 383576f627cSSteven Rostedt doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; 384a75fececSSteven Rostedt 385a75fececSSteven Rostedt return 1 if (!defined($store_failures)); 3867faafbd6SSteven Rostedt 3877faafbd6SSteven Rostedt my @t = localtime; 3887faafbd6SSteven Rostedt my $date = sprintf "%04d%02d%02d%02d%02d%02d", 3897faafbd6SSteven Rostedt 1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0]; 3907faafbd6SSteven Rostedt 391a75fececSSteven Rostedt my $dir = "$machine-$test_type-$build_type-fail-$date"; 392a75fececSSteven Rostedt my $faildir = "$store_failures/$dir"; 3937faafbd6SSteven Rostedt 3947faafbd6SSteven Rostedt if (!-d $faildir) { 3957faafbd6SSteven Rostedt mkpath($faildir) or 396a75fececSSteven Rostedt die "can't create $faildir"; 3977faafbd6SSteven Rostedt } 39851ad1dd1SSteven Rostedt if (-f "$output_config") { 39951ad1dd1SSteven Rostedt cp "$output_config", "$faildir/config" or 4007faafbd6SSteven Rostedt die "failed to copy .config"; 4017faafbd6SSteven Rostedt } 4027faafbd6SSteven Rostedt if (-f $buildlog) { 4037faafbd6SSteven Rostedt cp $buildlog, "$faildir/buildlog" or 4047faafbd6SSteven Rostedt die "failed to move $buildlog"; 4057faafbd6SSteven Rostedt } 4067faafbd6SSteven Rostedt if (-f $dmesg) { 4077faafbd6SSteven Rostedt cp $dmesg, "$faildir/dmesg" or 4087faafbd6SSteven Rostedt die "failed to move $dmesg"; 4097faafbd6SSteven Rostedt } 4107faafbd6SSteven Rostedt 4117faafbd6SSteven Rostedt doprint "*** Saved info to $faildir ***\n"; 4127faafbd6SSteven Rostedt 4132b7d9b21SSteven Rostedt return 1; 4142b7d9b21SSteven Rostedt} 4152b7d9b21SSteven Rostedt 4162545eb61SSteven Rostedtsub run_command { 4172545eb61SSteven Rostedt my ($command) = @_; 418d6ce2a0bSSteven Rostedt my $dolog = 0; 419d6ce2a0bSSteven Rostedt my $dord = 0; 420d6ce2a0bSSteven Rostedt my $pid; 421d6ce2a0bSSteven Rostedt 422d6ce2a0bSSteven Rostedt doprint("$command ... "); 423d6ce2a0bSSteven Rostedt 424d6ce2a0bSSteven Rostedt $pid = open(CMD, "$command 2>&1 |") or 4252b7d9b21SSteven Rostedt (fail "unable to exec $command" and return 0); 4262545eb61SSteven Rostedt 4272545eb61SSteven Rostedt if (defined($opt{"LOG_FILE"})) { 428d6ce2a0bSSteven Rostedt open(LOG, ">>$opt{LOG_FILE}") or 429d6ce2a0bSSteven Rostedt dodie "failed to write to log"; 430d6ce2a0bSSteven Rostedt $dolog = 1; 4316c5ee0beSSteven Rostedt } 4326c5ee0beSSteven Rostedt 4336c5ee0beSSteven Rostedt if (defined($redirect)) { 434d6ce2a0bSSteven Rostedt open (RD, ">$redirect") or 435d6ce2a0bSSteven Rostedt dodie "failed to write to redirect $redirect"; 436d6ce2a0bSSteven Rostedt $dord = 1; 4372545eb61SSteven Rostedt } 4382545eb61SSteven Rostedt 439d6ce2a0bSSteven Rostedt while (<CMD>) { 440d6ce2a0bSSteven Rostedt print LOG if ($dolog); 441d6ce2a0bSSteven Rostedt print RD if ($dord); 442d6ce2a0bSSteven Rostedt } 4432545eb61SSteven Rostedt 444d6ce2a0bSSteven Rostedt waitpid($pid, 0); 4452545eb61SSteven Rostedt my $failed = $?; 4462545eb61SSteven Rostedt 447d6ce2a0bSSteven Rostedt close(CMD); 448d6ce2a0bSSteven Rostedt close(LOG) if ($dolog); 449d6ce2a0bSSteven Rostedt close(RD) if ($dord); 450d6ce2a0bSSteven Rostedt 4512545eb61SSteven Rostedt if ($failed) { 4522545eb61SSteven Rostedt doprint "FAILED!\n"; 4532545eb61SSteven Rostedt } else { 4542545eb61SSteven Rostedt doprint "SUCCESS\n"; 4552545eb61SSteven Rostedt } 4562545eb61SSteven Rostedt 4575f9b6cedSSteven Rostedt return !$failed; 4585f9b6cedSSteven Rostedt} 4595f9b6cedSSteven Rostedt 4605f9b6cedSSteven Rostedtsub get_grub_index { 4615f9b6cedSSteven Rostedt 462a75fececSSteven Rostedt if ($reboot_type ne "grub") { 463a75fececSSteven Rostedt return; 464a75fececSSteven Rostedt } 4655a391fbfSSteven Rostedt return if (defined($grub_number)); 4665f9b6cedSSteven Rostedt 4675f9b6cedSSteven Rostedt doprint "Find grub menu ... "; 4685f9b6cedSSteven Rostedt $grub_number = -1; 4695f9b6cedSSteven Rostedt open(IN, "ssh $target cat /boot/grub/menu.lst |") 4705f9b6cedSSteven Rostedt or die "unable to get menu.lst"; 4715f9b6cedSSteven Rostedt while (<IN>) { 472a75fececSSteven Rostedt if (/^\s*title\s+$grub_menu\s*$/) { 4735f9b6cedSSteven Rostedt $grub_number++; 4745f9b6cedSSteven Rostedt last; 4755f9b6cedSSteven Rostedt } elsif (/^\s*title\s/) { 4765f9b6cedSSteven Rostedt $grub_number++; 4775f9b6cedSSteven Rostedt } 4785f9b6cedSSteven Rostedt } 4795f9b6cedSSteven Rostedt close(IN); 4805f9b6cedSSteven Rostedt 481a75fececSSteven Rostedt die "Could not find '$grub_menu' in /boot/grub/menu on $machine" 4825f9b6cedSSteven Rostedt if ($grub_number < 0); 4835f9b6cedSSteven Rostedt doprint "$grub_number\n"; 4842545eb61SSteven Rostedt} 4852545eb61SSteven Rostedt 4862545eb61SSteven Rostedtsub wait_for_input 4872545eb61SSteven Rostedt{ 4882545eb61SSteven Rostedt my ($fp, $time) = @_; 4892545eb61SSteven Rostedt my $rin; 4902545eb61SSteven Rostedt my $ready; 4912545eb61SSteven Rostedt my $line; 4922545eb61SSteven Rostedt my $ch; 4932545eb61SSteven Rostedt 4942545eb61SSteven Rostedt if (!defined($time)) { 4952545eb61SSteven Rostedt $time = $timeout; 4962545eb61SSteven Rostedt } 4972545eb61SSteven Rostedt 4982545eb61SSteven Rostedt $rin = ''; 4992545eb61SSteven Rostedt vec($rin, fileno($fp), 1) = 1; 5002545eb61SSteven Rostedt $ready = select($rin, undef, undef, $time); 5012545eb61SSteven Rostedt 5022545eb61SSteven Rostedt $line = ""; 5032545eb61SSteven Rostedt 5042545eb61SSteven Rostedt # try to read one char at a time 5052545eb61SSteven Rostedt while (sysread $fp, $ch, 1) { 5062545eb61SSteven Rostedt $line .= $ch; 5072545eb61SSteven Rostedt last if ($ch eq "\n"); 5082545eb61SSteven Rostedt } 5092545eb61SSteven Rostedt 5102545eb61SSteven Rostedt if (!length($line)) { 5112545eb61SSteven Rostedt return undef; 5122545eb61SSteven Rostedt } 5132545eb61SSteven Rostedt 5142545eb61SSteven Rostedt return $line; 5152545eb61SSteven Rostedt} 5162545eb61SSteven Rostedt 51775c3fda7SSteven Rostedtsub reboot_to { 518a75fececSSteven Rostedt if ($reboot_type eq "grub") { 5192545eb61SSteven Rostedt run_command "ssh $target '(echo \"savedefault --default=$grub_number --once\" | grub --batch; reboot)'"; 520a75fececSSteven Rostedt return; 521a75fececSSteven Rostedt } 522a75fececSSteven Rostedt 523a75fececSSteven Rostedt run_command "$reboot_script"; 5242545eb61SSteven Rostedt} 5252545eb61SSteven Rostedt 526a57419b3SSteven Rostedtsub get_sha1 { 527a57419b3SSteven Rostedt my ($commit) = @_; 528a57419b3SSteven Rostedt 529a57419b3SSteven Rostedt doprint "git rev-list --max-count=1 $commit ... "; 530a57419b3SSteven Rostedt my $sha1 = `git rev-list --max-count=1 $commit`; 531a57419b3SSteven Rostedt my $ret = $?; 532a57419b3SSteven Rostedt 533a57419b3SSteven Rostedt logit $sha1; 534a57419b3SSteven Rostedt 535a57419b3SSteven Rostedt if ($ret) { 536a57419b3SSteven Rostedt doprint "FAILED\n"; 537a57419b3SSteven Rostedt dodie "Failed to get git $commit"; 538a57419b3SSteven Rostedt } 539a57419b3SSteven Rostedt 540a57419b3SSteven Rostedt print "SUCCESS\n"; 541a57419b3SSteven Rostedt 542a57419b3SSteven Rostedt chomp $sha1; 543a57419b3SSteven Rostedt 544a57419b3SSteven Rostedt return $sha1; 545a57419b3SSteven Rostedt} 546a57419b3SSteven Rostedt 5475a391fbfSSteven Rostedtsub monitor { 5482545eb61SSteven Rostedt my $booted = 0; 5492545eb61SSteven Rostedt my $bug = 0; 5505c42fc5bSSteven Rostedt my $skip_call_trace = 0; 5512b7d9b21SSteven Rostedt my $loops; 5522545eb61SSteven Rostedt 5537faafbd6SSteven Rostedt wait_for_monitor 5; 5542545eb61SSteven Rostedt 5552545eb61SSteven Rostedt my $line; 5562545eb61SSteven Rostedt my $full_line = ""; 5572545eb61SSteven Rostedt 5587faafbd6SSteven Rostedt open(DMESG, "> $dmesg") or 5597faafbd6SSteven Rostedt die "unable to write to $dmesg"; 5602545eb61SSteven Rostedt 56175c3fda7SSteven Rostedt reboot_to; 5622545eb61SSteven Rostedt 5632545eb61SSteven Rostedt for (;;) { 5642545eb61SSteven Rostedt 5652b7d9b21SSteven Rostedt if ($booted) { 566a75fececSSteven Rostedt $line = wait_for_input($monitor_fp, $booted_timeout); 5672b7d9b21SSteven Rostedt } else { 5687faafbd6SSteven Rostedt $line = wait_for_input($monitor_fp); 5692b7d9b21SSteven Rostedt } 5702545eb61SSteven Rostedt 5712545eb61SSteven Rostedt last if (!defined($line)); 5722545eb61SSteven Rostedt 5732545eb61SSteven Rostedt doprint $line; 5747faafbd6SSteven Rostedt print DMESG $line; 5752545eb61SSteven Rostedt 5762545eb61SSteven Rostedt # we are not guaranteed to get a full line 5772545eb61SSteven Rostedt $full_line .= $line; 5782545eb61SSteven Rostedt 579a75fececSSteven Rostedt if ($full_line =~ /$success_line/) { 5802545eb61SSteven Rostedt $booted = 1; 5812545eb61SSteven Rostedt } 5822545eb61SSteven Rostedt 5835c42fc5bSSteven Rostedt if ($full_line =~ /\[ backtrace testing \]/) { 5845c42fc5bSSteven Rostedt $skip_call_trace = 1; 5855c42fc5bSSteven Rostedt } 5865c42fc5bSSteven Rostedt 5872545eb61SSteven Rostedt if ($full_line =~ /call trace:/i) { 5885c42fc5bSSteven Rostedt $bug = 1 if (!$skip_call_trace); 5895c42fc5bSSteven Rostedt } 5905c42fc5bSSteven Rostedt 5915c42fc5bSSteven Rostedt if ($full_line =~ /\[ end of backtrace testing \]/) { 5925c42fc5bSSteven Rostedt $skip_call_trace = 0; 5935c42fc5bSSteven Rostedt } 5945c42fc5bSSteven Rostedt 5955c42fc5bSSteven Rostedt if ($full_line =~ /Kernel panic -/) { 5962545eb61SSteven Rostedt $bug = 1; 5972545eb61SSteven Rostedt } 5982545eb61SSteven Rostedt 5992545eb61SSteven Rostedt if ($line =~ /\n/) { 6002545eb61SSteven Rostedt $full_line = ""; 6012545eb61SSteven Rostedt } 6022545eb61SSteven Rostedt } 6032545eb61SSteven Rostedt 6047faafbd6SSteven Rostedt close(DMESG); 6052545eb61SSteven Rostedt 6062545eb61SSteven Rostedt if ($bug) { 6072b7d9b21SSteven Rostedt return 0 if ($in_bisect); 608576f627cSSteven Rostedt fail "failed - got a bug report" and return 0; 6092545eb61SSteven Rostedt } 6105f9b6cedSSteven Rostedt 611a75fececSSteven Rostedt if (!$booted) { 612a75fececSSteven Rostedt return 0 if ($in_bisect); 613576f627cSSteven Rostedt fail "failed - never got a boot prompt." and return 0; 614a75fececSSteven Rostedt } 615a75fececSSteven Rostedt 6162b7d9b21SSteven Rostedt return 1; 6172545eb61SSteven Rostedt} 6182545eb61SSteven Rostedt 6192545eb61SSteven Rostedtsub install { 6202545eb61SSteven Rostedt 621a75fececSSteven Rostedt run_command "scp $outputdir/$build_target $target:$target_image" or 6225c42fc5bSSteven Rostedt dodie "failed to copy image"; 6235f9b6cedSSteven Rostedt 6245f9b6cedSSteven Rostedt my $install_mods = 0; 6255f9b6cedSSteven Rostedt 6265f9b6cedSSteven Rostedt # should we process modules? 6275f9b6cedSSteven Rostedt $install_mods = 0; 62851ad1dd1SSteven Rostedt open(IN, "$output_config") or dodie("Can't read config file"); 6295f9b6cedSSteven Rostedt while (<IN>) { 6305f9b6cedSSteven Rostedt if (/CONFIG_MODULES(=y)?/) { 6315f9b6cedSSteven Rostedt $install_mods = 1 if (defined($1)); 6325f9b6cedSSteven Rostedt last; 6335f9b6cedSSteven Rostedt } 6345f9b6cedSSteven Rostedt } 6355f9b6cedSSteven Rostedt close(IN); 6365f9b6cedSSteven Rostedt 6375f9b6cedSSteven Rostedt if (!$install_mods) { 6385f9b6cedSSteven Rostedt doprint "No modules needed\n"; 6395f9b6cedSSteven Rostedt return; 6402545eb61SSteven Rostedt } 6412545eb61SSteven Rostedt 642a75fececSSteven Rostedt run_command "$make INSTALL_MOD_PATH=$tmpdir modules_install" or 6435f9b6cedSSteven Rostedt dodie "Failed to install modules"; 6445f9b6cedSSteven Rostedt 6452545eb61SSteven Rostedt my $modlib = "/lib/modules/$version"; 646a57419b3SSteven Rostedt my $modtar = "ktest-mods.tar.bz2"; 6472545eb61SSteven Rostedt 6485f9b6cedSSteven Rostedt run_command "ssh $target rm -rf $modlib" or 6495c42fc5bSSteven Rostedt dodie "failed to remove old mods: $modlib"; 6502545eb61SSteven Rostedt 6515c42fc5bSSteven Rostedt # would be nice if scp -r did not follow symbolic links 652a75fececSSteven Rostedt run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or 6535c42fc5bSSteven Rostedt dodie "making tarball"; 6545c42fc5bSSteven Rostedt 655a75fececSSteven Rostedt run_command "scp $tmpdir/$modtar $target:/tmp" or 6565c42fc5bSSteven Rostedt dodie "failed to copy modules"; 6575c42fc5bSSteven Rostedt 658a75fececSSteven Rostedt unlink "$tmpdir/$modtar"; 6595c42fc5bSSteven Rostedt 6605f9b6cedSSteven Rostedt run_command "ssh $target '(cd / && tar xf /tmp/$modtar)'" or 6615c42fc5bSSteven Rostedt dodie "failed to tar modules"; 6625c42fc5bSSteven Rostedt 6635c42fc5bSSteven Rostedt run_command "ssh $target rm -f /tmp/$modtar"; 6648b37ca8cSSteven Rostedt 6658b37ca8cSSteven Rostedt return if (!defined($post_install)); 6668b37ca8cSSteven Rostedt 6678b37ca8cSSteven Rostedt my $save_env = $ENV{KERNEL_VERSION}; 6688b37ca8cSSteven Rostedt 6698b37ca8cSSteven Rostedt $ENV{KERNEL_VERSION} = $version; 670576f627cSSteven Rostedt run_command "$post_install" or 671576f627cSSteven Rostedt dodie "Failed to run post install"; 6728b37ca8cSSteven Rostedt 6738b37ca8cSSteven Rostedt $ENV{KERNEL_VERSION} = $save_env; 6742545eb61SSteven Rostedt} 6752545eb61SSteven Rostedt 6766c5ee0beSSteven Rostedtsub check_buildlog { 6776c5ee0beSSteven Rostedt my ($patch) = @_; 6786c5ee0beSSteven Rostedt 6796c5ee0beSSteven Rostedt my @files = `git show $patch | diffstat -l`; 6806c5ee0beSSteven Rostedt 6816c5ee0beSSteven Rostedt open(IN, "git show $patch |") or 6826c5ee0beSSteven Rostedt dodie "failed to show $patch"; 6836c5ee0beSSteven Rostedt while (<IN>) { 6846c5ee0beSSteven Rostedt if (m,^--- a/(.*),) { 6856c5ee0beSSteven Rostedt chomp $1; 6866c5ee0beSSteven Rostedt $files[$#files] = $1; 6876c5ee0beSSteven Rostedt } 6886c5ee0beSSteven Rostedt } 6896c5ee0beSSteven Rostedt close(IN); 6906c5ee0beSSteven Rostedt 6916c5ee0beSSteven Rostedt open(IN, $buildlog) or dodie "Can't open $buildlog"; 6926c5ee0beSSteven Rostedt while (<IN>) { 6936c5ee0beSSteven Rostedt if (/^\s*(.*?):.*(warning|error)/) { 6946c5ee0beSSteven Rostedt my $err = $1; 6956c5ee0beSSteven Rostedt foreach my $file (@files) { 696a75fececSSteven Rostedt my $fullpath = "$builddir/$file"; 6976c5ee0beSSteven Rostedt if ($file eq $err || $fullpath eq $err) { 6982b7d9b21SSteven Rostedt fail "$file built with warnings" and return 0; 6996c5ee0beSSteven Rostedt } 7006c5ee0beSSteven Rostedt } 7016c5ee0beSSteven Rostedt } 7026c5ee0beSSteven Rostedt } 7036c5ee0beSSteven Rostedt close(IN); 7042b7d9b21SSteven Rostedt 7052b7d9b21SSteven Rostedt return 1; 7066c5ee0beSSteven Rostedt} 7076c5ee0beSSteven Rostedt 7082545eb61SSteven Rostedtsub build { 7092545eb61SSteven Rostedt my ($type) = @_; 7105c42fc5bSSteven Rostedt my $defconfig = ""; 7112545eb61SSteven Rostedt 7127faafbd6SSteven Rostedt unlink $buildlog; 7137faafbd6SSteven Rostedt 71475c3fda7SSteven Rostedt if ($type =~ /^useconfig:(.*)/) { 71551ad1dd1SSteven Rostedt run_command "cp $1 $output_config" or 71675c3fda7SSteven Rostedt dodie "could not copy $1 to .config"; 7175f9b6cedSSteven Rostedt 71875c3fda7SSteven Rostedt $type = "oldconfig"; 71975c3fda7SSteven Rostedt } 72075c3fda7SSteven Rostedt 7215c42fc5bSSteven Rostedt # old config can ask questions 7225c42fc5bSSteven Rostedt if ($type eq "oldconfig") { 7239386c6abSSteven Rostedt $type = "oldnoconfig"; 72475c3fda7SSteven Rostedt 72575c3fda7SSteven Rostedt # allow for empty configs 72651ad1dd1SSteven Rostedt run_command "touch $output_config"; 72775c3fda7SSteven Rostedt 72851ad1dd1SSteven Rostedt run_command "mv $output_config $outputdir/config_temp" or 7295c42fc5bSSteven Rostedt dodie "moving .config"; 7305c42fc5bSSteven Rostedt 7315f9b6cedSSteven Rostedt if (!$noclean && !run_command "$make mrproper") { 7325c42fc5bSSteven Rostedt dodie "make mrproper"; 7335c42fc5bSSteven Rostedt } 7345c42fc5bSSteven Rostedt 73551ad1dd1SSteven Rostedt run_command "mv $outputdir/config_temp $output_config" or 7365c42fc5bSSteven Rostedt dodie "moving config_temp"; 7375c42fc5bSSteven Rostedt 7385c42fc5bSSteven Rostedt } elsif (!$noclean) { 73951ad1dd1SSteven Rostedt unlink "$output_config"; 7405f9b6cedSSteven Rostedt run_command "$make mrproper" or 7415c42fc5bSSteven Rostedt dodie "make mrproper"; 7425c42fc5bSSteven Rostedt } 7432545eb61SSteven Rostedt 7442545eb61SSteven Rostedt # add something to distinguish this build 745a75fececSSteven Rostedt open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file"); 746a75fececSSteven Rostedt print OUT "$localversion\n"; 7472545eb61SSteven Rostedt close(OUT); 7482545eb61SSteven Rostedt 7495f9b6cedSSteven Rostedt if (defined($minconfig)) { 7505f9b6cedSSteven Rostedt $defconfig = "KCONFIG_ALLCONFIG=$minconfig"; 7512545eb61SSteven Rostedt } 7522545eb61SSteven Rostedt 7539386c6abSSteven Rostedt run_command "$defconfig $make $type" or 7545c42fc5bSSteven Rostedt dodie "failed make config"; 7552545eb61SSteven Rostedt 756a75fececSSteven Rostedt $redirect = "$buildlog"; 757a75fececSSteven Rostedt if (!run_command "$make $build_options") { 7586c5ee0beSSteven Rostedt undef $redirect; 7595f9b6cedSSteven Rostedt # bisect may need this to pass 7602b7d9b21SSteven Rostedt return 0 if ($in_bisect); 7612b7d9b21SSteven Rostedt fail "failed build" and return 0; 7622545eb61SSteven Rostedt } 7636c5ee0beSSteven Rostedt undef $redirect; 7645f9b6cedSSteven Rostedt 7652b7d9b21SSteven Rostedt return 1; 7662545eb61SSteven Rostedt} 7672545eb61SSteven Rostedt 76875c3fda7SSteven Rostedtsub halt { 769a75fececSSteven Rostedt if (!run_command "ssh $target halt" or defined($power_off)) { 770576f627cSSteven Rostedt if (defined($poweroff_after_halt)) { 771576f627cSSteven Rostedt sleep $poweroff_after_halt; 772576f627cSSteven Rostedt run_command "$power_off"; 773576f627cSSteven Rostedt } 774576f627cSSteven Rostedt } else { 77575c3fda7SSteven Rostedt # nope? the zap it! 776a75fececSSteven Rostedt run_command "$power_off"; 77775c3fda7SSteven Rostedt } 77875c3fda7SSteven Rostedt} 77975c3fda7SSteven Rostedt 7805f9b6cedSSteven Rostedtsub success { 7815f9b6cedSSteven Rostedt my ($i) = @_; 7825f9b6cedSSteven Rostedt 7835f9b6cedSSteven Rostedt doprint "\n\n*******************************************\n"; 7845f9b6cedSSteven Rostedt doprint "*******************************************\n"; 785a75fececSSteven Rostedt doprint "** TEST $i SUCCESS!!!! **\n"; 7865f9b6cedSSteven Rostedt doprint "*******************************************\n"; 7875f9b6cedSSteven Rostedt doprint "*******************************************\n"; 7885f9b6cedSSteven Rostedt 789576f627cSSteven Rostedt if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) { 790a75fececSSteven Rostedt doprint "Reboot and wait $sleep_time seconds\n"; 7915f9b6cedSSteven Rostedt reboot; 7927faafbd6SSteven Rostedt start_monitor; 793a75fececSSteven Rostedt wait_for_monitor $sleep_time; 7947faafbd6SSteven Rostedt end_monitor; 7955f9b6cedSSteven Rostedt } 7965f9b6cedSSteven Rostedt} 7975f9b6cedSSteven Rostedt 7985f9b6cedSSteven Rostedtsub get_version { 7995f9b6cedSSteven Rostedt # get the release name 8005f9b6cedSSteven Rostedt doprint "$make kernelrelease ... "; 8015f9b6cedSSteven Rostedt $version = `$make kernelrelease | tail -1`; 8025f9b6cedSSteven Rostedt chomp($version); 8035f9b6cedSSteven Rostedt doprint "$version\n"; 8045f9b6cedSSteven Rostedt} 8055f9b6cedSSteven Rostedt 8065a391fbfSSteven Rostedtsub child_run_test { 8077faafbd6SSteven Rostedt my $failed = 0; 8085a391fbfSSteven Rostedt 8097faafbd6SSteven Rostedt # child should have no power 810a75fececSSteven Rostedt $reboot_on_error = 0; 811a75fececSSteven Rostedt $poweroff_on_error = 0; 812a75fececSSteven Rostedt $die_on_failure = 1; 8137faafbd6SSteven Rostedt 8147faafbd6SSteven Rostedt run_command $run_test or $failed = 1; 8155a391fbfSSteven Rostedt exit $failed; 8165a391fbfSSteven Rostedt} 8175a391fbfSSteven Rostedt 8185a391fbfSSteven Rostedtmy $child_done; 8195a391fbfSSteven Rostedt 8205a391fbfSSteven Rostedtsub child_finished { 8215a391fbfSSteven Rostedt $child_done = 1; 8225a391fbfSSteven Rostedt} 8235a391fbfSSteven Rostedt 8245a391fbfSSteven Rostedtsub do_run_test { 8255a391fbfSSteven Rostedt my $child_pid; 8265a391fbfSSteven Rostedt my $child_exit; 8275a391fbfSSteven Rostedt my $line; 8285a391fbfSSteven Rostedt my $full_line; 8295a391fbfSSteven Rostedt my $bug = 0; 8305a391fbfSSteven Rostedt 8317faafbd6SSteven Rostedt wait_for_monitor 1; 8325a391fbfSSteven Rostedt 8337faafbd6SSteven Rostedt doprint "run test $run_test\n"; 8345a391fbfSSteven Rostedt 8355a391fbfSSteven Rostedt $child_done = 0; 8365a391fbfSSteven Rostedt 8375a391fbfSSteven Rostedt $SIG{CHLD} = qw(child_finished); 8385a391fbfSSteven Rostedt 8395a391fbfSSteven Rostedt $child_pid = fork; 8405a391fbfSSteven Rostedt 8415a391fbfSSteven Rostedt child_run_test if (!$child_pid); 8425a391fbfSSteven Rostedt 8435a391fbfSSteven Rostedt $full_line = ""; 8445a391fbfSSteven Rostedt 8455a391fbfSSteven Rostedt do { 8467faafbd6SSteven Rostedt $line = wait_for_input($monitor_fp, 1); 8475a391fbfSSteven Rostedt if (defined($line)) { 8485a391fbfSSteven Rostedt 8495a391fbfSSteven Rostedt # we are not guaranteed to get a full line 8505a391fbfSSteven Rostedt $full_line .= $line; 8515a391fbfSSteven Rostedt 8525a391fbfSSteven Rostedt if ($full_line =~ /call trace:/i) { 8535a391fbfSSteven Rostedt $bug = 1; 8545a391fbfSSteven Rostedt } 8555a391fbfSSteven Rostedt 8565a391fbfSSteven Rostedt if ($full_line =~ /Kernel panic -/) { 8575a391fbfSSteven Rostedt $bug = 1; 8585a391fbfSSteven Rostedt } 8595a391fbfSSteven Rostedt 8605a391fbfSSteven Rostedt if ($line =~ /\n/) { 8615a391fbfSSteven Rostedt $full_line = ""; 8625a391fbfSSteven Rostedt } 8635a391fbfSSteven Rostedt } 8645a391fbfSSteven Rostedt } while (!$child_done && !$bug); 8655a391fbfSSteven Rostedt 8665a391fbfSSteven Rostedt if ($bug) { 8675a391fbfSSteven Rostedt doprint "Detected kernel crash!\n"; 8685a391fbfSSteven Rostedt # kill the child with extreme prejudice 8695a391fbfSSteven Rostedt kill 9, $child_pid; 8705a391fbfSSteven Rostedt } 8715a391fbfSSteven Rostedt 8725a391fbfSSteven Rostedt waitpid $child_pid, 0; 8735a391fbfSSteven Rostedt $child_exit = $?; 8745a391fbfSSteven Rostedt 8755a391fbfSSteven Rostedt if ($bug || $child_exit) { 8762b7d9b21SSteven Rostedt return 0 if $in_bisect; 8772b7d9b21SSteven Rostedt fail "test failed" and return 0; 8785a391fbfSSteven Rostedt } 8792b7d9b21SSteven Rostedt return 1; 8805a391fbfSSteven Rostedt} 8815a391fbfSSteven Rostedt 882a75fececSSteven Rostedtsub run_git_bisect { 883a75fececSSteven Rostedt my ($command) = @_; 884a75fececSSteven Rostedt 885a75fececSSteven Rostedt doprint "$command ... "; 886a75fececSSteven Rostedt 887a75fececSSteven Rostedt my $output = `$command 2>&1`; 888a75fececSSteven Rostedt my $ret = $?; 889a75fececSSteven Rostedt 890a75fececSSteven Rostedt logit $output; 891a75fececSSteven Rostedt 892a75fececSSteven Rostedt if ($ret) { 893a75fececSSteven Rostedt doprint "FAILED\n"; 894a75fececSSteven Rostedt dodie "Failed to git bisect"; 895a75fececSSteven Rostedt } 896a75fececSSteven Rostedt 897a75fececSSteven Rostedt doprint "SUCCESS\n"; 898a75fececSSteven Rostedt if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) { 899a75fececSSteven Rostedt doprint "$1 [$2]\n"; 900a75fececSSteven Rostedt } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) { 901a75fececSSteven Rostedt $bisect_bad = $1; 902a75fececSSteven Rostedt doprint "Found bad commit... $1\n"; 903a75fececSSteven Rostedt return 0; 904a75fececSSteven Rostedt } else { 905a75fececSSteven Rostedt # we already logged it, just print it now. 906a75fececSSteven Rostedt print $output; 907a75fececSSteven Rostedt } 908a75fececSSteven Rostedt 909a75fececSSteven Rostedt return 1; 910a75fececSSteven Rostedt} 911a75fececSSteven Rostedt 9125f9b6cedSSteven Rostedtsub run_bisect { 9135f9b6cedSSteven Rostedt my ($type) = @_; 9145f9b6cedSSteven Rostedt 9152b7d9b21SSteven Rostedt my $failed = 0; 9165f9b6cedSSteven Rostedt my $result; 9175f9b6cedSSteven Rostedt my $output; 9185f9b6cedSSteven Rostedt my $ret; 9195f9b6cedSSteven Rostedt 9205f9b6cedSSteven Rostedt if (defined($minconfig)) { 9212b7d9b21SSteven Rostedt build "useconfig:$minconfig" or $failed = 1; 9225f9b6cedSSteven Rostedt } else { 9235f9b6cedSSteven Rostedt # ?? no config to use? 9242b7d9b21SSteven Rostedt build "oldconfig" or $failed = 1; 9255f9b6cedSSteven Rostedt } 9265f9b6cedSSteven Rostedt 9275f9b6cedSSteven Rostedt if ($type ne "build") { 9287faafbd6SSteven Rostedt dodie "Failed on build" if $failed; 9295f9b6cedSSteven Rostedt 9305f9b6cedSSteven Rostedt # Now boot the box 9315f9b6cedSSteven Rostedt get_grub_index; 9325f9b6cedSSteven Rostedt get_version; 9335f9b6cedSSteven Rostedt install; 9347faafbd6SSteven Rostedt 9357faafbd6SSteven Rostedt start_monitor; 9362b7d9b21SSteven Rostedt monitor or $failed = 1; 9375f9b6cedSSteven Rostedt 9385f9b6cedSSteven Rostedt if ($type ne "boot") { 9397faafbd6SSteven Rostedt dodie "Failed on boot" if $failed; 9405a391fbfSSteven Rostedt 9412b7d9b21SSteven Rostedt do_run_test or $failed = 1; 9425f9b6cedSSteven Rostedt } 9437faafbd6SSteven Rostedt end_monitor; 9445f9b6cedSSteven Rostedt } 9455f9b6cedSSteven Rostedt 9465f9b6cedSSteven Rostedt if ($failed) { 9475f9b6cedSSteven Rostedt $result = "bad"; 9485a391fbfSSteven Rostedt 9495a391fbfSSteven Rostedt # reboot the box to a good kernel 950a75fececSSteven Rostedt if ($type ne "build") { 951a75fececSSteven Rostedt doprint "Reboot and sleep $bisect_sleep_time seconds\n"; 9525a391fbfSSteven Rostedt reboot; 9537faafbd6SSteven Rostedt start_monitor; 954a75fececSSteven Rostedt wait_for_monitor $bisect_sleep_time; 9557faafbd6SSteven Rostedt end_monitor; 9565a391fbfSSteven Rostedt } 9575f9b6cedSSteven Rostedt } else { 9585f9b6cedSSteven Rostedt $result = "good"; 9595f9b6cedSSteven Rostedt } 9605f9b6cedSSteven Rostedt 961d6ce2a0bSSteven Rostedt # Are we looking for where it worked, not failed? 962d6ce2a0bSSteven Rostedt if ($reverse_bisect) { 963d6ce2a0bSSteven Rostedt if ($failed) { 964d6ce2a0bSSteven Rostedt $result = "good"; 965d6ce2a0bSSteven Rostedt } else { 966d6ce2a0bSSteven Rostedt $result = "bad"; 967d6ce2a0bSSteven Rostedt } 968d6ce2a0bSSteven Rostedt } 969d6ce2a0bSSteven Rostedt 970a75fececSSteven Rostedt return $result; 9715f9b6cedSSteven Rostedt} 9725f9b6cedSSteven Rostedt 9735f9b6cedSSteven Rostedtsub bisect { 9745f9b6cedSSteven Rostedt my ($i) = @_; 9755f9b6cedSSteven Rostedt 9765f9b6cedSSteven Rostedt my $result; 9775f9b6cedSSteven Rostedt 9785f9b6cedSSteven Rostedt die "BISECT_GOOD[$i] not defined\n" if (!defined($opt{"BISECT_GOOD[$i]"})); 9795f9b6cedSSteven Rostedt die "BISECT_BAD[$i] not defined\n" if (!defined($opt{"BISECT_BAD[$i]"})); 9805f9b6cedSSteven Rostedt die "BISECT_TYPE[$i] not defined\n" if (!defined($opt{"BISECT_TYPE[$i]"})); 9815f9b6cedSSteven Rostedt 9825f9b6cedSSteven Rostedt my $good = $opt{"BISECT_GOOD[$i]"}; 9835f9b6cedSSteven Rostedt my $bad = $opt{"BISECT_BAD[$i]"}; 9845f9b6cedSSteven Rostedt my $type = $opt{"BISECT_TYPE[$i]"}; 985a75fececSSteven Rostedt my $start = $opt{"BISECT_START[$i]"}; 986a75fececSSteven Rostedt my $replay = $opt{"BISECT_REPLAY[$i]"}; 9875f9b6cedSSteven Rostedt 988a57419b3SSteven Rostedt # convert to true sha1's 989a57419b3SSteven Rostedt $good = get_sha1($good); 990a57419b3SSteven Rostedt $bad = get_sha1($bad); 991a57419b3SSteven Rostedt 992d6ce2a0bSSteven Rostedt if (defined($opt{"BISECT_REVERSE[$i]"}) && 993d6ce2a0bSSteven Rostedt $opt{"BISECT_REVERSE[$i]"} == 1) { 994d6ce2a0bSSteven Rostedt doprint "Performing a reverse bisect (bad is good, good is bad!)\n"; 995d6ce2a0bSSteven Rostedt $reverse_bisect = 1; 996d6ce2a0bSSteven Rostedt } else { 997d6ce2a0bSSteven Rostedt $reverse_bisect = 0; 998d6ce2a0bSSteven Rostedt } 999d6ce2a0bSSteven Rostedt 10005f9b6cedSSteven Rostedt $in_bisect = 1; 10015f9b6cedSSteven Rostedt 10025a391fbfSSteven Rostedt # Can't have a test without having a test to run 10035a391fbfSSteven Rostedt if ($type eq "test" && !defined($run_test)) { 10045a391fbfSSteven Rostedt $type = "boot"; 10055a391fbfSSteven Rostedt } 10065a391fbfSSteven Rostedt 1007a75fececSSteven Rostedt my $check = $opt{"BISECT_CHECK[$i]"}; 1008a75fececSSteven Rostedt if (defined($check) && $check ne "0") { 1009a75fececSSteven Rostedt 1010a75fececSSteven Rostedt # get current HEAD 1011a57419b3SSteven Rostedt my $head = get_sha1("HEAD"); 1012a75fececSSteven Rostedt 1013a75fececSSteven Rostedt if ($check ne "good") { 1014a75fececSSteven Rostedt doprint "TESTING BISECT BAD [$bad]\n"; 1015a75fececSSteven Rostedt run_command "git checkout $bad" or 1016a75fececSSteven Rostedt die "Failed to checkout $bad"; 1017a75fececSSteven Rostedt 1018a75fececSSteven Rostedt $result = run_bisect $type; 1019a75fececSSteven Rostedt 1020a75fececSSteven Rostedt if ($result ne "bad") { 1021a75fececSSteven Rostedt fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0; 1022a75fececSSteven Rostedt } 1023a75fececSSteven Rostedt } 1024a75fececSSteven Rostedt 1025a75fececSSteven Rostedt if ($check ne "bad") { 1026a75fececSSteven Rostedt doprint "TESTING BISECT GOOD [$good]\n"; 1027a75fececSSteven Rostedt run_command "git checkout $good" or 1028a75fececSSteven Rostedt die "Failed to checkout $good"; 1029a75fececSSteven Rostedt 1030a75fececSSteven Rostedt $result = run_bisect $type; 1031a75fececSSteven Rostedt 1032a75fececSSteven Rostedt if ($result ne "good") { 1033a75fececSSteven Rostedt fail "Tested BISECT_GOOD [$good] and it failed" and return 0; 1034a75fececSSteven Rostedt } 1035a75fececSSteven Rostedt } 1036a75fececSSteven Rostedt 1037a75fececSSteven Rostedt # checkout where we started 1038a75fececSSteven Rostedt run_command "git checkout $head" or 1039a75fececSSteven Rostedt die "Failed to checkout $head"; 1040a75fececSSteven Rostedt } 1041a75fececSSteven Rostedt 1042a75fececSSteven Rostedt run_command "git bisect start" or 1043a75fececSSteven Rostedt dodie "could not start bisect"; 1044a75fececSSteven Rostedt 1045a75fececSSteven Rostedt run_command "git bisect good $good" or 1046a75fececSSteven Rostedt dodie "could not set bisect good to $good"; 1047a75fececSSteven Rostedt 1048a75fececSSteven Rostedt run_git_bisect "git bisect bad $bad" or 1049a75fececSSteven Rostedt dodie "could not set bisect bad to $bad"; 1050a75fececSSteven Rostedt 1051a75fececSSteven Rostedt if (defined($replay)) { 1052a75fececSSteven Rostedt run_command "git bisect replay $replay" or 1053a75fececSSteven Rostedt dodie "failed to run replay"; 1054a75fececSSteven Rostedt } 1055a75fececSSteven Rostedt 1056a75fececSSteven Rostedt if (defined($start)) { 1057a75fececSSteven Rostedt run_command "git checkout $start" or 1058a75fececSSteven Rostedt dodie "failed to checkout $start"; 1059a75fececSSteven Rostedt } 1060a75fececSSteven Rostedt 1061a75fececSSteven Rostedt my $test; 10625f9b6cedSSteven Rostedt do { 10635f9b6cedSSteven Rostedt $result = run_bisect $type; 1064a75fececSSteven Rostedt $test = run_git_bisect "git bisect $result"; 1065a75fececSSteven Rostedt } while ($test); 10665f9b6cedSSteven Rostedt 10675f9b6cedSSteven Rostedt run_command "git bisect log" or 10685f9b6cedSSteven Rostedt dodie "could not capture git bisect log"; 10695f9b6cedSSteven Rostedt 10705f9b6cedSSteven Rostedt run_command "git bisect reset" or 10715f9b6cedSSteven Rostedt dodie "could not reset git bisect"; 10725f9b6cedSSteven Rostedt 10735f9b6cedSSteven Rostedt doprint "Bad commit was [$bisect_bad]\n"; 10745f9b6cedSSteven Rostedt 10755f9b6cedSSteven Rostedt $in_bisect = 0; 10765f9b6cedSSteven Rostedt 10775f9b6cedSSteven Rostedt success $i; 10785f9b6cedSSteven Rostedt} 10795f9b6cedSSteven Rostedt 10806c5ee0beSSteven Rostedtsub patchcheck { 10816c5ee0beSSteven Rostedt my ($i) = @_; 10826c5ee0beSSteven Rostedt 10836c5ee0beSSteven Rostedt die "PATCHCHECK_START[$i] not defined\n" 10846c5ee0beSSteven Rostedt if (!defined($opt{"PATCHCHECK_START[$i]"})); 10856c5ee0beSSteven Rostedt die "PATCHCHECK_TYPE[$i] not defined\n" 10866c5ee0beSSteven Rostedt if (!defined($opt{"PATCHCHECK_TYPE[$i]"})); 10876c5ee0beSSteven Rostedt 10886c5ee0beSSteven Rostedt my $start = $opt{"PATCHCHECK_START[$i]"}; 10896c5ee0beSSteven Rostedt 10906c5ee0beSSteven Rostedt my $end = "HEAD"; 10916c5ee0beSSteven Rostedt if (defined($opt{"PATCHCHECK_END[$i]"})) { 10926c5ee0beSSteven Rostedt $end = $opt{"PATCHCHECK_END[$i]"}; 10936c5ee0beSSteven Rostedt } 10946c5ee0beSSteven Rostedt 1095a57419b3SSteven Rostedt # Get the true sha1's since we can use things like HEAD~3 1096a57419b3SSteven Rostedt $start = get_sha1($start); 1097a57419b3SSteven Rostedt $end = get_sha1($end); 1098a57419b3SSteven Rostedt 10996c5ee0beSSteven Rostedt my $type = $opt{"PATCHCHECK_TYPE[$i]"}; 11006c5ee0beSSteven Rostedt 11016c5ee0beSSteven Rostedt # Can't have a test without having a test to run 11026c5ee0beSSteven Rostedt if ($type eq "test" && !defined($run_test)) { 11036c5ee0beSSteven Rostedt $type = "boot"; 11046c5ee0beSSteven Rostedt } 11056c5ee0beSSteven Rostedt 11066c5ee0beSSteven Rostedt open (IN, "git log --pretty=oneline $end|") or 11076c5ee0beSSteven Rostedt dodie "could not get git list"; 11086c5ee0beSSteven Rostedt 11096c5ee0beSSteven Rostedt my @list; 11106c5ee0beSSteven Rostedt 11116c5ee0beSSteven Rostedt while (<IN>) { 11126c5ee0beSSteven Rostedt chomp; 11136c5ee0beSSteven Rostedt $list[$#list+1] = $_; 11146c5ee0beSSteven Rostedt last if (/^$start/); 11156c5ee0beSSteven Rostedt } 11166c5ee0beSSteven Rostedt close(IN); 11176c5ee0beSSteven Rostedt 11186c5ee0beSSteven Rostedt if ($list[$#list] !~ /^$start/) { 11192b7d9b21SSteven Rostedt fail "SHA1 $start not found"; 11206c5ee0beSSteven Rostedt } 11216c5ee0beSSteven Rostedt 11226c5ee0beSSteven Rostedt # go backwards in the list 11236c5ee0beSSteven Rostedt @list = reverse @list; 11246c5ee0beSSteven Rostedt 11256c5ee0beSSteven Rostedt my $save_clean = $noclean; 11266c5ee0beSSteven Rostedt 11276c5ee0beSSteven Rostedt $in_patchcheck = 1; 11286c5ee0beSSteven Rostedt foreach my $item (@list) { 11296c5ee0beSSteven Rostedt my $sha1 = $item; 11306c5ee0beSSteven Rostedt $sha1 =~ s/^([[:xdigit:]]+).*/$1/; 11316c5ee0beSSteven Rostedt 11326c5ee0beSSteven Rostedt doprint "\nProcessing commit $item\n\n"; 11336c5ee0beSSteven Rostedt 11346c5ee0beSSteven Rostedt run_command "git checkout $sha1" or 11356c5ee0beSSteven Rostedt die "Failed to checkout $sha1"; 11366c5ee0beSSteven Rostedt 11376c5ee0beSSteven Rostedt # only clean on the first and last patch 11386c5ee0beSSteven Rostedt if ($item eq $list[0] || 11396c5ee0beSSteven Rostedt $item eq $list[$#list]) { 11406c5ee0beSSteven Rostedt $noclean = $save_clean; 11416c5ee0beSSteven Rostedt } else { 11426c5ee0beSSteven Rostedt $noclean = 1; 11436c5ee0beSSteven Rostedt } 11446c5ee0beSSteven Rostedt 11456c5ee0beSSteven Rostedt if (defined($minconfig)) { 11462b7d9b21SSteven Rostedt build "useconfig:$minconfig" or return 0; 11476c5ee0beSSteven Rostedt } else { 11486c5ee0beSSteven Rostedt # ?? no config to use? 11492b7d9b21SSteven Rostedt build "oldconfig" or return 0; 11506c5ee0beSSteven Rostedt } 11516c5ee0beSSteven Rostedt 11522b7d9b21SSteven Rostedt check_buildlog $sha1 or return 0; 11536c5ee0beSSteven Rostedt 11546c5ee0beSSteven Rostedt next if ($type eq "build"); 11556c5ee0beSSteven Rostedt 11566c5ee0beSSteven Rostedt get_grub_index; 11576c5ee0beSSteven Rostedt get_version; 11586c5ee0beSSteven Rostedt install; 11596c5ee0beSSteven Rostedt 11607faafbd6SSteven Rostedt my $failed = 0; 11617faafbd6SSteven Rostedt 11627faafbd6SSteven Rostedt start_monitor; 11637faafbd6SSteven Rostedt monitor or $failed = 1; 11647faafbd6SSteven Rostedt 11657faafbd6SSteven Rostedt if (!$failed && $type ne "boot"){ 11667faafbd6SSteven Rostedt do_run_test or $failed = 1; 11677faafbd6SSteven Rostedt } 11687faafbd6SSteven Rostedt end_monitor; 11697faafbd6SSteven Rostedt return 0 if ($failed); 11707faafbd6SSteven Rostedt 11716c5ee0beSSteven Rostedt } 11726c5ee0beSSteven Rostedt $in_patchcheck = 0; 11736c5ee0beSSteven Rostedt success $i; 11742b7d9b21SSteven Rostedt 11752b7d9b21SSteven Rostedt return 1; 11766c5ee0beSSteven Rostedt} 11776c5ee0beSSteven Rostedt 11782545eb61SSteven Rostedtread_config $ARGV[0]; 11792545eb61SSteven Rostedt 11802545eb61SSteven Rostedt# mandatory configs 11812545eb61SSteven Rostedtdie "MACHINE not defined\n" if (!defined($opt{"MACHINE"})); 11822545eb61SSteven Rostedtdie "SSH_USER not defined\n" if (!defined($opt{"SSH_USER"})); 11832545eb61SSteven Rostedtdie "BUILD_DIR not defined\n" if (!defined($opt{"BUILD_DIR"})); 11842545eb61SSteven Rostedtdie "OUTPUT_DIR not defined\n" if (!defined($opt{"OUTPUT_DIR"})); 11852545eb61SSteven Rostedtdie "BUILD_TARGET not defined\n" if (!defined($opt{"BUILD_TARGET"})); 118675c3fda7SSteven Rostedtdie "TARGET_IMAGE not defined\n" if (!defined($opt{"TARGET_IMAGE"})); 11872545eb61SSteven Rostedtdie "POWER_CYCLE not defined\n" if (!defined($opt{"POWER_CYCLE"})); 11882545eb61SSteven Rostedtdie "CONSOLE not defined\n" if (!defined($opt{"CONSOLE"})); 11892545eb61SSteven Rostedtdie "LOCALVERSION not defined\n" if (!defined($opt{"LOCALVERSION"})); 11902545eb61SSteven Rostedt 11912b7d9b21SSteven Rostedtif ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) { 11922b7d9b21SSteven Rostedt unlink $opt{"LOG_FILE"}; 11932b7d9b21SSteven Rostedt} 11942545eb61SSteven Rostedt 11952b7d9b21SSteven Rostedtdoprint "\n\nSTARTING AUTOMATED TESTS\n\n"; 11962b7d9b21SSteven Rostedt 1197a57419b3SSteven Rostedtfor (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) { 1198a57419b3SSteven Rostedt 1199a57419b3SSteven Rostedt if (!$i) { 1200a57419b3SSteven Rostedt doprint "DEFAULT OPTIONS:\n"; 1201a57419b3SSteven Rostedt } else { 1202a57419b3SSteven Rostedt doprint "\nTEST $i OPTIONS"; 1203a57419b3SSteven Rostedt if (defined($repeat_tests{$i})) { 1204a57419b3SSteven Rostedt $repeat = $repeat_tests{$i}; 1205a57419b3SSteven Rostedt doprint " ITERATE $repeat"; 1206a57419b3SSteven Rostedt } 1207a57419b3SSteven Rostedt doprint "\n"; 1208a57419b3SSteven Rostedt } 1209a57419b3SSteven Rostedt 12102b7d9b21SSteven Rostedt foreach my $option (sort keys %opt) { 1211a57419b3SSteven Rostedt 1212a57419b3SSteven Rostedt if ($option =~ /\[(\d+)\]$/) { 1213a57419b3SSteven Rostedt next if ($i != $1); 1214a57419b3SSteven Rostedt } else { 1215a57419b3SSteven Rostedt next if ($i); 1216a57419b3SSteven Rostedt } 1217a57419b3SSteven Rostedt 12182b7d9b21SSteven Rostedt doprint "$option = $opt{$option}\n"; 12192b7d9b21SSteven Rostedt } 1220a57419b3SSteven Rostedt} 12212545eb61SSteven Rostedt 1222a75fececSSteven Rostedtsub set_test_option { 12235a391fbfSSteven Rostedt my ($name, $i) = @_; 12245a391fbfSSteven Rostedt 12255a391fbfSSteven Rostedt my $option = "$name\[$i\]"; 12265a391fbfSSteven Rostedt 12275a391fbfSSteven Rostedt if (defined($opt{$option})) { 12285a391fbfSSteven Rostedt return $opt{$option}; 12295a391fbfSSteven Rostedt } 12305a391fbfSSteven Rostedt 1231a57419b3SSteven Rostedt foreach my $test (keys %repeat_tests) { 1232a57419b3SSteven Rostedt if ($i >= $test && 1233a57419b3SSteven Rostedt $i < $test + $repeat_tests{$test}) { 1234a57419b3SSteven Rostedt $option = "$name\[$test\]"; 1235a57419b3SSteven Rostedt if (defined($opt{$option})) { 1236a57419b3SSteven Rostedt return $opt{$option}; 1237a57419b3SSteven Rostedt } 1238a57419b3SSteven Rostedt } 1239a57419b3SSteven Rostedt } 1240a57419b3SSteven Rostedt 12415a391fbfSSteven Rostedt if (defined($opt{$name})) { 12425a391fbfSSteven Rostedt return $opt{$name}; 12435a391fbfSSteven Rostedt } 12445a391fbfSSteven Rostedt 12455a391fbfSSteven Rostedt return undef; 12465a391fbfSSteven Rostedt} 12475a391fbfSSteven Rostedt 12482545eb61SSteven Rostedt# First we need to do is the builds 1249a75fececSSteven Rostedtfor (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) { 12502545eb61SSteven Rostedt 1251576f627cSSteven Rostedt $iteration = $i; 1252576f627cSSteven Rostedt 1253a75fececSSteven Rostedt my $ssh_user = set_test_option("SSH_USER", $i); 1254a75fececSSteven Rostedt my $makecmd = set_test_option("MAKE_CMD", $i); 1255a75fececSSteven Rostedt 1256a75fececSSteven Rostedt $machine = set_test_option("MACHINE", $i); 1257a75fececSSteven Rostedt $tmpdir = set_test_option("TMP_DIR", $i); 1258a75fececSSteven Rostedt $outputdir = set_test_option("OUTPUT_DIR", $i); 1259a75fececSSteven Rostedt $builddir = set_test_option("BUILD_DIR", $i); 1260a75fececSSteven Rostedt $test_type = set_test_option("TEST_TYPE", $i); 1261a75fececSSteven Rostedt $build_type = set_test_option("BUILD_TYPE", $i); 1262a75fececSSteven Rostedt $build_options = set_test_option("BUILD_OPTIONS", $i); 1263a75fececSSteven Rostedt $power_cycle = set_test_option("POWER_CYCLE", $i); 1264a75fececSSteven Rostedt $noclean = set_test_option("BUILD_NOCLEAN", $i); 1265a75fececSSteven Rostedt $minconfig = set_test_option("MIN_CONFIG", $i); 1266a75fececSSteven Rostedt $run_test = set_test_option("TEST", $i); 1267a75fececSSteven Rostedt $addconfig = set_test_option("ADD_CONFIG", $i); 1268a75fececSSteven Rostedt $reboot_type = set_test_option("REBOOT_TYPE", $i); 1269a75fececSSteven Rostedt $grub_menu = set_test_option("GRUB_MENU", $i); 12708b37ca8cSSteven Rostedt $post_install = set_test_option("POST_INSTALL", $i); 1271a75fececSSteven Rostedt $reboot_script = set_test_option("REBOOT_SCRIPT", $i); 1272a75fececSSteven Rostedt $reboot_on_error = set_test_option("REBOOT_ON_ERROR", $i); 1273a75fececSSteven Rostedt $poweroff_on_error = set_test_option("POWEROFF_ON_ERROR", $i); 1274a75fececSSteven Rostedt $die_on_failure = set_test_option("DIE_ON_FAILURE", $i); 1275a75fececSSteven Rostedt $power_off = set_test_option("POWER_OFF", $i); 1276576f627cSSteven Rostedt $powercycle_after_reboot = set_test_option("POWERCYCLE_AFTER_REBOOT", $i); 1277576f627cSSteven Rostedt $poweroff_after_halt = set_test_option("POWEROFF_AFTER_HALT", $i); 1278a75fececSSteven Rostedt $sleep_time = set_test_option("SLEEP_TIME", $i); 1279a75fececSSteven Rostedt $bisect_sleep_time = set_test_option("BISECT_SLEEP_TIME", $i); 1280a75fececSSteven Rostedt $store_failures = set_test_option("STORE_FAILURES", $i); 1281a75fececSSteven Rostedt $timeout = set_test_option("TIMEOUT", $i); 1282a75fececSSteven Rostedt $booted_timeout = set_test_option("BOOTED_TIMEOUT", $i); 1283a75fececSSteven Rostedt $console = set_test_option("CONSOLE", $i); 1284a75fececSSteven Rostedt $success_line = set_test_option("SUCCESS_LINE", $i); 1285a75fececSSteven Rostedt $build_target = set_test_option("BUILD_TARGET", $i); 1286a75fececSSteven Rostedt $target_image = set_test_option("TARGET_IMAGE", $i); 1287a75fececSSteven Rostedt $localversion = set_test_option("LOCALVERSION", $i); 1288a75fececSSteven Rostedt 1289a75fececSSteven Rostedt chdir $builddir || die "can't change directory to $builddir"; 1290a75fececSSteven Rostedt 1291a75fececSSteven Rostedt if (!-d $tmpdir) { 1292a75fececSSteven Rostedt mkpath($tmpdir) or 1293a75fececSSteven Rostedt die "can't create $tmpdir"; 1294a75fececSSteven Rostedt } 1295a75fececSSteven Rostedt 1296a75fececSSteven Rostedt $target = "$ssh_user\@$machine"; 1297a75fececSSteven Rostedt 1298a75fececSSteven Rostedt $buildlog = "$tmpdir/buildlog-$machine"; 1299a75fececSSteven Rostedt $dmesg = "$tmpdir/dmesg-$machine"; 1300a75fececSSteven Rostedt $make = "$makecmd O=$outputdir"; 130151ad1dd1SSteven Rostedt $output_config = "$outputdir/.config"; 1302a75fececSSteven Rostedt 1303a75fececSSteven Rostedt if ($reboot_type eq "grub") { 1304576f627cSSteven Rostedt dodie "GRUB_MENU not defined" if (!defined($grub_menu)); 1305a75fececSSteven Rostedt } elsif (!defined($reboot_script)) { 1306576f627cSSteven Rostedt dodie "REBOOT_SCRIPT not defined" 1307a75fececSSteven Rostedt } 1308a75fececSSteven Rostedt 1309a75fececSSteven Rostedt my $run_type = $build_type; 1310a75fececSSteven Rostedt if ($test_type eq "patchcheck") { 1311a75fececSSteven Rostedt $run_type = $opt{"PATCHCHECK_TYPE[$i]"}; 1312a75fececSSteven Rostedt } elsif ($test_type eq "bisect") { 1313a75fececSSteven Rostedt $run_type = $opt{"BISECT_TYPE[$i]"}; 1314a75fececSSteven Rostedt } 1315a75fececSSteven Rostedt 1316a75fececSSteven Rostedt # mistake in config file? 1317a75fececSSteven Rostedt if (!defined($run_type)) { 1318a75fececSSteven Rostedt $run_type = "ERROR"; 1319a75fececSSteven Rostedt } 13202545eb61SSteven Rostedt 13212545eb61SSteven Rostedt doprint "\n\n"; 1322a75fececSSteven Rostedt doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type\n\n"; 13237faafbd6SSteven Rostedt 13247faafbd6SSteven Rostedt unlink $dmesg; 13257faafbd6SSteven Rostedt unlink $buildlog; 13262545eb61SSteven Rostedt 13272b7d9b21SSteven Rostedt if (!defined($minconfig)) { 13282b7d9b21SSteven Rostedt $minconfig = $addconfig; 13292b7d9b21SSteven Rostedt 13302b7d9b21SSteven Rostedt } elsif (defined($addconfig)) { 1331a75fececSSteven Rostedt run_command "cat $addconfig $minconfig > $tmpdir/use_config" or 13322b7d9b21SSteven Rostedt dodie "Failed to create temp config"; 1333a75fececSSteven Rostedt $minconfig = "$tmpdir/use_config"; 13342b7d9b21SSteven Rostedt } 13352b7d9b21SSteven Rostedt 13366c5ee0beSSteven Rostedt my $checkout = $opt{"CHECKOUT[$i]"}; 13376c5ee0beSSteven Rostedt if (defined($checkout)) { 13386c5ee0beSSteven Rostedt run_command "git checkout $checkout" or 13396c5ee0beSSteven Rostedt die "failed to checkout $checkout"; 13406c5ee0beSSteven Rostedt } 13416c5ee0beSSteven Rostedt 1342a75fececSSteven Rostedt if ($test_type eq "bisect") { 13435f9b6cedSSteven Rostedt bisect $i; 13445f9b6cedSSteven Rostedt next; 1345a75fececSSteven Rostedt } elsif ($test_type eq "patchcheck") { 13466c5ee0beSSteven Rostedt patchcheck $i; 13476c5ee0beSSteven Rostedt next; 13485f9b6cedSSteven Rostedt } 13495f9b6cedSSteven Rostedt 13507faafbd6SSteven Rostedt if ($build_type ne "nobuild") { 13517faafbd6SSteven Rostedt build $build_type or next; 13522545eb61SSteven Rostedt } 13532545eb61SSteven Rostedt 1354a75fececSSteven Rostedt if ($test_type ne "build") { 13555f9b6cedSSteven Rostedt get_grub_index; 13565f9b6cedSSteven Rostedt get_version; 13572545eb61SSteven Rostedt install; 13585a391fbfSSteven Rostedt 13597faafbd6SSteven Rostedt my $failed = 0; 13607faafbd6SSteven Rostedt start_monitor; 13617faafbd6SSteven Rostedt monitor or $failed = 1;; 1362a75fececSSteven Rostedt 1363a75fececSSteven Rostedt if (!$failed && $test_type ne "boot" && defined($run_test)) { 13647faafbd6SSteven Rostedt do_run_test or $failed = 1; 13655a391fbfSSteven Rostedt } 13667faafbd6SSteven Rostedt end_monitor; 13677faafbd6SSteven Rostedt next if ($failed); 1368a75fececSSteven Rostedt } 13695a391fbfSSteven Rostedt 13705f9b6cedSSteven Rostedt success $i; 137175c3fda7SSteven Rostedt} 13722545eb61SSteven Rostedt 13735c42fc5bSSteven Rostedtif ($opt{"POWEROFF_ON_SUCCESS"}) { 137475c3fda7SSteven Rostedt halt; 1375576f627cSSteven Rostedt} elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot) { 137675c3fda7SSteven Rostedt reboot; 13775c42fc5bSSteven Rostedt} 137875c3fda7SSteven Rostedt 13792545eb61SSteven Rostedtexit 0; 1380