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; 25*bb8474b1SSteven 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 139*bb8474b1SSteven Rostedt# set when a test is something other that just building 140*bb8474b1SSteven Rostedt# which would require more options. 141*bb8474b1SSteven Rostedtmy $buildonly = 1; 142*bb8474b1SSteven Rostedt 1438d1491baSSteven Rostedtmy %entered_configs; 1448d1491baSSteven Rostedtmy %config_help; 14577d942ceSSteven Rostedtmy %variable; 146fcb3f16aSSteven Rostedtmy %force_config; 1478d1491baSSteven Rostedt 1484ab1cce5SSteven Rostedt# do not force reboots on config problems 1494ab1cce5SSteven Rostedtmy $no_reboot = 1; 1504ab1cce5SSteven Rostedt 1517bf51073SSteven Rostedt# default variables that can be used 1527bf51073SSteven Rostedtchomp ($variable{"PWD"} = `pwd`); 1537bf51073SSteven Rostedt 1548d1491baSSteven Rostedt$config_help{"MACHINE"} = << "EOF" 1558d1491baSSteven Rostedt The machine hostname that you will test. 156*bb8474b1SSteven Rostedt For build only tests, it is still needed to differentiate log files. 1578d1491baSSteven RostedtEOF 1588d1491baSSteven Rostedt ; 1598d1491baSSteven Rostedt$config_help{"SSH_USER"} = << "EOF" 1608d1491baSSteven Rostedt The box is expected to have ssh on normal bootup, provide the user 1618d1491baSSteven Rostedt (most likely root, since you need privileged operations) 1628d1491baSSteven RostedtEOF 1638d1491baSSteven Rostedt ; 1648d1491baSSteven Rostedt$config_help{"BUILD_DIR"} = << "EOF" 1658d1491baSSteven Rostedt The directory that contains the Linux source code (full path). 1660e7a22deSSteven Rostedt You can use \${PWD} that will be the path where ktest.pl is run, or use 1670e7a22deSSteven Rostedt \${THIS_DIR} which is assigned \${PWD} but may be changed later. 1688d1491baSSteven RostedtEOF 1698d1491baSSteven Rostedt ; 1708d1491baSSteven Rostedt$config_help{"OUTPUT_DIR"} = << "EOF" 1718d1491baSSteven Rostedt The directory that the objects will be built (full path). 1728d1491baSSteven Rostedt (can not be same as BUILD_DIR) 1730e7a22deSSteven Rostedt You can use \${PWD} that will be the path where ktest.pl is run, or use 1740e7a22deSSteven Rostedt \${THIS_DIR} which is assigned \${PWD} but may be changed later. 1758d1491baSSteven RostedtEOF 1768d1491baSSteven Rostedt ; 1778d1491baSSteven Rostedt$config_help{"BUILD_TARGET"} = << "EOF" 1788d1491baSSteven Rostedt The location of the compiled file to copy to the target. 1798d1491baSSteven Rostedt (relative to OUTPUT_DIR) 1808d1491baSSteven RostedtEOF 1818d1491baSSteven Rostedt ; 1828d1491baSSteven Rostedt$config_help{"TARGET_IMAGE"} = << "EOF" 1838d1491baSSteven Rostedt The place to put your image on the test machine. 1848d1491baSSteven RostedtEOF 1858d1491baSSteven Rostedt ; 1868d1491baSSteven Rostedt$config_help{"POWER_CYCLE"} = << "EOF" 1878d1491baSSteven Rostedt A script or command to reboot the box. 1888d1491baSSteven Rostedt 1898d1491baSSteven Rostedt Here is a digital loggers power switch example 1908d1491baSSteven Rostedt POWER_CYCLE = wget --no-proxy -O /dev/null -q --auth-no-challenge 'http://admin:admin\@power/outlet?5=CCL' 1918d1491baSSteven Rostedt 1928d1491baSSteven Rostedt Here is an example to reboot a virtual box on the current host 1938d1491baSSteven Rostedt with the name "Guest". 1948d1491baSSteven Rostedt POWER_CYCLE = virsh destroy Guest; sleep 5; virsh start Guest 1958d1491baSSteven RostedtEOF 1968d1491baSSteven Rostedt ; 1978d1491baSSteven Rostedt$config_help{"CONSOLE"} = << "EOF" 1988d1491baSSteven Rostedt The script or command that reads the console 1998d1491baSSteven Rostedt 2008d1491baSSteven Rostedt If you use ttywatch server, something like the following would work. 2018d1491baSSteven RostedtCONSOLE = nc -d localhost 3001 2028d1491baSSteven Rostedt 2038d1491baSSteven Rostedt For a virtual machine with guest name "Guest". 2048d1491baSSteven RostedtCONSOLE = virsh console Guest 2058d1491baSSteven RostedtEOF 2068d1491baSSteven Rostedt ; 2078d1491baSSteven Rostedt$config_help{"LOCALVERSION"} = << "EOF" 2088d1491baSSteven Rostedt Required version ending to differentiate the test 2098d1491baSSteven Rostedt from other linux builds on the system. 2108d1491baSSteven RostedtEOF 2118d1491baSSteven Rostedt ; 2128d1491baSSteven Rostedt$config_help{"REBOOT_TYPE"} = << "EOF" 2138d1491baSSteven Rostedt Way to reboot the box to the test kernel. 2148d1491baSSteven Rostedt Only valid options so far are "grub" and "script". 2158d1491baSSteven Rostedt 2168d1491baSSteven Rostedt If you specify grub, it will assume grub version 1 2178d1491baSSteven Rostedt and will search in /boot/grub/menu.lst for the title \$GRUB_MENU 2188d1491baSSteven Rostedt and select that target to reboot to the kernel. If this is not 2198d1491baSSteven Rostedt your setup, then specify "script" and have a command or script 2208d1491baSSteven Rostedt specified in REBOOT_SCRIPT to boot to the target. 2218d1491baSSteven Rostedt 2228d1491baSSteven Rostedt The entry in /boot/grub/menu.lst must be entered in manually. 2238d1491baSSteven Rostedt The test will not modify that file. 2248d1491baSSteven RostedtEOF 2258d1491baSSteven Rostedt ; 2268d1491baSSteven Rostedt$config_help{"GRUB_MENU"} = << "EOF" 2278d1491baSSteven Rostedt The grub title name for the test kernel to boot 2288d1491baSSteven Rostedt (Only mandatory if REBOOT_TYPE = grub) 2298d1491baSSteven Rostedt 2308d1491baSSteven Rostedt Note, ktest.pl will not update the grub menu.lst, you need to 2318d1491baSSteven Rostedt manually add an option for the test. ktest.pl will search 2328d1491baSSteven Rostedt the grub menu.lst for this option to find what kernel to 2338d1491baSSteven Rostedt reboot into. 2348d1491baSSteven Rostedt 2358d1491baSSteven Rostedt For example, if in the /boot/grub/menu.lst the test kernel title has: 2368d1491baSSteven Rostedt title Test Kernel 2378d1491baSSteven Rostedt kernel vmlinuz-test 2388d1491baSSteven Rostedt GRUB_MENU = Test Kernel 2398d1491baSSteven RostedtEOF 2408d1491baSSteven Rostedt ; 2418d1491baSSteven Rostedt$config_help{"REBOOT_SCRIPT"} = << "EOF" 2428d1491baSSteven Rostedt A script to reboot the target into the test kernel 2438d1491baSSteven Rostedt (Only mandatory if REBOOT_TYPE = script) 2448d1491baSSteven RostedtEOF 2458d1491baSSteven Rostedt ; 2468d1491baSSteven Rostedt 247dad98754SSteven Rostedtsub read_prompt { 248dad98754SSteven Rostedt my ($cancel, $prompt) = @_; 24935ce5952SSteven Rostedt 25035ce5952SSteven Rostedt my $ans; 25135ce5952SSteven Rostedt 25235ce5952SSteven Rostedt for (;;) { 253dad98754SSteven Rostedt if ($cancel) { 254dad98754SSteven Rostedt print "$prompt [y/n/C] "; 255dad98754SSteven Rostedt } else { 25635ce5952SSteven Rostedt print "$prompt [Y/n] "; 257dad98754SSteven Rostedt } 25835ce5952SSteven Rostedt $ans = <STDIN>; 25935ce5952SSteven Rostedt chomp $ans; 26035ce5952SSteven Rostedt if ($ans =~ /^\s*$/) { 261dad98754SSteven Rostedt if ($cancel) { 262dad98754SSteven Rostedt $ans = "c"; 263dad98754SSteven Rostedt } else { 26435ce5952SSteven Rostedt $ans = "y"; 26535ce5952SSteven Rostedt } 266dad98754SSteven Rostedt } 26735ce5952SSteven Rostedt last if ($ans =~ /^y$/i || $ans =~ /^n$/i); 268dad98754SSteven Rostedt if ($cancel) { 269dad98754SSteven Rostedt last if ($ans =~ /^c$/i); 270dad98754SSteven Rostedt print "Please answer either 'y', 'n' or 'c'.\n"; 271dad98754SSteven Rostedt } else { 27235ce5952SSteven Rostedt print "Please answer either 'y' or 'n'.\n"; 27335ce5952SSteven Rostedt } 274dad98754SSteven Rostedt } 275dad98754SSteven Rostedt if ($ans =~ /^c/i) { 276dad98754SSteven Rostedt exit; 277dad98754SSteven Rostedt } 27835ce5952SSteven Rostedt if ($ans !~ /^y$/i) { 27935ce5952SSteven Rostedt return 0; 28035ce5952SSteven Rostedt } 28135ce5952SSteven Rostedt return 1; 28235ce5952SSteven Rostedt} 2838d1491baSSteven Rostedt 284dad98754SSteven Rostedtsub read_yn { 285dad98754SSteven Rostedt my ($prompt) = @_; 286dad98754SSteven Rostedt 287dad98754SSteven Rostedt return read_prompt 0, $prompt; 288dad98754SSteven Rostedt} 289dad98754SSteven Rostedt 290dad98754SSteven Rostedtsub read_ync { 291dad98754SSteven Rostedt my ($prompt) = @_; 292dad98754SSteven Rostedt 293dad98754SSteven Rostedt return read_prompt 1, $prompt; 294dad98754SSteven Rostedt} 295dad98754SSteven Rostedt 2968d1491baSSteven Rostedtsub get_ktest_config { 2978d1491baSSteven Rostedt my ($config) = @_; 298815e2bd7SSteven Rostedt my $ans; 2998d1491baSSteven Rostedt 3008d1491baSSteven Rostedt return if (defined($opt{$config})); 3018d1491baSSteven Rostedt 3028d1491baSSteven Rostedt if (defined($config_help{$config})) { 3038d1491baSSteven Rostedt print "\n"; 3048d1491baSSteven Rostedt print $config_help{$config}; 3058d1491baSSteven Rostedt } 3068d1491baSSteven Rostedt 3078d1491baSSteven Rostedt for (;;) { 3088d1491baSSteven Rostedt print "$config = "; 3098d1491baSSteven Rostedt if (defined($default{$config})) { 3108d1491baSSteven Rostedt print "\[$default{$config}\] "; 3118d1491baSSteven Rostedt } 312815e2bd7SSteven Rostedt $ans = <STDIN>; 313815e2bd7SSteven Rostedt $ans =~ s/^\s*(.*\S)\s*$/$1/; 314815e2bd7SSteven Rostedt if ($ans =~ /^\s*$/) { 3158d1491baSSteven Rostedt if ($default{$config}) { 316815e2bd7SSteven Rostedt $ans = $default{$config}; 3178d1491baSSteven Rostedt } else { 3188d1491baSSteven Rostedt print "Your answer can not be blank\n"; 3198d1491baSSteven Rostedt next; 3208d1491baSSteven Rostedt } 3218d1491baSSteven Rostedt } 3220e7a22deSSteven Rostedt $entered_configs{$config} = ${ans}; 3238d1491baSSteven Rostedt last; 3248d1491baSSteven Rostedt } 3258d1491baSSteven Rostedt} 3268d1491baSSteven Rostedt 3278d1491baSSteven Rostedtsub get_ktest_configs { 3288d1491baSSteven Rostedt get_ktest_config("MACHINE"); 3298d1491baSSteven Rostedt get_ktest_config("BUILD_DIR"); 3308d1491baSSteven Rostedt get_ktest_config("OUTPUT_DIR"); 331*bb8474b1SSteven Rostedt 332*bb8474b1SSteven Rostedt # options required for other than just building a kernel 333*bb8474b1SSteven Rostedt if (!$buildonly) { 334*bb8474b1SSteven Rostedt get_ktest_config("SSH_USER"); 3358d1491baSSteven Rostedt get_ktest_config("BUILD_TARGET"); 3368d1491baSSteven Rostedt get_ktest_config("TARGET_IMAGE"); 3378d1491baSSteven Rostedt get_ktest_config("POWER_CYCLE"); 3388d1491baSSteven Rostedt get_ktest_config("CONSOLE"); 339*bb8474b1SSteven Rostedt } 340*bb8474b1SSteven Rostedt 3418d1491baSSteven Rostedt get_ktest_config("LOCALVERSION"); 3428d1491baSSteven Rostedt 343*bb8474b1SSteven Rostedt return if ($buildonly); 344*bb8474b1SSteven Rostedt 3458d1491baSSteven Rostedt my $rtype = $opt{"REBOOT_TYPE"}; 3468d1491baSSteven Rostedt 3478d1491baSSteven Rostedt if (!defined($rtype)) { 3488d1491baSSteven Rostedt if (!defined($opt{"GRUB_MENU"})) { 3498d1491baSSteven Rostedt get_ktest_config("REBOOT_TYPE"); 3508d1491baSSteven Rostedt $rtype = $entered_configs{"REBOOT_TYPE"}; 3518d1491baSSteven Rostedt } else { 3528d1491baSSteven Rostedt $rtype = "grub"; 3538d1491baSSteven Rostedt } 3548d1491baSSteven Rostedt } 3558d1491baSSteven Rostedt 3568d1491baSSteven Rostedt if ($rtype eq "grub") { 3578d1491baSSteven Rostedt get_ktest_config("GRUB_MENU"); 3588d1491baSSteven Rostedt } else { 3598d1491baSSteven Rostedt get_ktest_config("REBOOT_SCRIPT"); 3608d1491baSSteven Rostedt } 3618d1491baSSteven Rostedt} 3628d1491baSSteven Rostedt 36377d942ceSSteven Rostedtsub process_variables { 3648d735212SSteven Rostedt my ($value, $remove_undef) = @_; 36577d942ceSSteven Rostedt my $retval = ""; 36677d942ceSSteven Rostedt 36777d942ceSSteven Rostedt # We want to check for '\', and it is just easier 36877d942ceSSteven Rostedt # to check the previous characet of '$' and not need 36977d942ceSSteven Rostedt # to worry if '$' is the first character. By adding 37077d942ceSSteven Rostedt # a space to $value, we can just check [^\\]\$ and 37177d942ceSSteven Rostedt # it will still work. 37277d942ceSSteven Rostedt $value = " $value"; 37377d942ceSSteven Rostedt 37477d942ceSSteven Rostedt while ($value =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) { 37577d942ceSSteven Rostedt my $begin = $1; 37677d942ceSSteven Rostedt my $var = $2; 37777d942ceSSteven Rostedt my $end = $3; 37877d942ceSSteven Rostedt # append beginning of value to retval 37977d942ceSSteven Rostedt $retval = "$retval$begin"; 38077d942ceSSteven Rostedt if (defined($variable{$var})) { 38177d942ceSSteven Rostedt $retval = "$retval$variable{$var}"; 3828d735212SSteven Rostedt } elsif (defined($remove_undef) && $remove_undef) { 3838d735212SSteven Rostedt # for if statements, any variable that is not defined, 3848d735212SSteven Rostedt # we simple convert to 0 3858d735212SSteven Rostedt $retval = "${retval}0"; 38677d942ceSSteven Rostedt } else { 38777d942ceSSteven Rostedt # put back the origin piece. 38877d942ceSSteven Rostedt $retval = "$retval\$\{$var\}"; 38977d942ceSSteven Rostedt } 39077d942ceSSteven Rostedt $value = $end; 39177d942ceSSteven Rostedt } 39277d942ceSSteven Rostedt $retval = "$retval$value"; 39377d942ceSSteven Rostedt 39477d942ceSSteven Rostedt # remove the space added in the beginning 39577d942ceSSteven Rostedt $retval =~ s/ //; 39677d942ceSSteven Rostedt 39777d942ceSSteven Rostedt return "$retval" 39877d942ceSSteven Rostedt} 39977d942ceSSteven Rostedt 400a57419b3SSteven Rostedtsub set_value { 4013d1cc414SSteven Rostedt my ($lvalue, $rvalue, $override, $overrides, $name) = @_; 4022545eb61SSteven Rostedt 403*bb8474b1SSteven Rostedt if ($lvalue =~ /^TEST_TYPE(\[.*\])?$/ && $rvalue ne "build") { 404*bb8474b1SSteven Rostedt # Note if a test is something other than build, then we 405*bb8474b1SSteven Rostedt # will need other manditory options. 406*bb8474b1SSteven Rostedt $buildonly = 0; 407*bb8474b1SSteven Rostedt } 408*bb8474b1SSteven Rostedt 409a75fececSSteven Rostedt if (defined($opt{$lvalue})) { 4103d1cc414SSteven Rostedt if (!$override || defined(${$overrides}{$lvalue})) { 4113d1cc414SSteven Rostedt my $extra = ""; 4123d1cc414SSteven Rostedt if ($override) { 4133d1cc414SSteven Rostedt $extra = "In the same override section!\n"; 4143d1cc414SSteven Rostedt } 4153d1cc414SSteven Rostedt die "$name: $.: Option $lvalue defined more than once!\n$extra"; 4163d1cc414SSteven Rostedt } 4173d1cc414SSteven Rostedt ${$overrides}{$lvalue} = $rvalue; 418a75fececSSteven Rostedt } 41921a9679fSSteven Rostedt if ($rvalue =~ /^\s*$/) { 42021a9679fSSteven Rostedt delete $opt{$lvalue}; 42121a9679fSSteven Rostedt } else { 42277d942ceSSteven Rostedt $rvalue = process_variables($rvalue); 42321a9679fSSteven Rostedt $opt{$lvalue} = $rvalue; 42421a9679fSSteven Rostedt } 4252545eb61SSteven Rostedt} 426a57419b3SSteven Rostedt 42777d942ceSSteven Rostedtsub set_variable { 42877d942ceSSteven Rostedt my ($lvalue, $rvalue) = @_; 42977d942ceSSteven Rostedt 43077d942ceSSteven Rostedt if ($rvalue =~ /^\s*$/) { 43177d942ceSSteven Rostedt delete $variable{$lvalue}; 43277d942ceSSteven Rostedt } else { 43377d942ceSSteven Rostedt $rvalue = process_variables($rvalue); 43477d942ceSSteven Rostedt $variable{$lvalue} = $rvalue; 43577d942ceSSteven Rostedt } 43677d942ceSSteven Rostedt} 43777d942ceSSteven Rostedt 438ab7a3f52SSteven Rostedtsub process_compare { 439ab7a3f52SSteven Rostedt my ($lval, $cmp, $rval) = @_; 440ab7a3f52SSteven Rostedt 441ab7a3f52SSteven Rostedt # remove whitespace 442ab7a3f52SSteven Rostedt 443ab7a3f52SSteven Rostedt $lval =~ s/^\s*//; 444ab7a3f52SSteven Rostedt $lval =~ s/\s*$//; 445ab7a3f52SSteven Rostedt 446ab7a3f52SSteven Rostedt $rval =~ s/^\s*//; 447ab7a3f52SSteven Rostedt $rval =~ s/\s*$//; 448ab7a3f52SSteven Rostedt 449ab7a3f52SSteven Rostedt if ($cmp eq "==") { 450ab7a3f52SSteven Rostedt return $lval eq $rval; 451ab7a3f52SSteven Rostedt } elsif ($cmp eq "!=") { 452ab7a3f52SSteven Rostedt return $lval ne $rval; 453ab7a3f52SSteven Rostedt } 454ab7a3f52SSteven Rostedt 455ab7a3f52SSteven Rostedt my $statement = "$lval $cmp $rval"; 456ab7a3f52SSteven Rostedt my $ret = eval $statement; 457ab7a3f52SSteven Rostedt 458ab7a3f52SSteven Rostedt # $@ stores error of eval 459ab7a3f52SSteven Rostedt if ($@) { 460ab7a3f52SSteven Rostedt return -1; 461ab7a3f52SSteven Rostedt } 462ab7a3f52SSteven Rostedt 463ab7a3f52SSteven Rostedt return $ret; 464ab7a3f52SSteven Rostedt} 465ab7a3f52SSteven Rostedt 4669900b5dcSSteven Rostedtsub value_defined { 4679900b5dcSSteven Rostedt my ($val) = @_; 4689900b5dcSSteven Rostedt 4699900b5dcSSteven Rostedt return defined($variable{$2}) || 4709900b5dcSSteven Rostedt defined($opt{$2}); 4719900b5dcSSteven Rostedt} 4729900b5dcSSteven Rostedt 4738d735212SSteven Rostedtmy $d = 0; 4748d735212SSteven Rostedtsub process_expression { 4758d735212SSteven Rostedt my ($name, $val) = @_; 47645d73a5dSSteven Rostedt 4778d735212SSteven Rostedt my $c = $d++; 4788d735212SSteven Rostedt 4798d735212SSteven Rostedt while ($val =~ s/\(([^\(]*?)\)/\&\&\&\&VAL\&\&\&\&/) { 4808d735212SSteven Rostedt my $express = $1; 4818d735212SSteven Rostedt 4828d735212SSteven Rostedt if (process_expression($name, $express)) { 4838d735212SSteven Rostedt $val =~ s/\&\&\&\&VAL\&\&\&\&/ 1 /; 4848d735212SSteven Rostedt } else { 4858d735212SSteven Rostedt $val =~ s/\&\&\&\&VAL\&\&\&\&/ 0 /; 4868d735212SSteven Rostedt } 4878d735212SSteven Rostedt } 4888d735212SSteven Rostedt 4898d735212SSteven Rostedt $d--; 4908d735212SSteven Rostedt my $OR = "\\|\\|"; 4918d735212SSteven Rostedt my $AND = "\\&\\&"; 4928d735212SSteven Rostedt 4938d735212SSteven Rostedt while ($val =~ s/^(.*?)($OR|$AND)//) { 4948d735212SSteven Rostedt my $express = $1; 4958d735212SSteven Rostedt my $op = $2; 4968d735212SSteven Rostedt 4978d735212SSteven Rostedt if (process_expression($name, $express)) { 4988d735212SSteven Rostedt if ($op eq "||") { 4998d735212SSteven Rostedt return 1; 5008d735212SSteven Rostedt } 5018d735212SSteven Rostedt } else { 5028d735212SSteven Rostedt if ($op eq "&&") { 5038d735212SSteven Rostedt return 0; 5048d735212SSteven Rostedt } 5058d735212SSteven Rostedt } 5068d735212SSteven Rostedt } 50745d73a5dSSteven Rostedt 508ab7a3f52SSteven Rostedt if ($val =~ /(.*)(==|\!=|>=|<=|>|<)(.*)/) { 509ab7a3f52SSteven Rostedt my $ret = process_compare($1, $2, $3); 510ab7a3f52SSteven Rostedt if ($ret < 0) { 511ab7a3f52SSteven Rostedt die "$name: $.: Unable to process comparison\n"; 512ab7a3f52SSteven Rostedt } 513ab7a3f52SSteven Rostedt return $ret; 514ab7a3f52SSteven Rostedt } 515ab7a3f52SSteven Rostedt 5169900b5dcSSteven Rostedt if ($val =~ /^\s*(NOT\s*)?DEFINED\s+(\S+)\s*$/) { 5179900b5dcSSteven Rostedt if (defined $1) { 5189900b5dcSSteven Rostedt return !value_defined($2); 5199900b5dcSSteven Rostedt } else { 5209900b5dcSSteven Rostedt return value_defined($2); 5219900b5dcSSteven Rostedt } 5229900b5dcSSteven Rostedt } 5239900b5dcSSteven Rostedt 52445d73a5dSSteven Rostedt if ($val =~ /^\s*0\s*$/) { 52545d73a5dSSteven Rostedt return 0; 52645d73a5dSSteven Rostedt } elsif ($val =~ /^\s*\d+\s*$/) { 52745d73a5dSSteven Rostedt return 1; 52845d73a5dSSteven Rostedt } 52945d73a5dSSteven Rostedt 5309900b5dcSSteven Rostedt die ("$name: $.: Undefined content $val in if statement\n"); 5318d735212SSteven Rostedt} 5328d735212SSteven Rostedt 5338d735212SSteven Rostedtsub process_if { 5348d735212SSteven Rostedt my ($name, $value) = @_; 5358d735212SSteven Rostedt 5368d735212SSteven Rostedt # Convert variables and replace undefined ones with 0 5378d735212SSteven Rostedt my $val = process_variables($value, 1); 5388d735212SSteven Rostedt my $ret = process_expression $name, $val; 5398d735212SSteven Rostedt 5408d735212SSteven Rostedt return $ret; 54145d73a5dSSteven Rostedt} 54245d73a5dSSteven Rostedt 5432ed3b161SSteven Rostedtsub __read_config { 5442ed3b161SSteven Rostedt my ($config, $current_test_num) = @_; 545a57419b3SSteven Rostedt 5462ed3b161SSteven Rostedt my $in; 5472ed3b161SSteven Rostedt open($in, $config) || die "can't read file $config"; 548a57419b3SSteven Rostedt 549a57419b3SSteven Rostedt my $name = $config; 550a57419b3SSteven Rostedt $name =~ s,.*/(.*),$1,; 551a57419b3SSteven Rostedt 5522ed3b161SSteven Rostedt my $test_num = $$current_test_num; 553a57419b3SSteven Rostedt my $default = 1; 554a57419b3SSteven Rostedt my $repeat = 1; 555a57419b3SSteven Rostedt my $num_tests_set = 0; 556a57419b3SSteven Rostedt my $skip = 0; 557a57419b3SSteven Rostedt my $rest; 558a9f84424SSteven Rostedt my $line; 5590df213caSSteven Rostedt my $test_case = 0; 56045d73a5dSSteven Rostedt my $if = 0; 56145d73a5dSSteven Rostedt my $if_set = 0; 5623d1cc414SSteven Rostedt my $override = 0; 5633d1cc414SSteven Rostedt 5643d1cc414SSteven Rostedt my %overrides; 565a57419b3SSteven Rostedt 5662ed3b161SSteven Rostedt while (<$in>) { 567a57419b3SSteven Rostedt 568a57419b3SSteven Rostedt # ignore blank lines and comments 569a57419b3SSteven Rostedt next if (/^\s*$/ || /\s*\#/); 570a57419b3SSteven Rostedt 5710050b6bbSSteven Rostedt if (/^\s*(TEST_START|DEFAULTS)\b(.*)/) { 572a57419b3SSteven Rostedt 5730050b6bbSSteven Rostedt my $type = $1; 5740050b6bbSSteven Rostedt $rest = $2; 575a9f84424SSteven Rostedt $line = $2; 5760050b6bbSSteven Rostedt 5770050b6bbSSteven Rostedt my $old_test_num; 5780050b6bbSSteven Rostedt my $old_repeat; 5793d1cc414SSteven Rostedt $override = 0; 5800050b6bbSSteven Rostedt 5810050b6bbSSteven Rostedt if ($type eq "TEST_START") { 582a57419b3SSteven Rostedt 583a57419b3SSteven Rostedt if ($num_tests_set) { 584a57419b3SSteven Rostedt die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n"; 585a57419b3SSteven Rostedt } 586a57419b3SSteven Rostedt 5870050b6bbSSteven Rostedt $old_test_num = $test_num; 5880050b6bbSSteven Rostedt $old_repeat = $repeat; 589a57419b3SSteven Rostedt 590a57419b3SSteven Rostedt $test_num += $repeat; 591a57419b3SSteven Rostedt $default = 0; 592a57419b3SSteven Rostedt $repeat = 1; 5930050b6bbSSteven Rostedt } else { 5940050b6bbSSteven Rostedt $default = 1; 5950050b6bbSSteven Rostedt } 596a57419b3SSteven Rostedt 597a9f84424SSteven Rostedt # If SKIP is anywhere in the line, the command will be skipped 598a9f84424SSteven Rostedt if ($rest =~ s/\s+SKIP\b//) { 599a57419b3SSteven Rostedt $skip = 1; 600a57419b3SSteven Rostedt } else { 6010df213caSSteven Rostedt $test_case = 1; 602a57419b3SSteven Rostedt $skip = 0; 603a57419b3SSteven Rostedt } 604a57419b3SSteven Rostedt 605a9f84424SSteven Rostedt if ($rest =~ s/\sELSE\b//) { 606a9f84424SSteven Rostedt if (!$if) { 607a9f84424SSteven Rostedt die "$name: $.: ELSE found with out matching IF section\n$_"; 608a57419b3SSteven Rostedt } 609a9f84424SSteven Rostedt $if = 0; 610a9f84424SSteven Rostedt 611a9f84424SSteven Rostedt if ($if_set) { 612a9f84424SSteven Rostedt $skip = 1; 613a9f84424SSteven Rostedt } else { 614a9f84424SSteven Rostedt $skip = 0; 6153d1cc414SSteven Rostedt } 6163d1cc414SSteven Rostedt } 617a57419b3SSteven Rostedt 618a9f84424SSteven Rostedt if ($rest =~ s/\sIF\s+(.*)//) { 61945d73a5dSSteven Rostedt if (process_if($name, $1)) { 62045d73a5dSSteven Rostedt $if_set = 1; 62145d73a5dSSteven Rostedt } else { 622a57419b3SSteven Rostedt $skip = 1; 623a57419b3SSteven Rostedt } 62445d73a5dSSteven Rostedt $if = 1; 62545d73a5dSSteven Rostedt } else { 62645d73a5dSSteven Rostedt $if = 0; 627a9f84424SSteven Rostedt $if_set = 0; 62845d73a5dSSteven Rostedt } 629a57419b3SSteven Rostedt 630a9f84424SSteven Rostedt if (!$skip) { 631a9f84424SSteven Rostedt if ($type eq "TEST_START") { 632a9f84424SSteven Rostedt if ($rest =~ s/\s+ITERATE\s+(\d+)//) { 633a9f84424SSteven Rostedt $repeat = $1; 634a9f84424SSteven Rostedt $repeat_tests{"$test_num"} = $repeat; 635a9f84424SSteven Rostedt } 636a9f84424SSteven Rostedt } elsif ($rest =~ s/\sOVERRIDE\b//) { 637a9f84424SSteven Rostedt # DEFAULT only 638a9f84424SSteven Rostedt $override = 1; 639a9f84424SSteven Rostedt # Clear previous overrides 640a9f84424SSteven Rostedt %overrides = (); 641a9f84424SSteven Rostedt } 642a9f84424SSteven Rostedt } 643a9f84424SSteven Rostedt 644a9f84424SSteven Rostedt if (!$skip && $rest !~ /^\s*$/) { 6450050b6bbSSteven Rostedt die "$name: $.: Gargbage found after $type\n$_"; 646a57419b3SSteven Rostedt } 647a57419b3SSteven Rostedt 6480050b6bbSSteven Rostedt if ($skip && $type eq "TEST_START") { 649a57419b3SSteven Rostedt $test_num = $old_test_num; 650e48c5293SSteven Rostedt $repeat = $old_repeat; 651a57419b3SSteven Rostedt } 652a57419b3SSteven Rostedt 653ab7a3f52SSteven Rostedt } elsif (/^\s*ELSE\b(.*)$/) { 65445d73a5dSSteven Rostedt if (!$if) { 65545d73a5dSSteven Rostedt die "$name: $.: ELSE found with out matching IF section\n$_"; 65645d73a5dSSteven Rostedt } 65745d73a5dSSteven Rostedt $rest = $1; 65845d73a5dSSteven Rostedt if ($if_set) { 65945d73a5dSSteven Rostedt $skip = 1; 660ab7a3f52SSteven Rostedt $rest = ""; 66145d73a5dSSteven Rostedt } else { 66245d73a5dSSteven Rostedt $skip = 0; 66345d73a5dSSteven Rostedt 664ab7a3f52SSteven Rostedt if ($rest =~ /\sIF\s+(.*)/) { 66545d73a5dSSteven Rostedt # May be a ELSE IF section. 66645d73a5dSSteven Rostedt if (!process_if($name, $1)) { 66745d73a5dSSteven Rostedt $skip = 1; 66845d73a5dSSteven Rostedt } 669ab7a3f52SSteven Rostedt $rest = ""; 67045d73a5dSSteven Rostedt } else { 67145d73a5dSSteven Rostedt $if = 0; 67245d73a5dSSteven Rostedt } 67345d73a5dSSteven Rostedt } 67445d73a5dSSteven Rostedt 675ab7a3f52SSteven Rostedt if ($rest !~ /^\s*$/) { 676ab7a3f52SSteven Rostedt die "$name: $.: Gargbage found after DEFAULTS\n$_"; 677ab7a3f52SSteven Rostedt } 678ab7a3f52SSteven Rostedt 6792ed3b161SSteven Rostedt } elsif (/^\s*INCLUDE\s+(\S+)/) { 6802ed3b161SSteven Rostedt 6812ed3b161SSteven Rostedt next if ($skip); 6822ed3b161SSteven Rostedt 6832ed3b161SSteven Rostedt if (!$default) { 6842ed3b161SSteven Rostedt die "$name: $.: INCLUDE can only be done in default sections\n$_"; 6852ed3b161SSteven Rostedt } 6862ed3b161SSteven Rostedt 6872ed3b161SSteven Rostedt my $file = process_variables($1); 6882ed3b161SSteven Rostedt 6892ed3b161SSteven Rostedt if ($file !~ m,^/,) { 6902ed3b161SSteven Rostedt # check the path of the config file first 6912ed3b161SSteven Rostedt if ($config =~ m,(.*)/,) { 6922ed3b161SSteven Rostedt if (-f "$1/$file") { 6932ed3b161SSteven Rostedt $file = "$1/$file"; 6942ed3b161SSteven Rostedt } 6952ed3b161SSteven Rostedt } 6962ed3b161SSteven Rostedt } 6972ed3b161SSteven Rostedt 6982ed3b161SSteven Rostedt if ( ! -r $file ) { 6992ed3b161SSteven Rostedt die "$name: $.: Can't read file $file\n$_"; 7002ed3b161SSteven Rostedt } 7012ed3b161SSteven Rostedt 7022ed3b161SSteven Rostedt if (__read_config($file, \$test_num)) { 7032ed3b161SSteven Rostedt $test_case = 1; 7042ed3b161SSteven Rostedt } 7052ed3b161SSteven Rostedt 706a57419b3SSteven Rostedt } elsif (/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) { 707a57419b3SSteven Rostedt 708a57419b3SSteven Rostedt next if ($skip); 709a57419b3SSteven Rostedt 710a57419b3SSteven Rostedt my $lvalue = $1; 711a57419b3SSteven Rostedt my $rvalue = $2; 712a57419b3SSteven Rostedt 713a57419b3SSteven Rostedt if (!$default && 714a57419b3SSteven Rostedt ($lvalue eq "NUM_TESTS" || 715a57419b3SSteven Rostedt $lvalue eq "LOG_FILE" || 716a57419b3SSteven Rostedt $lvalue eq "CLEAR_LOG")) { 717a57419b3SSteven Rostedt die "$name: $.: $lvalue must be set in DEFAULTS section\n"; 718a57419b3SSteven Rostedt } 719a57419b3SSteven Rostedt 720a57419b3SSteven Rostedt if ($lvalue eq "NUM_TESTS") { 721a57419b3SSteven Rostedt if ($test_num) { 722a57419b3SSteven Rostedt die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n"; 723a57419b3SSteven Rostedt } 724a57419b3SSteven Rostedt if (!$default) { 725a57419b3SSteven Rostedt die "$name: $.: NUM_TESTS must be set in default section\n"; 726a57419b3SSteven Rostedt } 727a57419b3SSteven Rostedt $num_tests_set = 1; 728a57419b3SSteven Rostedt } 729a57419b3SSteven Rostedt 730a57419b3SSteven Rostedt if ($default || $lvalue =~ /\[\d+\]$/) { 7313d1cc414SSteven Rostedt set_value($lvalue, $rvalue, $override, \%overrides, $name); 732a57419b3SSteven Rostedt } else { 733a57419b3SSteven Rostedt my $val = "$lvalue\[$test_num\]"; 7343d1cc414SSteven Rostedt set_value($val, $rvalue, $override, \%overrides, $name); 735a57419b3SSteven Rostedt 736a57419b3SSteven Rostedt if ($repeat > 1) { 737a57419b3SSteven Rostedt $repeats{$val} = $repeat; 738a57419b3SSteven Rostedt } 739a57419b3SSteven Rostedt } 74077d942ceSSteven Rostedt } elsif (/^\s*([A-Z_\[\]\d]+)\s*:=\s*(.*?)\s*$/) { 74177d942ceSSteven Rostedt next if ($skip); 74277d942ceSSteven Rostedt 74377d942ceSSteven Rostedt my $lvalue = $1; 74477d942ceSSteven Rostedt my $rvalue = $2; 74577d942ceSSteven Rostedt 74677d942ceSSteven Rostedt # process config variables. 74777d942ceSSteven Rostedt # Config variables are only active while reading the 74877d942ceSSteven Rostedt # config and can be defined anywhere. They also ignore 74977d942ceSSteven Rostedt # TEST_START and DEFAULTS, but are skipped if they are in 75077d942ceSSteven Rostedt # on of these sections that have SKIP defined. 75177d942ceSSteven Rostedt # The save variable can be 75277d942ceSSteven Rostedt # defined multiple times and the new one simply overrides 75377d942ceSSteven Rostedt # the prevous one. 75477d942ceSSteven Rostedt set_variable($lvalue, $rvalue); 75577d942ceSSteven Rostedt 756a57419b3SSteven Rostedt } else { 757a57419b3SSteven Rostedt die "$name: $.: Garbage found in config\n$_"; 758a57419b3SSteven Rostedt } 7592545eb61SSteven Rostedt } 7602545eb61SSteven Rostedt 761a57419b3SSteven Rostedt if ($test_num) { 762a57419b3SSteven Rostedt $test_num += $repeat - 1; 763a57419b3SSteven Rostedt $opt{"NUM_TESTS"} = $test_num; 764a57419b3SSteven Rostedt } 765a57419b3SSteven Rostedt 7662ed3b161SSteven Rostedt close($in); 7672ed3b161SSteven Rostedt 7682ed3b161SSteven Rostedt $$current_test_num = $test_num; 7692ed3b161SSteven Rostedt 7702ed3b161SSteven Rostedt return $test_case; 7712ed3b161SSteven Rostedt} 7722ed3b161SSteven Rostedt 773c4261d0fSSteven Rostedtsub get_test_case { 774c4261d0fSSteven Rostedt print "What test case would you like to run?\n"; 775c4261d0fSSteven Rostedt print " (build, install or boot)\n"; 776c4261d0fSSteven Rostedt print " Other tests are available but require editing the config file\n"; 777c4261d0fSSteven Rostedt my $ans = <STDIN>; 778c4261d0fSSteven Rostedt chomp $ans; 779c4261d0fSSteven Rostedt $default{"TEST_TYPE"} = $ans; 780c4261d0fSSteven Rostedt} 781c4261d0fSSteven Rostedt 7822ed3b161SSteven Rostedtsub read_config { 7832ed3b161SSteven Rostedt my ($config) = @_; 7842ed3b161SSteven Rostedt 7852ed3b161SSteven Rostedt my $test_case; 7862ed3b161SSteven Rostedt my $test_num = 0; 7872ed3b161SSteven Rostedt 7882ed3b161SSteven Rostedt $test_case = __read_config $config, \$test_num; 7892ed3b161SSteven Rostedt 7908d1491baSSteven Rostedt # make sure we have all mandatory configs 7918d1491baSSteven Rostedt get_ktest_configs; 7928d1491baSSteven Rostedt 7930df213caSSteven Rostedt # was a test specified? 7940df213caSSteven Rostedt if (!$test_case) { 7950df213caSSteven Rostedt print "No test case specified.\n"; 796c4261d0fSSteven Rostedt get_test_case; 7970df213caSSteven Rostedt } 7980df213caSSteven Rostedt 799a75fececSSteven Rostedt # set any defaults 800a75fececSSteven Rostedt 801a75fececSSteven Rostedt foreach my $default (keys %default) { 802a75fececSSteven Rostedt if (!defined($opt{$default})) { 803a75fececSSteven Rostedt $opt{$default} = $default{$default}; 804a75fececSSteven Rostedt } 805a75fececSSteven Rostedt } 8062545eb61SSteven Rostedt} 8072545eb61SSteven Rostedt 80823715c3cSSteven Rostedtsub __eval_option { 80923715c3cSSteven Rostedt my ($option, $i) = @_; 81023715c3cSSteven Rostedt 81123715c3cSSteven Rostedt # Add space to evaluate the character before $ 81223715c3cSSteven Rostedt $option = " $option"; 81323715c3cSSteven Rostedt my $retval = ""; 814f9dfb65bSRabin Vincent my $repeated = 0; 815f9dfb65bSRabin Vincent my $parent = 0; 816f9dfb65bSRabin Vincent 817f9dfb65bSRabin Vincent foreach my $test (keys %repeat_tests) { 818f9dfb65bSRabin Vincent if ($i >= $test && 819f9dfb65bSRabin Vincent $i < $test + $repeat_tests{$test}) { 820f9dfb65bSRabin Vincent 821f9dfb65bSRabin Vincent $repeated = 1; 822f9dfb65bSRabin Vincent $parent = $test; 823f9dfb65bSRabin Vincent last; 824f9dfb65bSRabin Vincent } 825f9dfb65bSRabin Vincent } 82623715c3cSSteven Rostedt 82723715c3cSSteven Rostedt while ($option =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) { 82823715c3cSSteven Rostedt my $start = $1; 82923715c3cSSteven Rostedt my $var = $2; 83023715c3cSSteven Rostedt my $end = $3; 83123715c3cSSteven Rostedt 83223715c3cSSteven Rostedt # Append beginning of line 83323715c3cSSteven Rostedt $retval = "$retval$start"; 83423715c3cSSteven Rostedt 83523715c3cSSteven Rostedt # If the iteration option OPT[$i] exists, then use that. 83623715c3cSSteven Rostedt # otherwise see if the default OPT (without [$i]) exists. 83723715c3cSSteven Rostedt 83823715c3cSSteven Rostedt my $o = "$var\[$i\]"; 839f9dfb65bSRabin Vincent my $parento = "$var\[$parent\]"; 84023715c3cSSteven Rostedt 84123715c3cSSteven Rostedt if (defined($opt{$o})) { 84223715c3cSSteven Rostedt $o = $opt{$o}; 84323715c3cSSteven Rostedt $retval = "$retval$o"; 844f9dfb65bSRabin Vincent } elsif ($repeated && defined($opt{$parento})) { 845f9dfb65bSRabin Vincent $o = $opt{$parento}; 846f9dfb65bSRabin Vincent $retval = "$retval$o"; 84723715c3cSSteven Rostedt } elsif (defined($opt{$var})) { 84823715c3cSSteven Rostedt $o = $opt{$var}; 84923715c3cSSteven Rostedt $retval = "$retval$o"; 85023715c3cSSteven Rostedt } else { 85123715c3cSSteven Rostedt $retval = "$retval\$\{$var\}"; 85223715c3cSSteven Rostedt } 85323715c3cSSteven Rostedt 85423715c3cSSteven Rostedt $option = $end; 85523715c3cSSteven Rostedt } 85623715c3cSSteven Rostedt 85723715c3cSSteven Rostedt $retval = "$retval$option"; 85823715c3cSSteven Rostedt 85923715c3cSSteven Rostedt $retval =~ s/^ //; 86023715c3cSSteven Rostedt 86123715c3cSSteven Rostedt return $retval; 86223715c3cSSteven Rostedt} 86323715c3cSSteven Rostedt 86423715c3cSSteven Rostedtsub eval_option { 86523715c3cSSteven Rostedt my ($option, $i) = @_; 86623715c3cSSteven Rostedt 86723715c3cSSteven Rostedt my $prev = ""; 86823715c3cSSteven Rostedt 86923715c3cSSteven Rostedt # Since an option can evaluate to another option, 87023715c3cSSteven Rostedt # keep iterating until we do not evaluate any more 87123715c3cSSteven Rostedt # options. 87223715c3cSSteven Rostedt my $r = 0; 87323715c3cSSteven Rostedt while ($prev ne $option) { 87423715c3cSSteven Rostedt # Check for recursive evaluations. 87523715c3cSSteven Rostedt # 100 deep should be more than enough. 87623715c3cSSteven Rostedt if ($r++ > 100) { 87723715c3cSSteven Rostedt die "Over 100 evaluations accurred with $option\n" . 87823715c3cSSteven Rostedt "Check for recursive variables\n"; 87923715c3cSSteven Rostedt } 88023715c3cSSteven Rostedt $prev = $option; 88123715c3cSSteven Rostedt $option = __eval_option($option, $i); 88223715c3cSSteven Rostedt } 88323715c3cSSteven Rostedt 88423715c3cSSteven Rostedt return $option; 88523715c3cSSteven Rostedt} 88623715c3cSSteven Rostedt 887d1e2f22aSSteven Rostedtsub _logit { 8882545eb61SSteven Rostedt if (defined($opt{"LOG_FILE"})) { 8892545eb61SSteven Rostedt open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}"; 8902545eb61SSteven Rostedt print OUT @_; 8912545eb61SSteven Rostedt close(OUT); 8922545eb61SSteven Rostedt } 8932545eb61SSteven Rostedt} 8942545eb61SSteven Rostedt 895d1e2f22aSSteven Rostedtsub logit { 896d1e2f22aSSteven Rostedt if (defined($opt{"LOG_FILE"})) { 897d1e2f22aSSteven Rostedt _logit @_; 898d1e2f22aSSteven Rostedt } else { 899d1e2f22aSSteven Rostedt print @_; 900d1e2f22aSSteven Rostedt } 901d1e2f22aSSteven Rostedt} 902d1e2f22aSSteven Rostedt 9035f9b6cedSSteven Rostedtsub doprint { 9045f9b6cedSSteven Rostedt print @_; 905d1e2f22aSSteven Rostedt _logit @_; 9065f9b6cedSSteven Rostedt} 9075f9b6cedSSteven Rostedt 9087faafbd6SSteven Rostedtsub run_command; 9092728be41SAndrew Jonessub start_monitor; 9102728be41SAndrew Jonessub end_monitor; 9112728be41SAndrew Jonessub wait_for_monitor; 9127faafbd6SSteven Rostedt 9137faafbd6SSteven Rostedtsub reboot { 9142728be41SAndrew Jones my ($time) = @_; 9152728be41SAndrew Jones 9162b803365SSteven Rostedt if (defined($time)) { 9172b803365SSteven Rostedt start_monitor; 9182b803365SSteven Rostedt # flush out current monitor 9192b803365SSteven Rostedt # May contain the reboot success line 9202b803365SSteven Rostedt wait_for_monitor 1; 9212b803365SSteven Rostedt } 9222b803365SSteven Rostedt 9237faafbd6SSteven Rostedt # try to reboot normally 924e48c5293SSteven Rostedt if (run_command $reboot) { 925576f627cSSteven Rostedt if (defined($powercycle_after_reboot)) { 926576f627cSSteven Rostedt sleep $powercycle_after_reboot; 927576f627cSSteven Rostedt run_command "$power_cycle"; 928576f627cSSteven Rostedt } 929576f627cSSteven Rostedt } else { 9307faafbd6SSteven Rostedt # nope? power cycle it. 931a75fececSSteven Rostedt run_command "$power_cycle"; 9327faafbd6SSteven Rostedt } 9332728be41SAndrew Jones 9342728be41SAndrew Jones if (defined($time)) { 9352b803365SSteven Rostedt wait_for_monitor($time, $reboot_success_line); 9362728be41SAndrew Jones end_monitor; 9372728be41SAndrew Jones } 9387faafbd6SSteven Rostedt} 9397faafbd6SSteven Rostedt 940576f627cSSteven Rostedtsub do_not_reboot { 941576f627cSSteven Rostedt my $i = $iteration; 942576f627cSSteven Rostedt 9434ab1cce5SSteven Rostedt return $test_type eq "build" || $no_reboot || 944576f627cSSteven Rostedt ($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") || 945576f627cSSteven Rostedt ($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build"); 946576f627cSSteven Rostedt} 947576f627cSSteven Rostedt 9485c42fc5bSSteven Rostedtsub dodie { 9495a391fbfSSteven Rostedt doprint "CRITICAL FAILURE... ", @_, "\n"; 9505c42fc5bSSteven Rostedt 951576f627cSSteven Rostedt my $i = $iteration; 952576f627cSSteven Rostedt 953576f627cSSteven Rostedt if ($reboot_on_error && !do_not_reboot) { 954576f627cSSteven Rostedt 95575c3fda7SSteven Rostedt doprint "REBOOTING\n"; 9567faafbd6SSteven Rostedt reboot; 95775c3fda7SSteven Rostedt 958a75fececSSteven Rostedt } elsif ($poweroff_on_error && defined($power_off)) { 9595c42fc5bSSteven Rostedt doprint "POWERING OFF\n"; 960a75fececSSteven Rostedt `$power_off`; 9615c42fc5bSSteven Rostedt } 96275c3fda7SSteven Rostedt 963f80802cbSSteven Rostedt if (defined($opt{"LOG_FILE"})) { 964f80802cbSSteven Rostedt print " See $opt{LOG_FILE} for more info.\n"; 965f80802cbSSteven Rostedt } 966f80802cbSSteven Rostedt 967576f627cSSteven Rostedt die @_, "\n"; 9685c42fc5bSSteven Rostedt} 9695c42fc5bSSteven Rostedt 9707faafbd6SSteven Rostedtsub open_console { 9717faafbd6SSteven Rostedt my ($fp) = @_; 9727faafbd6SSteven Rostedt 9737faafbd6SSteven Rostedt my $flags; 9747faafbd6SSteven Rostedt 975a75fececSSteven Rostedt my $pid = open($fp, "$console|") or 976a75fececSSteven Rostedt dodie "Can't open console $console"; 9777faafbd6SSteven Rostedt 9787faafbd6SSteven Rostedt $flags = fcntl($fp, F_GETFL, 0) or 979576f627cSSteven Rostedt dodie "Can't get flags for the socket: $!"; 9807faafbd6SSteven Rostedt $flags = fcntl($fp, F_SETFL, $flags | O_NONBLOCK) or 981576f627cSSteven Rostedt dodie "Can't set flags for the socket: $!"; 9827faafbd6SSteven Rostedt 9837faafbd6SSteven Rostedt return $pid; 9847faafbd6SSteven Rostedt} 9857faafbd6SSteven Rostedt 9867faafbd6SSteven Rostedtsub close_console { 9877faafbd6SSteven Rostedt my ($fp, $pid) = @_; 9887faafbd6SSteven Rostedt 9897faafbd6SSteven Rostedt doprint "kill child process $pid\n"; 9907faafbd6SSteven Rostedt kill 2, $pid; 9917faafbd6SSteven Rostedt 9927faafbd6SSteven Rostedt print "closing!\n"; 9937faafbd6SSteven Rostedt close($fp); 9947faafbd6SSteven Rostedt} 9957faafbd6SSteven Rostedt 9967faafbd6SSteven Rostedtsub start_monitor { 9977faafbd6SSteven Rostedt if ($monitor_cnt++) { 9987faafbd6SSteven Rostedt return; 9997faafbd6SSteven Rostedt } 10007faafbd6SSteven Rostedt $monitor_fp = \*MONFD; 10017faafbd6SSteven Rostedt $monitor_pid = open_console $monitor_fp; 1002a75fececSSteven Rostedt 1003a75fececSSteven Rostedt return; 1004a75fececSSteven Rostedt 1005a75fececSSteven Rostedt open(MONFD, "Stop perl from warning about single use of MONFD"); 10067faafbd6SSteven Rostedt} 10077faafbd6SSteven Rostedt 10087faafbd6SSteven Rostedtsub end_monitor { 10097faafbd6SSteven Rostedt if (--$monitor_cnt) { 10107faafbd6SSteven Rostedt return; 10117faafbd6SSteven Rostedt } 10127faafbd6SSteven Rostedt close_console($monitor_fp, $monitor_pid); 10137faafbd6SSteven Rostedt} 10147faafbd6SSteven Rostedt 10157faafbd6SSteven Rostedtsub wait_for_monitor { 10162b803365SSteven Rostedt my ($time, $stop) = @_; 10172b803365SSteven Rostedt my $full_line = ""; 10187faafbd6SSteven Rostedt my $line; 10192b803365SSteven Rostedt my $booted = 0; 10207faafbd6SSteven Rostedt 1021a75fececSSteven Rostedt doprint "** Wait for monitor to settle down **\n"; 10227faafbd6SSteven Rostedt 10237faafbd6SSteven Rostedt # read the monitor and wait for the system to calm down 10242b803365SSteven Rostedt while (!$booted) { 10257faafbd6SSteven Rostedt $line = wait_for_input($monitor_fp, $time); 10262b803365SSteven Rostedt last if (!defined($line)); 10272b803365SSteven Rostedt print "$line"; 10282b803365SSteven Rostedt $full_line .= $line; 10292b803365SSteven Rostedt 10302b803365SSteven Rostedt if (defined($stop) && $full_line =~ /$stop/) { 10312b803365SSteven Rostedt doprint "wait for monitor detected $stop\n"; 10322b803365SSteven Rostedt $booted = 1; 10332b803365SSteven Rostedt } 10342b803365SSteven Rostedt 10352b803365SSteven Rostedt if ($line =~ /\n/) { 10362b803365SSteven Rostedt $full_line = ""; 10372b803365SSteven Rostedt } 10382b803365SSteven Rostedt } 1039a75fececSSteven Rostedt print "** Monitor flushed **\n"; 10407faafbd6SSteven Rostedt} 10417faafbd6SSteven Rostedt 1042de5b6e3bSRabin Vincentsub save_logs { 1043de5b6e3bSRabin Vincent my ($result, $basedir) = @_; 1044de5b6e3bSRabin Vincent my @t = localtime; 1045de5b6e3bSRabin Vincent my $date = sprintf "%04d%02d%02d%02d%02d%02d", 1046de5b6e3bSRabin Vincent 1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0]; 1047de5b6e3bSRabin Vincent 1048de5b6e3bSRabin Vincent my $type = $build_type; 1049de5b6e3bSRabin Vincent if ($type =~ /useconfig/) { 1050de5b6e3bSRabin Vincent $type = "useconfig"; 1051de5b6e3bSRabin Vincent } 1052de5b6e3bSRabin Vincent 1053de5b6e3bSRabin Vincent my $dir = "$machine-$test_type-$type-$result-$date"; 1054de5b6e3bSRabin Vincent 1055de5b6e3bSRabin Vincent $dir = "$basedir/$dir"; 1056de5b6e3bSRabin Vincent 1057de5b6e3bSRabin Vincent if (!-d $dir) { 1058de5b6e3bSRabin Vincent mkpath($dir) or 1059de5b6e3bSRabin Vincent die "can't create $dir"; 1060de5b6e3bSRabin Vincent } 1061de5b6e3bSRabin Vincent 1062de5b6e3bSRabin Vincent my %files = ( 1063de5b6e3bSRabin Vincent "config" => $output_config, 1064de5b6e3bSRabin Vincent "buildlog" => $buildlog, 1065de5b6e3bSRabin Vincent "dmesg" => $dmesg, 1066de5b6e3bSRabin Vincent "testlog" => $testlog, 1067de5b6e3bSRabin Vincent ); 1068de5b6e3bSRabin Vincent 1069de5b6e3bSRabin Vincent while (my ($name, $source) = each(%files)) { 1070de5b6e3bSRabin Vincent if (-f "$source") { 1071de5b6e3bSRabin Vincent cp "$source", "$dir/$name" or 1072de5b6e3bSRabin Vincent die "failed to copy $source"; 1073de5b6e3bSRabin Vincent } 1074de5b6e3bSRabin Vincent } 1075de5b6e3bSRabin Vincent 1076de5b6e3bSRabin Vincent doprint "*** Saved info to $dir ***\n"; 1077de5b6e3bSRabin Vincent} 1078de5b6e3bSRabin Vincent 10792b7d9b21SSteven Rostedtsub fail { 10802b7d9b21SSteven Rostedt 1081a75fececSSteven Rostedt if ($die_on_failure) { 10822b7d9b21SSteven Rostedt dodie @_; 10832b7d9b21SSteven Rostedt } 10842b7d9b21SSteven Rostedt 1085a75fececSSteven Rostedt doprint "FAILED\n"; 10867faafbd6SSteven Rostedt 1087576f627cSSteven Rostedt my $i = $iteration; 1088576f627cSSteven Rostedt 1089a75fececSSteven Rostedt # no need to reboot for just building. 1090576f627cSSteven Rostedt if (!do_not_reboot) { 10917faafbd6SSteven Rostedt doprint "REBOOTING\n"; 10922728be41SAndrew Jones reboot $sleep_time; 1093a75fececSSteven Rostedt } 10947faafbd6SSteven Rostedt 10959064af52SSteven Rostedt my $name = ""; 10969064af52SSteven Rostedt 10979064af52SSteven Rostedt if (defined($test_name)) { 10989064af52SSteven Rostedt $name = " ($test_name)"; 10999064af52SSteven Rostedt } 11009064af52SSteven Rostedt 1101576f627cSSteven Rostedt doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; 1102576f627cSSteven Rostedt doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; 11039064af52SSteven Rostedt doprint "KTEST RESULT: TEST $i$name Failed: ", @_, "\n"; 1104576f627cSSteven Rostedt doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; 1105576f627cSSteven Rostedt doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; 1106a75fececSSteven Rostedt 1107de5b6e3bSRabin Vincent if (defined($store_failures)) { 1108de5b6e3bSRabin Vincent save_logs "fail", $store_failures; 1109cccae1a6SSteven Rostedt } 1110cccae1a6SSteven Rostedt 11112b7d9b21SSteven Rostedt return 1; 11122b7d9b21SSteven Rostedt} 11132b7d9b21SSteven Rostedt 11142545eb61SSteven Rostedtsub run_command { 11152545eb61SSteven Rostedt my ($command) = @_; 1116d6ce2a0bSSteven Rostedt my $dolog = 0; 1117d6ce2a0bSSteven Rostedt my $dord = 0; 1118d6ce2a0bSSteven Rostedt my $pid; 1119d6ce2a0bSSteven Rostedt 1120e48c5293SSteven Rostedt $command =~ s/\$SSH_USER/$ssh_user/g; 1121e48c5293SSteven Rostedt $command =~ s/\$MACHINE/$machine/g; 1122e48c5293SSteven Rostedt 1123d6ce2a0bSSteven Rostedt doprint("$command ... "); 1124d6ce2a0bSSteven Rostedt 1125d6ce2a0bSSteven Rostedt $pid = open(CMD, "$command 2>&1 |") or 11262b7d9b21SSteven Rostedt (fail "unable to exec $command" and return 0); 11272545eb61SSteven Rostedt 11282545eb61SSteven Rostedt if (defined($opt{"LOG_FILE"})) { 1129d6ce2a0bSSteven Rostedt open(LOG, ">>$opt{LOG_FILE}") or 1130d6ce2a0bSSteven Rostedt dodie "failed to write to log"; 1131d6ce2a0bSSteven Rostedt $dolog = 1; 11326c5ee0beSSteven Rostedt } 11336c5ee0beSSteven Rostedt 11346c5ee0beSSteven Rostedt if (defined($redirect)) { 1135d6ce2a0bSSteven Rostedt open (RD, ">$redirect") or 1136d6ce2a0bSSteven Rostedt dodie "failed to write to redirect $redirect"; 1137d6ce2a0bSSteven Rostedt $dord = 1; 11382545eb61SSteven Rostedt } 11392545eb61SSteven Rostedt 1140d6ce2a0bSSteven Rostedt while (<CMD>) { 1141d6ce2a0bSSteven Rostedt print LOG if ($dolog); 1142d6ce2a0bSSteven Rostedt print RD if ($dord); 1143d6ce2a0bSSteven Rostedt } 11442545eb61SSteven Rostedt 1145d6ce2a0bSSteven Rostedt waitpid($pid, 0); 11462545eb61SSteven Rostedt my $failed = $?; 11472545eb61SSteven Rostedt 1148d6ce2a0bSSteven Rostedt close(CMD); 1149d6ce2a0bSSteven Rostedt close(LOG) if ($dolog); 1150d6ce2a0bSSteven Rostedt close(RD) if ($dord); 1151d6ce2a0bSSteven Rostedt 11522545eb61SSteven Rostedt if ($failed) { 11532545eb61SSteven Rostedt doprint "FAILED!\n"; 11542545eb61SSteven Rostedt } else { 11552545eb61SSteven Rostedt doprint "SUCCESS\n"; 11562545eb61SSteven Rostedt } 11572545eb61SSteven Rostedt 11585f9b6cedSSteven Rostedt return !$failed; 11595f9b6cedSSteven Rostedt} 11605f9b6cedSSteven Rostedt 1161e48c5293SSteven Rostedtsub run_ssh { 1162e48c5293SSteven Rostedt my ($cmd) = @_; 1163e48c5293SSteven Rostedt my $cp_exec = $ssh_exec; 1164e48c5293SSteven Rostedt 1165e48c5293SSteven Rostedt $cp_exec =~ s/\$SSH_COMMAND/$cmd/g; 1166e48c5293SSteven Rostedt return run_command "$cp_exec"; 1167e48c5293SSteven Rostedt} 1168e48c5293SSteven Rostedt 1169e48c5293SSteven Rostedtsub run_scp { 1170e48c5293SSteven Rostedt my ($src, $dst) = @_; 1171e48c5293SSteven Rostedt my $cp_scp = $scp_to_target; 1172e48c5293SSteven Rostedt 1173e48c5293SSteven Rostedt $cp_scp =~ s/\$SRC_FILE/$src/g; 1174e48c5293SSteven Rostedt $cp_scp =~ s/\$DST_FILE/$dst/g; 1175e48c5293SSteven Rostedt 1176e48c5293SSteven Rostedt return run_command "$cp_scp"; 1177e48c5293SSteven Rostedt} 1178e48c5293SSteven Rostedt 11795f9b6cedSSteven Rostedtsub get_grub_index { 11805f9b6cedSSteven Rostedt 1181a75fececSSteven Rostedt if ($reboot_type ne "grub") { 1182a75fececSSteven Rostedt return; 1183a75fececSSteven Rostedt } 11845a391fbfSSteven Rostedt return if (defined($grub_number)); 11855f9b6cedSSteven Rostedt 11865f9b6cedSSteven Rostedt doprint "Find grub menu ... "; 11875f9b6cedSSteven Rostedt $grub_number = -1; 1188e48c5293SSteven Rostedt 1189e48c5293SSteven Rostedt my $ssh_grub = $ssh_exec; 1190e48c5293SSteven Rostedt $ssh_grub =~ s,\$SSH_COMMAND,cat /boot/grub/menu.lst,g; 1191e48c5293SSteven Rostedt 1192e48c5293SSteven Rostedt open(IN, "$ssh_grub |") 11935f9b6cedSSteven Rostedt or die "unable to get menu.lst"; 1194e48c5293SSteven Rostedt 1195eaa1fe25SSteven Rostedt my $found = 0; 1196eaa1fe25SSteven Rostedt 11975f9b6cedSSteven Rostedt while (<IN>) { 1198a75fececSSteven Rostedt if (/^\s*title\s+$grub_menu\s*$/) { 11995f9b6cedSSteven Rostedt $grub_number++; 1200eaa1fe25SSteven Rostedt $found = 1; 12015f9b6cedSSteven Rostedt last; 12025f9b6cedSSteven Rostedt } elsif (/^\s*title\s/) { 12035f9b6cedSSteven Rostedt $grub_number++; 12045f9b6cedSSteven Rostedt } 12055f9b6cedSSteven Rostedt } 12065f9b6cedSSteven Rostedt close(IN); 12075f9b6cedSSteven Rostedt 1208a75fececSSteven Rostedt die "Could not find '$grub_menu' in /boot/grub/menu on $machine" 1209eaa1fe25SSteven Rostedt if (!$found); 12105f9b6cedSSteven Rostedt doprint "$grub_number\n"; 12112545eb61SSteven Rostedt} 12122545eb61SSteven Rostedt 12132545eb61SSteven Rostedtsub wait_for_input 12142545eb61SSteven Rostedt{ 12152545eb61SSteven Rostedt my ($fp, $time) = @_; 12162545eb61SSteven Rostedt my $rin; 12172545eb61SSteven Rostedt my $ready; 12182545eb61SSteven Rostedt my $line; 12192545eb61SSteven Rostedt my $ch; 12202545eb61SSteven Rostedt 12212545eb61SSteven Rostedt if (!defined($time)) { 12222545eb61SSteven Rostedt $time = $timeout; 12232545eb61SSteven Rostedt } 12242545eb61SSteven Rostedt 12252545eb61SSteven Rostedt $rin = ''; 12262545eb61SSteven Rostedt vec($rin, fileno($fp), 1) = 1; 12272545eb61SSteven Rostedt $ready = select($rin, undef, undef, $time); 12282545eb61SSteven Rostedt 12292545eb61SSteven Rostedt $line = ""; 12302545eb61SSteven Rostedt 12312545eb61SSteven Rostedt # try to read one char at a time 12322545eb61SSteven Rostedt while (sysread $fp, $ch, 1) { 12332545eb61SSteven Rostedt $line .= $ch; 12342545eb61SSteven Rostedt last if ($ch eq "\n"); 12352545eb61SSteven Rostedt } 12362545eb61SSteven Rostedt 12372545eb61SSteven Rostedt if (!length($line)) { 12382545eb61SSteven Rostedt return undef; 12392545eb61SSteven Rostedt } 12402545eb61SSteven Rostedt 12412545eb61SSteven Rostedt return $line; 12422545eb61SSteven Rostedt} 12432545eb61SSteven Rostedt 124475c3fda7SSteven Rostedtsub reboot_to { 1245a75fececSSteven Rostedt if ($reboot_type eq "grub") { 1246c54367f9SSteven Rostedt run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch)'"; 1247c54367f9SSteven Rostedt reboot; 1248a75fececSSteven Rostedt return; 1249a75fececSSteven Rostedt } 1250a75fececSSteven Rostedt 1251a75fececSSteven Rostedt run_command "$reboot_script"; 12522545eb61SSteven Rostedt} 12532545eb61SSteven Rostedt 1254a57419b3SSteven Rostedtsub get_sha1 { 1255a57419b3SSteven Rostedt my ($commit) = @_; 1256a57419b3SSteven Rostedt 1257a57419b3SSteven Rostedt doprint "git rev-list --max-count=1 $commit ... "; 1258a57419b3SSteven Rostedt my $sha1 = `git rev-list --max-count=1 $commit`; 1259a57419b3SSteven Rostedt my $ret = $?; 1260a57419b3SSteven Rostedt 1261a57419b3SSteven Rostedt logit $sha1; 1262a57419b3SSteven Rostedt 1263a57419b3SSteven Rostedt if ($ret) { 1264a57419b3SSteven Rostedt doprint "FAILED\n"; 1265a57419b3SSteven Rostedt dodie "Failed to get git $commit"; 1266a57419b3SSteven Rostedt } 1267a57419b3SSteven Rostedt 1268a57419b3SSteven Rostedt print "SUCCESS\n"; 1269a57419b3SSteven Rostedt 1270a57419b3SSteven Rostedt chomp $sha1; 1271a57419b3SSteven Rostedt 1272a57419b3SSteven Rostedt return $sha1; 1273a57419b3SSteven Rostedt} 1274a57419b3SSteven Rostedt 12755a391fbfSSteven Rostedtsub monitor { 12762545eb61SSteven Rostedt my $booted = 0; 12772545eb61SSteven Rostedt my $bug = 0; 12785c42fc5bSSteven Rostedt my $skip_call_trace = 0; 12792b7d9b21SSteven Rostedt my $loops; 12802545eb61SSteven Rostedt 12817faafbd6SSteven Rostedt wait_for_monitor 5; 12822545eb61SSteven Rostedt 12832545eb61SSteven Rostedt my $line; 12842545eb61SSteven Rostedt my $full_line = ""; 12852545eb61SSteven Rostedt 12867faafbd6SSteven Rostedt open(DMESG, "> $dmesg") or 12877faafbd6SSteven Rostedt die "unable to write to $dmesg"; 12882545eb61SSteven Rostedt 128975c3fda7SSteven Rostedt reboot_to; 12902545eb61SSteven Rostedt 12911c8a617aSSteven Rostedt my $success_start; 12921c8a617aSSteven Rostedt my $failure_start; 12932d01b26aSSteven Rostedt my $monitor_start = time; 12942d01b26aSSteven Rostedt my $done = 0; 1295f1a5b962SSteven Rostedt my $version_found = 0; 12961c8a617aSSteven Rostedt 12972d01b26aSSteven Rostedt while (!$done) { 12982545eb61SSteven Rostedt 1299ecaf8e52SSteven Rostedt if ($bug && defined($stop_after_failure) && 1300ecaf8e52SSteven Rostedt $stop_after_failure >= 0) { 1301ecaf8e52SSteven Rostedt my $time = $stop_after_failure - (time - $failure_start); 1302ecaf8e52SSteven Rostedt $line = wait_for_input($monitor_fp, $time); 1303ecaf8e52SSteven Rostedt if (!defined($line)) { 1304ecaf8e52SSteven Rostedt doprint "bug timed out after $booted_timeout seconds\n"; 1305ecaf8e52SSteven Rostedt doprint "Test forced to stop after $stop_after_failure seconds after failure\n"; 1306ecaf8e52SSteven Rostedt last; 1307ecaf8e52SSteven Rostedt } 1308ecaf8e52SSteven Rostedt } elsif ($booted) { 1309a75fececSSteven Rostedt $line = wait_for_input($monitor_fp, $booted_timeout); 1310cd4f1d53SSteven Rostedt if (!defined($line)) { 1311cd4f1d53SSteven Rostedt my $s = $booted_timeout == 1 ? "" : "s"; 1312cd4f1d53SSteven Rostedt doprint "Successful boot found: break after $booted_timeout second$s\n"; 1313cd4f1d53SSteven Rostedt last; 1314cd4f1d53SSteven Rostedt } 13152b7d9b21SSteven Rostedt } else { 13167faafbd6SSteven Rostedt $line = wait_for_input($monitor_fp); 1317cd4f1d53SSteven Rostedt if (!defined($line)) { 1318cd4f1d53SSteven Rostedt my $s = $timeout == 1 ? "" : "s"; 1319cd4f1d53SSteven Rostedt doprint "Timed out after $timeout second$s\n"; 1320cd4f1d53SSteven Rostedt last; 13212b7d9b21SSteven Rostedt } 1322cd4f1d53SSteven Rostedt } 13232545eb61SSteven Rostedt 13242545eb61SSteven Rostedt doprint $line; 13257faafbd6SSteven Rostedt print DMESG $line; 13262545eb61SSteven Rostedt 13272545eb61SSteven Rostedt # we are not guaranteed to get a full line 13282545eb61SSteven Rostedt $full_line .= $line; 13292545eb61SSteven Rostedt 1330a75fececSSteven Rostedt if ($full_line =~ /$success_line/) { 13312545eb61SSteven Rostedt $booted = 1; 13321c8a617aSSteven Rostedt $success_start = time; 13331c8a617aSSteven Rostedt } 13341c8a617aSSteven Rostedt 13351c8a617aSSteven Rostedt if ($booted && defined($stop_after_success) && 13361c8a617aSSteven Rostedt $stop_after_success >= 0) { 13371c8a617aSSteven Rostedt my $now = time; 13381c8a617aSSteven Rostedt if ($now - $success_start >= $stop_after_success) { 13391c8a617aSSteven Rostedt doprint "Test forced to stop after $stop_after_success seconds after success\n"; 13401c8a617aSSteven Rostedt last; 13411c8a617aSSteven Rostedt } 13422545eb61SSteven Rostedt } 13432545eb61SSteven Rostedt 13445c42fc5bSSteven Rostedt if ($full_line =~ /\[ backtrace testing \]/) { 13455c42fc5bSSteven Rostedt $skip_call_trace = 1; 13465c42fc5bSSteven Rostedt } 13475c42fc5bSSteven Rostedt 13482545eb61SSteven Rostedt if ($full_line =~ /call trace:/i) { 13494651920eSSteven Rostedt if (!$bug && !$skip_call_trace) { 13501c8a617aSSteven Rostedt $bug = 1; 13511c8a617aSSteven Rostedt $failure_start = time; 13521c8a617aSSteven Rostedt } 13531c8a617aSSteven Rostedt } 13541c8a617aSSteven Rostedt 13551c8a617aSSteven Rostedt if ($bug && defined($stop_after_failure) && 13561c8a617aSSteven Rostedt $stop_after_failure >= 0) { 13571c8a617aSSteven Rostedt my $now = time; 13581c8a617aSSteven Rostedt if ($now - $failure_start >= $stop_after_failure) { 13591c8a617aSSteven Rostedt doprint "Test forced to stop after $stop_after_failure seconds after failure\n"; 13601c8a617aSSteven Rostedt last; 13611c8a617aSSteven Rostedt } 13625c42fc5bSSteven Rostedt } 13635c42fc5bSSteven Rostedt 13645c42fc5bSSteven Rostedt if ($full_line =~ /\[ end of backtrace testing \]/) { 13655c42fc5bSSteven Rostedt $skip_call_trace = 0; 13665c42fc5bSSteven Rostedt } 13675c42fc5bSSteven Rostedt 13685c42fc5bSSteven Rostedt if ($full_line =~ /Kernel panic -/) { 136910abf118SSteven Rostedt $failure_start = time; 13702545eb61SSteven Rostedt $bug = 1; 13712545eb61SSteven Rostedt } 13722545eb61SSteven Rostedt 1373f1a5b962SSteven Rostedt # Detect triple faults by testing the banner 1374f1a5b962SSteven Rostedt if ($full_line =~ /\bLinux version (\S+).*\n/) { 1375f1a5b962SSteven Rostedt if ($1 eq $version) { 1376f1a5b962SSteven Rostedt $version_found = 1; 1377f1a5b962SSteven Rostedt } elsif ($version_found && $detect_triplefault) { 1378f1a5b962SSteven Rostedt # We already booted into the kernel we are testing, 1379f1a5b962SSteven Rostedt # but now we booted into another kernel? 1380f1a5b962SSteven Rostedt # Consider this a triple fault. 1381f1a5b962SSteven Rostedt doprint "Aleady booted in Linux kernel $version, but now\n"; 1382f1a5b962SSteven Rostedt doprint "we booted into Linux kernel $1.\n"; 1383f1a5b962SSteven Rostedt doprint "Assuming that this is a triple fault.\n"; 1384f1a5b962SSteven Rostedt doprint "To disable this: set DETECT_TRIPLE_FAULT to 0\n"; 1385f1a5b962SSteven Rostedt last; 1386f1a5b962SSteven Rostedt } 1387f1a5b962SSteven Rostedt } 1388f1a5b962SSteven Rostedt 13892545eb61SSteven Rostedt if ($line =~ /\n/) { 13902545eb61SSteven Rostedt $full_line = ""; 13912545eb61SSteven Rostedt } 13922d01b26aSSteven Rostedt 13932d01b26aSSteven Rostedt if ($stop_test_after > 0 && !$booted && !$bug) { 13942d01b26aSSteven Rostedt if (time - $monitor_start > $stop_test_after) { 13954d62bf51SSteven Rostedt doprint "STOP_TEST_AFTER ($stop_test_after seconds) timed out\n"; 13962d01b26aSSteven Rostedt $done = 1; 13972d01b26aSSteven Rostedt } 13982d01b26aSSteven Rostedt } 13992545eb61SSteven Rostedt } 14002545eb61SSteven Rostedt 14017faafbd6SSteven Rostedt close(DMESG); 14022545eb61SSteven Rostedt 14032545eb61SSteven Rostedt if ($bug) { 14042b7d9b21SSteven Rostedt return 0 if ($in_bisect); 1405576f627cSSteven Rostedt fail "failed - got a bug report" and return 0; 14062545eb61SSteven Rostedt } 14075f9b6cedSSteven Rostedt 1408a75fececSSteven Rostedt if (!$booted) { 1409a75fececSSteven Rostedt return 0 if ($in_bisect); 1410576f627cSSteven Rostedt fail "failed - never got a boot prompt." and return 0; 1411a75fececSSteven Rostedt } 1412a75fececSSteven Rostedt 14132b7d9b21SSteven Rostedt return 1; 14142545eb61SSteven Rostedt} 14152545eb61SSteven Rostedt 1416db05cfefSSteven Rostedtsub do_post_install { 1417db05cfefSSteven Rostedt 1418db05cfefSSteven Rostedt return if (!defined($post_install)); 1419db05cfefSSteven Rostedt 1420db05cfefSSteven Rostedt my $cp_post_install = $post_install; 1421db05cfefSSteven Rostedt $cp_post_install =~ s/\$KERNEL_VERSION/$version/g; 1422db05cfefSSteven Rostedt run_command "$cp_post_install" or 1423db05cfefSSteven Rostedt dodie "Failed to run post install"; 1424db05cfefSSteven Rostedt} 1425db05cfefSSteven Rostedt 14262545eb61SSteven Rostedtsub install { 14272545eb61SSteven Rostedt 1428e0a8742eSSteven Rostedt return if ($no_install); 1429e0a8742eSSteven Rostedt 1430e48c5293SSteven Rostedt run_scp "$outputdir/$build_target", "$target_image" or 14315c42fc5bSSteven Rostedt dodie "failed to copy image"; 14325f9b6cedSSteven Rostedt 14335f9b6cedSSteven Rostedt my $install_mods = 0; 14345f9b6cedSSteven Rostedt 14355f9b6cedSSteven Rostedt # should we process modules? 14365f9b6cedSSteven Rostedt $install_mods = 0; 143751ad1dd1SSteven Rostedt open(IN, "$output_config") or dodie("Can't read config file"); 14385f9b6cedSSteven Rostedt while (<IN>) { 14395f9b6cedSSteven Rostedt if (/CONFIG_MODULES(=y)?/) { 14405f9b6cedSSteven Rostedt $install_mods = 1 if (defined($1)); 14415f9b6cedSSteven Rostedt last; 14425f9b6cedSSteven Rostedt } 14435f9b6cedSSteven Rostedt } 14445f9b6cedSSteven Rostedt close(IN); 14455f9b6cedSSteven Rostedt 14465f9b6cedSSteven Rostedt if (!$install_mods) { 1447db05cfefSSteven Rostedt do_post_install; 14485f9b6cedSSteven Rostedt doprint "No modules needed\n"; 14495f9b6cedSSteven Rostedt return; 14502545eb61SSteven Rostedt } 14512545eb61SSteven Rostedt 1452a75fececSSteven Rostedt run_command "$make INSTALL_MOD_PATH=$tmpdir modules_install" or 14535f9b6cedSSteven Rostedt dodie "Failed to install modules"; 14545f9b6cedSSteven Rostedt 14552545eb61SSteven Rostedt my $modlib = "/lib/modules/$version"; 1456a57419b3SSteven Rostedt my $modtar = "ktest-mods.tar.bz2"; 14572545eb61SSteven Rostedt 1458e48c5293SSteven Rostedt run_ssh "rm -rf $modlib" or 14595c42fc5bSSteven Rostedt dodie "failed to remove old mods: $modlib"; 14602545eb61SSteven Rostedt 14615c42fc5bSSteven Rostedt # would be nice if scp -r did not follow symbolic links 1462a75fececSSteven Rostedt run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or 14635c42fc5bSSteven Rostedt dodie "making tarball"; 14645c42fc5bSSteven Rostedt 1465e48c5293SSteven Rostedt run_scp "$tmpdir/$modtar", "/tmp" or 14665c42fc5bSSteven Rostedt dodie "failed to copy modules"; 14675c42fc5bSSteven Rostedt 1468a75fececSSteven Rostedt unlink "$tmpdir/$modtar"; 14695c42fc5bSSteven Rostedt 1470e7b13441SSteven Rostedt run_ssh "'(cd / && tar xjf /tmp/$modtar)'" or 14715c42fc5bSSteven Rostedt dodie "failed to tar modules"; 14725c42fc5bSSteven Rostedt 1473e48c5293SSteven Rostedt run_ssh "rm -f /tmp/$modtar"; 14748b37ca8cSSteven Rostedt 1475db05cfefSSteven Rostedt do_post_install; 14762545eb61SSteven Rostedt} 14772545eb61SSteven Rostedt 1478ddf607e5SSteven Rostedtsub get_version { 1479ddf607e5SSteven Rostedt # get the release name 1480ddf607e5SSteven Rostedt doprint "$make kernelrelease ... "; 1481ddf607e5SSteven Rostedt $version = `$make kernelrelease | tail -1`; 1482ddf607e5SSteven Rostedt chomp($version); 1483ddf607e5SSteven Rostedt doprint "$version\n"; 1484ddf607e5SSteven Rostedt} 1485ddf607e5SSteven Rostedt 1486ddf607e5SSteven Rostedtsub start_monitor_and_boot { 14879f7424ccSSteven Rostedt # Make sure the stable kernel has finished booting 14889f7424ccSSteven Rostedt start_monitor; 14899f7424ccSSteven Rostedt wait_for_monitor 5; 14909f7424ccSSteven Rostedt end_monitor; 14919f7424ccSSteven Rostedt 1492ddf607e5SSteven Rostedt get_grub_index; 1493ddf607e5SSteven Rostedt get_version; 1494ddf607e5SSteven Rostedt install; 1495ddf607e5SSteven Rostedt 1496ddf607e5SSteven Rostedt start_monitor; 1497ddf607e5SSteven Rostedt return monitor; 1498ddf607e5SSteven Rostedt} 1499ddf607e5SSteven Rostedt 15006c5ee0beSSteven Rostedtsub check_buildlog { 15016c5ee0beSSteven Rostedt my ($patch) = @_; 15026c5ee0beSSteven Rostedt 15036c5ee0beSSteven Rostedt my @files = `git show $patch | diffstat -l`; 15046c5ee0beSSteven Rostedt 15056c5ee0beSSteven Rostedt open(IN, "git show $patch |") or 15066c5ee0beSSteven Rostedt dodie "failed to show $patch"; 15076c5ee0beSSteven Rostedt while (<IN>) { 15086c5ee0beSSteven Rostedt if (m,^--- a/(.*),) { 15096c5ee0beSSteven Rostedt chomp $1; 15106c5ee0beSSteven Rostedt $files[$#files] = $1; 15116c5ee0beSSteven Rostedt } 15126c5ee0beSSteven Rostedt } 15136c5ee0beSSteven Rostedt close(IN); 15146c5ee0beSSteven Rostedt 15156c5ee0beSSteven Rostedt open(IN, $buildlog) or dodie "Can't open $buildlog"; 15166c5ee0beSSteven Rostedt while (<IN>) { 15176c5ee0beSSteven Rostedt if (/^\s*(.*?):.*(warning|error)/) { 15186c5ee0beSSteven Rostedt my $err = $1; 15196c5ee0beSSteven Rostedt foreach my $file (@files) { 1520a75fececSSteven Rostedt my $fullpath = "$builddir/$file"; 15216c5ee0beSSteven Rostedt if ($file eq $err || $fullpath eq $err) { 15222b7d9b21SSteven Rostedt fail "$file built with warnings" and return 0; 15236c5ee0beSSteven Rostedt } 15246c5ee0beSSteven Rostedt } 15256c5ee0beSSteven Rostedt } 15266c5ee0beSSteven Rostedt } 15276c5ee0beSSteven Rostedt close(IN); 15282b7d9b21SSteven Rostedt 15292b7d9b21SSteven Rostedt return 1; 15306c5ee0beSSteven Rostedt} 15316c5ee0beSSteven Rostedt 1532fcb3f16aSSteven Rostedtsub apply_min_config { 1533fcb3f16aSSteven Rostedt my $outconfig = "$output_config.new"; 1534612b9e9bSSteven Rostedt 1535fcb3f16aSSteven Rostedt # Read the config file and remove anything that 1536fcb3f16aSSteven Rostedt # is in the force_config hash (from minconfig and others) 1537fcb3f16aSSteven Rostedt # then add the force config back. 1538fcb3f16aSSteven Rostedt 1539fcb3f16aSSteven Rostedt doprint "Applying minimum configurations into $output_config.new\n"; 1540fcb3f16aSSteven Rostedt 1541fcb3f16aSSteven Rostedt open (OUT, ">$outconfig") or 1542fcb3f16aSSteven Rostedt dodie "Can't create $outconfig"; 1543fcb3f16aSSteven Rostedt 1544fcb3f16aSSteven Rostedt if (-f $output_config) { 1545fcb3f16aSSteven Rostedt open (IN, $output_config) or 1546fcb3f16aSSteven Rostedt dodie "Failed to open $output_config"; 1547fcb3f16aSSteven Rostedt while (<IN>) { 1548fcb3f16aSSteven Rostedt if (/^(# )?(CONFIG_[^\s=]*)/) { 1549fcb3f16aSSteven Rostedt next if (defined($force_config{$2})); 1550fcb3f16aSSteven Rostedt } 1551fcb3f16aSSteven Rostedt print OUT; 1552fcb3f16aSSteven Rostedt } 1553fcb3f16aSSteven Rostedt close IN; 1554fcb3f16aSSteven Rostedt } 1555fcb3f16aSSteven Rostedt foreach my $config (keys %force_config) { 1556fcb3f16aSSteven Rostedt print OUT "$force_config{$config}\n"; 1557fcb3f16aSSteven Rostedt } 1558fcb3f16aSSteven Rostedt close OUT; 1559fcb3f16aSSteven Rostedt 1560fcb3f16aSSteven Rostedt run_command "mv $outconfig $output_config"; 1561fcb3f16aSSteven Rostedt} 1562fcb3f16aSSteven Rostedt 1563fcb3f16aSSteven Rostedtsub make_oldconfig { 1564fcb3f16aSSteven Rostedt 15654c4ab120SSteven Rostedt my @force_list = keys %force_config; 15664c4ab120SSteven Rostedt 15674c4ab120SSteven Rostedt if ($#force_list >= 0) { 1568fcb3f16aSSteven Rostedt apply_min_config; 15694c4ab120SSteven Rostedt } 1570fcb3f16aSSteven Rostedt 1571fcb3f16aSSteven Rostedt if (!run_command "$make oldnoconfig") { 1572612b9e9bSSteven Rostedt # Perhaps oldnoconfig doesn't exist in this version of the kernel 1573612b9e9bSSteven Rostedt # try a yes '' | oldconfig 1574612b9e9bSSteven Rostedt doprint "oldnoconfig failed, trying yes '' | make oldconfig\n"; 1575fcb3f16aSSteven Rostedt run_command "yes '' | $make oldconfig" or 1576612b9e9bSSteven Rostedt dodie "failed make config oldconfig"; 1577612b9e9bSSteven Rostedt } 1578612b9e9bSSteven Rostedt} 1579612b9e9bSSteven Rostedt 1580fcb3f16aSSteven Rostedt# read a config file and use this to force new configs. 1581fcb3f16aSSteven Rostedtsub load_force_config { 1582fcb3f16aSSteven Rostedt my ($config) = @_; 1583fcb3f16aSSteven Rostedt 1584fcb3f16aSSteven Rostedt open(IN, $config) or 1585fcb3f16aSSteven Rostedt dodie "failed to read $config"; 1586fcb3f16aSSteven Rostedt while (<IN>) { 1587fcb3f16aSSteven Rostedt chomp; 1588fcb3f16aSSteven Rostedt if (/^(CONFIG[^\s=]*)(\s*=.*)/) { 1589fcb3f16aSSteven Rostedt $force_config{$1} = $_; 1590fcb3f16aSSteven Rostedt } elsif (/^# (CONFIG_\S*) is not set/) { 1591fcb3f16aSSteven Rostedt $force_config{$1} = $_; 1592fcb3f16aSSteven Rostedt } 1593fcb3f16aSSteven Rostedt } 1594fcb3f16aSSteven Rostedt close IN; 1595fcb3f16aSSteven Rostedt} 1596fcb3f16aSSteven Rostedt 15972545eb61SSteven Rostedtsub build { 15982545eb61SSteven Rostedt my ($type) = @_; 15992545eb61SSteven Rostedt 16007faafbd6SSteven Rostedt unlink $buildlog; 16017faafbd6SSteven Rostedt 16024ab1cce5SSteven Rostedt # Failed builds should not reboot the target 16034ab1cce5SSteven Rostedt my $save_no_reboot = $no_reboot; 16044ab1cce5SSteven Rostedt $no_reboot = 1; 16054ab1cce5SSteven Rostedt 16060bd6c1a3SSteven Rostedt if (defined($pre_build)) { 16070bd6c1a3SSteven Rostedt my $ret = run_command $pre_build; 16080bd6c1a3SSteven Rostedt if (!$ret && defined($pre_build_die) && 16090bd6c1a3SSteven Rostedt $pre_build_die) { 16100bd6c1a3SSteven Rostedt dodie "failed to pre_build\n"; 16110bd6c1a3SSteven Rostedt } 16120bd6c1a3SSteven Rostedt } 16130bd6c1a3SSteven Rostedt 161475c3fda7SSteven Rostedt if ($type =~ /^useconfig:(.*)/) { 161551ad1dd1SSteven Rostedt run_command "cp $1 $output_config" or 161675c3fda7SSteven Rostedt dodie "could not copy $1 to .config"; 16175f9b6cedSSteven Rostedt 161875c3fda7SSteven Rostedt $type = "oldconfig"; 161975c3fda7SSteven Rostedt } 162075c3fda7SSteven Rostedt 16215c42fc5bSSteven Rostedt # old config can ask questions 16225c42fc5bSSteven Rostedt if ($type eq "oldconfig") { 16239386c6abSSteven Rostedt $type = "oldnoconfig"; 162475c3fda7SSteven Rostedt 162575c3fda7SSteven Rostedt # allow for empty configs 162651ad1dd1SSteven Rostedt run_command "touch $output_config"; 162775c3fda7SSteven Rostedt 162813488231SAndrew Jones if (!$noclean) { 162951ad1dd1SSteven Rostedt run_command "mv $output_config $outputdir/config_temp" or 16305c42fc5bSSteven Rostedt dodie "moving .config"; 16315c42fc5bSSteven Rostedt 163213488231SAndrew Jones run_command "$make mrproper" or dodie "make mrproper"; 16335c42fc5bSSteven Rostedt 163451ad1dd1SSteven Rostedt run_command "mv $outputdir/config_temp $output_config" or 16355c42fc5bSSteven Rostedt dodie "moving config_temp"; 163613488231SAndrew Jones } 16375c42fc5bSSteven Rostedt 16385c42fc5bSSteven Rostedt } elsif (!$noclean) { 163951ad1dd1SSteven Rostedt unlink "$output_config"; 16405f9b6cedSSteven Rostedt run_command "$make mrproper" or 16415c42fc5bSSteven Rostedt dodie "make mrproper"; 16425c42fc5bSSteven Rostedt } 16432545eb61SSteven Rostedt 16442545eb61SSteven Rostedt # add something to distinguish this build 1645a75fececSSteven Rostedt open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file"); 1646a75fececSSteven Rostedt print OUT "$localversion\n"; 16472545eb61SSteven Rostedt close(OUT); 16482545eb61SSteven Rostedt 16495f9b6cedSSteven Rostedt if (defined($minconfig)) { 1650fcb3f16aSSteven Rostedt load_force_config($minconfig); 16512545eb61SSteven Rostedt } 16522545eb61SSteven Rostedt 1653fcb3f16aSSteven Rostedt if ($type ne "oldnoconfig") { 1654fcb3f16aSSteven Rostedt run_command "$make $type" or 16555c42fc5bSSteven Rostedt dodie "failed make config"; 1656612b9e9bSSteven Rostedt } 1657fcb3f16aSSteven Rostedt # Run old config regardless, to enforce min configurations 1658fcb3f16aSSteven Rostedt make_oldconfig; 16592545eb61SSteven Rostedt 1660a75fececSSteven Rostedt $redirect = "$buildlog"; 16610bd6c1a3SSteven Rostedt my $build_ret = run_command "$make $build_options"; 16626c5ee0beSSteven Rostedt undef $redirect; 16630bd6c1a3SSteven Rostedt 16640bd6c1a3SSteven Rostedt if (defined($post_build)) { 16650bd6c1a3SSteven Rostedt my $ret = run_command $post_build; 16660bd6c1a3SSteven Rostedt if (!$ret && defined($post_build_die) && 16670bd6c1a3SSteven Rostedt $post_build_die) { 16680bd6c1a3SSteven Rostedt dodie "failed to post_build\n"; 16690bd6c1a3SSteven Rostedt } 16700bd6c1a3SSteven Rostedt } 16710bd6c1a3SSteven Rostedt 16720bd6c1a3SSteven Rostedt if (!$build_ret) { 16735f9b6cedSSteven Rostedt # bisect may need this to pass 16744ab1cce5SSteven Rostedt if ($in_bisect) { 16754ab1cce5SSteven Rostedt $no_reboot = $save_no_reboot; 16764ab1cce5SSteven Rostedt return 0; 16774ab1cce5SSteven Rostedt } 16782b7d9b21SSteven Rostedt fail "failed build" and return 0; 16792545eb61SSteven Rostedt } 16805f9b6cedSSteven Rostedt 16814ab1cce5SSteven Rostedt $no_reboot = $save_no_reboot; 16824ab1cce5SSteven Rostedt 16832b7d9b21SSteven Rostedt return 1; 16842545eb61SSteven Rostedt} 16852545eb61SSteven Rostedt 168675c3fda7SSteven Rostedtsub halt { 1687e48c5293SSteven Rostedt if (!run_ssh "halt" or defined($power_off)) { 1688576f627cSSteven Rostedt if (defined($poweroff_after_halt)) { 1689576f627cSSteven Rostedt sleep $poweroff_after_halt; 1690576f627cSSteven Rostedt run_command "$power_off"; 1691576f627cSSteven Rostedt } 1692576f627cSSteven Rostedt } else { 169375c3fda7SSteven Rostedt # nope? the zap it! 1694a75fececSSteven Rostedt run_command "$power_off"; 169575c3fda7SSteven Rostedt } 169675c3fda7SSteven Rostedt} 169775c3fda7SSteven Rostedt 16985f9b6cedSSteven Rostedtsub success { 16995f9b6cedSSteven Rostedt my ($i) = @_; 17005f9b6cedSSteven Rostedt 1701e48c5293SSteven Rostedt $successes++; 1702e48c5293SSteven Rostedt 17039064af52SSteven Rostedt my $name = ""; 17049064af52SSteven Rostedt 17059064af52SSteven Rostedt if (defined($test_name)) { 17069064af52SSteven Rostedt $name = " ($test_name)"; 17079064af52SSteven Rostedt } 17089064af52SSteven Rostedt 17095f9b6cedSSteven Rostedt doprint "\n\n*******************************************\n"; 17105f9b6cedSSteven Rostedt doprint "*******************************************\n"; 17119064af52SSteven Rostedt doprint "KTEST RESULT: TEST $i$name SUCCESS!!!! **\n"; 17125f9b6cedSSteven Rostedt doprint "*******************************************\n"; 17135f9b6cedSSteven Rostedt doprint "*******************************************\n"; 17145f9b6cedSSteven Rostedt 1715de5b6e3bSRabin Vincent if (defined($store_successes)) { 1716de5b6e3bSRabin Vincent save_logs "success", $store_successes; 1717de5b6e3bSRabin Vincent } 1718de5b6e3bSRabin Vincent 1719576f627cSSteven Rostedt if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) { 1720a75fececSSteven Rostedt doprint "Reboot and wait $sleep_time seconds\n"; 17212728be41SAndrew Jones reboot $sleep_time; 17225f9b6cedSSteven Rostedt } 17235f9b6cedSSteven Rostedt} 17245f9b6cedSSteven Rostedt 1725c960bb9fSSteven Rostedtsub answer_bisect { 1726c960bb9fSSteven Rostedt for (;;) { 1727c960bb9fSSteven Rostedt doprint "Pass or fail? [p/f]"; 1728c960bb9fSSteven Rostedt my $ans = <STDIN>; 1729c960bb9fSSteven Rostedt chomp $ans; 1730c960bb9fSSteven Rostedt if ($ans eq "p" || $ans eq "P") { 1731c960bb9fSSteven Rostedt return 1; 1732c960bb9fSSteven Rostedt } elsif ($ans eq "f" || $ans eq "F") { 1733c960bb9fSSteven Rostedt return 0; 1734c960bb9fSSteven Rostedt } else { 1735c960bb9fSSteven Rostedt print "Please answer 'P' or 'F'\n"; 1736c960bb9fSSteven Rostedt } 1737c960bb9fSSteven Rostedt } 1738c960bb9fSSteven Rostedt} 1739c960bb9fSSteven Rostedt 17405a391fbfSSteven Rostedtsub child_run_test { 17417faafbd6SSteven Rostedt my $failed = 0; 17425a391fbfSSteven Rostedt 17437faafbd6SSteven Rostedt # child should have no power 1744a75fececSSteven Rostedt $reboot_on_error = 0; 1745a75fececSSteven Rostedt $poweroff_on_error = 0; 1746a75fececSSteven Rostedt $die_on_failure = 1; 17477faafbd6SSteven Rostedt 1748a9dd5d63SRabin Vincent $redirect = "$testlog"; 17497faafbd6SSteven Rostedt run_command $run_test or $failed = 1; 1750a9dd5d63SRabin Vincent undef $redirect; 1751a9dd5d63SRabin Vincent 17525a391fbfSSteven Rostedt exit $failed; 17535a391fbfSSteven Rostedt} 17545a391fbfSSteven Rostedt 17555a391fbfSSteven Rostedtmy $child_done; 17565a391fbfSSteven Rostedt 17575a391fbfSSteven Rostedtsub child_finished { 17585a391fbfSSteven Rostedt $child_done = 1; 17595a391fbfSSteven Rostedt} 17605a391fbfSSteven Rostedt 17615a391fbfSSteven Rostedtsub do_run_test { 17625a391fbfSSteven Rostedt my $child_pid; 17635a391fbfSSteven Rostedt my $child_exit; 17645a391fbfSSteven Rostedt my $line; 17655a391fbfSSteven Rostedt my $full_line; 17665a391fbfSSteven Rostedt my $bug = 0; 17675a391fbfSSteven Rostedt 17687faafbd6SSteven Rostedt wait_for_monitor 1; 17695a391fbfSSteven Rostedt 17707faafbd6SSteven Rostedt doprint "run test $run_test\n"; 17715a391fbfSSteven Rostedt 17725a391fbfSSteven Rostedt $child_done = 0; 17735a391fbfSSteven Rostedt 17745a391fbfSSteven Rostedt $SIG{CHLD} = qw(child_finished); 17755a391fbfSSteven Rostedt 17765a391fbfSSteven Rostedt $child_pid = fork; 17775a391fbfSSteven Rostedt 17785a391fbfSSteven Rostedt child_run_test if (!$child_pid); 17795a391fbfSSteven Rostedt 17805a391fbfSSteven Rostedt $full_line = ""; 17815a391fbfSSteven Rostedt 17825a391fbfSSteven Rostedt do { 17837faafbd6SSteven Rostedt $line = wait_for_input($monitor_fp, 1); 17845a391fbfSSteven Rostedt if (defined($line)) { 17855a391fbfSSteven Rostedt 17865a391fbfSSteven Rostedt # we are not guaranteed to get a full line 17875a391fbfSSteven Rostedt $full_line .= $line; 17888ea0e063SSteven Rostedt doprint $line; 17895a391fbfSSteven Rostedt 17905a391fbfSSteven Rostedt if ($full_line =~ /call trace:/i) { 17915a391fbfSSteven Rostedt $bug = 1; 17925a391fbfSSteven Rostedt } 17935a391fbfSSteven Rostedt 17945a391fbfSSteven Rostedt if ($full_line =~ /Kernel panic -/) { 17955a391fbfSSteven Rostedt $bug = 1; 17965a391fbfSSteven Rostedt } 17975a391fbfSSteven Rostedt 17985a391fbfSSteven Rostedt if ($line =~ /\n/) { 17995a391fbfSSteven Rostedt $full_line = ""; 18005a391fbfSSteven Rostedt } 18015a391fbfSSteven Rostedt } 18025a391fbfSSteven Rostedt } while (!$child_done && !$bug); 18035a391fbfSSteven Rostedt 18045a391fbfSSteven Rostedt if ($bug) { 18058ea0e063SSteven Rostedt my $failure_start = time; 18068ea0e063SSteven Rostedt my $now; 18078ea0e063SSteven Rostedt do { 18088ea0e063SSteven Rostedt $line = wait_for_input($monitor_fp, 1); 18098ea0e063SSteven Rostedt if (defined($line)) { 18108ea0e063SSteven Rostedt doprint $line; 18118ea0e063SSteven Rostedt } 18128ea0e063SSteven Rostedt $now = time; 18138ea0e063SSteven Rostedt if ($now - $failure_start >= $stop_after_failure) { 18148ea0e063SSteven Rostedt last; 18158ea0e063SSteven Rostedt } 18168ea0e063SSteven Rostedt } while (defined($line)); 18178ea0e063SSteven Rostedt 18185a391fbfSSteven Rostedt doprint "Detected kernel crash!\n"; 18195a391fbfSSteven Rostedt # kill the child with extreme prejudice 18205a391fbfSSteven Rostedt kill 9, $child_pid; 18215a391fbfSSteven Rostedt } 18225a391fbfSSteven Rostedt 18235a391fbfSSteven Rostedt waitpid $child_pid, 0; 18245a391fbfSSteven Rostedt $child_exit = $?; 18255a391fbfSSteven Rostedt 18265a391fbfSSteven Rostedt if ($bug || $child_exit) { 18272b7d9b21SSteven Rostedt return 0 if $in_bisect; 18282b7d9b21SSteven Rostedt fail "test failed" and return 0; 18295a391fbfSSteven Rostedt } 18302b7d9b21SSteven Rostedt return 1; 18315a391fbfSSteven Rostedt} 18325a391fbfSSteven Rostedt 1833a75fececSSteven Rostedtsub run_git_bisect { 1834a75fececSSteven Rostedt my ($command) = @_; 1835a75fececSSteven Rostedt 1836a75fececSSteven Rostedt doprint "$command ... "; 1837a75fececSSteven Rostedt 1838a75fececSSteven Rostedt my $output = `$command 2>&1`; 1839a75fececSSteven Rostedt my $ret = $?; 1840a75fececSSteven Rostedt 1841a75fececSSteven Rostedt logit $output; 1842a75fececSSteven Rostedt 1843a75fececSSteven Rostedt if ($ret) { 1844a75fececSSteven Rostedt doprint "FAILED\n"; 1845a75fececSSteven Rostedt dodie "Failed to git bisect"; 1846a75fececSSteven Rostedt } 1847a75fececSSteven Rostedt 1848a75fececSSteven Rostedt doprint "SUCCESS\n"; 1849a75fececSSteven Rostedt if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) { 1850a75fececSSteven Rostedt doprint "$1 [$2]\n"; 1851a75fececSSteven Rostedt } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) { 1852a75fececSSteven Rostedt $bisect_bad = $1; 1853a75fececSSteven Rostedt doprint "Found bad commit... $1\n"; 1854a75fececSSteven Rostedt return 0; 1855a75fececSSteven Rostedt } else { 1856a75fececSSteven Rostedt # we already logged it, just print it now. 1857a75fececSSteven Rostedt print $output; 1858a75fececSSteven Rostedt } 1859a75fececSSteven Rostedt 1860a75fececSSteven Rostedt return 1; 1861a75fececSSteven Rostedt} 1862a75fececSSteven Rostedt 1863c23dca7cSSteven Rostedtsub bisect_reboot { 1864c23dca7cSSteven Rostedt doprint "Reboot and sleep $bisect_sleep_time seconds\n"; 18652728be41SAndrew Jones reboot $bisect_sleep_time; 1866c23dca7cSSteven Rostedt} 1867c23dca7cSSteven Rostedt 1868c23dca7cSSteven Rostedt# returns 1 on success, 0 on failure, -1 on skip 18690a05c769SSteven Rostedtsub run_bisect_test { 18700a05c769SSteven Rostedt my ($type, $buildtype) = @_; 18715f9b6cedSSteven Rostedt 18722b7d9b21SSteven Rostedt my $failed = 0; 18735f9b6cedSSteven Rostedt my $result; 18745f9b6cedSSteven Rostedt my $output; 18755f9b6cedSSteven Rostedt my $ret; 18765f9b6cedSSteven Rostedt 18770a05c769SSteven Rostedt $in_bisect = 1; 18780a05c769SSteven Rostedt 18790a05c769SSteven Rostedt build $buildtype or $failed = 1; 18805f9b6cedSSteven Rostedt 18815f9b6cedSSteven Rostedt if ($type ne "build") { 1882c23dca7cSSteven Rostedt if ($failed && $bisect_skip) { 1883c23dca7cSSteven Rostedt $in_bisect = 0; 1884c23dca7cSSteven Rostedt return -1; 1885c23dca7cSSteven Rostedt } 18867faafbd6SSteven Rostedt dodie "Failed on build" if $failed; 18875f9b6cedSSteven Rostedt 18885f9b6cedSSteven Rostedt # Now boot the box 1889ddf607e5SSteven Rostedt start_monitor_and_boot or $failed = 1; 18905f9b6cedSSteven Rostedt 18915f9b6cedSSteven Rostedt if ($type ne "boot") { 1892c23dca7cSSteven Rostedt if ($failed && $bisect_skip) { 1893c23dca7cSSteven Rostedt end_monitor; 1894c23dca7cSSteven Rostedt bisect_reboot; 1895c23dca7cSSteven Rostedt $in_bisect = 0; 1896c23dca7cSSteven Rostedt return -1; 1897c23dca7cSSteven Rostedt } 18987faafbd6SSteven Rostedt dodie "Failed on boot" if $failed; 18995a391fbfSSteven Rostedt 19002b7d9b21SSteven Rostedt do_run_test or $failed = 1; 19015f9b6cedSSteven Rostedt } 19027faafbd6SSteven Rostedt end_monitor; 19035f9b6cedSSteven Rostedt } 19045f9b6cedSSteven Rostedt 19055f9b6cedSSteven Rostedt if ($failed) { 19060a05c769SSteven Rostedt $result = 0; 19075f9b6cedSSteven Rostedt } else { 19080a05c769SSteven Rostedt $result = 1; 19095f9b6cedSSteven Rostedt } 19104025bc62SSteven Rostedt 19114025bc62SSteven Rostedt # reboot the box to a kernel we can ssh to 19124025bc62SSteven Rostedt if ($type ne "build") { 19134025bc62SSteven Rostedt bisect_reboot; 19144025bc62SSteven Rostedt } 19150a05c769SSteven Rostedt $in_bisect = 0; 19160a05c769SSteven Rostedt 19170a05c769SSteven Rostedt return $result; 19180a05c769SSteven Rostedt} 19190a05c769SSteven Rostedt 19200a05c769SSteven Rostedtsub run_bisect { 19210a05c769SSteven Rostedt my ($type) = @_; 19220a05c769SSteven Rostedt my $buildtype = "oldconfig"; 19230a05c769SSteven Rostedt 19240a05c769SSteven Rostedt # We should have a minconfig to use? 19250a05c769SSteven Rostedt if (defined($minconfig)) { 19260a05c769SSteven Rostedt $buildtype = "useconfig:$minconfig"; 19270a05c769SSteven Rostedt } 19280a05c769SSteven Rostedt 19290a05c769SSteven Rostedt my $ret = run_bisect_test $type, $buildtype; 19300a05c769SSteven Rostedt 1931c960bb9fSSteven Rostedt if ($bisect_manual) { 1932c960bb9fSSteven Rostedt $ret = answer_bisect; 1933c960bb9fSSteven Rostedt } 19345f9b6cedSSteven Rostedt 1935d6ce2a0bSSteven Rostedt # Are we looking for where it worked, not failed? 1936d6ce2a0bSSteven Rostedt if ($reverse_bisect) { 19370a05c769SSteven Rostedt $ret = !$ret; 1938d6ce2a0bSSteven Rostedt } 1939d6ce2a0bSSteven Rostedt 1940c23dca7cSSteven Rostedt if ($ret > 0) { 19410a05c769SSteven Rostedt return "good"; 1942c23dca7cSSteven Rostedt } elsif ($ret == 0) { 19430a05c769SSteven Rostedt return "bad"; 1944c23dca7cSSteven Rostedt } elsif ($bisect_skip) { 1945c23dca7cSSteven Rostedt doprint "HIT A BAD COMMIT ... SKIPPING\n"; 1946c23dca7cSSteven Rostedt return "skip"; 19470a05c769SSteven Rostedt } 19485f9b6cedSSteven Rostedt} 19495f9b6cedSSteven Rostedt 1950dad98754SSteven Rostedtsub update_bisect_replay { 1951dad98754SSteven Rostedt my $tmp_log = "$tmpdir/ktest_bisect_log"; 1952dad98754SSteven Rostedt run_command "git bisect log > $tmp_log" or 1953dad98754SSteven Rostedt die "can't create bisect log"; 1954dad98754SSteven Rostedt return $tmp_log; 1955dad98754SSteven Rostedt} 1956dad98754SSteven Rostedt 19575f9b6cedSSteven Rostedtsub bisect { 19585f9b6cedSSteven Rostedt my ($i) = @_; 19595f9b6cedSSteven Rostedt 19605f9b6cedSSteven Rostedt my $result; 19615f9b6cedSSteven Rostedt 19625f9b6cedSSteven Rostedt die "BISECT_GOOD[$i] not defined\n" if (!defined($opt{"BISECT_GOOD[$i]"})); 19635f9b6cedSSteven Rostedt die "BISECT_BAD[$i] not defined\n" if (!defined($opt{"BISECT_BAD[$i]"})); 19645f9b6cedSSteven Rostedt die "BISECT_TYPE[$i] not defined\n" if (!defined($opt{"BISECT_TYPE[$i]"})); 19655f9b6cedSSteven Rostedt 19665f9b6cedSSteven Rostedt my $good = $opt{"BISECT_GOOD[$i]"}; 19675f9b6cedSSteven Rostedt my $bad = $opt{"BISECT_BAD[$i]"}; 19685f9b6cedSSteven Rostedt my $type = $opt{"BISECT_TYPE[$i]"}; 1969a75fececSSteven Rostedt my $start = $opt{"BISECT_START[$i]"}; 1970a75fececSSteven Rostedt my $replay = $opt{"BISECT_REPLAY[$i]"}; 19713410f6fdSSteven Rostedt my $start_files = $opt{"BISECT_FILES[$i]"}; 19723410f6fdSSteven Rostedt 19733410f6fdSSteven Rostedt if (defined($start_files)) { 19743410f6fdSSteven Rostedt $start_files = " -- " . $start_files; 19753410f6fdSSteven Rostedt } else { 19763410f6fdSSteven Rostedt $start_files = ""; 19773410f6fdSSteven Rostedt } 19785f9b6cedSSteven Rostedt 1979a57419b3SSteven Rostedt # convert to true sha1's 1980a57419b3SSteven Rostedt $good = get_sha1($good); 1981a57419b3SSteven Rostedt $bad = get_sha1($bad); 1982a57419b3SSteven Rostedt 1983d6ce2a0bSSteven Rostedt if (defined($opt{"BISECT_REVERSE[$i]"}) && 1984d6ce2a0bSSteven Rostedt $opt{"BISECT_REVERSE[$i]"} == 1) { 1985d6ce2a0bSSteven Rostedt doprint "Performing a reverse bisect (bad is good, good is bad!)\n"; 1986d6ce2a0bSSteven Rostedt $reverse_bisect = 1; 1987d6ce2a0bSSteven Rostedt } else { 1988d6ce2a0bSSteven Rostedt $reverse_bisect = 0; 1989d6ce2a0bSSteven Rostedt } 1990d6ce2a0bSSteven Rostedt 19915a391fbfSSteven Rostedt # Can't have a test without having a test to run 19925a391fbfSSteven Rostedt if ($type eq "test" && !defined($run_test)) { 19935a391fbfSSteven Rostedt $type = "boot"; 19945a391fbfSSteven Rostedt } 19955a391fbfSSteven Rostedt 1996dad98754SSteven Rostedt # Check if a bisect was running 1997dad98754SSteven Rostedt my $bisect_start_file = "$builddir/.git/BISECT_START"; 1998dad98754SSteven Rostedt 1999a75fececSSteven Rostedt my $check = $opt{"BISECT_CHECK[$i]"}; 2000dad98754SSteven Rostedt my $do_check = defined($check) && $check ne "0"; 2001dad98754SSteven Rostedt 2002dad98754SSteven Rostedt if ( -f $bisect_start_file ) { 2003dad98754SSteven Rostedt print "Bisect in progress found\n"; 2004dad98754SSteven Rostedt if ($do_check) { 2005dad98754SSteven Rostedt print " If you say yes, then no checks of good or bad will be done\n"; 2006dad98754SSteven Rostedt } 2007dad98754SSteven Rostedt if (defined($replay)) { 2008dad98754SSteven Rostedt print "** BISECT_REPLAY is defined in config file **"; 2009dad98754SSteven Rostedt print " Ignore config option and perform new git bisect log?\n"; 2010dad98754SSteven Rostedt if (read_ync " (yes, no, or cancel) ") { 2011dad98754SSteven Rostedt $replay = update_bisect_replay; 2012dad98754SSteven Rostedt $do_check = 0; 2013dad98754SSteven Rostedt } 2014dad98754SSteven Rostedt } elsif (read_yn "read git log and continue?") { 2015dad98754SSteven Rostedt $replay = update_bisect_replay; 2016dad98754SSteven Rostedt $do_check = 0; 2017dad98754SSteven Rostedt } 2018dad98754SSteven Rostedt } 2019dad98754SSteven Rostedt 2020dad98754SSteven Rostedt if ($do_check) { 2021a75fececSSteven Rostedt 2022a75fececSSteven Rostedt # get current HEAD 2023a57419b3SSteven Rostedt my $head = get_sha1("HEAD"); 2024a75fececSSteven Rostedt 2025a75fececSSteven Rostedt if ($check ne "good") { 2026a75fececSSteven Rostedt doprint "TESTING BISECT BAD [$bad]\n"; 2027a75fececSSteven Rostedt run_command "git checkout $bad" or 2028a75fececSSteven Rostedt die "Failed to checkout $bad"; 2029a75fececSSteven Rostedt 2030a75fececSSteven Rostedt $result = run_bisect $type; 2031a75fececSSteven Rostedt 2032a75fececSSteven Rostedt if ($result ne "bad") { 2033a75fececSSteven Rostedt fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0; 2034a75fececSSteven Rostedt } 2035a75fececSSteven Rostedt } 2036a75fececSSteven Rostedt 2037a75fececSSteven Rostedt if ($check ne "bad") { 2038a75fececSSteven Rostedt doprint "TESTING BISECT GOOD [$good]\n"; 2039a75fececSSteven Rostedt run_command "git checkout $good" or 2040a75fececSSteven Rostedt die "Failed to checkout $good"; 2041a75fececSSteven Rostedt 2042a75fececSSteven Rostedt $result = run_bisect $type; 2043a75fececSSteven Rostedt 2044a75fececSSteven Rostedt if ($result ne "good") { 2045a75fececSSteven Rostedt fail "Tested BISECT_GOOD [$good] and it failed" and return 0; 2046a75fececSSteven Rostedt } 2047a75fececSSteven Rostedt } 2048a75fececSSteven Rostedt 2049a75fececSSteven Rostedt # checkout where we started 2050a75fececSSteven Rostedt run_command "git checkout $head" or 2051a75fececSSteven Rostedt die "Failed to checkout $head"; 2052a75fececSSteven Rostedt } 2053a75fececSSteven Rostedt 20543410f6fdSSteven Rostedt run_command "git bisect start$start_files" or 2055a75fececSSteven Rostedt dodie "could not start bisect"; 2056a75fececSSteven Rostedt 2057a75fececSSteven Rostedt run_command "git bisect good $good" or 2058a75fececSSteven Rostedt dodie "could not set bisect good to $good"; 2059a75fececSSteven Rostedt 2060a75fececSSteven Rostedt run_git_bisect "git bisect bad $bad" or 2061a75fececSSteven Rostedt dodie "could not set bisect bad to $bad"; 2062a75fececSSteven Rostedt 2063a75fececSSteven Rostedt if (defined($replay)) { 2064a75fececSSteven Rostedt run_command "git bisect replay $replay" or 2065a75fececSSteven Rostedt dodie "failed to run replay"; 2066a75fececSSteven Rostedt } 2067a75fececSSteven Rostedt 2068a75fececSSteven Rostedt if (defined($start)) { 2069a75fececSSteven Rostedt run_command "git checkout $start" or 2070a75fececSSteven Rostedt dodie "failed to checkout $start"; 2071a75fececSSteven Rostedt } 2072a75fececSSteven Rostedt 2073a75fececSSteven Rostedt my $test; 20745f9b6cedSSteven Rostedt do { 20755f9b6cedSSteven Rostedt $result = run_bisect $type; 2076a75fececSSteven Rostedt $test = run_git_bisect "git bisect $result"; 2077a75fececSSteven Rostedt } while ($test); 20785f9b6cedSSteven Rostedt 20795f9b6cedSSteven Rostedt run_command "git bisect log" or 20805f9b6cedSSteven Rostedt dodie "could not capture git bisect log"; 20815f9b6cedSSteven Rostedt 20825f9b6cedSSteven Rostedt run_command "git bisect reset" or 20835f9b6cedSSteven Rostedt dodie "could not reset git bisect"; 20845f9b6cedSSteven Rostedt 20855f9b6cedSSteven Rostedt doprint "Bad commit was [$bisect_bad]\n"; 20865f9b6cedSSteven Rostedt 20870a05c769SSteven Rostedt success $i; 20880a05c769SSteven Rostedt} 20890a05c769SSteven Rostedt 20900a05c769SSteven Rostedtmy %config_ignore; 20910a05c769SSteven Rostedtmy %config_set; 20920a05c769SSteven Rostedt 20930a05c769SSteven Rostedtmy %config_list; 20940a05c769SSteven Rostedtmy %null_config; 20950a05c769SSteven Rostedt 20960a05c769SSteven Rostedtmy %dependency; 20970a05c769SSteven Rostedt 20984c4ab120SSteven Rostedtsub assign_configs { 20994c4ab120SSteven Rostedt my ($hash, $config) = @_; 21000a05c769SSteven Rostedt 21010a05c769SSteven Rostedt open (IN, $config) 21020a05c769SSteven Rostedt or dodie "Failed to read $config"; 21030a05c769SSteven Rostedt 21040a05c769SSteven Rostedt while (<IN>) { 21059bf71749SSteven Rostedt if (/^((CONFIG\S*)=.*)/) { 21064c4ab120SSteven Rostedt ${$hash}{$2} = $1; 21070a05c769SSteven Rostedt } 21080a05c769SSteven Rostedt } 21090a05c769SSteven Rostedt 21100a05c769SSteven Rostedt close(IN); 21110a05c769SSteven Rostedt} 21120a05c769SSteven Rostedt 21134c4ab120SSteven Rostedtsub process_config_ignore { 21144c4ab120SSteven Rostedt my ($config) = @_; 21154c4ab120SSteven Rostedt 21164c4ab120SSteven Rostedt assign_configs \%config_ignore, $config; 21174c4ab120SSteven Rostedt} 21184c4ab120SSteven Rostedt 21190a05c769SSteven Rostedtsub read_current_config { 21200a05c769SSteven Rostedt my ($config_ref) = @_; 21210a05c769SSteven Rostedt 21220a05c769SSteven Rostedt %{$config_ref} = (); 21230a05c769SSteven Rostedt undef %{$config_ref}; 21240a05c769SSteven Rostedt 21250a05c769SSteven Rostedt my @key = keys %{$config_ref}; 21260a05c769SSteven Rostedt if ($#key >= 0) { 21270a05c769SSteven Rostedt print "did not delete!\n"; 21280a05c769SSteven Rostedt exit; 21290a05c769SSteven Rostedt } 21300a05c769SSteven Rostedt open (IN, "$output_config"); 21310a05c769SSteven Rostedt 21320a05c769SSteven Rostedt while (<IN>) { 21330a05c769SSteven Rostedt if (/^(CONFIG\S+)=(.*)/) { 21340a05c769SSteven Rostedt ${$config_ref}{$1} = $2; 21350a05c769SSteven Rostedt } 21360a05c769SSteven Rostedt } 21370a05c769SSteven Rostedt close(IN); 21380a05c769SSteven Rostedt} 21390a05c769SSteven Rostedt 21400a05c769SSteven Rostedtsub get_dependencies { 21410a05c769SSteven Rostedt my ($config) = @_; 21420a05c769SSteven Rostedt 21430a05c769SSteven Rostedt my $arr = $dependency{$config}; 21440a05c769SSteven Rostedt if (!defined($arr)) { 21450a05c769SSteven Rostedt return (); 21460a05c769SSteven Rostedt } 21470a05c769SSteven Rostedt 21480a05c769SSteven Rostedt my @deps = @{$arr}; 21490a05c769SSteven Rostedt 21500a05c769SSteven Rostedt foreach my $dep (@{$arr}) { 21510a05c769SSteven Rostedt print "ADD DEP $dep\n"; 21520a05c769SSteven Rostedt @deps = (@deps, get_dependencies $dep); 21530a05c769SSteven Rostedt } 21540a05c769SSteven Rostedt 21550a05c769SSteven Rostedt return @deps; 21560a05c769SSteven Rostedt} 21570a05c769SSteven Rostedt 21580a05c769SSteven Rostedtsub create_config { 21590a05c769SSteven Rostedt my @configs = @_; 21600a05c769SSteven Rostedt 21610a05c769SSteven Rostedt open(OUT, ">$output_config") or dodie "Can not write to $output_config"; 21620a05c769SSteven Rostedt 21630a05c769SSteven Rostedt foreach my $config (@configs) { 21640a05c769SSteven Rostedt print OUT "$config_set{$config}\n"; 21650a05c769SSteven Rostedt my @deps = get_dependencies $config; 21660a05c769SSteven Rostedt foreach my $dep (@deps) { 21670a05c769SSteven Rostedt print OUT "$config_set{$dep}\n"; 21680a05c769SSteven Rostedt } 21690a05c769SSteven Rostedt } 21700a05c769SSteven Rostedt 21710a05c769SSteven Rostedt foreach my $config (keys %config_ignore) { 21720a05c769SSteven Rostedt print OUT "$config_ignore{$config}\n"; 21730a05c769SSteven Rostedt } 21740a05c769SSteven Rostedt close(OUT); 21750a05c769SSteven Rostedt 21760a05c769SSteven Rostedt# exit; 2177fcb3f16aSSteven Rostedt make_oldconfig; 21780a05c769SSteven Rostedt} 21790a05c769SSteven Rostedt 21800a05c769SSteven Rostedtsub compare_configs { 21810a05c769SSteven Rostedt my (%a, %b) = @_; 21820a05c769SSteven Rostedt 21830a05c769SSteven Rostedt foreach my $item (keys %a) { 21840a05c769SSteven Rostedt if (!defined($b{$item})) { 21850a05c769SSteven Rostedt print "diff $item\n"; 21860a05c769SSteven Rostedt return 1; 21870a05c769SSteven Rostedt } 21880a05c769SSteven Rostedt delete $b{$item}; 21890a05c769SSteven Rostedt } 21900a05c769SSteven Rostedt 21910a05c769SSteven Rostedt my @keys = keys %b; 21920a05c769SSteven Rostedt if ($#keys) { 21930a05c769SSteven Rostedt print "diff2 $keys[0]\n"; 21940a05c769SSteven Rostedt } 21950a05c769SSteven Rostedt return -1 if ($#keys >= 0); 21960a05c769SSteven Rostedt 21970a05c769SSteven Rostedt return 0; 21980a05c769SSteven Rostedt} 21990a05c769SSteven Rostedt 22000a05c769SSteven Rostedtsub run_config_bisect_test { 22010a05c769SSteven Rostedt my ($type) = @_; 22020a05c769SSteven Rostedt 22030a05c769SSteven Rostedt return run_bisect_test $type, "oldconfig"; 22040a05c769SSteven Rostedt} 22050a05c769SSteven Rostedt 22060a05c769SSteven Rostedtsub process_passed { 22070a05c769SSteven Rostedt my (%configs) = @_; 22080a05c769SSteven Rostedt 22090a05c769SSteven Rostedt doprint "These configs had no failure: (Enabling them for further compiles)\n"; 22100a05c769SSteven Rostedt # Passed! All these configs are part of a good compile. 22110a05c769SSteven Rostedt # Add them to the min options. 22120a05c769SSteven Rostedt foreach my $config (keys %configs) { 22130a05c769SSteven Rostedt if (defined($config_list{$config})) { 22140a05c769SSteven Rostedt doprint " removing $config\n"; 22150a05c769SSteven Rostedt $config_ignore{$config} = $config_list{$config}; 22160a05c769SSteven Rostedt delete $config_list{$config}; 22170a05c769SSteven Rostedt } 22180a05c769SSteven Rostedt } 2219f1a27850SSteven Rostedt doprint "config copied to $outputdir/config_good\n"; 2220f1a27850SSteven Rostedt run_command "cp -f $output_config $outputdir/config_good"; 22210a05c769SSteven Rostedt} 22220a05c769SSteven Rostedt 22230a05c769SSteven Rostedtsub process_failed { 22240a05c769SSteven Rostedt my ($config) = @_; 22250a05c769SSteven Rostedt 22260a05c769SSteven Rostedt doprint "\n\n***************************************\n"; 22270a05c769SSteven Rostedt doprint "Found bad config: $config\n"; 22280a05c769SSteven Rostedt doprint "***************************************\n\n"; 22290a05c769SSteven Rostedt} 22300a05c769SSteven Rostedt 22310a05c769SSteven Rostedtsub run_config_bisect { 22320a05c769SSteven Rostedt 22330a05c769SSteven Rostedt my @start_list = keys %config_list; 22340a05c769SSteven Rostedt 22350a05c769SSteven Rostedt if ($#start_list < 0) { 22360a05c769SSteven Rostedt doprint "No more configs to test!!!\n"; 22370a05c769SSteven Rostedt return -1; 22380a05c769SSteven Rostedt } 22390a05c769SSteven Rostedt 22400a05c769SSteven Rostedt doprint "***** RUN TEST ***\n"; 22410a05c769SSteven Rostedt my $type = $opt{"CONFIG_BISECT_TYPE[$iteration]"}; 22420a05c769SSteven Rostedt my $ret; 22430a05c769SSteven Rostedt my %current_config; 22440a05c769SSteven Rostedt 22450a05c769SSteven Rostedt my $count = $#start_list + 1; 22460a05c769SSteven Rostedt doprint " $count configs to test\n"; 22470a05c769SSteven Rostedt 22480a05c769SSteven Rostedt my $half = int($#start_list / 2); 22490a05c769SSteven Rostedt 22500a05c769SSteven Rostedt do { 22510a05c769SSteven Rostedt my @tophalf = @start_list[0 .. $half]; 22520a05c769SSteven Rostedt 22530a05c769SSteven Rostedt create_config @tophalf; 22540a05c769SSteven Rostedt read_current_config \%current_config; 22550a05c769SSteven Rostedt 22560a05c769SSteven Rostedt $count = $#tophalf + 1; 22570a05c769SSteven Rostedt doprint "Testing $count configs\n"; 22580a05c769SSteven Rostedt my $found = 0; 22590a05c769SSteven Rostedt # make sure we test something 22600a05c769SSteven Rostedt foreach my $config (@tophalf) { 22610a05c769SSteven Rostedt if (defined($current_config{$config})) { 22620a05c769SSteven Rostedt logit " $config\n"; 22630a05c769SSteven Rostedt $found = 1; 22640a05c769SSteven Rostedt } 22650a05c769SSteven Rostedt } 22660a05c769SSteven Rostedt if (!$found) { 22670a05c769SSteven Rostedt # try the other half 22680a05c769SSteven Rostedt doprint "Top half produced no set configs, trying bottom half\n"; 22694c8cc55bSSteven Rostedt @tophalf = @start_list[$half + 1 .. $#start_list]; 22700a05c769SSteven Rostedt create_config @tophalf; 22710a05c769SSteven Rostedt read_current_config \%current_config; 22720a05c769SSteven Rostedt foreach my $config (@tophalf) { 22730a05c769SSteven Rostedt if (defined($current_config{$config})) { 22740a05c769SSteven Rostedt logit " $config\n"; 22750a05c769SSteven Rostedt $found = 1; 22760a05c769SSteven Rostedt } 22770a05c769SSteven Rostedt } 22780a05c769SSteven Rostedt if (!$found) { 22790a05c769SSteven Rostedt doprint "Failed: Can't make new config with current configs\n"; 22800a05c769SSteven Rostedt foreach my $config (@start_list) { 22810a05c769SSteven Rostedt doprint " CONFIG: $config\n"; 22820a05c769SSteven Rostedt } 22830a05c769SSteven Rostedt return -1; 22840a05c769SSteven Rostedt } 22850a05c769SSteven Rostedt $count = $#tophalf + 1; 22860a05c769SSteven Rostedt doprint "Testing $count configs\n"; 22870a05c769SSteven Rostedt } 22880a05c769SSteven Rostedt 22890a05c769SSteven Rostedt $ret = run_config_bisect_test $type; 2290c960bb9fSSteven Rostedt if ($bisect_manual) { 2291c960bb9fSSteven Rostedt $ret = answer_bisect; 2292c960bb9fSSteven Rostedt } 22930a05c769SSteven Rostedt if ($ret) { 22940a05c769SSteven Rostedt process_passed %current_config; 22950a05c769SSteven Rostedt return 0; 22960a05c769SSteven Rostedt } 22970a05c769SSteven Rostedt 22980a05c769SSteven Rostedt doprint "This config had a failure.\n"; 22990a05c769SSteven Rostedt doprint "Removing these configs that were not set in this config:\n"; 2300f1a27850SSteven Rostedt doprint "config copied to $outputdir/config_bad\n"; 2301f1a27850SSteven Rostedt run_command "cp -f $output_config $outputdir/config_bad"; 23020a05c769SSteven Rostedt 23030a05c769SSteven Rostedt # A config exists in this group that was bad. 23040a05c769SSteven Rostedt foreach my $config (keys %config_list) { 23050a05c769SSteven Rostedt if (!defined($current_config{$config})) { 23060a05c769SSteven Rostedt doprint " removing $config\n"; 23070a05c769SSteven Rostedt delete $config_list{$config}; 23080a05c769SSteven Rostedt } 23090a05c769SSteven Rostedt } 23100a05c769SSteven Rostedt 23110a05c769SSteven Rostedt @start_list = @tophalf; 23120a05c769SSteven Rostedt 23130a05c769SSteven Rostedt if ($#start_list == 0) { 23140a05c769SSteven Rostedt process_failed $start_list[0]; 23150a05c769SSteven Rostedt return 1; 23160a05c769SSteven Rostedt } 23170a05c769SSteven Rostedt 23180a05c769SSteven Rostedt # remove half the configs we are looking at and see if 23190a05c769SSteven Rostedt # they are good. 23200a05c769SSteven Rostedt $half = int($#start_list / 2); 23214c8cc55bSSteven Rostedt } while ($#start_list > 0); 23220a05c769SSteven Rostedt 2323c960bb9fSSteven Rostedt # we found a single config, try it again unless we are running manually 2324c960bb9fSSteven Rostedt 2325c960bb9fSSteven Rostedt if ($bisect_manual) { 2326c960bb9fSSteven Rostedt process_failed $start_list[0]; 2327c960bb9fSSteven Rostedt return 1; 2328c960bb9fSSteven Rostedt } 2329c960bb9fSSteven Rostedt 23300a05c769SSteven Rostedt my @tophalf = @start_list[0 .. 0]; 23310a05c769SSteven Rostedt 23320a05c769SSteven Rostedt $ret = run_config_bisect_test $type; 23330a05c769SSteven Rostedt if ($ret) { 23340a05c769SSteven Rostedt process_passed %current_config; 23350a05c769SSteven Rostedt return 0; 23360a05c769SSteven Rostedt } 23370a05c769SSteven Rostedt 23380a05c769SSteven Rostedt process_failed $start_list[0]; 23390a05c769SSteven Rostedt return 1; 23400a05c769SSteven Rostedt} 23410a05c769SSteven Rostedt 23420a05c769SSteven Rostedtsub config_bisect { 23430a05c769SSteven Rostedt my ($i) = @_; 23440a05c769SSteven Rostedt 23450a05c769SSteven Rostedt my $start_config = $opt{"CONFIG_BISECT[$i]"}; 23460a05c769SSteven Rostedt 23470a05c769SSteven Rostedt my $tmpconfig = "$tmpdir/use_config"; 23480a05c769SSteven Rostedt 234930f75da5SSteven Rostedt if (defined($config_bisect_good)) { 235030f75da5SSteven Rostedt process_config_ignore $config_bisect_good; 235130f75da5SSteven Rostedt } 235230f75da5SSteven Rostedt 23530a05c769SSteven Rostedt # Make the file with the bad config and the min config 23540a05c769SSteven Rostedt if (defined($minconfig)) { 23550a05c769SSteven Rostedt # read the min config for things to ignore 23560a05c769SSteven Rostedt run_command "cp $minconfig $tmpconfig" or 23570a05c769SSteven Rostedt dodie "failed to copy $minconfig to $tmpconfig"; 23580a05c769SSteven Rostedt } else { 23590a05c769SSteven Rostedt unlink $tmpconfig; 23600a05c769SSteven Rostedt } 23610a05c769SSteven Rostedt 23620a05c769SSteven Rostedt if (-f $tmpconfig) { 2363fcb3f16aSSteven Rostedt load_force_config($tmpconfig); 23640a05c769SSteven Rostedt process_config_ignore $tmpconfig; 23650a05c769SSteven Rostedt } 23660a05c769SSteven Rostedt 23670a05c769SSteven Rostedt # now process the start config 23680a05c769SSteven Rostedt run_command "cp $start_config $output_config" or 23690a05c769SSteven Rostedt dodie "failed to copy $start_config to $output_config"; 23700a05c769SSteven Rostedt 23710a05c769SSteven Rostedt # read directly what we want to check 23720a05c769SSteven Rostedt my %config_check; 23730a05c769SSteven Rostedt open (IN, $output_config) 23740a05c769SSteven Rostedt or dodie "faied to open $output_config"; 23750a05c769SSteven Rostedt 23760a05c769SSteven Rostedt while (<IN>) { 23770a05c769SSteven Rostedt if (/^((CONFIG\S*)=.*)/) { 23780a05c769SSteven Rostedt $config_check{$2} = $1; 23790a05c769SSteven Rostedt } 23800a05c769SSteven Rostedt } 23810a05c769SSteven Rostedt close(IN); 23820a05c769SSteven Rostedt 2383250bae8bSSteven Rostedt # Now run oldconfig with the minconfig 2384fcb3f16aSSteven Rostedt make_oldconfig; 23850a05c769SSteven Rostedt 23860a05c769SSteven Rostedt # check to see what we lost (or gained) 23870a05c769SSteven Rostedt open (IN, $output_config) 23880a05c769SSteven Rostedt or dodie "Failed to read $start_config"; 23890a05c769SSteven Rostedt 23900a05c769SSteven Rostedt my %removed_configs; 23910a05c769SSteven Rostedt my %added_configs; 23920a05c769SSteven Rostedt 23930a05c769SSteven Rostedt while (<IN>) { 23940a05c769SSteven Rostedt if (/^((CONFIG\S*)=.*)/) { 23950a05c769SSteven Rostedt # save off all options 23960a05c769SSteven Rostedt $config_set{$2} = $1; 23970a05c769SSteven Rostedt if (defined($config_check{$2})) { 23980a05c769SSteven Rostedt if (defined($config_ignore{$2})) { 23990a05c769SSteven Rostedt $removed_configs{$2} = $1; 24000a05c769SSteven Rostedt } else { 24010a05c769SSteven Rostedt $config_list{$2} = $1; 24020a05c769SSteven Rostedt } 24030a05c769SSteven Rostedt } elsif (!defined($config_ignore{$2})) { 24040a05c769SSteven Rostedt $added_configs{$2} = $1; 24050a05c769SSteven Rostedt $config_list{$2} = $1; 24060a05c769SSteven Rostedt } 24070a05c769SSteven Rostedt } 24080a05c769SSteven Rostedt } 24090a05c769SSteven Rostedt close(IN); 24100a05c769SSteven Rostedt 24110a05c769SSteven Rostedt my @confs = keys %removed_configs; 24120a05c769SSteven Rostedt if ($#confs >= 0) { 24130a05c769SSteven Rostedt doprint "Configs overridden by default configs and removed from check:\n"; 24140a05c769SSteven Rostedt foreach my $config (@confs) { 24150a05c769SSteven Rostedt doprint " $config\n"; 24160a05c769SSteven Rostedt } 24170a05c769SSteven Rostedt } 24180a05c769SSteven Rostedt @confs = keys %added_configs; 24190a05c769SSteven Rostedt if ($#confs >= 0) { 24200a05c769SSteven Rostedt doprint "Configs appearing in make oldconfig and added:\n"; 24210a05c769SSteven Rostedt foreach my $config (@confs) { 24220a05c769SSteven Rostedt doprint " $config\n"; 24230a05c769SSteven Rostedt } 24240a05c769SSteven Rostedt } 24250a05c769SSteven Rostedt 24260a05c769SSteven Rostedt my %config_test; 24270a05c769SSteven Rostedt my $once = 0; 24280a05c769SSteven Rostedt 24290a05c769SSteven Rostedt # Sometimes kconfig does weird things. We must make sure 24300a05c769SSteven Rostedt # that the config we autocreate has everything we need 24310a05c769SSteven Rostedt # to test, otherwise we may miss testing configs, or 24320a05c769SSteven Rostedt # may not be able to create a new config. 24330a05c769SSteven Rostedt # Here we create a config with everything set. 24340a05c769SSteven Rostedt create_config (keys %config_list); 24350a05c769SSteven Rostedt read_current_config \%config_test; 24360a05c769SSteven Rostedt foreach my $config (keys %config_list) { 24370a05c769SSteven Rostedt if (!defined($config_test{$config})) { 24380a05c769SSteven Rostedt if (!$once) { 24390a05c769SSteven Rostedt $once = 1; 24400a05c769SSteven Rostedt doprint "Configs not produced by kconfig (will not be checked):\n"; 24410a05c769SSteven Rostedt } 24420a05c769SSteven Rostedt doprint " $config\n"; 24430a05c769SSteven Rostedt delete $config_list{$config}; 24440a05c769SSteven Rostedt } 24450a05c769SSteven Rostedt } 24460a05c769SSteven Rostedt my $ret; 24470a05c769SSteven Rostedt do { 24480a05c769SSteven Rostedt $ret = run_config_bisect; 24490a05c769SSteven Rostedt } while (!$ret); 24500a05c769SSteven Rostedt 24510a05c769SSteven Rostedt return $ret if ($ret < 0); 24525f9b6cedSSteven Rostedt 24535f9b6cedSSteven Rostedt success $i; 24545f9b6cedSSteven Rostedt} 24555f9b6cedSSteven Rostedt 245627d934b2SSteven Rostedtsub patchcheck_reboot { 245727d934b2SSteven Rostedt doprint "Reboot and sleep $patchcheck_sleep_time seconds\n"; 24582728be41SAndrew Jones reboot $patchcheck_sleep_time; 245927d934b2SSteven Rostedt} 246027d934b2SSteven Rostedt 24616c5ee0beSSteven Rostedtsub patchcheck { 24626c5ee0beSSteven Rostedt my ($i) = @_; 24636c5ee0beSSteven Rostedt 24646c5ee0beSSteven Rostedt die "PATCHCHECK_START[$i] not defined\n" 24656c5ee0beSSteven Rostedt if (!defined($opt{"PATCHCHECK_START[$i]"})); 24666c5ee0beSSteven Rostedt die "PATCHCHECK_TYPE[$i] not defined\n" 24676c5ee0beSSteven Rostedt if (!defined($opt{"PATCHCHECK_TYPE[$i]"})); 24686c5ee0beSSteven Rostedt 24696c5ee0beSSteven Rostedt my $start = $opt{"PATCHCHECK_START[$i]"}; 24706c5ee0beSSteven Rostedt 24716c5ee0beSSteven Rostedt my $end = "HEAD"; 24726c5ee0beSSteven Rostedt if (defined($opt{"PATCHCHECK_END[$i]"})) { 24736c5ee0beSSteven Rostedt $end = $opt{"PATCHCHECK_END[$i]"}; 24746c5ee0beSSteven Rostedt } 24756c5ee0beSSteven Rostedt 2476a57419b3SSteven Rostedt # Get the true sha1's since we can use things like HEAD~3 2477a57419b3SSteven Rostedt $start = get_sha1($start); 2478a57419b3SSteven Rostedt $end = get_sha1($end); 2479a57419b3SSteven Rostedt 24806c5ee0beSSteven Rostedt my $type = $opt{"PATCHCHECK_TYPE[$i]"}; 24816c5ee0beSSteven Rostedt 24826c5ee0beSSteven Rostedt # Can't have a test without having a test to run 24836c5ee0beSSteven Rostedt if ($type eq "test" && !defined($run_test)) { 24846c5ee0beSSteven Rostedt $type = "boot"; 24856c5ee0beSSteven Rostedt } 24866c5ee0beSSteven Rostedt 24876c5ee0beSSteven Rostedt open (IN, "git log --pretty=oneline $end|") or 24886c5ee0beSSteven Rostedt dodie "could not get git list"; 24896c5ee0beSSteven Rostedt 24906c5ee0beSSteven Rostedt my @list; 24916c5ee0beSSteven Rostedt 24926c5ee0beSSteven Rostedt while (<IN>) { 24936c5ee0beSSteven Rostedt chomp; 24946c5ee0beSSteven Rostedt $list[$#list+1] = $_; 24956c5ee0beSSteven Rostedt last if (/^$start/); 24966c5ee0beSSteven Rostedt } 24976c5ee0beSSteven Rostedt close(IN); 24986c5ee0beSSteven Rostedt 24996c5ee0beSSteven Rostedt if ($list[$#list] !~ /^$start/) { 25002b7d9b21SSteven Rostedt fail "SHA1 $start not found"; 25016c5ee0beSSteven Rostedt } 25026c5ee0beSSteven Rostedt 25036c5ee0beSSteven Rostedt # go backwards in the list 25046c5ee0beSSteven Rostedt @list = reverse @list; 25056c5ee0beSSteven Rostedt 25066c5ee0beSSteven Rostedt my $save_clean = $noclean; 25071990207dSSteven Rostedt my %ignored_warnings; 25081990207dSSteven Rostedt 25091990207dSSteven Rostedt if (defined($ignore_warnings)) { 25101990207dSSteven Rostedt foreach my $sha1 (split /\s+/, $ignore_warnings) { 25111990207dSSteven Rostedt $ignored_warnings{$sha1} = 1; 25121990207dSSteven Rostedt } 25131990207dSSteven Rostedt } 25146c5ee0beSSteven Rostedt 25156c5ee0beSSteven Rostedt $in_patchcheck = 1; 25166c5ee0beSSteven Rostedt foreach my $item (@list) { 25176c5ee0beSSteven Rostedt my $sha1 = $item; 25186c5ee0beSSteven Rostedt $sha1 =~ s/^([[:xdigit:]]+).*/$1/; 25196c5ee0beSSteven Rostedt 25206c5ee0beSSteven Rostedt doprint "\nProcessing commit $item\n\n"; 25216c5ee0beSSteven Rostedt 25226c5ee0beSSteven Rostedt run_command "git checkout $sha1" or 25236c5ee0beSSteven Rostedt die "Failed to checkout $sha1"; 25246c5ee0beSSteven Rostedt 25256c5ee0beSSteven Rostedt # only clean on the first and last patch 25266c5ee0beSSteven Rostedt if ($item eq $list[0] || 25276c5ee0beSSteven Rostedt $item eq $list[$#list]) { 25286c5ee0beSSteven Rostedt $noclean = $save_clean; 25296c5ee0beSSteven Rostedt } else { 25306c5ee0beSSteven Rostedt $noclean = 1; 25316c5ee0beSSteven Rostedt } 25326c5ee0beSSteven Rostedt 25336c5ee0beSSteven Rostedt if (defined($minconfig)) { 25342b7d9b21SSteven Rostedt build "useconfig:$minconfig" or return 0; 25356c5ee0beSSteven Rostedt } else { 25366c5ee0beSSteven Rostedt # ?? no config to use? 25372b7d9b21SSteven Rostedt build "oldconfig" or return 0; 25386c5ee0beSSteven Rostedt } 25396c5ee0beSSteven Rostedt 25401990207dSSteven Rostedt 25411990207dSSteven Rostedt if (!defined($ignored_warnings{$sha1})) { 25422b7d9b21SSteven Rostedt check_buildlog $sha1 or return 0; 25431990207dSSteven Rostedt } 25446c5ee0beSSteven Rostedt 25456c5ee0beSSteven Rostedt next if ($type eq "build"); 25466c5ee0beSSteven Rostedt 25477faafbd6SSteven Rostedt my $failed = 0; 25487faafbd6SSteven Rostedt 2549ddf607e5SSteven Rostedt start_monitor_and_boot or $failed = 1; 25507faafbd6SSteven Rostedt 25517faafbd6SSteven Rostedt if (!$failed && $type ne "boot"){ 25527faafbd6SSteven Rostedt do_run_test or $failed = 1; 25537faafbd6SSteven Rostedt } 25547faafbd6SSteven Rostedt end_monitor; 25557faafbd6SSteven Rostedt return 0 if ($failed); 25567faafbd6SSteven Rostedt 255727d934b2SSteven Rostedt patchcheck_reboot; 255827d934b2SSteven Rostedt 25596c5ee0beSSteven Rostedt } 25606c5ee0beSSteven Rostedt $in_patchcheck = 0; 25616c5ee0beSSteven Rostedt success $i; 25622b7d9b21SSteven Rostedt 25632b7d9b21SSteven Rostedt return 1; 25646c5ee0beSSteven Rostedt} 25656c5ee0beSSteven Rostedt 2566b9066f6cSSteven Rostedtmy %depends; 2567ac6974c7SSteven Rostedtmy %depcount; 2568b9066f6cSSteven Rostedtmy $iflevel = 0; 2569b9066f6cSSteven Rostedtmy @ifdeps; 2570b9066f6cSSteven Rostedt 2571b9066f6cSSteven Rostedt# prevent recursion 2572b9066f6cSSteven Rostedtmy %read_kconfigs; 2573b9066f6cSSteven Rostedt 2574ac6974c7SSteven Rostedtsub add_dep { 2575ac6974c7SSteven Rostedt # $config depends on $dep 2576ac6974c7SSteven Rostedt my ($config, $dep) = @_; 2577ac6974c7SSteven Rostedt 2578ac6974c7SSteven Rostedt if (defined($depends{$config})) { 2579ac6974c7SSteven Rostedt $depends{$config} .= " " . $dep; 2580ac6974c7SSteven Rostedt } else { 2581ac6974c7SSteven Rostedt $depends{$config} = $dep; 2582ac6974c7SSteven Rostedt } 2583ac6974c7SSteven Rostedt 2584ac6974c7SSteven Rostedt # record the number of configs depending on $dep 2585ac6974c7SSteven Rostedt if (defined $depcount{$dep}) { 2586ac6974c7SSteven Rostedt $depcount{$dep}++; 2587ac6974c7SSteven Rostedt } else { 2588ac6974c7SSteven Rostedt $depcount{$dep} = 1; 2589ac6974c7SSteven Rostedt } 2590ac6974c7SSteven Rostedt} 2591ac6974c7SSteven Rostedt 2592b9066f6cSSteven Rostedt# taken from streamline_config.pl 2593b9066f6cSSteven Rostedtsub read_kconfig { 2594b9066f6cSSteven Rostedt my ($kconfig) = @_; 2595b9066f6cSSteven Rostedt 2596b9066f6cSSteven Rostedt my $state = "NONE"; 2597b9066f6cSSteven Rostedt my $config; 2598b9066f6cSSteven Rostedt my @kconfigs; 2599b9066f6cSSteven Rostedt 2600b9066f6cSSteven Rostedt my $cont = 0; 2601b9066f6cSSteven Rostedt my $line; 2602b9066f6cSSteven Rostedt 2603b9066f6cSSteven Rostedt 2604b9066f6cSSteven Rostedt if (! -f $kconfig) { 2605b9066f6cSSteven Rostedt doprint "file $kconfig does not exist, skipping\n"; 2606b9066f6cSSteven Rostedt return; 2607b9066f6cSSteven Rostedt } 2608b9066f6cSSteven Rostedt 2609b9066f6cSSteven Rostedt open(KIN, "$kconfig") 2610b9066f6cSSteven Rostedt or die "Can't open $kconfig"; 2611b9066f6cSSteven Rostedt while (<KIN>) { 2612b9066f6cSSteven Rostedt chomp; 2613b9066f6cSSteven Rostedt 2614b9066f6cSSteven Rostedt # Make sure that lines ending with \ continue 2615b9066f6cSSteven Rostedt if ($cont) { 2616b9066f6cSSteven Rostedt $_ = $line . " " . $_; 2617b9066f6cSSteven Rostedt } 2618b9066f6cSSteven Rostedt 2619b9066f6cSSteven Rostedt if (s/\\$//) { 2620b9066f6cSSteven Rostedt $cont = 1; 2621b9066f6cSSteven Rostedt $line = $_; 2622b9066f6cSSteven Rostedt next; 2623b9066f6cSSteven Rostedt } 2624b9066f6cSSteven Rostedt 2625b9066f6cSSteven Rostedt $cont = 0; 2626b9066f6cSSteven Rostedt 2627b9066f6cSSteven Rostedt # collect any Kconfig sources 2628b9066f6cSSteven Rostedt if (/^source\s*"(.*)"/) { 2629b9066f6cSSteven Rostedt $kconfigs[$#kconfigs+1] = $1; 2630b9066f6cSSteven Rostedt } 2631b9066f6cSSteven Rostedt 2632b9066f6cSSteven Rostedt # configs found 2633b9066f6cSSteven Rostedt if (/^\s*(menu)?config\s+(\S+)\s*$/) { 2634b9066f6cSSteven Rostedt $state = "NEW"; 2635b9066f6cSSteven Rostedt $config = $2; 2636b9066f6cSSteven Rostedt 2637b9066f6cSSteven Rostedt for (my $i = 0; $i < $iflevel; $i++) { 2638ac6974c7SSteven Rostedt add_dep $config, $ifdeps[$i]; 2639b9066f6cSSteven Rostedt } 2640b9066f6cSSteven Rostedt 2641b9066f6cSSteven Rostedt # collect the depends for the config 2642b9066f6cSSteven Rostedt } elsif ($state eq "NEW" && /^\s*depends\s+on\s+(.*)$/) { 2643b9066f6cSSteven Rostedt 2644ac6974c7SSteven Rostedt add_dep $config, $1; 2645b9066f6cSSteven Rostedt 2646b9066f6cSSteven Rostedt # Get the configs that select this config 2647ac6974c7SSteven Rostedt } elsif ($state eq "NEW" && /^\s*select\s+(\S+)/) { 2648ac6974c7SSteven Rostedt 2649ac6974c7SSteven Rostedt # selected by depends on config 2650ac6974c7SSteven Rostedt add_dep $1, $config; 2651b9066f6cSSteven Rostedt 2652b9066f6cSSteven Rostedt # Check for if statements 2653b9066f6cSSteven Rostedt } elsif (/^if\s+(.*\S)\s*$/) { 2654b9066f6cSSteven Rostedt my $deps = $1; 2655b9066f6cSSteven Rostedt # remove beginning and ending non text 2656b9066f6cSSteven Rostedt $deps =~ s/^[^a-zA-Z0-9_]*//; 2657b9066f6cSSteven Rostedt $deps =~ s/[^a-zA-Z0-9_]*$//; 2658b9066f6cSSteven Rostedt 2659b9066f6cSSteven Rostedt my @deps = split /[^a-zA-Z0-9_]+/, $deps; 2660b9066f6cSSteven Rostedt 2661b9066f6cSSteven Rostedt $ifdeps[$iflevel++] = join ':', @deps; 2662b9066f6cSSteven Rostedt 2663b9066f6cSSteven Rostedt } elsif (/^endif/) { 2664b9066f6cSSteven Rostedt 2665b9066f6cSSteven Rostedt $iflevel-- if ($iflevel); 2666b9066f6cSSteven Rostedt 2667b9066f6cSSteven Rostedt # stop on "help" 2668b9066f6cSSteven Rostedt } elsif (/^\s*help\s*$/) { 2669b9066f6cSSteven Rostedt $state = "NONE"; 2670b9066f6cSSteven Rostedt } 2671b9066f6cSSteven Rostedt } 2672b9066f6cSSteven Rostedt close(KIN); 2673b9066f6cSSteven Rostedt 2674b9066f6cSSteven Rostedt # read in any configs that were found. 2675b9066f6cSSteven Rostedt foreach $kconfig (@kconfigs) { 2676b9066f6cSSteven Rostedt if (!defined($read_kconfigs{$kconfig})) { 2677b9066f6cSSteven Rostedt $read_kconfigs{$kconfig} = 1; 2678b9066f6cSSteven Rostedt read_kconfig("$builddir/$kconfig"); 2679b9066f6cSSteven Rostedt } 2680b9066f6cSSteven Rostedt } 2681b9066f6cSSteven Rostedt} 2682b9066f6cSSteven Rostedt 2683b9066f6cSSteven Rostedtsub read_depends { 2684b9066f6cSSteven Rostedt # find out which arch this is by the kconfig file 2685b9066f6cSSteven Rostedt open (IN, $output_config) 2686b9066f6cSSteven Rostedt or dodie "Failed to read $output_config"; 2687b9066f6cSSteven Rostedt my $arch; 2688b9066f6cSSteven Rostedt while (<IN>) { 2689b9066f6cSSteven Rostedt if (m,Linux/(\S+)\s+\S+\s+Kernel Configuration,) { 2690b9066f6cSSteven Rostedt $arch = $1; 2691b9066f6cSSteven Rostedt last; 2692b9066f6cSSteven Rostedt } 2693b9066f6cSSteven Rostedt } 2694b9066f6cSSteven Rostedt close IN; 2695b9066f6cSSteven Rostedt 2696b9066f6cSSteven Rostedt if (!defined($arch)) { 2697b9066f6cSSteven Rostedt doprint "Could not find arch from config file\n"; 2698b9066f6cSSteven Rostedt doprint "no dependencies used\n"; 2699b9066f6cSSteven Rostedt return; 2700b9066f6cSSteven Rostedt } 2701b9066f6cSSteven Rostedt 2702b9066f6cSSteven Rostedt # arch is really the subarch, we need to know 2703b9066f6cSSteven Rostedt # what directory to look at. 2704b9066f6cSSteven Rostedt if ($arch eq "i386" || $arch eq "x86_64") { 2705b9066f6cSSteven Rostedt $arch = "x86"; 2706b9066f6cSSteven Rostedt } elsif ($arch =~ /^tile/) { 2707b9066f6cSSteven Rostedt $arch = "tile"; 2708b9066f6cSSteven Rostedt } 2709b9066f6cSSteven Rostedt 2710b9066f6cSSteven Rostedt my $kconfig = "$builddir/arch/$arch/Kconfig"; 2711b9066f6cSSteven Rostedt 2712b9066f6cSSteven Rostedt if (! -f $kconfig && $arch =~ /\d$/) { 2713b9066f6cSSteven Rostedt my $orig = $arch; 2714b9066f6cSSteven Rostedt # some subarchs have numbers, truncate them 2715b9066f6cSSteven Rostedt $arch =~ s/\d*$//; 2716b9066f6cSSteven Rostedt $kconfig = "$builddir/arch/$arch/Kconfig"; 2717b9066f6cSSteven Rostedt if (! -f $kconfig) { 2718b9066f6cSSteven Rostedt doprint "No idea what arch dir $orig is for\n"; 2719b9066f6cSSteven Rostedt doprint "no dependencies used\n"; 2720b9066f6cSSteven Rostedt return; 2721b9066f6cSSteven Rostedt } 2722b9066f6cSSteven Rostedt } 2723b9066f6cSSteven Rostedt 2724b9066f6cSSteven Rostedt read_kconfig($kconfig); 2725b9066f6cSSteven Rostedt} 2726b9066f6cSSteven Rostedt 27274c4ab120SSteven Rostedtsub read_config_list { 27284c4ab120SSteven Rostedt my ($config) = @_; 27294c4ab120SSteven Rostedt 27304c4ab120SSteven Rostedt open (IN, $config) 27314c4ab120SSteven Rostedt or dodie "Failed to read $config"; 27324c4ab120SSteven Rostedt 27334c4ab120SSteven Rostedt while (<IN>) { 27344c4ab120SSteven Rostedt if (/^((CONFIG\S*)=.*)/) { 27354c4ab120SSteven Rostedt if (!defined($config_ignore{$2})) { 27364c4ab120SSteven Rostedt $config_list{$2} = $1; 27374c4ab120SSteven Rostedt } 27384c4ab120SSteven Rostedt } 27394c4ab120SSteven Rostedt } 27404c4ab120SSteven Rostedt 27414c4ab120SSteven Rostedt close(IN); 27424c4ab120SSteven Rostedt} 27434c4ab120SSteven Rostedt 27444c4ab120SSteven Rostedtsub read_output_config { 27454c4ab120SSteven Rostedt my ($config) = @_; 27464c4ab120SSteven Rostedt 27474c4ab120SSteven Rostedt assign_configs \%config_ignore, $config; 27484c4ab120SSteven Rostedt} 27494c4ab120SSteven Rostedt 27504c4ab120SSteven Rostedtsub make_new_config { 27514c4ab120SSteven Rostedt my @configs = @_; 27524c4ab120SSteven Rostedt 27534c4ab120SSteven Rostedt open (OUT, ">$output_config") 27544c4ab120SSteven Rostedt or dodie "Failed to write $output_config"; 27554c4ab120SSteven Rostedt 27564c4ab120SSteven Rostedt foreach my $config (@configs) { 27574c4ab120SSteven Rostedt print OUT "$config\n"; 27584c4ab120SSteven Rostedt } 27594c4ab120SSteven Rostedt close OUT; 27604c4ab120SSteven Rostedt} 27614c4ab120SSteven Rostedt 2762ac6974c7SSteven Rostedtsub chomp_config { 2763ac6974c7SSteven Rostedt my ($config) = @_; 2764ac6974c7SSteven Rostedt 2765ac6974c7SSteven Rostedt $config =~ s/CONFIG_//; 2766ac6974c7SSteven Rostedt 2767ac6974c7SSteven Rostedt return $config; 2768ac6974c7SSteven Rostedt} 2769ac6974c7SSteven Rostedt 2770b9066f6cSSteven Rostedtsub get_depends { 2771b9066f6cSSteven Rostedt my ($dep) = @_; 2772b9066f6cSSteven Rostedt 2773ac6974c7SSteven Rostedt my $kconfig = chomp_config $dep; 2774b9066f6cSSteven Rostedt 2775b9066f6cSSteven Rostedt $dep = $depends{"$kconfig"}; 2776b9066f6cSSteven Rostedt 2777b9066f6cSSteven Rostedt # the dep string we have saves the dependencies as they 2778b9066f6cSSteven Rostedt # were found, including expressions like ! && ||. We 2779b9066f6cSSteven Rostedt # want to split this out into just an array of configs. 2780b9066f6cSSteven Rostedt 2781b9066f6cSSteven Rostedt my $valid = "A-Za-z_0-9"; 2782b9066f6cSSteven Rostedt 2783b9066f6cSSteven Rostedt my @configs; 2784b9066f6cSSteven Rostedt 2785b9066f6cSSteven Rostedt while ($dep =~ /[$valid]/) { 2786b9066f6cSSteven Rostedt 2787b9066f6cSSteven Rostedt if ($dep =~ /^[^$valid]*([$valid]+)/) { 2788b9066f6cSSteven Rostedt my $conf = "CONFIG_" . $1; 2789b9066f6cSSteven Rostedt 2790b9066f6cSSteven Rostedt $configs[$#configs + 1] = $conf; 2791b9066f6cSSteven Rostedt 2792b9066f6cSSteven Rostedt $dep =~ s/^[^$valid]*[$valid]+//; 2793b9066f6cSSteven Rostedt } else { 2794b9066f6cSSteven Rostedt die "this should never happen"; 2795b9066f6cSSteven Rostedt } 2796b9066f6cSSteven Rostedt } 2797b9066f6cSSteven Rostedt 2798b9066f6cSSteven Rostedt return @configs; 2799b9066f6cSSteven Rostedt} 2800b9066f6cSSteven Rostedt 2801b9066f6cSSteven Rostedtmy %min_configs; 2802b9066f6cSSteven Rostedtmy %keep_configs; 280343d1b651SSteven Rostedtmy %save_configs; 2804b9066f6cSSteven Rostedtmy %processed_configs; 2805b9066f6cSSteven Rostedtmy %nochange_config; 2806b9066f6cSSteven Rostedt 2807b9066f6cSSteven Rostedtsub test_this_config { 2808b9066f6cSSteven Rostedt my ($config) = @_; 2809b9066f6cSSteven Rostedt 2810b9066f6cSSteven Rostedt my $found; 2811b9066f6cSSteven Rostedt 2812b9066f6cSSteven Rostedt # if we already processed this config, skip it 2813b9066f6cSSteven Rostedt if (defined($processed_configs{$config})) { 2814b9066f6cSSteven Rostedt return undef; 2815b9066f6cSSteven Rostedt } 2816b9066f6cSSteven Rostedt $processed_configs{$config} = 1; 2817b9066f6cSSteven Rostedt 2818b9066f6cSSteven Rostedt # if this config failed during this round, skip it 2819b9066f6cSSteven Rostedt if (defined($nochange_config{$config})) { 2820b9066f6cSSteven Rostedt return undef; 2821b9066f6cSSteven Rostedt } 2822b9066f6cSSteven Rostedt 2823ac6974c7SSteven Rostedt my $kconfig = chomp_config $config; 2824b9066f6cSSteven Rostedt 2825b9066f6cSSteven Rostedt # Test dependencies first 2826b9066f6cSSteven Rostedt if (defined($depends{"$kconfig"})) { 2827b9066f6cSSteven Rostedt my @parents = get_depends $config; 2828b9066f6cSSteven Rostedt foreach my $parent (@parents) { 2829b9066f6cSSteven Rostedt # if the parent is in the min config, check it first 2830b9066f6cSSteven Rostedt next if (!defined($min_configs{$parent})); 2831b9066f6cSSteven Rostedt $found = test_this_config($parent); 2832b9066f6cSSteven Rostedt if (defined($found)) { 2833b9066f6cSSteven Rostedt return $found; 2834b9066f6cSSteven Rostedt } 2835b9066f6cSSteven Rostedt } 2836b9066f6cSSteven Rostedt } 2837b9066f6cSSteven Rostedt 2838b9066f6cSSteven Rostedt # Remove this config from the list of configs 2839b9066f6cSSteven Rostedt # do a make oldnoconfig and then read the resulting 2840b9066f6cSSteven Rostedt # .config to make sure it is missing the config that 2841b9066f6cSSteven Rostedt # we had before 2842b9066f6cSSteven Rostedt my %configs = %min_configs; 2843b9066f6cSSteven Rostedt delete $configs{$config}; 2844b9066f6cSSteven Rostedt make_new_config ((values %configs), (values %keep_configs)); 2845b9066f6cSSteven Rostedt make_oldconfig; 2846b9066f6cSSteven Rostedt undef %configs; 2847b9066f6cSSteven Rostedt assign_configs \%configs, $output_config; 2848b9066f6cSSteven Rostedt 2849b9066f6cSSteven Rostedt return $config if (!defined($configs{$config})); 2850b9066f6cSSteven Rostedt 2851b9066f6cSSteven Rostedt doprint "disabling config $config did not change .config\n"; 2852b9066f6cSSteven Rostedt 2853b9066f6cSSteven Rostedt $nochange_config{$config} = 1; 2854b9066f6cSSteven Rostedt 2855b9066f6cSSteven Rostedt return undef; 2856b9066f6cSSteven Rostedt} 2857b9066f6cSSteven Rostedt 28584c4ab120SSteven Rostedtsub make_min_config { 28594c4ab120SSteven Rostedt my ($i) = @_; 28604c4ab120SSteven Rostedt 28614c4ab120SSteven Rostedt if (!defined($output_minconfig)) { 28624c4ab120SSteven Rostedt fail "OUTPUT_MIN_CONFIG not defined" and return; 28634c4ab120SSteven Rostedt } 286435ce5952SSteven Rostedt 286535ce5952SSteven Rostedt # If output_minconfig exists, and the start_minconfig 286635ce5952SSteven Rostedt # came from min_config, than ask if we should use 286735ce5952SSteven Rostedt # that instead. 286835ce5952SSteven Rostedt if (-f $output_minconfig && !$start_minconfig_defined) { 286935ce5952SSteven Rostedt print "$output_minconfig exists\n"; 287035ce5952SSteven Rostedt if (read_yn " Use it as minconfig?") { 287135ce5952SSteven Rostedt $start_minconfig = $output_minconfig; 287235ce5952SSteven Rostedt } 287335ce5952SSteven Rostedt } 287435ce5952SSteven Rostedt 28754c4ab120SSteven Rostedt if (!defined($start_minconfig)) { 28764c4ab120SSteven Rostedt fail "START_MIN_CONFIG or MIN_CONFIG not defined" and return; 28774c4ab120SSteven Rostedt } 28784c4ab120SSteven Rostedt 287935ce5952SSteven Rostedt my $temp_config = "$tmpdir/temp_config"; 288035ce5952SSteven Rostedt 28814c4ab120SSteven Rostedt # First things first. We build an allnoconfig to find 28824c4ab120SSteven Rostedt # out what the defaults are that we can't touch. 28834c4ab120SSteven Rostedt # Some are selections, but we really can't handle selections. 28844c4ab120SSteven Rostedt 28854c4ab120SSteven Rostedt my $save_minconfig = $minconfig; 28864c4ab120SSteven Rostedt undef $minconfig; 28874c4ab120SSteven Rostedt 28884c4ab120SSteven Rostedt run_command "$make allnoconfig" or return 0; 28894c4ab120SSteven Rostedt 2890b9066f6cSSteven Rostedt read_depends; 2891b9066f6cSSteven Rostedt 28924c4ab120SSteven Rostedt process_config_ignore $output_config; 2893b9066f6cSSteven Rostedt 289443d1b651SSteven Rostedt undef %save_configs; 2895b9066f6cSSteven Rostedt undef %min_configs; 28964c4ab120SSteven Rostedt 28974c4ab120SSteven Rostedt if (defined($ignore_config)) { 28984c4ab120SSteven Rostedt # make sure the file exists 28994c4ab120SSteven Rostedt `touch $ignore_config`; 290043d1b651SSteven Rostedt assign_configs \%save_configs, $ignore_config; 29014c4ab120SSteven Rostedt } 29024c4ab120SSteven Rostedt 290343d1b651SSteven Rostedt %keep_configs = %save_configs; 290443d1b651SSteven Rostedt 29054c4ab120SSteven Rostedt doprint "Load initial configs from $start_minconfig\n"; 29064c4ab120SSteven Rostedt 29074c4ab120SSteven Rostedt # Look at the current min configs, and save off all the 29084c4ab120SSteven Rostedt # ones that were set via the allnoconfig 29094c4ab120SSteven Rostedt assign_configs \%min_configs, $start_minconfig; 29104c4ab120SSteven Rostedt 29114c4ab120SSteven Rostedt my @config_keys = keys %min_configs; 29124c4ab120SSteven Rostedt 2913ac6974c7SSteven Rostedt # All configs need a depcount 2914ac6974c7SSteven Rostedt foreach my $config (@config_keys) { 2915ac6974c7SSteven Rostedt my $kconfig = chomp_config $config; 2916ac6974c7SSteven Rostedt if (!defined $depcount{$kconfig}) { 2917ac6974c7SSteven Rostedt $depcount{$kconfig} = 0; 2918ac6974c7SSteven Rostedt } 2919ac6974c7SSteven Rostedt } 2920ac6974c7SSteven Rostedt 29214c4ab120SSteven Rostedt # Remove anything that was set by the make allnoconfig 29224c4ab120SSteven Rostedt # we shouldn't need them as they get set for us anyway. 29234c4ab120SSteven Rostedt foreach my $config (@config_keys) { 29244c4ab120SSteven Rostedt # Remove anything in the ignore_config 29254c4ab120SSteven Rostedt if (defined($keep_configs{$config})) { 29264c4ab120SSteven Rostedt my $file = $ignore_config; 29274c4ab120SSteven Rostedt $file =~ s,.*/(.*?)$,$1,; 29284c4ab120SSteven Rostedt doprint "$config set by $file ... ignored\n"; 29294c4ab120SSteven Rostedt delete $min_configs{$config}; 29304c4ab120SSteven Rostedt next; 29314c4ab120SSteven Rostedt } 29324c4ab120SSteven Rostedt # But make sure the settings are the same. If a min config 29334c4ab120SSteven Rostedt # sets a selection, we do not want to get rid of it if 29344c4ab120SSteven Rostedt # it is not the same as what we have. Just move it into 29354c4ab120SSteven Rostedt # the keep configs. 29364c4ab120SSteven Rostedt if (defined($config_ignore{$config})) { 29374c4ab120SSteven Rostedt if ($config_ignore{$config} ne $min_configs{$config}) { 29384c4ab120SSteven Rostedt doprint "$config is in allnoconfig as '$config_ignore{$config}'"; 29394c4ab120SSteven Rostedt doprint " but it is '$min_configs{$config}' in minconfig .. keeping\n"; 29404c4ab120SSteven Rostedt $keep_configs{$config} = $min_configs{$config}; 29414c4ab120SSteven Rostedt } else { 29424c4ab120SSteven Rostedt doprint "$config set by allnoconfig ... ignored\n"; 29434c4ab120SSteven Rostedt } 29444c4ab120SSteven Rostedt delete $min_configs{$config}; 29454c4ab120SSteven Rostedt } 29464c4ab120SSteven Rostedt } 29474c4ab120SSteven Rostedt 29484c4ab120SSteven Rostedt my $done = 0; 2949b9066f6cSSteven Rostedt my $take_two = 0; 29504c4ab120SSteven Rostedt 29514c4ab120SSteven Rostedt while (!$done) { 29524c4ab120SSteven Rostedt 29534c4ab120SSteven Rostedt my $config; 29544c4ab120SSteven Rostedt my $found; 29554c4ab120SSteven Rostedt 29564c4ab120SSteven Rostedt # Now disable each config one by one and do a make oldconfig 29574c4ab120SSteven Rostedt # till we find a config that changes our list. 29584c4ab120SSteven Rostedt 29594c4ab120SSteven Rostedt my @test_configs = keys %min_configs; 2960ac6974c7SSteven Rostedt 2961ac6974c7SSteven Rostedt # Sort keys by who is most dependent on 2962ac6974c7SSteven Rostedt @test_configs = sort { $depcount{chomp_config($b)} <=> $depcount{chomp_config($a)} } 2963ac6974c7SSteven Rostedt @test_configs ; 2964ac6974c7SSteven Rostedt 2965ac6974c7SSteven Rostedt # Put configs that did not modify the config at the end. 29664c4ab120SSteven Rostedt my $reset = 1; 29674c4ab120SSteven Rostedt for (my $i = 0; $i < $#test_configs; $i++) { 29684c4ab120SSteven Rostedt if (!defined($nochange_config{$test_configs[0]})) { 29694c4ab120SSteven Rostedt $reset = 0; 29704c4ab120SSteven Rostedt last; 29714c4ab120SSteven Rostedt } 29724c4ab120SSteven Rostedt # This config didn't change the .config last time. 29734c4ab120SSteven Rostedt # Place it at the end 29744c4ab120SSteven Rostedt my $config = shift @test_configs; 29754c4ab120SSteven Rostedt push @test_configs, $config; 29764c4ab120SSteven Rostedt } 29774c4ab120SSteven Rostedt 29784c4ab120SSteven Rostedt # if every test config has failed to modify the .config file 29794c4ab120SSteven Rostedt # in the past, then reset and start over. 29804c4ab120SSteven Rostedt if ($reset) { 29814c4ab120SSteven Rostedt undef %nochange_config; 29824c4ab120SSteven Rostedt } 29834c4ab120SSteven Rostedt 2984b9066f6cSSteven Rostedt undef %processed_configs; 2985b9066f6cSSteven Rostedt 29864c4ab120SSteven Rostedt foreach my $config (@test_configs) { 29874c4ab120SSteven Rostedt 2988b9066f6cSSteven Rostedt $found = test_this_config $config; 29894c4ab120SSteven Rostedt 2990b9066f6cSSteven Rostedt last if (defined($found)); 29914c4ab120SSteven Rostedt 29924c4ab120SSteven Rostedt # oh well, try another config 29934c4ab120SSteven Rostedt } 29944c4ab120SSteven Rostedt 29954c4ab120SSteven Rostedt if (!defined($found)) { 2996b9066f6cSSteven Rostedt # we could have failed due to the nochange_config hash 2997b9066f6cSSteven Rostedt # reset and try again 2998b9066f6cSSteven Rostedt if (!$take_two) { 2999b9066f6cSSteven Rostedt undef %nochange_config; 3000b9066f6cSSteven Rostedt $take_two = 1; 3001b9066f6cSSteven Rostedt next; 3002b9066f6cSSteven Rostedt } 30034c4ab120SSteven Rostedt doprint "No more configs found that we can disable\n"; 30044c4ab120SSteven Rostedt $done = 1; 30054c4ab120SSteven Rostedt last; 30064c4ab120SSteven Rostedt } 3007b9066f6cSSteven Rostedt $take_two = 0; 30084c4ab120SSteven Rostedt 30094c4ab120SSteven Rostedt $config = $found; 30104c4ab120SSteven Rostedt 30114c4ab120SSteven Rostedt doprint "Test with $config disabled\n"; 30124c4ab120SSteven Rostedt 30134c4ab120SSteven Rostedt # set in_bisect to keep build and monitor from dieing 30144c4ab120SSteven Rostedt $in_bisect = 1; 30154c4ab120SSteven Rostedt 30164c4ab120SSteven Rostedt my $failed = 0; 30174c4ab120SSteven Rostedt build "oldconfig"; 30184c4ab120SSteven Rostedt start_monitor_and_boot or $failed = 1; 30194c4ab120SSteven Rostedt end_monitor; 30204c4ab120SSteven Rostedt 30214c4ab120SSteven Rostedt $in_bisect = 0; 30224c4ab120SSteven Rostedt 30234c4ab120SSteven Rostedt if ($failed) { 3024b9066f6cSSteven Rostedt doprint "$min_configs{$config} is needed to boot the box... keeping\n"; 30254c4ab120SSteven Rostedt # this config is needed, add it to the ignore list. 30264c4ab120SSteven Rostedt $keep_configs{$config} = $min_configs{$config}; 302743d1b651SSteven Rostedt $save_configs{$config} = $min_configs{$config}; 30284c4ab120SSteven Rostedt delete $min_configs{$config}; 302935ce5952SSteven Rostedt 303035ce5952SSteven Rostedt # update new ignore configs 303135ce5952SSteven Rostedt if (defined($ignore_config)) { 303235ce5952SSteven Rostedt open (OUT, ">$temp_config") 303335ce5952SSteven Rostedt or die "Can't write to $temp_config"; 303443d1b651SSteven Rostedt foreach my $config (keys %save_configs) { 303543d1b651SSteven Rostedt print OUT "$save_configs{$config}\n"; 303635ce5952SSteven Rostedt } 303735ce5952SSteven Rostedt close OUT; 303835ce5952SSteven Rostedt run_command "mv $temp_config $ignore_config" or 303935ce5952SSteven Rostedt dodie "failed to copy update to $ignore_config"; 304035ce5952SSteven Rostedt } 304135ce5952SSteven Rostedt 30424c4ab120SSteven Rostedt } else { 30434c4ab120SSteven Rostedt # We booted without this config, remove it from the minconfigs. 30444c4ab120SSteven Rostedt doprint "$config is not needed, disabling\n"; 30454c4ab120SSteven Rostedt 30464c4ab120SSteven Rostedt delete $min_configs{$config}; 30474c4ab120SSteven Rostedt 30484c4ab120SSteven Rostedt # Also disable anything that is not enabled in this config 30494c4ab120SSteven Rostedt my %configs; 30504c4ab120SSteven Rostedt assign_configs \%configs, $output_config; 30514c4ab120SSteven Rostedt my @config_keys = keys %min_configs; 30524c4ab120SSteven Rostedt foreach my $config (@config_keys) { 30534c4ab120SSteven Rostedt if (!defined($configs{$config})) { 30544c4ab120SSteven Rostedt doprint "$config is not set, disabling\n"; 30554c4ab120SSteven Rostedt delete $min_configs{$config}; 30564c4ab120SSteven Rostedt } 30574c4ab120SSteven Rostedt } 30584c4ab120SSteven Rostedt 30594c4ab120SSteven Rostedt # Save off all the current mandidory configs 306035ce5952SSteven Rostedt open (OUT, ">$temp_config") 306135ce5952SSteven Rostedt or die "Can't write to $temp_config"; 30624c4ab120SSteven Rostedt foreach my $config (keys %keep_configs) { 30634c4ab120SSteven Rostedt print OUT "$keep_configs{$config}\n"; 30644c4ab120SSteven Rostedt } 30654c4ab120SSteven Rostedt foreach my $config (keys %min_configs) { 30664c4ab120SSteven Rostedt print OUT "$min_configs{$config}\n"; 30674c4ab120SSteven Rostedt } 30684c4ab120SSteven Rostedt close OUT; 306935ce5952SSteven Rostedt 307035ce5952SSteven Rostedt run_command "mv $temp_config $output_minconfig" or 307135ce5952SSteven Rostedt dodie "failed to copy update to $output_minconfig"; 30724c4ab120SSteven Rostedt } 30734c4ab120SSteven Rostedt 30744c4ab120SSteven Rostedt doprint "Reboot and wait $sleep_time seconds\n"; 30752728be41SAndrew Jones reboot $sleep_time; 30764c4ab120SSteven Rostedt } 30774c4ab120SSteven Rostedt 30784c4ab120SSteven Rostedt success $i; 30794c4ab120SSteven Rostedt return 1; 30804c4ab120SSteven Rostedt} 30814c4ab120SSteven Rostedt 30828d1491baSSteven Rostedt$#ARGV < 1 or die "ktest.pl version: $VERSION\n usage: ktest.pl config-file\n"; 30832545eb61SSteven Rostedt 30848d1491baSSteven Rostedtif ($#ARGV == 0) { 30858d1491baSSteven Rostedt $ktest_config = $ARGV[0]; 30868d1491baSSteven Rostedt if (! -f $ktest_config) { 30878d1491baSSteven Rostedt print "$ktest_config does not exist.\n"; 308835ce5952SSteven Rostedt if (!read_yn "Create it?") { 30898d1491baSSteven Rostedt exit 0; 30908d1491baSSteven Rostedt } 30918d1491baSSteven Rostedt } 30928d1491baSSteven Rostedt} else { 30938d1491baSSteven Rostedt $ktest_config = "ktest.conf"; 30948d1491baSSteven Rostedt} 30958d1491baSSteven Rostedt 30968d1491baSSteven Rostedtif (! -f $ktest_config) { 3097c4261d0fSSteven Rostedt get_test_case; 30988d1491baSSteven Rostedt open(OUT, ">$ktest_config") or die "Can not create $ktest_config"; 30998d1491baSSteven Rostedt print OUT << "EOF" 31008d1491baSSteven Rostedt# Generated by ktest.pl 31018d1491baSSteven Rostedt# 31020e7a22deSSteven Rostedt 31030e7a22deSSteven Rostedt# PWD is a ktest.pl variable that will result in the process working 31040e7a22deSSteven Rostedt# directory that ktest.pl is executed in. 31050e7a22deSSteven Rostedt 31060e7a22deSSteven Rostedt# THIS_DIR is automatically assigned the PWD of the path that generated 31070e7a22deSSteven Rostedt# the config file. It is best to use this variable when assigning other 31080e7a22deSSteven Rostedt# directory paths within this directory. This allows you to easily 31090e7a22deSSteven Rostedt# move the test cases to other locations or to other machines. 31100e7a22deSSteven Rostedt# 31110e7a22deSSteven RostedtTHIS_DIR := $variable{"PWD"} 31120e7a22deSSteven Rostedt 31138d1491baSSteven Rostedt# Define each test with TEST_START 31148d1491baSSteven Rostedt# The config options below it will override the defaults 31158d1491baSSteven RostedtTEST_START 3116c4261d0fSSteven RostedtTEST_TYPE = $default{"TEST_TYPE"} 31178d1491baSSteven Rostedt 31188d1491baSSteven RostedtDEFAULTS 31198d1491baSSteven RostedtEOF 31208d1491baSSteven Rostedt; 31218d1491baSSteven Rostedt close(OUT); 31228d1491baSSteven Rostedt} 31238d1491baSSteven Rostedtread_config $ktest_config; 31248d1491baSSteven Rostedt 312523715c3cSSteven Rostedtif (defined($opt{"LOG_FILE"})) { 312623715c3cSSteven Rostedt $opt{"LOG_FILE"} = eval_option($opt{"LOG_FILE"}, -1); 312723715c3cSSteven Rostedt} 312823715c3cSSteven Rostedt 31298d1491baSSteven Rostedt# Append any configs entered in manually to the config file. 31308d1491baSSteven Rostedtmy @new_configs = keys %entered_configs; 31318d1491baSSteven Rostedtif ($#new_configs >= 0) { 31328d1491baSSteven Rostedt print "\nAppending entered in configs to $ktest_config\n"; 31338d1491baSSteven Rostedt open(OUT, ">>$ktest_config") or die "Can not append to $ktest_config"; 31348d1491baSSteven Rostedt foreach my $config (@new_configs) { 31358d1491baSSteven Rostedt print OUT "$config = $entered_configs{$config}\n"; 31360e7a22deSSteven Rostedt $opt{$config} = process_variables($entered_configs{$config}); 31378d1491baSSteven Rostedt } 31388d1491baSSteven Rostedt} 31392545eb61SSteven Rostedt 31402b7d9b21SSteven Rostedtif ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) { 31412b7d9b21SSteven Rostedt unlink $opt{"LOG_FILE"}; 31422b7d9b21SSteven Rostedt} 31432545eb61SSteven Rostedt 31442b7d9b21SSteven Rostedtdoprint "\n\nSTARTING AUTOMATED TESTS\n\n"; 31452b7d9b21SSteven Rostedt 3146a57419b3SSteven Rostedtfor (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) { 3147a57419b3SSteven Rostedt 3148a57419b3SSteven Rostedt if (!$i) { 3149a57419b3SSteven Rostedt doprint "DEFAULT OPTIONS:\n"; 3150a57419b3SSteven Rostedt } else { 3151a57419b3SSteven Rostedt doprint "\nTEST $i OPTIONS"; 3152a57419b3SSteven Rostedt if (defined($repeat_tests{$i})) { 3153a57419b3SSteven Rostedt $repeat = $repeat_tests{$i}; 3154a57419b3SSteven Rostedt doprint " ITERATE $repeat"; 3155a57419b3SSteven Rostedt } 3156a57419b3SSteven Rostedt doprint "\n"; 3157a57419b3SSteven Rostedt } 3158a57419b3SSteven Rostedt 31592b7d9b21SSteven Rostedt foreach my $option (sort keys %opt) { 3160a57419b3SSteven Rostedt 3161a57419b3SSteven Rostedt if ($option =~ /\[(\d+)\]$/) { 3162a57419b3SSteven Rostedt next if ($i != $1); 3163a57419b3SSteven Rostedt } else { 3164a57419b3SSteven Rostedt next if ($i); 3165a57419b3SSteven Rostedt } 3166a57419b3SSteven Rostedt 31672b7d9b21SSteven Rostedt doprint "$option = $opt{$option}\n"; 31682b7d9b21SSteven Rostedt } 3169a57419b3SSteven Rostedt} 31702545eb61SSteven Rostedt 31712a62512bSSteven Rostedtsub __set_test_option { 31725a391fbfSSteven Rostedt my ($name, $i) = @_; 31735a391fbfSSteven Rostedt 31745a391fbfSSteven Rostedt my $option = "$name\[$i\]"; 31755a391fbfSSteven Rostedt 31765a391fbfSSteven Rostedt if (defined($opt{$option})) { 31775a391fbfSSteven Rostedt return $opt{$option}; 31785a391fbfSSteven Rostedt } 31795a391fbfSSteven Rostedt 3180a57419b3SSteven Rostedt foreach my $test (keys %repeat_tests) { 3181a57419b3SSteven Rostedt if ($i >= $test && 3182a57419b3SSteven Rostedt $i < $test + $repeat_tests{$test}) { 3183a57419b3SSteven Rostedt $option = "$name\[$test\]"; 3184a57419b3SSteven Rostedt if (defined($opt{$option})) { 3185a57419b3SSteven Rostedt return $opt{$option}; 3186a57419b3SSteven Rostedt } 3187a57419b3SSteven Rostedt } 3188a57419b3SSteven Rostedt } 3189a57419b3SSteven Rostedt 31905a391fbfSSteven Rostedt if (defined($opt{$name})) { 31915a391fbfSSteven Rostedt return $opt{$name}; 31925a391fbfSSteven Rostedt } 31935a391fbfSSteven Rostedt 31945a391fbfSSteven Rostedt return undef; 31955a391fbfSSteven Rostedt} 31965a391fbfSSteven Rostedt 31972a62512bSSteven Rostedtsub set_test_option { 31982a62512bSSteven Rostedt my ($name, $i) = @_; 31992a62512bSSteven Rostedt 32002a62512bSSteven Rostedt my $option = __set_test_option($name, $i); 32012a62512bSSteven Rostedt return $option if (!defined($option)); 32022a62512bSSteven Rostedt 320323715c3cSSteven Rostedt return eval_option($option, $i); 32042a62512bSSteven Rostedt} 32052a62512bSSteven Rostedt 32062545eb61SSteven Rostedt# First we need to do is the builds 3207a75fececSSteven Rostedtfor (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) { 32082545eb61SSteven Rostedt 32094ab1cce5SSteven Rostedt # Do not reboot on failing test options 32104ab1cce5SSteven Rostedt $no_reboot = 1; 32114ab1cce5SSteven Rostedt 3212576f627cSSteven Rostedt $iteration = $i; 3213576f627cSSteven Rostedt 3214a75fececSSteven Rostedt my $makecmd = set_test_option("MAKE_CMD", $i); 3215a75fececSSteven Rostedt 3216a75fececSSteven Rostedt $machine = set_test_option("MACHINE", $i); 3217e48c5293SSteven Rostedt $ssh_user = set_test_option("SSH_USER", $i); 3218a75fececSSteven Rostedt $tmpdir = set_test_option("TMP_DIR", $i); 3219a75fececSSteven Rostedt $outputdir = set_test_option("OUTPUT_DIR", $i); 3220a75fececSSteven Rostedt $builddir = set_test_option("BUILD_DIR", $i); 3221a75fececSSteven Rostedt $test_type = set_test_option("TEST_TYPE", $i); 3222a75fececSSteven Rostedt $build_type = set_test_option("BUILD_TYPE", $i); 3223a75fececSSteven Rostedt $build_options = set_test_option("BUILD_OPTIONS", $i); 32240bd6c1a3SSteven Rostedt $pre_build = set_test_option("PRE_BUILD", $i); 32250bd6c1a3SSteven Rostedt $post_build = set_test_option("POST_BUILD", $i); 32260bd6c1a3SSteven Rostedt $pre_build_die = set_test_option("PRE_BUILD_DIE", $i); 32270bd6c1a3SSteven Rostedt $post_build_die = set_test_option("POST_BUILD_DIE", $i); 3228a75fececSSteven Rostedt $power_cycle = set_test_option("POWER_CYCLE", $i); 3229e48c5293SSteven Rostedt $reboot = set_test_option("REBOOT", $i); 3230a75fececSSteven Rostedt $noclean = set_test_option("BUILD_NOCLEAN", $i); 3231a75fececSSteven Rostedt $minconfig = set_test_option("MIN_CONFIG", $i); 32324c4ab120SSteven Rostedt $output_minconfig = set_test_option("OUTPUT_MIN_CONFIG", $i); 32334c4ab120SSteven Rostedt $start_minconfig = set_test_option("START_MIN_CONFIG", $i); 32344c4ab120SSteven Rostedt $ignore_config = set_test_option("IGNORE_CONFIG", $i); 3235a75fececSSteven Rostedt $run_test = set_test_option("TEST", $i); 3236a75fececSSteven Rostedt $addconfig = set_test_option("ADD_CONFIG", $i); 3237a75fececSSteven Rostedt $reboot_type = set_test_option("REBOOT_TYPE", $i); 3238a75fececSSteven Rostedt $grub_menu = set_test_option("GRUB_MENU", $i); 32398b37ca8cSSteven Rostedt $post_install = set_test_option("POST_INSTALL", $i); 3240e0a8742eSSteven Rostedt $no_install = set_test_option("NO_INSTALL", $i); 3241a75fececSSteven Rostedt $reboot_script = set_test_option("REBOOT_SCRIPT", $i); 3242a75fececSSteven Rostedt $reboot_on_error = set_test_option("REBOOT_ON_ERROR", $i); 3243a75fececSSteven Rostedt $poweroff_on_error = set_test_option("POWEROFF_ON_ERROR", $i); 3244a75fececSSteven Rostedt $die_on_failure = set_test_option("DIE_ON_FAILURE", $i); 3245a75fececSSteven Rostedt $power_off = set_test_option("POWER_OFF", $i); 3246576f627cSSteven Rostedt $powercycle_after_reboot = set_test_option("POWERCYCLE_AFTER_REBOOT", $i); 3247576f627cSSteven Rostedt $poweroff_after_halt = set_test_option("POWEROFF_AFTER_HALT", $i); 3248a75fececSSteven Rostedt $sleep_time = set_test_option("SLEEP_TIME", $i); 3249a75fececSSteven Rostedt $bisect_sleep_time = set_test_option("BISECT_SLEEP_TIME", $i); 325027d934b2SSteven Rostedt $patchcheck_sleep_time = set_test_option("PATCHCHECK_SLEEP_TIME", $i); 32511990207dSSteven Rostedt $ignore_warnings = set_test_option("IGNORE_WARNINGS", $i); 3252c960bb9fSSteven Rostedt $bisect_manual = set_test_option("BISECT_MANUAL", $i); 3253c23dca7cSSteven Rostedt $bisect_skip = set_test_option("BISECT_SKIP", $i); 325430f75da5SSteven Rostedt $config_bisect_good = set_test_option("CONFIG_BISECT_GOOD", $i); 3255a75fececSSteven Rostedt $store_failures = set_test_option("STORE_FAILURES", $i); 3256de5b6e3bSRabin Vincent $store_successes = set_test_option("STORE_SUCCESSES", $i); 32579064af52SSteven Rostedt $test_name = set_test_option("TEST_NAME", $i); 3258a75fececSSteven Rostedt $timeout = set_test_option("TIMEOUT", $i); 3259a75fececSSteven Rostedt $booted_timeout = set_test_option("BOOTED_TIMEOUT", $i); 3260a75fececSSteven Rostedt $console = set_test_option("CONSOLE", $i); 3261f1a5b962SSteven Rostedt $detect_triplefault = set_test_option("DETECT_TRIPLE_FAULT", $i); 3262a75fececSSteven Rostedt $success_line = set_test_option("SUCCESS_LINE", $i); 32632b803365SSteven Rostedt $reboot_success_line = set_test_option("REBOOT_SUCCESS_LINE", $i); 32641c8a617aSSteven Rostedt $stop_after_success = set_test_option("STOP_AFTER_SUCCESS", $i); 32651c8a617aSSteven Rostedt $stop_after_failure = set_test_option("STOP_AFTER_FAILURE", $i); 32662d01b26aSSteven Rostedt $stop_test_after = set_test_option("STOP_TEST_AFTER", $i); 3267a75fececSSteven Rostedt $build_target = set_test_option("BUILD_TARGET", $i); 3268e48c5293SSteven Rostedt $ssh_exec = set_test_option("SSH_EXEC", $i); 3269e48c5293SSteven Rostedt $scp_to_target = set_test_option("SCP_TO_TARGET", $i); 3270a75fececSSteven Rostedt $target_image = set_test_option("TARGET_IMAGE", $i); 3271a75fececSSteven Rostedt $localversion = set_test_option("LOCALVERSION", $i); 3272a75fececSSteven Rostedt 327335ce5952SSteven Rostedt $start_minconfig_defined = 1; 327435ce5952SSteven Rostedt 32754c4ab120SSteven Rostedt if (!defined($start_minconfig)) { 327635ce5952SSteven Rostedt $start_minconfig_defined = 0; 32774c4ab120SSteven Rostedt $start_minconfig = $minconfig; 32784c4ab120SSteven Rostedt } 32794c4ab120SSteven Rostedt 3280a75fececSSteven Rostedt chdir $builddir || die "can't change directory to $builddir"; 3281a75fececSSteven Rostedt 3282a908a665SAndrew Jones foreach my $dir ($tmpdir, $outputdir) { 3283a908a665SAndrew Jones if (!-d $dir) { 3284a908a665SAndrew Jones mkpath($dir) or 3285a908a665SAndrew Jones die "can't create $dir"; 3286a908a665SAndrew Jones } 3287a75fececSSteven Rostedt } 3288a75fececSSteven Rostedt 3289e48c5293SSteven Rostedt $ENV{"SSH_USER"} = $ssh_user; 3290e48c5293SSteven Rostedt $ENV{"MACHINE"} = $machine; 3291e48c5293SSteven Rostedt 3292a75fececSSteven Rostedt $buildlog = "$tmpdir/buildlog-$machine"; 3293a9dd5d63SRabin Vincent $testlog = "$tmpdir/testlog-$machine"; 3294a75fececSSteven Rostedt $dmesg = "$tmpdir/dmesg-$machine"; 3295a75fececSSteven Rostedt $make = "$makecmd O=$outputdir"; 329651ad1dd1SSteven Rostedt $output_config = "$outputdir/.config"; 3297a75fececSSteven Rostedt 3298*bb8474b1SSteven Rostedt if (!$buildonly) { 3299*bb8474b1SSteven Rostedt $target = "$ssh_user\@$machine"; 3300a75fececSSteven Rostedt if ($reboot_type eq "grub") { 3301576f627cSSteven Rostedt dodie "GRUB_MENU not defined" if (!defined($grub_menu)); 3302a75fececSSteven Rostedt } elsif (!defined($reboot_script)) { 3303576f627cSSteven Rostedt dodie "REBOOT_SCRIPT not defined" 3304a75fececSSteven Rostedt } 3305*bb8474b1SSteven Rostedt } 3306a75fececSSteven Rostedt 3307a75fececSSteven Rostedt my $run_type = $build_type; 3308a75fececSSteven Rostedt if ($test_type eq "patchcheck") { 3309a75fececSSteven Rostedt $run_type = $opt{"PATCHCHECK_TYPE[$i]"}; 3310a75fececSSteven Rostedt } elsif ($test_type eq "bisect") { 3311a75fececSSteven Rostedt $run_type = $opt{"BISECT_TYPE[$i]"}; 33120a05c769SSteven Rostedt } elsif ($test_type eq "config_bisect") { 33130a05c769SSteven Rostedt $run_type = $opt{"CONFIG_BISECT_TYPE[$i]"}; 3314a75fececSSteven Rostedt } 3315a75fececSSteven Rostedt 33164c4ab120SSteven Rostedt if ($test_type eq "make_min_config") { 33174c4ab120SSteven Rostedt $run_type = ""; 33184c4ab120SSteven Rostedt } 33194c4ab120SSteven Rostedt 3320a75fececSSteven Rostedt # mistake in config file? 3321a75fececSSteven Rostedt if (!defined($run_type)) { 3322a75fececSSteven Rostedt $run_type = "ERROR"; 3323a75fececSSteven Rostedt } 33242545eb61SSteven Rostedt 3325e0a8742eSSteven Rostedt my $installme = ""; 3326e0a8742eSSteven Rostedt $installme = " no_install" if ($no_install); 3327e0a8742eSSteven Rostedt 33282545eb61SSteven Rostedt doprint "\n\n"; 3329e0a8742eSSteven Rostedt doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type$installme\n\n"; 33307faafbd6SSteven Rostedt 33317faafbd6SSteven Rostedt unlink $dmesg; 33327faafbd6SSteven Rostedt unlink $buildlog; 3333a9dd5d63SRabin Vincent unlink $testlog; 33342545eb61SSteven Rostedt 3335250bae8bSSteven Rostedt if (defined($addconfig)) { 3336250bae8bSSteven Rostedt my $min = $minconfig; 33372b7d9b21SSteven Rostedt if (!defined($minconfig)) { 3338250bae8bSSteven Rostedt $min = ""; 3339250bae8bSSteven Rostedt } 3340250bae8bSSteven Rostedt run_command "cat $addconfig $min > $tmpdir/add_config" or 33412b7d9b21SSteven Rostedt dodie "Failed to create temp config"; 33429be2e6b5SSteven Rostedt $minconfig = "$tmpdir/add_config"; 33432b7d9b21SSteven Rostedt } 33442b7d9b21SSteven Rostedt 33456c5ee0beSSteven Rostedt my $checkout = $opt{"CHECKOUT[$i]"}; 33466c5ee0beSSteven Rostedt if (defined($checkout)) { 33476c5ee0beSSteven Rostedt run_command "git checkout $checkout" or 33486c5ee0beSSteven Rostedt die "failed to checkout $checkout"; 33496c5ee0beSSteven Rostedt } 33506c5ee0beSSteven Rostedt 33514ab1cce5SSteven Rostedt $no_reboot = 0; 33524ab1cce5SSteven Rostedt 33534ab1cce5SSteven Rostedt 3354a75fececSSteven Rostedt if ($test_type eq "bisect") { 33555f9b6cedSSteven Rostedt bisect $i; 33565f9b6cedSSteven Rostedt next; 33570a05c769SSteven Rostedt } elsif ($test_type eq "config_bisect") { 33580a05c769SSteven Rostedt config_bisect $i; 33590a05c769SSteven Rostedt next; 3360a75fececSSteven Rostedt } elsif ($test_type eq "patchcheck") { 33616c5ee0beSSteven Rostedt patchcheck $i; 33626c5ee0beSSteven Rostedt next; 33634c4ab120SSteven Rostedt } elsif ($test_type eq "make_min_config") { 33644c4ab120SSteven Rostedt make_min_config $i; 33654c4ab120SSteven Rostedt next; 33665f9b6cedSSteven Rostedt } 33675f9b6cedSSteven Rostedt 33687faafbd6SSteven Rostedt if ($build_type ne "nobuild") { 33697faafbd6SSteven Rostedt build $build_type or next; 33702545eb61SSteven Rostedt } 33712545eb61SSteven Rostedt 3372cd8e368fSSteven Rostedt if ($test_type eq "install") { 3373cd8e368fSSteven Rostedt get_version; 3374cd8e368fSSteven Rostedt install; 3375cd8e368fSSteven Rostedt success $i; 3376cd8e368fSSteven Rostedt next; 3377cd8e368fSSteven Rostedt } 3378cd8e368fSSteven Rostedt 3379a75fececSSteven Rostedt if ($test_type ne "build") { 33807faafbd6SSteven Rostedt my $failed = 0; 3381ddf607e5SSteven Rostedt start_monitor_and_boot or $failed = 1; 3382a75fececSSteven Rostedt 3383a75fececSSteven Rostedt if (!$failed && $test_type ne "boot" && defined($run_test)) { 33847faafbd6SSteven Rostedt do_run_test or $failed = 1; 33855a391fbfSSteven Rostedt } 33867faafbd6SSteven Rostedt end_monitor; 33877faafbd6SSteven Rostedt next if ($failed); 3388a75fececSSteven Rostedt } 33895a391fbfSSteven Rostedt 33905f9b6cedSSteven Rostedt success $i; 339175c3fda7SSteven Rostedt} 33922545eb61SSteven Rostedt 33935c42fc5bSSteven Rostedtif ($opt{"POWEROFF_ON_SUCCESS"}) { 339475c3fda7SSteven Rostedt halt; 3395576f627cSSteven Rostedt} elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot) { 339675c3fda7SSteven Rostedt reboot; 33975c42fc5bSSteven Rostedt} 339875c3fda7SSteven Rostedt 3399e48c5293SSteven Rostedtdoprint "\n $successes of $opt{NUM_TESTS} tests were successful\n\n"; 3400e48c5293SSteven Rostedt 34012545eb61SSteven Rostedtexit 0; 3402