12545eb61SSteven Rostedt#!/usr/bin/perl -w 2d6ce2a0bSSteven Rostedt# 3cce1dac8SUwe Kleine-König# Copyright 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; 25bb8474b1SSteven Rostedt$default{"TEST_TYPE"} = "build"; 26a75fececSSteven Rostedt$default{"BUILD_TYPE"} = "randconfig"; 27a75fececSSteven Rostedt$default{"MAKE_CMD"} = "make"; 28a75fececSSteven Rostedt$default{"TIMEOUT"} = 120; 2948920630SSteven Rostedt$default{"TMP_DIR"} = "/tmp/ktest/\${MACHINE}"; 30a75fececSSteven Rostedt$default{"SLEEP_TIME"} = 60; # sleep time between tests 31a75fececSSteven Rostedt$default{"BUILD_NOCLEAN"} = 0; 32a75fececSSteven Rostedt$default{"REBOOT_ON_ERROR"} = 0; 33a75fececSSteven Rostedt$default{"POWEROFF_ON_ERROR"} = 0; 34a75fececSSteven Rostedt$default{"REBOOT_ON_SUCCESS"} = 1; 35a75fececSSteven Rostedt$default{"POWEROFF_ON_SUCCESS"} = 0; 36a75fececSSteven Rostedt$default{"BUILD_OPTIONS"} = ""; 37a75fececSSteven Rostedt$default{"BISECT_SLEEP_TIME"} = 60; # sleep time between bisects 3827d934b2SSteven Rostedt$default{"PATCHCHECK_SLEEP_TIME"} = 60; # sleep time between patch checks 39a75fececSSteven Rostedt$default{"CLEAR_LOG"} = 0; 40c960bb9fSSteven Rostedt$default{"BISECT_MANUAL"} = 0; 41c23dca7cSSteven Rostedt$default{"BISECT_SKIP"} = 1; 42a75fececSSteven Rostedt$default{"SUCCESS_LINE"} = "login:"; 43f1a5b962SSteven Rostedt$default{"DETECT_TRIPLE_FAULT"} = 1; 44e0a8742eSSteven Rostedt$default{"NO_INSTALL"} = 0; 45a75fececSSteven Rostedt$default{"BOOTED_TIMEOUT"} = 1; 46a75fececSSteven Rostedt$default{"DIE_ON_FAILURE"} = 1; 47e48c5293SSteven Rostedt$default{"SSH_EXEC"} = "ssh \$SSH_USER\@\$MACHINE \$SSH_COMMAND"; 48e48c5293SSteven Rostedt$default{"SCP_TO_TARGET"} = "scp \$SRC_FILE \$SSH_USER\@\$MACHINE:\$DST_FILE"; 49e48c5293SSteven Rostedt$default{"REBOOT"} = "ssh \$SSH_USER\@\$MACHINE reboot"; 501c8a617aSSteven Rostedt$default{"STOP_AFTER_SUCCESS"} = 10; 511c8a617aSSteven Rostedt$default{"STOP_AFTER_FAILURE"} = 60; 522d01b26aSSteven Rostedt$default{"STOP_TEST_AFTER"} = 600; 53600bbf0aSSteven Rostedt 54600bbf0aSSteven Rostedt# required, and we will ask users if they don't have them but we keep the default 55600bbf0aSSteven Rostedt# value something that is common. 56600bbf0aSSteven Rostedt$default{"REBOOT_TYPE"} = "grub"; 578d1491baSSteven Rostedt$default{"LOCALVERSION"} = "-test"; 58600bbf0aSSteven Rostedt$default{"SSH_USER"} = "root"; 59600bbf0aSSteven Rostedt$default{"BUILD_TARGET"} = "arch/x86/boot/bzImage"; 60600bbf0aSSteven Rostedt$default{"TARGET_IMAGE"} = "/boot/vmlinuz-test"; 612545eb61SSteven Rostedt 628d1491baSSteven Rostedtmy $ktest_config; 632545eb61SSteven Rostedtmy $version; 64a75fececSSteven Rostedtmy $machine; 65e48c5293SSteven Rostedtmy $ssh_user; 66a75fececSSteven Rostedtmy $tmpdir; 67a75fececSSteven Rostedtmy $builddir; 68a75fececSSteven Rostedtmy $outputdir; 6951ad1dd1SSteven Rostedtmy $output_config; 70a75fececSSteven Rostedtmy $test_type; 717faafbd6SSteven Rostedtmy $build_type; 72a75fececSSteven Rostedtmy $build_options; 730bd6c1a3SSteven Rostedtmy $pre_build; 740bd6c1a3SSteven Rostedtmy $post_build; 750bd6c1a3SSteven Rostedtmy $pre_build_die; 760bd6c1a3SSteven Rostedtmy $post_build_die; 77a75fececSSteven Rostedtmy $reboot_type; 78a75fececSSteven Rostedtmy $reboot_script; 79a75fececSSteven Rostedtmy $power_cycle; 80e48c5293SSteven Rostedtmy $reboot; 81a75fececSSteven Rostedtmy $reboot_on_error; 82a75fececSSteven Rostedtmy $poweroff_on_error; 83a75fececSSteven Rostedtmy $die_on_failure; 84576f627cSSteven Rostedtmy $powercycle_after_reboot; 85576f627cSSteven Rostedtmy $poweroff_after_halt; 86e48c5293SSteven Rostedtmy $ssh_exec; 87e48c5293SSteven Rostedtmy $scp_to_target; 88a75fececSSteven Rostedtmy $power_off; 89a75fececSSteven Rostedtmy $grub_menu; 902545eb61SSteven Rostedtmy $grub_number; 912545eb61SSteven Rostedtmy $target; 922545eb61SSteven Rostedtmy $make; 938b37ca8cSSteven Rostedtmy $post_install; 94e0a8742eSSteven Rostedtmy $no_install; 955c42fc5bSSteven Rostedtmy $noclean; 965f9b6cedSSteven Rostedtmy $minconfig; 974c4ab120SSteven Rostedtmy $start_minconfig; 9835ce5952SSteven Rostedtmy $start_minconfig_defined; 994c4ab120SSteven Rostedtmy $output_minconfig; 1004c4ab120SSteven Rostedtmy $ignore_config; 1012b7d9b21SSteven Rostedtmy $addconfig; 1025f9b6cedSSteven Rostedtmy $in_bisect = 0; 1035f9b6cedSSteven Rostedtmy $bisect_bad = ""; 104d6ce2a0bSSteven Rostedtmy $reverse_bisect; 105c960bb9fSSteven Rostedtmy $bisect_manual; 106c23dca7cSSteven Rostedtmy $bisect_skip; 10730f75da5SSteven Rostedtmy $config_bisect_good; 1086c5ee0beSSteven Rostedtmy $in_patchcheck = 0; 1095a391fbfSSteven Rostedtmy $run_test; 1106c5ee0beSSteven Rostedtmy $redirect; 1117faafbd6SSteven Rostedtmy $buildlog; 112a9dd5d63SRabin Vincentmy $testlog; 1137faafbd6SSteven Rostedtmy $dmesg; 1147faafbd6SSteven Rostedtmy $monitor_fp; 1157faafbd6SSteven Rostedtmy $monitor_pid; 1167faafbd6SSteven Rostedtmy $monitor_cnt = 0; 117a75fececSSteven Rostedtmy $sleep_time; 118a75fececSSteven Rostedtmy $bisect_sleep_time; 11927d934b2SSteven Rostedtmy $patchcheck_sleep_time; 1201990207dSSteven Rostedtmy $ignore_warnings; 121a75fececSSteven Rostedtmy $store_failures; 122de5b6e3bSRabin Vincentmy $store_successes; 1239064af52SSteven Rostedtmy $test_name; 124a75fececSSteven Rostedtmy $timeout; 125a75fececSSteven Rostedtmy $booted_timeout; 126f1a5b962SSteven Rostedtmy $detect_triplefault; 127a75fececSSteven Rostedtmy $console; 1282b803365SSteven Rostedtmy $reboot_success_line; 129a75fececSSteven Rostedtmy $success_line; 1301c8a617aSSteven Rostedtmy $stop_after_success; 1311c8a617aSSteven Rostedtmy $stop_after_failure; 1322d01b26aSSteven Rostedtmy $stop_test_after; 133a75fececSSteven Rostedtmy $build_target; 134a75fececSSteven Rostedtmy $target_image; 135a75fececSSteven Rostedtmy $localversion; 136576f627cSSteven Rostedtmy $iteration = 0; 137e48c5293SSteven Rostedtmy $successes = 0; 1382545eb61SSteven Rostedt 139165708b2SSteven Rostedt# set when a test is something other that just building or install 140bb8474b1SSteven Rostedt# which would require more options. 141bb8474b1SSteven Rostedtmy $buildonly = 1; 142bb8474b1SSteven Rostedt 143dbd3783bSSteven Rostedt# set when creating a new config 144dbd3783bSSteven Rostedtmy $newconfig = 0; 145dbd3783bSSteven Rostedt 1468d1491baSSteven Rostedtmy %entered_configs; 1478d1491baSSteven Rostedtmy %config_help; 14877d942ceSSteven Rostedtmy %variable; 149fcb3f16aSSteven Rostedtmy %force_config; 1508d1491baSSteven Rostedt 1514ab1cce5SSteven Rostedt# do not force reboots on config problems 1524ab1cce5SSteven Rostedtmy $no_reboot = 1; 1534ab1cce5SSteven Rostedt 1547bf51073SSteven Rostedt# default variables that can be used 1557bf51073SSteven Rostedtchomp ($variable{"PWD"} = `pwd`); 1567bf51073SSteven Rostedt 1578d1491baSSteven Rostedt$config_help{"MACHINE"} = << "EOF" 1588d1491baSSteven Rostedt The machine hostname that you will test. 159bb8474b1SSteven Rostedt For build only tests, it is still needed to differentiate log files. 1608d1491baSSteven RostedtEOF 1618d1491baSSteven Rostedt ; 1628d1491baSSteven Rostedt$config_help{"SSH_USER"} = << "EOF" 1638d1491baSSteven Rostedt The box is expected to have ssh on normal bootup, provide the user 1648d1491baSSteven Rostedt (most likely root, since you need privileged operations) 1658d1491baSSteven RostedtEOF 1668d1491baSSteven Rostedt ; 1678d1491baSSteven Rostedt$config_help{"BUILD_DIR"} = << "EOF" 1688d1491baSSteven Rostedt The directory that contains the Linux source code (full path). 1690e7a22deSSteven Rostedt You can use \${PWD} that will be the path where ktest.pl is run, or use 1700e7a22deSSteven Rostedt \${THIS_DIR} which is assigned \${PWD} but may be changed later. 1718d1491baSSteven RostedtEOF 1728d1491baSSteven Rostedt ; 1738d1491baSSteven Rostedt$config_help{"OUTPUT_DIR"} = << "EOF" 1748d1491baSSteven Rostedt The directory that the objects will be built (full path). 1758d1491baSSteven Rostedt (can not be same as BUILD_DIR) 1760e7a22deSSteven Rostedt You can use \${PWD} that will be the path where ktest.pl is run, or use 1770e7a22deSSteven Rostedt \${THIS_DIR} which is assigned \${PWD} but may be changed later. 1788d1491baSSteven RostedtEOF 1798d1491baSSteven Rostedt ; 1808d1491baSSteven Rostedt$config_help{"BUILD_TARGET"} = << "EOF" 1818d1491baSSteven Rostedt The location of the compiled file to copy to the target. 1828d1491baSSteven Rostedt (relative to OUTPUT_DIR) 1838d1491baSSteven RostedtEOF 1848d1491baSSteven Rostedt ; 185dbd3783bSSteven Rostedt$config_help{"BUILD_OPTIONS"} = << "EOF" 186dbd3783bSSteven Rostedt Options to add to \"make\" when building. 187dbd3783bSSteven Rostedt i.e. -j20 188dbd3783bSSteven RostedtEOF 189dbd3783bSSteven Rostedt ; 1908d1491baSSteven Rostedt$config_help{"TARGET_IMAGE"} = << "EOF" 1918d1491baSSteven Rostedt The place to put your image on the test machine. 1928d1491baSSteven RostedtEOF 1938d1491baSSteven Rostedt ; 1948d1491baSSteven Rostedt$config_help{"POWER_CYCLE"} = << "EOF" 1958d1491baSSteven Rostedt A script or command to reboot the box. 1968d1491baSSteven Rostedt 1978d1491baSSteven Rostedt Here is a digital loggers power switch example 1988d1491baSSteven Rostedt POWER_CYCLE = wget --no-proxy -O /dev/null -q --auth-no-challenge 'http://admin:admin\@power/outlet?5=CCL' 1998d1491baSSteven Rostedt 2008d1491baSSteven Rostedt Here is an example to reboot a virtual box on the current host 2018d1491baSSteven Rostedt with the name "Guest". 2028d1491baSSteven Rostedt POWER_CYCLE = virsh destroy Guest; sleep 5; virsh start Guest 2038d1491baSSteven RostedtEOF 2048d1491baSSteven Rostedt ; 2058d1491baSSteven Rostedt$config_help{"CONSOLE"} = << "EOF" 2068d1491baSSteven Rostedt The script or command that reads the console 2078d1491baSSteven Rostedt 2088d1491baSSteven Rostedt If you use ttywatch server, something like the following would work. 2098d1491baSSteven RostedtCONSOLE = nc -d localhost 3001 2108d1491baSSteven Rostedt 2118d1491baSSteven Rostedt For a virtual machine with guest name "Guest". 2128d1491baSSteven RostedtCONSOLE = virsh console Guest 2138d1491baSSteven RostedtEOF 2148d1491baSSteven Rostedt ; 2158d1491baSSteven Rostedt$config_help{"LOCALVERSION"} = << "EOF" 2168d1491baSSteven Rostedt Required version ending to differentiate the test 2178d1491baSSteven Rostedt from other linux builds on the system. 2188d1491baSSteven RostedtEOF 2198d1491baSSteven Rostedt ; 2208d1491baSSteven Rostedt$config_help{"REBOOT_TYPE"} = << "EOF" 2218d1491baSSteven Rostedt Way to reboot the box to the test kernel. 2228d1491baSSteven Rostedt Only valid options so far are "grub" and "script". 2238d1491baSSteven Rostedt 2248d1491baSSteven Rostedt If you specify grub, it will assume grub version 1 2258d1491baSSteven Rostedt and will search in /boot/grub/menu.lst for the title \$GRUB_MENU 2268d1491baSSteven Rostedt and select that target to reboot to the kernel. If this is not 2278d1491baSSteven Rostedt your setup, then specify "script" and have a command or script 2288d1491baSSteven Rostedt specified in REBOOT_SCRIPT to boot to the target. 2298d1491baSSteven Rostedt 2308d1491baSSteven Rostedt The entry in /boot/grub/menu.lst must be entered in manually. 2318d1491baSSteven Rostedt The test will not modify that file. 2328d1491baSSteven RostedtEOF 2338d1491baSSteven Rostedt ; 2348d1491baSSteven Rostedt$config_help{"GRUB_MENU"} = << "EOF" 2358d1491baSSteven Rostedt The grub title name for the test kernel to boot 2368d1491baSSteven Rostedt (Only mandatory if REBOOT_TYPE = grub) 2378d1491baSSteven Rostedt 2388d1491baSSteven Rostedt Note, ktest.pl will not update the grub menu.lst, you need to 2398d1491baSSteven Rostedt manually add an option for the test. ktest.pl will search 2408d1491baSSteven Rostedt the grub menu.lst for this option to find what kernel to 2418d1491baSSteven Rostedt reboot into. 2428d1491baSSteven Rostedt 2438d1491baSSteven Rostedt For example, if in the /boot/grub/menu.lst the test kernel title has: 2448d1491baSSteven Rostedt title Test Kernel 2458d1491baSSteven Rostedt kernel vmlinuz-test 2468d1491baSSteven Rostedt GRUB_MENU = Test Kernel 2478d1491baSSteven RostedtEOF 2488d1491baSSteven Rostedt ; 2498d1491baSSteven Rostedt$config_help{"REBOOT_SCRIPT"} = << "EOF" 2508d1491baSSteven Rostedt A script to reboot the target into the test kernel 2518d1491baSSteven Rostedt (Only mandatory if REBOOT_TYPE = script) 2528d1491baSSteven RostedtEOF 2538d1491baSSteven Rostedt ; 2548d1491baSSteven Rostedt 255dad98754SSteven Rostedtsub read_prompt { 256dad98754SSteven Rostedt my ($cancel, $prompt) = @_; 25735ce5952SSteven Rostedt 25835ce5952SSteven Rostedt my $ans; 25935ce5952SSteven Rostedt 26035ce5952SSteven Rostedt for (;;) { 261dad98754SSteven Rostedt if ($cancel) { 262dad98754SSteven Rostedt print "$prompt [y/n/C] "; 263dad98754SSteven Rostedt } else { 26435ce5952SSteven Rostedt print "$prompt [Y/n] "; 265dad98754SSteven Rostedt } 26635ce5952SSteven Rostedt $ans = <STDIN>; 26735ce5952SSteven Rostedt chomp $ans; 26835ce5952SSteven Rostedt if ($ans =~ /^\s*$/) { 269dad98754SSteven Rostedt if ($cancel) { 270dad98754SSteven Rostedt $ans = "c"; 271dad98754SSteven Rostedt } else { 27235ce5952SSteven Rostedt $ans = "y"; 27335ce5952SSteven Rostedt } 274dad98754SSteven Rostedt } 27535ce5952SSteven Rostedt last if ($ans =~ /^y$/i || $ans =~ /^n$/i); 276dad98754SSteven Rostedt if ($cancel) { 277dad98754SSteven Rostedt last if ($ans =~ /^c$/i); 278dad98754SSteven Rostedt print "Please answer either 'y', 'n' or 'c'.\n"; 279dad98754SSteven Rostedt } else { 28035ce5952SSteven Rostedt print "Please answer either 'y' or 'n'.\n"; 28135ce5952SSteven Rostedt } 282dad98754SSteven Rostedt } 283dad98754SSteven Rostedt if ($ans =~ /^c/i) { 284dad98754SSteven Rostedt exit; 285dad98754SSteven Rostedt } 28635ce5952SSteven Rostedt if ($ans !~ /^y$/i) { 28735ce5952SSteven Rostedt return 0; 28835ce5952SSteven Rostedt } 28935ce5952SSteven Rostedt return 1; 29035ce5952SSteven Rostedt} 2918d1491baSSteven Rostedt 292dad98754SSteven Rostedtsub read_yn { 293dad98754SSteven Rostedt my ($prompt) = @_; 294dad98754SSteven Rostedt 295dad98754SSteven Rostedt return read_prompt 0, $prompt; 296dad98754SSteven Rostedt} 297dad98754SSteven Rostedt 298dad98754SSteven Rostedtsub read_ync { 299dad98754SSteven Rostedt my ($prompt) = @_; 300dad98754SSteven Rostedt 301dad98754SSteven Rostedt return read_prompt 1, $prompt; 302dad98754SSteven Rostedt} 303dad98754SSteven Rostedt 3048d1491baSSteven Rostedtsub get_ktest_config { 3058d1491baSSteven Rostedt my ($config) = @_; 306815e2bd7SSteven Rostedt my $ans; 3078d1491baSSteven Rostedt 3088d1491baSSteven Rostedt return if (defined($opt{$config})); 3098d1491baSSteven Rostedt 3108d1491baSSteven Rostedt if (defined($config_help{$config})) { 3118d1491baSSteven Rostedt print "\n"; 3128d1491baSSteven Rostedt print $config_help{$config}; 3138d1491baSSteven Rostedt } 3148d1491baSSteven Rostedt 3158d1491baSSteven Rostedt for (;;) { 3168d1491baSSteven Rostedt print "$config = "; 317dbd3783bSSteven Rostedt if (defined($default{$config}) && length($default{$config})) { 3188d1491baSSteven Rostedt print "\[$default{$config}\] "; 3198d1491baSSteven Rostedt } 320815e2bd7SSteven Rostedt $ans = <STDIN>; 321815e2bd7SSteven Rostedt $ans =~ s/^\s*(.*\S)\s*$/$1/; 322815e2bd7SSteven Rostedt if ($ans =~ /^\s*$/) { 3238d1491baSSteven Rostedt if ($default{$config}) { 324815e2bd7SSteven Rostedt $ans = $default{$config}; 3258d1491baSSteven Rostedt } else { 3268d1491baSSteven Rostedt print "Your answer can not be blank\n"; 3278d1491baSSteven Rostedt next; 3288d1491baSSteven Rostedt } 3298d1491baSSteven Rostedt } 3300e7a22deSSteven Rostedt $entered_configs{$config} = ${ans}; 3318d1491baSSteven Rostedt last; 3328d1491baSSteven Rostedt } 3338d1491baSSteven Rostedt} 3348d1491baSSteven Rostedt 3358d1491baSSteven Rostedtsub get_ktest_configs { 3368d1491baSSteven Rostedt get_ktest_config("MACHINE"); 3378d1491baSSteven Rostedt get_ktest_config("BUILD_DIR"); 3388d1491baSSteven Rostedt get_ktest_config("OUTPUT_DIR"); 339bb8474b1SSteven Rostedt 340dbd3783bSSteven Rostedt if ($newconfig) { 341dbd3783bSSteven Rostedt get_ktest_config("BUILD_OPTIONS"); 342dbd3783bSSteven Rostedt } 343dbd3783bSSteven Rostedt 344bb8474b1SSteven Rostedt # options required for other than just building a kernel 345bb8474b1SSteven Rostedt if (!$buildonly) { 346165708b2SSteven Rostedt get_ktest_config("POWER_CYCLE"); 347165708b2SSteven Rostedt get_ktest_config("CONSOLE"); 348165708b2SSteven Rostedt } 349165708b2SSteven Rostedt 350165708b2SSteven Rostedt # options required for install and more 351165708b2SSteven Rostedt if ($buildonly != 1) { 352bb8474b1SSteven Rostedt get_ktest_config("SSH_USER"); 3538d1491baSSteven Rostedt get_ktest_config("BUILD_TARGET"); 3548d1491baSSteven Rostedt get_ktest_config("TARGET_IMAGE"); 355bb8474b1SSteven Rostedt } 356bb8474b1SSteven Rostedt 3578d1491baSSteven Rostedt get_ktest_config("LOCALVERSION"); 3588d1491baSSteven Rostedt 359bb8474b1SSteven Rostedt return if ($buildonly); 360bb8474b1SSteven Rostedt 3618d1491baSSteven Rostedt my $rtype = $opt{"REBOOT_TYPE"}; 3628d1491baSSteven Rostedt 3638d1491baSSteven Rostedt if (!defined($rtype)) { 3648d1491baSSteven Rostedt if (!defined($opt{"GRUB_MENU"})) { 3658d1491baSSteven Rostedt get_ktest_config("REBOOT_TYPE"); 3668d1491baSSteven Rostedt $rtype = $entered_configs{"REBOOT_TYPE"}; 3678d1491baSSteven Rostedt } else { 3688d1491baSSteven Rostedt $rtype = "grub"; 3698d1491baSSteven Rostedt } 3708d1491baSSteven Rostedt } 3718d1491baSSteven Rostedt 3728d1491baSSteven Rostedt if ($rtype eq "grub") { 3738d1491baSSteven Rostedt get_ktest_config("GRUB_MENU"); 3748d1491baSSteven Rostedt } else { 3758d1491baSSteven Rostedt get_ktest_config("REBOOT_SCRIPT"); 3768d1491baSSteven Rostedt } 3778d1491baSSteven Rostedt} 3788d1491baSSteven Rostedt 37977d942ceSSteven Rostedtsub process_variables { 3808d735212SSteven Rostedt my ($value, $remove_undef) = @_; 38177d942ceSSteven Rostedt my $retval = ""; 38277d942ceSSteven Rostedt 38377d942ceSSteven Rostedt # We want to check for '\', and it is just easier 38477d942ceSSteven Rostedt # to check the previous characet of '$' and not need 38577d942ceSSteven Rostedt # to worry if '$' is the first character. By adding 38677d942ceSSteven Rostedt # a space to $value, we can just check [^\\]\$ and 38777d942ceSSteven Rostedt # it will still work. 38877d942ceSSteven Rostedt $value = " $value"; 38977d942ceSSteven Rostedt 39077d942ceSSteven Rostedt while ($value =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) { 39177d942ceSSteven Rostedt my $begin = $1; 39277d942ceSSteven Rostedt my $var = $2; 39377d942ceSSteven Rostedt my $end = $3; 39477d942ceSSteven Rostedt # append beginning of value to retval 39577d942ceSSteven Rostedt $retval = "$retval$begin"; 39677d942ceSSteven Rostedt if (defined($variable{$var})) { 39777d942ceSSteven Rostedt $retval = "$retval$variable{$var}"; 3988d735212SSteven Rostedt } elsif (defined($remove_undef) && $remove_undef) { 3998d735212SSteven Rostedt # for if statements, any variable that is not defined, 4008d735212SSteven Rostedt # we simple convert to 0 4018d735212SSteven Rostedt $retval = "${retval}0"; 40277d942ceSSteven Rostedt } else { 40377d942ceSSteven Rostedt # put back the origin piece. 40477d942ceSSteven Rostedt $retval = "$retval\$\{$var\}"; 40577d942ceSSteven Rostedt } 40677d942ceSSteven Rostedt $value = $end; 40777d942ceSSteven Rostedt } 40877d942ceSSteven Rostedt $retval = "$retval$value"; 40977d942ceSSteven Rostedt 41077d942ceSSteven Rostedt # remove the space added in the beginning 41177d942ceSSteven Rostedt $retval =~ s/ //; 41277d942ceSSteven Rostedt 41377d942ceSSteven Rostedt return "$retval" 41477d942ceSSteven Rostedt} 41577d942ceSSteven Rostedt 416a57419b3SSteven Rostedtsub set_value { 4173d1cc414SSteven Rostedt my ($lvalue, $rvalue, $override, $overrides, $name) = @_; 4182545eb61SSteven Rostedt 419165708b2SSteven Rostedt if ($buildonly && $lvalue =~ /^TEST_TYPE(\[.*\])?$/ && $rvalue ne "build") { 420bb8474b1SSteven Rostedt # Note if a test is something other than build, then we 421bb8474b1SSteven Rostedt # will need other manditory options. 422165708b2SSteven Rostedt if ($rvalue ne "install") { 423bb8474b1SSteven Rostedt $buildonly = 0; 424165708b2SSteven Rostedt } else { 425165708b2SSteven Rostedt # install still limits some manditory options. 426165708b2SSteven Rostedt $buildonly = 2; 427165708b2SSteven Rostedt } 428bb8474b1SSteven Rostedt } 429bb8474b1SSteven Rostedt 430a75fececSSteven Rostedt if (defined($opt{$lvalue})) { 4313d1cc414SSteven Rostedt if (!$override || defined(${$overrides}{$lvalue})) { 4323d1cc414SSteven Rostedt my $extra = ""; 4333d1cc414SSteven Rostedt if ($override) { 4343d1cc414SSteven Rostedt $extra = "In the same override section!\n"; 4353d1cc414SSteven Rostedt } 4363d1cc414SSteven Rostedt die "$name: $.: Option $lvalue defined more than once!\n$extra"; 4373d1cc414SSteven Rostedt } 4383d1cc414SSteven Rostedt ${$overrides}{$lvalue} = $rvalue; 439a75fececSSteven Rostedt } 44021a9679fSSteven Rostedt if ($rvalue =~ /^\s*$/) { 44121a9679fSSteven Rostedt delete $opt{$lvalue}; 44221a9679fSSteven Rostedt } else { 44377d942ceSSteven Rostedt $rvalue = process_variables($rvalue); 44421a9679fSSteven Rostedt $opt{$lvalue} = $rvalue; 44521a9679fSSteven Rostedt } 4462545eb61SSteven Rostedt} 447a57419b3SSteven Rostedt 44877d942ceSSteven Rostedtsub set_variable { 44977d942ceSSteven Rostedt my ($lvalue, $rvalue) = @_; 45077d942ceSSteven Rostedt 45177d942ceSSteven Rostedt if ($rvalue =~ /^\s*$/) { 45277d942ceSSteven Rostedt delete $variable{$lvalue}; 45377d942ceSSteven Rostedt } else { 45477d942ceSSteven Rostedt $rvalue = process_variables($rvalue); 45577d942ceSSteven Rostedt $variable{$lvalue} = $rvalue; 45677d942ceSSteven Rostedt } 45777d942ceSSteven Rostedt} 45877d942ceSSteven Rostedt 459ab7a3f52SSteven Rostedtsub process_compare { 460ab7a3f52SSteven Rostedt my ($lval, $cmp, $rval) = @_; 461ab7a3f52SSteven Rostedt 462ab7a3f52SSteven Rostedt # remove whitespace 463ab7a3f52SSteven Rostedt 464ab7a3f52SSteven Rostedt $lval =~ s/^\s*//; 465ab7a3f52SSteven Rostedt $lval =~ s/\s*$//; 466ab7a3f52SSteven Rostedt 467ab7a3f52SSteven Rostedt $rval =~ s/^\s*//; 468ab7a3f52SSteven Rostedt $rval =~ s/\s*$//; 469ab7a3f52SSteven Rostedt 470ab7a3f52SSteven Rostedt if ($cmp eq "==") { 471ab7a3f52SSteven Rostedt return $lval eq $rval; 472ab7a3f52SSteven Rostedt } elsif ($cmp eq "!=") { 473ab7a3f52SSteven Rostedt return $lval ne $rval; 474ab7a3f52SSteven Rostedt } 475ab7a3f52SSteven Rostedt 476ab7a3f52SSteven Rostedt my $statement = "$lval $cmp $rval"; 477ab7a3f52SSteven Rostedt my $ret = eval $statement; 478ab7a3f52SSteven Rostedt 479ab7a3f52SSteven Rostedt # $@ stores error of eval 480ab7a3f52SSteven Rostedt if ($@) { 481ab7a3f52SSteven Rostedt return -1; 482ab7a3f52SSteven Rostedt } 483ab7a3f52SSteven Rostedt 484ab7a3f52SSteven Rostedt return $ret; 485ab7a3f52SSteven Rostedt} 486ab7a3f52SSteven Rostedt 4879900b5dcSSteven Rostedtsub value_defined { 4889900b5dcSSteven Rostedt my ($val) = @_; 4899900b5dcSSteven Rostedt 4909900b5dcSSteven Rostedt return defined($variable{$2}) || 4919900b5dcSSteven Rostedt defined($opt{$2}); 4929900b5dcSSteven Rostedt} 4939900b5dcSSteven Rostedt 4948d735212SSteven Rostedtmy $d = 0; 4958d735212SSteven Rostedtsub process_expression { 4968d735212SSteven Rostedt my ($name, $val) = @_; 49745d73a5dSSteven Rostedt 4988d735212SSteven Rostedt my $c = $d++; 4998d735212SSteven Rostedt 5008d735212SSteven Rostedt while ($val =~ s/\(([^\(]*?)\)/\&\&\&\&VAL\&\&\&\&/) { 5018d735212SSteven Rostedt my $express = $1; 5028d735212SSteven Rostedt 5038d735212SSteven Rostedt if (process_expression($name, $express)) { 5048d735212SSteven Rostedt $val =~ s/\&\&\&\&VAL\&\&\&\&/ 1 /; 5058d735212SSteven Rostedt } else { 5068d735212SSteven Rostedt $val =~ s/\&\&\&\&VAL\&\&\&\&/ 0 /; 5078d735212SSteven Rostedt } 5088d735212SSteven Rostedt } 5098d735212SSteven Rostedt 5108d735212SSteven Rostedt $d--; 5118d735212SSteven Rostedt my $OR = "\\|\\|"; 5128d735212SSteven Rostedt my $AND = "\\&\\&"; 5138d735212SSteven Rostedt 5148d735212SSteven Rostedt while ($val =~ s/^(.*?)($OR|$AND)//) { 5158d735212SSteven Rostedt my $express = $1; 5168d735212SSteven Rostedt my $op = $2; 5178d735212SSteven Rostedt 5188d735212SSteven Rostedt if (process_expression($name, $express)) { 5198d735212SSteven Rostedt if ($op eq "||") { 5208d735212SSteven Rostedt return 1; 5218d735212SSteven Rostedt } 5228d735212SSteven Rostedt } else { 5238d735212SSteven Rostedt if ($op eq "&&") { 5248d735212SSteven Rostedt return 0; 5258d735212SSteven Rostedt } 5268d735212SSteven Rostedt } 5278d735212SSteven Rostedt } 52845d73a5dSSteven Rostedt 529ab7a3f52SSteven Rostedt if ($val =~ /(.*)(==|\!=|>=|<=|>|<)(.*)/) { 530ab7a3f52SSteven Rostedt my $ret = process_compare($1, $2, $3); 531ab7a3f52SSteven Rostedt if ($ret < 0) { 532ab7a3f52SSteven Rostedt die "$name: $.: Unable to process comparison\n"; 533ab7a3f52SSteven Rostedt } 534ab7a3f52SSteven Rostedt return $ret; 535ab7a3f52SSteven Rostedt } 536ab7a3f52SSteven Rostedt 5379900b5dcSSteven Rostedt if ($val =~ /^\s*(NOT\s*)?DEFINED\s+(\S+)\s*$/) { 5389900b5dcSSteven Rostedt if (defined $1) { 5399900b5dcSSteven Rostedt return !value_defined($2); 5409900b5dcSSteven Rostedt } else { 5419900b5dcSSteven Rostedt return value_defined($2); 5429900b5dcSSteven Rostedt } 5439900b5dcSSteven Rostedt } 5449900b5dcSSteven Rostedt 54545d73a5dSSteven Rostedt if ($val =~ /^\s*0\s*$/) { 54645d73a5dSSteven Rostedt return 0; 54745d73a5dSSteven Rostedt } elsif ($val =~ /^\s*\d+\s*$/) { 54845d73a5dSSteven Rostedt return 1; 54945d73a5dSSteven Rostedt } 55045d73a5dSSteven Rostedt 5519900b5dcSSteven Rostedt die ("$name: $.: Undefined content $val in if statement\n"); 5528d735212SSteven Rostedt} 5538d735212SSteven Rostedt 5548d735212SSteven Rostedtsub process_if { 5558d735212SSteven Rostedt my ($name, $value) = @_; 5568d735212SSteven Rostedt 5578d735212SSteven Rostedt # Convert variables and replace undefined ones with 0 5588d735212SSteven Rostedt my $val = process_variables($value, 1); 5598d735212SSteven Rostedt my $ret = process_expression $name, $val; 5608d735212SSteven Rostedt 5618d735212SSteven Rostedt return $ret; 56245d73a5dSSteven Rostedt} 56345d73a5dSSteven Rostedt 5642ed3b161SSteven Rostedtsub __read_config { 5652ed3b161SSteven Rostedt my ($config, $current_test_num) = @_; 566a57419b3SSteven Rostedt 5672ed3b161SSteven Rostedt my $in; 5682ed3b161SSteven Rostedt open($in, $config) || die "can't read file $config"; 569a57419b3SSteven Rostedt 570a57419b3SSteven Rostedt my $name = $config; 571a57419b3SSteven Rostedt $name =~ s,.*/(.*),$1,; 572a57419b3SSteven Rostedt 5732ed3b161SSteven Rostedt my $test_num = $$current_test_num; 574a57419b3SSteven Rostedt my $default = 1; 575a57419b3SSteven Rostedt my $repeat = 1; 576a57419b3SSteven Rostedt my $num_tests_set = 0; 577a57419b3SSteven Rostedt my $skip = 0; 578a57419b3SSteven Rostedt my $rest; 579a9f84424SSteven Rostedt my $line; 5800df213caSSteven Rostedt my $test_case = 0; 58145d73a5dSSteven Rostedt my $if = 0; 58245d73a5dSSteven Rostedt my $if_set = 0; 5833d1cc414SSteven Rostedt my $override = 0; 5843d1cc414SSteven Rostedt 5853d1cc414SSteven Rostedt my %overrides; 586a57419b3SSteven Rostedt 5872ed3b161SSteven Rostedt while (<$in>) { 588a57419b3SSteven Rostedt 589a57419b3SSteven Rostedt # ignore blank lines and comments 590a57419b3SSteven Rostedt next if (/^\s*$/ || /\s*\#/); 591a57419b3SSteven Rostedt 5920050b6bbSSteven Rostedt if (/^\s*(TEST_START|DEFAULTS)\b(.*)/) { 593a57419b3SSteven Rostedt 5940050b6bbSSteven Rostedt my $type = $1; 5950050b6bbSSteven Rostedt $rest = $2; 596a9f84424SSteven Rostedt $line = $2; 5970050b6bbSSteven Rostedt 5980050b6bbSSteven Rostedt my $old_test_num; 5990050b6bbSSteven Rostedt my $old_repeat; 6003d1cc414SSteven Rostedt $override = 0; 6010050b6bbSSteven Rostedt 6020050b6bbSSteven Rostedt if ($type eq "TEST_START") { 603a57419b3SSteven Rostedt 604a57419b3SSteven Rostedt if ($num_tests_set) { 605a57419b3SSteven Rostedt die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n"; 606a57419b3SSteven Rostedt } 607a57419b3SSteven Rostedt 6080050b6bbSSteven Rostedt $old_test_num = $test_num; 6090050b6bbSSteven Rostedt $old_repeat = $repeat; 610a57419b3SSteven Rostedt 611a57419b3SSteven Rostedt $test_num += $repeat; 612a57419b3SSteven Rostedt $default = 0; 613a57419b3SSteven Rostedt $repeat = 1; 6140050b6bbSSteven Rostedt } else { 6150050b6bbSSteven Rostedt $default = 1; 6160050b6bbSSteven Rostedt } 617a57419b3SSteven Rostedt 618a9f84424SSteven Rostedt # If SKIP is anywhere in the line, the command will be skipped 619a9f84424SSteven Rostedt if ($rest =~ s/\s+SKIP\b//) { 620a57419b3SSteven Rostedt $skip = 1; 621a57419b3SSteven Rostedt } else { 6220df213caSSteven Rostedt $test_case = 1; 623a57419b3SSteven Rostedt $skip = 0; 624a57419b3SSteven Rostedt } 625a57419b3SSteven Rostedt 626a9f84424SSteven Rostedt if ($rest =~ s/\sELSE\b//) { 627a9f84424SSteven Rostedt if (!$if) { 628a9f84424SSteven Rostedt die "$name: $.: ELSE found with out matching IF section\n$_"; 629a57419b3SSteven Rostedt } 630a9f84424SSteven Rostedt $if = 0; 631a9f84424SSteven Rostedt 632a9f84424SSteven Rostedt if ($if_set) { 633a9f84424SSteven Rostedt $skip = 1; 634a9f84424SSteven Rostedt } else { 635a9f84424SSteven Rostedt $skip = 0; 6363d1cc414SSteven Rostedt } 6373d1cc414SSteven Rostedt } 638a57419b3SSteven Rostedt 639a9f84424SSteven Rostedt if ($rest =~ s/\sIF\s+(.*)//) { 64045d73a5dSSteven Rostedt if (process_if($name, $1)) { 64145d73a5dSSteven Rostedt $if_set = 1; 64245d73a5dSSteven Rostedt } else { 643a57419b3SSteven Rostedt $skip = 1; 644a57419b3SSteven Rostedt } 64545d73a5dSSteven Rostedt $if = 1; 64645d73a5dSSteven Rostedt } else { 64745d73a5dSSteven Rostedt $if = 0; 648a9f84424SSteven Rostedt $if_set = 0; 64945d73a5dSSteven Rostedt } 650a57419b3SSteven Rostedt 651a9f84424SSteven Rostedt if (!$skip) { 652a9f84424SSteven Rostedt if ($type eq "TEST_START") { 653a9f84424SSteven Rostedt if ($rest =~ s/\s+ITERATE\s+(\d+)//) { 654a9f84424SSteven Rostedt $repeat = $1; 655a9f84424SSteven Rostedt $repeat_tests{"$test_num"} = $repeat; 656a9f84424SSteven Rostedt } 657a9f84424SSteven Rostedt } elsif ($rest =~ s/\sOVERRIDE\b//) { 658a9f84424SSteven Rostedt # DEFAULT only 659a9f84424SSteven Rostedt $override = 1; 660a9f84424SSteven Rostedt # Clear previous overrides 661a9f84424SSteven Rostedt %overrides = (); 662a9f84424SSteven Rostedt } 663a9f84424SSteven Rostedt } 664a9f84424SSteven Rostedt 665a9f84424SSteven Rostedt if (!$skip && $rest !~ /^\s*$/) { 6660050b6bbSSteven Rostedt die "$name: $.: Gargbage found after $type\n$_"; 667a57419b3SSteven Rostedt } 668a57419b3SSteven Rostedt 6690050b6bbSSteven Rostedt if ($skip && $type eq "TEST_START") { 670a57419b3SSteven Rostedt $test_num = $old_test_num; 671e48c5293SSteven Rostedt $repeat = $old_repeat; 672a57419b3SSteven Rostedt } 673a57419b3SSteven Rostedt 674ab7a3f52SSteven Rostedt } elsif (/^\s*ELSE\b(.*)$/) { 67545d73a5dSSteven Rostedt if (!$if) { 67645d73a5dSSteven Rostedt die "$name: $.: ELSE found with out matching IF section\n$_"; 67745d73a5dSSteven Rostedt } 67845d73a5dSSteven Rostedt $rest = $1; 67945d73a5dSSteven Rostedt if ($if_set) { 68045d73a5dSSteven Rostedt $skip = 1; 681ab7a3f52SSteven Rostedt $rest = ""; 68245d73a5dSSteven Rostedt } else { 68345d73a5dSSteven Rostedt $skip = 0; 68445d73a5dSSteven Rostedt 685ab7a3f52SSteven Rostedt if ($rest =~ /\sIF\s+(.*)/) { 68645d73a5dSSteven Rostedt # May be a ELSE IF section. 68745d73a5dSSteven Rostedt if (!process_if($name, $1)) { 68845d73a5dSSteven Rostedt $skip = 1; 68945d73a5dSSteven Rostedt } 690ab7a3f52SSteven Rostedt $rest = ""; 69145d73a5dSSteven Rostedt } else { 69245d73a5dSSteven Rostedt $if = 0; 69345d73a5dSSteven Rostedt } 69445d73a5dSSteven Rostedt } 69545d73a5dSSteven Rostedt 696ab7a3f52SSteven Rostedt if ($rest !~ /^\s*$/) { 697ab7a3f52SSteven Rostedt die "$name: $.: Gargbage found after DEFAULTS\n$_"; 698ab7a3f52SSteven Rostedt } 699ab7a3f52SSteven Rostedt 7002ed3b161SSteven Rostedt } elsif (/^\s*INCLUDE\s+(\S+)/) { 7012ed3b161SSteven Rostedt 7022ed3b161SSteven Rostedt next if ($skip); 7032ed3b161SSteven Rostedt 7042ed3b161SSteven Rostedt if (!$default) { 7052ed3b161SSteven Rostedt die "$name: $.: INCLUDE can only be done in default sections\n$_"; 7062ed3b161SSteven Rostedt } 7072ed3b161SSteven Rostedt 7082ed3b161SSteven Rostedt my $file = process_variables($1); 7092ed3b161SSteven Rostedt 7102ed3b161SSteven Rostedt if ($file !~ m,^/,) { 7112ed3b161SSteven Rostedt # check the path of the config file first 7122ed3b161SSteven Rostedt if ($config =~ m,(.*)/,) { 7132ed3b161SSteven Rostedt if (-f "$1/$file") { 7142ed3b161SSteven Rostedt $file = "$1/$file"; 7152ed3b161SSteven Rostedt } 7162ed3b161SSteven Rostedt } 7172ed3b161SSteven Rostedt } 7182ed3b161SSteven Rostedt 7192ed3b161SSteven Rostedt if ( ! -r $file ) { 7202ed3b161SSteven Rostedt die "$name: $.: Can't read file $file\n$_"; 7212ed3b161SSteven Rostedt } 7222ed3b161SSteven Rostedt 7232ed3b161SSteven Rostedt if (__read_config($file, \$test_num)) { 7242ed3b161SSteven Rostedt $test_case = 1; 7252ed3b161SSteven Rostedt } 7262ed3b161SSteven Rostedt 727a57419b3SSteven Rostedt } elsif (/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) { 728a57419b3SSteven Rostedt 729a57419b3SSteven Rostedt next if ($skip); 730a57419b3SSteven Rostedt 731a57419b3SSteven Rostedt my $lvalue = $1; 732a57419b3SSteven Rostedt my $rvalue = $2; 733a57419b3SSteven Rostedt 734a57419b3SSteven Rostedt if (!$default && 735a57419b3SSteven Rostedt ($lvalue eq "NUM_TESTS" || 736a57419b3SSteven Rostedt $lvalue eq "LOG_FILE" || 737a57419b3SSteven Rostedt $lvalue eq "CLEAR_LOG")) { 738a57419b3SSteven Rostedt die "$name: $.: $lvalue must be set in DEFAULTS section\n"; 739a57419b3SSteven Rostedt } 740a57419b3SSteven Rostedt 741a57419b3SSteven Rostedt if ($lvalue eq "NUM_TESTS") { 742a57419b3SSteven Rostedt if ($test_num) { 743a57419b3SSteven Rostedt die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n"; 744a57419b3SSteven Rostedt } 745a57419b3SSteven Rostedt if (!$default) { 746a57419b3SSteven Rostedt die "$name: $.: NUM_TESTS must be set in default section\n"; 747a57419b3SSteven Rostedt } 748a57419b3SSteven Rostedt $num_tests_set = 1; 749a57419b3SSteven Rostedt } 750a57419b3SSteven Rostedt 751a57419b3SSteven Rostedt if ($default || $lvalue =~ /\[\d+\]$/) { 7523d1cc414SSteven Rostedt set_value($lvalue, $rvalue, $override, \%overrides, $name); 753a57419b3SSteven Rostedt } else { 754a57419b3SSteven Rostedt my $val = "$lvalue\[$test_num\]"; 7553d1cc414SSteven Rostedt set_value($val, $rvalue, $override, \%overrides, $name); 756a57419b3SSteven Rostedt 757a57419b3SSteven Rostedt if ($repeat > 1) { 758a57419b3SSteven Rostedt $repeats{$val} = $repeat; 759a57419b3SSteven Rostedt } 760a57419b3SSteven Rostedt } 76177d942ceSSteven Rostedt } elsif (/^\s*([A-Z_\[\]\d]+)\s*:=\s*(.*?)\s*$/) { 76277d942ceSSteven Rostedt next if ($skip); 76377d942ceSSteven Rostedt 76477d942ceSSteven Rostedt my $lvalue = $1; 76577d942ceSSteven Rostedt my $rvalue = $2; 76677d942ceSSteven Rostedt 76777d942ceSSteven Rostedt # process config variables. 76877d942ceSSteven Rostedt # Config variables are only active while reading the 76977d942ceSSteven Rostedt # config and can be defined anywhere. They also ignore 77077d942ceSSteven Rostedt # TEST_START and DEFAULTS, but are skipped if they are in 77177d942ceSSteven Rostedt # on of these sections that have SKIP defined. 77277d942ceSSteven Rostedt # The save variable can be 77377d942ceSSteven Rostedt # defined multiple times and the new one simply overrides 77477d942ceSSteven Rostedt # the prevous one. 77577d942ceSSteven Rostedt set_variable($lvalue, $rvalue); 77677d942ceSSteven Rostedt 777a57419b3SSteven Rostedt } else { 778a57419b3SSteven Rostedt die "$name: $.: Garbage found in config\n$_"; 779a57419b3SSteven Rostedt } 7802545eb61SSteven Rostedt } 7812545eb61SSteven Rostedt 782a57419b3SSteven Rostedt if ($test_num) { 783a57419b3SSteven Rostedt $test_num += $repeat - 1; 784a57419b3SSteven Rostedt $opt{"NUM_TESTS"} = $test_num; 785a57419b3SSteven Rostedt } 786a57419b3SSteven Rostedt 7872ed3b161SSteven Rostedt close($in); 7882ed3b161SSteven Rostedt 7892ed3b161SSteven Rostedt $$current_test_num = $test_num; 7902ed3b161SSteven Rostedt 7912ed3b161SSteven Rostedt return $test_case; 7922ed3b161SSteven Rostedt} 7932ed3b161SSteven Rostedt 794c4261d0fSSteven Rostedtsub get_test_case { 795c4261d0fSSteven Rostedt print "What test case would you like to run?\n"; 796c4261d0fSSteven Rostedt print " (build, install or boot)\n"; 797c4261d0fSSteven Rostedt print " Other tests are available but require editing the config file\n"; 798c4261d0fSSteven Rostedt my $ans = <STDIN>; 799c4261d0fSSteven Rostedt chomp $ans; 800c4261d0fSSteven Rostedt $default{"TEST_TYPE"} = $ans; 801c4261d0fSSteven Rostedt} 802c4261d0fSSteven Rostedt 8032ed3b161SSteven Rostedtsub read_config { 8042ed3b161SSteven Rostedt my ($config) = @_; 8052ed3b161SSteven Rostedt 8062ed3b161SSteven Rostedt my $test_case; 8072ed3b161SSteven Rostedt my $test_num = 0; 8082ed3b161SSteven Rostedt 8092ed3b161SSteven Rostedt $test_case = __read_config $config, \$test_num; 8102ed3b161SSteven Rostedt 8118d1491baSSteven Rostedt # make sure we have all mandatory configs 8128d1491baSSteven Rostedt get_ktest_configs; 8138d1491baSSteven Rostedt 8140df213caSSteven Rostedt # was a test specified? 8150df213caSSteven Rostedt if (!$test_case) { 8160df213caSSteven Rostedt print "No test case specified.\n"; 817c4261d0fSSteven Rostedt get_test_case; 8180df213caSSteven Rostedt } 8190df213caSSteven Rostedt 820a75fececSSteven Rostedt # set any defaults 821a75fececSSteven Rostedt 822a75fececSSteven Rostedt foreach my $default (keys %default) { 823a75fececSSteven Rostedt if (!defined($opt{$default})) { 824a75fececSSteven Rostedt $opt{$default} = $default{$default}; 825a75fececSSteven Rostedt } 826a75fececSSteven Rostedt } 8272545eb61SSteven Rostedt} 8282545eb61SSteven Rostedt 82923715c3cSSteven Rostedtsub __eval_option { 83023715c3cSSteven Rostedt my ($option, $i) = @_; 83123715c3cSSteven Rostedt 83223715c3cSSteven Rostedt # Add space to evaluate the character before $ 83323715c3cSSteven Rostedt $option = " $option"; 83423715c3cSSteven Rostedt my $retval = ""; 835f9dfb65bSRabin Vincent my $repeated = 0; 836f9dfb65bSRabin Vincent my $parent = 0; 837f9dfb65bSRabin Vincent 838f9dfb65bSRabin Vincent foreach my $test (keys %repeat_tests) { 839f9dfb65bSRabin Vincent if ($i >= $test && 840f9dfb65bSRabin Vincent $i < $test + $repeat_tests{$test}) { 841f9dfb65bSRabin Vincent 842f9dfb65bSRabin Vincent $repeated = 1; 843f9dfb65bSRabin Vincent $parent = $test; 844f9dfb65bSRabin Vincent last; 845f9dfb65bSRabin Vincent } 846f9dfb65bSRabin Vincent } 84723715c3cSSteven Rostedt 84823715c3cSSteven Rostedt while ($option =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) { 84923715c3cSSteven Rostedt my $start = $1; 85023715c3cSSteven Rostedt my $var = $2; 85123715c3cSSteven Rostedt my $end = $3; 85223715c3cSSteven Rostedt 85323715c3cSSteven Rostedt # Append beginning of line 85423715c3cSSteven Rostedt $retval = "$retval$start"; 85523715c3cSSteven Rostedt 85623715c3cSSteven Rostedt # If the iteration option OPT[$i] exists, then use that. 85723715c3cSSteven Rostedt # otherwise see if the default OPT (without [$i]) exists. 85823715c3cSSteven Rostedt 85923715c3cSSteven Rostedt my $o = "$var\[$i\]"; 860f9dfb65bSRabin Vincent my $parento = "$var\[$parent\]"; 86123715c3cSSteven Rostedt 86223715c3cSSteven Rostedt if (defined($opt{$o})) { 86323715c3cSSteven Rostedt $o = $opt{$o}; 86423715c3cSSteven Rostedt $retval = "$retval$o"; 865f9dfb65bSRabin Vincent } elsif ($repeated && defined($opt{$parento})) { 866f9dfb65bSRabin Vincent $o = $opt{$parento}; 867f9dfb65bSRabin Vincent $retval = "$retval$o"; 86823715c3cSSteven Rostedt } elsif (defined($opt{$var})) { 86923715c3cSSteven Rostedt $o = $opt{$var}; 87023715c3cSSteven Rostedt $retval = "$retval$o"; 87123715c3cSSteven Rostedt } else { 87223715c3cSSteven Rostedt $retval = "$retval\$\{$var\}"; 87323715c3cSSteven Rostedt } 87423715c3cSSteven Rostedt 87523715c3cSSteven Rostedt $option = $end; 87623715c3cSSteven Rostedt } 87723715c3cSSteven Rostedt 87823715c3cSSteven Rostedt $retval = "$retval$option"; 87923715c3cSSteven Rostedt 88023715c3cSSteven Rostedt $retval =~ s/^ //; 88123715c3cSSteven Rostedt 88223715c3cSSteven Rostedt return $retval; 88323715c3cSSteven Rostedt} 88423715c3cSSteven Rostedt 88523715c3cSSteven Rostedtsub eval_option { 88623715c3cSSteven Rostedt my ($option, $i) = @_; 88723715c3cSSteven Rostedt 88823715c3cSSteven Rostedt my $prev = ""; 88923715c3cSSteven Rostedt 89023715c3cSSteven Rostedt # Since an option can evaluate to another option, 89123715c3cSSteven Rostedt # keep iterating until we do not evaluate any more 89223715c3cSSteven Rostedt # options. 89323715c3cSSteven Rostedt my $r = 0; 89423715c3cSSteven Rostedt while ($prev ne $option) { 89523715c3cSSteven Rostedt # Check for recursive evaluations. 89623715c3cSSteven Rostedt # 100 deep should be more than enough. 89723715c3cSSteven Rostedt if ($r++ > 100) { 89823715c3cSSteven Rostedt die "Over 100 evaluations accurred with $option\n" . 89923715c3cSSteven Rostedt "Check for recursive variables\n"; 90023715c3cSSteven Rostedt } 90123715c3cSSteven Rostedt $prev = $option; 90223715c3cSSteven Rostedt $option = __eval_option($option, $i); 90323715c3cSSteven Rostedt } 90423715c3cSSteven Rostedt 90523715c3cSSteven Rostedt return $option; 90623715c3cSSteven Rostedt} 90723715c3cSSteven Rostedt 908d1e2f22aSSteven Rostedtsub _logit { 9092545eb61SSteven Rostedt if (defined($opt{"LOG_FILE"})) { 9102545eb61SSteven Rostedt open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}"; 9112545eb61SSteven Rostedt print OUT @_; 9122545eb61SSteven Rostedt close(OUT); 9132545eb61SSteven Rostedt } 9142545eb61SSteven Rostedt} 9152545eb61SSteven Rostedt 916d1e2f22aSSteven Rostedtsub logit { 917d1e2f22aSSteven Rostedt if (defined($opt{"LOG_FILE"})) { 918d1e2f22aSSteven Rostedt _logit @_; 919d1e2f22aSSteven Rostedt } else { 920d1e2f22aSSteven Rostedt print @_; 921d1e2f22aSSteven Rostedt } 922d1e2f22aSSteven Rostedt} 923d1e2f22aSSteven Rostedt 9245f9b6cedSSteven Rostedtsub doprint { 9255f9b6cedSSteven Rostedt print @_; 926d1e2f22aSSteven Rostedt _logit @_; 9275f9b6cedSSteven Rostedt} 9285f9b6cedSSteven Rostedt 9297faafbd6SSteven Rostedtsub run_command; 9302728be41SAndrew Jonessub start_monitor; 9312728be41SAndrew Jonessub end_monitor; 9322728be41SAndrew Jonessub wait_for_monitor; 9337faafbd6SSteven Rostedt 9347faafbd6SSteven Rostedtsub reboot { 9352728be41SAndrew Jones my ($time) = @_; 9362728be41SAndrew Jones 9372b803365SSteven Rostedt if (defined($time)) { 9382b803365SSteven Rostedt start_monitor; 9392b803365SSteven Rostedt # flush out current monitor 9402b803365SSteven Rostedt # May contain the reboot success line 9412b803365SSteven Rostedt wait_for_monitor 1; 9422b803365SSteven Rostedt } 9432b803365SSteven Rostedt 9447faafbd6SSteven Rostedt # try to reboot normally 945e48c5293SSteven Rostedt if (run_command $reboot) { 946576f627cSSteven Rostedt if (defined($powercycle_after_reboot)) { 947576f627cSSteven Rostedt sleep $powercycle_after_reboot; 948576f627cSSteven Rostedt run_command "$power_cycle"; 949576f627cSSteven Rostedt } 950576f627cSSteven Rostedt } else { 9517faafbd6SSteven Rostedt # nope? power cycle it. 952a75fececSSteven Rostedt run_command "$power_cycle"; 9537faafbd6SSteven Rostedt } 9542728be41SAndrew Jones 9552728be41SAndrew Jones if (defined($time)) { 9562b803365SSteven Rostedt wait_for_monitor($time, $reboot_success_line); 9572728be41SAndrew Jones end_monitor; 9582728be41SAndrew Jones } 9597faafbd6SSteven Rostedt} 9607faafbd6SSteven Rostedt 961576f627cSSteven Rostedtsub do_not_reboot { 962576f627cSSteven Rostedt my $i = $iteration; 963576f627cSSteven Rostedt 9644ab1cce5SSteven Rostedt return $test_type eq "build" || $no_reboot || 965576f627cSSteven Rostedt ($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") || 966576f627cSSteven Rostedt ($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build"); 967576f627cSSteven Rostedt} 968576f627cSSteven Rostedt 9695c42fc5bSSteven Rostedtsub dodie { 9705a391fbfSSteven Rostedt doprint "CRITICAL FAILURE... ", @_, "\n"; 9715c42fc5bSSteven Rostedt 972576f627cSSteven Rostedt my $i = $iteration; 973576f627cSSteven Rostedt 974576f627cSSteven Rostedt if ($reboot_on_error && !do_not_reboot) { 975576f627cSSteven Rostedt 97675c3fda7SSteven Rostedt doprint "REBOOTING\n"; 9777faafbd6SSteven Rostedt reboot; 97875c3fda7SSteven Rostedt 979a75fececSSteven Rostedt } elsif ($poweroff_on_error && defined($power_off)) { 9805c42fc5bSSteven Rostedt doprint "POWERING OFF\n"; 981a75fececSSteven Rostedt `$power_off`; 9825c42fc5bSSteven Rostedt } 98375c3fda7SSteven Rostedt 984f80802cbSSteven Rostedt if (defined($opt{"LOG_FILE"})) { 985f80802cbSSteven Rostedt print " See $opt{LOG_FILE} for more info.\n"; 986f80802cbSSteven Rostedt } 987f80802cbSSteven Rostedt 988576f627cSSteven Rostedt die @_, "\n"; 9895c42fc5bSSteven Rostedt} 9905c42fc5bSSteven Rostedt 9917faafbd6SSteven Rostedtsub open_console { 9927faafbd6SSteven Rostedt my ($fp) = @_; 9937faafbd6SSteven Rostedt 9947faafbd6SSteven Rostedt my $flags; 9957faafbd6SSteven Rostedt 996a75fececSSteven Rostedt my $pid = open($fp, "$console|") or 997a75fececSSteven Rostedt dodie "Can't open console $console"; 9987faafbd6SSteven Rostedt 9997faafbd6SSteven Rostedt $flags = fcntl($fp, F_GETFL, 0) or 1000576f627cSSteven Rostedt dodie "Can't get flags for the socket: $!"; 10017faafbd6SSteven Rostedt $flags = fcntl($fp, F_SETFL, $flags | O_NONBLOCK) or 1002576f627cSSteven Rostedt dodie "Can't set flags for the socket: $!"; 10037faafbd6SSteven Rostedt 10047faafbd6SSteven Rostedt return $pid; 10057faafbd6SSteven Rostedt} 10067faafbd6SSteven Rostedt 10077faafbd6SSteven Rostedtsub close_console { 10087faafbd6SSteven Rostedt my ($fp, $pid) = @_; 10097faafbd6SSteven Rostedt 10107faafbd6SSteven Rostedt doprint "kill child process $pid\n"; 10117faafbd6SSteven Rostedt kill 2, $pid; 10127faafbd6SSteven Rostedt 10137faafbd6SSteven Rostedt print "closing!\n"; 10147faafbd6SSteven Rostedt close($fp); 10157faafbd6SSteven Rostedt} 10167faafbd6SSteven Rostedt 10177faafbd6SSteven Rostedtsub start_monitor { 10187faafbd6SSteven Rostedt if ($monitor_cnt++) { 10197faafbd6SSteven Rostedt return; 10207faafbd6SSteven Rostedt } 10217faafbd6SSteven Rostedt $monitor_fp = \*MONFD; 10227faafbd6SSteven Rostedt $monitor_pid = open_console $monitor_fp; 1023a75fececSSteven Rostedt 1024a75fececSSteven Rostedt return; 1025a75fececSSteven Rostedt 1026a75fececSSteven Rostedt open(MONFD, "Stop perl from warning about single use of MONFD"); 10277faafbd6SSteven Rostedt} 10287faafbd6SSteven Rostedt 10297faafbd6SSteven Rostedtsub end_monitor { 10307faafbd6SSteven Rostedt if (--$monitor_cnt) { 10317faafbd6SSteven Rostedt return; 10327faafbd6SSteven Rostedt } 10337faafbd6SSteven Rostedt close_console($monitor_fp, $monitor_pid); 10347faafbd6SSteven Rostedt} 10357faafbd6SSteven Rostedt 10367faafbd6SSteven Rostedtsub wait_for_monitor { 10372b803365SSteven Rostedt my ($time, $stop) = @_; 10382b803365SSteven Rostedt my $full_line = ""; 10397faafbd6SSteven Rostedt my $line; 10402b803365SSteven Rostedt my $booted = 0; 10417faafbd6SSteven Rostedt 1042a75fececSSteven Rostedt doprint "** Wait for monitor to settle down **\n"; 10437faafbd6SSteven Rostedt 10447faafbd6SSteven Rostedt # read the monitor and wait for the system to calm down 10452b803365SSteven Rostedt while (!$booted) { 10467faafbd6SSteven Rostedt $line = wait_for_input($monitor_fp, $time); 10472b803365SSteven Rostedt last if (!defined($line)); 10482b803365SSteven Rostedt print "$line"; 10492b803365SSteven Rostedt $full_line .= $line; 10502b803365SSteven Rostedt 10512b803365SSteven Rostedt if (defined($stop) && $full_line =~ /$stop/) { 10522b803365SSteven Rostedt doprint "wait for monitor detected $stop\n"; 10532b803365SSteven Rostedt $booted = 1; 10542b803365SSteven Rostedt } 10552b803365SSteven Rostedt 10562b803365SSteven Rostedt if ($line =~ /\n/) { 10572b803365SSteven Rostedt $full_line = ""; 10582b803365SSteven Rostedt } 10592b803365SSteven Rostedt } 1060a75fececSSteven Rostedt print "** Monitor flushed **\n"; 10617faafbd6SSteven Rostedt} 10627faafbd6SSteven Rostedt 1063de5b6e3bSRabin Vincentsub save_logs { 1064de5b6e3bSRabin Vincent my ($result, $basedir) = @_; 1065de5b6e3bSRabin Vincent my @t = localtime; 1066de5b6e3bSRabin Vincent my $date = sprintf "%04d%02d%02d%02d%02d%02d", 1067de5b6e3bSRabin Vincent 1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0]; 1068de5b6e3bSRabin Vincent 1069de5b6e3bSRabin Vincent my $type = $build_type; 1070de5b6e3bSRabin Vincent if ($type =~ /useconfig/) { 1071de5b6e3bSRabin Vincent $type = "useconfig"; 1072de5b6e3bSRabin Vincent } 1073de5b6e3bSRabin Vincent 1074de5b6e3bSRabin Vincent my $dir = "$machine-$test_type-$type-$result-$date"; 1075de5b6e3bSRabin Vincent 1076de5b6e3bSRabin Vincent $dir = "$basedir/$dir"; 1077de5b6e3bSRabin Vincent 1078de5b6e3bSRabin Vincent if (!-d $dir) { 1079de5b6e3bSRabin Vincent mkpath($dir) or 1080de5b6e3bSRabin Vincent die "can't create $dir"; 1081de5b6e3bSRabin Vincent } 1082de5b6e3bSRabin Vincent 1083de5b6e3bSRabin Vincent my %files = ( 1084de5b6e3bSRabin Vincent "config" => $output_config, 1085de5b6e3bSRabin Vincent "buildlog" => $buildlog, 1086de5b6e3bSRabin Vincent "dmesg" => $dmesg, 1087de5b6e3bSRabin Vincent "testlog" => $testlog, 1088de5b6e3bSRabin Vincent ); 1089de5b6e3bSRabin Vincent 1090de5b6e3bSRabin Vincent while (my ($name, $source) = each(%files)) { 1091de5b6e3bSRabin Vincent if (-f "$source") { 1092de5b6e3bSRabin Vincent cp "$source", "$dir/$name" or 1093de5b6e3bSRabin Vincent die "failed to copy $source"; 1094de5b6e3bSRabin Vincent } 1095de5b6e3bSRabin Vincent } 1096de5b6e3bSRabin Vincent 1097de5b6e3bSRabin Vincent doprint "*** Saved info to $dir ***\n"; 1098de5b6e3bSRabin Vincent} 1099de5b6e3bSRabin Vincent 11002b7d9b21SSteven Rostedtsub fail { 11012b7d9b21SSteven Rostedt 1102a75fececSSteven Rostedt if ($die_on_failure) { 11032b7d9b21SSteven Rostedt dodie @_; 11042b7d9b21SSteven Rostedt } 11052b7d9b21SSteven Rostedt 1106a75fececSSteven Rostedt doprint "FAILED\n"; 11077faafbd6SSteven Rostedt 1108576f627cSSteven Rostedt my $i = $iteration; 1109576f627cSSteven Rostedt 1110a75fececSSteven Rostedt # no need to reboot for just building. 1111576f627cSSteven Rostedt if (!do_not_reboot) { 11127faafbd6SSteven Rostedt doprint "REBOOTING\n"; 11132728be41SAndrew Jones reboot $sleep_time; 1114a75fececSSteven Rostedt } 11157faafbd6SSteven Rostedt 11169064af52SSteven Rostedt my $name = ""; 11179064af52SSteven Rostedt 11189064af52SSteven Rostedt if (defined($test_name)) { 11199064af52SSteven Rostedt $name = " ($test_name)"; 11209064af52SSteven Rostedt } 11219064af52SSteven Rostedt 1122576f627cSSteven Rostedt doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; 1123576f627cSSteven Rostedt doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; 11249064af52SSteven Rostedt doprint "KTEST RESULT: TEST $i$name Failed: ", @_, "\n"; 1125576f627cSSteven Rostedt doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; 1126576f627cSSteven Rostedt doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; 1127a75fececSSteven Rostedt 1128de5b6e3bSRabin Vincent if (defined($store_failures)) { 1129de5b6e3bSRabin Vincent save_logs "fail", $store_failures; 1130cccae1a6SSteven Rostedt } 1131cccae1a6SSteven Rostedt 11322b7d9b21SSteven Rostedt return 1; 11332b7d9b21SSteven Rostedt} 11342b7d9b21SSteven Rostedt 11352545eb61SSteven Rostedtsub run_command { 11362545eb61SSteven Rostedt my ($command) = @_; 1137d6ce2a0bSSteven Rostedt my $dolog = 0; 1138d6ce2a0bSSteven Rostedt my $dord = 0; 1139d6ce2a0bSSteven Rostedt my $pid; 1140d6ce2a0bSSteven Rostedt 1141e48c5293SSteven Rostedt $command =~ s/\$SSH_USER/$ssh_user/g; 1142e48c5293SSteven Rostedt $command =~ s/\$MACHINE/$machine/g; 1143e48c5293SSteven Rostedt 1144d6ce2a0bSSteven Rostedt doprint("$command ... "); 1145d6ce2a0bSSteven Rostedt 1146d6ce2a0bSSteven Rostedt $pid = open(CMD, "$command 2>&1 |") or 11472b7d9b21SSteven Rostedt (fail "unable to exec $command" and return 0); 11482545eb61SSteven Rostedt 11492545eb61SSteven Rostedt if (defined($opt{"LOG_FILE"})) { 1150d6ce2a0bSSteven Rostedt open(LOG, ">>$opt{LOG_FILE}") or 1151d6ce2a0bSSteven Rostedt dodie "failed to write to log"; 1152d6ce2a0bSSteven Rostedt $dolog = 1; 11536c5ee0beSSteven Rostedt } 11546c5ee0beSSteven Rostedt 11556c5ee0beSSteven Rostedt if (defined($redirect)) { 1156d6ce2a0bSSteven Rostedt open (RD, ">$redirect") or 1157d6ce2a0bSSteven Rostedt dodie "failed to write to redirect $redirect"; 1158d6ce2a0bSSteven Rostedt $dord = 1; 11592545eb61SSteven Rostedt } 11602545eb61SSteven Rostedt 1161d6ce2a0bSSteven Rostedt while (<CMD>) { 1162d6ce2a0bSSteven Rostedt print LOG if ($dolog); 1163d6ce2a0bSSteven Rostedt print RD if ($dord); 1164d6ce2a0bSSteven Rostedt } 11652545eb61SSteven Rostedt 1166d6ce2a0bSSteven Rostedt waitpid($pid, 0); 11672545eb61SSteven Rostedt my $failed = $?; 11682545eb61SSteven Rostedt 1169d6ce2a0bSSteven Rostedt close(CMD); 1170d6ce2a0bSSteven Rostedt close(LOG) if ($dolog); 1171d6ce2a0bSSteven Rostedt close(RD) if ($dord); 1172d6ce2a0bSSteven Rostedt 11732545eb61SSteven Rostedt if ($failed) { 11742545eb61SSteven Rostedt doprint "FAILED!\n"; 11752545eb61SSteven Rostedt } else { 11762545eb61SSteven Rostedt doprint "SUCCESS\n"; 11772545eb61SSteven Rostedt } 11782545eb61SSteven Rostedt 11795f9b6cedSSteven Rostedt return !$failed; 11805f9b6cedSSteven Rostedt} 11815f9b6cedSSteven Rostedt 1182e48c5293SSteven Rostedtsub run_ssh { 1183e48c5293SSteven Rostedt my ($cmd) = @_; 1184e48c5293SSteven Rostedt my $cp_exec = $ssh_exec; 1185e48c5293SSteven Rostedt 1186e48c5293SSteven Rostedt $cp_exec =~ s/\$SSH_COMMAND/$cmd/g; 1187e48c5293SSteven Rostedt return run_command "$cp_exec"; 1188e48c5293SSteven Rostedt} 1189e48c5293SSteven Rostedt 1190e48c5293SSteven Rostedtsub run_scp { 1191e48c5293SSteven Rostedt my ($src, $dst) = @_; 1192e48c5293SSteven Rostedt my $cp_scp = $scp_to_target; 1193e48c5293SSteven Rostedt 1194e48c5293SSteven Rostedt $cp_scp =~ s/\$SRC_FILE/$src/g; 1195e48c5293SSteven Rostedt $cp_scp =~ s/\$DST_FILE/$dst/g; 1196e48c5293SSteven Rostedt 1197e48c5293SSteven Rostedt return run_command "$cp_scp"; 1198e48c5293SSteven Rostedt} 1199e48c5293SSteven Rostedt 12005f9b6cedSSteven Rostedtsub get_grub_index { 12015f9b6cedSSteven Rostedt 1202a75fececSSteven Rostedt if ($reboot_type ne "grub") { 1203a75fececSSteven Rostedt return; 1204a75fececSSteven Rostedt } 12055a391fbfSSteven Rostedt return if (defined($grub_number)); 12065f9b6cedSSteven Rostedt 12075f9b6cedSSteven Rostedt doprint "Find grub menu ... "; 12085f9b6cedSSteven Rostedt $grub_number = -1; 1209e48c5293SSteven Rostedt 1210e48c5293SSteven Rostedt my $ssh_grub = $ssh_exec; 1211e48c5293SSteven Rostedt $ssh_grub =~ s,\$SSH_COMMAND,cat /boot/grub/menu.lst,g; 1212e48c5293SSteven Rostedt 1213e48c5293SSteven Rostedt open(IN, "$ssh_grub |") 12145f9b6cedSSteven Rostedt or die "unable to get menu.lst"; 1215e48c5293SSteven Rostedt 1216eaa1fe25SSteven Rostedt my $found = 0; 1217eaa1fe25SSteven Rostedt 12185f9b6cedSSteven Rostedt while (<IN>) { 1219a75fececSSteven Rostedt if (/^\s*title\s+$grub_menu\s*$/) { 12205f9b6cedSSteven Rostedt $grub_number++; 1221eaa1fe25SSteven Rostedt $found = 1; 12225f9b6cedSSteven Rostedt last; 12235f9b6cedSSteven Rostedt } elsif (/^\s*title\s/) { 12245f9b6cedSSteven Rostedt $grub_number++; 12255f9b6cedSSteven Rostedt } 12265f9b6cedSSteven Rostedt } 12275f9b6cedSSteven Rostedt close(IN); 12285f9b6cedSSteven Rostedt 1229a75fececSSteven Rostedt die "Could not find '$grub_menu' in /boot/grub/menu on $machine" 1230eaa1fe25SSteven Rostedt if (!$found); 12315f9b6cedSSteven Rostedt doprint "$grub_number\n"; 12322545eb61SSteven Rostedt} 12332545eb61SSteven Rostedt 12342545eb61SSteven Rostedtsub wait_for_input 12352545eb61SSteven Rostedt{ 12362545eb61SSteven Rostedt my ($fp, $time) = @_; 12372545eb61SSteven Rostedt my $rin; 12382545eb61SSteven Rostedt my $ready; 12392545eb61SSteven Rostedt my $line; 12402545eb61SSteven Rostedt my $ch; 12412545eb61SSteven Rostedt 12422545eb61SSteven Rostedt if (!defined($time)) { 12432545eb61SSteven Rostedt $time = $timeout; 12442545eb61SSteven Rostedt } 12452545eb61SSteven Rostedt 12462545eb61SSteven Rostedt $rin = ''; 12472545eb61SSteven Rostedt vec($rin, fileno($fp), 1) = 1; 12482545eb61SSteven Rostedt $ready = select($rin, undef, undef, $time); 12492545eb61SSteven Rostedt 12502545eb61SSteven Rostedt $line = ""; 12512545eb61SSteven Rostedt 12522545eb61SSteven Rostedt # try to read one char at a time 12532545eb61SSteven Rostedt while (sysread $fp, $ch, 1) { 12542545eb61SSteven Rostedt $line .= $ch; 12552545eb61SSteven Rostedt last if ($ch eq "\n"); 12562545eb61SSteven Rostedt } 12572545eb61SSteven Rostedt 12582545eb61SSteven Rostedt if (!length($line)) { 12592545eb61SSteven Rostedt return undef; 12602545eb61SSteven Rostedt } 12612545eb61SSteven Rostedt 12622545eb61SSteven Rostedt return $line; 12632545eb61SSteven Rostedt} 12642545eb61SSteven Rostedt 126575c3fda7SSteven Rostedtsub reboot_to { 1266a75fececSSteven Rostedt if ($reboot_type eq "grub") { 1267c54367f9SSteven Rostedt run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch)'"; 1268c54367f9SSteven Rostedt reboot; 1269a75fececSSteven Rostedt return; 1270a75fececSSteven Rostedt } 1271a75fececSSteven Rostedt 1272a75fececSSteven Rostedt run_command "$reboot_script"; 12732545eb61SSteven Rostedt} 12742545eb61SSteven Rostedt 1275a57419b3SSteven Rostedtsub get_sha1 { 1276a57419b3SSteven Rostedt my ($commit) = @_; 1277a57419b3SSteven Rostedt 1278a57419b3SSteven Rostedt doprint "git rev-list --max-count=1 $commit ... "; 1279a57419b3SSteven Rostedt my $sha1 = `git rev-list --max-count=1 $commit`; 1280a57419b3SSteven Rostedt my $ret = $?; 1281a57419b3SSteven Rostedt 1282a57419b3SSteven Rostedt logit $sha1; 1283a57419b3SSteven Rostedt 1284a57419b3SSteven Rostedt if ($ret) { 1285a57419b3SSteven Rostedt doprint "FAILED\n"; 1286a57419b3SSteven Rostedt dodie "Failed to get git $commit"; 1287a57419b3SSteven Rostedt } 1288a57419b3SSteven Rostedt 1289a57419b3SSteven Rostedt print "SUCCESS\n"; 1290a57419b3SSteven Rostedt 1291a57419b3SSteven Rostedt chomp $sha1; 1292a57419b3SSteven Rostedt 1293a57419b3SSteven Rostedt return $sha1; 1294a57419b3SSteven Rostedt} 1295a57419b3SSteven Rostedt 12965a391fbfSSteven Rostedtsub monitor { 12972545eb61SSteven Rostedt my $booted = 0; 12982545eb61SSteven Rostedt my $bug = 0; 12995c42fc5bSSteven Rostedt my $skip_call_trace = 0; 13002b7d9b21SSteven Rostedt my $loops; 13012545eb61SSteven Rostedt 13027faafbd6SSteven Rostedt wait_for_monitor 5; 13032545eb61SSteven Rostedt 13042545eb61SSteven Rostedt my $line; 13052545eb61SSteven Rostedt my $full_line = ""; 13062545eb61SSteven Rostedt 13077faafbd6SSteven Rostedt open(DMESG, "> $dmesg") or 13087faafbd6SSteven Rostedt die "unable to write to $dmesg"; 13092545eb61SSteven Rostedt 131075c3fda7SSteven Rostedt reboot_to; 13112545eb61SSteven Rostedt 13121c8a617aSSteven Rostedt my $success_start; 13131c8a617aSSteven Rostedt my $failure_start; 13142d01b26aSSteven Rostedt my $monitor_start = time; 13152d01b26aSSteven Rostedt my $done = 0; 1316f1a5b962SSteven Rostedt my $version_found = 0; 13171c8a617aSSteven Rostedt 13182d01b26aSSteven Rostedt while (!$done) { 13192545eb61SSteven Rostedt 1320ecaf8e52SSteven Rostedt if ($bug && defined($stop_after_failure) && 1321ecaf8e52SSteven Rostedt $stop_after_failure >= 0) { 1322ecaf8e52SSteven Rostedt my $time = $stop_after_failure - (time - $failure_start); 1323ecaf8e52SSteven Rostedt $line = wait_for_input($monitor_fp, $time); 1324ecaf8e52SSteven Rostedt if (!defined($line)) { 1325ecaf8e52SSteven Rostedt doprint "bug timed out after $booted_timeout seconds\n"; 1326ecaf8e52SSteven Rostedt doprint "Test forced to stop after $stop_after_failure seconds after failure\n"; 1327ecaf8e52SSteven Rostedt last; 1328ecaf8e52SSteven Rostedt } 1329ecaf8e52SSteven Rostedt } elsif ($booted) { 1330a75fececSSteven Rostedt $line = wait_for_input($monitor_fp, $booted_timeout); 1331cd4f1d53SSteven Rostedt if (!defined($line)) { 1332cd4f1d53SSteven Rostedt my $s = $booted_timeout == 1 ? "" : "s"; 1333cd4f1d53SSteven Rostedt doprint "Successful boot found: break after $booted_timeout second$s\n"; 1334cd4f1d53SSteven Rostedt last; 1335cd4f1d53SSteven Rostedt } 13362b7d9b21SSteven Rostedt } else { 13377faafbd6SSteven Rostedt $line = wait_for_input($monitor_fp); 1338cd4f1d53SSteven Rostedt if (!defined($line)) { 1339cd4f1d53SSteven Rostedt my $s = $timeout == 1 ? "" : "s"; 1340cd4f1d53SSteven Rostedt doprint "Timed out after $timeout second$s\n"; 1341cd4f1d53SSteven Rostedt last; 13422b7d9b21SSteven Rostedt } 1343cd4f1d53SSteven Rostedt } 13442545eb61SSteven Rostedt 13452545eb61SSteven Rostedt doprint $line; 13467faafbd6SSteven Rostedt print DMESG $line; 13472545eb61SSteven Rostedt 13482545eb61SSteven Rostedt # we are not guaranteed to get a full line 13492545eb61SSteven Rostedt $full_line .= $line; 13502545eb61SSteven Rostedt 1351a75fececSSteven Rostedt if ($full_line =~ /$success_line/) { 13522545eb61SSteven Rostedt $booted = 1; 13531c8a617aSSteven Rostedt $success_start = time; 13541c8a617aSSteven Rostedt } 13551c8a617aSSteven Rostedt 13561c8a617aSSteven Rostedt if ($booted && defined($stop_after_success) && 13571c8a617aSSteven Rostedt $stop_after_success >= 0) { 13581c8a617aSSteven Rostedt my $now = time; 13591c8a617aSSteven Rostedt if ($now - $success_start >= $stop_after_success) { 13601c8a617aSSteven Rostedt doprint "Test forced to stop after $stop_after_success seconds after success\n"; 13611c8a617aSSteven Rostedt last; 13621c8a617aSSteven Rostedt } 13632545eb61SSteven Rostedt } 13642545eb61SSteven Rostedt 13655c42fc5bSSteven Rostedt if ($full_line =~ /\[ backtrace testing \]/) { 13665c42fc5bSSteven Rostedt $skip_call_trace = 1; 13675c42fc5bSSteven Rostedt } 13685c42fc5bSSteven Rostedt 13692545eb61SSteven Rostedt if ($full_line =~ /call trace:/i) { 13704651920eSSteven Rostedt if (!$bug && !$skip_call_trace) { 13711c8a617aSSteven Rostedt $bug = 1; 13721c8a617aSSteven Rostedt $failure_start = time; 13731c8a617aSSteven Rostedt } 13741c8a617aSSteven Rostedt } 13751c8a617aSSteven Rostedt 13761c8a617aSSteven Rostedt if ($bug && defined($stop_after_failure) && 13771c8a617aSSteven Rostedt $stop_after_failure >= 0) { 13781c8a617aSSteven Rostedt my $now = time; 13791c8a617aSSteven Rostedt if ($now - $failure_start >= $stop_after_failure) { 13801c8a617aSSteven Rostedt doprint "Test forced to stop after $stop_after_failure seconds after failure\n"; 13811c8a617aSSteven Rostedt last; 13821c8a617aSSteven Rostedt } 13835c42fc5bSSteven Rostedt } 13845c42fc5bSSteven Rostedt 13855c42fc5bSSteven Rostedt if ($full_line =~ /\[ end of backtrace testing \]/) { 13865c42fc5bSSteven Rostedt $skip_call_trace = 0; 13875c42fc5bSSteven Rostedt } 13885c42fc5bSSteven Rostedt 13895c42fc5bSSteven Rostedt if ($full_line =~ /Kernel panic -/) { 139010abf118SSteven Rostedt $failure_start = time; 13912545eb61SSteven Rostedt $bug = 1; 13922545eb61SSteven Rostedt } 13932545eb61SSteven Rostedt 1394f1a5b962SSteven Rostedt # Detect triple faults by testing the banner 1395f1a5b962SSteven Rostedt if ($full_line =~ /\bLinux version (\S+).*\n/) { 1396f1a5b962SSteven Rostedt if ($1 eq $version) { 1397f1a5b962SSteven Rostedt $version_found = 1; 1398f1a5b962SSteven Rostedt } elsif ($version_found && $detect_triplefault) { 1399f1a5b962SSteven Rostedt # We already booted into the kernel we are testing, 1400f1a5b962SSteven Rostedt # but now we booted into another kernel? 1401f1a5b962SSteven Rostedt # Consider this a triple fault. 1402f1a5b962SSteven Rostedt doprint "Aleady booted in Linux kernel $version, but now\n"; 1403f1a5b962SSteven Rostedt doprint "we booted into Linux kernel $1.\n"; 1404f1a5b962SSteven Rostedt doprint "Assuming that this is a triple fault.\n"; 1405f1a5b962SSteven Rostedt doprint "To disable this: set DETECT_TRIPLE_FAULT to 0\n"; 1406f1a5b962SSteven Rostedt last; 1407f1a5b962SSteven Rostedt } 1408f1a5b962SSteven Rostedt } 1409f1a5b962SSteven Rostedt 14102545eb61SSteven Rostedt if ($line =~ /\n/) { 14112545eb61SSteven Rostedt $full_line = ""; 14122545eb61SSteven Rostedt } 14132d01b26aSSteven Rostedt 14142d01b26aSSteven Rostedt if ($stop_test_after > 0 && !$booted && !$bug) { 14152d01b26aSSteven Rostedt if (time - $monitor_start > $stop_test_after) { 14164d62bf51SSteven Rostedt doprint "STOP_TEST_AFTER ($stop_test_after seconds) timed out\n"; 14172d01b26aSSteven Rostedt $done = 1; 14182d01b26aSSteven Rostedt } 14192d01b26aSSteven Rostedt } 14202545eb61SSteven Rostedt } 14212545eb61SSteven Rostedt 14227faafbd6SSteven Rostedt close(DMESG); 14232545eb61SSteven Rostedt 14242545eb61SSteven Rostedt if ($bug) { 14252b7d9b21SSteven Rostedt return 0 if ($in_bisect); 1426576f627cSSteven Rostedt fail "failed - got a bug report" and return 0; 14272545eb61SSteven Rostedt } 14285f9b6cedSSteven Rostedt 1429a75fececSSteven Rostedt if (!$booted) { 1430a75fececSSteven Rostedt return 0 if ($in_bisect); 1431576f627cSSteven Rostedt fail "failed - never got a boot prompt." and return 0; 1432a75fececSSteven Rostedt } 1433a75fececSSteven Rostedt 14342b7d9b21SSteven Rostedt return 1; 14352545eb61SSteven Rostedt} 14362545eb61SSteven Rostedt 1437*2b29b2f8SSteven Rostedtsub eval_kernel_version { 1438*2b29b2f8SSteven Rostedt my ($option) = @_; 1439*2b29b2f8SSteven Rostedt 1440*2b29b2f8SSteven Rostedt $option =~ s/\$KERNEL_VERSION/$version/g; 1441*2b29b2f8SSteven Rostedt 1442*2b29b2f8SSteven Rostedt return $option; 1443*2b29b2f8SSteven Rostedt} 1444*2b29b2f8SSteven Rostedt 1445db05cfefSSteven Rostedtsub do_post_install { 1446db05cfefSSteven Rostedt 1447db05cfefSSteven Rostedt return if (!defined($post_install)); 1448db05cfefSSteven Rostedt 1449*2b29b2f8SSteven Rostedt my $cp_post_install = eval_kernel_version $post_install; 1450db05cfefSSteven Rostedt run_command "$cp_post_install" or 1451db05cfefSSteven Rostedt dodie "Failed to run post install"; 1452db05cfefSSteven Rostedt} 1453db05cfefSSteven Rostedt 14542545eb61SSteven Rostedtsub install { 14552545eb61SSteven Rostedt 1456e0a8742eSSteven Rostedt return if ($no_install); 1457e0a8742eSSteven Rostedt 1458*2b29b2f8SSteven Rostedt my $cp_target = eval_kernel_version $target_image; 1459*2b29b2f8SSteven Rostedt 1460*2b29b2f8SSteven Rostedt run_scp "$outputdir/$build_target", "$cp_target" or 14615c42fc5bSSteven Rostedt dodie "failed to copy image"; 14625f9b6cedSSteven Rostedt 14635f9b6cedSSteven Rostedt my $install_mods = 0; 14645f9b6cedSSteven Rostedt 14655f9b6cedSSteven Rostedt # should we process modules? 14665f9b6cedSSteven Rostedt $install_mods = 0; 146751ad1dd1SSteven Rostedt open(IN, "$output_config") or dodie("Can't read config file"); 14685f9b6cedSSteven Rostedt while (<IN>) { 14695f9b6cedSSteven Rostedt if (/CONFIG_MODULES(=y)?/) { 14705f9b6cedSSteven Rostedt $install_mods = 1 if (defined($1)); 14715f9b6cedSSteven Rostedt last; 14725f9b6cedSSteven Rostedt } 14735f9b6cedSSteven Rostedt } 14745f9b6cedSSteven Rostedt close(IN); 14755f9b6cedSSteven Rostedt 14765f9b6cedSSteven Rostedt if (!$install_mods) { 1477db05cfefSSteven Rostedt do_post_install; 14785f9b6cedSSteven Rostedt doprint "No modules needed\n"; 14795f9b6cedSSteven Rostedt return; 14802545eb61SSteven Rostedt } 14812545eb61SSteven Rostedt 1482a75fececSSteven Rostedt run_command "$make INSTALL_MOD_PATH=$tmpdir modules_install" or 14835f9b6cedSSteven Rostedt dodie "Failed to install modules"; 14845f9b6cedSSteven Rostedt 14852545eb61SSteven Rostedt my $modlib = "/lib/modules/$version"; 1486a57419b3SSteven Rostedt my $modtar = "ktest-mods.tar.bz2"; 14872545eb61SSteven Rostedt 1488e48c5293SSteven Rostedt run_ssh "rm -rf $modlib" or 14895c42fc5bSSteven Rostedt dodie "failed to remove old mods: $modlib"; 14902545eb61SSteven Rostedt 14915c42fc5bSSteven Rostedt # would be nice if scp -r did not follow symbolic links 1492a75fececSSteven Rostedt run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or 14935c42fc5bSSteven Rostedt dodie "making tarball"; 14945c42fc5bSSteven Rostedt 1495e48c5293SSteven Rostedt run_scp "$tmpdir/$modtar", "/tmp" or 14965c42fc5bSSteven Rostedt dodie "failed to copy modules"; 14975c42fc5bSSteven Rostedt 1498a75fececSSteven Rostedt unlink "$tmpdir/$modtar"; 14995c42fc5bSSteven Rostedt 1500e7b13441SSteven Rostedt run_ssh "'(cd / && tar xjf /tmp/$modtar)'" or 15015c42fc5bSSteven Rostedt dodie "failed to tar modules"; 15025c42fc5bSSteven Rostedt 1503e48c5293SSteven Rostedt run_ssh "rm -f /tmp/$modtar"; 15048b37ca8cSSteven Rostedt 1505db05cfefSSteven Rostedt do_post_install; 15062545eb61SSteven Rostedt} 15072545eb61SSteven Rostedt 1508ddf607e5SSteven Rostedtsub get_version { 1509ddf607e5SSteven Rostedt # get the release name 1510ddf607e5SSteven Rostedt doprint "$make kernelrelease ... "; 1511ddf607e5SSteven Rostedt $version = `$make kernelrelease | tail -1`; 1512ddf607e5SSteven Rostedt chomp($version); 1513ddf607e5SSteven Rostedt doprint "$version\n"; 1514ddf607e5SSteven Rostedt} 1515ddf607e5SSteven Rostedt 1516ddf607e5SSteven Rostedtsub start_monitor_and_boot { 15179f7424ccSSteven Rostedt # Make sure the stable kernel has finished booting 15189f7424ccSSteven Rostedt start_monitor; 15199f7424ccSSteven Rostedt wait_for_monitor 5; 15209f7424ccSSteven Rostedt end_monitor; 15219f7424ccSSteven Rostedt 1522ddf607e5SSteven Rostedt get_grub_index; 1523ddf607e5SSteven Rostedt get_version; 1524ddf607e5SSteven Rostedt install; 1525ddf607e5SSteven Rostedt 1526ddf607e5SSteven Rostedt start_monitor; 1527ddf607e5SSteven Rostedt return monitor; 1528ddf607e5SSteven Rostedt} 1529ddf607e5SSteven Rostedt 15306c5ee0beSSteven Rostedtsub check_buildlog { 15316c5ee0beSSteven Rostedt my ($patch) = @_; 15326c5ee0beSSteven Rostedt 15336c5ee0beSSteven Rostedt my @files = `git show $patch | diffstat -l`; 15346c5ee0beSSteven Rostedt 15356c5ee0beSSteven Rostedt open(IN, "git show $patch |") or 15366c5ee0beSSteven Rostedt dodie "failed to show $patch"; 15376c5ee0beSSteven Rostedt while (<IN>) { 15386c5ee0beSSteven Rostedt if (m,^--- a/(.*),) { 15396c5ee0beSSteven Rostedt chomp $1; 15406c5ee0beSSteven Rostedt $files[$#files] = $1; 15416c5ee0beSSteven Rostedt } 15426c5ee0beSSteven Rostedt } 15436c5ee0beSSteven Rostedt close(IN); 15446c5ee0beSSteven Rostedt 15456c5ee0beSSteven Rostedt open(IN, $buildlog) or dodie "Can't open $buildlog"; 15466c5ee0beSSteven Rostedt while (<IN>) { 15476c5ee0beSSteven Rostedt if (/^\s*(.*?):.*(warning|error)/) { 15486c5ee0beSSteven Rostedt my $err = $1; 15496c5ee0beSSteven Rostedt foreach my $file (@files) { 1550a75fececSSteven Rostedt my $fullpath = "$builddir/$file"; 15516c5ee0beSSteven Rostedt if ($file eq $err || $fullpath eq $err) { 15522b7d9b21SSteven Rostedt fail "$file built with warnings" and return 0; 15536c5ee0beSSteven Rostedt } 15546c5ee0beSSteven Rostedt } 15556c5ee0beSSteven Rostedt } 15566c5ee0beSSteven Rostedt } 15576c5ee0beSSteven Rostedt close(IN); 15582b7d9b21SSteven Rostedt 15592b7d9b21SSteven Rostedt return 1; 15606c5ee0beSSteven Rostedt} 15616c5ee0beSSteven Rostedt 1562fcb3f16aSSteven Rostedtsub apply_min_config { 1563fcb3f16aSSteven Rostedt my $outconfig = "$output_config.new"; 1564612b9e9bSSteven Rostedt 1565fcb3f16aSSteven Rostedt # Read the config file and remove anything that 1566fcb3f16aSSteven Rostedt # is in the force_config hash (from minconfig and others) 1567fcb3f16aSSteven Rostedt # then add the force config back. 1568fcb3f16aSSteven Rostedt 1569fcb3f16aSSteven Rostedt doprint "Applying minimum configurations into $output_config.new\n"; 1570fcb3f16aSSteven Rostedt 1571fcb3f16aSSteven Rostedt open (OUT, ">$outconfig") or 1572fcb3f16aSSteven Rostedt dodie "Can't create $outconfig"; 1573fcb3f16aSSteven Rostedt 1574fcb3f16aSSteven Rostedt if (-f $output_config) { 1575fcb3f16aSSteven Rostedt open (IN, $output_config) or 1576fcb3f16aSSteven Rostedt dodie "Failed to open $output_config"; 1577fcb3f16aSSteven Rostedt while (<IN>) { 1578fcb3f16aSSteven Rostedt if (/^(# )?(CONFIG_[^\s=]*)/) { 1579fcb3f16aSSteven Rostedt next if (defined($force_config{$2})); 1580fcb3f16aSSteven Rostedt } 1581fcb3f16aSSteven Rostedt print OUT; 1582fcb3f16aSSteven Rostedt } 1583fcb3f16aSSteven Rostedt close IN; 1584fcb3f16aSSteven Rostedt } 1585fcb3f16aSSteven Rostedt foreach my $config (keys %force_config) { 1586fcb3f16aSSteven Rostedt print OUT "$force_config{$config}\n"; 1587fcb3f16aSSteven Rostedt } 1588fcb3f16aSSteven Rostedt close OUT; 1589fcb3f16aSSteven Rostedt 1590fcb3f16aSSteven Rostedt run_command "mv $outconfig $output_config"; 1591fcb3f16aSSteven Rostedt} 1592fcb3f16aSSteven Rostedt 1593fcb3f16aSSteven Rostedtsub make_oldconfig { 1594fcb3f16aSSteven Rostedt 15954c4ab120SSteven Rostedt my @force_list = keys %force_config; 15964c4ab120SSteven Rostedt 15974c4ab120SSteven Rostedt if ($#force_list >= 0) { 1598fcb3f16aSSteven Rostedt apply_min_config; 15994c4ab120SSteven Rostedt } 1600fcb3f16aSSteven Rostedt 1601fcb3f16aSSteven Rostedt if (!run_command "$make oldnoconfig") { 1602612b9e9bSSteven Rostedt # Perhaps oldnoconfig doesn't exist in this version of the kernel 1603612b9e9bSSteven Rostedt # try a yes '' | oldconfig 1604612b9e9bSSteven Rostedt doprint "oldnoconfig failed, trying yes '' | make oldconfig\n"; 1605fcb3f16aSSteven Rostedt run_command "yes '' | $make oldconfig" or 1606612b9e9bSSteven Rostedt dodie "failed make config oldconfig"; 1607612b9e9bSSteven Rostedt } 1608612b9e9bSSteven Rostedt} 1609612b9e9bSSteven Rostedt 1610fcb3f16aSSteven Rostedt# read a config file and use this to force new configs. 1611fcb3f16aSSteven Rostedtsub load_force_config { 1612fcb3f16aSSteven Rostedt my ($config) = @_; 1613fcb3f16aSSteven Rostedt 1614fcb3f16aSSteven Rostedt open(IN, $config) or 1615fcb3f16aSSteven Rostedt dodie "failed to read $config"; 1616fcb3f16aSSteven Rostedt while (<IN>) { 1617fcb3f16aSSteven Rostedt chomp; 1618fcb3f16aSSteven Rostedt if (/^(CONFIG[^\s=]*)(\s*=.*)/) { 1619fcb3f16aSSteven Rostedt $force_config{$1} = $_; 1620fcb3f16aSSteven Rostedt } elsif (/^# (CONFIG_\S*) is not set/) { 1621fcb3f16aSSteven Rostedt $force_config{$1} = $_; 1622fcb3f16aSSteven Rostedt } 1623fcb3f16aSSteven Rostedt } 1624fcb3f16aSSteven Rostedt close IN; 1625fcb3f16aSSteven Rostedt} 1626fcb3f16aSSteven Rostedt 16272545eb61SSteven Rostedtsub build { 16282545eb61SSteven Rostedt my ($type) = @_; 16292545eb61SSteven Rostedt 16307faafbd6SSteven Rostedt unlink $buildlog; 16317faafbd6SSteven Rostedt 16324ab1cce5SSteven Rostedt # Failed builds should not reboot the target 16334ab1cce5SSteven Rostedt my $save_no_reboot = $no_reboot; 16344ab1cce5SSteven Rostedt $no_reboot = 1; 16354ab1cce5SSteven Rostedt 16360bd6c1a3SSteven Rostedt if (defined($pre_build)) { 16370bd6c1a3SSteven Rostedt my $ret = run_command $pre_build; 16380bd6c1a3SSteven Rostedt if (!$ret && defined($pre_build_die) && 16390bd6c1a3SSteven Rostedt $pre_build_die) { 16400bd6c1a3SSteven Rostedt dodie "failed to pre_build\n"; 16410bd6c1a3SSteven Rostedt } 16420bd6c1a3SSteven Rostedt } 16430bd6c1a3SSteven Rostedt 164475c3fda7SSteven Rostedt if ($type =~ /^useconfig:(.*)/) { 164551ad1dd1SSteven Rostedt run_command "cp $1 $output_config" or 164675c3fda7SSteven Rostedt dodie "could not copy $1 to .config"; 16475f9b6cedSSteven Rostedt 164875c3fda7SSteven Rostedt $type = "oldconfig"; 164975c3fda7SSteven Rostedt } 165075c3fda7SSteven Rostedt 16515c42fc5bSSteven Rostedt # old config can ask questions 16525c42fc5bSSteven Rostedt if ($type eq "oldconfig") { 16539386c6abSSteven Rostedt $type = "oldnoconfig"; 165475c3fda7SSteven Rostedt 165575c3fda7SSteven Rostedt # allow for empty configs 165651ad1dd1SSteven Rostedt run_command "touch $output_config"; 165775c3fda7SSteven Rostedt 165813488231SAndrew Jones if (!$noclean) { 165951ad1dd1SSteven Rostedt run_command "mv $output_config $outputdir/config_temp" or 16605c42fc5bSSteven Rostedt dodie "moving .config"; 16615c42fc5bSSteven Rostedt 166213488231SAndrew Jones run_command "$make mrproper" or dodie "make mrproper"; 16635c42fc5bSSteven Rostedt 166451ad1dd1SSteven Rostedt run_command "mv $outputdir/config_temp $output_config" or 16655c42fc5bSSteven Rostedt dodie "moving config_temp"; 166613488231SAndrew Jones } 16675c42fc5bSSteven Rostedt 16685c42fc5bSSteven Rostedt } elsif (!$noclean) { 166951ad1dd1SSteven Rostedt unlink "$output_config"; 16705f9b6cedSSteven Rostedt run_command "$make mrproper" or 16715c42fc5bSSteven Rostedt dodie "make mrproper"; 16725c42fc5bSSteven Rostedt } 16732545eb61SSteven Rostedt 16742545eb61SSteven Rostedt # add something to distinguish this build 1675a75fececSSteven Rostedt open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file"); 1676a75fececSSteven Rostedt print OUT "$localversion\n"; 16772545eb61SSteven Rostedt close(OUT); 16782545eb61SSteven Rostedt 16795f9b6cedSSteven Rostedt if (defined($minconfig)) { 1680fcb3f16aSSteven Rostedt load_force_config($minconfig); 16812545eb61SSteven Rostedt } 16822545eb61SSteven Rostedt 1683fcb3f16aSSteven Rostedt if ($type ne "oldnoconfig") { 1684fcb3f16aSSteven Rostedt run_command "$make $type" or 16855c42fc5bSSteven Rostedt dodie "failed make config"; 1686612b9e9bSSteven Rostedt } 1687fcb3f16aSSteven Rostedt # Run old config regardless, to enforce min configurations 1688fcb3f16aSSteven Rostedt make_oldconfig; 16892545eb61SSteven Rostedt 1690a75fececSSteven Rostedt $redirect = "$buildlog"; 16910bd6c1a3SSteven Rostedt my $build_ret = run_command "$make $build_options"; 16926c5ee0beSSteven Rostedt undef $redirect; 16930bd6c1a3SSteven Rostedt 16940bd6c1a3SSteven Rostedt if (defined($post_build)) { 16950bd6c1a3SSteven Rostedt my $ret = run_command $post_build; 16960bd6c1a3SSteven Rostedt if (!$ret && defined($post_build_die) && 16970bd6c1a3SSteven Rostedt $post_build_die) { 16980bd6c1a3SSteven Rostedt dodie "failed to post_build\n"; 16990bd6c1a3SSteven Rostedt } 17000bd6c1a3SSteven Rostedt } 17010bd6c1a3SSteven Rostedt 17020bd6c1a3SSteven Rostedt if (!$build_ret) { 17035f9b6cedSSteven Rostedt # bisect may need this to pass 17044ab1cce5SSteven Rostedt if ($in_bisect) { 17054ab1cce5SSteven Rostedt $no_reboot = $save_no_reboot; 17064ab1cce5SSteven Rostedt return 0; 17074ab1cce5SSteven Rostedt } 17082b7d9b21SSteven Rostedt fail "failed build" and return 0; 17092545eb61SSteven Rostedt } 17105f9b6cedSSteven Rostedt 17114ab1cce5SSteven Rostedt $no_reboot = $save_no_reboot; 17124ab1cce5SSteven Rostedt 17132b7d9b21SSteven Rostedt return 1; 17142545eb61SSteven Rostedt} 17152545eb61SSteven Rostedt 171675c3fda7SSteven Rostedtsub halt { 1717e48c5293SSteven Rostedt if (!run_ssh "halt" or defined($power_off)) { 1718576f627cSSteven Rostedt if (defined($poweroff_after_halt)) { 1719576f627cSSteven Rostedt sleep $poweroff_after_halt; 1720576f627cSSteven Rostedt run_command "$power_off"; 1721576f627cSSteven Rostedt } 1722576f627cSSteven Rostedt } else { 172375c3fda7SSteven Rostedt # nope? the zap it! 1724a75fececSSteven Rostedt run_command "$power_off"; 172575c3fda7SSteven Rostedt } 172675c3fda7SSteven Rostedt} 172775c3fda7SSteven Rostedt 17285f9b6cedSSteven Rostedtsub success { 17295f9b6cedSSteven Rostedt my ($i) = @_; 17305f9b6cedSSteven Rostedt 1731e48c5293SSteven Rostedt $successes++; 1732e48c5293SSteven Rostedt 17339064af52SSteven Rostedt my $name = ""; 17349064af52SSteven Rostedt 17359064af52SSteven Rostedt if (defined($test_name)) { 17369064af52SSteven Rostedt $name = " ($test_name)"; 17379064af52SSteven Rostedt } 17389064af52SSteven Rostedt 17395f9b6cedSSteven Rostedt doprint "\n\n*******************************************\n"; 17405f9b6cedSSteven Rostedt doprint "*******************************************\n"; 17419064af52SSteven Rostedt doprint "KTEST RESULT: TEST $i$name SUCCESS!!!! **\n"; 17425f9b6cedSSteven Rostedt doprint "*******************************************\n"; 17435f9b6cedSSteven Rostedt doprint "*******************************************\n"; 17445f9b6cedSSteven Rostedt 1745de5b6e3bSRabin Vincent if (defined($store_successes)) { 1746de5b6e3bSRabin Vincent save_logs "success", $store_successes; 1747de5b6e3bSRabin Vincent } 1748de5b6e3bSRabin Vincent 1749576f627cSSteven Rostedt if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) { 1750a75fececSSteven Rostedt doprint "Reboot and wait $sleep_time seconds\n"; 17512728be41SAndrew Jones reboot $sleep_time; 17525f9b6cedSSteven Rostedt } 17535f9b6cedSSteven Rostedt} 17545f9b6cedSSteven Rostedt 1755c960bb9fSSteven Rostedtsub answer_bisect { 1756c960bb9fSSteven Rostedt for (;;) { 1757c960bb9fSSteven Rostedt doprint "Pass or fail? [p/f]"; 1758c960bb9fSSteven Rostedt my $ans = <STDIN>; 1759c960bb9fSSteven Rostedt chomp $ans; 1760c960bb9fSSteven Rostedt if ($ans eq "p" || $ans eq "P") { 1761c960bb9fSSteven Rostedt return 1; 1762c960bb9fSSteven Rostedt } elsif ($ans eq "f" || $ans eq "F") { 1763c960bb9fSSteven Rostedt return 0; 1764c960bb9fSSteven Rostedt } else { 1765c960bb9fSSteven Rostedt print "Please answer 'P' or 'F'\n"; 1766c960bb9fSSteven Rostedt } 1767c960bb9fSSteven Rostedt } 1768c960bb9fSSteven Rostedt} 1769c960bb9fSSteven Rostedt 17705a391fbfSSteven Rostedtsub child_run_test { 17717faafbd6SSteven Rostedt my $failed = 0; 17725a391fbfSSteven Rostedt 17737faafbd6SSteven Rostedt # child should have no power 1774a75fececSSteven Rostedt $reboot_on_error = 0; 1775a75fececSSteven Rostedt $poweroff_on_error = 0; 1776a75fececSSteven Rostedt $die_on_failure = 1; 17777faafbd6SSteven Rostedt 1778a9dd5d63SRabin Vincent $redirect = "$testlog"; 17797faafbd6SSteven Rostedt run_command $run_test or $failed = 1; 1780a9dd5d63SRabin Vincent undef $redirect; 1781a9dd5d63SRabin Vincent 17825a391fbfSSteven Rostedt exit $failed; 17835a391fbfSSteven Rostedt} 17845a391fbfSSteven Rostedt 17855a391fbfSSteven Rostedtmy $child_done; 17865a391fbfSSteven Rostedt 17875a391fbfSSteven Rostedtsub child_finished { 17885a391fbfSSteven Rostedt $child_done = 1; 17895a391fbfSSteven Rostedt} 17905a391fbfSSteven Rostedt 17915a391fbfSSteven Rostedtsub do_run_test { 17925a391fbfSSteven Rostedt my $child_pid; 17935a391fbfSSteven Rostedt my $child_exit; 17945a391fbfSSteven Rostedt my $line; 17955a391fbfSSteven Rostedt my $full_line; 17965a391fbfSSteven Rostedt my $bug = 0; 17975a391fbfSSteven Rostedt 17987faafbd6SSteven Rostedt wait_for_monitor 1; 17995a391fbfSSteven Rostedt 18007faafbd6SSteven Rostedt doprint "run test $run_test\n"; 18015a391fbfSSteven Rostedt 18025a391fbfSSteven Rostedt $child_done = 0; 18035a391fbfSSteven Rostedt 18045a391fbfSSteven Rostedt $SIG{CHLD} = qw(child_finished); 18055a391fbfSSteven Rostedt 18065a391fbfSSteven Rostedt $child_pid = fork; 18075a391fbfSSteven Rostedt 18085a391fbfSSteven Rostedt child_run_test if (!$child_pid); 18095a391fbfSSteven Rostedt 18105a391fbfSSteven Rostedt $full_line = ""; 18115a391fbfSSteven Rostedt 18125a391fbfSSteven Rostedt do { 18137faafbd6SSteven Rostedt $line = wait_for_input($monitor_fp, 1); 18145a391fbfSSteven Rostedt if (defined($line)) { 18155a391fbfSSteven Rostedt 18165a391fbfSSteven Rostedt # we are not guaranteed to get a full line 18175a391fbfSSteven Rostedt $full_line .= $line; 18188ea0e063SSteven Rostedt doprint $line; 18195a391fbfSSteven Rostedt 18205a391fbfSSteven Rostedt if ($full_line =~ /call trace:/i) { 18215a391fbfSSteven Rostedt $bug = 1; 18225a391fbfSSteven Rostedt } 18235a391fbfSSteven Rostedt 18245a391fbfSSteven Rostedt if ($full_line =~ /Kernel panic -/) { 18255a391fbfSSteven Rostedt $bug = 1; 18265a391fbfSSteven Rostedt } 18275a391fbfSSteven Rostedt 18285a391fbfSSteven Rostedt if ($line =~ /\n/) { 18295a391fbfSSteven Rostedt $full_line = ""; 18305a391fbfSSteven Rostedt } 18315a391fbfSSteven Rostedt } 18325a391fbfSSteven Rostedt } while (!$child_done && !$bug); 18335a391fbfSSteven Rostedt 18345a391fbfSSteven Rostedt if ($bug) { 18358ea0e063SSteven Rostedt my $failure_start = time; 18368ea0e063SSteven Rostedt my $now; 18378ea0e063SSteven Rostedt do { 18388ea0e063SSteven Rostedt $line = wait_for_input($monitor_fp, 1); 18398ea0e063SSteven Rostedt if (defined($line)) { 18408ea0e063SSteven Rostedt doprint $line; 18418ea0e063SSteven Rostedt } 18428ea0e063SSteven Rostedt $now = time; 18438ea0e063SSteven Rostedt if ($now - $failure_start >= $stop_after_failure) { 18448ea0e063SSteven Rostedt last; 18458ea0e063SSteven Rostedt } 18468ea0e063SSteven Rostedt } while (defined($line)); 18478ea0e063SSteven Rostedt 18485a391fbfSSteven Rostedt doprint "Detected kernel crash!\n"; 18495a391fbfSSteven Rostedt # kill the child with extreme prejudice 18505a391fbfSSteven Rostedt kill 9, $child_pid; 18515a391fbfSSteven Rostedt } 18525a391fbfSSteven Rostedt 18535a391fbfSSteven Rostedt waitpid $child_pid, 0; 18545a391fbfSSteven Rostedt $child_exit = $?; 18555a391fbfSSteven Rostedt 18565a391fbfSSteven Rostedt if ($bug || $child_exit) { 18572b7d9b21SSteven Rostedt return 0 if $in_bisect; 18582b7d9b21SSteven Rostedt fail "test failed" and return 0; 18595a391fbfSSteven Rostedt } 18602b7d9b21SSteven Rostedt return 1; 18615a391fbfSSteven Rostedt} 18625a391fbfSSteven Rostedt 1863a75fececSSteven Rostedtsub run_git_bisect { 1864a75fececSSteven Rostedt my ($command) = @_; 1865a75fececSSteven Rostedt 1866a75fececSSteven Rostedt doprint "$command ... "; 1867a75fececSSteven Rostedt 1868a75fececSSteven Rostedt my $output = `$command 2>&1`; 1869a75fececSSteven Rostedt my $ret = $?; 1870a75fececSSteven Rostedt 1871a75fececSSteven Rostedt logit $output; 1872a75fececSSteven Rostedt 1873a75fececSSteven Rostedt if ($ret) { 1874a75fececSSteven Rostedt doprint "FAILED\n"; 1875a75fececSSteven Rostedt dodie "Failed to git bisect"; 1876a75fececSSteven Rostedt } 1877a75fececSSteven Rostedt 1878a75fececSSteven Rostedt doprint "SUCCESS\n"; 1879a75fececSSteven Rostedt if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) { 1880a75fececSSteven Rostedt doprint "$1 [$2]\n"; 1881a75fececSSteven Rostedt } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) { 1882a75fececSSteven Rostedt $bisect_bad = $1; 1883a75fececSSteven Rostedt doprint "Found bad commit... $1\n"; 1884a75fececSSteven Rostedt return 0; 1885a75fececSSteven Rostedt } else { 1886a75fececSSteven Rostedt # we already logged it, just print it now. 1887a75fececSSteven Rostedt print $output; 1888a75fececSSteven Rostedt } 1889a75fececSSteven Rostedt 1890a75fececSSteven Rostedt return 1; 1891a75fececSSteven Rostedt} 1892a75fececSSteven Rostedt 1893c23dca7cSSteven Rostedtsub bisect_reboot { 1894c23dca7cSSteven Rostedt doprint "Reboot and sleep $bisect_sleep_time seconds\n"; 18952728be41SAndrew Jones reboot $bisect_sleep_time; 1896c23dca7cSSteven Rostedt} 1897c23dca7cSSteven Rostedt 1898c23dca7cSSteven Rostedt# returns 1 on success, 0 on failure, -1 on skip 18990a05c769SSteven Rostedtsub run_bisect_test { 19000a05c769SSteven Rostedt my ($type, $buildtype) = @_; 19015f9b6cedSSteven Rostedt 19022b7d9b21SSteven Rostedt my $failed = 0; 19035f9b6cedSSteven Rostedt my $result; 19045f9b6cedSSteven Rostedt my $output; 19055f9b6cedSSteven Rostedt my $ret; 19065f9b6cedSSteven Rostedt 19070a05c769SSteven Rostedt $in_bisect = 1; 19080a05c769SSteven Rostedt 19090a05c769SSteven Rostedt build $buildtype or $failed = 1; 19105f9b6cedSSteven Rostedt 19115f9b6cedSSteven Rostedt if ($type ne "build") { 1912c23dca7cSSteven Rostedt if ($failed && $bisect_skip) { 1913c23dca7cSSteven Rostedt $in_bisect = 0; 1914c23dca7cSSteven Rostedt return -1; 1915c23dca7cSSteven Rostedt } 19167faafbd6SSteven Rostedt dodie "Failed on build" if $failed; 19175f9b6cedSSteven Rostedt 19185f9b6cedSSteven Rostedt # Now boot the box 1919ddf607e5SSteven Rostedt start_monitor_and_boot or $failed = 1; 19205f9b6cedSSteven Rostedt 19215f9b6cedSSteven Rostedt if ($type ne "boot") { 1922c23dca7cSSteven Rostedt if ($failed && $bisect_skip) { 1923c23dca7cSSteven Rostedt end_monitor; 1924c23dca7cSSteven Rostedt bisect_reboot; 1925c23dca7cSSteven Rostedt $in_bisect = 0; 1926c23dca7cSSteven Rostedt return -1; 1927c23dca7cSSteven Rostedt } 19287faafbd6SSteven Rostedt dodie "Failed on boot" if $failed; 19295a391fbfSSteven Rostedt 19302b7d9b21SSteven Rostedt do_run_test or $failed = 1; 19315f9b6cedSSteven Rostedt } 19327faafbd6SSteven Rostedt end_monitor; 19335f9b6cedSSteven Rostedt } 19345f9b6cedSSteven Rostedt 19355f9b6cedSSteven Rostedt if ($failed) { 19360a05c769SSteven Rostedt $result = 0; 19375f9b6cedSSteven Rostedt } else { 19380a05c769SSteven Rostedt $result = 1; 19395f9b6cedSSteven Rostedt } 19404025bc62SSteven Rostedt 19414025bc62SSteven Rostedt # reboot the box to a kernel we can ssh to 19424025bc62SSteven Rostedt if ($type ne "build") { 19434025bc62SSteven Rostedt bisect_reboot; 19444025bc62SSteven Rostedt } 19450a05c769SSteven Rostedt $in_bisect = 0; 19460a05c769SSteven Rostedt 19470a05c769SSteven Rostedt return $result; 19480a05c769SSteven Rostedt} 19490a05c769SSteven Rostedt 19500a05c769SSteven Rostedtsub run_bisect { 19510a05c769SSteven Rostedt my ($type) = @_; 19520a05c769SSteven Rostedt my $buildtype = "oldconfig"; 19530a05c769SSteven Rostedt 19540a05c769SSteven Rostedt # We should have a minconfig to use? 19550a05c769SSteven Rostedt if (defined($minconfig)) { 19560a05c769SSteven Rostedt $buildtype = "useconfig:$minconfig"; 19570a05c769SSteven Rostedt } 19580a05c769SSteven Rostedt 19590a05c769SSteven Rostedt my $ret = run_bisect_test $type, $buildtype; 19600a05c769SSteven Rostedt 1961c960bb9fSSteven Rostedt if ($bisect_manual) { 1962c960bb9fSSteven Rostedt $ret = answer_bisect; 1963c960bb9fSSteven Rostedt } 19645f9b6cedSSteven Rostedt 1965d6ce2a0bSSteven Rostedt # Are we looking for where it worked, not failed? 1966d6ce2a0bSSteven Rostedt if ($reverse_bisect) { 19670a05c769SSteven Rostedt $ret = !$ret; 1968d6ce2a0bSSteven Rostedt } 1969d6ce2a0bSSteven Rostedt 1970c23dca7cSSteven Rostedt if ($ret > 0) { 19710a05c769SSteven Rostedt return "good"; 1972c23dca7cSSteven Rostedt } elsif ($ret == 0) { 19730a05c769SSteven Rostedt return "bad"; 1974c23dca7cSSteven Rostedt } elsif ($bisect_skip) { 1975c23dca7cSSteven Rostedt doprint "HIT A BAD COMMIT ... SKIPPING\n"; 1976c23dca7cSSteven Rostedt return "skip"; 19770a05c769SSteven Rostedt } 19785f9b6cedSSteven Rostedt} 19795f9b6cedSSteven Rostedt 1980dad98754SSteven Rostedtsub update_bisect_replay { 1981dad98754SSteven Rostedt my $tmp_log = "$tmpdir/ktest_bisect_log"; 1982dad98754SSteven Rostedt run_command "git bisect log > $tmp_log" or 1983dad98754SSteven Rostedt die "can't create bisect log"; 1984dad98754SSteven Rostedt return $tmp_log; 1985dad98754SSteven Rostedt} 1986dad98754SSteven Rostedt 19875f9b6cedSSteven Rostedtsub bisect { 19885f9b6cedSSteven Rostedt my ($i) = @_; 19895f9b6cedSSteven Rostedt 19905f9b6cedSSteven Rostedt my $result; 19915f9b6cedSSteven Rostedt 19925f9b6cedSSteven Rostedt die "BISECT_GOOD[$i] not defined\n" if (!defined($opt{"BISECT_GOOD[$i]"})); 19935f9b6cedSSteven Rostedt die "BISECT_BAD[$i] not defined\n" if (!defined($opt{"BISECT_BAD[$i]"})); 19945f9b6cedSSteven Rostedt die "BISECT_TYPE[$i] not defined\n" if (!defined($opt{"BISECT_TYPE[$i]"})); 19955f9b6cedSSteven Rostedt 19965f9b6cedSSteven Rostedt my $good = $opt{"BISECT_GOOD[$i]"}; 19975f9b6cedSSteven Rostedt my $bad = $opt{"BISECT_BAD[$i]"}; 19985f9b6cedSSteven Rostedt my $type = $opt{"BISECT_TYPE[$i]"}; 1999a75fececSSteven Rostedt my $start = $opt{"BISECT_START[$i]"}; 2000a75fececSSteven Rostedt my $replay = $opt{"BISECT_REPLAY[$i]"}; 20013410f6fdSSteven Rostedt my $start_files = $opt{"BISECT_FILES[$i]"}; 20023410f6fdSSteven Rostedt 20033410f6fdSSteven Rostedt if (defined($start_files)) { 20043410f6fdSSteven Rostedt $start_files = " -- " . $start_files; 20053410f6fdSSteven Rostedt } else { 20063410f6fdSSteven Rostedt $start_files = ""; 20073410f6fdSSteven Rostedt } 20085f9b6cedSSteven Rostedt 2009a57419b3SSteven Rostedt # convert to true sha1's 2010a57419b3SSteven Rostedt $good = get_sha1($good); 2011a57419b3SSteven Rostedt $bad = get_sha1($bad); 2012a57419b3SSteven Rostedt 2013d6ce2a0bSSteven Rostedt if (defined($opt{"BISECT_REVERSE[$i]"}) && 2014d6ce2a0bSSteven Rostedt $opt{"BISECT_REVERSE[$i]"} == 1) { 2015d6ce2a0bSSteven Rostedt doprint "Performing a reverse bisect (bad is good, good is bad!)\n"; 2016d6ce2a0bSSteven Rostedt $reverse_bisect = 1; 2017d6ce2a0bSSteven Rostedt } else { 2018d6ce2a0bSSteven Rostedt $reverse_bisect = 0; 2019d6ce2a0bSSteven Rostedt } 2020d6ce2a0bSSteven Rostedt 20215a391fbfSSteven Rostedt # Can't have a test without having a test to run 20225a391fbfSSteven Rostedt if ($type eq "test" && !defined($run_test)) { 20235a391fbfSSteven Rostedt $type = "boot"; 20245a391fbfSSteven Rostedt } 20255a391fbfSSteven Rostedt 2026dad98754SSteven Rostedt # Check if a bisect was running 2027dad98754SSteven Rostedt my $bisect_start_file = "$builddir/.git/BISECT_START"; 2028dad98754SSteven Rostedt 2029a75fececSSteven Rostedt my $check = $opt{"BISECT_CHECK[$i]"}; 2030dad98754SSteven Rostedt my $do_check = defined($check) && $check ne "0"; 2031dad98754SSteven Rostedt 2032dad98754SSteven Rostedt if ( -f $bisect_start_file ) { 2033dad98754SSteven Rostedt print "Bisect in progress found\n"; 2034dad98754SSteven Rostedt if ($do_check) { 2035dad98754SSteven Rostedt print " If you say yes, then no checks of good or bad will be done\n"; 2036dad98754SSteven Rostedt } 2037dad98754SSteven Rostedt if (defined($replay)) { 2038dad98754SSteven Rostedt print "** BISECT_REPLAY is defined in config file **"; 2039dad98754SSteven Rostedt print " Ignore config option and perform new git bisect log?\n"; 2040dad98754SSteven Rostedt if (read_ync " (yes, no, or cancel) ") { 2041dad98754SSteven Rostedt $replay = update_bisect_replay; 2042dad98754SSteven Rostedt $do_check = 0; 2043dad98754SSteven Rostedt } 2044dad98754SSteven Rostedt } elsif (read_yn "read git log and continue?") { 2045dad98754SSteven Rostedt $replay = update_bisect_replay; 2046dad98754SSteven Rostedt $do_check = 0; 2047dad98754SSteven Rostedt } 2048dad98754SSteven Rostedt } 2049dad98754SSteven Rostedt 2050dad98754SSteven Rostedt if ($do_check) { 2051a75fececSSteven Rostedt 2052a75fececSSteven Rostedt # get current HEAD 2053a57419b3SSteven Rostedt my $head = get_sha1("HEAD"); 2054a75fececSSteven Rostedt 2055a75fececSSteven Rostedt if ($check ne "good") { 2056a75fececSSteven Rostedt doprint "TESTING BISECT BAD [$bad]\n"; 2057a75fececSSteven Rostedt run_command "git checkout $bad" or 2058a75fececSSteven Rostedt die "Failed to checkout $bad"; 2059a75fececSSteven Rostedt 2060a75fececSSteven Rostedt $result = run_bisect $type; 2061a75fececSSteven Rostedt 2062a75fececSSteven Rostedt if ($result ne "bad") { 2063a75fececSSteven Rostedt fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0; 2064a75fececSSteven Rostedt } 2065a75fececSSteven Rostedt } 2066a75fececSSteven Rostedt 2067a75fececSSteven Rostedt if ($check ne "bad") { 2068a75fececSSteven Rostedt doprint "TESTING BISECT GOOD [$good]\n"; 2069a75fececSSteven Rostedt run_command "git checkout $good" or 2070a75fececSSteven Rostedt die "Failed to checkout $good"; 2071a75fececSSteven Rostedt 2072a75fececSSteven Rostedt $result = run_bisect $type; 2073a75fececSSteven Rostedt 2074a75fececSSteven Rostedt if ($result ne "good") { 2075a75fececSSteven Rostedt fail "Tested BISECT_GOOD [$good] and it failed" and return 0; 2076a75fececSSteven Rostedt } 2077a75fececSSteven Rostedt } 2078a75fececSSteven Rostedt 2079a75fececSSteven Rostedt # checkout where we started 2080a75fececSSteven Rostedt run_command "git checkout $head" or 2081a75fececSSteven Rostedt die "Failed to checkout $head"; 2082a75fececSSteven Rostedt } 2083a75fececSSteven Rostedt 20843410f6fdSSteven Rostedt run_command "git bisect start$start_files" or 2085a75fececSSteven Rostedt dodie "could not start bisect"; 2086a75fececSSteven Rostedt 2087a75fececSSteven Rostedt run_command "git bisect good $good" or 2088a75fececSSteven Rostedt dodie "could not set bisect good to $good"; 2089a75fececSSteven Rostedt 2090a75fececSSteven Rostedt run_git_bisect "git bisect bad $bad" or 2091a75fececSSteven Rostedt dodie "could not set bisect bad to $bad"; 2092a75fececSSteven Rostedt 2093a75fececSSteven Rostedt if (defined($replay)) { 2094a75fececSSteven Rostedt run_command "git bisect replay $replay" or 2095a75fececSSteven Rostedt dodie "failed to run replay"; 2096a75fececSSteven Rostedt } 2097a75fececSSteven Rostedt 2098a75fececSSteven Rostedt if (defined($start)) { 2099a75fececSSteven Rostedt run_command "git checkout $start" or 2100a75fececSSteven Rostedt dodie "failed to checkout $start"; 2101a75fececSSteven Rostedt } 2102a75fececSSteven Rostedt 2103a75fececSSteven Rostedt my $test; 21045f9b6cedSSteven Rostedt do { 21055f9b6cedSSteven Rostedt $result = run_bisect $type; 2106a75fececSSteven Rostedt $test = run_git_bisect "git bisect $result"; 2107a75fececSSteven Rostedt } while ($test); 21085f9b6cedSSteven Rostedt 21095f9b6cedSSteven Rostedt run_command "git bisect log" or 21105f9b6cedSSteven Rostedt dodie "could not capture git bisect log"; 21115f9b6cedSSteven Rostedt 21125f9b6cedSSteven Rostedt run_command "git bisect reset" or 21135f9b6cedSSteven Rostedt dodie "could not reset git bisect"; 21145f9b6cedSSteven Rostedt 21155f9b6cedSSteven Rostedt doprint "Bad commit was [$bisect_bad]\n"; 21165f9b6cedSSteven Rostedt 21170a05c769SSteven Rostedt success $i; 21180a05c769SSteven Rostedt} 21190a05c769SSteven Rostedt 21200a05c769SSteven Rostedtmy %config_ignore; 21210a05c769SSteven Rostedtmy %config_set; 21220a05c769SSteven Rostedt 21230a05c769SSteven Rostedtmy %config_list; 21240a05c769SSteven Rostedtmy %null_config; 21250a05c769SSteven Rostedt 21260a05c769SSteven Rostedtmy %dependency; 21270a05c769SSteven Rostedt 21284c4ab120SSteven Rostedtsub assign_configs { 21294c4ab120SSteven Rostedt my ($hash, $config) = @_; 21300a05c769SSteven Rostedt 21310a05c769SSteven Rostedt open (IN, $config) 21320a05c769SSteven Rostedt or dodie "Failed to read $config"; 21330a05c769SSteven Rostedt 21340a05c769SSteven Rostedt while (<IN>) { 21359bf71749SSteven Rostedt if (/^((CONFIG\S*)=.*)/) { 21364c4ab120SSteven Rostedt ${$hash}{$2} = $1; 21370a05c769SSteven Rostedt } 21380a05c769SSteven Rostedt } 21390a05c769SSteven Rostedt 21400a05c769SSteven Rostedt close(IN); 21410a05c769SSteven Rostedt} 21420a05c769SSteven Rostedt 21434c4ab120SSteven Rostedtsub process_config_ignore { 21444c4ab120SSteven Rostedt my ($config) = @_; 21454c4ab120SSteven Rostedt 21464c4ab120SSteven Rostedt assign_configs \%config_ignore, $config; 21474c4ab120SSteven Rostedt} 21484c4ab120SSteven Rostedt 21490a05c769SSteven Rostedtsub read_current_config { 21500a05c769SSteven Rostedt my ($config_ref) = @_; 21510a05c769SSteven Rostedt 21520a05c769SSteven Rostedt %{$config_ref} = (); 21530a05c769SSteven Rostedt undef %{$config_ref}; 21540a05c769SSteven Rostedt 21550a05c769SSteven Rostedt my @key = keys %{$config_ref}; 21560a05c769SSteven Rostedt if ($#key >= 0) { 21570a05c769SSteven Rostedt print "did not delete!\n"; 21580a05c769SSteven Rostedt exit; 21590a05c769SSteven Rostedt } 21600a05c769SSteven Rostedt open (IN, "$output_config"); 21610a05c769SSteven Rostedt 21620a05c769SSteven Rostedt while (<IN>) { 21630a05c769SSteven Rostedt if (/^(CONFIG\S+)=(.*)/) { 21640a05c769SSteven Rostedt ${$config_ref}{$1} = $2; 21650a05c769SSteven Rostedt } 21660a05c769SSteven Rostedt } 21670a05c769SSteven Rostedt close(IN); 21680a05c769SSteven Rostedt} 21690a05c769SSteven Rostedt 21700a05c769SSteven Rostedtsub get_dependencies { 21710a05c769SSteven Rostedt my ($config) = @_; 21720a05c769SSteven Rostedt 21730a05c769SSteven Rostedt my $arr = $dependency{$config}; 21740a05c769SSteven Rostedt if (!defined($arr)) { 21750a05c769SSteven Rostedt return (); 21760a05c769SSteven Rostedt } 21770a05c769SSteven Rostedt 21780a05c769SSteven Rostedt my @deps = @{$arr}; 21790a05c769SSteven Rostedt 21800a05c769SSteven Rostedt foreach my $dep (@{$arr}) { 21810a05c769SSteven Rostedt print "ADD DEP $dep\n"; 21820a05c769SSteven Rostedt @deps = (@deps, get_dependencies $dep); 21830a05c769SSteven Rostedt } 21840a05c769SSteven Rostedt 21850a05c769SSteven Rostedt return @deps; 21860a05c769SSteven Rostedt} 21870a05c769SSteven Rostedt 21880a05c769SSteven Rostedtsub create_config { 21890a05c769SSteven Rostedt my @configs = @_; 21900a05c769SSteven Rostedt 21910a05c769SSteven Rostedt open(OUT, ">$output_config") or dodie "Can not write to $output_config"; 21920a05c769SSteven Rostedt 21930a05c769SSteven Rostedt foreach my $config (@configs) { 21940a05c769SSteven Rostedt print OUT "$config_set{$config}\n"; 21950a05c769SSteven Rostedt my @deps = get_dependencies $config; 21960a05c769SSteven Rostedt foreach my $dep (@deps) { 21970a05c769SSteven Rostedt print OUT "$config_set{$dep}\n"; 21980a05c769SSteven Rostedt } 21990a05c769SSteven Rostedt } 22000a05c769SSteven Rostedt 22010a05c769SSteven Rostedt foreach my $config (keys %config_ignore) { 22020a05c769SSteven Rostedt print OUT "$config_ignore{$config}\n"; 22030a05c769SSteven Rostedt } 22040a05c769SSteven Rostedt close(OUT); 22050a05c769SSteven Rostedt 22060a05c769SSteven Rostedt# exit; 2207fcb3f16aSSteven Rostedt make_oldconfig; 22080a05c769SSteven Rostedt} 22090a05c769SSteven Rostedt 22100a05c769SSteven Rostedtsub compare_configs { 22110a05c769SSteven Rostedt my (%a, %b) = @_; 22120a05c769SSteven Rostedt 22130a05c769SSteven Rostedt foreach my $item (keys %a) { 22140a05c769SSteven Rostedt if (!defined($b{$item})) { 22150a05c769SSteven Rostedt print "diff $item\n"; 22160a05c769SSteven Rostedt return 1; 22170a05c769SSteven Rostedt } 22180a05c769SSteven Rostedt delete $b{$item}; 22190a05c769SSteven Rostedt } 22200a05c769SSteven Rostedt 22210a05c769SSteven Rostedt my @keys = keys %b; 22220a05c769SSteven Rostedt if ($#keys) { 22230a05c769SSteven Rostedt print "diff2 $keys[0]\n"; 22240a05c769SSteven Rostedt } 22250a05c769SSteven Rostedt return -1 if ($#keys >= 0); 22260a05c769SSteven Rostedt 22270a05c769SSteven Rostedt return 0; 22280a05c769SSteven Rostedt} 22290a05c769SSteven Rostedt 22300a05c769SSteven Rostedtsub run_config_bisect_test { 22310a05c769SSteven Rostedt my ($type) = @_; 22320a05c769SSteven Rostedt 22330a05c769SSteven Rostedt return run_bisect_test $type, "oldconfig"; 22340a05c769SSteven Rostedt} 22350a05c769SSteven Rostedt 22360a05c769SSteven Rostedtsub process_passed { 22370a05c769SSteven Rostedt my (%configs) = @_; 22380a05c769SSteven Rostedt 22390a05c769SSteven Rostedt doprint "These configs had no failure: (Enabling them for further compiles)\n"; 22400a05c769SSteven Rostedt # Passed! All these configs are part of a good compile. 22410a05c769SSteven Rostedt # Add them to the min options. 22420a05c769SSteven Rostedt foreach my $config (keys %configs) { 22430a05c769SSteven Rostedt if (defined($config_list{$config})) { 22440a05c769SSteven Rostedt doprint " removing $config\n"; 22450a05c769SSteven Rostedt $config_ignore{$config} = $config_list{$config}; 22460a05c769SSteven Rostedt delete $config_list{$config}; 22470a05c769SSteven Rostedt } 22480a05c769SSteven Rostedt } 2249f1a27850SSteven Rostedt doprint "config copied to $outputdir/config_good\n"; 2250f1a27850SSteven Rostedt run_command "cp -f $output_config $outputdir/config_good"; 22510a05c769SSteven Rostedt} 22520a05c769SSteven Rostedt 22530a05c769SSteven Rostedtsub process_failed { 22540a05c769SSteven Rostedt my ($config) = @_; 22550a05c769SSteven Rostedt 22560a05c769SSteven Rostedt doprint "\n\n***************************************\n"; 22570a05c769SSteven Rostedt doprint "Found bad config: $config\n"; 22580a05c769SSteven Rostedt doprint "***************************************\n\n"; 22590a05c769SSteven Rostedt} 22600a05c769SSteven Rostedt 22610a05c769SSteven Rostedtsub run_config_bisect { 22620a05c769SSteven Rostedt 22630a05c769SSteven Rostedt my @start_list = keys %config_list; 22640a05c769SSteven Rostedt 22650a05c769SSteven Rostedt if ($#start_list < 0) { 22660a05c769SSteven Rostedt doprint "No more configs to test!!!\n"; 22670a05c769SSteven Rostedt return -1; 22680a05c769SSteven Rostedt } 22690a05c769SSteven Rostedt 22700a05c769SSteven Rostedt doprint "***** RUN TEST ***\n"; 22710a05c769SSteven Rostedt my $type = $opt{"CONFIG_BISECT_TYPE[$iteration]"}; 22720a05c769SSteven Rostedt my $ret; 22730a05c769SSteven Rostedt my %current_config; 22740a05c769SSteven Rostedt 22750a05c769SSteven Rostedt my $count = $#start_list + 1; 22760a05c769SSteven Rostedt doprint " $count configs to test\n"; 22770a05c769SSteven Rostedt 22780a05c769SSteven Rostedt my $half = int($#start_list / 2); 22790a05c769SSteven Rostedt 22800a05c769SSteven Rostedt do { 22810a05c769SSteven Rostedt my @tophalf = @start_list[0 .. $half]; 22820a05c769SSteven Rostedt 22830a05c769SSteven Rostedt create_config @tophalf; 22840a05c769SSteven Rostedt read_current_config \%current_config; 22850a05c769SSteven Rostedt 22860a05c769SSteven Rostedt $count = $#tophalf + 1; 22870a05c769SSteven Rostedt doprint "Testing $count configs\n"; 22880a05c769SSteven Rostedt my $found = 0; 22890a05c769SSteven Rostedt # make sure we test something 22900a05c769SSteven Rostedt foreach my $config (@tophalf) { 22910a05c769SSteven Rostedt if (defined($current_config{$config})) { 22920a05c769SSteven Rostedt logit " $config\n"; 22930a05c769SSteven Rostedt $found = 1; 22940a05c769SSteven Rostedt } 22950a05c769SSteven Rostedt } 22960a05c769SSteven Rostedt if (!$found) { 22970a05c769SSteven Rostedt # try the other half 22980a05c769SSteven Rostedt doprint "Top half produced no set configs, trying bottom half\n"; 22994c8cc55bSSteven Rostedt @tophalf = @start_list[$half + 1 .. $#start_list]; 23000a05c769SSteven Rostedt create_config @tophalf; 23010a05c769SSteven Rostedt read_current_config \%current_config; 23020a05c769SSteven Rostedt foreach my $config (@tophalf) { 23030a05c769SSteven Rostedt if (defined($current_config{$config})) { 23040a05c769SSteven Rostedt logit " $config\n"; 23050a05c769SSteven Rostedt $found = 1; 23060a05c769SSteven Rostedt } 23070a05c769SSteven Rostedt } 23080a05c769SSteven Rostedt if (!$found) { 23090a05c769SSteven Rostedt doprint "Failed: Can't make new config with current configs\n"; 23100a05c769SSteven Rostedt foreach my $config (@start_list) { 23110a05c769SSteven Rostedt doprint " CONFIG: $config\n"; 23120a05c769SSteven Rostedt } 23130a05c769SSteven Rostedt return -1; 23140a05c769SSteven Rostedt } 23150a05c769SSteven Rostedt $count = $#tophalf + 1; 23160a05c769SSteven Rostedt doprint "Testing $count configs\n"; 23170a05c769SSteven Rostedt } 23180a05c769SSteven Rostedt 23190a05c769SSteven Rostedt $ret = run_config_bisect_test $type; 2320c960bb9fSSteven Rostedt if ($bisect_manual) { 2321c960bb9fSSteven Rostedt $ret = answer_bisect; 2322c960bb9fSSteven Rostedt } 23230a05c769SSteven Rostedt if ($ret) { 23240a05c769SSteven Rostedt process_passed %current_config; 23250a05c769SSteven Rostedt return 0; 23260a05c769SSteven Rostedt } 23270a05c769SSteven Rostedt 23280a05c769SSteven Rostedt doprint "This config had a failure.\n"; 23290a05c769SSteven Rostedt doprint "Removing these configs that were not set in this config:\n"; 2330f1a27850SSteven Rostedt doprint "config copied to $outputdir/config_bad\n"; 2331f1a27850SSteven Rostedt run_command "cp -f $output_config $outputdir/config_bad"; 23320a05c769SSteven Rostedt 23330a05c769SSteven Rostedt # A config exists in this group that was bad. 23340a05c769SSteven Rostedt foreach my $config (keys %config_list) { 23350a05c769SSteven Rostedt if (!defined($current_config{$config})) { 23360a05c769SSteven Rostedt doprint " removing $config\n"; 23370a05c769SSteven Rostedt delete $config_list{$config}; 23380a05c769SSteven Rostedt } 23390a05c769SSteven Rostedt } 23400a05c769SSteven Rostedt 23410a05c769SSteven Rostedt @start_list = @tophalf; 23420a05c769SSteven Rostedt 23430a05c769SSteven Rostedt if ($#start_list == 0) { 23440a05c769SSteven Rostedt process_failed $start_list[0]; 23450a05c769SSteven Rostedt return 1; 23460a05c769SSteven Rostedt } 23470a05c769SSteven Rostedt 23480a05c769SSteven Rostedt # remove half the configs we are looking at and see if 23490a05c769SSteven Rostedt # they are good. 23500a05c769SSteven Rostedt $half = int($#start_list / 2); 23514c8cc55bSSteven Rostedt } while ($#start_list > 0); 23520a05c769SSteven Rostedt 2353c960bb9fSSteven Rostedt # we found a single config, try it again unless we are running manually 2354c960bb9fSSteven Rostedt 2355c960bb9fSSteven Rostedt if ($bisect_manual) { 2356c960bb9fSSteven Rostedt process_failed $start_list[0]; 2357c960bb9fSSteven Rostedt return 1; 2358c960bb9fSSteven Rostedt } 2359c960bb9fSSteven Rostedt 23600a05c769SSteven Rostedt my @tophalf = @start_list[0 .. 0]; 23610a05c769SSteven Rostedt 23620a05c769SSteven Rostedt $ret = run_config_bisect_test $type; 23630a05c769SSteven Rostedt if ($ret) { 23640a05c769SSteven Rostedt process_passed %current_config; 23650a05c769SSteven Rostedt return 0; 23660a05c769SSteven Rostedt } 23670a05c769SSteven Rostedt 23680a05c769SSteven Rostedt process_failed $start_list[0]; 23690a05c769SSteven Rostedt return 1; 23700a05c769SSteven Rostedt} 23710a05c769SSteven Rostedt 23720a05c769SSteven Rostedtsub config_bisect { 23730a05c769SSteven Rostedt my ($i) = @_; 23740a05c769SSteven Rostedt 23750a05c769SSteven Rostedt my $start_config = $opt{"CONFIG_BISECT[$i]"}; 23760a05c769SSteven Rostedt 23770a05c769SSteven Rostedt my $tmpconfig = "$tmpdir/use_config"; 23780a05c769SSteven Rostedt 237930f75da5SSteven Rostedt if (defined($config_bisect_good)) { 238030f75da5SSteven Rostedt process_config_ignore $config_bisect_good; 238130f75da5SSteven Rostedt } 238230f75da5SSteven Rostedt 23830a05c769SSteven Rostedt # Make the file with the bad config and the min config 23840a05c769SSteven Rostedt if (defined($minconfig)) { 23850a05c769SSteven Rostedt # read the min config for things to ignore 23860a05c769SSteven Rostedt run_command "cp $minconfig $tmpconfig" or 23870a05c769SSteven Rostedt dodie "failed to copy $minconfig to $tmpconfig"; 23880a05c769SSteven Rostedt } else { 23890a05c769SSteven Rostedt unlink $tmpconfig; 23900a05c769SSteven Rostedt } 23910a05c769SSteven Rostedt 23920a05c769SSteven Rostedt if (-f $tmpconfig) { 2393fcb3f16aSSteven Rostedt load_force_config($tmpconfig); 23940a05c769SSteven Rostedt process_config_ignore $tmpconfig; 23950a05c769SSteven Rostedt } 23960a05c769SSteven Rostedt 23970a05c769SSteven Rostedt # now process the start config 23980a05c769SSteven Rostedt run_command "cp $start_config $output_config" or 23990a05c769SSteven Rostedt dodie "failed to copy $start_config to $output_config"; 24000a05c769SSteven Rostedt 24010a05c769SSteven Rostedt # read directly what we want to check 24020a05c769SSteven Rostedt my %config_check; 24030a05c769SSteven Rostedt open (IN, $output_config) 24040a05c769SSteven Rostedt or dodie "faied to open $output_config"; 24050a05c769SSteven Rostedt 24060a05c769SSteven Rostedt while (<IN>) { 24070a05c769SSteven Rostedt if (/^((CONFIG\S*)=.*)/) { 24080a05c769SSteven Rostedt $config_check{$2} = $1; 24090a05c769SSteven Rostedt } 24100a05c769SSteven Rostedt } 24110a05c769SSteven Rostedt close(IN); 24120a05c769SSteven Rostedt 2413250bae8bSSteven Rostedt # Now run oldconfig with the minconfig 2414fcb3f16aSSteven Rostedt make_oldconfig; 24150a05c769SSteven Rostedt 24160a05c769SSteven Rostedt # check to see what we lost (or gained) 24170a05c769SSteven Rostedt open (IN, $output_config) 24180a05c769SSteven Rostedt or dodie "Failed to read $start_config"; 24190a05c769SSteven Rostedt 24200a05c769SSteven Rostedt my %removed_configs; 24210a05c769SSteven Rostedt my %added_configs; 24220a05c769SSteven Rostedt 24230a05c769SSteven Rostedt while (<IN>) { 24240a05c769SSteven Rostedt if (/^((CONFIG\S*)=.*)/) { 24250a05c769SSteven Rostedt # save off all options 24260a05c769SSteven Rostedt $config_set{$2} = $1; 24270a05c769SSteven Rostedt if (defined($config_check{$2})) { 24280a05c769SSteven Rostedt if (defined($config_ignore{$2})) { 24290a05c769SSteven Rostedt $removed_configs{$2} = $1; 24300a05c769SSteven Rostedt } else { 24310a05c769SSteven Rostedt $config_list{$2} = $1; 24320a05c769SSteven Rostedt } 24330a05c769SSteven Rostedt } elsif (!defined($config_ignore{$2})) { 24340a05c769SSteven Rostedt $added_configs{$2} = $1; 24350a05c769SSteven Rostedt $config_list{$2} = $1; 24360a05c769SSteven Rostedt } 24370a05c769SSteven Rostedt } 24380a05c769SSteven Rostedt } 24390a05c769SSteven Rostedt close(IN); 24400a05c769SSteven Rostedt 24410a05c769SSteven Rostedt my @confs = keys %removed_configs; 24420a05c769SSteven Rostedt if ($#confs >= 0) { 24430a05c769SSteven Rostedt doprint "Configs overridden by default configs and removed from check:\n"; 24440a05c769SSteven Rostedt foreach my $config (@confs) { 24450a05c769SSteven Rostedt doprint " $config\n"; 24460a05c769SSteven Rostedt } 24470a05c769SSteven Rostedt } 24480a05c769SSteven Rostedt @confs = keys %added_configs; 24490a05c769SSteven Rostedt if ($#confs >= 0) { 24500a05c769SSteven Rostedt doprint "Configs appearing in make oldconfig and added:\n"; 24510a05c769SSteven Rostedt foreach my $config (@confs) { 24520a05c769SSteven Rostedt doprint " $config\n"; 24530a05c769SSteven Rostedt } 24540a05c769SSteven Rostedt } 24550a05c769SSteven Rostedt 24560a05c769SSteven Rostedt my %config_test; 24570a05c769SSteven Rostedt my $once = 0; 24580a05c769SSteven Rostedt 24590a05c769SSteven Rostedt # Sometimes kconfig does weird things. We must make sure 24600a05c769SSteven Rostedt # that the config we autocreate has everything we need 24610a05c769SSteven Rostedt # to test, otherwise we may miss testing configs, or 24620a05c769SSteven Rostedt # may not be able to create a new config. 24630a05c769SSteven Rostedt # Here we create a config with everything set. 24640a05c769SSteven Rostedt create_config (keys %config_list); 24650a05c769SSteven Rostedt read_current_config \%config_test; 24660a05c769SSteven Rostedt foreach my $config (keys %config_list) { 24670a05c769SSteven Rostedt if (!defined($config_test{$config})) { 24680a05c769SSteven Rostedt if (!$once) { 24690a05c769SSteven Rostedt $once = 1; 24700a05c769SSteven Rostedt doprint "Configs not produced by kconfig (will not be checked):\n"; 24710a05c769SSteven Rostedt } 24720a05c769SSteven Rostedt doprint " $config\n"; 24730a05c769SSteven Rostedt delete $config_list{$config}; 24740a05c769SSteven Rostedt } 24750a05c769SSteven Rostedt } 24760a05c769SSteven Rostedt my $ret; 24770a05c769SSteven Rostedt do { 24780a05c769SSteven Rostedt $ret = run_config_bisect; 24790a05c769SSteven Rostedt } while (!$ret); 24800a05c769SSteven Rostedt 24810a05c769SSteven Rostedt return $ret if ($ret < 0); 24825f9b6cedSSteven Rostedt 24835f9b6cedSSteven Rostedt success $i; 24845f9b6cedSSteven Rostedt} 24855f9b6cedSSteven Rostedt 248627d934b2SSteven Rostedtsub patchcheck_reboot { 248727d934b2SSteven Rostedt doprint "Reboot and sleep $patchcheck_sleep_time seconds\n"; 24882728be41SAndrew Jones reboot $patchcheck_sleep_time; 248927d934b2SSteven Rostedt} 249027d934b2SSteven Rostedt 24916c5ee0beSSteven Rostedtsub patchcheck { 24926c5ee0beSSteven Rostedt my ($i) = @_; 24936c5ee0beSSteven Rostedt 24946c5ee0beSSteven Rostedt die "PATCHCHECK_START[$i] not defined\n" 24956c5ee0beSSteven Rostedt if (!defined($opt{"PATCHCHECK_START[$i]"})); 24966c5ee0beSSteven Rostedt die "PATCHCHECK_TYPE[$i] not defined\n" 24976c5ee0beSSteven Rostedt if (!defined($opt{"PATCHCHECK_TYPE[$i]"})); 24986c5ee0beSSteven Rostedt 24996c5ee0beSSteven Rostedt my $start = $opt{"PATCHCHECK_START[$i]"}; 25006c5ee0beSSteven Rostedt 25016c5ee0beSSteven Rostedt my $end = "HEAD"; 25026c5ee0beSSteven Rostedt if (defined($opt{"PATCHCHECK_END[$i]"})) { 25036c5ee0beSSteven Rostedt $end = $opt{"PATCHCHECK_END[$i]"}; 25046c5ee0beSSteven Rostedt } 25056c5ee0beSSteven Rostedt 2506a57419b3SSteven Rostedt # Get the true sha1's since we can use things like HEAD~3 2507a57419b3SSteven Rostedt $start = get_sha1($start); 2508a57419b3SSteven Rostedt $end = get_sha1($end); 2509a57419b3SSteven Rostedt 25106c5ee0beSSteven Rostedt my $type = $opt{"PATCHCHECK_TYPE[$i]"}; 25116c5ee0beSSteven Rostedt 25126c5ee0beSSteven Rostedt # Can't have a test without having a test to run 25136c5ee0beSSteven Rostedt if ($type eq "test" && !defined($run_test)) { 25146c5ee0beSSteven Rostedt $type = "boot"; 25156c5ee0beSSteven Rostedt } 25166c5ee0beSSteven Rostedt 25176c5ee0beSSteven Rostedt open (IN, "git log --pretty=oneline $end|") or 25186c5ee0beSSteven Rostedt dodie "could not get git list"; 25196c5ee0beSSteven Rostedt 25206c5ee0beSSteven Rostedt my @list; 25216c5ee0beSSteven Rostedt 25226c5ee0beSSteven Rostedt while (<IN>) { 25236c5ee0beSSteven Rostedt chomp; 25246c5ee0beSSteven Rostedt $list[$#list+1] = $_; 25256c5ee0beSSteven Rostedt last if (/^$start/); 25266c5ee0beSSteven Rostedt } 25276c5ee0beSSteven Rostedt close(IN); 25286c5ee0beSSteven Rostedt 25296c5ee0beSSteven Rostedt if ($list[$#list] !~ /^$start/) { 25302b7d9b21SSteven Rostedt fail "SHA1 $start not found"; 25316c5ee0beSSteven Rostedt } 25326c5ee0beSSteven Rostedt 25336c5ee0beSSteven Rostedt # go backwards in the list 25346c5ee0beSSteven Rostedt @list = reverse @list; 25356c5ee0beSSteven Rostedt 25366c5ee0beSSteven Rostedt my $save_clean = $noclean; 25371990207dSSteven Rostedt my %ignored_warnings; 25381990207dSSteven Rostedt 25391990207dSSteven Rostedt if (defined($ignore_warnings)) { 25401990207dSSteven Rostedt foreach my $sha1 (split /\s+/, $ignore_warnings) { 25411990207dSSteven Rostedt $ignored_warnings{$sha1} = 1; 25421990207dSSteven Rostedt } 25431990207dSSteven Rostedt } 25446c5ee0beSSteven Rostedt 25456c5ee0beSSteven Rostedt $in_patchcheck = 1; 25466c5ee0beSSteven Rostedt foreach my $item (@list) { 25476c5ee0beSSteven Rostedt my $sha1 = $item; 25486c5ee0beSSteven Rostedt $sha1 =~ s/^([[:xdigit:]]+).*/$1/; 25496c5ee0beSSteven Rostedt 25506c5ee0beSSteven Rostedt doprint "\nProcessing commit $item\n\n"; 25516c5ee0beSSteven Rostedt 25526c5ee0beSSteven Rostedt run_command "git checkout $sha1" or 25536c5ee0beSSteven Rostedt die "Failed to checkout $sha1"; 25546c5ee0beSSteven Rostedt 25556c5ee0beSSteven Rostedt # only clean on the first and last patch 25566c5ee0beSSteven Rostedt if ($item eq $list[0] || 25576c5ee0beSSteven Rostedt $item eq $list[$#list]) { 25586c5ee0beSSteven Rostedt $noclean = $save_clean; 25596c5ee0beSSteven Rostedt } else { 25606c5ee0beSSteven Rostedt $noclean = 1; 25616c5ee0beSSteven Rostedt } 25626c5ee0beSSteven Rostedt 25636c5ee0beSSteven Rostedt if (defined($minconfig)) { 25642b7d9b21SSteven Rostedt build "useconfig:$minconfig" or return 0; 25656c5ee0beSSteven Rostedt } else { 25666c5ee0beSSteven Rostedt # ?? no config to use? 25672b7d9b21SSteven Rostedt build "oldconfig" or return 0; 25686c5ee0beSSteven Rostedt } 25696c5ee0beSSteven Rostedt 25701990207dSSteven Rostedt 25711990207dSSteven Rostedt if (!defined($ignored_warnings{$sha1})) { 25722b7d9b21SSteven Rostedt check_buildlog $sha1 or return 0; 25731990207dSSteven Rostedt } 25746c5ee0beSSteven Rostedt 25756c5ee0beSSteven Rostedt next if ($type eq "build"); 25766c5ee0beSSteven Rostedt 25777faafbd6SSteven Rostedt my $failed = 0; 25787faafbd6SSteven Rostedt 2579ddf607e5SSteven Rostedt start_monitor_and_boot or $failed = 1; 25807faafbd6SSteven Rostedt 25817faafbd6SSteven Rostedt if (!$failed && $type ne "boot"){ 25827faafbd6SSteven Rostedt do_run_test or $failed = 1; 25837faafbd6SSteven Rostedt } 25847faafbd6SSteven Rostedt end_monitor; 25857faafbd6SSteven Rostedt return 0 if ($failed); 25867faafbd6SSteven Rostedt 258727d934b2SSteven Rostedt patchcheck_reboot; 258827d934b2SSteven Rostedt 25896c5ee0beSSteven Rostedt } 25906c5ee0beSSteven Rostedt $in_patchcheck = 0; 25916c5ee0beSSteven Rostedt success $i; 25922b7d9b21SSteven Rostedt 25932b7d9b21SSteven Rostedt return 1; 25946c5ee0beSSteven Rostedt} 25956c5ee0beSSteven Rostedt 2596b9066f6cSSteven Rostedtmy %depends; 2597ac6974c7SSteven Rostedtmy %depcount; 2598b9066f6cSSteven Rostedtmy $iflevel = 0; 2599b9066f6cSSteven Rostedtmy @ifdeps; 2600b9066f6cSSteven Rostedt 2601b9066f6cSSteven Rostedt# prevent recursion 2602b9066f6cSSteven Rostedtmy %read_kconfigs; 2603b9066f6cSSteven Rostedt 2604ac6974c7SSteven Rostedtsub add_dep { 2605ac6974c7SSteven Rostedt # $config depends on $dep 2606ac6974c7SSteven Rostedt my ($config, $dep) = @_; 2607ac6974c7SSteven Rostedt 2608ac6974c7SSteven Rostedt if (defined($depends{$config})) { 2609ac6974c7SSteven Rostedt $depends{$config} .= " " . $dep; 2610ac6974c7SSteven Rostedt } else { 2611ac6974c7SSteven Rostedt $depends{$config} = $dep; 2612ac6974c7SSteven Rostedt } 2613ac6974c7SSteven Rostedt 2614ac6974c7SSteven Rostedt # record the number of configs depending on $dep 2615ac6974c7SSteven Rostedt if (defined $depcount{$dep}) { 2616ac6974c7SSteven Rostedt $depcount{$dep}++; 2617ac6974c7SSteven Rostedt } else { 2618ac6974c7SSteven Rostedt $depcount{$dep} = 1; 2619ac6974c7SSteven Rostedt } 2620ac6974c7SSteven Rostedt} 2621ac6974c7SSteven Rostedt 2622b9066f6cSSteven Rostedt# taken from streamline_config.pl 2623b9066f6cSSteven Rostedtsub read_kconfig { 2624b9066f6cSSteven Rostedt my ($kconfig) = @_; 2625b9066f6cSSteven Rostedt 2626b9066f6cSSteven Rostedt my $state = "NONE"; 2627b9066f6cSSteven Rostedt my $config; 2628b9066f6cSSteven Rostedt my @kconfigs; 2629b9066f6cSSteven Rostedt 2630b9066f6cSSteven Rostedt my $cont = 0; 2631b9066f6cSSteven Rostedt my $line; 2632b9066f6cSSteven Rostedt 2633b9066f6cSSteven Rostedt 2634b9066f6cSSteven Rostedt if (! -f $kconfig) { 2635b9066f6cSSteven Rostedt doprint "file $kconfig does not exist, skipping\n"; 2636b9066f6cSSteven Rostedt return; 2637b9066f6cSSteven Rostedt } 2638b9066f6cSSteven Rostedt 2639b9066f6cSSteven Rostedt open(KIN, "$kconfig") 2640b9066f6cSSteven Rostedt or die "Can't open $kconfig"; 2641b9066f6cSSteven Rostedt while (<KIN>) { 2642b9066f6cSSteven Rostedt chomp; 2643b9066f6cSSteven Rostedt 2644b9066f6cSSteven Rostedt # Make sure that lines ending with \ continue 2645b9066f6cSSteven Rostedt if ($cont) { 2646b9066f6cSSteven Rostedt $_ = $line . " " . $_; 2647b9066f6cSSteven Rostedt } 2648b9066f6cSSteven Rostedt 2649b9066f6cSSteven Rostedt if (s/\\$//) { 2650b9066f6cSSteven Rostedt $cont = 1; 2651b9066f6cSSteven Rostedt $line = $_; 2652b9066f6cSSteven Rostedt next; 2653b9066f6cSSteven Rostedt } 2654b9066f6cSSteven Rostedt 2655b9066f6cSSteven Rostedt $cont = 0; 2656b9066f6cSSteven Rostedt 2657b9066f6cSSteven Rostedt # collect any Kconfig sources 2658b9066f6cSSteven Rostedt if (/^source\s*"(.*)"/) { 2659b9066f6cSSteven Rostedt $kconfigs[$#kconfigs+1] = $1; 2660b9066f6cSSteven Rostedt } 2661b9066f6cSSteven Rostedt 2662b9066f6cSSteven Rostedt # configs found 2663b9066f6cSSteven Rostedt if (/^\s*(menu)?config\s+(\S+)\s*$/) { 2664b9066f6cSSteven Rostedt $state = "NEW"; 2665b9066f6cSSteven Rostedt $config = $2; 2666b9066f6cSSteven Rostedt 2667b9066f6cSSteven Rostedt for (my $i = 0; $i < $iflevel; $i++) { 2668ac6974c7SSteven Rostedt add_dep $config, $ifdeps[$i]; 2669b9066f6cSSteven Rostedt } 2670b9066f6cSSteven Rostedt 2671b9066f6cSSteven Rostedt # collect the depends for the config 2672b9066f6cSSteven Rostedt } elsif ($state eq "NEW" && /^\s*depends\s+on\s+(.*)$/) { 2673b9066f6cSSteven Rostedt 2674ac6974c7SSteven Rostedt add_dep $config, $1; 2675b9066f6cSSteven Rostedt 2676b9066f6cSSteven Rostedt # Get the configs that select this config 2677ac6974c7SSteven Rostedt } elsif ($state eq "NEW" && /^\s*select\s+(\S+)/) { 2678ac6974c7SSteven Rostedt 2679ac6974c7SSteven Rostedt # selected by depends on config 2680ac6974c7SSteven Rostedt add_dep $1, $config; 2681b9066f6cSSteven Rostedt 2682b9066f6cSSteven Rostedt # Check for if statements 2683b9066f6cSSteven Rostedt } elsif (/^if\s+(.*\S)\s*$/) { 2684b9066f6cSSteven Rostedt my $deps = $1; 2685b9066f6cSSteven Rostedt # remove beginning and ending non text 2686b9066f6cSSteven Rostedt $deps =~ s/^[^a-zA-Z0-9_]*//; 2687b9066f6cSSteven Rostedt $deps =~ s/[^a-zA-Z0-9_]*$//; 2688b9066f6cSSteven Rostedt 2689b9066f6cSSteven Rostedt my @deps = split /[^a-zA-Z0-9_]+/, $deps; 2690b9066f6cSSteven Rostedt 2691b9066f6cSSteven Rostedt $ifdeps[$iflevel++] = join ':', @deps; 2692b9066f6cSSteven Rostedt 2693b9066f6cSSteven Rostedt } elsif (/^endif/) { 2694b9066f6cSSteven Rostedt 2695b9066f6cSSteven Rostedt $iflevel-- if ($iflevel); 2696b9066f6cSSteven Rostedt 2697b9066f6cSSteven Rostedt # stop on "help" 2698b9066f6cSSteven Rostedt } elsif (/^\s*help\s*$/) { 2699b9066f6cSSteven Rostedt $state = "NONE"; 2700b9066f6cSSteven Rostedt } 2701b9066f6cSSteven Rostedt } 2702b9066f6cSSteven Rostedt close(KIN); 2703b9066f6cSSteven Rostedt 2704b9066f6cSSteven Rostedt # read in any configs that were found. 2705b9066f6cSSteven Rostedt foreach $kconfig (@kconfigs) { 2706b9066f6cSSteven Rostedt if (!defined($read_kconfigs{$kconfig})) { 2707b9066f6cSSteven Rostedt $read_kconfigs{$kconfig} = 1; 2708b9066f6cSSteven Rostedt read_kconfig("$builddir/$kconfig"); 2709b9066f6cSSteven Rostedt } 2710b9066f6cSSteven Rostedt } 2711b9066f6cSSteven Rostedt} 2712b9066f6cSSteven Rostedt 2713b9066f6cSSteven Rostedtsub read_depends { 2714b9066f6cSSteven Rostedt # find out which arch this is by the kconfig file 2715b9066f6cSSteven Rostedt open (IN, $output_config) 2716b9066f6cSSteven Rostedt or dodie "Failed to read $output_config"; 2717b9066f6cSSteven Rostedt my $arch; 2718b9066f6cSSteven Rostedt while (<IN>) { 2719b9066f6cSSteven Rostedt if (m,Linux/(\S+)\s+\S+\s+Kernel Configuration,) { 2720b9066f6cSSteven Rostedt $arch = $1; 2721b9066f6cSSteven Rostedt last; 2722b9066f6cSSteven Rostedt } 2723b9066f6cSSteven Rostedt } 2724b9066f6cSSteven Rostedt close IN; 2725b9066f6cSSteven Rostedt 2726b9066f6cSSteven Rostedt if (!defined($arch)) { 2727b9066f6cSSteven Rostedt doprint "Could not find arch from config file\n"; 2728b9066f6cSSteven Rostedt doprint "no dependencies used\n"; 2729b9066f6cSSteven Rostedt return; 2730b9066f6cSSteven Rostedt } 2731b9066f6cSSteven Rostedt 2732b9066f6cSSteven Rostedt # arch is really the subarch, we need to know 2733b9066f6cSSteven Rostedt # what directory to look at. 2734b9066f6cSSteven Rostedt if ($arch eq "i386" || $arch eq "x86_64") { 2735b9066f6cSSteven Rostedt $arch = "x86"; 2736b9066f6cSSteven Rostedt } elsif ($arch =~ /^tile/) { 2737b9066f6cSSteven Rostedt $arch = "tile"; 2738b9066f6cSSteven Rostedt } 2739b9066f6cSSteven Rostedt 2740b9066f6cSSteven Rostedt my $kconfig = "$builddir/arch/$arch/Kconfig"; 2741b9066f6cSSteven Rostedt 2742b9066f6cSSteven Rostedt if (! -f $kconfig && $arch =~ /\d$/) { 2743b9066f6cSSteven Rostedt my $orig = $arch; 2744b9066f6cSSteven Rostedt # some subarchs have numbers, truncate them 2745b9066f6cSSteven Rostedt $arch =~ s/\d*$//; 2746b9066f6cSSteven Rostedt $kconfig = "$builddir/arch/$arch/Kconfig"; 2747b9066f6cSSteven Rostedt if (! -f $kconfig) { 2748b9066f6cSSteven Rostedt doprint "No idea what arch dir $orig is for\n"; 2749b9066f6cSSteven Rostedt doprint "no dependencies used\n"; 2750b9066f6cSSteven Rostedt return; 2751b9066f6cSSteven Rostedt } 2752b9066f6cSSteven Rostedt } 2753b9066f6cSSteven Rostedt 2754b9066f6cSSteven Rostedt read_kconfig($kconfig); 2755b9066f6cSSteven Rostedt} 2756b9066f6cSSteven Rostedt 27574c4ab120SSteven Rostedtsub read_config_list { 27584c4ab120SSteven Rostedt my ($config) = @_; 27594c4ab120SSteven Rostedt 27604c4ab120SSteven Rostedt open (IN, $config) 27614c4ab120SSteven Rostedt or dodie "Failed to read $config"; 27624c4ab120SSteven Rostedt 27634c4ab120SSteven Rostedt while (<IN>) { 27644c4ab120SSteven Rostedt if (/^((CONFIG\S*)=.*)/) { 27654c4ab120SSteven Rostedt if (!defined($config_ignore{$2})) { 27664c4ab120SSteven Rostedt $config_list{$2} = $1; 27674c4ab120SSteven Rostedt } 27684c4ab120SSteven Rostedt } 27694c4ab120SSteven Rostedt } 27704c4ab120SSteven Rostedt 27714c4ab120SSteven Rostedt close(IN); 27724c4ab120SSteven Rostedt} 27734c4ab120SSteven Rostedt 27744c4ab120SSteven Rostedtsub read_output_config { 27754c4ab120SSteven Rostedt my ($config) = @_; 27764c4ab120SSteven Rostedt 27774c4ab120SSteven Rostedt assign_configs \%config_ignore, $config; 27784c4ab120SSteven Rostedt} 27794c4ab120SSteven Rostedt 27804c4ab120SSteven Rostedtsub make_new_config { 27814c4ab120SSteven Rostedt my @configs = @_; 27824c4ab120SSteven Rostedt 27834c4ab120SSteven Rostedt open (OUT, ">$output_config") 27844c4ab120SSteven Rostedt or dodie "Failed to write $output_config"; 27854c4ab120SSteven Rostedt 27864c4ab120SSteven Rostedt foreach my $config (@configs) { 27874c4ab120SSteven Rostedt print OUT "$config\n"; 27884c4ab120SSteven Rostedt } 27894c4ab120SSteven Rostedt close OUT; 27904c4ab120SSteven Rostedt} 27914c4ab120SSteven Rostedt 2792ac6974c7SSteven Rostedtsub chomp_config { 2793ac6974c7SSteven Rostedt my ($config) = @_; 2794ac6974c7SSteven Rostedt 2795ac6974c7SSteven Rostedt $config =~ s/CONFIG_//; 2796ac6974c7SSteven Rostedt 2797ac6974c7SSteven Rostedt return $config; 2798ac6974c7SSteven Rostedt} 2799ac6974c7SSteven Rostedt 2800b9066f6cSSteven Rostedtsub get_depends { 2801b9066f6cSSteven Rostedt my ($dep) = @_; 2802b9066f6cSSteven Rostedt 2803ac6974c7SSteven Rostedt my $kconfig = chomp_config $dep; 2804b9066f6cSSteven Rostedt 2805b9066f6cSSteven Rostedt $dep = $depends{"$kconfig"}; 2806b9066f6cSSteven Rostedt 2807b9066f6cSSteven Rostedt # the dep string we have saves the dependencies as they 2808b9066f6cSSteven Rostedt # were found, including expressions like ! && ||. We 2809b9066f6cSSteven Rostedt # want to split this out into just an array of configs. 2810b9066f6cSSteven Rostedt 2811b9066f6cSSteven Rostedt my $valid = "A-Za-z_0-9"; 2812b9066f6cSSteven Rostedt 2813b9066f6cSSteven Rostedt my @configs; 2814b9066f6cSSteven Rostedt 2815b9066f6cSSteven Rostedt while ($dep =~ /[$valid]/) { 2816b9066f6cSSteven Rostedt 2817b9066f6cSSteven Rostedt if ($dep =~ /^[^$valid]*([$valid]+)/) { 2818b9066f6cSSteven Rostedt my $conf = "CONFIG_" . $1; 2819b9066f6cSSteven Rostedt 2820b9066f6cSSteven Rostedt $configs[$#configs + 1] = $conf; 2821b9066f6cSSteven Rostedt 2822b9066f6cSSteven Rostedt $dep =~ s/^[^$valid]*[$valid]+//; 2823b9066f6cSSteven Rostedt } else { 2824b9066f6cSSteven Rostedt die "this should never happen"; 2825b9066f6cSSteven Rostedt } 2826b9066f6cSSteven Rostedt } 2827b9066f6cSSteven Rostedt 2828b9066f6cSSteven Rostedt return @configs; 2829b9066f6cSSteven Rostedt} 2830b9066f6cSSteven Rostedt 2831b9066f6cSSteven Rostedtmy %min_configs; 2832b9066f6cSSteven Rostedtmy %keep_configs; 283343d1b651SSteven Rostedtmy %save_configs; 2834b9066f6cSSteven Rostedtmy %processed_configs; 2835b9066f6cSSteven Rostedtmy %nochange_config; 2836b9066f6cSSteven Rostedt 2837b9066f6cSSteven Rostedtsub test_this_config { 2838b9066f6cSSteven Rostedt my ($config) = @_; 2839b9066f6cSSteven Rostedt 2840b9066f6cSSteven Rostedt my $found; 2841b9066f6cSSteven Rostedt 2842b9066f6cSSteven Rostedt # if we already processed this config, skip it 2843b9066f6cSSteven Rostedt if (defined($processed_configs{$config})) { 2844b9066f6cSSteven Rostedt return undef; 2845b9066f6cSSteven Rostedt } 2846b9066f6cSSteven Rostedt $processed_configs{$config} = 1; 2847b9066f6cSSteven Rostedt 2848b9066f6cSSteven Rostedt # if this config failed during this round, skip it 2849b9066f6cSSteven Rostedt if (defined($nochange_config{$config})) { 2850b9066f6cSSteven Rostedt return undef; 2851b9066f6cSSteven Rostedt } 2852b9066f6cSSteven Rostedt 2853ac6974c7SSteven Rostedt my $kconfig = chomp_config $config; 2854b9066f6cSSteven Rostedt 2855b9066f6cSSteven Rostedt # Test dependencies first 2856b9066f6cSSteven Rostedt if (defined($depends{"$kconfig"})) { 2857b9066f6cSSteven Rostedt my @parents = get_depends $config; 2858b9066f6cSSteven Rostedt foreach my $parent (@parents) { 2859b9066f6cSSteven Rostedt # if the parent is in the min config, check it first 2860b9066f6cSSteven Rostedt next if (!defined($min_configs{$parent})); 2861b9066f6cSSteven Rostedt $found = test_this_config($parent); 2862b9066f6cSSteven Rostedt if (defined($found)) { 2863b9066f6cSSteven Rostedt return $found; 2864b9066f6cSSteven Rostedt } 2865b9066f6cSSteven Rostedt } 2866b9066f6cSSteven Rostedt } 2867b9066f6cSSteven Rostedt 2868b9066f6cSSteven Rostedt # Remove this config from the list of configs 2869b9066f6cSSteven Rostedt # do a make oldnoconfig and then read the resulting 2870b9066f6cSSteven Rostedt # .config to make sure it is missing the config that 2871b9066f6cSSteven Rostedt # we had before 2872b9066f6cSSteven Rostedt my %configs = %min_configs; 2873b9066f6cSSteven Rostedt delete $configs{$config}; 2874b9066f6cSSteven Rostedt make_new_config ((values %configs), (values %keep_configs)); 2875b9066f6cSSteven Rostedt make_oldconfig; 2876b9066f6cSSteven Rostedt undef %configs; 2877b9066f6cSSteven Rostedt assign_configs \%configs, $output_config; 2878b9066f6cSSteven Rostedt 2879b9066f6cSSteven Rostedt return $config if (!defined($configs{$config})); 2880b9066f6cSSteven Rostedt 2881b9066f6cSSteven Rostedt doprint "disabling config $config did not change .config\n"; 2882b9066f6cSSteven Rostedt 2883b9066f6cSSteven Rostedt $nochange_config{$config} = 1; 2884b9066f6cSSteven Rostedt 2885b9066f6cSSteven Rostedt return undef; 2886b9066f6cSSteven Rostedt} 2887b9066f6cSSteven Rostedt 28884c4ab120SSteven Rostedtsub make_min_config { 28894c4ab120SSteven Rostedt my ($i) = @_; 28904c4ab120SSteven Rostedt 28914c4ab120SSteven Rostedt if (!defined($output_minconfig)) { 28924c4ab120SSteven Rostedt fail "OUTPUT_MIN_CONFIG not defined" and return; 28934c4ab120SSteven Rostedt } 289435ce5952SSteven Rostedt 289535ce5952SSteven Rostedt # If output_minconfig exists, and the start_minconfig 289635ce5952SSteven Rostedt # came from min_config, than ask if we should use 289735ce5952SSteven Rostedt # that instead. 289835ce5952SSteven Rostedt if (-f $output_minconfig && !$start_minconfig_defined) { 289935ce5952SSteven Rostedt print "$output_minconfig exists\n"; 290035ce5952SSteven Rostedt if (read_yn " Use it as minconfig?") { 290135ce5952SSteven Rostedt $start_minconfig = $output_minconfig; 290235ce5952SSteven Rostedt } 290335ce5952SSteven Rostedt } 290435ce5952SSteven Rostedt 29054c4ab120SSteven Rostedt if (!defined($start_minconfig)) { 29064c4ab120SSteven Rostedt fail "START_MIN_CONFIG or MIN_CONFIG not defined" and return; 29074c4ab120SSteven Rostedt } 29084c4ab120SSteven Rostedt 290935ce5952SSteven Rostedt my $temp_config = "$tmpdir/temp_config"; 291035ce5952SSteven Rostedt 29114c4ab120SSteven Rostedt # First things first. We build an allnoconfig to find 29124c4ab120SSteven Rostedt # out what the defaults are that we can't touch. 29134c4ab120SSteven Rostedt # Some are selections, but we really can't handle selections. 29144c4ab120SSteven Rostedt 29154c4ab120SSteven Rostedt my $save_minconfig = $minconfig; 29164c4ab120SSteven Rostedt undef $minconfig; 29174c4ab120SSteven Rostedt 29184c4ab120SSteven Rostedt run_command "$make allnoconfig" or return 0; 29194c4ab120SSteven Rostedt 2920b9066f6cSSteven Rostedt read_depends; 2921b9066f6cSSteven Rostedt 29224c4ab120SSteven Rostedt process_config_ignore $output_config; 2923b9066f6cSSteven Rostedt 292443d1b651SSteven Rostedt undef %save_configs; 2925b9066f6cSSteven Rostedt undef %min_configs; 29264c4ab120SSteven Rostedt 29274c4ab120SSteven Rostedt if (defined($ignore_config)) { 29284c4ab120SSteven Rostedt # make sure the file exists 29294c4ab120SSteven Rostedt `touch $ignore_config`; 293043d1b651SSteven Rostedt assign_configs \%save_configs, $ignore_config; 29314c4ab120SSteven Rostedt } 29324c4ab120SSteven Rostedt 293343d1b651SSteven Rostedt %keep_configs = %save_configs; 293443d1b651SSteven Rostedt 29354c4ab120SSteven Rostedt doprint "Load initial configs from $start_minconfig\n"; 29364c4ab120SSteven Rostedt 29374c4ab120SSteven Rostedt # Look at the current min configs, and save off all the 29384c4ab120SSteven Rostedt # ones that were set via the allnoconfig 29394c4ab120SSteven Rostedt assign_configs \%min_configs, $start_minconfig; 29404c4ab120SSteven Rostedt 29414c4ab120SSteven Rostedt my @config_keys = keys %min_configs; 29424c4ab120SSteven Rostedt 2943ac6974c7SSteven Rostedt # All configs need a depcount 2944ac6974c7SSteven Rostedt foreach my $config (@config_keys) { 2945ac6974c7SSteven Rostedt my $kconfig = chomp_config $config; 2946ac6974c7SSteven Rostedt if (!defined $depcount{$kconfig}) { 2947ac6974c7SSteven Rostedt $depcount{$kconfig} = 0; 2948ac6974c7SSteven Rostedt } 2949ac6974c7SSteven Rostedt } 2950ac6974c7SSteven Rostedt 29514c4ab120SSteven Rostedt # Remove anything that was set by the make allnoconfig 29524c4ab120SSteven Rostedt # we shouldn't need them as they get set for us anyway. 29534c4ab120SSteven Rostedt foreach my $config (@config_keys) { 29544c4ab120SSteven Rostedt # Remove anything in the ignore_config 29554c4ab120SSteven Rostedt if (defined($keep_configs{$config})) { 29564c4ab120SSteven Rostedt my $file = $ignore_config; 29574c4ab120SSteven Rostedt $file =~ s,.*/(.*?)$,$1,; 29584c4ab120SSteven Rostedt doprint "$config set by $file ... ignored\n"; 29594c4ab120SSteven Rostedt delete $min_configs{$config}; 29604c4ab120SSteven Rostedt next; 29614c4ab120SSteven Rostedt } 29624c4ab120SSteven Rostedt # But make sure the settings are the same. If a min config 29634c4ab120SSteven Rostedt # sets a selection, we do not want to get rid of it if 29644c4ab120SSteven Rostedt # it is not the same as what we have. Just move it into 29654c4ab120SSteven Rostedt # the keep configs. 29664c4ab120SSteven Rostedt if (defined($config_ignore{$config})) { 29674c4ab120SSteven Rostedt if ($config_ignore{$config} ne $min_configs{$config}) { 29684c4ab120SSteven Rostedt doprint "$config is in allnoconfig as '$config_ignore{$config}'"; 29694c4ab120SSteven Rostedt doprint " but it is '$min_configs{$config}' in minconfig .. keeping\n"; 29704c4ab120SSteven Rostedt $keep_configs{$config} = $min_configs{$config}; 29714c4ab120SSteven Rostedt } else { 29724c4ab120SSteven Rostedt doprint "$config set by allnoconfig ... ignored\n"; 29734c4ab120SSteven Rostedt } 29744c4ab120SSteven Rostedt delete $min_configs{$config}; 29754c4ab120SSteven Rostedt } 29764c4ab120SSteven Rostedt } 29774c4ab120SSteven Rostedt 29784c4ab120SSteven Rostedt my $done = 0; 2979b9066f6cSSteven Rostedt my $take_two = 0; 29804c4ab120SSteven Rostedt 29814c4ab120SSteven Rostedt while (!$done) { 29824c4ab120SSteven Rostedt 29834c4ab120SSteven Rostedt my $config; 29844c4ab120SSteven Rostedt my $found; 29854c4ab120SSteven Rostedt 29864c4ab120SSteven Rostedt # Now disable each config one by one and do a make oldconfig 29874c4ab120SSteven Rostedt # till we find a config that changes our list. 29884c4ab120SSteven Rostedt 29894c4ab120SSteven Rostedt my @test_configs = keys %min_configs; 2990ac6974c7SSteven Rostedt 2991ac6974c7SSteven Rostedt # Sort keys by who is most dependent on 2992ac6974c7SSteven Rostedt @test_configs = sort { $depcount{chomp_config($b)} <=> $depcount{chomp_config($a)} } 2993ac6974c7SSteven Rostedt @test_configs ; 2994ac6974c7SSteven Rostedt 2995ac6974c7SSteven Rostedt # Put configs that did not modify the config at the end. 29964c4ab120SSteven Rostedt my $reset = 1; 29974c4ab120SSteven Rostedt for (my $i = 0; $i < $#test_configs; $i++) { 29984c4ab120SSteven Rostedt if (!defined($nochange_config{$test_configs[0]})) { 29994c4ab120SSteven Rostedt $reset = 0; 30004c4ab120SSteven Rostedt last; 30014c4ab120SSteven Rostedt } 30024c4ab120SSteven Rostedt # This config didn't change the .config last time. 30034c4ab120SSteven Rostedt # Place it at the end 30044c4ab120SSteven Rostedt my $config = shift @test_configs; 30054c4ab120SSteven Rostedt push @test_configs, $config; 30064c4ab120SSteven Rostedt } 30074c4ab120SSteven Rostedt 30084c4ab120SSteven Rostedt # if every test config has failed to modify the .config file 30094c4ab120SSteven Rostedt # in the past, then reset and start over. 30104c4ab120SSteven Rostedt if ($reset) { 30114c4ab120SSteven Rostedt undef %nochange_config; 30124c4ab120SSteven Rostedt } 30134c4ab120SSteven Rostedt 3014b9066f6cSSteven Rostedt undef %processed_configs; 3015b9066f6cSSteven Rostedt 30164c4ab120SSteven Rostedt foreach my $config (@test_configs) { 30174c4ab120SSteven Rostedt 3018b9066f6cSSteven Rostedt $found = test_this_config $config; 30194c4ab120SSteven Rostedt 3020b9066f6cSSteven Rostedt last if (defined($found)); 30214c4ab120SSteven Rostedt 30224c4ab120SSteven Rostedt # oh well, try another config 30234c4ab120SSteven Rostedt } 30244c4ab120SSteven Rostedt 30254c4ab120SSteven Rostedt if (!defined($found)) { 3026b9066f6cSSteven Rostedt # we could have failed due to the nochange_config hash 3027b9066f6cSSteven Rostedt # reset and try again 3028b9066f6cSSteven Rostedt if (!$take_two) { 3029b9066f6cSSteven Rostedt undef %nochange_config; 3030b9066f6cSSteven Rostedt $take_two = 1; 3031b9066f6cSSteven Rostedt next; 3032b9066f6cSSteven Rostedt } 30334c4ab120SSteven Rostedt doprint "No more configs found that we can disable\n"; 30344c4ab120SSteven Rostedt $done = 1; 30354c4ab120SSteven Rostedt last; 30364c4ab120SSteven Rostedt } 3037b9066f6cSSteven Rostedt $take_two = 0; 30384c4ab120SSteven Rostedt 30394c4ab120SSteven Rostedt $config = $found; 30404c4ab120SSteven Rostedt 30414c4ab120SSteven Rostedt doprint "Test with $config disabled\n"; 30424c4ab120SSteven Rostedt 30434c4ab120SSteven Rostedt # set in_bisect to keep build and monitor from dieing 30444c4ab120SSteven Rostedt $in_bisect = 1; 30454c4ab120SSteven Rostedt 30464c4ab120SSteven Rostedt my $failed = 0; 30474c4ab120SSteven Rostedt build "oldconfig"; 30484c4ab120SSteven Rostedt start_monitor_and_boot or $failed = 1; 30494c4ab120SSteven Rostedt end_monitor; 30504c4ab120SSteven Rostedt 30514c4ab120SSteven Rostedt $in_bisect = 0; 30524c4ab120SSteven Rostedt 30534c4ab120SSteven Rostedt if ($failed) { 3054b9066f6cSSteven Rostedt doprint "$min_configs{$config} is needed to boot the box... keeping\n"; 30554c4ab120SSteven Rostedt # this config is needed, add it to the ignore list. 30564c4ab120SSteven Rostedt $keep_configs{$config} = $min_configs{$config}; 305743d1b651SSteven Rostedt $save_configs{$config} = $min_configs{$config}; 30584c4ab120SSteven Rostedt delete $min_configs{$config}; 305935ce5952SSteven Rostedt 306035ce5952SSteven Rostedt # update new ignore configs 306135ce5952SSteven Rostedt if (defined($ignore_config)) { 306235ce5952SSteven Rostedt open (OUT, ">$temp_config") 306335ce5952SSteven Rostedt or die "Can't write to $temp_config"; 306443d1b651SSteven Rostedt foreach my $config (keys %save_configs) { 306543d1b651SSteven Rostedt print OUT "$save_configs{$config}\n"; 306635ce5952SSteven Rostedt } 306735ce5952SSteven Rostedt close OUT; 306835ce5952SSteven Rostedt run_command "mv $temp_config $ignore_config" or 306935ce5952SSteven Rostedt dodie "failed to copy update to $ignore_config"; 307035ce5952SSteven Rostedt } 307135ce5952SSteven Rostedt 30724c4ab120SSteven Rostedt } else { 30734c4ab120SSteven Rostedt # We booted without this config, remove it from the minconfigs. 30744c4ab120SSteven Rostedt doprint "$config is not needed, disabling\n"; 30754c4ab120SSteven Rostedt 30764c4ab120SSteven Rostedt delete $min_configs{$config}; 30774c4ab120SSteven Rostedt 30784c4ab120SSteven Rostedt # Also disable anything that is not enabled in this config 30794c4ab120SSteven Rostedt my %configs; 30804c4ab120SSteven Rostedt assign_configs \%configs, $output_config; 30814c4ab120SSteven Rostedt my @config_keys = keys %min_configs; 30824c4ab120SSteven Rostedt foreach my $config (@config_keys) { 30834c4ab120SSteven Rostedt if (!defined($configs{$config})) { 30844c4ab120SSteven Rostedt doprint "$config is not set, disabling\n"; 30854c4ab120SSteven Rostedt delete $min_configs{$config}; 30864c4ab120SSteven Rostedt } 30874c4ab120SSteven Rostedt } 30884c4ab120SSteven Rostedt 30894c4ab120SSteven Rostedt # Save off all the current mandidory configs 309035ce5952SSteven Rostedt open (OUT, ">$temp_config") 309135ce5952SSteven Rostedt or die "Can't write to $temp_config"; 30924c4ab120SSteven Rostedt foreach my $config (keys %keep_configs) { 30934c4ab120SSteven Rostedt print OUT "$keep_configs{$config}\n"; 30944c4ab120SSteven Rostedt } 30954c4ab120SSteven Rostedt foreach my $config (keys %min_configs) { 30964c4ab120SSteven Rostedt print OUT "$min_configs{$config}\n"; 30974c4ab120SSteven Rostedt } 30984c4ab120SSteven Rostedt close OUT; 309935ce5952SSteven Rostedt 310035ce5952SSteven Rostedt run_command "mv $temp_config $output_minconfig" or 310135ce5952SSteven Rostedt dodie "failed to copy update to $output_minconfig"; 31024c4ab120SSteven Rostedt } 31034c4ab120SSteven Rostedt 31044c4ab120SSteven Rostedt doprint "Reboot and wait $sleep_time seconds\n"; 31052728be41SAndrew Jones reboot $sleep_time; 31064c4ab120SSteven Rostedt } 31074c4ab120SSteven Rostedt 31084c4ab120SSteven Rostedt success $i; 31094c4ab120SSteven Rostedt return 1; 31104c4ab120SSteven Rostedt} 31114c4ab120SSteven Rostedt 31128d1491baSSteven Rostedt$#ARGV < 1 or die "ktest.pl version: $VERSION\n usage: ktest.pl config-file\n"; 31132545eb61SSteven Rostedt 31148d1491baSSteven Rostedtif ($#ARGV == 0) { 31158d1491baSSteven Rostedt $ktest_config = $ARGV[0]; 31168d1491baSSteven Rostedt if (! -f $ktest_config) { 31178d1491baSSteven Rostedt print "$ktest_config does not exist.\n"; 311835ce5952SSteven Rostedt if (!read_yn "Create it?") { 31198d1491baSSteven Rostedt exit 0; 31208d1491baSSteven Rostedt } 31218d1491baSSteven Rostedt } 31228d1491baSSteven Rostedt} else { 31238d1491baSSteven Rostedt $ktest_config = "ktest.conf"; 31248d1491baSSteven Rostedt} 31258d1491baSSteven Rostedt 31268d1491baSSteven Rostedtif (! -f $ktest_config) { 3127dbd3783bSSteven Rostedt $newconfig = 1; 3128c4261d0fSSteven Rostedt get_test_case; 31298d1491baSSteven Rostedt open(OUT, ">$ktest_config") or die "Can not create $ktest_config"; 31308d1491baSSteven Rostedt print OUT << "EOF" 31318d1491baSSteven Rostedt# Generated by ktest.pl 31328d1491baSSteven Rostedt# 31330e7a22deSSteven Rostedt 31340e7a22deSSteven Rostedt# PWD is a ktest.pl variable that will result in the process working 31350e7a22deSSteven Rostedt# directory that ktest.pl is executed in. 31360e7a22deSSteven Rostedt 31370e7a22deSSteven Rostedt# THIS_DIR is automatically assigned the PWD of the path that generated 31380e7a22deSSteven Rostedt# the config file. It is best to use this variable when assigning other 31390e7a22deSSteven Rostedt# directory paths within this directory. This allows you to easily 31400e7a22deSSteven Rostedt# move the test cases to other locations or to other machines. 31410e7a22deSSteven Rostedt# 31420e7a22deSSteven RostedtTHIS_DIR := $variable{"PWD"} 31430e7a22deSSteven Rostedt 31448d1491baSSteven Rostedt# Define each test with TEST_START 31458d1491baSSteven Rostedt# The config options below it will override the defaults 31468d1491baSSteven RostedtTEST_START 3147c4261d0fSSteven RostedtTEST_TYPE = $default{"TEST_TYPE"} 31488d1491baSSteven Rostedt 31498d1491baSSteven RostedtDEFAULTS 31508d1491baSSteven RostedtEOF 31518d1491baSSteven Rostedt; 31528d1491baSSteven Rostedt close(OUT); 31538d1491baSSteven Rostedt} 31548d1491baSSteven Rostedtread_config $ktest_config; 31558d1491baSSteven Rostedt 315623715c3cSSteven Rostedtif (defined($opt{"LOG_FILE"})) { 315723715c3cSSteven Rostedt $opt{"LOG_FILE"} = eval_option($opt{"LOG_FILE"}, -1); 315823715c3cSSteven Rostedt} 315923715c3cSSteven Rostedt 31608d1491baSSteven Rostedt# Append any configs entered in manually to the config file. 31618d1491baSSteven Rostedtmy @new_configs = keys %entered_configs; 31628d1491baSSteven Rostedtif ($#new_configs >= 0) { 31638d1491baSSteven Rostedt print "\nAppending entered in configs to $ktest_config\n"; 31648d1491baSSteven Rostedt open(OUT, ">>$ktest_config") or die "Can not append to $ktest_config"; 31658d1491baSSteven Rostedt foreach my $config (@new_configs) { 31668d1491baSSteven Rostedt print OUT "$config = $entered_configs{$config}\n"; 31670e7a22deSSteven Rostedt $opt{$config} = process_variables($entered_configs{$config}); 31688d1491baSSteven Rostedt } 31698d1491baSSteven Rostedt} 31702545eb61SSteven Rostedt 31712b7d9b21SSteven Rostedtif ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) { 31722b7d9b21SSteven Rostedt unlink $opt{"LOG_FILE"}; 31732b7d9b21SSteven Rostedt} 31742545eb61SSteven Rostedt 31752b7d9b21SSteven Rostedtdoprint "\n\nSTARTING AUTOMATED TESTS\n\n"; 31762b7d9b21SSteven Rostedt 3177a57419b3SSteven Rostedtfor (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) { 3178a57419b3SSteven Rostedt 3179a57419b3SSteven Rostedt if (!$i) { 3180a57419b3SSteven Rostedt doprint "DEFAULT OPTIONS:\n"; 3181a57419b3SSteven Rostedt } else { 3182a57419b3SSteven Rostedt doprint "\nTEST $i OPTIONS"; 3183a57419b3SSteven Rostedt if (defined($repeat_tests{$i})) { 3184a57419b3SSteven Rostedt $repeat = $repeat_tests{$i}; 3185a57419b3SSteven Rostedt doprint " ITERATE $repeat"; 3186a57419b3SSteven Rostedt } 3187a57419b3SSteven Rostedt doprint "\n"; 3188a57419b3SSteven Rostedt } 3189a57419b3SSteven Rostedt 31902b7d9b21SSteven Rostedt foreach my $option (sort keys %opt) { 3191a57419b3SSteven Rostedt 3192a57419b3SSteven Rostedt if ($option =~ /\[(\d+)\]$/) { 3193a57419b3SSteven Rostedt next if ($i != $1); 3194a57419b3SSteven Rostedt } else { 3195a57419b3SSteven Rostedt next if ($i); 3196a57419b3SSteven Rostedt } 3197a57419b3SSteven Rostedt 31982b7d9b21SSteven Rostedt doprint "$option = $opt{$option}\n"; 31992b7d9b21SSteven Rostedt } 3200a57419b3SSteven Rostedt} 32012545eb61SSteven Rostedt 32022a62512bSSteven Rostedtsub __set_test_option { 32035a391fbfSSteven Rostedt my ($name, $i) = @_; 32045a391fbfSSteven Rostedt 32055a391fbfSSteven Rostedt my $option = "$name\[$i\]"; 32065a391fbfSSteven Rostedt 32075a391fbfSSteven Rostedt if (defined($opt{$option})) { 32085a391fbfSSteven Rostedt return $opt{$option}; 32095a391fbfSSteven Rostedt } 32105a391fbfSSteven Rostedt 3211a57419b3SSteven Rostedt foreach my $test (keys %repeat_tests) { 3212a57419b3SSteven Rostedt if ($i >= $test && 3213a57419b3SSteven Rostedt $i < $test + $repeat_tests{$test}) { 3214a57419b3SSteven Rostedt $option = "$name\[$test\]"; 3215a57419b3SSteven Rostedt if (defined($opt{$option})) { 3216a57419b3SSteven Rostedt return $opt{$option}; 3217a57419b3SSteven Rostedt } 3218a57419b3SSteven Rostedt } 3219a57419b3SSteven Rostedt } 3220a57419b3SSteven Rostedt 32215a391fbfSSteven Rostedt if (defined($opt{$name})) { 32225a391fbfSSteven Rostedt return $opt{$name}; 32235a391fbfSSteven Rostedt } 32245a391fbfSSteven Rostedt 32255a391fbfSSteven Rostedt return undef; 32265a391fbfSSteven Rostedt} 32275a391fbfSSteven Rostedt 32282a62512bSSteven Rostedtsub set_test_option { 32292a62512bSSteven Rostedt my ($name, $i) = @_; 32302a62512bSSteven Rostedt 32312a62512bSSteven Rostedt my $option = __set_test_option($name, $i); 32322a62512bSSteven Rostedt return $option if (!defined($option)); 32332a62512bSSteven Rostedt 323423715c3cSSteven Rostedt return eval_option($option, $i); 32352a62512bSSteven Rostedt} 32362a62512bSSteven Rostedt 32372545eb61SSteven Rostedt# First we need to do is the builds 3238a75fececSSteven Rostedtfor (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) { 32392545eb61SSteven Rostedt 32404ab1cce5SSteven Rostedt # Do not reboot on failing test options 32414ab1cce5SSteven Rostedt $no_reboot = 1; 32424ab1cce5SSteven Rostedt 3243576f627cSSteven Rostedt $iteration = $i; 3244576f627cSSteven Rostedt 3245a75fececSSteven Rostedt my $makecmd = set_test_option("MAKE_CMD", $i); 3246a75fececSSteven Rostedt 3247a75fececSSteven Rostedt $machine = set_test_option("MACHINE", $i); 3248e48c5293SSteven Rostedt $ssh_user = set_test_option("SSH_USER", $i); 3249a75fececSSteven Rostedt $tmpdir = set_test_option("TMP_DIR", $i); 3250a75fececSSteven Rostedt $outputdir = set_test_option("OUTPUT_DIR", $i); 3251a75fececSSteven Rostedt $builddir = set_test_option("BUILD_DIR", $i); 3252a75fececSSteven Rostedt $test_type = set_test_option("TEST_TYPE", $i); 3253a75fececSSteven Rostedt $build_type = set_test_option("BUILD_TYPE", $i); 3254a75fececSSteven Rostedt $build_options = set_test_option("BUILD_OPTIONS", $i); 32550bd6c1a3SSteven Rostedt $pre_build = set_test_option("PRE_BUILD", $i); 32560bd6c1a3SSteven Rostedt $post_build = set_test_option("POST_BUILD", $i); 32570bd6c1a3SSteven Rostedt $pre_build_die = set_test_option("PRE_BUILD_DIE", $i); 32580bd6c1a3SSteven Rostedt $post_build_die = set_test_option("POST_BUILD_DIE", $i); 3259a75fececSSteven Rostedt $power_cycle = set_test_option("POWER_CYCLE", $i); 3260e48c5293SSteven Rostedt $reboot = set_test_option("REBOOT", $i); 3261a75fececSSteven Rostedt $noclean = set_test_option("BUILD_NOCLEAN", $i); 3262a75fececSSteven Rostedt $minconfig = set_test_option("MIN_CONFIG", $i); 32634c4ab120SSteven Rostedt $output_minconfig = set_test_option("OUTPUT_MIN_CONFIG", $i); 32644c4ab120SSteven Rostedt $start_minconfig = set_test_option("START_MIN_CONFIG", $i); 32654c4ab120SSteven Rostedt $ignore_config = set_test_option("IGNORE_CONFIG", $i); 3266a75fececSSteven Rostedt $run_test = set_test_option("TEST", $i); 3267a75fececSSteven Rostedt $addconfig = set_test_option("ADD_CONFIG", $i); 3268a75fececSSteven Rostedt $reboot_type = set_test_option("REBOOT_TYPE", $i); 3269a75fececSSteven Rostedt $grub_menu = set_test_option("GRUB_MENU", $i); 32708b37ca8cSSteven Rostedt $post_install = set_test_option("POST_INSTALL", $i); 3271e0a8742eSSteven Rostedt $no_install = set_test_option("NO_INSTALL", $i); 3272a75fececSSteven Rostedt $reboot_script = set_test_option("REBOOT_SCRIPT", $i); 3273a75fececSSteven Rostedt $reboot_on_error = set_test_option("REBOOT_ON_ERROR", $i); 3274a75fececSSteven Rostedt $poweroff_on_error = set_test_option("POWEROFF_ON_ERROR", $i); 3275a75fececSSteven Rostedt $die_on_failure = set_test_option("DIE_ON_FAILURE", $i); 3276a75fececSSteven Rostedt $power_off = set_test_option("POWER_OFF", $i); 3277576f627cSSteven Rostedt $powercycle_after_reboot = set_test_option("POWERCYCLE_AFTER_REBOOT", $i); 3278576f627cSSteven Rostedt $poweroff_after_halt = set_test_option("POWEROFF_AFTER_HALT", $i); 3279a75fececSSteven Rostedt $sleep_time = set_test_option("SLEEP_TIME", $i); 3280a75fececSSteven Rostedt $bisect_sleep_time = set_test_option("BISECT_SLEEP_TIME", $i); 328127d934b2SSteven Rostedt $patchcheck_sleep_time = set_test_option("PATCHCHECK_SLEEP_TIME", $i); 32821990207dSSteven Rostedt $ignore_warnings = set_test_option("IGNORE_WARNINGS", $i); 3283c960bb9fSSteven Rostedt $bisect_manual = set_test_option("BISECT_MANUAL", $i); 3284c23dca7cSSteven Rostedt $bisect_skip = set_test_option("BISECT_SKIP", $i); 328530f75da5SSteven Rostedt $config_bisect_good = set_test_option("CONFIG_BISECT_GOOD", $i); 3286a75fececSSteven Rostedt $store_failures = set_test_option("STORE_FAILURES", $i); 3287de5b6e3bSRabin Vincent $store_successes = set_test_option("STORE_SUCCESSES", $i); 32889064af52SSteven Rostedt $test_name = set_test_option("TEST_NAME", $i); 3289a75fececSSteven Rostedt $timeout = set_test_option("TIMEOUT", $i); 3290a75fececSSteven Rostedt $booted_timeout = set_test_option("BOOTED_TIMEOUT", $i); 3291a75fececSSteven Rostedt $console = set_test_option("CONSOLE", $i); 3292f1a5b962SSteven Rostedt $detect_triplefault = set_test_option("DETECT_TRIPLE_FAULT", $i); 3293a75fececSSteven Rostedt $success_line = set_test_option("SUCCESS_LINE", $i); 32942b803365SSteven Rostedt $reboot_success_line = set_test_option("REBOOT_SUCCESS_LINE", $i); 32951c8a617aSSteven Rostedt $stop_after_success = set_test_option("STOP_AFTER_SUCCESS", $i); 32961c8a617aSSteven Rostedt $stop_after_failure = set_test_option("STOP_AFTER_FAILURE", $i); 32972d01b26aSSteven Rostedt $stop_test_after = set_test_option("STOP_TEST_AFTER", $i); 3298a75fececSSteven Rostedt $build_target = set_test_option("BUILD_TARGET", $i); 3299e48c5293SSteven Rostedt $ssh_exec = set_test_option("SSH_EXEC", $i); 3300e48c5293SSteven Rostedt $scp_to_target = set_test_option("SCP_TO_TARGET", $i); 3301a75fececSSteven Rostedt $target_image = set_test_option("TARGET_IMAGE", $i); 3302a75fececSSteven Rostedt $localversion = set_test_option("LOCALVERSION", $i); 3303a75fececSSteven Rostedt 330435ce5952SSteven Rostedt $start_minconfig_defined = 1; 330535ce5952SSteven Rostedt 33064c4ab120SSteven Rostedt if (!defined($start_minconfig)) { 330735ce5952SSteven Rostedt $start_minconfig_defined = 0; 33084c4ab120SSteven Rostedt $start_minconfig = $minconfig; 33094c4ab120SSteven Rostedt } 33104c4ab120SSteven Rostedt 3311a75fececSSteven Rostedt chdir $builddir || die "can't change directory to $builddir"; 3312a75fececSSteven Rostedt 3313a908a665SAndrew Jones foreach my $dir ($tmpdir, $outputdir) { 3314a908a665SAndrew Jones if (!-d $dir) { 3315a908a665SAndrew Jones mkpath($dir) or 3316a908a665SAndrew Jones die "can't create $dir"; 3317a908a665SAndrew Jones } 3318a75fececSSteven Rostedt } 3319a75fececSSteven Rostedt 3320e48c5293SSteven Rostedt $ENV{"SSH_USER"} = $ssh_user; 3321e48c5293SSteven Rostedt $ENV{"MACHINE"} = $machine; 3322e48c5293SSteven Rostedt 3323a75fececSSteven Rostedt $buildlog = "$tmpdir/buildlog-$machine"; 3324a9dd5d63SRabin Vincent $testlog = "$tmpdir/testlog-$machine"; 3325a75fececSSteven Rostedt $dmesg = "$tmpdir/dmesg-$machine"; 3326a75fececSSteven Rostedt $make = "$makecmd O=$outputdir"; 332751ad1dd1SSteven Rostedt $output_config = "$outputdir/.config"; 3328a75fececSSteven Rostedt 3329bb8474b1SSteven Rostedt if (!$buildonly) { 3330bb8474b1SSteven Rostedt $target = "$ssh_user\@$machine"; 3331a75fececSSteven Rostedt if ($reboot_type eq "grub") { 3332576f627cSSteven Rostedt dodie "GRUB_MENU not defined" if (!defined($grub_menu)); 3333a75fececSSteven Rostedt } elsif (!defined($reboot_script)) { 3334576f627cSSteven Rostedt dodie "REBOOT_SCRIPT not defined" 3335a75fececSSteven Rostedt } 3336bb8474b1SSteven Rostedt } 3337a75fececSSteven Rostedt 3338a75fececSSteven Rostedt my $run_type = $build_type; 3339a75fececSSteven Rostedt if ($test_type eq "patchcheck") { 3340a75fececSSteven Rostedt $run_type = $opt{"PATCHCHECK_TYPE[$i]"}; 3341a75fececSSteven Rostedt } elsif ($test_type eq "bisect") { 3342a75fececSSteven Rostedt $run_type = $opt{"BISECT_TYPE[$i]"}; 33430a05c769SSteven Rostedt } elsif ($test_type eq "config_bisect") { 33440a05c769SSteven Rostedt $run_type = $opt{"CONFIG_BISECT_TYPE[$i]"}; 3345a75fececSSteven Rostedt } 3346a75fececSSteven Rostedt 33474c4ab120SSteven Rostedt if ($test_type eq "make_min_config") { 33484c4ab120SSteven Rostedt $run_type = ""; 33494c4ab120SSteven Rostedt } 33504c4ab120SSteven Rostedt 3351a75fececSSteven Rostedt # mistake in config file? 3352a75fececSSteven Rostedt if (!defined($run_type)) { 3353a75fececSSteven Rostedt $run_type = "ERROR"; 3354a75fececSSteven Rostedt } 33552545eb61SSteven Rostedt 3356e0a8742eSSteven Rostedt my $installme = ""; 3357e0a8742eSSteven Rostedt $installme = " no_install" if ($no_install); 3358e0a8742eSSteven Rostedt 33592545eb61SSteven Rostedt doprint "\n\n"; 3360e0a8742eSSteven Rostedt doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type$installme\n\n"; 33617faafbd6SSteven Rostedt 33627faafbd6SSteven Rostedt unlink $dmesg; 33637faafbd6SSteven Rostedt unlink $buildlog; 3364a9dd5d63SRabin Vincent unlink $testlog; 33652545eb61SSteven Rostedt 3366250bae8bSSteven Rostedt if (defined($addconfig)) { 3367250bae8bSSteven Rostedt my $min = $minconfig; 33682b7d9b21SSteven Rostedt if (!defined($minconfig)) { 3369250bae8bSSteven Rostedt $min = ""; 3370250bae8bSSteven Rostedt } 3371250bae8bSSteven Rostedt run_command "cat $addconfig $min > $tmpdir/add_config" or 33722b7d9b21SSteven Rostedt dodie "Failed to create temp config"; 33739be2e6b5SSteven Rostedt $minconfig = "$tmpdir/add_config"; 33742b7d9b21SSteven Rostedt } 33752b7d9b21SSteven Rostedt 33766c5ee0beSSteven Rostedt my $checkout = $opt{"CHECKOUT[$i]"}; 33776c5ee0beSSteven Rostedt if (defined($checkout)) { 33786c5ee0beSSteven Rostedt run_command "git checkout $checkout" or 33796c5ee0beSSteven Rostedt die "failed to checkout $checkout"; 33806c5ee0beSSteven Rostedt } 33816c5ee0beSSteven Rostedt 33824ab1cce5SSteven Rostedt $no_reboot = 0; 33834ab1cce5SSteven Rostedt 33844ab1cce5SSteven Rostedt 3385a75fececSSteven Rostedt if ($test_type eq "bisect") { 33865f9b6cedSSteven Rostedt bisect $i; 33875f9b6cedSSteven Rostedt next; 33880a05c769SSteven Rostedt } elsif ($test_type eq "config_bisect") { 33890a05c769SSteven Rostedt config_bisect $i; 33900a05c769SSteven Rostedt next; 3391a75fececSSteven Rostedt } elsif ($test_type eq "patchcheck") { 33926c5ee0beSSteven Rostedt patchcheck $i; 33936c5ee0beSSteven Rostedt next; 33944c4ab120SSteven Rostedt } elsif ($test_type eq "make_min_config") { 33954c4ab120SSteven Rostedt make_min_config $i; 33964c4ab120SSteven Rostedt next; 33975f9b6cedSSteven Rostedt } 33985f9b6cedSSteven Rostedt 33997faafbd6SSteven Rostedt if ($build_type ne "nobuild") { 34007faafbd6SSteven Rostedt build $build_type or next; 34012545eb61SSteven Rostedt } 34022545eb61SSteven Rostedt 3403cd8e368fSSteven Rostedt if ($test_type eq "install") { 3404cd8e368fSSteven Rostedt get_version; 3405cd8e368fSSteven Rostedt install; 3406cd8e368fSSteven Rostedt success $i; 3407cd8e368fSSteven Rostedt next; 3408cd8e368fSSteven Rostedt } 3409cd8e368fSSteven Rostedt 3410a75fececSSteven Rostedt if ($test_type ne "build") { 34117faafbd6SSteven Rostedt my $failed = 0; 3412ddf607e5SSteven Rostedt start_monitor_and_boot or $failed = 1; 3413a75fececSSteven Rostedt 3414a75fececSSteven Rostedt if (!$failed && $test_type ne "boot" && defined($run_test)) { 34157faafbd6SSteven Rostedt do_run_test or $failed = 1; 34165a391fbfSSteven Rostedt } 34177faafbd6SSteven Rostedt end_monitor; 34187faafbd6SSteven Rostedt next if ($failed); 3419a75fececSSteven Rostedt } 34205a391fbfSSteven Rostedt 34215f9b6cedSSteven Rostedt success $i; 342275c3fda7SSteven Rostedt} 34232545eb61SSteven Rostedt 34245c42fc5bSSteven Rostedtif ($opt{"POWEROFF_ON_SUCCESS"}) { 342575c3fda7SSteven Rostedt halt; 3426576f627cSSteven Rostedt} elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot) { 342775c3fda7SSteven Rostedt reboot; 34285c42fc5bSSteven Rostedt} 342975c3fda7SSteven Rostedt 3430e48c5293SSteven Rostedtdoprint "\n $successes of $opt{NUM_TESTS} tests were successful\n\n"; 3431e48c5293SSteven Rostedt 34322545eb61SSteven Rostedtexit 0; 3433