12545eb61SSteven Rostedt#!/usr/bin/perl -w 2d6ce2a0bSSteven Rostedt# 3d6ce2a0bSSteven Rostedt# Copywrite 2010 - Steven Rostedt <srostedt@redhat.com>, Red Hat Inc. 4d6ce2a0bSSteven Rostedt# Licensed under the terms of the GNU GPL License version 2 5d6ce2a0bSSteven Rostedt# 62545eb61SSteven Rostedt 72545eb61SSteven Rostedtuse strict; 82545eb61SSteven Rostedtuse IPC::Open2; 92545eb61SSteven Rostedtuse Fcntl qw(F_GETFL F_SETFL O_NONBLOCK); 107faafbd6SSteven Rostedtuse File::Path qw(mkpath); 117faafbd6SSteven Rostedtuse File::Copy qw(cp); 122545eb61SSteven Rostedtuse FileHandle; 132545eb61SSteven Rostedt 14e48c5293SSteven Rostedtmy $VERSION = "0.2"; 15e48c5293SSteven Rostedt 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; 43e48c5293SSteven Rostedt$default{"SSH_EXEC"} = "ssh \$SSH_USER\@\$MACHINE \$SSH_COMMAND"; 44e48c5293SSteven Rostedt$default{"SCP_TO_TARGET"} = "scp \$SRC_FILE \$SSH_USER\@\$MACHINE:\$DST_FILE"; 45e48c5293SSteven Rostedt$default{"REBOOT"} = "ssh \$SSH_USER\@\$MACHINE reboot"; 461c8a617aSSteven Rostedt$default{"STOP_AFTER_SUCCESS"} = 10; 471c8a617aSSteven Rostedt$default{"STOP_AFTER_FAILURE"} = 60; 48*8d1491baSSteven Rostedt$default{"LOCALVERSION"} = "-test"; 492545eb61SSteven Rostedt 50*8d1491baSSteven Rostedtmy $ktest_config; 512545eb61SSteven Rostedtmy $version; 52a75fececSSteven Rostedtmy $machine; 53e48c5293SSteven Rostedtmy $ssh_user; 54a75fececSSteven Rostedtmy $tmpdir; 55a75fececSSteven Rostedtmy $builddir; 56a75fececSSteven Rostedtmy $outputdir; 5751ad1dd1SSteven Rostedtmy $output_config; 58a75fececSSteven Rostedtmy $test_type; 597faafbd6SSteven Rostedtmy $build_type; 60a75fececSSteven Rostedtmy $build_options; 61a75fececSSteven Rostedtmy $reboot_type; 62a75fececSSteven Rostedtmy $reboot_script; 63a75fececSSteven Rostedtmy $power_cycle; 64e48c5293SSteven Rostedtmy $reboot; 65a75fececSSteven Rostedtmy $reboot_on_error; 66a75fececSSteven Rostedtmy $poweroff_on_error; 67a75fececSSteven Rostedtmy $die_on_failure; 68576f627cSSteven Rostedtmy $powercycle_after_reboot; 69576f627cSSteven Rostedtmy $poweroff_after_halt; 70e48c5293SSteven Rostedtmy $ssh_exec; 71e48c5293SSteven Rostedtmy $scp_to_target; 72a75fececSSteven Rostedtmy $power_off; 73a75fececSSteven Rostedtmy $grub_menu; 742545eb61SSteven Rostedtmy $grub_number; 752545eb61SSteven Rostedtmy $target; 762545eb61SSteven Rostedtmy $make; 778b37ca8cSSteven Rostedtmy $post_install; 785c42fc5bSSteven Rostedtmy $noclean; 795f9b6cedSSteven Rostedtmy $minconfig; 802b7d9b21SSteven Rostedtmy $addconfig; 815f9b6cedSSteven Rostedtmy $in_bisect = 0; 825f9b6cedSSteven Rostedtmy $bisect_bad = ""; 83d6ce2a0bSSteven Rostedtmy $reverse_bisect; 846c5ee0beSSteven Rostedtmy $in_patchcheck = 0; 855a391fbfSSteven Rostedtmy $run_test; 866c5ee0beSSteven Rostedtmy $redirect; 877faafbd6SSteven Rostedtmy $buildlog; 887faafbd6SSteven Rostedtmy $dmesg; 897faafbd6SSteven Rostedtmy $monitor_fp; 907faafbd6SSteven Rostedtmy $monitor_pid; 917faafbd6SSteven Rostedtmy $monitor_cnt = 0; 92a75fececSSteven Rostedtmy $sleep_time; 93a75fececSSteven Rostedtmy $bisect_sleep_time; 94a75fececSSteven Rostedtmy $store_failures; 95a75fececSSteven Rostedtmy $timeout; 96a75fececSSteven Rostedtmy $booted_timeout; 97a75fececSSteven Rostedtmy $console; 98a75fececSSteven Rostedtmy $success_line; 991c8a617aSSteven Rostedtmy $stop_after_success; 1001c8a617aSSteven Rostedtmy $stop_after_failure; 101a75fececSSteven Rostedtmy $build_target; 102a75fececSSteven Rostedtmy $target_image; 103a75fececSSteven Rostedtmy $localversion; 104576f627cSSteven Rostedtmy $iteration = 0; 105e48c5293SSteven Rostedtmy $successes = 0; 1062545eb61SSteven Rostedt 107*8d1491baSSteven Rostedtmy %entered_configs; 108*8d1491baSSteven Rostedtmy %config_help; 109*8d1491baSSteven Rostedt 110*8d1491baSSteven Rostedt$config_help{"MACHINE"} = << "EOF" 111*8d1491baSSteven Rostedt The machine hostname that you will test. 112*8d1491baSSteven RostedtEOF 113*8d1491baSSteven Rostedt ; 114*8d1491baSSteven Rostedt$config_help{"SSH_USER"} = << "EOF" 115*8d1491baSSteven Rostedt The box is expected to have ssh on normal bootup, provide the user 116*8d1491baSSteven Rostedt (most likely root, since you need privileged operations) 117*8d1491baSSteven RostedtEOF 118*8d1491baSSteven Rostedt ; 119*8d1491baSSteven Rostedt$config_help{"BUILD_DIR"} = << "EOF" 120*8d1491baSSteven Rostedt The directory that contains the Linux source code (full path). 121*8d1491baSSteven RostedtEOF 122*8d1491baSSteven Rostedt ; 123*8d1491baSSteven Rostedt$config_help{"OUTPUT_DIR"} = << "EOF" 124*8d1491baSSteven Rostedt The directory that the objects will be built (full path). 125*8d1491baSSteven Rostedt (can not be same as BUILD_DIR) 126*8d1491baSSteven RostedtEOF 127*8d1491baSSteven Rostedt ; 128*8d1491baSSteven Rostedt$config_help{"BUILD_TARGET"} = << "EOF" 129*8d1491baSSteven Rostedt The location of the compiled file to copy to the target. 130*8d1491baSSteven Rostedt (relative to OUTPUT_DIR) 131*8d1491baSSteven RostedtEOF 132*8d1491baSSteven Rostedt ; 133*8d1491baSSteven Rostedt$config_help{"TARGET_IMAGE"} = << "EOF" 134*8d1491baSSteven Rostedt The place to put your image on the test machine. 135*8d1491baSSteven RostedtEOF 136*8d1491baSSteven Rostedt ; 137*8d1491baSSteven Rostedt$config_help{"POWER_CYCLE"} = << "EOF" 138*8d1491baSSteven Rostedt A script or command to reboot the box. 139*8d1491baSSteven Rostedt 140*8d1491baSSteven Rostedt Here is a digital loggers power switch example 141*8d1491baSSteven Rostedt POWER_CYCLE = wget --no-proxy -O /dev/null -q --auth-no-challenge 'http://admin:admin\@power/outlet?5=CCL' 142*8d1491baSSteven Rostedt 143*8d1491baSSteven Rostedt Here is an example to reboot a virtual box on the current host 144*8d1491baSSteven Rostedt with the name "Guest". 145*8d1491baSSteven Rostedt POWER_CYCLE = virsh destroy Guest; sleep 5; virsh start Guest 146*8d1491baSSteven RostedtEOF 147*8d1491baSSteven Rostedt ; 148*8d1491baSSteven Rostedt$config_help{"CONSOLE"} = << "EOF" 149*8d1491baSSteven Rostedt The script or command that reads the console 150*8d1491baSSteven Rostedt 151*8d1491baSSteven Rostedt If you use ttywatch server, something like the following would work. 152*8d1491baSSteven RostedtCONSOLE = nc -d localhost 3001 153*8d1491baSSteven Rostedt 154*8d1491baSSteven Rostedt For a virtual machine with guest name "Guest". 155*8d1491baSSteven RostedtCONSOLE = virsh console Guest 156*8d1491baSSteven RostedtEOF 157*8d1491baSSteven Rostedt ; 158*8d1491baSSteven Rostedt$config_help{"LOCALVERSION"} = << "EOF" 159*8d1491baSSteven Rostedt Required version ending to differentiate the test 160*8d1491baSSteven Rostedt from other linux builds on the system. 161*8d1491baSSteven RostedtEOF 162*8d1491baSSteven Rostedt ; 163*8d1491baSSteven Rostedt$config_help{"REBOOT_TYPE"} = << "EOF" 164*8d1491baSSteven Rostedt Way to reboot the box to the test kernel. 165*8d1491baSSteven Rostedt Only valid options so far are "grub" and "script". 166*8d1491baSSteven Rostedt 167*8d1491baSSteven Rostedt If you specify grub, it will assume grub version 1 168*8d1491baSSteven Rostedt and will search in /boot/grub/menu.lst for the title \$GRUB_MENU 169*8d1491baSSteven Rostedt and select that target to reboot to the kernel. If this is not 170*8d1491baSSteven Rostedt your setup, then specify "script" and have a command or script 171*8d1491baSSteven Rostedt specified in REBOOT_SCRIPT to boot to the target. 172*8d1491baSSteven Rostedt 173*8d1491baSSteven Rostedt The entry in /boot/grub/menu.lst must be entered in manually. 174*8d1491baSSteven Rostedt The test will not modify that file. 175*8d1491baSSteven RostedtEOF 176*8d1491baSSteven Rostedt ; 177*8d1491baSSteven Rostedt$config_help{"GRUB_MENU"} = << "EOF" 178*8d1491baSSteven Rostedt The grub title name for the test kernel to boot 179*8d1491baSSteven Rostedt (Only mandatory if REBOOT_TYPE = grub) 180*8d1491baSSteven Rostedt 181*8d1491baSSteven Rostedt Note, ktest.pl will not update the grub menu.lst, you need to 182*8d1491baSSteven Rostedt manually add an option for the test. ktest.pl will search 183*8d1491baSSteven Rostedt the grub menu.lst for this option to find what kernel to 184*8d1491baSSteven Rostedt reboot into. 185*8d1491baSSteven Rostedt 186*8d1491baSSteven Rostedt For example, if in the /boot/grub/menu.lst the test kernel title has: 187*8d1491baSSteven Rostedt title Test Kernel 188*8d1491baSSteven Rostedt kernel vmlinuz-test 189*8d1491baSSteven Rostedt GRUB_MENU = Test Kernel 190*8d1491baSSteven RostedtEOF 191*8d1491baSSteven Rostedt ; 192*8d1491baSSteven Rostedt$config_help{"REBOOT_SCRIPT"} = << "EOF" 193*8d1491baSSteven Rostedt A script to reboot the target into the test kernel 194*8d1491baSSteven Rostedt (Only mandatory if REBOOT_TYPE = script) 195*8d1491baSSteven RostedtEOF 196*8d1491baSSteven Rostedt ; 197*8d1491baSSteven Rostedt 198*8d1491baSSteven Rostedt 199*8d1491baSSteven Rostedtsub get_ktest_config { 200*8d1491baSSteven Rostedt my ($config) = @_; 201*8d1491baSSteven Rostedt 202*8d1491baSSteven Rostedt return if (defined($opt{$config})); 203*8d1491baSSteven Rostedt 204*8d1491baSSteven Rostedt if (defined($config_help{$config})) { 205*8d1491baSSteven Rostedt print "\n"; 206*8d1491baSSteven Rostedt print $config_help{$config}; 207*8d1491baSSteven Rostedt } 208*8d1491baSSteven Rostedt 209*8d1491baSSteven Rostedt for (;;) { 210*8d1491baSSteven Rostedt print "$config = "; 211*8d1491baSSteven Rostedt if (defined($default{$config})) { 212*8d1491baSSteven Rostedt print "\[$default{$config}\] "; 213*8d1491baSSteven Rostedt } 214*8d1491baSSteven Rostedt $entered_configs{$config} = <STDIN>; 215*8d1491baSSteven Rostedt $entered_configs{$config} =~ s/^\s*(.*\S)\s*$/$1/; 216*8d1491baSSteven Rostedt if ($entered_configs{$config} =~ /^\s*$/) { 217*8d1491baSSteven Rostedt if ($default{$config}) { 218*8d1491baSSteven Rostedt $entered_configs{$config} = $default{$config}; 219*8d1491baSSteven Rostedt } else { 220*8d1491baSSteven Rostedt print "Your answer can not be blank\n"; 221*8d1491baSSteven Rostedt next; 222*8d1491baSSteven Rostedt } 223*8d1491baSSteven Rostedt } 224*8d1491baSSteven Rostedt last; 225*8d1491baSSteven Rostedt } 226*8d1491baSSteven Rostedt} 227*8d1491baSSteven Rostedt 228*8d1491baSSteven Rostedtsub get_ktest_configs { 229*8d1491baSSteven Rostedt get_ktest_config("MACHINE"); 230*8d1491baSSteven Rostedt get_ktest_config("SSH_USER"); 231*8d1491baSSteven Rostedt get_ktest_config("BUILD_DIR"); 232*8d1491baSSteven Rostedt get_ktest_config("OUTPUT_DIR"); 233*8d1491baSSteven Rostedt get_ktest_config("BUILD_TARGET"); 234*8d1491baSSteven Rostedt get_ktest_config("TARGET_IMAGE"); 235*8d1491baSSteven Rostedt get_ktest_config("POWER_CYCLE"); 236*8d1491baSSteven Rostedt get_ktest_config("CONSOLE"); 237*8d1491baSSteven Rostedt get_ktest_config("LOCALVERSION"); 238*8d1491baSSteven Rostedt 239*8d1491baSSteven Rostedt my $rtype = $opt{"REBOOT_TYPE"}; 240*8d1491baSSteven Rostedt 241*8d1491baSSteven Rostedt if (!defined($rtype)) { 242*8d1491baSSteven Rostedt if (!defined($opt{"GRUB_MENU"})) { 243*8d1491baSSteven Rostedt get_ktest_config("REBOOT_TYPE"); 244*8d1491baSSteven Rostedt $rtype = $entered_configs{"REBOOT_TYPE"}; 245*8d1491baSSteven Rostedt } else { 246*8d1491baSSteven Rostedt $rtype = "grub"; 247*8d1491baSSteven Rostedt } 248*8d1491baSSteven Rostedt } 249*8d1491baSSteven Rostedt 250*8d1491baSSteven Rostedt if ($rtype eq "grub") { 251*8d1491baSSteven Rostedt get_ktest_config("GRUB_MENU"); 252*8d1491baSSteven Rostedt } else { 253*8d1491baSSteven Rostedt get_ktest_config("REBOOT_SCRIPT"); 254*8d1491baSSteven Rostedt } 255*8d1491baSSteven Rostedt} 256*8d1491baSSteven Rostedt 257a57419b3SSteven Rostedtsub set_value { 258a57419b3SSteven Rostedt my ($lvalue, $rvalue) = @_; 2592545eb61SSteven Rostedt 260a75fececSSteven Rostedt if (defined($opt{$lvalue})) { 261a75fececSSteven Rostedt die "Error: Option $lvalue defined more than once!\n"; 262a75fececSSteven Rostedt } 26321a9679fSSteven Rostedt if ($rvalue =~ /^\s*$/) { 26421a9679fSSteven Rostedt delete $opt{$lvalue}; 26521a9679fSSteven Rostedt } else { 26621a9679fSSteven Rostedt $opt{$lvalue} = $rvalue; 26721a9679fSSteven Rostedt } 2682545eb61SSteven Rostedt} 269a57419b3SSteven Rostedt 270a57419b3SSteven Rostedtsub read_config { 271a57419b3SSteven Rostedt my ($config) = @_; 272a57419b3SSteven Rostedt 273a57419b3SSteven Rostedt open(IN, $config) || die "can't read file $config"; 274a57419b3SSteven Rostedt 275a57419b3SSteven Rostedt my $name = $config; 276a57419b3SSteven Rostedt $name =~ s,.*/(.*),$1,; 277a57419b3SSteven Rostedt 278a57419b3SSteven Rostedt my $test_num = 0; 279a57419b3SSteven Rostedt my $default = 1; 280a57419b3SSteven Rostedt my $repeat = 1; 281a57419b3SSteven Rostedt my $num_tests_set = 0; 282a57419b3SSteven Rostedt my $skip = 0; 283a57419b3SSteven Rostedt my $rest; 284a57419b3SSteven Rostedt 285a57419b3SSteven Rostedt while (<IN>) { 286a57419b3SSteven Rostedt 287a57419b3SSteven Rostedt # ignore blank lines and comments 288a57419b3SSteven Rostedt next if (/^\s*$/ || /\s*\#/); 289a57419b3SSteven Rostedt 290a57419b3SSteven Rostedt if (/^\s*TEST_START(.*)/) { 291a57419b3SSteven Rostedt 292a57419b3SSteven Rostedt $rest = $1; 293a57419b3SSteven Rostedt 294a57419b3SSteven Rostedt if ($num_tests_set) { 295a57419b3SSteven Rostedt die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n"; 296a57419b3SSteven Rostedt } 297a57419b3SSteven Rostedt 298a57419b3SSteven Rostedt my $old_test_num = $test_num; 299e48c5293SSteven Rostedt my $old_repeat = $repeat; 300a57419b3SSteven Rostedt 301a57419b3SSteven Rostedt $test_num += $repeat; 302a57419b3SSteven Rostedt $default = 0; 303a57419b3SSteven Rostedt $repeat = 1; 304a57419b3SSteven Rostedt 305a57419b3SSteven Rostedt if ($rest =~ /\s+SKIP(.*)/) { 306a57419b3SSteven Rostedt $rest = $1; 307a57419b3SSteven Rostedt $skip = 1; 308a57419b3SSteven Rostedt } else { 309a57419b3SSteven Rostedt $skip = 0; 310a57419b3SSteven Rostedt } 311a57419b3SSteven Rostedt 312a57419b3SSteven Rostedt if ($rest =~ /\s+ITERATE\s+(\d+)(.*)$/) { 313a57419b3SSteven Rostedt $repeat = $1; 314a57419b3SSteven Rostedt $rest = $2; 315a57419b3SSteven Rostedt $repeat_tests{"$test_num"} = $repeat; 316a57419b3SSteven Rostedt } 317a57419b3SSteven Rostedt 318a57419b3SSteven Rostedt if ($rest =~ /\s+SKIP(.*)/) { 319a57419b3SSteven Rostedt $rest = $1; 320a57419b3SSteven Rostedt $skip = 1; 321a57419b3SSteven Rostedt } 322a57419b3SSteven Rostedt 323a57419b3SSteven Rostedt if ($rest !~ /^\s*$/) { 324a57419b3SSteven Rostedt die "$name: $.: Gargbage found after TEST_START\n$_"; 325a57419b3SSteven Rostedt } 326a57419b3SSteven Rostedt 327a57419b3SSteven Rostedt if ($skip) { 328a57419b3SSteven Rostedt $test_num = $old_test_num; 329e48c5293SSteven Rostedt $repeat = $old_repeat; 330a57419b3SSteven Rostedt } 331a57419b3SSteven Rostedt 332a57419b3SSteven Rostedt } elsif (/^\s*DEFAULTS(.*)$/) { 333a57419b3SSteven Rostedt $default = 1; 334a57419b3SSteven Rostedt 335a57419b3SSteven Rostedt $rest = $1; 336a57419b3SSteven Rostedt 337a57419b3SSteven Rostedt if ($rest =~ /\s+SKIP(.*)/) { 338a57419b3SSteven Rostedt $rest = $1; 339a57419b3SSteven Rostedt $skip = 1; 340a57419b3SSteven Rostedt } else { 341a57419b3SSteven Rostedt $skip = 0; 342a57419b3SSteven Rostedt } 343a57419b3SSteven Rostedt 344a57419b3SSteven Rostedt if ($rest !~ /^\s*$/) { 345a57419b3SSteven Rostedt die "$name: $.: Gargbage found after DEFAULTS\n$_"; 346a57419b3SSteven Rostedt } 347a57419b3SSteven Rostedt 348a57419b3SSteven Rostedt } elsif (/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) { 349a57419b3SSteven Rostedt 350a57419b3SSteven Rostedt next if ($skip); 351a57419b3SSteven Rostedt 352a57419b3SSteven Rostedt my $lvalue = $1; 353a57419b3SSteven Rostedt my $rvalue = $2; 354a57419b3SSteven Rostedt 355a57419b3SSteven Rostedt if (!$default && 356a57419b3SSteven Rostedt ($lvalue eq "NUM_TESTS" || 357a57419b3SSteven Rostedt $lvalue eq "LOG_FILE" || 358a57419b3SSteven Rostedt $lvalue eq "CLEAR_LOG")) { 359a57419b3SSteven Rostedt die "$name: $.: $lvalue must be set in DEFAULTS section\n"; 360a57419b3SSteven Rostedt } 361a57419b3SSteven Rostedt 362a57419b3SSteven Rostedt if ($lvalue eq "NUM_TESTS") { 363a57419b3SSteven Rostedt if ($test_num) { 364a57419b3SSteven Rostedt die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n"; 365a57419b3SSteven Rostedt } 366a57419b3SSteven Rostedt if (!$default) { 367a57419b3SSteven Rostedt die "$name: $.: NUM_TESTS must be set in default section\n"; 368a57419b3SSteven Rostedt } 369a57419b3SSteven Rostedt $num_tests_set = 1; 370a57419b3SSteven Rostedt } 371a57419b3SSteven Rostedt 372a57419b3SSteven Rostedt if ($default || $lvalue =~ /\[\d+\]$/) { 373a57419b3SSteven Rostedt set_value($lvalue, $rvalue); 374a57419b3SSteven Rostedt } else { 375a57419b3SSteven Rostedt my $val = "$lvalue\[$test_num\]"; 376a57419b3SSteven Rostedt set_value($val, $rvalue); 377a57419b3SSteven Rostedt 378a57419b3SSteven Rostedt if ($repeat > 1) { 379a57419b3SSteven Rostedt $repeats{$val} = $repeat; 380a57419b3SSteven Rostedt } 381a57419b3SSteven Rostedt } 382a57419b3SSteven Rostedt } else { 383a57419b3SSteven Rostedt die "$name: $.: Garbage found in config\n$_"; 384a57419b3SSteven Rostedt } 3852545eb61SSteven Rostedt } 3862545eb61SSteven Rostedt 3872545eb61SSteven Rostedt close(IN); 388a75fececSSteven Rostedt 389a57419b3SSteven Rostedt if ($test_num) { 390a57419b3SSteven Rostedt $test_num += $repeat - 1; 391a57419b3SSteven Rostedt $opt{"NUM_TESTS"} = $test_num; 392a57419b3SSteven Rostedt } 393a57419b3SSteven Rostedt 394*8d1491baSSteven Rostedt # make sure we have all mandatory configs 395*8d1491baSSteven Rostedt get_ktest_configs; 396*8d1491baSSteven Rostedt 397a75fececSSteven Rostedt # set any defaults 398a75fececSSteven Rostedt 399a75fececSSteven Rostedt foreach my $default (keys %default) { 400a75fececSSteven Rostedt if (!defined($opt{$default})) { 401a75fececSSteven Rostedt $opt{$default} = $default{$default}; 402a75fececSSteven Rostedt } 403a75fececSSteven Rostedt } 4042545eb61SSteven Rostedt} 4052545eb61SSteven Rostedt 406d1e2f22aSSteven Rostedtsub _logit { 4072545eb61SSteven Rostedt if (defined($opt{"LOG_FILE"})) { 4082545eb61SSteven Rostedt open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}"; 4092545eb61SSteven Rostedt print OUT @_; 4102545eb61SSteven Rostedt close(OUT); 4112545eb61SSteven Rostedt } 4122545eb61SSteven Rostedt} 4132545eb61SSteven Rostedt 414d1e2f22aSSteven Rostedtsub logit { 415d1e2f22aSSteven Rostedt if (defined($opt{"LOG_FILE"})) { 416d1e2f22aSSteven Rostedt _logit @_; 417d1e2f22aSSteven Rostedt } else { 418d1e2f22aSSteven Rostedt print @_; 419d1e2f22aSSteven Rostedt } 420d1e2f22aSSteven Rostedt} 421d1e2f22aSSteven Rostedt 4225f9b6cedSSteven Rostedtsub doprint { 4235f9b6cedSSteven Rostedt print @_; 424d1e2f22aSSteven Rostedt _logit @_; 4255f9b6cedSSteven Rostedt} 4265f9b6cedSSteven Rostedt 4277faafbd6SSteven Rostedtsub run_command; 4287faafbd6SSteven Rostedt 4297faafbd6SSteven Rostedtsub reboot { 4307faafbd6SSteven Rostedt # try to reboot normally 431e48c5293SSteven Rostedt if (run_command $reboot) { 432576f627cSSteven Rostedt if (defined($powercycle_after_reboot)) { 433576f627cSSteven Rostedt sleep $powercycle_after_reboot; 434576f627cSSteven Rostedt run_command "$power_cycle"; 435576f627cSSteven Rostedt } 436576f627cSSteven Rostedt } else { 4377faafbd6SSteven Rostedt # nope? power cycle it. 438a75fececSSteven Rostedt run_command "$power_cycle"; 4397faafbd6SSteven Rostedt } 4407faafbd6SSteven Rostedt} 4417faafbd6SSteven Rostedt 442576f627cSSteven Rostedtsub do_not_reboot { 443576f627cSSteven Rostedt my $i = $iteration; 444576f627cSSteven Rostedt 445576f627cSSteven Rostedt return $test_type eq "build" || 446576f627cSSteven Rostedt ($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") || 447576f627cSSteven Rostedt ($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build"); 448576f627cSSteven Rostedt} 449576f627cSSteven Rostedt 4505c42fc5bSSteven Rostedtsub dodie { 4515a391fbfSSteven Rostedt doprint "CRITICAL FAILURE... ", @_, "\n"; 4525c42fc5bSSteven Rostedt 453576f627cSSteven Rostedt my $i = $iteration; 454576f627cSSteven Rostedt 455576f627cSSteven Rostedt if ($reboot_on_error && !do_not_reboot) { 456576f627cSSteven Rostedt 45775c3fda7SSteven Rostedt doprint "REBOOTING\n"; 4587faafbd6SSteven Rostedt reboot; 45975c3fda7SSteven Rostedt 460a75fececSSteven Rostedt } elsif ($poweroff_on_error && defined($power_off)) { 4615c42fc5bSSteven Rostedt doprint "POWERING OFF\n"; 462a75fececSSteven Rostedt `$power_off`; 4635c42fc5bSSteven Rostedt } 46475c3fda7SSteven Rostedt 465576f627cSSteven Rostedt die @_, "\n"; 4665c42fc5bSSteven Rostedt} 4675c42fc5bSSteven Rostedt 4687faafbd6SSteven Rostedtsub open_console { 4697faafbd6SSteven Rostedt my ($fp) = @_; 4707faafbd6SSteven Rostedt 4717faafbd6SSteven Rostedt my $flags; 4727faafbd6SSteven Rostedt 473a75fececSSteven Rostedt my $pid = open($fp, "$console|") or 474a75fececSSteven Rostedt dodie "Can't open console $console"; 4757faafbd6SSteven Rostedt 4767faafbd6SSteven Rostedt $flags = fcntl($fp, F_GETFL, 0) or 477576f627cSSteven Rostedt dodie "Can't get flags for the socket: $!"; 4787faafbd6SSteven Rostedt $flags = fcntl($fp, F_SETFL, $flags | O_NONBLOCK) or 479576f627cSSteven Rostedt dodie "Can't set flags for the socket: $!"; 4807faafbd6SSteven Rostedt 4817faafbd6SSteven Rostedt return $pid; 4827faafbd6SSteven Rostedt} 4837faafbd6SSteven Rostedt 4847faafbd6SSteven Rostedtsub close_console { 4857faafbd6SSteven Rostedt my ($fp, $pid) = @_; 4867faafbd6SSteven Rostedt 4877faafbd6SSteven Rostedt doprint "kill child process $pid\n"; 4887faafbd6SSteven Rostedt kill 2, $pid; 4897faafbd6SSteven Rostedt 4907faafbd6SSteven Rostedt print "closing!\n"; 4917faafbd6SSteven Rostedt close($fp); 4927faafbd6SSteven Rostedt} 4937faafbd6SSteven Rostedt 4947faafbd6SSteven Rostedtsub start_monitor { 4957faafbd6SSteven Rostedt if ($monitor_cnt++) { 4967faafbd6SSteven Rostedt return; 4977faafbd6SSteven Rostedt } 4987faafbd6SSteven Rostedt $monitor_fp = \*MONFD; 4997faafbd6SSteven Rostedt $monitor_pid = open_console $monitor_fp; 500a75fececSSteven Rostedt 501a75fececSSteven Rostedt return; 502a75fececSSteven Rostedt 503a75fececSSteven Rostedt open(MONFD, "Stop perl from warning about single use of MONFD"); 5047faafbd6SSteven Rostedt} 5057faafbd6SSteven Rostedt 5067faafbd6SSteven Rostedtsub end_monitor { 5077faafbd6SSteven Rostedt if (--$monitor_cnt) { 5087faafbd6SSteven Rostedt return; 5097faafbd6SSteven Rostedt } 5107faafbd6SSteven Rostedt close_console($monitor_fp, $monitor_pid); 5117faafbd6SSteven Rostedt} 5127faafbd6SSteven Rostedt 5137faafbd6SSteven Rostedtsub wait_for_monitor { 5147faafbd6SSteven Rostedt my ($time) = @_; 5157faafbd6SSteven Rostedt my $line; 5167faafbd6SSteven Rostedt 517a75fececSSteven Rostedt doprint "** Wait for monitor to settle down **\n"; 5187faafbd6SSteven Rostedt 5197faafbd6SSteven Rostedt # read the monitor and wait for the system to calm down 5207faafbd6SSteven Rostedt do { 5217faafbd6SSteven Rostedt $line = wait_for_input($monitor_fp, $time); 522a75fececSSteven Rostedt print "$line" if (defined($line)); 5237faafbd6SSteven Rostedt } while (defined($line)); 524a75fececSSteven Rostedt print "** Monitor flushed **\n"; 5257faafbd6SSteven Rostedt} 5267faafbd6SSteven Rostedt 5272b7d9b21SSteven Rostedtsub fail { 5282b7d9b21SSteven Rostedt 529a75fececSSteven Rostedt if ($die_on_failure) { 5302b7d9b21SSteven Rostedt dodie @_; 5312b7d9b21SSteven Rostedt } 5322b7d9b21SSteven Rostedt 533a75fececSSteven Rostedt doprint "FAILED\n"; 5347faafbd6SSteven Rostedt 535576f627cSSteven Rostedt my $i = $iteration; 536576f627cSSteven Rostedt 537a75fececSSteven Rostedt # no need to reboot for just building. 538576f627cSSteven Rostedt if (!do_not_reboot) { 5397faafbd6SSteven Rostedt doprint "REBOOTING\n"; 5407faafbd6SSteven Rostedt reboot; 5417faafbd6SSteven Rostedt start_monitor; 542a75fececSSteven Rostedt wait_for_monitor $sleep_time; 5437faafbd6SSteven Rostedt end_monitor; 544a75fececSSteven Rostedt } 5457faafbd6SSteven Rostedt 546576f627cSSteven Rostedt doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; 547576f627cSSteven Rostedt doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; 5487a849cd9SSteven Rostedt doprint "KTEST RESULT: TEST $i Failed: ", @_, "\n"; 549576f627cSSteven Rostedt doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; 550576f627cSSteven Rostedt doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; 551a75fececSSteven Rostedt 552a75fececSSteven Rostedt return 1 if (!defined($store_failures)); 5537faafbd6SSteven Rostedt 5547faafbd6SSteven Rostedt my @t = localtime; 5557faafbd6SSteven Rostedt my $date = sprintf "%04d%02d%02d%02d%02d%02d", 5567faafbd6SSteven Rostedt 1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0]; 5577faafbd6SSteven Rostedt 558cccae1a6SSteven Rostedt my $type = $build_type; 559cccae1a6SSteven Rostedt if ($type =~ /useconfig/) { 560cccae1a6SSteven Rostedt $type = "useconfig"; 561cccae1a6SSteven Rostedt } 562cccae1a6SSteven Rostedt 563cccae1a6SSteven Rostedt my $dir = "$machine-$test_type-$type-fail-$date"; 564a75fececSSteven Rostedt my $faildir = "$store_failures/$dir"; 5657faafbd6SSteven Rostedt 5667faafbd6SSteven Rostedt if (!-d $faildir) { 5677faafbd6SSteven Rostedt mkpath($faildir) or 568a75fececSSteven Rostedt die "can't create $faildir"; 5697faafbd6SSteven Rostedt } 57051ad1dd1SSteven Rostedt if (-f "$output_config") { 57151ad1dd1SSteven Rostedt cp "$output_config", "$faildir/config" or 5727faafbd6SSteven Rostedt die "failed to copy .config"; 5737faafbd6SSteven Rostedt } 5747faafbd6SSteven Rostedt if (-f $buildlog) { 5757faafbd6SSteven Rostedt cp $buildlog, "$faildir/buildlog" or 5767faafbd6SSteven Rostedt die "failed to move $buildlog"; 5777faafbd6SSteven Rostedt } 5787faafbd6SSteven Rostedt if (-f $dmesg) { 5797faafbd6SSteven Rostedt cp $dmesg, "$faildir/dmesg" or 5807faafbd6SSteven Rostedt die "failed to move $dmesg"; 5817faafbd6SSteven Rostedt } 5827faafbd6SSteven Rostedt 5837faafbd6SSteven Rostedt doprint "*** Saved info to $faildir ***\n"; 5847faafbd6SSteven Rostedt 5852b7d9b21SSteven Rostedt return 1; 5862b7d9b21SSteven Rostedt} 5872b7d9b21SSteven Rostedt 5882545eb61SSteven Rostedtsub run_command { 5892545eb61SSteven Rostedt my ($command) = @_; 590d6ce2a0bSSteven Rostedt my $dolog = 0; 591d6ce2a0bSSteven Rostedt my $dord = 0; 592d6ce2a0bSSteven Rostedt my $pid; 593d6ce2a0bSSteven Rostedt 594e48c5293SSteven Rostedt $command =~ s/\$SSH_USER/$ssh_user/g; 595e48c5293SSteven Rostedt $command =~ s/\$MACHINE/$machine/g; 596e48c5293SSteven Rostedt 597d6ce2a0bSSteven Rostedt doprint("$command ... "); 598d6ce2a0bSSteven Rostedt 599d6ce2a0bSSteven Rostedt $pid = open(CMD, "$command 2>&1 |") or 6002b7d9b21SSteven Rostedt (fail "unable to exec $command" and return 0); 6012545eb61SSteven Rostedt 6022545eb61SSteven Rostedt if (defined($opt{"LOG_FILE"})) { 603d6ce2a0bSSteven Rostedt open(LOG, ">>$opt{LOG_FILE}") or 604d6ce2a0bSSteven Rostedt dodie "failed to write to log"; 605d6ce2a0bSSteven Rostedt $dolog = 1; 6066c5ee0beSSteven Rostedt } 6076c5ee0beSSteven Rostedt 6086c5ee0beSSteven Rostedt if (defined($redirect)) { 609d6ce2a0bSSteven Rostedt open (RD, ">$redirect") or 610d6ce2a0bSSteven Rostedt dodie "failed to write to redirect $redirect"; 611d6ce2a0bSSteven Rostedt $dord = 1; 6122545eb61SSteven Rostedt } 6132545eb61SSteven Rostedt 614d6ce2a0bSSteven Rostedt while (<CMD>) { 615d6ce2a0bSSteven Rostedt print LOG if ($dolog); 616d6ce2a0bSSteven Rostedt print RD if ($dord); 617d6ce2a0bSSteven Rostedt } 6182545eb61SSteven Rostedt 619d6ce2a0bSSteven Rostedt waitpid($pid, 0); 6202545eb61SSteven Rostedt my $failed = $?; 6212545eb61SSteven Rostedt 622d6ce2a0bSSteven Rostedt close(CMD); 623d6ce2a0bSSteven Rostedt close(LOG) if ($dolog); 624d6ce2a0bSSteven Rostedt close(RD) if ($dord); 625d6ce2a0bSSteven Rostedt 6262545eb61SSteven Rostedt if ($failed) { 6272545eb61SSteven Rostedt doprint "FAILED!\n"; 6282545eb61SSteven Rostedt } else { 6292545eb61SSteven Rostedt doprint "SUCCESS\n"; 6302545eb61SSteven Rostedt } 6312545eb61SSteven Rostedt 6325f9b6cedSSteven Rostedt return !$failed; 6335f9b6cedSSteven Rostedt} 6345f9b6cedSSteven Rostedt 635e48c5293SSteven Rostedtsub run_ssh { 636e48c5293SSteven Rostedt my ($cmd) = @_; 637e48c5293SSteven Rostedt my $cp_exec = $ssh_exec; 638e48c5293SSteven Rostedt 639e48c5293SSteven Rostedt $cp_exec =~ s/\$SSH_COMMAND/$cmd/g; 640e48c5293SSteven Rostedt return run_command "$cp_exec"; 641e48c5293SSteven Rostedt} 642e48c5293SSteven Rostedt 643e48c5293SSteven Rostedtsub run_scp { 644e48c5293SSteven Rostedt my ($src, $dst) = @_; 645e48c5293SSteven Rostedt my $cp_scp = $scp_to_target; 646e48c5293SSteven Rostedt 647e48c5293SSteven Rostedt $cp_scp =~ s/\$SRC_FILE/$src/g; 648e48c5293SSteven Rostedt $cp_scp =~ s/\$DST_FILE/$dst/g; 649e48c5293SSteven Rostedt 650e48c5293SSteven Rostedt return run_command "$cp_scp"; 651e48c5293SSteven Rostedt} 652e48c5293SSteven Rostedt 6535f9b6cedSSteven Rostedtsub get_grub_index { 6545f9b6cedSSteven Rostedt 655a75fececSSteven Rostedt if ($reboot_type ne "grub") { 656a75fececSSteven Rostedt return; 657a75fececSSteven Rostedt } 6585a391fbfSSteven Rostedt return if (defined($grub_number)); 6595f9b6cedSSteven Rostedt 6605f9b6cedSSteven Rostedt doprint "Find grub menu ... "; 6615f9b6cedSSteven Rostedt $grub_number = -1; 662e48c5293SSteven Rostedt 663e48c5293SSteven Rostedt my $ssh_grub = $ssh_exec; 664e48c5293SSteven Rostedt $ssh_grub =~ s,\$SSH_COMMAND,cat /boot/grub/menu.lst,g; 665e48c5293SSteven Rostedt 666e48c5293SSteven Rostedt open(IN, "$ssh_grub |") 6675f9b6cedSSteven Rostedt or die "unable to get menu.lst"; 668e48c5293SSteven Rostedt 6695f9b6cedSSteven Rostedt while (<IN>) { 670a75fececSSteven Rostedt if (/^\s*title\s+$grub_menu\s*$/) { 6715f9b6cedSSteven Rostedt $grub_number++; 6725f9b6cedSSteven Rostedt last; 6735f9b6cedSSteven Rostedt } elsif (/^\s*title\s/) { 6745f9b6cedSSteven Rostedt $grub_number++; 6755f9b6cedSSteven Rostedt } 6765f9b6cedSSteven Rostedt } 6775f9b6cedSSteven Rostedt close(IN); 6785f9b6cedSSteven Rostedt 679a75fececSSteven Rostedt die "Could not find '$grub_menu' in /boot/grub/menu on $machine" 6805f9b6cedSSteven Rostedt if ($grub_number < 0); 6815f9b6cedSSteven Rostedt doprint "$grub_number\n"; 6822545eb61SSteven Rostedt} 6832545eb61SSteven Rostedt 6842545eb61SSteven Rostedtsub wait_for_input 6852545eb61SSteven Rostedt{ 6862545eb61SSteven Rostedt my ($fp, $time) = @_; 6872545eb61SSteven Rostedt my $rin; 6882545eb61SSteven Rostedt my $ready; 6892545eb61SSteven Rostedt my $line; 6902545eb61SSteven Rostedt my $ch; 6912545eb61SSteven Rostedt 6922545eb61SSteven Rostedt if (!defined($time)) { 6932545eb61SSteven Rostedt $time = $timeout; 6942545eb61SSteven Rostedt } 6952545eb61SSteven Rostedt 6962545eb61SSteven Rostedt $rin = ''; 6972545eb61SSteven Rostedt vec($rin, fileno($fp), 1) = 1; 6982545eb61SSteven Rostedt $ready = select($rin, undef, undef, $time); 6992545eb61SSteven Rostedt 7002545eb61SSteven Rostedt $line = ""; 7012545eb61SSteven Rostedt 7022545eb61SSteven Rostedt # try to read one char at a time 7032545eb61SSteven Rostedt while (sysread $fp, $ch, 1) { 7042545eb61SSteven Rostedt $line .= $ch; 7052545eb61SSteven Rostedt last if ($ch eq "\n"); 7062545eb61SSteven Rostedt } 7072545eb61SSteven Rostedt 7082545eb61SSteven Rostedt if (!length($line)) { 7092545eb61SSteven Rostedt return undef; 7102545eb61SSteven Rostedt } 7112545eb61SSteven Rostedt 7122545eb61SSteven Rostedt return $line; 7132545eb61SSteven Rostedt} 7142545eb61SSteven Rostedt 71575c3fda7SSteven Rostedtsub reboot_to { 716a75fececSSteven Rostedt if ($reboot_type eq "grub") { 717eec56460SSteven Rostedt run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch; reboot)'"; 718a75fececSSteven Rostedt return; 719a75fececSSteven Rostedt } 720a75fececSSteven Rostedt 721a75fececSSteven Rostedt run_command "$reboot_script"; 7222545eb61SSteven Rostedt} 7232545eb61SSteven Rostedt 724a57419b3SSteven Rostedtsub get_sha1 { 725a57419b3SSteven Rostedt my ($commit) = @_; 726a57419b3SSteven Rostedt 727a57419b3SSteven Rostedt doprint "git rev-list --max-count=1 $commit ... "; 728a57419b3SSteven Rostedt my $sha1 = `git rev-list --max-count=1 $commit`; 729a57419b3SSteven Rostedt my $ret = $?; 730a57419b3SSteven Rostedt 731a57419b3SSteven Rostedt logit $sha1; 732a57419b3SSteven Rostedt 733a57419b3SSteven Rostedt if ($ret) { 734a57419b3SSteven Rostedt doprint "FAILED\n"; 735a57419b3SSteven Rostedt dodie "Failed to get git $commit"; 736a57419b3SSteven Rostedt } 737a57419b3SSteven Rostedt 738a57419b3SSteven Rostedt print "SUCCESS\n"; 739a57419b3SSteven Rostedt 740a57419b3SSteven Rostedt chomp $sha1; 741a57419b3SSteven Rostedt 742a57419b3SSteven Rostedt return $sha1; 743a57419b3SSteven Rostedt} 744a57419b3SSteven Rostedt 7455a391fbfSSteven Rostedtsub monitor { 7462545eb61SSteven Rostedt my $booted = 0; 7472545eb61SSteven Rostedt my $bug = 0; 7485c42fc5bSSteven Rostedt my $skip_call_trace = 0; 7492b7d9b21SSteven Rostedt my $loops; 7502545eb61SSteven Rostedt 7517faafbd6SSteven Rostedt wait_for_monitor 5; 7522545eb61SSteven Rostedt 7532545eb61SSteven Rostedt my $line; 7542545eb61SSteven Rostedt my $full_line = ""; 7552545eb61SSteven Rostedt 7567faafbd6SSteven Rostedt open(DMESG, "> $dmesg") or 7577faafbd6SSteven Rostedt die "unable to write to $dmesg"; 7582545eb61SSteven Rostedt 75975c3fda7SSteven Rostedt reboot_to; 7602545eb61SSteven Rostedt 7611c8a617aSSteven Rostedt my $success_start; 7621c8a617aSSteven Rostedt my $failure_start; 7631c8a617aSSteven Rostedt 7642545eb61SSteven Rostedt for (;;) { 7652545eb61SSteven Rostedt 7662b7d9b21SSteven Rostedt if ($booted) { 767a75fececSSteven Rostedt $line = wait_for_input($monitor_fp, $booted_timeout); 7682b7d9b21SSteven Rostedt } else { 7697faafbd6SSteven Rostedt $line = wait_for_input($monitor_fp); 7702b7d9b21SSteven Rostedt } 7712545eb61SSteven Rostedt 7722545eb61SSteven Rostedt last if (!defined($line)); 7732545eb61SSteven Rostedt 7742545eb61SSteven Rostedt doprint $line; 7757faafbd6SSteven Rostedt print DMESG $line; 7762545eb61SSteven Rostedt 7772545eb61SSteven Rostedt # we are not guaranteed to get a full line 7782545eb61SSteven Rostedt $full_line .= $line; 7792545eb61SSteven Rostedt 780a75fececSSteven Rostedt if ($full_line =~ /$success_line/) { 7812545eb61SSteven Rostedt $booted = 1; 7821c8a617aSSteven Rostedt $success_start = time; 7831c8a617aSSteven Rostedt } 7841c8a617aSSteven Rostedt 7851c8a617aSSteven Rostedt if ($booted && defined($stop_after_success) && 7861c8a617aSSteven Rostedt $stop_after_success >= 0) { 7871c8a617aSSteven Rostedt my $now = time; 7881c8a617aSSteven Rostedt if ($now - $success_start >= $stop_after_success) { 7891c8a617aSSteven Rostedt doprint "Test forced to stop after $stop_after_success seconds after success\n"; 7901c8a617aSSteven Rostedt last; 7911c8a617aSSteven Rostedt } 7922545eb61SSteven Rostedt } 7932545eb61SSteven Rostedt 7945c42fc5bSSteven Rostedt if ($full_line =~ /\[ backtrace testing \]/) { 7955c42fc5bSSteven Rostedt $skip_call_trace = 1; 7965c42fc5bSSteven Rostedt } 7975c42fc5bSSteven Rostedt 7982545eb61SSteven Rostedt if ($full_line =~ /call trace:/i) { 7991c8a617aSSteven Rostedt if (!$skip_call_trace) { 8001c8a617aSSteven Rostedt $bug = 1; 8011c8a617aSSteven Rostedt $failure_start = time; 8021c8a617aSSteven Rostedt } 8031c8a617aSSteven Rostedt } 8041c8a617aSSteven Rostedt 8051c8a617aSSteven Rostedt if ($bug && defined($stop_after_failure) && 8061c8a617aSSteven Rostedt $stop_after_failure >= 0) { 8071c8a617aSSteven Rostedt my $now = time; 8081c8a617aSSteven Rostedt if ($now - $failure_start >= $stop_after_failure) { 8091c8a617aSSteven Rostedt doprint "Test forced to stop after $stop_after_failure seconds after failure\n"; 8101c8a617aSSteven Rostedt last; 8111c8a617aSSteven Rostedt } 8125c42fc5bSSteven Rostedt } 8135c42fc5bSSteven Rostedt 8145c42fc5bSSteven Rostedt if ($full_line =~ /\[ end of backtrace testing \]/) { 8155c42fc5bSSteven Rostedt $skip_call_trace = 0; 8165c42fc5bSSteven Rostedt } 8175c42fc5bSSteven Rostedt 8185c42fc5bSSteven Rostedt if ($full_line =~ /Kernel panic -/) { 8192545eb61SSteven Rostedt $bug = 1; 8202545eb61SSteven Rostedt } 8212545eb61SSteven Rostedt 8222545eb61SSteven Rostedt if ($line =~ /\n/) { 8232545eb61SSteven Rostedt $full_line = ""; 8242545eb61SSteven Rostedt } 8252545eb61SSteven Rostedt } 8262545eb61SSteven Rostedt 8277faafbd6SSteven Rostedt close(DMESG); 8282545eb61SSteven Rostedt 8292545eb61SSteven Rostedt if ($bug) { 8302b7d9b21SSteven Rostedt return 0 if ($in_bisect); 831576f627cSSteven Rostedt fail "failed - got a bug report" and return 0; 8322545eb61SSteven Rostedt } 8335f9b6cedSSteven Rostedt 834a75fececSSteven Rostedt if (!$booted) { 835a75fececSSteven Rostedt return 0 if ($in_bisect); 836576f627cSSteven Rostedt fail "failed - never got a boot prompt." and return 0; 837a75fececSSteven Rostedt } 838a75fececSSteven Rostedt 8392b7d9b21SSteven Rostedt return 1; 8402545eb61SSteven Rostedt} 8412545eb61SSteven Rostedt 8422545eb61SSteven Rostedtsub install { 8432545eb61SSteven Rostedt 844e48c5293SSteven Rostedt run_scp "$outputdir/$build_target", "$target_image" or 8455c42fc5bSSteven Rostedt dodie "failed to copy image"; 8465f9b6cedSSteven Rostedt 8475f9b6cedSSteven Rostedt my $install_mods = 0; 8485f9b6cedSSteven Rostedt 8495f9b6cedSSteven Rostedt # should we process modules? 8505f9b6cedSSteven Rostedt $install_mods = 0; 85151ad1dd1SSteven Rostedt open(IN, "$output_config") or dodie("Can't read config file"); 8525f9b6cedSSteven Rostedt while (<IN>) { 8535f9b6cedSSteven Rostedt if (/CONFIG_MODULES(=y)?/) { 8545f9b6cedSSteven Rostedt $install_mods = 1 if (defined($1)); 8555f9b6cedSSteven Rostedt last; 8565f9b6cedSSteven Rostedt } 8575f9b6cedSSteven Rostedt } 8585f9b6cedSSteven Rostedt close(IN); 8595f9b6cedSSteven Rostedt 8605f9b6cedSSteven Rostedt if (!$install_mods) { 8615f9b6cedSSteven Rostedt doprint "No modules needed\n"; 8625f9b6cedSSteven Rostedt return; 8632545eb61SSteven Rostedt } 8642545eb61SSteven Rostedt 865a75fececSSteven Rostedt run_command "$make INSTALL_MOD_PATH=$tmpdir modules_install" or 8665f9b6cedSSteven Rostedt dodie "Failed to install modules"; 8675f9b6cedSSteven Rostedt 8682545eb61SSteven Rostedt my $modlib = "/lib/modules/$version"; 869a57419b3SSteven Rostedt my $modtar = "ktest-mods.tar.bz2"; 8702545eb61SSteven Rostedt 871e48c5293SSteven Rostedt run_ssh "rm -rf $modlib" or 8725c42fc5bSSteven Rostedt dodie "failed to remove old mods: $modlib"; 8732545eb61SSteven Rostedt 8745c42fc5bSSteven Rostedt # would be nice if scp -r did not follow symbolic links 875a75fececSSteven Rostedt run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or 8765c42fc5bSSteven Rostedt dodie "making tarball"; 8775c42fc5bSSteven Rostedt 878e48c5293SSteven Rostedt run_scp "$tmpdir/$modtar", "/tmp" or 8795c42fc5bSSteven Rostedt dodie "failed to copy modules"; 8805c42fc5bSSteven Rostedt 881a75fececSSteven Rostedt unlink "$tmpdir/$modtar"; 8825c42fc5bSSteven Rostedt 883e48c5293SSteven Rostedt run_ssh "'(cd / && tar xf /tmp/$modtar)'" or 8845c42fc5bSSteven Rostedt dodie "failed to tar modules"; 8855c42fc5bSSteven Rostedt 886e48c5293SSteven Rostedt run_ssh "rm -f /tmp/$modtar"; 8878b37ca8cSSteven Rostedt 8888b37ca8cSSteven Rostedt return if (!defined($post_install)); 8898b37ca8cSSteven Rostedt 890e48c5293SSteven Rostedt my $cp_post_install = $post_install; 891e48c5293SSteven Rostedt $cp_post_install = s/\$KERNEL_VERSION/$version/g; 892e48c5293SSteven Rostedt run_command "$cp_post_install" or 893576f627cSSteven Rostedt dodie "Failed to run post install"; 8942545eb61SSteven Rostedt} 8952545eb61SSteven Rostedt 8966c5ee0beSSteven Rostedtsub check_buildlog { 8976c5ee0beSSteven Rostedt my ($patch) = @_; 8986c5ee0beSSteven Rostedt 8996c5ee0beSSteven Rostedt my @files = `git show $patch | diffstat -l`; 9006c5ee0beSSteven Rostedt 9016c5ee0beSSteven Rostedt open(IN, "git show $patch |") or 9026c5ee0beSSteven Rostedt dodie "failed to show $patch"; 9036c5ee0beSSteven Rostedt while (<IN>) { 9046c5ee0beSSteven Rostedt if (m,^--- a/(.*),) { 9056c5ee0beSSteven Rostedt chomp $1; 9066c5ee0beSSteven Rostedt $files[$#files] = $1; 9076c5ee0beSSteven Rostedt } 9086c5ee0beSSteven Rostedt } 9096c5ee0beSSteven Rostedt close(IN); 9106c5ee0beSSteven Rostedt 9116c5ee0beSSteven Rostedt open(IN, $buildlog) or dodie "Can't open $buildlog"; 9126c5ee0beSSteven Rostedt while (<IN>) { 9136c5ee0beSSteven Rostedt if (/^\s*(.*?):.*(warning|error)/) { 9146c5ee0beSSteven Rostedt my $err = $1; 9156c5ee0beSSteven Rostedt foreach my $file (@files) { 916a75fececSSteven Rostedt my $fullpath = "$builddir/$file"; 9176c5ee0beSSteven Rostedt if ($file eq $err || $fullpath eq $err) { 9182b7d9b21SSteven Rostedt fail "$file built with warnings" and return 0; 9196c5ee0beSSteven Rostedt } 9206c5ee0beSSteven Rostedt } 9216c5ee0beSSteven Rostedt } 9226c5ee0beSSteven Rostedt } 9236c5ee0beSSteven Rostedt close(IN); 9242b7d9b21SSteven Rostedt 9252b7d9b21SSteven Rostedt return 1; 9266c5ee0beSSteven Rostedt} 9276c5ee0beSSteven Rostedt 9282545eb61SSteven Rostedtsub build { 9292545eb61SSteven Rostedt my ($type) = @_; 9305c42fc5bSSteven Rostedt my $defconfig = ""; 9312545eb61SSteven Rostedt 9327faafbd6SSteven Rostedt unlink $buildlog; 9337faafbd6SSteven Rostedt 93475c3fda7SSteven Rostedt if ($type =~ /^useconfig:(.*)/) { 93551ad1dd1SSteven Rostedt run_command "cp $1 $output_config" or 93675c3fda7SSteven Rostedt dodie "could not copy $1 to .config"; 9375f9b6cedSSteven Rostedt 93875c3fda7SSteven Rostedt $type = "oldconfig"; 93975c3fda7SSteven Rostedt } 94075c3fda7SSteven Rostedt 9415c42fc5bSSteven Rostedt # old config can ask questions 9425c42fc5bSSteven Rostedt if ($type eq "oldconfig") { 9439386c6abSSteven Rostedt $type = "oldnoconfig"; 94475c3fda7SSteven Rostedt 94575c3fda7SSteven Rostedt # allow for empty configs 94651ad1dd1SSteven Rostedt run_command "touch $output_config"; 94775c3fda7SSteven Rostedt 94851ad1dd1SSteven Rostedt run_command "mv $output_config $outputdir/config_temp" or 9495c42fc5bSSteven Rostedt dodie "moving .config"; 9505c42fc5bSSteven Rostedt 9515f9b6cedSSteven Rostedt if (!$noclean && !run_command "$make mrproper") { 9525c42fc5bSSteven Rostedt dodie "make mrproper"; 9535c42fc5bSSteven Rostedt } 9545c42fc5bSSteven Rostedt 95551ad1dd1SSteven Rostedt run_command "mv $outputdir/config_temp $output_config" or 9565c42fc5bSSteven Rostedt dodie "moving config_temp"; 9575c42fc5bSSteven Rostedt 9585c42fc5bSSteven Rostedt } elsif (!$noclean) { 95951ad1dd1SSteven Rostedt unlink "$output_config"; 9605f9b6cedSSteven Rostedt run_command "$make mrproper" or 9615c42fc5bSSteven Rostedt dodie "make mrproper"; 9625c42fc5bSSteven Rostedt } 9632545eb61SSteven Rostedt 9642545eb61SSteven Rostedt # add something to distinguish this build 965a75fececSSteven Rostedt open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file"); 966a75fececSSteven Rostedt print OUT "$localversion\n"; 9672545eb61SSteven Rostedt close(OUT); 9682545eb61SSteven Rostedt 9695f9b6cedSSteven Rostedt if (defined($minconfig)) { 9705f9b6cedSSteven Rostedt $defconfig = "KCONFIG_ALLCONFIG=$minconfig"; 9712545eb61SSteven Rostedt } 9722545eb61SSteven Rostedt 9739386c6abSSteven Rostedt run_command "$defconfig $make $type" or 9745c42fc5bSSteven Rostedt dodie "failed make config"; 9752545eb61SSteven Rostedt 976a75fececSSteven Rostedt $redirect = "$buildlog"; 977a75fececSSteven Rostedt if (!run_command "$make $build_options") { 9786c5ee0beSSteven Rostedt undef $redirect; 9795f9b6cedSSteven Rostedt # bisect may need this to pass 9802b7d9b21SSteven Rostedt return 0 if ($in_bisect); 9812b7d9b21SSteven Rostedt fail "failed build" and return 0; 9822545eb61SSteven Rostedt } 9836c5ee0beSSteven Rostedt undef $redirect; 9845f9b6cedSSteven Rostedt 9852b7d9b21SSteven Rostedt return 1; 9862545eb61SSteven Rostedt} 9872545eb61SSteven Rostedt 98875c3fda7SSteven Rostedtsub halt { 989e48c5293SSteven Rostedt if (!run_ssh "halt" or defined($power_off)) { 990576f627cSSteven Rostedt if (defined($poweroff_after_halt)) { 991576f627cSSteven Rostedt sleep $poweroff_after_halt; 992576f627cSSteven Rostedt run_command "$power_off"; 993576f627cSSteven Rostedt } 994576f627cSSteven Rostedt } else { 99575c3fda7SSteven Rostedt # nope? the zap it! 996a75fececSSteven Rostedt run_command "$power_off"; 99775c3fda7SSteven Rostedt } 99875c3fda7SSteven Rostedt} 99975c3fda7SSteven Rostedt 10005f9b6cedSSteven Rostedtsub success { 10015f9b6cedSSteven Rostedt my ($i) = @_; 10025f9b6cedSSteven Rostedt 1003e48c5293SSteven Rostedt $successes++; 1004e48c5293SSteven Rostedt 10055f9b6cedSSteven Rostedt doprint "\n\n*******************************************\n"; 10065f9b6cedSSteven Rostedt doprint "*******************************************\n"; 10077a849cd9SSteven Rostedt doprint "KTEST RESULT: TEST $i SUCCESS!!!! **\n"; 10085f9b6cedSSteven Rostedt doprint "*******************************************\n"; 10095f9b6cedSSteven Rostedt doprint "*******************************************\n"; 10105f9b6cedSSteven Rostedt 1011576f627cSSteven Rostedt if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) { 1012a75fececSSteven Rostedt doprint "Reboot and wait $sleep_time seconds\n"; 10135f9b6cedSSteven Rostedt reboot; 10147faafbd6SSteven Rostedt start_monitor; 1015a75fececSSteven Rostedt wait_for_monitor $sleep_time; 10167faafbd6SSteven Rostedt end_monitor; 10175f9b6cedSSteven Rostedt } 10185f9b6cedSSteven Rostedt} 10195f9b6cedSSteven Rostedt 10205f9b6cedSSteven Rostedtsub get_version { 10215f9b6cedSSteven Rostedt # get the release name 10225f9b6cedSSteven Rostedt doprint "$make kernelrelease ... "; 10235f9b6cedSSteven Rostedt $version = `$make kernelrelease | tail -1`; 10245f9b6cedSSteven Rostedt chomp($version); 10255f9b6cedSSteven Rostedt doprint "$version\n"; 10265f9b6cedSSteven Rostedt} 10275f9b6cedSSteven Rostedt 10285a391fbfSSteven Rostedtsub child_run_test { 10297faafbd6SSteven Rostedt my $failed = 0; 10305a391fbfSSteven Rostedt 10317faafbd6SSteven Rostedt # child should have no power 1032a75fececSSteven Rostedt $reboot_on_error = 0; 1033a75fececSSteven Rostedt $poweroff_on_error = 0; 1034a75fececSSteven Rostedt $die_on_failure = 1; 10357faafbd6SSteven Rostedt 10367faafbd6SSteven Rostedt run_command $run_test or $failed = 1; 10375a391fbfSSteven Rostedt exit $failed; 10385a391fbfSSteven Rostedt} 10395a391fbfSSteven Rostedt 10405a391fbfSSteven Rostedtmy $child_done; 10415a391fbfSSteven Rostedt 10425a391fbfSSteven Rostedtsub child_finished { 10435a391fbfSSteven Rostedt $child_done = 1; 10445a391fbfSSteven Rostedt} 10455a391fbfSSteven Rostedt 10465a391fbfSSteven Rostedtsub do_run_test { 10475a391fbfSSteven Rostedt my $child_pid; 10485a391fbfSSteven Rostedt my $child_exit; 10495a391fbfSSteven Rostedt my $line; 10505a391fbfSSteven Rostedt my $full_line; 10515a391fbfSSteven Rostedt my $bug = 0; 10525a391fbfSSteven Rostedt 10537faafbd6SSteven Rostedt wait_for_monitor 1; 10545a391fbfSSteven Rostedt 10557faafbd6SSteven Rostedt doprint "run test $run_test\n"; 10565a391fbfSSteven Rostedt 10575a391fbfSSteven Rostedt $child_done = 0; 10585a391fbfSSteven Rostedt 10595a391fbfSSteven Rostedt $SIG{CHLD} = qw(child_finished); 10605a391fbfSSteven Rostedt 10615a391fbfSSteven Rostedt $child_pid = fork; 10625a391fbfSSteven Rostedt 10635a391fbfSSteven Rostedt child_run_test if (!$child_pid); 10645a391fbfSSteven Rostedt 10655a391fbfSSteven Rostedt $full_line = ""; 10665a391fbfSSteven Rostedt 10675a391fbfSSteven Rostedt do { 10687faafbd6SSteven Rostedt $line = wait_for_input($monitor_fp, 1); 10695a391fbfSSteven Rostedt if (defined($line)) { 10705a391fbfSSteven Rostedt 10715a391fbfSSteven Rostedt # we are not guaranteed to get a full line 10725a391fbfSSteven Rostedt $full_line .= $line; 10735a391fbfSSteven Rostedt 10745a391fbfSSteven Rostedt if ($full_line =~ /call trace:/i) { 10755a391fbfSSteven Rostedt $bug = 1; 10765a391fbfSSteven Rostedt } 10775a391fbfSSteven Rostedt 10785a391fbfSSteven Rostedt if ($full_line =~ /Kernel panic -/) { 10795a391fbfSSteven Rostedt $bug = 1; 10805a391fbfSSteven Rostedt } 10815a391fbfSSteven Rostedt 10825a391fbfSSteven Rostedt if ($line =~ /\n/) { 10835a391fbfSSteven Rostedt $full_line = ""; 10845a391fbfSSteven Rostedt } 10855a391fbfSSteven Rostedt } 10865a391fbfSSteven Rostedt } while (!$child_done && !$bug); 10875a391fbfSSteven Rostedt 10885a391fbfSSteven Rostedt if ($bug) { 10895a391fbfSSteven Rostedt doprint "Detected kernel crash!\n"; 10905a391fbfSSteven Rostedt # kill the child with extreme prejudice 10915a391fbfSSteven Rostedt kill 9, $child_pid; 10925a391fbfSSteven Rostedt } 10935a391fbfSSteven Rostedt 10945a391fbfSSteven Rostedt waitpid $child_pid, 0; 10955a391fbfSSteven Rostedt $child_exit = $?; 10965a391fbfSSteven Rostedt 10975a391fbfSSteven Rostedt if ($bug || $child_exit) { 10982b7d9b21SSteven Rostedt return 0 if $in_bisect; 10992b7d9b21SSteven Rostedt fail "test failed" and return 0; 11005a391fbfSSteven Rostedt } 11012b7d9b21SSteven Rostedt return 1; 11025a391fbfSSteven Rostedt} 11035a391fbfSSteven Rostedt 1104a75fececSSteven Rostedtsub run_git_bisect { 1105a75fececSSteven Rostedt my ($command) = @_; 1106a75fececSSteven Rostedt 1107a75fececSSteven Rostedt doprint "$command ... "; 1108a75fececSSteven Rostedt 1109a75fececSSteven Rostedt my $output = `$command 2>&1`; 1110a75fececSSteven Rostedt my $ret = $?; 1111a75fececSSteven Rostedt 1112a75fececSSteven Rostedt logit $output; 1113a75fececSSteven Rostedt 1114a75fececSSteven Rostedt if ($ret) { 1115a75fececSSteven Rostedt doprint "FAILED\n"; 1116a75fececSSteven Rostedt dodie "Failed to git bisect"; 1117a75fececSSteven Rostedt } 1118a75fececSSteven Rostedt 1119a75fececSSteven Rostedt doprint "SUCCESS\n"; 1120a75fececSSteven Rostedt if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) { 1121a75fececSSteven Rostedt doprint "$1 [$2]\n"; 1122a75fececSSteven Rostedt } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) { 1123a75fececSSteven Rostedt $bisect_bad = $1; 1124a75fececSSteven Rostedt doprint "Found bad commit... $1\n"; 1125a75fececSSteven Rostedt return 0; 1126a75fececSSteven Rostedt } else { 1127a75fececSSteven Rostedt # we already logged it, just print it now. 1128a75fececSSteven Rostedt print $output; 1129a75fececSSteven Rostedt } 1130a75fececSSteven Rostedt 1131a75fececSSteven Rostedt return 1; 1132a75fececSSteven Rostedt} 1133a75fececSSteven Rostedt 11340a05c769SSteven Rostedt# returns 1 on success, 0 on failure 11350a05c769SSteven Rostedtsub run_bisect_test { 11360a05c769SSteven Rostedt my ($type, $buildtype) = @_; 11375f9b6cedSSteven Rostedt 11382b7d9b21SSteven Rostedt my $failed = 0; 11395f9b6cedSSteven Rostedt my $result; 11405f9b6cedSSteven Rostedt my $output; 11415f9b6cedSSteven Rostedt my $ret; 11425f9b6cedSSteven Rostedt 11430a05c769SSteven Rostedt $in_bisect = 1; 11440a05c769SSteven Rostedt 11450a05c769SSteven Rostedt build $buildtype or $failed = 1; 11465f9b6cedSSteven Rostedt 11475f9b6cedSSteven Rostedt if ($type ne "build") { 11487faafbd6SSteven Rostedt dodie "Failed on build" if $failed; 11495f9b6cedSSteven Rostedt 11505f9b6cedSSteven Rostedt # Now boot the box 11515f9b6cedSSteven Rostedt get_grub_index; 11525f9b6cedSSteven Rostedt get_version; 11535f9b6cedSSteven Rostedt install; 11547faafbd6SSteven Rostedt 11557faafbd6SSteven Rostedt start_monitor; 11562b7d9b21SSteven Rostedt monitor or $failed = 1; 11575f9b6cedSSteven Rostedt 11585f9b6cedSSteven Rostedt if ($type ne "boot") { 11597faafbd6SSteven Rostedt dodie "Failed on boot" if $failed; 11605a391fbfSSteven Rostedt 11612b7d9b21SSteven Rostedt do_run_test or $failed = 1; 11625f9b6cedSSteven Rostedt } 11637faafbd6SSteven Rostedt end_monitor; 11645f9b6cedSSteven Rostedt } 11655f9b6cedSSteven Rostedt 11665f9b6cedSSteven Rostedt if ($failed) { 11670a05c769SSteven Rostedt $result = 0; 11685a391fbfSSteven Rostedt 11695a391fbfSSteven Rostedt # reboot the box to a good kernel 1170a75fececSSteven Rostedt if ($type ne "build") { 1171a75fececSSteven Rostedt doprint "Reboot and sleep $bisect_sleep_time seconds\n"; 11725a391fbfSSteven Rostedt reboot; 11737faafbd6SSteven Rostedt start_monitor; 1174a75fececSSteven Rostedt wait_for_monitor $bisect_sleep_time; 11757faafbd6SSteven Rostedt end_monitor; 11765a391fbfSSteven Rostedt } 11775f9b6cedSSteven Rostedt } else { 11780a05c769SSteven Rostedt $result = 1; 11795f9b6cedSSteven Rostedt } 11800a05c769SSteven Rostedt $in_bisect = 0; 11810a05c769SSteven Rostedt 11820a05c769SSteven Rostedt return $result; 11830a05c769SSteven Rostedt} 11840a05c769SSteven Rostedt 11850a05c769SSteven Rostedtsub run_bisect { 11860a05c769SSteven Rostedt my ($type) = @_; 11870a05c769SSteven Rostedt my $buildtype = "oldconfig"; 11880a05c769SSteven Rostedt 11890a05c769SSteven Rostedt # We should have a minconfig to use? 11900a05c769SSteven Rostedt if (defined($minconfig)) { 11910a05c769SSteven Rostedt $buildtype = "useconfig:$minconfig"; 11920a05c769SSteven Rostedt } 11930a05c769SSteven Rostedt 11940a05c769SSteven Rostedt my $ret = run_bisect_test $type, $buildtype; 11950a05c769SSteven Rostedt 11965f9b6cedSSteven Rostedt 1197d6ce2a0bSSteven Rostedt # Are we looking for where it worked, not failed? 1198d6ce2a0bSSteven Rostedt if ($reverse_bisect) { 11990a05c769SSteven Rostedt $ret = !$ret; 1200d6ce2a0bSSteven Rostedt } 1201d6ce2a0bSSteven Rostedt 12020a05c769SSteven Rostedt if ($ret) { 12030a05c769SSteven Rostedt return "good"; 12040a05c769SSteven Rostedt } else { 12050a05c769SSteven Rostedt return "bad"; 12060a05c769SSteven Rostedt } 12075f9b6cedSSteven Rostedt} 12085f9b6cedSSteven Rostedt 12095f9b6cedSSteven Rostedtsub bisect { 12105f9b6cedSSteven Rostedt my ($i) = @_; 12115f9b6cedSSteven Rostedt 12125f9b6cedSSteven Rostedt my $result; 12135f9b6cedSSteven Rostedt 12145f9b6cedSSteven Rostedt die "BISECT_GOOD[$i] not defined\n" if (!defined($opt{"BISECT_GOOD[$i]"})); 12155f9b6cedSSteven Rostedt die "BISECT_BAD[$i] not defined\n" if (!defined($opt{"BISECT_BAD[$i]"})); 12165f9b6cedSSteven Rostedt die "BISECT_TYPE[$i] not defined\n" if (!defined($opt{"BISECT_TYPE[$i]"})); 12175f9b6cedSSteven Rostedt 12185f9b6cedSSteven Rostedt my $good = $opt{"BISECT_GOOD[$i]"}; 12195f9b6cedSSteven Rostedt my $bad = $opt{"BISECT_BAD[$i]"}; 12205f9b6cedSSteven Rostedt my $type = $opt{"BISECT_TYPE[$i]"}; 1221a75fececSSteven Rostedt my $start = $opt{"BISECT_START[$i]"}; 1222a75fececSSteven Rostedt my $replay = $opt{"BISECT_REPLAY[$i]"}; 12235f9b6cedSSteven Rostedt 1224a57419b3SSteven Rostedt # convert to true sha1's 1225a57419b3SSteven Rostedt $good = get_sha1($good); 1226a57419b3SSteven Rostedt $bad = get_sha1($bad); 1227a57419b3SSteven Rostedt 1228d6ce2a0bSSteven Rostedt if (defined($opt{"BISECT_REVERSE[$i]"}) && 1229d6ce2a0bSSteven Rostedt $opt{"BISECT_REVERSE[$i]"} == 1) { 1230d6ce2a0bSSteven Rostedt doprint "Performing a reverse bisect (bad is good, good is bad!)\n"; 1231d6ce2a0bSSteven Rostedt $reverse_bisect = 1; 1232d6ce2a0bSSteven Rostedt } else { 1233d6ce2a0bSSteven Rostedt $reverse_bisect = 0; 1234d6ce2a0bSSteven Rostedt } 1235d6ce2a0bSSteven Rostedt 12365a391fbfSSteven Rostedt # Can't have a test without having a test to run 12375a391fbfSSteven Rostedt if ($type eq "test" && !defined($run_test)) { 12385a391fbfSSteven Rostedt $type = "boot"; 12395a391fbfSSteven Rostedt } 12405a391fbfSSteven Rostedt 1241a75fececSSteven Rostedt my $check = $opt{"BISECT_CHECK[$i]"}; 1242a75fececSSteven Rostedt if (defined($check) && $check ne "0") { 1243a75fececSSteven Rostedt 1244a75fececSSteven Rostedt # get current HEAD 1245a57419b3SSteven Rostedt my $head = get_sha1("HEAD"); 1246a75fececSSteven Rostedt 1247a75fececSSteven Rostedt if ($check ne "good") { 1248a75fececSSteven Rostedt doprint "TESTING BISECT BAD [$bad]\n"; 1249a75fececSSteven Rostedt run_command "git checkout $bad" or 1250a75fececSSteven Rostedt die "Failed to checkout $bad"; 1251a75fececSSteven Rostedt 1252a75fececSSteven Rostedt $result = run_bisect $type; 1253a75fececSSteven Rostedt 1254a75fececSSteven Rostedt if ($result ne "bad") { 1255a75fececSSteven Rostedt fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0; 1256a75fececSSteven Rostedt } 1257a75fececSSteven Rostedt } 1258a75fececSSteven Rostedt 1259a75fececSSteven Rostedt if ($check ne "bad") { 1260a75fececSSteven Rostedt doprint "TESTING BISECT GOOD [$good]\n"; 1261a75fececSSteven Rostedt run_command "git checkout $good" or 1262a75fececSSteven Rostedt die "Failed to checkout $good"; 1263a75fececSSteven Rostedt 1264a75fececSSteven Rostedt $result = run_bisect $type; 1265a75fececSSteven Rostedt 1266a75fececSSteven Rostedt if ($result ne "good") { 1267a75fececSSteven Rostedt fail "Tested BISECT_GOOD [$good] and it failed" and return 0; 1268a75fececSSteven Rostedt } 1269a75fececSSteven Rostedt } 1270a75fececSSteven Rostedt 1271a75fececSSteven Rostedt # checkout where we started 1272a75fececSSteven Rostedt run_command "git checkout $head" or 1273a75fececSSteven Rostedt die "Failed to checkout $head"; 1274a75fececSSteven Rostedt } 1275a75fececSSteven Rostedt 1276a75fececSSteven Rostedt run_command "git bisect start" or 1277a75fececSSteven Rostedt dodie "could not start bisect"; 1278a75fececSSteven Rostedt 1279a75fececSSteven Rostedt run_command "git bisect good $good" or 1280a75fececSSteven Rostedt dodie "could not set bisect good to $good"; 1281a75fececSSteven Rostedt 1282a75fececSSteven Rostedt run_git_bisect "git bisect bad $bad" or 1283a75fececSSteven Rostedt dodie "could not set bisect bad to $bad"; 1284a75fececSSteven Rostedt 1285a75fececSSteven Rostedt if (defined($replay)) { 1286a75fececSSteven Rostedt run_command "git bisect replay $replay" or 1287a75fececSSteven Rostedt dodie "failed to run replay"; 1288a75fececSSteven Rostedt } 1289a75fececSSteven Rostedt 1290a75fececSSteven Rostedt if (defined($start)) { 1291a75fececSSteven Rostedt run_command "git checkout $start" or 1292a75fececSSteven Rostedt dodie "failed to checkout $start"; 1293a75fececSSteven Rostedt } 1294a75fececSSteven Rostedt 1295a75fececSSteven Rostedt my $test; 12965f9b6cedSSteven Rostedt do { 12975f9b6cedSSteven Rostedt $result = run_bisect $type; 1298a75fececSSteven Rostedt $test = run_git_bisect "git bisect $result"; 1299a75fececSSteven Rostedt } while ($test); 13005f9b6cedSSteven Rostedt 13015f9b6cedSSteven Rostedt run_command "git bisect log" or 13025f9b6cedSSteven Rostedt dodie "could not capture git bisect log"; 13035f9b6cedSSteven Rostedt 13045f9b6cedSSteven Rostedt run_command "git bisect reset" or 13055f9b6cedSSteven Rostedt dodie "could not reset git bisect"; 13065f9b6cedSSteven Rostedt 13075f9b6cedSSteven Rostedt doprint "Bad commit was [$bisect_bad]\n"; 13085f9b6cedSSteven Rostedt 13090a05c769SSteven Rostedt success $i; 13100a05c769SSteven Rostedt} 13110a05c769SSteven Rostedt 13120a05c769SSteven Rostedtmy %config_ignore; 13130a05c769SSteven Rostedtmy %config_set; 13140a05c769SSteven Rostedt 13150a05c769SSteven Rostedtmy %config_list; 13160a05c769SSteven Rostedtmy %null_config; 13170a05c769SSteven Rostedt 13180a05c769SSteven Rostedtmy %dependency; 13190a05c769SSteven Rostedt 13200a05c769SSteven Rostedtsub process_config_ignore { 13210a05c769SSteven Rostedt my ($config) = @_; 13220a05c769SSteven Rostedt 13230a05c769SSteven Rostedt open (IN, $config) 13240a05c769SSteven Rostedt or dodie "Failed to read $config"; 13250a05c769SSteven Rostedt 13260a05c769SSteven Rostedt while (<IN>) { 13270a05c769SSteven Rostedt if (/^(.*?(CONFIG\S*)(=.*| is not set))/) { 13280a05c769SSteven Rostedt $config_ignore{$2} = $1; 13290a05c769SSteven Rostedt } 13300a05c769SSteven Rostedt } 13310a05c769SSteven Rostedt 13320a05c769SSteven Rostedt close(IN); 13330a05c769SSteven Rostedt} 13340a05c769SSteven Rostedt 13350a05c769SSteven Rostedtsub read_current_config { 13360a05c769SSteven Rostedt my ($config_ref) = @_; 13370a05c769SSteven Rostedt 13380a05c769SSteven Rostedt %{$config_ref} = (); 13390a05c769SSteven Rostedt undef %{$config_ref}; 13400a05c769SSteven Rostedt 13410a05c769SSteven Rostedt my @key = keys %{$config_ref}; 13420a05c769SSteven Rostedt if ($#key >= 0) { 13430a05c769SSteven Rostedt print "did not delete!\n"; 13440a05c769SSteven Rostedt exit; 13450a05c769SSteven Rostedt } 13460a05c769SSteven Rostedt open (IN, "$output_config"); 13470a05c769SSteven Rostedt 13480a05c769SSteven Rostedt while (<IN>) { 13490a05c769SSteven Rostedt if (/^(CONFIG\S+)=(.*)/) { 13500a05c769SSteven Rostedt ${$config_ref}{$1} = $2; 13510a05c769SSteven Rostedt } 13520a05c769SSteven Rostedt } 13530a05c769SSteven Rostedt close(IN); 13540a05c769SSteven Rostedt} 13550a05c769SSteven Rostedt 13560a05c769SSteven Rostedtsub get_dependencies { 13570a05c769SSteven Rostedt my ($config) = @_; 13580a05c769SSteven Rostedt 13590a05c769SSteven Rostedt my $arr = $dependency{$config}; 13600a05c769SSteven Rostedt if (!defined($arr)) { 13610a05c769SSteven Rostedt return (); 13620a05c769SSteven Rostedt } 13630a05c769SSteven Rostedt 13640a05c769SSteven Rostedt my @deps = @{$arr}; 13650a05c769SSteven Rostedt 13660a05c769SSteven Rostedt foreach my $dep (@{$arr}) { 13670a05c769SSteven Rostedt print "ADD DEP $dep\n"; 13680a05c769SSteven Rostedt @deps = (@deps, get_dependencies $dep); 13690a05c769SSteven Rostedt } 13700a05c769SSteven Rostedt 13710a05c769SSteven Rostedt return @deps; 13720a05c769SSteven Rostedt} 13730a05c769SSteven Rostedt 13740a05c769SSteven Rostedtsub create_config { 13750a05c769SSteven Rostedt my @configs = @_; 13760a05c769SSteven Rostedt 13770a05c769SSteven Rostedt open(OUT, ">$output_config") or dodie "Can not write to $output_config"; 13780a05c769SSteven Rostedt 13790a05c769SSteven Rostedt foreach my $config (@configs) { 13800a05c769SSteven Rostedt print OUT "$config_set{$config}\n"; 13810a05c769SSteven Rostedt my @deps = get_dependencies $config; 13820a05c769SSteven Rostedt foreach my $dep (@deps) { 13830a05c769SSteven Rostedt print OUT "$config_set{$dep}\n"; 13840a05c769SSteven Rostedt } 13850a05c769SSteven Rostedt } 13860a05c769SSteven Rostedt 13870a05c769SSteven Rostedt foreach my $config (keys %config_ignore) { 13880a05c769SSteven Rostedt print OUT "$config_ignore{$config}\n"; 13890a05c769SSteven Rostedt } 13900a05c769SSteven Rostedt close(OUT); 13910a05c769SSteven Rostedt 13920a05c769SSteven Rostedt# exit; 13930a05c769SSteven Rostedt run_command "$make oldnoconfig" or 13940a05c769SSteven Rostedt dodie "failed make config oldconfig"; 13950a05c769SSteven Rostedt 13960a05c769SSteven Rostedt} 13970a05c769SSteven Rostedt 13980a05c769SSteven Rostedtsub compare_configs { 13990a05c769SSteven Rostedt my (%a, %b) = @_; 14000a05c769SSteven Rostedt 14010a05c769SSteven Rostedt foreach my $item (keys %a) { 14020a05c769SSteven Rostedt if (!defined($b{$item})) { 14030a05c769SSteven Rostedt print "diff $item\n"; 14040a05c769SSteven Rostedt return 1; 14050a05c769SSteven Rostedt } 14060a05c769SSteven Rostedt delete $b{$item}; 14070a05c769SSteven Rostedt } 14080a05c769SSteven Rostedt 14090a05c769SSteven Rostedt my @keys = keys %b; 14100a05c769SSteven Rostedt if ($#keys) { 14110a05c769SSteven Rostedt print "diff2 $keys[0]\n"; 14120a05c769SSteven Rostedt } 14130a05c769SSteven Rostedt return -1 if ($#keys >= 0); 14140a05c769SSteven Rostedt 14150a05c769SSteven Rostedt return 0; 14160a05c769SSteven Rostedt} 14170a05c769SSteven Rostedt 14180a05c769SSteven Rostedtsub run_config_bisect_test { 14190a05c769SSteven Rostedt my ($type) = @_; 14200a05c769SSteven Rostedt 14210a05c769SSteven Rostedt return run_bisect_test $type, "oldconfig"; 14220a05c769SSteven Rostedt} 14230a05c769SSteven Rostedt 14240a05c769SSteven Rostedtsub process_passed { 14250a05c769SSteven Rostedt my (%configs) = @_; 14260a05c769SSteven Rostedt 14270a05c769SSteven Rostedt doprint "These configs had no failure: (Enabling them for further compiles)\n"; 14280a05c769SSteven Rostedt # Passed! All these configs are part of a good compile. 14290a05c769SSteven Rostedt # Add them to the min options. 14300a05c769SSteven Rostedt foreach my $config (keys %configs) { 14310a05c769SSteven Rostedt if (defined($config_list{$config})) { 14320a05c769SSteven Rostedt doprint " removing $config\n"; 14330a05c769SSteven Rostedt $config_ignore{$config} = $config_list{$config}; 14340a05c769SSteven Rostedt delete $config_list{$config}; 14350a05c769SSteven Rostedt } 14360a05c769SSteven Rostedt } 1437f1a27850SSteven Rostedt doprint "config copied to $outputdir/config_good\n"; 1438f1a27850SSteven Rostedt run_command "cp -f $output_config $outputdir/config_good"; 14390a05c769SSteven Rostedt} 14400a05c769SSteven Rostedt 14410a05c769SSteven Rostedtsub process_failed { 14420a05c769SSteven Rostedt my ($config) = @_; 14430a05c769SSteven Rostedt 14440a05c769SSteven Rostedt doprint "\n\n***************************************\n"; 14450a05c769SSteven Rostedt doprint "Found bad config: $config\n"; 14460a05c769SSteven Rostedt doprint "***************************************\n\n"; 14470a05c769SSteven Rostedt} 14480a05c769SSteven Rostedt 14490a05c769SSteven Rostedtsub run_config_bisect { 14500a05c769SSteven Rostedt 14510a05c769SSteven Rostedt my @start_list = keys %config_list; 14520a05c769SSteven Rostedt 14530a05c769SSteven Rostedt if ($#start_list < 0) { 14540a05c769SSteven Rostedt doprint "No more configs to test!!!\n"; 14550a05c769SSteven Rostedt return -1; 14560a05c769SSteven Rostedt } 14570a05c769SSteven Rostedt 14580a05c769SSteven Rostedt doprint "***** RUN TEST ***\n"; 14590a05c769SSteven Rostedt my $type = $opt{"CONFIG_BISECT_TYPE[$iteration]"}; 14600a05c769SSteven Rostedt my $ret; 14610a05c769SSteven Rostedt my %current_config; 14620a05c769SSteven Rostedt 14630a05c769SSteven Rostedt my $count = $#start_list + 1; 14640a05c769SSteven Rostedt doprint " $count configs to test\n"; 14650a05c769SSteven Rostedt 14660a05c769SSteven Rostedt my $half = int($#start_list / 2); 14670a05c769SSteven Rostedt 14680a05c769SSteven Rostedt do { 14690a05c769SSteven Rostedt my @tophalf = @start_list[0 .. $half]; 14700a05c769SSteven Rostedt 14710a05c769SSteven Rostedt create_config @tophalf; 14720a05c769SSteven Rostedt read_current_config \%current_config; 14730a05c769SSteven Rostedt 14740a05c769SSteven Rostedt $count = $#tophalf + 1; 14750a05c769SSteven Rostedt doprint "Testing $count configs\n"; 14760a05c769SSteven Rostedt my $found = 0; 14770a05c769SSteven Rostedt # make sure we test something 14780a05c769SSteven Rostedt foreach my $config (@tophalf) { 14790a05c769SSteven Rostedt if (defined($current_config{$config})) { 14800a05c769SSteven Rostedt logit " $config\n"; 14810a05c769SSteven Rostedt $found = 1; 14820a05c769SSteven Rostedt } 14830a05c769SSteven Rostedt } 14840a05c769SSteven Rostedt if (!$found) { 14850a05c769SSteven Rostedt # try the other half 14860a05c769SSteven Rostedt doprint "Top half produced no set configs, trying bottom half\n"; 14870a05c769SSteven Rostedt @tophalf = @start_list[$half .. $#start_list]; 14880a05c769SSteven Rostedt create_config @tophalf; 14890a05c769SSteven Rostedt read_current_config \%current_config; 14900a05c769SSteven Rostedt foreach my $config (@tophalf) { 14910a05c769SSteven Rostedt if (defined($current_config{$config})) { 14920a05c769SSteven Rostedt logit " $config\n"; 14930a05c769SSteven Rostedt $found = 1; 14940a05c769SSteven Rostedt } 14950a05c769SSteven Rostedt } 14960a05c769SSteven Rostedt if (!$found) { 14970a05c769SSteven Rostedt doprint "Failed: Can't make new config with current configs\n"; 14980a05c769SSteven Rostedt foreach my $config (@start_list) { 14990a05c769SSteven Rostedt doprint " CONFIG: $config\n"; 15000a05c769SSteven Rostedt } 15010a05c769SSteven Rostedt return -1; 15020a05c769SSteven Rostedt } 15030a05c769SSteven Rostedt $count = $#tophalf + 1; 15040a05c769SSteven Rostedt doprint "Testing $count configs\n"; 15050a05c769SSteven Rostedt } 15060a05c769SSteven Rostedt 15070a05c769SSteven Rostedt $ret = run_config_bisect_test $type; 15080a05c769SSteven Rostedt 15090a05c769SSteven Rostedt if ($ret) { 15100a05c769SSteven Rostedt process_passed %current_config; 15110a05c769SSteven Rostedt return 0; 15120a05c769SSteven Rostedt } 15130a05c769SSteven Rostedt 15140a05c769SSteven Rostedt doprint "This config had a failure.\n"; 15150a05c769SSteven Rostedt doprint "Removing these configs that were not set in this config:\n"; 1516f1a27850SSteven Rostedt doprint "config copied to $outputdir/config_bad\n"; 1517f1a27850SSteven Rostedt run_command "cp -f $output_config $outputdir/config_bad"; 15180a05c769SSteven Rostedt 15190a05c769SSteven Rostedt # A config exists in this group that was bad. 15200a05c769SSteven Rostedt foreach my $config (keys %config_list) { 15210a05c769SSteven Rostedt if (!defined($current_config{$config})) { 15220a05c769SSteven Rostedt doprint " removing $config\n"; 15230a05c769SSteven Rostedt delete $config_list{$config}; 15240a05c769SSteven Rostedt } 15250a05c769SSteven Rostedt } 15260a05c769SSteven Rostedt 15270a05c769SSteven Rostedt @start_list = @tophalf; 15280a05c769SSteven Rostedt 15290a05c769SSteven Rostedt if ($#start_list == 0) { 15300a05c769SSteven Rostedt process_failed $start_list[0]; 15310a05c769SSteven Rostedt return 1; 15320a05c769SSteven Rostedt } 15330a05c769SSteven Rostedt 15340a05c769SSteven Rostedt # remove half the configs we are looking at and see if 15350a05c769SSteven Rostedt # they are good. 15360a05c769SSteven Rostedt $half = int($#start_list / 2); 15370a05c769SSteven Rostedt } while ($half > 0); 15380a05c769SSteven Rostedt 15390a05c769SSteven Rostedt # we found a single config, try it again 15400a05c769SSteven Rostedt my @tophalf = @start_list[0 .. 0]; 15410a05c769SSteven Rostedt 15420a05c769SSteven Rostedt $ret = run_config_bisect_test $type; 15430a05c769SSteven Rostedt if ($ret) { 15440a05c769SSteven Rostedt process_passed %current_config; 15450a05c769SSteven Rostedt return 0; 15460a05c769SSteven Rostedt } 15470a05c769SSteven Rostedt 15480a05c769SSteven Rostedt process_failed $start_list[0]; 15490a05c769SSteven Rostedt return 1; 15500a05c769SSteven Rostedt} 15510a05c769SSteven Rostedt 15520a05c769SSteven Rostedtsub config_bisect { 15530a05c769SSteven Rostedt my ($i) = @_; 15540a05c769SSteven Rostedt 15550a05c769SSteven Rostedt my $start_config = $opt{"CONFIG_BISECT[$i]"}; 15560a05c769SSteven Rostedt 15570a05c769SSteven Rostedt my $tmpconfig = "$tmpdir/use_config"; 15580a05c769SSteven Rostedt 15590a05c769SSteven Rostedt # Make the file with the bad config and the min config 15600a05c769SSteven Rostedt if (defined($minconfig)) { 15610a05c769SSteven Rostedt # read the min config for things to ignore 15620a05c769SSteven Rostedt run_command "cp $minconfig $tmpconfig" or 15630a05c769SSteven Rostedt dodie "failed to copy $minconfig to $tmpconfig"; 15640a05c769SSteven Rostedt } else { 15650a05c769SSteven Rostedt unlink $tmpconfig; 15660a05c769SSteven Rostedt } 15670a05c769SSteven Rostedt 15680a05c769SSteven Rostedt # Add other configs 15690a05c769SSteven Rostedt if (defined($addconfig)) { 15700a05c769SSteven Rostedt run_command "cat $addconfig >> $tmpconfig" or 15710a05c769SSteven Rostedt dodie "failed to append $addconfig"; 15720a05c769SSteven Rostedt } 15730a05c769SSteven Rostedt 15740a05c769SSteven Rostedt my $defconfig = ""; 15750a05c769SSteven Rostedt if (-f $tmpconfig) { 15760a05c769SSteven Rostedt $defconfig = "KCONFIG_ALLCONFIG=$tmpconfig"; 15770a05c769SSteven Rostedt process_config_ignore $tmpconfig; 15780a05c769SSteven Rostedt } 15790a05c769SSteven Rostedt 15800a05c769SSteven Rostedt # now process the start config 15810a05c769SSteven Rostedt run_command "cp $start_config $output_config" or 15820a05c769SSteven Rostedt dodie "failed to copy $start_config to $output_config"; 15830a05c769SSteven Rostedt 15840a05c769SSteven Rostedt # read directly what we want to check 15850a05c769SSteven Rostedt my %config_check; 15860a05c769SSteven Rostedt open (IN, $output_config) 15870a05c769SSteven Rostedt or dodie "faied to open $output_config"; 15880a05c769SSteven Rostedt 15890a05c769SSteven Rostedt while (<IN>) { 15900a05c769SSteven Rostedt if (/^((CONFIG\S*)=.*)/) { 15910a05c769SSteven Rostedt $config_check{$2} = $1; 15920a05c769SSteven Rostedt } 15930a05c769SSteven Rostedt } 15940a05c769SSteven Rostedt close(IN); 15950a05c769SSteven Rostedt 15960a05c769SSteven Rostedt # Now run oldconfig with the minconfig (and addconfigs) 15970a05c769SSteven Rostedt run_command "$defconfig $make oldnoconfig" or 15980a05c769SSteven Rostedt dodie "failed make config oldconfig"; 15990a05c769SSteven Rostedt 16000a05c769SSteven Rostedt # check to see what we lost (or gained) 16010a05c769SSteven Rostedt open (IN, $output_config) 16020a05c769SSteven Rostedt or dodie "Failed to read $start_config"; 16030a05c769SSteven Rostedt 16040a05c769SSteven Rostedt my %removed_configs; 16050a05c769SSteven Rostedt my %added_configs; 16060a05c769SSteven Rostedt 16070a05c769SSteven Rostedt while (<IN>) { 16080a05c769SSteven Rostedt if (/^((CONFIG\S*)=.*)/) { 16090a05c769SSteven Rostedt # save off all options 16100a05c769SSteven Rostedt $config_set{$2} = $1; 16110a05c769SSteven Rostedt if (defined($config_check{$2})) { 16120a05c769SSteven Rostedt if (defined($config_ignore{$2})) { 16130a05c769SSteven Rostedt $removed_configs{$2} = $1; 16140a05c769SSteven Rostedt } else { 16150a05c769SSteven Rostedt $config_list{$2} = $1; 16160a05c769SSteven Rostedt } 16170a05c769SSteven Rostedt } elsif (!defined($config_ignore{$2})) { 16180a05c769SSteven Rostedt $added_configs{$2} = $1; 16190a05c769SSteven Rostedt $config_list{$2} = $1; 16200a05c769SSteven Rostedt } 16210a05c769SSteven Rostedt } 16220a05c769SSteven Rostedt } 16230a05c769SSteven Rostedt close(IN); 16240a05c769SSteven Rostedt 16250a05c769SSteven Rostedt my @confs = keys %removed_configs; 16260a05c769SSteven Rostedt if ($#confs >= 0) { 16270a05c769SSteven Rostedt doprint "Configs overridden by default configs and removed from check:\n"; 16280a05c769SSteven Rostedt foreach my $config (@confs) { 16290a05c769SSteven Rostedt doprint " $config\n"; 16300a05c769SSteven Rostedt } 16310a05c769SSteven Rostedt } 16320a05c769SSteven Rostedt @confs = keys %added_configs; 16330a05c769SSteven Rostedt if ($#confs >= 0) { 16340a05c769SSteven Rostedt doprint "Configs appearing in make oldconfig and added:\n"; 16350a05c769SSteven Rostedt foreach my $config (@confs) { 16360a05c769SSteven Rostedt doprint " $config\n"; 16370a05c769SSteven Rostedt } 16380a05c769SSteven Rostedt } 16390a05c769SSteven Rostedt 16400a05c769SSteven Rostedt my %config_test; 16410a05c769SSteven Rostedt my $once = 0; 16420a05c769SSteven Rostedt 16430a05c769SSteven Rostedt # Sometimes kconfig does weird things. We must make sure 16440a05c769SSteven Rostedt # that the config we autocreate has everything we need 16450a05c769SSteven Rostedt # to test, otherwise we may miss testing configs, or 16460a05c769SSteven Rostedt # may not be able to create a new config. 16470a05c769SSteven Rostedt # Here we create a config with everything set. 16480a05c769SSteven Rostedt create_config (keys %config_list); 16490a05c769SSteven Rostedt read_current_config \%config_test; 16500a05c769SSteven Rostedt foreach my $config (keys %config_list) { 16510a05c769SSteven Rostedt if (!defined($config_test{$config})) { 16520a05c769SSteven Rostedt if (!$once) { 16530a05c769SSteven Rostedt $once = 1; 16540a05c769SSteven Rostedt doprint "Configs not produced by kconfig (will not be checked):\n"; 16550a05c769SSteven Rostedt } 16560a05c769SSteven Rostedt doprint " $config\n"; 16570a05c769SSteven Rostedt delete $config_list{$config}; 16580a05c769SSteven Rostedt } 16590a05c769SSteven Rostedt } 16600a05c769SSteven Rostedt my $ret; 16610a05c769SSteven Rostedt do { 16620a05c769SSteven Rostedt $ret = run_config_bisect; 16630a05c769SSteven Rostedt } while (!$ret); 16640a05c769SSteven Rostedt 16650a05c769SSteven Rostedt return $ret if ($ret < 0); 16665f9b6cedSSteven Rostedt 16675f9b6cedSSteven Rostedt success $i; 16685f9b6cedSSteven Rostedt} 16695f9b6cedSSteven Rostedt 16706c5ee0beSSteven Rostedtsub patchcheck { 16716c5ee0beSSteven Rostedt my ($i) = @_; 16726c5ee0beSSteven Rostedt 16736c5ee0beSSteven Rostedt die "PATCHCHECK_START[$i] not defined\n" 16746c5ee0beSSteven Rostedt if (!defined($opt{"PATCHCHECK_START[$i]"})); 16756c5ee0beSSteven Rostedt die "PATCHCHECK_TYPE[$i] not defined\n" 16766c5ee0beSSteven Rostedt if (!defined($opt{"PATCHCHECK_TYPE[$i]"})); 16776c5ee0beSSteven Rostedt 16786c5ee0beSSteven Rostedt my $start = $opt{"PATCHCHECK_START[$i]"}; 16796c5ee0beSSteven Rostedt 16806c5ee0beSSteven Rostedt my $end = "HEAD"; 16816c5ee0beSSteven Rostedt if (defined($opt{"PATCHCHECK_END[$i]"})) { 16826c5ee0beSSteven Rostedt $end = $opt{"PATCHCHECK_END[$i]"}; 16836c5ee0beSSteven Rostedt } 16846c5ee0beSSteven Rostedt 1685a57419b3SSteven Rostedt # Get the true sha1's since we can use things like HEAD~3 1686a57419b3SSteven Rostedt $start = get_sha1($start); 1687a57419b3SSteven Rostedt $end = get_sha1($end); 1688a57419b3SSteven Rostedt 16896c5ee0beSSteven Rostedt my $type = $opt{"PATCHCHECK_TYPE[$i]"}; 16906c5ee0beSSteven Rostedt 16916c5ee0beSSteven Rostedt # Can't have a test without having a test to run 16926c5ee0beSSteven Rostedt if ($type eq "test" && !defined($run_test)) { 16936c5ee0beSSteven Rostedt $type = "boot"; 16946c5ee0beSSteven Rostedt } 16956c5ee0beSSteven Rostedt 16966c5ee0beSSteven Rostedt open (IN, "git log --pretty=oneline $end|") or 16976c5ee0beSSteven Rostedt dodie "could not get git list"; 16986c5ee0beSSteven Rostedt 16996c5ee0beSSteven Rostedt my @list; 17006c5ee0beSSteven Rostedt 17016c5ee0beSSteven Rostedt while (<IN>) { 17026c5ee0beSSteven Rostedt chomp; 17036c5ee0beSSteven Rostedt $list[$#list+1] = $_; 17046c5ee0beSSteven Rostedt last if (/^$start/); 17056c5ee0beSSteven Rostedt } 17066c5ee0beSSteven Rostedt close(IN); 17076c5ee0beSSteven Rostedt 17086c5ee0beSSteven Rostedt if ($list[$#list] !~ /^$start/) { 17092b7d9b21SSteven Rostedt fail "SHA1 $start not found"; 17106c5ee0beSSteven Rostedt } 17116c5ee0beSSteven Rostedt 17126c5ee0beSSteven Rostedt # go backwards in the list 17136c5ee0beSSteven Rostedt @list = reverse @list; 17146c5ee0beSSteven Rostedt 17156c5ee0beSSteven Rostedt my $save_clean = $noclean; 17166c5ee0beSSteven Rostedt 17176c5ee0beSSteven Rostedt $in_patchcheck = 1; 17186c5ee0beSSteven Rostedt foreach my $item (@list) { 17196c5ee0beSSteven Rostedt my $sha1 = $item; 17206c5ee0beSSteven Rostedt $sha1 =~ s/^([[:xdigit:]]+).*/$1/; 17216c5ee0beSSteven Rostedt 17226c5ee0beSSteven Rostedt doprint "\nProcessing commit $item\n\n"; 17236c5ee0beSSteven Rostedt 17246c5ee0beSSteven Rostedt run_command "git checkout $sha1" or 17256c5ee0beSSteven Rostedt die "Failed to checkout $sha1"; 17266c5ee0beSSteven Rostedt 17276c5ee0beSSteven Rostedt # only clean on the first and last patch 17286c5ee0beSSteven Rostedt if ($item eq $list[0] || 17296c5ee0beSSteven Rostedt $item eq $list[$#list]) { 17306c5ee0beSSteven Rostedt $noclean = $save_clean; 17316c5ee0beSSteven Rostedt } else { 17326c5ee0beSSteven Rostedt $noclean = 1; 17336c5ee0beSSteven Rostedt } 17346c5ee0beSSteven Rostedt 17356c5ee0beSSteven Rostedt if (defined($minconfig)) { 17362b7d9b21SSteven Rostedt build "useconfig:$minconfig" or return 0; 17376c5ee0beSSteven Rostedt } else { 17386c5ee0beSSteven Rostedt # ?? no config to use? 17392b7d9b21SSteven Rostedt build "oldconfig" or return 0; 17406c5ee0beSSteven Rostedt } 17416c5ee0beSSteven Rostedt 17422b7d9b21SSteven Rostedt check_buildlog $sha1 or return 0; 17436c5ee0beSSteven Rostedt 17446c5ee0beSSteven Rostedt next if ($type eq "build"); 17456c5ee0beSSteven Rostedt 17466c5ee0beSSteven Rostedt get_grub_index; 17476c5ee0beSSteven Rostedt get_version; 17486c5ee0beSSteven Rostedt install; 17496c5ee0beSSteven Rostedt 17507faafbd6SSteven Rostedt my $failed = 0; 17517faafbd6SSteven Rostedt 17527faafbd6SSteven Rostedt start_monitor; 17537faafbd6SSteven Rostedt monitor or $failed = 1; 17547faafbd6SSteven Rostedt 17557faafbd6SSteven Rostedt if (!$failed && $type ne "boot"){ 17567faafbd6SSteven Rostedt do_run_test or $failed = 1; 17577faafbd6SSteven Rostedt } 17587faafbd6SSteven Rostedt end_monitor; 17597faafbd6SSteven Rostedt return 0 if ($failed); 17607faafbd6SSteven Rostedt 17616c5ee0beSSteven Rostedt } 17626c5ee0beSSteven Rostedt $in_patchcheck = 0; 17636c5ee0beSSteven Rostedt success $i; 17642b7d9b21SSteven Rostedt 17652b7d9b21SSteven Rostedt return 1; 17666c5ee0beSSteven Rostedt} 17676c5ee0beSSteven Rostedt 1768*8d1491baSSteven Rostedt$#ARGV < 1 or die "ktest.pl version: $VERSION\n usage: ktest.pl config-file\n"; 17692545eb61SSteven Rostedt 1770*8d1491baSSteven Rostedtif ($#ARGV == 0) { 1771*8d1491baSSteven Rostedt $ktest_config = $ARGV[0]; 1772*8d1491baSSteven Rostedt if (! -f $ktest_config) { 1773*8d1491baSSteven Rostedt print "$ktest_config does not exist.\n"; 1774*8d1491baSSteven Rostedt my $ans; 1775*8d1491baSSteven Rostedt for (;;) { 1776*8d1491baSSteven Rostedt print "Create it? [Y/n] "; 1777*8d1491baSSteven Rostedt $ans = <STDIN>; 1778*8d1491baSSteven Rostedt chomp $ans; 1779*8d1491baSSteven Rostedt if ($ans =~ /^\s*$/) { 1780*8d1491baSSteven Rostedt $ans = "y"; 1781*8d1491baSSteven Rostedt } 1782*8d1491baSSteven Rostedt last if ($ans =~ /^y$/i || $ans =~ /^n$/i); 1783*8d1491baSSteven Rostedt print "Please answer either 'y' or 'n'.\n"; 1784*8d1491baSSteven Rostedt } 1785*8d1491baSSteven Rostedt if ($ans !~ /^y$/i) { 1786*8d1491baSSteven Rostedt exit 0; 1787*8d1491baSSteven Rostedt } 1788*8d1491baSSteven Rostedt } 1789*8d1491baSSteven Rostedt} else { 1790*8d1491baSSteven Rostedt $ktest_config = "ktest.conf"; 1791*8d1491baSSteven Rostedt} 1792*8d1491baSSteven Rostedt 1793*8d1491baSSteven Rostedtif (! -f $ktest_config) { 1794*8d1491baSSteven Rostedt open(OUT, ">$ktest_config") or die "Can not create $ktest_config"; 1795*8d1491baSSteven Rostedt print OUT << "EOF" 1796*8d1491baSSteven Rostedt# Generated by ktest.pl 1797*8d1491baSSteven Rostedt# 1798*8d1491baSSteven Rostedt# Define each test with TEST_START 1799*8d1491baSSteven Rostedt# The config options below it will override the defaults 1800*8d1491baSSteven RostedtTEST_START 1801*8d1491baSSteven Rostedt 1802*8d1491baSSteven RostedtDEFAULTS 1803*8d1491baSSteven RostedtEOF 1804*8d1491baSSteven Rostedt; 1805*8d1491baSSteven Rostedt close(OUT); 1806*8d1491baSSteven Rostedt} 1807*8d1491baSSteven Rostedtread_config $ktest_config; 1808*8d1491baSSteven Rostedt 1809*8d1491baSSteven Rostedt# Append any configs entered in manually to the config file. 1810*8d1491baSSteven Rostedtmy @new_configs = keys %entered_configs; 1811*8d1491baSSteven Rostedtif ($#new_configs >= 0) { 1812*8d1491baSSteven Rostedt print "\nAppending entered in configs to $ktest_config\n"; 1813*8d1491baSSteven Rostedt open(OUT, ">>$ktest_config") or die "Can not append to $ktest_config"; 1814*8d1491baSSteven Rostedt foreach my $config (@new_configs) { 1815*8d1491baSSteven Rostedt print OUT "$config = $entered_configs{$config}\n"; 1816*8d1491baSSteven Rostedt $opt{$config} = $entered_configs{$config}; 1817*8d1491baSSteven Rostedt } 1818*8d1491baSSteven Rostedt} 18192545eb61SSteven Rostedt 18202b7d9b21SSteven Rostedtif ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) { 18212b7d9b21SSteven Rostedt unlink $opt{"LOG_FILE"}; 18222b7d9b21SSteven Rostedt} 18232545eb61SSteven Rostedt 18242b7d9b21SSteven Rostedtdoprint "\n\nSTARTING AUTOMATED TESTS\n\n"; 18252b7d9b21SSteven Rostedt 1826a57419b3SSteven Rostedtfor (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) { 1827a57419b3SSteven Rostedt 1828a57419b3SSteven Rostedt if (!$i) { 1829a57419b3SSteven Rostedt doprint "DEFAULT OPTIONS:\n"; 1830a57419b3SSteven Rostedt } else { 1831a57419b3SSteven Rostedt doprint "\nTEST $i OPTIONS"; 1832a57419b3SSteven Rostedt if (defined($repeat_tests{$i})) { 1833a57419b3SSteven Rostedt $repeat = $repeat_tests{$i}; 1834a57419b3SSteven Rostedt doprint " ITERATE $repeat"; 1835a57419b3SSteven Rostedt } 1836a57419b3SSteven Rostedt doprint "\n"; 1837a57419b3SSteven Rostedt } 1838a57419b3SSteven Rostedt 18392b7d9b21SSteven Rostedt foreach my $option (sort keys %opt) { 1840a57419b3SSteven Rostedt 1841a57419b3SSteven Rostedt if ($option =~ /\[(\d+)\]$/) { 1842a57419b3SSteven Rostedt next if ($i != $1); 1843a57419b3SSteven Rostedt } else { 1844a57419b3SSteven Rostedt next if ($i); 1845a57419b3SSteven Rostedt } 1846a57419b3SSteven Rostedt 18472b7d9b21SSteven Rostedt doprint "$option = $opt{$option}\n"; 18482b7d9b21SSteven Rostedt } 1849a57419b3SSteven Rostedt} 18502545eb61SSteven Rostedt 1851a75fececSSteven Rostedtsub set_test_option { 18525a391fbfSSteven Rostedt my ($name, $i) = @_; 18535a391fbfSSteven Rostedt 18545a391fbfSSteven Rostedt my $option = "$name\[$i\]"; 18555a391fbfSSteven Rostedt 18565a391fbfSSteven Rostedt if (defined($opt{$option})) { 18575a391fbfSSteven Rostedt return $opt{$option}; 18585a391fbfSSteven Rostedt } 18595a391fbfSSteven Rostedt 1860a57419b3SSteven Rostedt foreach my $test (keys %repeat_tests) { 1861a57419b3SSteven Rostedt if ($i >= $test && 1862a57419b3SSteven Rostedt $i < $test + $repeat_tests{$test}) { 1863a57419b3SSteven Rostedt $option = "$name\[$test\]"; 1864a57419b3SSteven Rostedt if (defined($opt{$option})) { 1865a57419b3SSteven Rostedt return $opt{$option}; 1866a57419b3SSteven Rostedt } 1867a57419b3SSteven Rostedt } 1868a57419b3SSteven Rostedt } 1869a57419b3SSteven Rostedt 18705a391fbfSSteven Rostedt if (defined($opt{$name})) { 18715a391fbfSSteven Rostedt return $opt{$name}; 18725a391fbfSSteven Rostedt } 18735a391fbfSSteven Rostedt 18745a391fbfSSteven Rostedt return undef; 18755a391fbfSSteven Rostedt} 18765a391fbfSSteven Rostedt 18772545eb61SSteven Rostedt# First we need to do is the builds 1878a75fececSSteven Rostedtfor (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) { 18792545eb61SSteven Rostedt 1880576f627cSSteven Rostedt $iteration = $i; 1881576f627cSSteven Rostedt 1882a75fececSSteven Rostedt my $makecmd = set_test_option("MAKE_CMD", $i); 1883a75fececSSteven Rostedt 1884a75fececSSteven Rostedt $machine = set_test_option("MACHINE", $i); 1885e48c5293SSteven Rostedt $ssh_user = set_test_option("SSH_USER", $i); 1886a75fececSSteven Rostedt $tmpdir = set_test_option("TMP_DIR", $i); 1887a75fececSSteven Rostedt $outputdir = set_test_option("OUTPUT_DIR", $i); 1888a75fececSSteven Rostedt $builddir = set_test_option("BUILD_DIR", $i); 1889a75fececSSteven Rostedt $test_type = set_test_option("TEST_TYPE", $i); 1890a75fececSSteven Rostedt $build_type = set_test_option("BUILD_TYPE", $i); 1891a75fececSSteven Rostedt $build_options = set_test_option("BUILD_OPTIONS", $i); 1892a75fececSSteven Rostedt $power_cycle = set_test_option("POWER_CYCLE", $i); 1893e48c5293SSteven Rostedt $reboot = set_test_option("REBOOT", $i); 1894a75fececSSteven Rostedt $noclean = set_test_option("BUILD_NOCLEAN", $i); 1895a75fececSSteven Rostedt $minconfig = set_test_option("MIN_CONFIG", $i); 1896a75fececSSteven Rostedt $run_test = set_test_option("TEST", $i); 1897a75fececSSteven Rostedt $addconfig = set_test_option("ADD_CONFIG", $i); 1898a75fececSSteven Rostedt $reboot_type = set_test_option("REBOOT_TYPE", $i); 1899a75fececSSteven Rostedt $grub_menu = set_test_option("GRUB_MENU", $i); 19008b37ca8cSSteven Rostedt $post_install = set_test_option("POST_INSTALL", $i); 1901a75fececSSteven Rostedt $reboot_script = set_test_option("REBOOT_SCRIPT", $i); 1902a75fececSSteven Rostedt $reboot_on_error = set_test_option("REBOOT_ON_ERROR", $i); 1903a75fececSSteven Rostedt $poweroff_on_error = set_test_option("POWEROFF_ON_ERROR", $i); 1904a75fececSSteven Rostedt $die_on_failure = set_test_option("DIE_ON_FAILURE", $i); 1905a75fececSSteven Rostedt $power_off = set_test_option("POWER_OFF", $i); 1906576f627cSSteven Rostedt $powercycle_after_reboot = set_test_option("POWERCYCLE_AFTER_REBOOT", $i); 1907576f627cSSteven Rostedt $poweroff_after_halt = set_test_option("POWEROFF_AFTER_HALT", $i); 1908a75fececSSteven Rostedt $sleep_time = set_test_option("SLEEP_TIME", $i); 1909a75fececSSteven Rostedt $bisect_sleep_time = set_test_option("BISECT_SLEEP_TIME", $i); 1910a75fececSSteven Rostedt $store_failures = set_test_option("STORE_FAILURES", $i); 1911a75fececSSteven Rostedt $timeout = set_test_option("TIMEOUT", $i); 1912a75fececSSteven Rostedt $booted_timeout = set_test_option("BOOTED_TIMEOUT", $i); 1913a75fececSSteven Rostedt $console = set_test_option("CONSOLE", $i); 1914a75fececSSteven Rostedt $success_line = set_test_option("SUCCESS_LINE", $i); 19151c8a617aSSteven Rostedt $stop_after_success = set_test_option("STOP_AFTER_SUCCESS", $i); 19161c8a617aSSteven Rostedt $stop_after_failure = set_test_option("STOP_AFTER_FAILURE", $i); 1917a75fececSSteven Rostedt $build_target = set_test_option("BUILD_TARGET", $i); 1918e48c5293SSteven Rostedt $ssh_exec = set_test_option("SSH_EXEC", $i); 1919e48c5293SSteven Rostedt $scp_to_target = set_test_option("SCP_TO_TARGET", $i); 1920a75fececSSteven Rostedt $target_image = set_test_option("TARGET_IMAGE", $i); 1921a75fececSSteven Rostedt $localversion = set_test_option("LOCALVERSION", $i); 1922a75fececSSteven Rostedt 1923a75fececSSteven Rostedt chdir $builddir || die "can't change directory to $builddir"; 1924a75fececSSteven Rostedt 1925a75fececSSteven Rostedt if (!-d $tmpdir) { 1926a75fececSSteven Rostedt mkpath($tmpdir) or 1927a75fececSSteven Rostedt die "can't create $tmpdir"; 1928a75fececSSteven Rostedt } 1929a75fececSSteven Rostedt 1930e48c5293SSteven Rostedt $ENV{"SSH_USER"} = $ssh_user; 1931e48c5293SSteven Rostedt $ENV{"MACHINE"} = $machine; 1932e48c5293SSteven Rostedt 1933a75fececSSteven Rostedt $target = "$ssh_user\@$machine"; 1934a75fececSSteven Rostedt 1935a75fececSSteven Rostedt $buildlog = "$tmpdir/buildlog-$machine"; 1936a75fececSSteven Rostedt $dmesg = "$tmpdir/dmesg-$machine"; 1937a75fececSSteven Rostedt $make = "$makecmd O=$outputdir"; 193851ad1dd1SSteven Rostedt $output_config = "$outputdir/.config"; 1939a75fececSSteven Rostedt 1940a75fececSSteven Rostedt if ($reboot_type eq "grub") { 1941576f627cSSteven Rostedt dodie "GRUB_MENU not defined" if (!defined($grub_menu)); 1942a75fececSSteven Rostedt } elsif (!defined($reboot_script)) { 1943576f627cSSteven Rostedt dodie "REBOOT_SCRIPT not defined" 1944a75fececSSteven Rostedt } 1945a75fececSSteven Rostedt 1946a75fececSSteven Rostedt my $run_type = $build_type; 1947a75fececSSteven Rostedt if ($test_type eq "patchcheck") { 1948a75fececSSteven Rostedt $run_type = $opt{"PATCHCHECK_TYPE[$i]"}; 1949a75fececSSteven Rostedt } elsif ($test_type eq "bisect") { 1950a75fececSSteven Rostedt $run_type = $opt{"BISECT_TYPE[$i]"}; 19510a05c769SSteven Rostedt } elsif ($test_type eq "config_bisect") { 19520a05c769SSteven Rostedt $run_type = $opt{"CONFIG_BISECT_TYPE[$i]"}; 1953a75fececSSteven Rostedt } 1954a75fececSSteven Rostedt 1955a75fececSSteven Rostedt # mistake in config file? 1956a75fececSSteven Rostedt if (!defined($run_type)) { 1957a75fececSSteven Rostedt $run_type = "ERROR"; 1958a75fececSSteven Rostedt } 19592545eb61SSteven Rostedt 19602545eb61SSteven Rostedt doprint "\n\n"; 1961a75fececSSteven Rostedt doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type\n\n"; 19627faafbd6SSteven Rostedt 19637faafbd6SSteven Rostedt unlink $dmesg; 19647faafbd6SSteven Rostedt unlink $buildlog; 19652545eb61SSteven Rostedt 19662b7d9b21SSteven Rostedt if (!defined($minconfig)) { 19672b7d9b21SSteven Rostedt $minconfig = $addconfig; 19682b7d9b21SSteven Rostedt 19692b7d9b21SSteven Rostedt } elsif (defined($addconfig)) { 19709be2e6b5SSteven Rostedt run_command "cat $addconfig $minconfig > $tmpdir/add_config" or 19712b7d9b21SSteven Rostedt dodie "Failed to create temp config"; 19729be2e6b5SSteven Rostedt $minconfig = "$tmpdir/add_config"; 19732b7d9b21SSteven Rostedt } 19742b7d9b21SSteven Rostedt 19756c5ee0beSSteven Rostedt my $checkout = $opt{"CHECKOUT[$i]"}; 19766c5ee0beSSteven Rostedt if (defined($checkout)) { 19776c5ee0beSSteven Rostedt run_command "git checkout $checkout" or 19786c5ee0beSSteven Rostedt die "failed to checkout $checkout"; 19796c5ee0beSSteven Rostedt } 19806c5ee0beSSteven Rostedt 1981a75fececSSteven Rostedt if ($test_type eq "bisect") { 19825f9b6cedSSteven Rostedt bisect $i; 19835f9b6cedSSteven Rostedt next; 19840a05c769SSteven Rostedt } elsif ($test_type eq "config_bisect") { 19850a05c769SSteven Rostedt config_bisect $i; 19860a05c769SSteven Rostedt next; 1987a75fececSSteven Rostedt } elsif ($test_type eq "patchcheck") { 19886c5ee0beSSteven Rostedt patchcheck $i; 19896c5ee0beSSteven Rostedt next; 19905f9b6cedSSteven Rostedt } 19915f9b6cedSSteven Rostedt 19927faafbd6SSteven Rostedt if ($build_type ne "nobuild") { 19937faafbd6SSteven Rostedt build $build_type or next; 19942545eb61SSteven Rostedt } 19952545eb61SSteven Rostedt 1996a75fececSSteven Rostedt if ($test_type ne "build") { 19975f9b6cedSSteven Rostedt get_grub_index; 19985f9b6cedSSteven Rostedt get_version; 19992545eb61SSteven Rostedt install; 20005a391fbfSSteven Rostedt 20017faafbd6SSteven Rostedt my $failed = 0; 20027faafbd6SSteven Rostedt start_monitor; 20037faafbd6SSteven Rostedt monitor or $failed = 1;; 2004a75fececSSteven Rostedt 2005a75fececSSteven Rostedt if (!$failed && $test_type ne "boot" && defined($run_test)) { 20067faafbd6SSteven Rostedt do_run_test or $failed = 1; 20075a391fbfSSteven Rostedt } 20087faafbd6SSteven Rostedt end_monitor; 20097faafbd6SSteven Rostedt next if ($failed); 2010a75fececSSteven Rostedt } 20115a391fbfSSteven Rostedt 20125f9b6cedSSteven Rostedt success $i; 201375c3fda7SSteven Rostedt} 20142545eb61SSteven Rostedt 20155c42fc5bSSteven Rostedtif ($opt{"POWEROFF_ON_SUCCESS"}) { 201675c3fda7SSteven Rostedt halt; 2017576f627cSSteven Rostedt} elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot) { 201875c3fda7SSteven Rostedt reboot; 20195c42fc5bSSteven Rostedt} 202075c3fda7SSteven Rostedt 2021e48c5293SSteven Rostedtdoprint "\n $successes of $opt{NUM_TESTS} tests were successful\n\n"; 2022e48c5293SSteven Rostedt 20232545eb61SSteven Rostedtexit 0; 2024