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; 212545eb61SSteven Rostedt 222545eb61SSteven Rostedt#default opts 234f43e0dcSSteven Rostedtmy %default = ( 244f43e0dcSSteven Rostedt "NUM_TESTS" => 1, 254f43e0dcSSteven Rostedt "TEST_TYPE" => "build", 264f43e0dcSSteven Rostedt "BUILD_TYPE" => "randconfig", 274f43e0dcSSteven Rostedt "MAKE_CMD" => "make", 284f43e0dcSSteven Rostedt "TIMEOUT" => 120, 294f43e0dcSSteven Rostedt "TMP_DIR" => "/tmp/ktest/\${MACHINE}", 304f43e0dcSSteven Rostedt "SLEEP_TIME" => 60, # sleep time between tests 314f43e0dcSSteven Rostedt "BUILD_NOCLEAN" => 0, 324f43e0dcSSteven Rostedt "REBOOT_ON_ERROR" => 0, 334f43e0dcSSteven Rostedt "POWEROFF_ON_ERROR" => 0, 344f43e0dcSSteven Rostedt "REBOOT_ON_SUCCESS" => 1, 354f43e0dcSSteven Rostedt "POWEROFF_ON_SUCCESS" => 0, 364f43e0dcSSteven Rostedt "BUILD_OPTIONS" => "", 374f43e0dcSSteven Rostedt "BISECT_SLEEP_TIME" => 60, # sleep time between bisects 384f43e0dcSSteven Rostedt "PATCHCHECK_SLEEP_TIME" => 60, # sleep time between patch checks 394f43e0dcSSteven Rostedt "CLEAR_LOG" => 0, 404f43e0dcSSteven Rostedt "BISECT_MANUAL" => 0, 414f43e0dcSSteven Rostedt "BISECT_SKIP" => 1, 42ccc513b6SSteven Rostedt "MIN_CONFIG_TYPE" => "boot", 434f43e0dcSSteven Rostedt "SUCCESS_LINE" => "login:", 444f43e0dcSSteven Rostedt "DETECT_TRIPLE_FAULT" => 1, 454f43e0dcSSteven Rostedt "NO_INSTALL" => 0, 464f43e0dcSSteven Rostedt "BOOTED_TIMEOUT" => 1, 474f43e0dcSSteven Rostedt "DIE_ON_FAILURE" => 1, 484f43e0dcSSteven Rostedt "SSH_EXEC" => "ssh \$SSH_USER\@\$MACHINE \$SSH_COMMAND", 494f43e0dcSSteven Rostedt "SCP_TO_TARGET" => "scp \$SRC_FILE \$SSH_USER\@\$MACHINE:\$DST_FILE", 5002ad2617SSteven Rostedt "SCP_TO_TARGET_INSTALL" => "\${SCP_TO_TARGET}", 514f43e0dcSSteven Rostedt "REBOOT" => "ssh \$SSH_USER\@\$MACHINE reboot", 524f43e0dcSSteven Rostedt "STOP_AFTER_SUCCESS" => 10, 534f43e0dcSSteven Rostedt "STOP_AFTER_FAILURE" => 60, 544f43e0dcSSteven Rostedt "STOP_TEST_AFTER" => 600, 55600bbf0aSSteven Rostedt 56600bbf0aSSteven Rostedt# required, and we will ask users if they don't have them but we keep the default 57600bbf0aSSteven Rostedt# value something that is common. 584f43e0dcSSteven Rostedt "REBOOT_TYPE" => "grub", 594f43e0dcSSteven Rostedt "LOCALVERSION" => "-test", 604f43e0dcSSteven Rostedt "SSH_USER" => "root", 614f43e0dcSSteven Rostedt "BUILD_TARGET" => "arch/x86/boot/bzImage", 624f43e0dcSSteven Rostedt "TARGET_IMAGE" => "/boot/vmlinuz-test", 639cc9e091SSteven Rostedt 649cc9e091SSteven Rostedt "LOG_FILE" => undef, 659cc9e091SSteven Rostedt "IGNORE_UNUSED" => 0, 664f43e0dcSSteven Rostedt); 672545eb61SSteven Rostedt 688d1491baSSteven Rostedtmy $ktest_config; 692545eb61SSteven Rostedtmy $version; 70683a3e64SSteven Rostedtmy $have_version = 0; 71a75fececSSteven Rostedtmy $machine; 72e48c5293SSteven Rostedtmy $ssh_user; 73a75fececSSteven Rostedtmy $tmpdir; 74a75fececSSteven Rostedtmy $builddir; 75a75fececSSteven Rostedtmy $outputdir; 7651ad1dd1SSteven Rostedtmy $output_config; 77a75fececSSteven Rostedtmy $test_type; 787faafbd6SSteven Rostedtmy $build_type; 79a75fececSSteven Rostedtmy $build_options; 80921ed4c7SSteven Rostedtmy $final_post_ktest; 81921ed4c7SSteven Rostedtmy $pre_ktest; 82921ed4c7SSteven Rostedtmy $post_ktest; 83921ed4c7SSteven Rostedtmy $pre_test; 84921ed4c7SSteven Rostedtmy $post_test; 850bd6c1a3SSteven Rostedtmy $pre_build; 860bd6c1a3SSteven Rostedtmy $post_build; 870bd6c1a3SSteven Rostedtmy $pre_build_die; 880bd6c1a3SSteven Rostedtmy $post_build_die; 89a75fececSSteven Rostedtmy $reboot_type; 90a75fececSSteven Rostedtmy $reboot_script; 91a75fececSSteven Rostedtmy $power_cycle; 92e48c5293SSteven Rostedtmy $reboot; 93a75fececSSteven Rostedtmy $reboot_on_error; 94bc7c5803SSteven Rostedtmy $switch_to_good; 95bc7c5803SSteven Rostedtmy $switch_to_test; 96a75fececSSteven Rostedtmy $poweroff_on_error; 97648a182cSSteven Rostedtmy $reboot_on_success; 98a75fececSSteven Rostedtmy $die_on_failure; 99576f627cSSteven Rostedtmy $powercycle_after_reboot; 100576f627cSSteven Rostedtmy $poweroff_after_halt; 101e48c5293SSteven Rostedtmy $ssh_exec; 102e48c5293SSteven Rostedtmy $scp_to_target; 10302ad2617SSteven Rostedtmy $scp_to_target_install; 104a75fececSSteven Rostedtmy $power_off; 105a75fececSSteven Rostedtmy $grub_menu; 1062545eb61SSteven Rostedtmy $grub_number; 1072545eb61SSteven Rostedtmy $target; 1082545eb61SSteven Rostedtmy $make; 109e5c2ec11SSteven Rostedtmy $pre_install; 1108b37ca8cSSteven Rostedtmy $post_install; 111e0a8742eSSteven Rostedtmy $no_install; 1125c42fc5bSSteven Rostedtmy $noclean; 1135f9b6cedSSteven Rostedtmy $minconfig; 1144c4ab120SSteven Rostedtmy $start_minconfig; 11535ce5952SSteven Rostedtmy $start_minconfig_defined; 1164c4ab120SSteven Rostedtmy $output_minconfig; 117ccc513b6SSteven Rostedtmy $minconfig_type; 11843de3316SSteven Rostedtmy $use_output_minconfig; 1194c4ab120SSteven Rostedtmy $ignore_config; 120be405f95SSteven Rostedtmy $ignore_errors; 1212b7d9b21SSteven Rostedtmy $addconfig; 1225f9b6cedSSteven Rostedtmy $in_bisect = 0; 123b5f4aea6SSteven Rostedtmy $bisect_bad_commit = ""; 124d6ce2a0bSSteven Rostedtmy $reverse_bisect; 125c960bb9fSSteven Rostedtmy $bisect_manual; 126c23dca7cSSteven Rostedtmy $bisect_skip; 12730f75da5SSteven Rostedtmy $config_bisect_good; 128c5dacb88SSteven Rostedtmy $bisect_ret_good; 129c5dacb88SSteven Rostedtmy $bisect_ret_bad; 130c5dacb88SSteven Rostedtmy $bisect_ret_skip; 131c5dacb88SSteven Rostedtmy $bisect_ret_abort; 132c5dacb88SSteven Rostedtmy $bisect_ret_default; 1336c5ee0beSSteven Rostedtmy $in_patchcheck = 0; 1345a391fbfSSteven Rostedtmy $run_test; 1356c5ee0beSSteven Rostedtmy $redirect; 1367faafbd6SSteven Rostedtmy $buildlog; 137a9dd5d63SRabin Vincentmy $testlog; 1387faafbd6SSteven Rostedtmy $dmesg; 1397faafbd6SSteven Rostedtmy $monitor_fp; 1407faafbd6SSteven Rostedtmy $monitor_pid; 1417faafbd6SSteven Rostedtmy $monitor_cnt = 0; 142a75fececSSteven Rostedtmy $sleep_time; 143a75fececSSteven Rostedtmy $bisect_sleep_time; 14427d934b2SSteven Rostedtmy $patchcheck_sleep_time; 1451990207dSSteven Rostedtmy $ignore_warnings; 146a75fececSSteven Rostedtmy $store_failures; 147de5b6e3bSRabin Vincentmy $store_successes; 1489064af52SSteven Rostedtmy $test_name; 149a75fececSSteven Rostedtmy $timeout; 150a75fececSSteven Rostedtmy $booted_timeout; 151f1a5b962SSteven Rostedtmy $detect_triplefault; 152a75fececSSteven Rostedtmy $console; 1532b803365SSteven Rostedtmy $reboot_success_line; 154a75fececSSteven Rostedtmy $success_line; 1551c8a617aSSteven Rostedtmy $stop_after_success; 1561c8a617aSSteven Rostedtmy $stop_after_failure; 1572d01b26aSSteven Rostedtmy $stop_test_after; 158a75fececSSteven Rostedtmy $build_target; 159a75fececSSteven Rostedtmy $target_image; 160b5f4aea6SSteven Rostedtmy $checkout; 161a75fececSSteven Rostedtmy $localversion; 162576f627cSSteven Rostedtmy $iteration = 0; 163e48c5293SSteven Rostedtmy $successes = 0; 1642545eb61SSteven Rostedt 165b5f4aea6SSteven Rostedtmy $bisect_good; 166b5f4aea6SSteven Rostedtmy $bisect_bad; 167b5f4aea6SSteven Rostedtmy $bisect_type; 168b5f4aea6SSteven Rostedtmy $bisect_start; 169b5f4aea6SSteven Rostedtmy $bisect_replay; 170b5f4aea6SSteven Rostedtmy $bisect_files; 171b5f4aea6SSteven Rostedtmy $bisect_reverse; 172b5f4aea6SSteven Rostedtmy $bisect_check; 173b5f4aea6SSteven Rostedt 174b5f4aea6SSteven Rostedtmy $config_bisect; 175b5f4aea6SSteven Rostedtmy $config_bisect_type; 176b0918612SSteven Rostedtmy $config_bisect_check; 177b5f4aea6SSteven Rostedt 178b5f4aea6SSteven Rostedtmy $patchcheck_type; 179b5f4aea6SSteven Rostedtmy $patchcheck_start; 180b5f4aea6SSteven Rostedtmy $patchcheck_end; 181b5f4aea6SSteven Rostedt 182165708b2SSteven Rostedt# set when a test is something other that just building or install 183bb8474b1SSteven Rostedt# which would require more options. 184bb8474b1SSteven Rostedtmy $buildonly = 1; 185bb8474b1SSteven Rostedt 186dbd3783bSSteven Rostedt# set when creating a new config 187dbd3783bSSteven Rostedtmy $newconfig = 0; 188dbd3783bSSteven Rostedt 1898d1491baSSteven Rostedtmy %entered_configs; 1908d1491baSSteven Rostedtmy %config_help; 19177d942ceSSteven Rostedtmy %variable; 192*cf79fab6SSteven Rostedt 193*cf79fab6SSteven Rostedt# force_config is the list of configs that we force enabled (or disabled) 194*cf79fab6SSteven Rostedt# in a .config file. The MIN_CONFIG and ADD_CONFIG configs. 195fcb3f16aSSteven Rostedtmy %force_config; 1968d1491baSSteven Rostedt 1974ab1cce5SSteven Rostedt# do not force reboots on config problems 1984ab1cce5SSteven Rostedtmy $no_reboot = 1; 1994ab1cce5SSteven Rostedt 200759a3cc6SSteven Rostedt# reboot on success 201759a3cc6SSteven Rostedtmy $reboot_success = 0; 202759a3cc6SSteven Rostedt 2039cc9e091SSteven Rostedtmy %option_map = ( 2049cc9e091SSteven Rostedt "MACHINE" => \$machine, 2059cc9e091SSteven Rostedt "SSH_USER" => \$ssh_user, 2069cc9e091SSteven Rostedt "TMP_DIR" => \$tmpdir, 2079cc9e091SSteven Rostedt "OUTPUT_DIR" => \$outputdir, 2089cc9e091SSteven Rostedt "BUILD_DIR" => \$builddir, 2099cc9e091SSteven Rostedt "TEST_TYPE" => \$test_type, 210921ed4c7SSteven Rostedt "PRE_KTEST" => \$pre_ktest, 211921ed4c7SSteven Rostedt "POST_KTEST" => \$post_ktest, 212921ed4c7SSteven Rostedt "PRE_TEST" => \$pre_test, 213921ed4c7SSteven Rostedt "POST_TEST" => \$post_test, 2149cc9e091SSteven Rostedt "BUILD_TYPE" => \$build_type, 2159cc9e091SSteven Rostedt "BUILD_OPTIONS" => \$build_options, 2169cc9e091SSteven Rostedt "PRE_BUILD" => \$pre_build, 2179cc9e091SSteven Rostedt "POST_BUILD" => \$post_build, 2189cc9e091SSteven Rostedt "PRE_BUILD_DIE" => \$pre_build_die, 2199cc9e091SSteven Rostedt "POST_BUILD_DIE" => \$post_build_die, 2209cc9e091SSteven Rostedt "POWER_CYCLE" => \$power_cycle, 2219cc9e091SSteven Rostedt "REBOOT" => \$reboot, 2229cc9e091SSteven Rostedt "BUILD_NOCLEAN" => \$noclean, 2239cc9e091SSteven Rostedt "MIN_CONFIG" => \$minconfig, 2249cc9e091SSteven Rostedt "OUTPUT_MIN_CONFIG" => \$output_minconfig, 2259cc9e091SSteven Rostedt "START_MIN_CONFIG" => \$start_minconfig, 226ccc513b6SSteven Rostedt "MIN_CONFIG_TYPE" => \$minconfig_type, 22743de3316SSteven Rostedt "USE_OUTPUT_MIN_CONFIG" => \$use_output_minconfig, 2289cc9e091SSteven Rostedt "IGNORE_CONFIG" => \$ignore_config, 2299cc9e091SSteven Rostedt "TEST" => \$run_test, 2309cc9e091SSteven Rostedt "ADD_CONFIG" => \$addconfig, 2319cc9e091SSteven Rostedt "REBOOT_TYPE" => \$reboot_type, 2329cc9e091SSteven Rostedt "GRUB_MENU" => \$grub_menu, 233e5c2ec11SSteven Rostedt "PRE_INSTALL" => \$pre_install, 2349cc9e091SSteven Rostedt "POST_INSTALL" => \$post_install, 2359cc9e091SSteven Rostedt "NO_INSTALL" => \$no_install, 2369cc9e091SSteven Rostedt "REBOOT_SCRIPT" => \$reboot_script, 2379cc9e091SSteven Rostedt "REBOOT_ON_ERROR" => \$reboot_on_error, 2389cc9e091SSteven Rostedt "SWITCH_TO_GOOD" => \$switch_to_good, 2399cc9e091SSteven Rostedt "SWITCH_TO_TEST" => \$switch_to_test, 2409cc9e091SSteven Rostedt "POWEROFF_ON_ERROR" => \$poweroff_on_error, 241648a182cSSteven Rostedt "REBOOT_ON_SUCCESS" => \$reboot_on_success, 2429cc9e091SSteven Rostedt "DIE_ON_FAILURE" => \$die_on_failure, 2439cc9e091SSteven Rostedt "POWER_OFF" => \$power_off, 2449cc9e091SSteven Rostedt "POWERCYCLE_AFTER_REBOOT" => \$powercycle_after_reboot, 2459cc9e091SSteven Rostedt "POWEROFF_AFTER_HALT" => \$poweroff_after_halt, 2469cc9e091SSteven Rostedt "SLEEP_TIME" => \$sleep_time, 2479cc9e091SSteven Rostedt "BISECT_SLEEP_TIME" => \$bisect_sleep_time, 2489cc9e091SSteven Rostedt "PATCHCHECK_SLEEP_TIME" => \$patchcheck_sleep_time, 2499cc9e091SSteven Rostedt "IGNORE_WARNINGS" => \$ignore_warnings, 250be405f95SSteven Rostedt "IGNORE_ERRORS" => \$ignore_errors, 2519cc9e091SSteven Rostedt "BISECT_MANUAL" => \$bisect_manual, 2529cc9e091SSteven Rostedt "BISECT_SKIP" => \$bisect_skip, 2539cc9e091SSteven Rostedt "CONFIG_BISECT_GOOD" => \$config_bisect_good, 2549cc9e091SSteven Rostedt "BISECT_RET_GOOD" => \$bisect_ret_good, 2559cc9e091SSteven Rostedt "BISECT_RET_BAD" => \$bisect_ret_bad, 2569cc9e091SSteven Rostedt "BISECT_RET_SKIP" => \$bisect_ret_skip, 2579cc9e091SSteven Rostedt "BISECT_RET_ABORT" => \$bisect_ret_abort, 2589cc9e091SSteven Rostedt "BISECT_RET_DEFAULT" => \$bisect_ret_default, 2599cc9e091SSteven Rostedt "STORE_FAILURES" => \$store_failures, 2609cc9e091SSteven Rostedt "STORE_SUCCESSES" => \$store_successes, 2619cc9e091SSteven Rostedt "TEST_NAME" => \$test_name, 2629cc9e091SSteven Rostedt "TIMEOUT" => \$timeout, 2639cc9e091SSteven Rostedt "BOOTED_TIMEOUT" => \$booted_timeout, 2649cc9e091SSteven Rostedt "CONSOLE" => \$console, 2659cc9e091SSteven Rostedt "DETECT_TRIPLE_FAULT" => \$detect_triplefault, 2669cc9e091SSteven Rostedt "SUCCESS_LINE" => \$success_line, 2679cc9e091SSteven Rostedt "REBOOT_SUCCESS_LINE" => \$reboot_success_line, 2689cc9e091SSteven Rostedt "STOP_AFTER_SUCCESS" => \$stop_after_success, 2699cc9e091SSteven Rostedt "STOP_AFTER_FAILURE" => \$stop_after_failure, 2709cc9e091SSteven Rostedt "STOP_TEST_AFTER" => \$stop_test_after, 2719cc9e091SSteven Rostedt "BUILD_TARGET" => \$build_target, 2729cc9e091SSteven Rostedt "SSH_EXEC" => \$ssh_exec, 2739cc9e091SSteven Rostedt "SCP_TO_TARGET" => \$scp_to_target, 27402ad2617SSteven Rostedt "SCP_TO_TARGET_INSTALL" => \$scp_to_target_install, 2759cc9e091SSteven Rostedt "CHECKOUT" => \$checkout, 2769cc9e091SSteven Rostedt "TARGET_IMAGE" => \$target_image, 2779cc9e091SSteven Rostedt "LOCALVERSION" => \$localversion, 2789cc9e091SSteven Rostedt 2799cc9e091SSteven Rostedt "BISECT_GOOD" => \$bisect_good, 2809cc9e091SSteven Rostedt "BISECT_BAD" => \$bisect_bad, 2819cc9e091SSteven Rostedt "BISECT_TYPE" => \$bisect_type, 2829cc9e091SSteven Rostedt "BISECT_START" => \$bisect_start, 2839cc9e091SSteven Rostedt "BISECT_REPLAY" => \$bisect_replay, 2849cc9e091SSteven Rostedt "BISECT_FILES" => \$bisect_files, 2859cc9e091SSteven Rostedt "BISECT_REVERSE" => \$bisect_reverse, 2869cc9e091SSteven Rostedt "BISECT_CHECK" => \$bisect_check, 2879cc9e091SSteven Rostedt 2889cc9e091SSteven Rostedt "CONFIG_BISECT" => \$config_bisect, 2899cc9e091SSteven Rostedt "CONFIG_BISECT_TYPE" => \$config_bisect_type, 290b0918612SSteven Rostedt "CONFIG_BISECT_CHECK" => \$config_bisect_check, 2919cc9e091SSteven Rostedt 2929cc9e091SSteven Rostedt "PATCHCHECK_TYPE" => \$patchcheck_type, 2939cc9e091SSteven Rostedt "PATCHCHECK_START" => \$patchcheck_start, 2949cc9e091SSteven Rostedt "PATCHCHECK_END" => \$patchcheck_end, 2959cc9e091SSteven Rostedt); 2969cc9e091SSteven Rostedt 2979cc9e091SSteven Rostedt# Options may be used by other options, record them. 2989cc9e091SSteven Rostedtmy %used_options; 2999cc9e091SSteven Rostedt 3007bf51073SSteven Rostedt# default variables that can be used 3017bf51073SSteven Rostedtchomp ($variable{"PWD"} = `pwd`); 3027bf51073SSteven Rostedt 3038d1491baSSteven Rostedt$config_help{"MACHINE"} = << "EOF" 3048d1491baSSteven Rostedt The machine hostname that you will test. 305bb8474b1SSteven Rostedt For build only tests, it is still needed to differentiate log files. 3068d1491baSSteven RostedtEOF 3078d1491baSSteven Rostedt ; 3088d1491baSSteven Rostedt$config_help{"SSH_USER"} = << "EOF" 3098d1491baSSteven Rostedt The box is expected to have ssh on normal bootup, provide the user 3108d1491baSSteven Rostedt (most likely root, since you need privileged operations) 3118d1491baSSteven RostedtEOF 3128d1491baSSteven Rostedt ; 3138d1491baSSteven Rostedt$config_help{"BUILD_DIR"} = << "EOF" 3148d1491baSSteven Rostedt The directory that contains the Linux source code (full path). 3150e7a22deSSteven Rostedt You can use \${PWD} that will be the path where ktest.pl is run, or use 3160e7a22deSSteven Rostedt \${THIS_DIR} which is assigned \${PWD} but may be changed later. 3178d1491baSSteven RostedtEOF 3188d1491baSSteven Rostedt ; 3198d1491baSSteven Rostedt$config_help{"OUTPUT_DIR"} = << "EOF" 3208d1491baSSteven Rostedt The directory that the objects will be built (full path). 3218d1491baSSteven Rostedt (can not be same as BUILD_DIR) 3220e7a22deSSteven Rostedt You can use \${PWD} that will be the path where ktest.pl is run, or use 3230e7a22deSSteven Rostedt \${THIS_DIR} which is assigned \${PWD} but may be changed later. 3248d1491baSSteven RostedtEOF 3258d1491baSSteven Rostedt ; 3268d1491baSSteven Rostedt$config_help{"BUILD_TARGET"} = << "EOF" 3278d1491baSSteven Rostedt The location of the compiled file to copy to the target. 3288d1491baSSteven Rostedt (relative to OUTPUT_DIR) 3298d1491baSSteven RostedtEOF 3308d1491baSSteven Rostedt ; 331dbd3783bSSteven Rostedt$config_help{"BUILD_OPTIONS"} = << "EOF" 332dbd3783bSSteven Rostedt Options to add to \"make\" when building. 333dbd3783bSSteven Rostedt i.e. -j20 334dbd3783bSSteven RostedtEOF 335dbd3783bSSteven Rostedt ; 3368d1491baSSteven Rostedt$config_help{"TARGET_IMAGE"} = << "EOF" 3378d1491baSSteven Rostedt The place to put your image on the test machine. 3388d1491baSSteven RostedtEOF 3398d1491baSSteven Rostedt ; 3408d1491baSSteven Rostedt$config_help{"POWER_CYCLE"} = << "EOF" 3418d1491baSSteven Rostedt A script or command to reboot the box. 3428d1491baSSteven Rostedt 3438d1491baSSteven Rostedt Here is a digital loggers power switch example 3448d1491baSSteven Rostedt POWER_CYCLE = wget --no-proxy -O /dev/null -q --auth-no-challenge 'http://admin:admin\@power/outlet?5=CCL' 3458d1491baSSteven Rostedt 3468d1491baSSteven Rostedt Here is an example to reboot a virtual box on the current host 3478d1491baSSteven Rostedt with the name "Guest". 3488d1491baSSteven Rostedt POWER_CYCLE = virsh destroy Guest; sleep 5; virsh start Guest 3498d1491baSSteven RostedtEOF 3508d1491baSSteven Rostedt ; 3518d1491baSSteven Rostedt$config_help{"CONSOLE"} = << "EOF" 3528d1491baSSteven Rostedt The script or command that reads the console 3538d1491baSSteven Rostedt 3548d1491baSSteven Rostedt If you use ttywatch server, something like the following would work. 3558d1491baSSteven RostedtCONSOLE = nc -d localhost 3001 3568d1491baSSteven Rostedt 3578d1491baSSteven Rostedt For a virtual machine with guest name "Guest". 3588d1491baSSteven RostedtCONSOLE = virsh console Guest 3598d1491baSSteven RostedtEOF 3608d1491baSSteven Rostedt ; 3618d1491baSSteven Rostedt$config_help{"LOCALVERSION"} = << "EOF" 3628d1491baSSteven Rostedt Required version ending to differentiate the test 3638d1491baSSteven Rostedt from other linux builds on the system. 3648d1491baSSteven RostedtEOF 3658d1491baSSteven Rostedt ; 3668d1491baSSteven Rostedt$config_help{"REBOOT_TYPE"} = << "EOF" 3678d1491baSSteven Rostedt Way to reboot the box to the test kernel. 3688d1491baSSteven Rostedt Only valid options so far are "grub" and "script". 3698d1491baSSteven Rostedt 3708d1491baSSteven Rostedt If you specify grub, it will assume grub version 1 3718d1491baSSteven Rostedt and will search in /boot/grub/menu.lst for the title \$GRUB_MENU 3728d1491baSSteven Rostedt and select that target to reboot to the kernel. If this is not 3738d1491baSSteven Rostedt your setup, then specify "script" and have a command or script 3748d1491baSSteven Rostedt specified in REBOOT_SCRIPT to boot to the target. 3758d1491baSSteven Rostedt 3768d1491baSSteven Rostedt The entry in /boot/grub/menu.lst must be entered in manually. 3778d1491baSSteven Rostedt The test will not modify that file. 3788d1491baSSteven RostedtEOF 3798d1491baSSteven Rostedt ; 3808d1491baSSteven Rostedt$config_help{"GRUB_MENU"} = << "EOF" 3818d1491baSSteven Rostedt The grub title name for the test kernel to boot 3828d1491baSSteven Rostedt (Only mandatory if REBOOT_TYPE = grub) 3838d1491baSSteven Rostedt 3848d1491baSSteven Rostedt Note, ktest.pl will not update the grub menu.lst, you need to 3858d1491baSSteven Rostedt manually add an option for the test. ktest.pl will search 3868d1491baSSteven Rostedt the grub menu.lst for this option to find what kernel to 3878d1491baSSteven Rostedt reboot into. 3888d1491baSSteven Rostedt 3898d1491baSSteven Rostedt For example, if in the /boot/grub/menu.lst the test kernel title has: 3908d1491baSSteven Rostedt title Test Kernel 3918d1491baSSteven Rostedt kernel vmlinuz-test 3928d1491baSSteven Rostedt GRUB_MENU = Test Kernel 3938d1491baSSteven RostedtEOF 3948d1491baSSteven Rostedt ; 3958d1491baSSteven Rostedt$config_help{"REBOOT_SCRIPT"} = << "EOF" 3968d1491baSSteven Rostedt A script to reboot the target into the test kernel 3978d1491baSSteven Rostedt (Only mandatory if REBOOT_TYPE = script) 3988d1491baSSteven RostedtEOF 3998d1491baSSteven Rostedt ; 4008d1491baSSteven Rostedt 401dad98754SSteven Rostedtsub read_prompt { 402dad98754SSteven Rostedt my ($cancel, $prompt) = @_; 40335ce5952SSteven Rostedt 40435ce5952SSteven Rostedt my $ans; 40535ce5952SSteven Rostedt 40635ce5952SSteven Rostedt for (;;) { 407dad98754SSteven Rostedt if ($cancel) { 408dad98754SSteven Rostedt print "$prompt [y/n/C] "; 409dad98754SSteven Rostedt } else { 41035ce5952SSteven Rostedt print "$prompt [Y/n] "; 411dad98754SSteven Rostedt } 41235ce5952SSteven Rostedt $ans = <STDIN>; 41335ce5952SSteven Rostedt chomp $ans; 41435ce5952SSteven Rostedt if ($ans =~ /^\s*$/) { 415dad98754SSteven Rostedt if ($cancel) { 416dad98754SSteven Rostedt $ans = "c"; 417dad98754SSteven Rostedt } else { 41835ce5952SSteven Rostedt $ans = "y"; 41935ce5952SSteven Rostedt } 420dad98754SSteven Rostedt } 42135ce5952SSteven Rostedt last if ($ans =~ /^y$/i || $ans =~ /^n$/i); 422dad98754SSteven Rostedt if ($cancel) { 423dad98754SSteven Rostedt last if ($ans =~ /^c$/i); 424dad98754SSteven Rostedt print "Please answer either 'y', 'n' or 'c'.\n"; 425dad98754SSteven Rostedt } else { 42635ce5952SSteven Rostedt print "Please answer either 'y' or 'n'.\n"; 42735ce5952SSteven Rostedt } 428dad98754SSteven Rostedt } 429dad98754SSteven Rostedt if ($ans =~ /^c/i) { 430dad98754SSteven Rostedt exit; 431dad98754SSteven Rostedt } 43235ce5952SSteven Rostedt if ($ans !~ /^y$/i) { 43335ce5952SSteven Rostedt return 0; 43435ce5952SSteven Rostedt } 43535ce5952SSteven Rostedt return 1; 43635ce5952SSteven Rostedt} 4378d1491baSSteven Rostedt 438dad98754SSteven Rostedtsub read_yn { 439dad98754SSteven Rostedt my ($prompt) = @_; 440dad98754SSteven Rostedt 441dad98754SSteven Rostedt return read_prompt 0, $prompt; 442dad98754SSteven Rostedt} 443dad98754SSteven Rostedt 444dad98754SSteven Rostedtsub read_ync { 445dad98754SSteven Rostedt my ($prompt) = @_; 446dad98754SSteven Rostedt 447dad98754SSteven Rostedt return read_prompt 1, $prompt; 448dad98754SSteven Rostedt} 449dad98754SSteven Rostedt 4508d1491baSSteven Rostedtsub get_ktest_config { 4518d1491baSSteven Rostedt my ($config) = @_; 452815e2bd7SSteven Rostedt my $ans; 4538d1491baSSteven Rostedt 4548d1491baSSteven Rostedt return if (defined($opt{$config})); 4558d1491baSSteven Rostedt 4568d1491baSSteven Rostedt if (defined($config_help{$config})) { 4578d1491baSSteven Rostedt print "\n"; 4588d1491baSSteven Rostedt print $config_help{$config}; 4598d1491baSSteven Rostedt } 4608d1491baSSteven Rostedt 4618d1491baSSteven Rostedt for (;;) { 4628d1491baSSteven Rostedt print "$config = "; 463dbd3783bSSteven Rostedt if (defined($default{$config}) && length($default{$config})) { 4648d1491baSSteven Rostedt print "\[$default{$config}\] "; 4658d1491baSSteven Rostedt } 466815e2bd7SSteven Rostedt $ans = <STDIN>; 467815e2bd7SSteven Rostedt $ans =~ s/^\s*(.*\S)\s*$/$1/; 468815e2bd7SSteven Rostedt if ($ans =~ /^\s*$/) { 4698d1491baSSteven Rostedt if ($default{$config}) { 470815e2bd7SSteven Rostedt $ans = $default{$config}; 4718d1491baSSteven Rostedt } else { 4728d1491baSSteven Rostedt print "Your answer can not be blank\n"; 4738d1491baSSteven Rostedt next; 4748d1491baSSteven Rostedt } 4758d1491baSSteven Rostedt } 4760e7a22deSSteven Rostedt $entered_configs{$config} = ${ans}; 4778d1491baSSteven Rostedt last; 4788d1491baSSteven Rostedt } 4798d1491baSSteven Rostedt} 4808d1491baSSteven Rostedt 4818d1491baSSteven Rostedtsub get_ktest_configs { 4828d1491baSSteven Rostedt get_ktest_config("MACHINE"); 4838d1491baSSteven Rostedt get_ktest_config("BUILD_DIR"); 4848d1491baSSteven Rostedt get_ktest_config("OUTPUT_DIR"); 485bb8474b1SSteven Rostedt 486dbd3783bSSteven Rostedt if ($newconfig) { 487dbd3783bSSteven Rostedt get_ktest_config("BUILD_OPTIONS"); 488dbd3783bSSteven Rostedt } 489dbd3783bSSteven Rostedt 490bb8474b1SSteven Rostedt # options required for other than just building a kernel 491bb8474b1SSteven Rostedt if (!$buildonly) { 492165708b2SSteven Rostedt get_ktest_config("POWER_CYCLE"); 493165708b2SSteven Rostedt get_ktest_config("CONSOLE"); 494165708b2SSteven Rostedt } 495165708b2SSteven Rostedt 496165708b2SSteven Rostedt # options required for install and more 497165708b2SSteven Rostedt if ($buildonly != 1) { 498bb8474b1SSteven Rostedt get_ktest_config("SSH_USER"); 4998d1491baSSteven Rostedt get_ktest_config("BUILD_TARGET"); 5008d1491baSSteven Rostedt get_ktest_config("TARGET_IMAGE"); 501bb8474b1SSteven Rostedt } 502bb8474b1SSteven Rostedt 5038d1491baSSteven Rostedt get_ktest_config("LOCALVERSION"); 5048d1491baSSteven Rostedt 505bb8474b1SSteven Rostedt return if ($buildonly); 506bb8474b1SSteven Rostedt 5078d1491baSSteven Rostedt my $rtype = $opt{"REBOOT_TYPE"}; 5088d1491baSSteven Rostedt 5098d1491baSSteven Rostedt if (!defined($rtype)) { 5108d1491baSSteven Rostedt if (!defined($opt{"GRUB_MENU"})) { 5118d1491baSSteven Rostedt get_ktest_config("REBOOT_TYPE"); 5128d1491baSSteven Rostedt $rtype = $entered_configs{"REBOOT_TYPE"}; 5138d1491baSSteven Rostedt } else { 5148d1491baSSteven Rostedt $rtype = "grub"; 5158d1491baSSteven Rostedt } 5168d1491baSSteven Rostedt } 5178d1491baSSteven Rostedt 5188d1491baSSteven Rostedt if ($rtype eq "grub") { 5198d1491baSSteven Rostedt get_ktest_config("GRUB_MENU"); 5208d1491baSSteven Rostedt } 5218d1491baSSteven Rostedt} 5228d1491baSSteven Rostedt 52377d942ceSSteven Rostedtsub process_variables { 5248d735212SSteven Rostedt my ($value, $remove_undef) = @_; 52577d942ceSSteven Rostedt my $retval = ""; 52677d942ceSSteven Rostedt 52777d942ceSSteven Rostedt # We want to check for '\', and it is just easier 52877d942ceSSteven Rostedt # to check the previous characet of '$' and not need 52977d942ceSSteven Rostedt # to worry if '$' is the first character. By adding 53077d942ceSSteven Rostedt # a space to $value, we can just check [^\\]\$ and 53177d942ceSSteven Rostedt # it will still work. 53277d942ceSSteven Rostedt $value = " $value"; 53377d942ceSSteven Rostedt 53477d942ceSSteven Rostedt while ($value =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) { 53577d942ceSSteven Rostedt my $begin = $1; 53677d942ceSSteven Rostedt my $var = $2; 53777d942ceSSteven Rostedt my $end = $3; 53877d942ceSSteven Rostedt # append beginning of value to retval 53977d942ceSSteven Rostedt $retval = "$retval$begin"; 54077d942ceSSteven Rostedt if (defined($variable{$var})) { 54177d942ceSSteven Rostedt $retval = "$retval$variable{$var}"; 5428d735212SSteven Rostedt } elsif (defined($remove_undef) && $remove_undef) { 5438d735212SSteven Rostedt # for if statements, any variable that is not defined, 5448d735212SSteven Rostedt # we simple convert to 0 5458d735212SSteven Rostedt $retval = "${retval}0"; 54677d942ceSSteven Rostedt } else { 54777d942ceSSteven Rostedt # put back the origin piece. 54877d942ceSSteven Rostedt $retval = "$retval\$\{$var\}"; 5499cc9e091SSteven Rostedt # This could be an option that is used later, save 5509cc9e091SSteven Rostedt # it so we don't warn if this option is not one of 5519cc9e091SSteven Rostedt # ktests options. 5529cc9e091SSteven Rostedt $used_options{$var} = 1; 55377d942ceSSteven Rostedt } 55477d942ceSSteven Rostedt $value = $end; 55577d942ceSSteven Rostedt } 55677d942ceSSteven Rostedt $retval = "$retval$value"; 55777d942ceSSteven Rostedt 55877d942ceSSteven Rostedt # remove the space added in the beginning 55977d942ceSSteven Rostedt $retval =~ s/ //; 56077d942ceSSteven Rostedt 56177d942ceSSteven Rostedt return "$retval" 56277d942ceSSteven Rostedt} 56377d942ceSSteven Rostedt 564a57419b3SSteven Rostedtsub set_value { 5653d1cc414SSteven Rostedt my ($lvalue, $rvalue, $override, $overrides, $name) = @_; 5662545eb61SSteven Rostedt 567cad96669SSteven Rostedt my $prvalue = process_variables($rvalue); 568cad96669SSteven Rostedt 569cad96669SSteven Rostedt if ($buildonly && $lvalue =~ /^TEST_TYPE(\[.*\])?$/ && $prvalue ne "build") { 570bb8474b1SSteven Rostedt # Note if a test is something other than build, then we 571bb8474b1SSteven Rostedt # will need other manditory options. 572cad96669SSteven Rostedt if ($prvalue ne "install") { 573bb8474b1SSteven Rostedt $buildonly = 0; 574165708b2SSteven Rostedt } else { 575165708b2SSteven Rostedt # install still limits some manditory options. 576165708b2SSteven Rostedt $buildonly = 2; 577165708b2SSteven Rostedt } 578bb8474b1SSteven Rostedt } 579bb8474b1SSteven Rostedt 580a75fececSSteven Rostedt if (defined($opt{$lvalue})) { 5813d1cc414SSteven Rostedt if (!$override || defined(${$overrides}{$lvalue})) { 5823d1cc414SSteven Rostedt my $extra = ""; 5833d1cc414SSteven Rostedt if ($override) { 5843d1cc414SSteven Rostedt $extra = "In the same override section!\n"; 5853d1cc414SSteven Rostedt } 5863d1cc414SSteven Rostedt die "$name: $.: Option $lvalue defined more than once!\n$extra"; 5873d1cc414SSteven Rostedt } 588cad96669SSteven Rostedt ${$overrides}{$lvalue} = $prvalue; 589a75fececSSteven Rostedt } 59021a9679fSSteven Rostedt if ($rvalue =~ /^\s*$/) { 59121a9679fSSteven Rostedt delete $opt{$lvalue}; 59221a9679fSSteven Rostedt } else { 593cad96669SSteven Rostedt $opt{$lvalue} = $prvalue; 59421a9679fSSteven Rostedt } 5952545eb61SSteven Rostedt} 596a57419b3SSteven Rostedt 59777d942ceSSteven Rostedtsub set_variable { 59877d942ceSSteven Rostedt my ($lvalue, $rvalue) = @_; 59977d942ceSSteven Rostedt 60077d942ceSSteven Rostedt if ($rvalue =~ /^\s*$/) { 60177d942ceSSteven Rostedt delete $variable{$lvalue}; 60277d942ceSSteven Rostedt } else { 60377d942ceSSteven Rostedt $rvalue = process_variables($rvalue); 60477d942ceSSteven Rostedt $variable{$lvalue} = $rvalue; 60577d942ceSSteven Rostedt } 60677d942ceSSteven Rostedt} 60777d942ceSSteven Rostedt 608ab7a3f52SSteven Rostedtsub process_compare { 609ab7a3f52SSteven Rostedt my ($lval, $cmp, $rval) = @_; 610ab7a3f52SSteven Rostedt 611ab7a3f52SSteven Rostedt # remove whitespace 612ab7a3f52SSteven Rostedt 613ab7a3f52SSteven Rostedt $lval =~ s/^\s*//; 614ab7a3f52SSteven Rostedt $lval =~ s/\s*$//; 615ab7a3f52SSteven Rostedt 616ab7a3f52SSteven Rostedt $rval =~ s/^\s*//; 617ab7a3f52SSteven Rostedt $rval =~ s/\s*$//; 618ab7a3f52SSteven Rostedt 619ab7a3f52SSteven Rostedt if ($cmp eq "==") { 620ab7a3f52SSteven Rostedt return $lval eq $rval; 621ab7a3f52SSteven Rostedt } elsif ($cmp eq "!=") { 622ab7a3f52SSteven Rostedt return $lval ne $rval; 623ab7a3f52SSteven Rostedt } 624ab7a3f52SSteven Rostedt 625ab7a3f52SSteven Rostedt my $statement = "$lval $cmp $rval"; 626ab7a3f52SSteven Rostedt my $ret = eval $statement; 627ab7a3f52SSteven Rostedt 628ab7a3f52SSteven Rostedt # $@ stores error of eval 629ab7a3f52SSteven Rostedt if ($@) { 630ab7a3f52SSteven Rostedt return -1; 631ab7a3f52SSteven Rostedt } 632ab7a3f52SSteven Rostedt 633ab7a3f52SSteven Rostedt return $ret; 634ab7a3f52SSteven Rostedt} 635ab7a3f52SSteven Rostedt 6369900b5dcSSteven Rostedtsub value_defined { 6379900b5dcSSteven Rostedt my ($val) = @_; 6389900b5dcSSteven Rostedt 6399900b5dcSSteven Rostedt return defined($variable{$2}) || 6409900b5dcSSteven Rostedt defined($opt{$2}); 6419900b5dcSSteven Rostedt} 6429900b5dcSSteven Rostedt 6438d735212SSteven Rostedtmy $d = 0; 6448d735212SSteven Rostedtsub process_expression { 6458d735212SSteven Rostedt my ($name, $val) = @_; 64645d73a5dSSteven Rostedt 6478d735212SSteven Rostedt my $c = $d++; 6488d735212SSteven Rostedt 6498d735212SSteven Rostedt while ($val =~ s/\(([^\(]*?)\)/\&\&\&\&VAL\&\&\&\&/) { 6508d735212SSteven Rostedt my $express = $1; 6518d735212SSteven Rostedt 6528d735212SSteven Rostedt if (process_expression($name, $express)) { 6538d735212SSteven Rostedt $val =~ s/\&\&\&\&VAL\&\&\&\&/ 1 /; 6548d735212SSteven Rostedt } else { 6558d735212SSteven Rostedt $val =~ s/\&\&\&\&VAL\&\&\&\&/ 0 /; 6568d735212SSteven Rostedt } 6578d735212SSteven Rostedt } 6588d735212SSteven Rostedt 6598d735212SSteven Rostedt $d--; 6608d735212SSteven Rostedt my $OR = "\\|\\|"; 6618d735212SSteven Rostedt my $AND = "\\&\\&"; 6628d735212SSteven Rostedt 6638d735212SSteven Rostedt while ($val =~ s/^(.*?)($OR|$AND)//) { 6648d735212SSteven Rostedt my $express = $1; 6658d735212SSteven Rostedt my $op = $2; 6668d735212SSteven Rostedt 6678d735212SSteven Rostedt if (process_expression($name, $express)) { 6688d735212SSteven Rostedt if ($op eq "||") { 6698d735212SSteven Rostedt return 1; 6708d735212SSteven Rostedt } 6718d735212SSteven Rostedt } else { 6728d735212SSteven Rostedt if ($op eq "&&") { 6738d735212SSteven Rostedt return 0; 6748d735212SSteven Rostedt } 6758d735212SSteven Rostedt } 6768d735212SSteven Rostedt } 67745d73a5dSSteven Rostedt 678ab7a3f52SSteven Rostedt if ($val =~ /(.*)(==|\!=|>=|<=|>|<)(.*)/) { 679ab7a3f52SSteven Rostedt my $ret = process_compare($1, $2, $3); 680ab7a3f52SSteven Rostedt if ($ret < 0) { 681ab7a3f52SSteven Rostedt die "$name: $.: Unable to process comparison\n"; 682ab7a3f52SSteven Rostedt } 683ab7a3f52SSteven Rostedt return $ret; 684ab7a3f52SSteven Rostedt } 685ab7a3f52SSteven Rostedt 6869900b5dcSSteven Rostedt if ($val =~ /^\s*(NOT\s*)?DEFINED\s+(\S+)\s*$/) { 6879900b5dcSSteven Rostedt if (defined $1) { 6889900b5dcSSteven Rostedt return !value_defined($2); 6899900b5dcSSteven Rostedt } else { 6909900b5dcSSteven Rostedt return value_defined($2); 6919900b5dcSSteven Rostedt } 6929900b5dcSSteven Rostedt } 6939900b5dcSSteven Rostedt 69445d73a5dSSteven Rostedt if ($val =~ /^\s*0\s*$/) { 69545d73a5dSSteven Rostedt return 0; 69645d73a5dSSteven Rostedt } elsif ($val =~ /^\s*\d+\s*$/) { 69745d73a5dSSteven Rostedt return 1; 69845d73a5dSSteven Rostedt } 69945d73a5dSSteven Rostedt 7009900b5dcSSteven Rostedt die ("$name: $.: Undefined content $val in if statement\n"); 7018d735212SSteven Rostedt} 7028d735212SSteven Rostedt 7038d735212SSteven Rostedtsub process_if { 7048d735212SSteven Rostedt my ($name, $value) = @_; 7058d735212SSteven Rostedt 7068d735212SSteven Rostedt # Convert variables and replace undefined ones with 0 7078d735212SSteven Rostedt my $val = process_variables($value, 1); 7088d735212SSteven Rostedt my $ret = process_expression $name, $val; 7098d735212SSteven Rostedt 7108d735212SSteven Rostedt return $ret; 71145d73a5dSSteven Rostedt} 71245d73a5dSSteven Rostedt 7132ed3b161SSteven Rostedtsub __read_config { 7142ed3b161SSteven Rostedt my ($config, $current_test_num) = @_; 715a57419b3SSteven Rostedt 7162ed3b161SSteven Rostedt my $in; 7172ed3b161SSteven Rostedt open($in, $config) || die "can't read file $config"; 718a57419b3SSteven Rostedt 719a57419b3SSteven Rostedt my $name = $config; 720a57419b3SSteven Rostedt $name =~ s,.*/(.*),$1,; 721a57419b3SSteven Rostedt 7222ed3b161SSteven Rostedt my $test_num = $$current_test_num; 723a57419b3SSteven Rostedt my $default = 1; 724a57419b3SSteven Rostedt my $repeat = 1; 725a57419b3SSteven Rostedt my $num_tests_set = 0; 726a57419b3SSteven Rostedt my $skip = 0; 727a57419b3SSteven Rostedt my $rest; 728a9f84424SSteven Rostedt my $line; 7290df213caSSteven Rostedt my $test_case = 0; 73045d73a5dSSteven Rostedt my $if = 0; 73145d73a5dSSteven Rostedt my $if_set = 0; 7323d1cc414SSteven Rostedt my $override = 0; 7333d1cc414SSteven Rostedt 7343d1cc414SSteven Rostedt my %overrides; 735a57419b3SSteven Rostedt 7362ed3b161SSteven Rostedt while (<$in>) { 737a57419b3SSteven Rostedt 738a57419b3SSteven Rostedt # ignore blank lines and comments 739a57419b3SSteven Rostedt next if (/^\s*$/ || /\s*\#/); 740a57419b3SSteven Rostedt 7410050b6bbSSteven Rostedt if (/^\s*(TEST_START|DEFAULTS)\b(.*)/) { 742a57419b3SSteven Rostedt 7430050b6bbSSteven Rostedt my $type = $1; 7440050b6bbSSteven Rostedt $rest = $2; 745a9f84424SSteven Rostedt $line = $2; 7460050b6bbSSteven Rostedt 7470050b6bbSSteven Rostedt my $old_test_num; 7480050b6bbSSteven Rostedt my $old_repeat; 7493d1cc414SSteven Rostedt $override = 0; 7500050b6bbSSteven Rostedt 7510050b6bbSSteven Rostedt if ($type eq "TEST_START") { 752a57419b3SSteven Rostedt 753a57419b3SSteven Rostedt if ($num_tests_set) { 754a57419b3SSteven Rostedt die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n"; 755a57419b3SSteven Rostedt } 756a57419b3SSteven Rostedt 7570050b6bbSSteven Rostedt $old_test_num = $test_num; 7580050b6bbSSteven Rostedt $old_repeat = $repeat; 759a57419b3SSteven Rostedt 760a57419b3SSteven Rostedt $test_num += $repeat; 761a57419b3SSteven Rostedt $default = 0; 762a57419b3SSteven Rostedt $repeat = 1; 7630050b6bbSSteven Rostedt } else { 7640050b6bbSSteven Rostedt $default = 1; 7650050b6bbSSteven Rostedt } 766a57419b3SSteven Rostedt 767a9f84424SSteven Rostedt # If SKIP is anywhere in the line, the command will be skipped 768a9f84424SSteven Rostedt if ($rest =~ s/\s+SKIP\b//) { 769a57419b3SSteven Rostedt $skip = 1; 770a57419b3SSteven Rostedt } else { 7710df213caSSteven Rostedt $test_case = 1; 772a57419b3SSteven Rostedt $skip = 0; 773a57419b3SSteven Rostedt } 774a57419b3SSteven Rostedt 775a9f84424SSteven Rostedt if ($rest =~ s/\sELSE\b//) { 776a9f84424SSteven Rostedt if (!$if) { 777a9f84424SSteven Rostedt die "$name: $.: ELSE found with out matching IF section\n$_"; 778a57419b3SSteven Rostedt } 779a9f84424SSteven Rostedt $if = 0; 780a9f84424SSteven Rostedt 781a9f84424SSteven Rostedt if ($if_set) { 782a9f84424SSteven Rostedt $skip = 1; 783a9f84424SSteven Rostedt } else { 784a9f84424SSteven Rostedt $skip = 0; 7853d1cc414SSteven Rostedt } 7863d1cc414SSteven Rostedt } 787a57419b3SSteven Rostedt 788a9f84424SSteven Rostedt if ($rest =~ s/\sIF\s+(.*)//) { 78945d73a5dSSteven Rostedt if (process_if($name, $1)) { 79045d73a5dSSteven Rostedt $if_set = 1; 79145d73a5dSSteven Rostedt } else { 792a57419b3SSteven Rostedt $skip = 1; 793a57419b3SSteven Rostedt } 79445d73a5dSSteven Rostedt $if = 1; 79545d73a5dSSteven Rostedt } else { 79645d73a5dSSteven Rostedt $if = 0; 797a9f84424SSteven Rostedt $if_set = 0; 79845d73a5dSSteven Rostedt } 799a57419b3SSteven Rostedt 800a9f84424SSteven Rostedt if (!$skip) { 801a9f84424SSteven Rostedt if ($type eq "TEST_START") { 802a9f84424SSteven Rostedt if ($rest =~ s/\s+ITERATE\s+(\d+)//) { 803a9f84424SSteven Rostedt $repeat = $1; 804a9f84424SSteven Rostedt $repeat_tests{"$test_num"} = $repeat; 805a9f84424SSteven Rostedt } 806a9f84424SSteven Rostedt } elsif ($rest =~ s/\sOVERRIDE\b//) { 807a9f84424SSteven Rostedt # DEFAULT only 808a9f84424SSteven Rostedt $override = 1; 809a9f84424SSteven Rostedt # Clear previous overrides 810a9f84424SSteven Rostedt %overrides = (); 811a9f84424SSteven Rostedt } 812a9f84424SSteven Rostedt } 813a9f84424SSteven Rostedt 814a9f84424SSteven Rostedt if (!$skip && $rest !~ /^\s*$/) { 8150050b6bbSSteven Rostedt die "$name: $.: Gargbage found after $type\n$_"; 816a57419b3SSteven Rostedt } 817a57419b3SSteven Rostedt 8180050b6bbSSteven Rostedt if ($skip && $type eq "TEST_START") { 819a57419b3SSteven Rostedt $test_num = $old_test_num; 820e48c5293SSteven Rostedt $repeat = $old_repeat; 821a57419b3SSteven Rostedt } 822a57419b3SSteven Rostedt 823ab7a3f52SSteven Rostedt } elsif (/^\s*ELSE\b(.*)$/) { 82445d73a5dSSteven Rostedt if (!$if) { 82545d73a5dSSteven Rostedt die "$name: $.: ELSE found with out matching IF section\n$_"; 82645d73a5dSSteven Rostedt } 82745d73a5dSSteven Rostedt $rest = $1; 82845d73a5dSSteven Rostedt if ($if_set) { 82945d73a5dSSteven Rostedt $skip = 1; 830ab7a3f52SSteven Rostedt $rest = ""; 83145d73a5dSSteven Rostedt } else { 83245d73a5dSSteven Rostedt $skip = 0; 83345d73a5dSSteven Rostedt 834ab7a3f52SSteven Rostedt if ($rest =~ /\sIF\s+(.*)/) { 83545d73a5dSSteven Rostedt # May be a ELSE IF section. 83645d73a5dSSteven Rostedt if (!process_if($name, $1)) { 83745d73a5dSSteven Rostedt $skip = 1; 83845d73a5dSSteven Rostedt } 839ab7a3f52SSteven Rostedt $rest = ""; 84045d73a5dSSteven Rostedt } else { 84145d73a5dSSteven Rostedt $if = 0; 84245d73a5dSSteven Rostedt } 84345d73a5dSSteven Rostedt } 84445d73a5dSSteven Rostedt 845ab7a3f52SSteven Rostedt if ($rest !~ /^\s*$/) { 846ab7a3f52SSteven Rostedt die "$name: $.: Gargbage found after DEFAULTS\n$_"; 847ab7a3f52SSteven Rostedt } 848ab7a3f52SSteven Rostedt 8492ed3b161SSteven Rostedt } elsif (/^\s*INCLUDE\s+(\S+)/) { 8502ed3b161SSteven Rostedt 8512ed3b161SSteven Rostedt next if ($skip); 8522ed3b161SSteven Rostedt 8532ed3b161SSteven Rostedt if (!$default) { 8542ed3b161SSteven Rostedt die "$name: $.: INCLUDE can only be done in default sections\n$_"; 8552ed3b161SSteven Rostedt } 8562ed3b161SSteven Rostedt 8572ed3b161SSteven Rostedt my $file = process_variables($1); 8582ed3b161SSteven Rostedt 8592ed3b161SSteven Rostedt if ($file !~ m,^/,) { 8602ed3b161SSteven Rostedt # check the path of the config file first 8612ed3b161SSteven Rostedt if ($config =~ m,(.*)/,) { 8622ed3b161SSteven Rostedt if (-f "$1/$file") { 8632ed3b161SSteven Rostedt $file = "$1/$file"; 8642ed3b161SSteven Rostedt } 8652ed3b161SSteven Rostedt } 8662ed3b161SSteven Rostedt } 8672ed3b161SSteven Rostedt 8682ed3b161SSteven Rostedt if ( ! -r $file ) { 8692ed3b161SSteven Rostedt die "$name: $.: Can't read file $file\n$_"; 8702ed3b161SSteven Rostedt } 8712ed3b161SSteven Rostedt 8722ed3b161SSteven Rostedt if (__read_config($file, \$test_num)) { 8732ed3b161SSteven Rostedt $test_case = 1; 8742ed3b161SSteven Rostedt } 8752ed3b161SSteven Rostedt 876a57419b3SSteven Rostedt } elsif (/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) { 877a57419b3SSteven Rostedt 878a57419b3SSteven Rostedt next if ($skip); 879a57419b3SSteven Rostedt 880a57419b3SSteven Rostedt my $lvalue = $1; 881a57419b3SSteven Rostedt my $rvalue = $2; 882a57419b3SSteven Rostedt 883a57419b3SSteven Rostedt if (!$default && 884a57419b3SSteven Rostedt ($lvalue eq "NUM_TESTS" || 885a57419b3SSteven Rostedt $lvalue eq "LOG_FILE" || 886a57419b3SSteven Rostedt $lvalue eq "CLEAR_LOG")) { 887a57419b3SSteven Rostedt die "$name: $.: $lvalue must be set in DEFAULTS section\n"; 888a57419b3SSteven Rostedt } 889a57419b3SSteven Rostedt 890a57419b3SSteven Rostedt if ($lvalue eq "NUM_TESTS") { 891a57419b3SSteven Rostedt if ($test_num) { 892a57419b3SSteven Rostedt die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n"; 893a57419b3SSteven Rostedt } 894a57419b3SSteven Rostedt if (!$default) { 895a57419b3SSteven Rostedt die "$name: $.: NUM_TESTS must be set in default section\n"; 896a57419b3SSteven Rostedt } 897a57419b3SSteven Rostedt $num_tests_set = 1; 898a57419b3SSteven Rostedt } 899a57419b3SSteven Rostedt 900a57419b3SSteven Rostedt if ($default || $lvalue =~ /\[\d+\]$/) { 9013d1cc414SSteven Rostedt set_value($lvalue, $rvalue, $override, \%overrides, $name); 902a57419b3SSteven Rostedt } else { 903a57419b3SSteven Rostedt my $val = "$lvalue\[$test_num\]"; 9043d1cc414SSteven Rostedt set_value($val, $rvalue, $override, \%overrides, $name); 905a57419b3SSteven Rostedt 906a57419b3SSteven Rostedt if ($repeat > 1) { 907a57419b3SSteven Rostedt $repeats{$val} = $repeat; 908a57419b3SSteven Rostedt } 909a57419b3SSteven Rostedt } 91077d942ceSSteven Rostedt } elsif (/^\s*([A-Z_\[\]\d]+)\s*:=\s*(.*?)\s*$/) { 91177d942ceSSteven Rostedt next if ($skip); 91277d942ceSSteven Rostedt 91377d942ceSSteven Rostedt my $lvalue = $1; 91477d942ceSSteven Rostedt my $rvalue = $2; 91577d942ceSSteven Rostedt 91677d942ceSSteven Rostedt # process config variables. 91777d942ceSSteven Rostedt # Config variables are only active while reading the 91877d942ceSSteven Rostedt # config and can be defined anywhere. They also ignore 91977d942ceSSteven Rostedt # TEST_START and DEFAULTS, but are skipped if they are in 92077d942ceSSteven Rostedt # on of these sections that have SKIP defined. 92177d942ceSSteven Rostedt # The save variable can be 92277d942ceSSteven Rostedt # defined multiple times and the new one simply overrides 92377d942ceSSteven Rostedt # the prevous one. 92477d942ceSSteven Rostedt set_variable($lvalue, $rvalue); 92577d942ceSSteven Rostedt 926a57419b3SSteven Rostedt } else { 927a57419b3SSteven Rostedt die "$name: $.: Garbage found in config\n$_"; 928a57419b3SSteven Rostedt } 9292545eb61SSteven Rostedt } 9302545eb61SSteven Rostedt 931a57419b3SSteven Rostedt if ($test_num) { 932a57419b3SSteven Rostedt $test_num += $repeat - 1; 933a57419b3SSteven Rostedt $opt{"NUM_TESTS"} = $test_num; 934a57419b3SSteven Rostedt } 935a57419b3SSteven Rostedt 9362ed3b161SSteven Rostedt close($in); 9372ed3b161SSteven Rostedt 9382ed3b161SSteven Rostedt $$current_test_num = $test_num; 9392ed3b161SSteven Rostedt 9402ed3b161SSteven Rostedt return $test_case; 9412ed3b161SSteven Rostedt} 9422ed3b161SSteven Rostedt 943c4261d0fSSteven Rostedtsub get_test_case { 944c4261d0fSSteven Rostedt print "What test case would you like to run?\n"; 945c4261d0fSSteven Rostedt print " (build, install or boot)\n"; 946c4261d0fSSteven Rostedt print " Other tests are available but require editing the config file\n"; 947c4261d0fSSteven Rostedt my $ans = <STDIN>; 948c4261d0fSSteven Rostedt chomp $ans; 949c4261d0fSSteven Rostedt $default{"TEST_TYPE"} = $ans; 950c4261d0fSSteven Rostedt} 951c4261d0fSSteven Rostedt 9522ed3b161SSteven Rostedtsub read_config { 9532ed3b161SSteven Rostedt my ($config) = @_; 9542ed3b161SSteven Rostedt 9552ed3b161SSteven Rostedt my $test_case; 9562ed3b161SSteven Rostedt my $test_num = 0; 9572ed3b161SSteven Rostedt 9582ed3b161SSteven Rostedt $test_case = __read_config $config, \$test_num; 9592ed3b161SSteven Rostedt 9608d1491baSSteven Rostedt # make sure we have all mandatory configs 9618d1491baSSteven Rostedt get_ktest_configs; 9628d1491baSSteven Rostedt 9630df213caSSteven Rostedt # was a test specified? 9640df213caSSteven Rostedt if (!$test_case) { 9650df213caSSteven Rostedt print "No test case specified.\n"; 966c4261d0fSSteven Rostedt get_test_case; 9670df213caSSteven Rostedt } 9680df213caSSteven Rostedt 969a75fececSSteven Rostedt # set any defaults 970a75fececSSteven Rostedt 971a75fececSSteven Rostedt foreach my $default (keys %default) { 972a75fececSSteven Rostedt if (!defined($opt{$default})) { 973a75fececSSteven Rostedt $opt{$default} = $default{$default}; 974a75fececSSteven Rostedt } 975a75fececSSteven Rostedt } 9769cc9e091SSteven Rostedt 9779cc9e091SSteven Rostedt if ($opt{"IGNORE_UNUSED"} == 1) { 9789cc9e091SSteven Rostedt return; 9799cc9e091SSteven Rostedt } 9809cc9e091SSteven Rostedt 9819cc9e091SSteven Rostedt my %not_used; 9829cc9e091SSteven Rostedt 9839cc9e091SSteven Rostedt # check if there are any stragglers (typos?) 9849cc9e091SSteven Rostedt foreach my $option (keys %opt) { 9859cc9e091SSteven Rostedt my $op = $option; 9869cc9e091SSteven Rostedt # remove per test labels. 9879cc9e091SSteven Rostedt $op =~ s/\[.*\]//; 9889cc9e091SSteven Rostedt if (!exists($option_map{$op}) && 9899cc9e091SSteven Rostedt !exists($default{$op}) && 9909cc9e091SSteven Rostedt !exists($used_options{$op})) { 9919cc9e091SSteven Rostedt $not_used{$op} = 1; 9929cc9e091SSteven Rostedt } 9939cc9e091SSteven Rostedt } 9949cc9e091SSteven Rostedt 9959cc9e091SSteven Rostedt if (%not_used) { 9969cc9e091SSteven Rostedt my $s = "s are"; 9979cc9e091SSteven Rostedt $s = " is" if (keys %not_used == 1); 9989cc9e091SSteven Rostedt print "The following option$s not used; could be a typo:\n"; 9999cc9e091SSteven Rostedt foreach my $option (keys %not_used) { 10009cc9e091SSteven Rostedt print "$option\n"; 10019cc9e091SSteven Rostedt } 10029cc9e091SSteven Rostedt print "Set IGRNORE_UNUSED = 1 to have ktest ignore unused variables\n"; 10039cc9e091SSteven Rostedt if (!read_yn "Do you want to continue?") { 10049cc9e091SSteven Rostedt exit -1; 10059cc9e091SSteven Rostedt } 10069cc9e091SSteven Rostedt } 10072545eb61SSteven Rostedt} 10082545eb61SSteven Rostedt 100923715c3cSSteven Rostedtsub __eval_option { 101023715c3cSSteven Rostedt my ($option, $i) = @_; 101123715c3cSSteven Rostedt 101223715c3cSSteven Rostedt # Add space to evaluate the character before $ 101323715c3cSSteven Rostedt $option = " $option"; 101423715c3cSSteven Rostedt my $retval = ""; 1015f9dfb65bSRabin Vincent my $repeated = 0; 1016f9dfb65bSRabin Vincent my $parent = 0; 1017f9dfb65bSRabin Vincent 1018f9dfb65bSRabin Vincent foreach my $test (keys %repeat_tests) { 1019f9dfb65bSRabin Vincent if ($i >= $test && 1020f9dfb65bSRabin Vincent $i < $test + $repeat_tests{$test}) { 1021f9dfb65bSRabin Vincent 1022f9dfb65bSRabin Vincent $repeated = 1; 1023f9dfb65bSRabin Vincent $parent = $test; 1024f9dfb65bSRabin Vincent last; 1025f9dfb65bSRabin Vincent } 1026f9dfb65bSRabin Vincent } 102723715c3cSSteven Rostedt 102823715c3cSSteven Rostedt while ($option =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) { 102923715c3cSSteven Rostedt my $start = $1; 103023715c3cSSteven Rostedt my $var = $2; 103123715c3cSSteven Rostedt my $end = $3; 103223715c3cSSteven Rostedt 103323715c3cSSteven Rostedt # Append beginning of line 103423715c3cSSteven Rostedt $retval = "$retval$start"; 103523715c3cSSteven Rostedt 103623715c3cSSteven Rostedt # If the iteration option OPT[$i] exists, then use that. 103723715c3cSSteven Rostedt # otherwise see if the default OPT (without [$i]) exists. 103823715c3cSSteven Rostedt 103923715c3cSSteven Rostedt my $o = "$var\[$i\]"; 1040f9dfb65bSRabin Vincent my $parento = "$var\[$parent\]"; 104123715c3cSSteven Rostedt 104223715c3cSSteven Rostedt if (defined($opt{$o})) { 104323715c3cSSteven Rostedt $o = $opt{$o}; 104423715c3cSSteven Rostedt $retval = "$retval$o"; 1045f9dfb65bSRabin Vincent } elsif ($repeated && defined($opt{$parento})) { 1046f9dfb65bSRabin Vincent $o = $opt{$parento}; 1047f9dfb65bSRabin Vincent $retval = "$retval$o"; 104823715c3cSSteven Rostedt } elsif (defined($opt{$var})) { 104923715c3cSSteven Rostedt $o = $opt{$var}; 105023715c3cSSteven Rostedt $retval = "$retval$o"; 105123715c3cSSteven Rostedt } else { 105223715c3cSSteven Rostedt $retval = "$retval\$\{$var\}"; 105323715c3cSSteven Rostedt } 105423715c3cSSteven Rostedt 105523715c3cSSteven Rostedt $option = $end; 105623715c3cSSteven Rostedt } 105723715c3cSSteven Rostedt 105823715c3cSSteven Rostedt $retval = "$retval$option"; 105923715c3cSSteven Rostedt 106023715c3cSSteven Rostedt $retval =~ s/^ //; 106123715c3cSSteven Rostedt 106223715c3cSSteven Rostedt return $retval; 106323715c3cSSteven Rostedt} 106423715c3cSSteven Rostedt 106523715c3cSSteven Rostedtsub eval_option { 106623715c3cSSteven Rostedt my ($option, $i) = @_; 106723715c3cSSteven Rostedt 106823715c3cSSteven Rostedt my $prev = ""; 106923715c3cSSteven Rostedt 107023715c3cSSteven Rostedt # Since an option can evaluate to another option, 107123715c3cSSteven Rostedt # keep iterating until we do not evaluate any more 107223715c3cSSteven Rostedt # options. 107323715c3cSSteven Rostedt my $r = 0; 107423715c3cSSteven Rostedt while ($prev ne $option) { 107523715c3cSSteven Rostedt # Check for recursive evaluations. 107623715c3cSSteven Rostedt # 100 deep should be more than enough. 107723715c3cSSteven Rostedt if ($r++ > 100) { 107823715c3cSSteven Rostedt die "Over 100 evaluations accurred with $option\n" . 107923715c3cSSteven Rostedt "Check for recursive variables\n"; 108023715c3cSSteven Rostedt } 108123715c3cSSteven Rostedt $prev = $option; 108223715c3cSSteven Rostedt $option = __eval_option($option, $i); 108323715c3cSSteven Rostedt } 108423715c3cSSteven Rostedt 108523715c3cSSteven Rostedt return $option; 108623715c3cSSteven Rostedt} 108723715c3cSSteven Rostedt 1088d1e2f22aSSteven Rostedtsub _logit { 10892545eb61SSteven Rostedt if (defined($opt{"LOG_FILE"})) { 10902545eb61SSteven Rostedt open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}"; 10912545eb61SSteven Rostedt print OUT @_; 10922545eb61SSteven Rostedt close(OUT); 10932545eb61SSteven Rostedt } 10942545eb61SSteven Rostedt} 10952545eb61SSteven Rostedt 1096d1e2f22aSSteven Rostedtsub logit { 1097d1e2f22aSSteven Rostedt if (defined($opt{"LOG_FILE"})) { 1098d1e2f22aSSteven Rostedt _logit @_; 1099d1e2f22aSSteven Rostedt } else { 1100d1e2f22aSSteven Rostedt print @_; 1101d1e2f22aSSteven Rostedt } 1102d1e2f22aSSteven Rostedt} 1103d1e2f22aSSteven Rostedt 11045f9b6cedSSteven Rostedtsub doprint { 11055f9b6cedSSteven Rostedt print @_; 1106d1e2f22aSSteven Rostedt _logit @_; 11075f9b6cedSSteven Rostedt} 11085f9b6cedSSteven Rostedt 11097faafbd6SSteven Rostedtsub run_command; 11102728be41SAndrew Jonessub start_monitor; 11112728be41SAndrew Jonessub end_monitor; 11122728be41SAndrew Jonessub wait_for_monitor; 11137faafbd6SSteven Rostedt 11147faafbd6SSteven Rostedtsub reboot { 11152728be41SAndrew Jones my ($time) = @_; 11162728be41SAndrew Jones 11172b803365SSteven Rostedt if (defined($time)) { 11182b803365SSteven Rostedt start_monitor; 11192b803365SSteven Rostedt # flush out current monitor 11202b803365SSteven Rostedt # May contain the reboot success line 11212b803365SSteven Rostedt wait_for_monitor 1; 11222b803365SSteven Rostedt } 11232b803365SSteven Rostedt 11247faafbd6SSteven Rostedt # try to reboot normally 1125e48c5293SSteven Rostedt if (run_command $reboot) { 1126576f627cSSteven Rostedt if (defined($powercycle_after_reboot)) { 1127576f627cSSteven Rostedt sleep $powercycle_after_reboot; 1128576f627cSSteven Rostedt run_command "$power_cycle"; 1129576f627cSSteven Rostedt } 1130576f627cSSteven Rostedt } else { 11317faafbd6SSteven Rostedt # nope? power cycle it. 1132a75fececSSteven Rostedt run_command "$power_cycle"; 11337faafbd6SSteven Rostedt } 11342728be41SAndrew Jones 11352728be41SAndrew Jones if (defined($time)) { 11362b803365SSteven Rostedt wait_for_monitor($time, $reboot_success_line); 11372728be41SAndrew Jones end_monitor; 11382728be41SAndrew Jones } 11397faafbd6SSteven Rostedt} 11407faafbd6SSteven Rostedt 1141bc7c5803SSteven Rostedtsub reboot_to_good { 1142bc7c5803SSteven Rostedt my ($time) = @_; 1143bc7c5803SSteven Rostedt 1144bc7c5803SSteven Rostedt if (defined($switch_to_good)) { 1145bc7c5803SSteven Rostedt run_command $switch_to_good; 1146bc7c5803SSteven Rostedt } 1147bc7c5803SSteven Rostedt 1148bc7c5803SSteven Rostedt reboot $time; 1149bc7c5803SSteven Rostedt} 1150bc7c5803SSteven Rostedt 1151576f627cSSteven Rostedtsub do_not_reboot { 1152576f627cSSteven Rostedt my $i = $iteration; 1153576f627cSSteven Rostedt 11544ab1cce5SSteven Rostedt return $test_type eq "build" || $no_reboot || 1155576f627cSSteven Rostedt ($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") || 1156576f627cSSteven Rostedt ($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build"); 1157576f627cSSteven Rostedt} 1158576f627cSSteven Rostedt 11595c42fc5bSSteven Rostedtsub dodie { 11605a391fbfSSteven Rostedt doprint "CRITICAL FAILURE... ", @_, "\n"; 11615c42fc5bSSteven Rostedt 1162576f627cSSteven Rostedt my $i = $iteration; 1163576f627cSSteven Rostedt 1164576f627cSSteven Rostedt if ($reboot_on_error && !do_not_reboot) { 1165576f627cSSteven Rostedt 116675c3fda7SSteven Rostedt doprint "REBOOTING\n"; 1167bc7c5803SSteven Rostedt reboot_to_good; 116875c3fda7SSteven Rostedt 1169a75fececSSteven Rostedt } elsif ($poweroff_on_error && defined($power_off)) { 11705c42fc5bSSteven Rostedt doprint "POWERING OFF\n"; 1171a75fececSSteven Rostedt `$power_off`; 11725c42fc5bSSteven Rostedt } 117375c3fda7SSteven Rostedt 1174f80802cbSSteven Rostedt if (defined($opt{"LOG_FILE"})) { 1175f80802cbSSteven Rostedt print " See $opt{LOG_FILE} for more info.\n"; 1176f80802cbSSteven Rostedt } 1177f80802cbSSteven Rostedt 1178576f627cSSteven Rostedt die @_, "\n"; 11795c42fc5bSSteven Rostedt} 11805c42fc5bSSteven Rostedt 11817faafbd6SSteven Rostedtsub open_console { 11827faafbd6SSteven Rostedt my ($fp) = @_; 11837faafbd6SSteven Rostedt 11847faafbd6SSteven Rostedt my $flags; 11857faafbd6SSteven Rostedt 1186a75fececSSteven Rostedt my $pid = open($fp, "$console|") or 1187a75fececSSteven Rostedt dodie "Can't open console $console"; 11887faafbd6SSteven Rostedt 11897faafbd6SSteven Rostedt $flags = fcntl($fp, F_GETFL, 0) or 1190576f627cSSteven Rostedt dodie "Can't get flags for the socket: $!"; 11917faafbd6SSteven Rostedt $flags = fcntl($fp, F_SETFL, $flags | O_NONBLOCK) or 1192576f627cSSteven Rostedt dodie "Can't set flags for the socket: $!"; 11937faafbd6SSteven Rostedt 11947faafbd6SSteven Rostedt return $pid; 11957faafbd6SSteven Rostedt} 11967faafbd6SSteven Rostedt 11977faafbd6SSteven Rostedtsub close_console { 11987faafbd6SSteven Rostedt my ($fp, $pid) = @_; 11997faafbd6SSteven Rostedt 12007faafbd6SSteven Rostedt doprint "kill child process $pid\n"; 12017faafbd6SSteven Rostedt kill 2, $pid; 12027faafbd6SSteven Rostedt 12037faafbd6SSteven Rostedt print "closing!\n"; 12047faafbd6SSteven Rostedt close($fp); 12057faafbd6SSteven Rostedt} 12067faafbd6SSteven Rostedt 12077faafbd6SSteven Rostedtsub start_monitor { 12087faafbd6SSteven Rostedt if ($monitor_cnt++) { 12097faafbd6SSteven Rostedt return; 12107faafbd6SSteven Rostedt } 12117faafbd6SSteven Rostedt $monitor_fp = \*MONFD; 12127faafbd6SSteven Rostedt $monitor_pid = open_console $monitor_fp; 1213a75fececSSteven Rostedt 1214a75fececSSteven Rostedt return; 1215a75fececSSteven Rostedt 1216a75fececSSteven Rostedt open(MONFD, "Stop perl from warning about single use of MONFD"); 12177faafbd6SSteven Rostedt} 12187faafbd6SSteven Rostedt 12197faafbd6SSteven Rostedtsub end_monitor { 12207faafbd6SSteven Rostedt if (--$monitor_cnt) { 12217faafbd6SSteven Rostedt return; 12227faafbd6SSteven Rostedt } 12237faafbd6SSteven Rostedt close_console($monitor_fp, $monitor_pid); 12247faafbd6SSteven Rostedt} 12257faafbd6SSteven Rostedt 12267faafbd6SSteven Rostedtsub wait_for_monitor { 12272b803365SSteven Rostedt my ($time, $stop) = @_; 12282b803365SSteven Rostedt my $full_line = ""; 12297faafbd6SSteven Rostedt my $line; 12302b803365SSteven Rostedt my $booted = 0; 12317faafbd6SSteven Rostedt 1232a75fececSSteven Rostedt doprint "** Wait for monitor to settle down **\n"; 12337faafbd6SSteven Rostedt 12347faafbd6SSteven Rostedt # read the monitor and wait for the system to calm down 12352b803365SSteven Rostedt while (!$booted) { 12367faafbd6SSteven Rostedt $line = wait_for_input($monitor_fp, $time); 12372b803365SSteven Rostedt last if (!defined($line)); 12382b803365SSteven Rostedt print "$line"; 12392b803365SSteven Rostedt $full_line .= $line; 12402b803365SSteven Rostedt 12412b803365SSteven Rostedt if (defined($stop) && $full_line =~ /$stop/) { 12422b803365SSteven Rostedt doprint "wait for monitor detected $stop\n"; 12432b803365SSteven Rostedt $booted = 1; 12442b803365SSteven Rostedt } 12452b803365SSteven Rostedt 12462b803365SSteven Rostedt if ($line =~ /\n/) { 12472b803365SSteven Rostedt $full_line = ""; 12482b803365SSteven Rostedt } 12492b803365SSteven Rostedt } 1250a75fececSSteven Rostedt print "** Monitor flushed **\n"; 12517faafbd6SSteven Rostedt} 12527faafbd6SSteven Rostedt 1253de5b6e3bSRabin Vincentsub save_logs { 1254de5b6e3bSRabin Vincent my ($result, $basedir) = @_; 1255de5b6e3bSRabin Vincent my @t = localtime; 1256de5b6e3bSRabin Vincent my $date = sprintf "%04d%02d%02d%02d%02d%02d", 1257de5b6e3bSRabin Vincent 1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0]; 1258de5b6e3bSRabin Vincent 1259de5b6e3bSRabin Vincent my $type = $build_type; 1260de5b6e3bSRabin Vincent if ($type =~ /useconfig/) { 1261de5b6e3bSRabin Vincent $type = "useconfig"; 1262de5b6e3bSRabin Vincent } 1263de5b6e3bSRabin Vincent 1264de5b6e3bSRabin Vincent my $dir = "$machine-$test_type-$type-$result-$date"; 1265de5b6e3bSRabin Vincent 1266de5b6e3bSRabin Vincent $dir = "$basedir/$dir"; 1267de5b6e3bSRabin Vincent 1268de5b6e3bSRabin Vincent if (!-d $dir) { 1269de5b6e3bSRabin Vincent mkpath($dir) or 1270de5b6e3bSRabin Vincent die "can't create $dir"; 1271de5b6e3bSRabin Vincent } 1272de5b6e3bSRabin Vincent 1273de5b6e3bSRabin Vincent my %files = ( 1274de5b6e3bSRabin Vincent "config" => $output_config, 1275de5b6e3bSRabin Vincent "buildlog" => $buildlog, 1276de5b6e3bSRabin Vincent "dmesg" => $dmesg, 1277de5b6e3bSRabin Vincent "testlog" => $testlog, 1278de5b6e3bSRabin Vincent ); 1279de5b6e3bSRabin Vincent 1280de5b6e3bSRabin Vincent while (my ($name, $source) = each(%files)) { 1281de5b6e3bSRabin Vincent if (-f "$source") { 1282de5b6e3bSRabin Vincent cp "$source", "$dir/$name" or 1283de5b6e3bSRabin Vincent die "failed to copy $source"; 1284de5b6e3bSRabin Vincent } 1285de5b6e3bSRabin Vincent } 1286de5b6e3bSRabin Vincent 1287de5b6e3bSRabin Vincent doprint "*** Saved info to $dir ***\n"; 1288de5b6e3bSRabin Vincent} 1289de5b6e3bSRabin Vincent 12902b7d9b21SSteven Rostedtsub fail { 12912b7d9b21SSteven Rostedt 1292921ed4c7SSteven Rostedt if (defined($post_test)) { 1293921ed4c7SSteven Rostedt run_command $post_test; 1294921ed4c7SSteven Rostedt } 1295921ed4c7SSteven Rostedt 1296a75fececSSteven Rostedt if ($die_on_failure) { 12972b7d9b21SSteven Rostedt dodie @_; 12982b7d9b21SSteven Rostedt } 12992b7d9b21SSteven Rostedt 1300a75fececSSteven Rostedt doprint "FAILED\n"; 13017faafbd6SSteven Rostedt 1302576f627cSSteven Rostedt my $i = $iteration; 1303576f627cSSteven Rostedt 1304a75fececSSteven Rostedt # no need to reboot for just building. 1305576f627cSSteven Rostedt if (!do_not_reboot) { 13067faafbd6SSteven Rostedt doprint "REBOOTING\n"; 1307bc7c5803SSteven Rostedt reboot_to_good $sleep_time; 1308a75fececSSteven Rostedt } 13097faafbd6SSteven Rostedt 13109064af52SSteven Rostedt my $name = ""; 13119064af52SSteven Rostedt 13129064af52SSteven Rostedt if (defined($test_name)) { 13139064af52SSteven Rostedt $name = " ($test_name)"; 13149064af52SSteven Rostedt } 13159064af52SSteven Rostedt 1316576f627cSSteven Rostedt doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; 1317576f627cSSteven Rostedt doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; 13189064af52SSteven Rostedt doprint "KTEST RESULT: TEST $i$name Failed: ", @_, "\n"; 1319576f627cSSteven Rostedt doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; 1320576f627cSSteven Rostedt doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; 1321a75fececSSteven Rostedt 1322de5b6e3bSRabin Vincent if (defined($store_failures)) { 1323de5b6e3bSRabin Vincent save_logs "fail", $store_failures; 1324cccae1a6SSteven Rostedt } 1325cccae1a6SSteven Rostedt 13262b7d9b21SSteven Rostedt return 1; 13272b7d9b21SSteven Rostedt} 13282b7d9b21SSteven Rostedt 13292545eb61SSteven Rostedtsub run_command { 13302545eb61SSteven Rostedt my ($command) = @_; 1331d6ce2a0bSSteven Rostedt my $dolog = 0; 1332d6ce2a0bSSteven Rostedt my $dord = 0; 1333d6ce2a0bSSteven Rostedt my $pid; 1334d6ce2a0bSSteven Rostedt 1335e48c5293SSteven Rostedt $command =~ s/\$SSH_USER/$ssh_user/g; 1336e48c5293SSteven Rostedt $command =~ s/\$MACHINE/$machine/g; 1337e48c5293SSteven Rostedt 1338d6ce2a0bSSteven Rostedt doprint("$command ... "); 1339d6ce2a0bSSteven Rostedt 1340d6ce2a0bSSteven Rostedt $pid = open(CMD, "$command 2>&1 |") or 13412b7d9b21SSteven Rostedt (fail "unable to exec $command" and return 0); 13422545eb61SSteven Rostedt 13432545eb61SSteven Rostedt if (defined($opt{"LOG_FILE"})) { 1344d6ce2a0bSSteven Rostedt open(LOG, ">>$opt{LOG_FILE}") or 1345d6ce2a0bSSteven Rostedt dodie "failed to write to log"; 1346d6ce2a0bSSteven Rostedt $dolog = 1; 13476c5ee0beSSteven Rostedt } 13486c5ee0beSSteven Rostedt 13496c5ee0beSSteven Rostedt if (defined($redirect)) { 1350d6ce2a0bSSteven Rostedt open (RD, ">$redirect") or 1351d6ce2a0bSSteven Rostedt dodie "failed to write to redirect $redirect"; 1352d6ce2a0bSSteven Rostedt $dord = 1; 13532545eb61SSteven Rostedt } 13542545eb61SSteven Rostedt 1355d6ce2a0bSSteven Rostedt while (<CMD>) { 1356d6ce2a0bSSteven Rostedt print LOG if ($dolog); 1357d6ce2a0bSSteven Rostedt print RD if ($dord); 1358d6ce2a0bSSteven Rostedt } 13592545eb61SSteven Rostedt 1360d6ce2a0bSSteven Rostedt waitpid($pid, 0); 13612545eb61SSteven Rostedt my $failed = $?; 13622545eb61SSteven Rostedt 1363d6ce2a0bSSteven Rostedt close(CMD); 1364d6ce2a0bSSteven Rostedt close(LOG) if ($dolog); 1365d6ce2a0bSSteven Rostedt close(RD) if ($dord); 1366d6ce2a0bSSteven Rostedt 13672545eb61SSteven Rostedt if ($failed) { 13682545eb61SSteven Rostedt doprint "FAILED!\n"; 13692545eb61SSteven Rostedt } else { 13702545eb61SSteven Rostedt doprint "SUCCESS\n"; 13712545eb61SSteven Rostedt } 13722545eb61SSteven Rostedt 13735f9b6cedSSteven Rostedt return !$failed; 13745f9b6cedSSteven Rostedt} 13755f9b6cedSSteven Rostedt 1376e48c5293SSteven Rostedtsub run_ssh { 1377e48c5293SSteven Rostedt my ($cmd) = @_; 1378e48c5293SSteven Rostedt my $cp_exec = $ssh_exec; 1379e48c5293SSteven Rostedt 1380e48c5293SSteven Rostedt $cp_exec =~ s/\$SSH_COMMAND/$cmd/g; 1381e48c5293SSteven Rostedt return run_command "$cp_exec"; 1382e48c5293SSteven Rostedt} 1383e48c5293SSteven Rostedt 1384e48c5293SSteven Rostedtsub run_scp { 138502ad2617SSteven Rostedt my ($src, $dst, $cp_scp) = @_; 1386e48c5293SSteven Rostedt 1387e48c5293SSteven Rostedt $cp_scp =~ s/\$SRC_FILE/$src/g; 1388e48c5293SSteven Rostedt $cp_scp =~ s/\$DST_FILE/$dst/g; 1389e48c5293SSteven Rostedt 1390e48c5293SSteven Rostedt return run_command "$cp_scp"; 1391e48c5293SSteven Rostedt} 1392e48c5293SSteven Rostedt 139302ad2617SSteven Rostedtsub run_scp_install { 139402ad2617SSteven Rostedt my ($src, $dst) = @_; 139502ad2617SSteven Rostedt 139602ad2617SSteven Rostedt my $cp_scp = $scp_to_target_install; 139702ad2617SSteven Rostedt 139802ad2617SSteven Rostedt return run_scp($src, $dst, $cp_scp); 139902ad2617SSteven Rostedt} 140002ad2617SSteven Rostedt 140102ad2617SSteven Rostedtsub run_scp_mod { 140202ad2617SSteven Rostedt my ($src, $dst) = @_; 140302ad2617SSteven Rostedt 140402ad2617SSteven Rostedt my $cp_scp = $scp_to_target; 140502ad2617SSteven Rostedt 140602ad2617SSteven Rostedt return run_scp($src, $dst, $cp_scp); 140702ad2617SSteven Rostedt} 140802ad2617SSteven Rostedt 14095f9b6cedSSteven Rostedtsub get_grub_index { 14105f9b6cedSSteven Rostedt 1411a75fececSSteven Rostedt if ($reboot_type ne "grub") { 1412a75fececSSteven Rostedt return; 1413a75fececSSteven Rostedt } 14145a391fbfSSteven Rostedt return if (defined($grub_number)); 14155f9b6cedSSteven Rostedt 14165f9b6cedSSteven Rostedt doprint "Find grub menu ... "; 14175f9b6cedSSteven Rostedt $grub_number = -1; 1418e48c5293SSteven Rostedt 1419e48c5293SSteven Rostedt my $ssh_grub = $ssh_exec; 1420e48c5293SSteven Rostedt $ssh_grub =~ s,\$SSH_COMMAND,cat /boot/grub/menu.lst,g; 1421e48c5293SSteven Rostedt 1422e48c5293SSteven Rostedt open(IN, "$ssh_grub |") 14235f9b6cedSSteven Rostedt or die "unable to get menu.lst"; 1424e48c5293SSteven Rostedt 1425eaa1fe25SSteven Rostedt my $found = 0; 1426eaa1fe25SSteven Rostedt 14275f9b6cedSSteven Rostedt while (<IN>) { 1428a75fececSSteven Rostedt if (/^\s*title\s+$grub_menu\s*$/) { 14295f9b6cedSSteven Rostedt $grub_number++; 1430eaa1fe25SSteven Rostedt $found = 1; 14315f9b6cedSSteven Rostedt last; 14325f9b6cedSSteven Rostedt } elsif (/^\s*title\s/) { 14335f9b6cedSSteven Rostedt $grub_number++; 14345f9b6cedSSteven Rostedt } 14355f9b6cedSSteven Rostedt } 14365f9b6cedSSteven Rostedt close(IN); 14375f9b6cedSSteven Rostedt 1438a75fececSSteven Rostedt die "Could not find '$grub_menu' in /boot/grub/menu on $machine" 1439eaa1fe25SSteven Rostedt if (!$found); 14405f9b6cedSSteven Rostedt doprint "$grub_number\n"; 14412545eb61SSteven Rostedt} 14422545eb61SSteven Rostedt 14432545eb61SSteven Rostedtsub wait_for_input 14442545eb61SSteven Rostedt{ 14452545eb61SSteven Rostedt my ($fp, $time) = @_; 14462545eb61SSteven Rostedt my $rin; 14472545eb61SSteven Rostedt my $ready; 14482545eb61SSteven Rostedt my $line; 14492545eb61SSteven Rostedt my $ch; 14502545eb61SSteven Rostedt 14512545eb61SSteven Rostedt if (!defined($time)) { 14522545eb61SSteven Rostedt $time = $timeout; 14532545eb61SSteven Rostedt } 14542545eb61SSteven Rostedt 14552545eb61SSteven Rostedt $rin = ''; 14562545eb61SSteven Rostedt vec($rin, fileno($fp), 1) = 1; 14572545eb61SSteven Rostedt $ready = select($rin, undef, undef, $time); 14582545eb61SSteven Rostedt 14592545eb61SSteven Rostedt $line = ""; 14602545eb61SSteven Rostedt 14612545eb61SSteven Rostedt # try to read one char at a time 14622545eb61SSteven Rostedt while (sysread $fp, $ch, 1) { 14632545eb61SSteven Rostedt $line .= $ch; 14642545eb61SSteven Rostedt last if ($ch eq "\n"); 14652545eb61SSteven Rostedt } 14662545eb61SSteven Rostedt 14672545eb61SSteven Rostedt if (!length($line)) { 14682545eb61SSteven Rostedt return undef; 14692545eb61SSteven Rostedt } 14702545eb61SSteven Rostedt 14712545eb61SSteven Rostedt return $line; 14722545eb61SSteven Rostedt} 14732545eb61SSteven Rostedt 147475c3fda7SSteven Rostedtsub reboot_to { 1475bc7c5803SSteven Rostedt if (defined($switch_to_test)) { 1476bc7c5803SSteven Rostedt run_command $switch_to_test; 1477bc7c5803SSteven Rostedt } 1478bc7c5803SSteven Rostedt 1479a75fececSSteven Rostedt if ($reboot_type eq "grub") { 1480c54367f9SSteven Rostedt run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch)'"; 148196f6a0dfSSteven Rostedt } elsif (defined $reboot_script) { 1482a75fececSSteven Rostedt run_command "$reboot_script"; 14832545eb61SSteven Rostedt } 148496f6a0dfSSteven Rostedt reboot; 148596f6a0dfSSteven Rostedt} 14862545eb61SSteven Rostedt 1487a57419b3SSteven Rostedtsub get_sha1 { 1488a57419b3SSteven Rostedt my ($commit) = @_; 1489a57419b3SSteven Rostedt 1490a57419b3SSteven Rostedt doprint "git rev-list --max-count=1 $commit ... "; 1491a57419b3SSteven Rostedt my $sha1 = `git rev-list --max-count=1 $commit`; 1492a57419b3SSteven Rostedt my $ret = $?; 1493a57419b3SSteven Rostedt 1494a57419b3SSteven Rostedt logit $sha1; 1495a57419b3SSteven Rostedt 1496a57419b3SSteven Rostedt if ($ret) { 1497a57419b3SSteven Rostedt doprint "FAILED\n"; 1498a57419b3SSteven Rostedt dodie "Failed to get git $commit"; 1499a57419b3SSteven Rostedt } 1500a57419b3SSteven Rostedt 1501a57419b3SSteven Rostedt print "SUCCESS\n"; 1502a57419b3SSteven Rostedt 1503a57419b3SSteven Rostedt chomp $sha1; 1504a57419b3SSteven Rostedt 1505a57419b3SSteven Rostedt return $sha1; 1506a57419b3SSteven Rostedt} 1507a57419b3SSteven Rostedt 15085a391fbfSSteven Rostedtsub monitor { 15092545eb61SSteven Rostedt my $booted = 0; 15102545eb61SSteven Rostedt my $bug = 0; 15116ca996ccSSteven Rostedt my $bug_ignored = 0; 15125c42fc5bSSteven Rostedt my $skip_call_trace = 0; 15132b7d9b21SSteven Rostedt my $loops; 15142545eb61SSteven Rostedt 15157faafbd6SSteven Rostedt wait_for_monitor 5; 15162545eb61SSteven Rostedt 15172545eb61SSteven Rostedt my $line; 15182545eb61SSteven Rostedt my $full_line = ""; 15192545eb61SSteven Rostedt 15207faafbd6SSteven Rostedt open(DMESG, "> $dmesg") or 15217faafbd6SSteven Rostedt die "unable to write to $dmesg"; 15222545eb61SSteven Rostedt 152375c3fda7SSteven Rostedt reboot_to; 15242545eb61SSteven Rostedt 15251c8a617aSSteven Rostedt my $success_start; 15261c8a617aSSteven Rostedt my $failure_start; 15272d01b26aSSteven Rostedt my $monitor_start = time; 15282d01b26aSSteven Rostedt my $done = 0; 1529f1a5b962SSteven Rostedt my $version_found = 0; 15301c8a617aSSteven Rostedt 15312d01b26aSSteven Rostedt while (!$done) { 15322545eb61SSteven Rostedt 1533ecaf8e52SSteven Rostedt if ($bug && defined($stop_after_failure) && 1534ecaf8e52SSteven Rostedt $stop_after_failure >= 0) { 1535ecaf8e52SSteven Rostedt my $time = $stop_after_failure - (time - $failure_start); 1536ecaf8e52SSteven Rostedt $line = wait_for_input($monitor_fp, $time); 1537ecaf8e52SSteven Rostedt if (!defined($line)) { 1538ecaf8e52SSteven Rostedt doprint "bug timed out after $booted_timeout seconds\n"; 1539ecaf8e52SSteven Rostedt doprint "Test forced to stop after $stop_after_failure seconds after failure\n"; 1540ecaf8e52SSteven Rostedt last; 1541ecaf8e52SSteven Rostedt } 1542ecaf8e52SSteven Rostedt } elsif ($booted) { 1543a75fececSSteven Rostedt $line = wait_for_input($monitor_fp, $booted_timeout); 1544cd4f1d53SSteven Rostedt if (!defined($line)) { 1545cd4f1d53SSteven Rostedt my $s = $booted_timeout == 1 ? "" : "s"; 1546cd4f1d53SSteven Rostedt doprint "Successful boot found: break after $booted_timeout second$s\n"; 1547cd4f1d53SSteven Rostedt last; 1548cd4f1d53SSteven Rostedt } 15492b7d9b21SSteven Rostedt } else { 15507faafbd6SSteven Rostedt $line = wait_for_input($monitor_fp); 1551cd4f1d53SSteven Rostedt if (!defined($line)) { 1552cd4f1d53SSteven Rostedt my $s = $timeout == 1 ? "" : "s"; 1553cd4f1d53SSteven Rostedt doprint "Timed out after $timeout second$s\n"; 1554cd4f1d53SSteven Rostedt last; 15552b7d9b21SSteven Rostedt } 1556cd4f1d53SSteven Rostedt } 15572545eb61SSteven Rostedt 15582545eb61SSteven Rostedt doprint $line; 15597faafbd6SSteven Rostedt print DMESG $line; 15602545eb61SSteven Rostedt 15612545eb61SSteven Rostedt # we are not guaranteed to get a full line 15622545eb61SSteven Rostedt $full_line .= $line; 15632545eb61SSteven Rostedt 1564a75fececSSteven Rostedt if ($full_line =~ /$success_line/) { 15652545eb61SSteven Rostedt $booted = 1; 15661c8a617aSSteven Rostedt $success_start = time; 15671c8a617aSSteven Rostedt } 15681c8a617aSSteven Rostedt 15691c8a617aSSteven Rostedt if ($booted && defined($stop_after_success) && 15701c8a617aSSteven Rostedt $stop_after_success >= 0) { 15711c8a617aSSteven Rostedt my $now = time; 15721c8a617aSSteven Rostedt if ($now - $success_start >= $stop_after_success) { 15731c8a617aSSteven Rostedt doprint "Test forced to stop after $stop_after_success seconds after success\n"; 15741c8a617aSSteven Rostedt last; 15751c8a617aSSteven Rostedt } 15762545eb61SSteven Rostedt } 15772545eb61SSteven Rostedt 15785c42fc5bSSteven Rostedt if ($full_line =~ /\[ backtrace testing \]/) { 15795c42fc5bSSteven Rostedt $skip_call_trace = 1; 15805c42fc5bSSteven Rostedt } 15815c42fc5bSSteven Rostedt 15822545eb61SSteven Rostedt if ($full_line =~ /call trace:/i) { 15836ca996ccSSteven Rostedt if (!$bug && !$skip_call_trace) { 15846ca996ccSSteven Rostedt if ($ignore_errors) { 15856ca996ccSSteven Rostedt $bug_ignored = 1; 15866ca996ccSSteven Rostedt } else { 15871c8a617aSSteven Rostedt $bug = 1; 15881c8a617aSSteven Rostedt $failure_start = time; 15891c8a617aSSteven Rostedt } 15901c8a617aSSteven Rostedt } 15916ca996ccSSteven Rostedt } 15921c8a617aSSteven Rostedt 15931c8a617aSSteven Rostedt if ($bug && defined($stop_after_failure) && 15941c8a617aSSteven Rostedt $stop_after_failure >= 0) { 15951c8a617aSSteven Rostedt my $now = time; 15961c8a617aSSteven Rostedt if ($now - $failure_start >= $stop_after_failure) { 15971c8a617aSSteven Rostedt doprint "Test forced to stop after $stop_after_failure seconds after failure\n"; 15981c8a617aSSteven Rostedt last; 15991c8a617aSSteven Rostedt } 16005c42fc5bSSteven Rostedt } 16015c42fc5bSSteven Rostedt 16025c42fc5bSSteven Rostedt if ($full_line =~ /\[ end of backtrace testing \]/) { 16035c42fc5bSSteven Rostedt $skip_call_trace = 0; 16045c42fc5bSSteven Rostedt } 16055c42fc5bSSteven Rostedt 16065c42fc5bSSteven Rostedt if ($full_line =~ /Kernel panic -/) { 160710abf118SSteven Rostedt $failure_start = time; 16082545eb61SSteven Rostedt $bug = 1; 16092545eb61SSteven Rostedt } 16102545eb61SSteven Rostedt 1611f1a5b962SSteven Rostedt # Detect triple faults by testing the banner 1612f1a5b962SSteven Rostedt if ($full_line =~ /\bLinux version (\S+).*\n/) { 1613f1a5b962SSteven Rostedt if ($1 eq $version) { 1614f1a5b962SSteven Rostedt $version_found = 1; 1615f1a5b962SSteven Rostedt } elsif ($version_found && $detect_triplefault) { 1616f1a5b962SSteven Rostedt # We already booted into the kernel we are testing, 1617f1a5b962SSteven Rostedt # but now we booted into another kernel? 1618f1a5b962SSteven Rostedt # Consider this a triple fault. 1619f1a5b962SSteven Rostedt doprint "Aleady booted in Linux kernel $version, but now\n"; 1620f1a5b962SSteven Rostedt doprint "we booted into Linux kernel $1.\n"; 1621f1a5b962SSteven Rostedt doprint "Assuming that this is a triple fault.\n"; 1622f1a5b962SSteven Rostedt doprint "To disable this: set DETECT_TRIPLE_FAULT to 0\n"; 1623f1a5b962SSteven Rostedt last; 1624f1a5b962SSteven Rostedt } 1625f1a5b962SSteven Rostedt } 1626f1a5b962SSteven Rostedt 16272545eb61SSteven Rostedt if ($line =~ /\n/) { 16282545eb61SSteven Rostedt $full_line = ""; 16292545eb61SSteven Rostedt } 16302d01b26aSSteven Rostedt 16312d01b26aSSteven Rostedt if ($stop_test_after > 0 && !$booted && !$bug) { 16322d01b26aSSteven Rostedt if (time - $monitor_start > $stop_test_after) { 16334d62bf51SSteven Rostedt doprint "STOP_TEST_AFTER ($stop_test_after seconds) timed out\n"; 16342d01b26aSSteven Rostedt $done = 1; 16352d01b26aSSteven Rostedt } 16362d01b26aSSteven Rostedt } 16372545eb61SSteven Rostedt } 16382545eb61SSteven Rostedt 16397faafbd6SSteven Rostedt close(DMESG); 16402545eb61SSteven Rostedt 16412545eb61SSteven Rostedt if ($bug) { 16422b7d9b21SSteven Rostedt return 0 if ($in_bisect); 1643576f627cSSteven Rostedt fail "failed - got a bug report" and return 0; 16442545eb61SSteven Rostedt } 16455f9b6cedSSteven Rostedt 1646a75fececSSteven Rostedt if (!$booted) { 1647a75fececSSteven Rostedt return 0 if ($in_bisect); 1648576f627cSSteven Rostedt fail "failed - never got a boot prompt." and return 0; 1649a75fececSSteven Rostedt } 1650a75fececSSteven Rostedt 16516ca996ccSSteven Rostedt if ($bug_ignored) { 16526ca996ccSSteven Rostedt doprint "WARNING: Call Trace detected but ignored due to IGNORE_ERRORS=1\n"; 16536ca996ccSSteven Rostedt } 16546ca996ccSSteven Rostedt 16552b7d9b21SSteven Rostedt return 1; 16562545eb61SSteven Rostedt} 16572545eb61SSteven Rostedt 16582b29b2f8SSteven Rostedtsub eval_kernel_version { 16592b29b2f8SSteven Rostedt my ($option) = @_; 16602b29b2f8SSteven Rostedt 16612b29b2f8SSteven Rostedt $option =~ s/\$KERNEL_VERSION/$version/g; 16622b29b2f8SSteven Rostedt 16632b29b2f8SSteven Rostedt return $option; 16642b29b2f8SSteven Rostedt} 16652b29b2f8SSteven Rostedt 1666db05cfefSSteven Rostedtsub do_post_install { 1667db05cfefSSteven Rostedt 1668db05cfefSSteven Rostedt return if (!defined($post_install)); 1669db05cfefSSteven Rostedt 16702b29b2f8SSteven Rostedt my $cp_post_install = eval_kernel_version $post_install; 1671db05cfefSSteven Rostedt run_command "$cp_post_install" or 1672db05cfefSSteven Rostedt dodie "Failed to run post install"; 1673db05cfefSSteven Rostedt} 1674db05cfefSSteven Rostedt 16752545eb61SSteven Rostedtsub install { 16762545eb61SSteven Rostedt 1677e0a8742eSSteven Rostedt return if ($no_install); 1678e0a8742eSSteven Rostedt 1679e5c2ec11SSteven Rostedt if (defined($pre_install)) { 1680e5c2ec11SSteven Rostedt my $cp_pre_install = eval_kernel_version $pre_install; 1681e5c2ec11SSteven Rostedt run_command "$cp_pre_install" or 1682e5c2ec11SSteven Rostedt dodie "Failed to run pre install"; 1683e5c2ec11SSteven Rostedt } 1684e5c2ec11SSteven Rostedt 16852b29b2f8SSteven Rostedt my $cp_target = eval_kernel_version $target_image; 16862b29b2f8SSteven Rostedt 168702ad2617SSteven Rostedt run_scp_install "$outputdir/$build_target", "$cp_target" or 16885c42fc5bSSteven Rostedt dodie "failed to copy image"; 16895f9b6cedSSteven Rostedt 16905f9b6cedSSteven Rostedt my $install_mods = 0; 16915f9b6cedSSteven Rostedt 16925f9b6cedSSteven Rostedt # should we process modules? 16935f9b6cedSSteven Rostedt $install_mods = 0; 169451ad1dd1SSteven Rostedt open(IN, "$output_config") or dodie("Can't read config file"); 16955f9b6cedSSteven Rostedt while (<IN>) { 16965f9b6cedSSteven Rostedt if (/CONFIG_MODULES(=y)?/) { 16975f9b6cedSSteven Rostedt $install_mods = 1 if (defined($1)); 16985f9b6cedSSteven Rostedt last; 16995f9b6cedSSteven Rostedt } 17005f9b6cedSSteven Rostedt } 17015f9b6cedSSteven Rostedt close(IN); 17025f9b6cedSSteven Rostedt 17035f9b6cedSSteven Rostedt if (!$install_mods) { 1704db05cfefSSteven Rostedt do_post_install; 17055f9b6cedSSteven Rostedt doprint "No modules needed\n"; 17065f9b6cedSSteven Rostedt return; 17072545eb61SSteven Rostedt } 17082545eb61SSteven Rostedt 1709627977d8SSteven Rostedt run_command "$make INSTALL_MOD_STRIP=1 INSTALL_MOD_PATH=$tmpdir modules_install" or 17105f9b6cedSSteven Rostedt dodie "Failed to install modules"; 17115f9b6cedSSteven Rostedt 17122545eb61SSteven Rostedt my $modlib = "/lib/modules/$version"; 1713a57419b3SSteven Rostedt my $modtar = "ktest-mods.tar.bz2"; 17142545eb61SSteven Rostedt 1715e48c5293SSteven Rostedt run_ssh "rm -rf $modlib" or 17165c42fc5bSSteven Rostedt dodie "failed to remove old mods: $modlib"; 17172545eb61SSteven Rostedt 17185c42fc5bSSteven Rostedt # would be nice if scp -r did not follow symbolic links 1719a75fececSSteven Rostedt run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or 17205c42fc5bSSteven Rostedt dodie "making tarball"; 17215c42fc5bSSteven Rostedt 172202ad2617SSteven Rostedt run_scp_mod "$tmpdir/$modtar", "/tmp" or 17235c42fc5bSSteven Rostedt dodie "failed to copy modules"; 17245c42fc5bSSteven Rostedt 1725a75fececSSteven Rostedt unlink "$tmpdir/$modtar"; 17265c42fc5bSSteven Rostedt 1727e7b13441SSteven Rostedt run_ssh "'(cd / && tar xjf /tmp/$modtar)'" or 17285c42fc5bSSteven Rostedt dodie "failed to tar modules"; 17295c42fc5bSSteven Rostedt 1730e48c5293SSteven Rostedt run_ssh "rm -f /tmp/$modtar"; 17318b37ca8cSSteven Rostedt 1732db05cfefSSteven Rostedt do_post_install; 17332545eb61SSteven Rostedt} 17342545eb61SSteven Rostedt 1735ddf607e5SSteven Rostedtsub get_version { 1736ddf607e5SSteven Rostedt # get the release name 1737683a3e64SSteven Rostedt return if ($have_version); 1738ddf607e5SSteven Rostedt doprint "$make kernelrelease ... "; 1739ddf607e5SSteven Rostedt $version = `$make kernelrelease | tail -1`; 1740ddf607e5SSteven Rostedt chomp($version); 1741ddf607e5SSteven Rostedt doprint "$version\n"; 1742683a3e64SSteven Rostedt $have_version = 1; 1743ddf607e5SSteven Rostedt} 1744ddf607e5SSteven Rostedt 1745ddf607e5SSteven Rostedtsub start_monitor_and_boot { 17469f7424ccSSteven Rostedt # Make sure the stable kernel has finished booting 17479f7424ccSSteven Rostedt start_monitor; 17489f7424ccSSteven Rostedt wait_for_monitor 5; 17499f7424ccSSteven Rostedt end_monitor; 17509f7424ccSSteven Rostedt 1751ddf607e5SSteven Rostedt get_grub_index; 1752ddf607e5SSteven Rostedt get_version; 1753ddf607e5SSteven Rostedt install; 1754ddf607e5SSteven Rostedt 1755ddf607e5SSteven Rostedt start_monitor; 1756ddf607e5SSteven Rostedt return monitor; 1757ddf607e5SSteven Rostedt} 1758ddf607e5SSteven Rostedt 17596c5ee0beSSteven Rostedtsub check_buildlog { 17606c5ee0beSSteven Rostedt my ($patch) = @_; 17616c5ee0beSSteven Rostedt 17626c5ee0beSSteven Rostedt my @files = `git show $patch | diffstat -l`; 17636c5ee0beSSteven Rostedt 17646c5ee0beSSteven Rostedt open(IN, "git show $patch |") or 17656c5ee0beSSteven Rostedt dodie "failed to show $patch"; 17666c5ee0beSSteven Rostedt while (<IN>) { 17676c5ee0beSSteven Rostedt if (m,^--- a/(.*),) { 17686c5ee0beSSteven Rostedt chomp $1; 17696c5ee0beSSteven Rostedt $files[$#files] = $1; 17706c5ee0beSSteven Rostedt } 17716c5ee0beSSteven Rostedt } 17726c5ee0beSSteven Rostedt close(IN); 17736c5ee0beSSteven Rostedt 17746c5ee0beSSteven Rostedt open(IN, $buildlog) or dodie "Can't open $buildlog"; 17756c5ee0beSSteven Rostedt while (<IN>) { 17766c5ee0beSSteven Rostedt if (/^\s*(.*?):.*(warning|error)/) { 17776c5ee0beSSteven Rostedt my $err = $1; 17786c5ee0beSSteven Rostedt foreach my $file (@files) { 1779a75fececSSteven Rostedt my $fullpath = "$builddir/$file"; 17806c5ee0beSSteven Rostedt if ($file eq $err || $fullpath eq $err) { 17812b7d9b21SSteven Rostedt fail "$file built with warnings" and return 0; 17826c5ee0beSSteven Rostedt } 17836c5ee0beSSteven Rostedt } 17846c5ee0beSSteven Rostedt } 17856c5ee0beSSteven Rostedt } 17866c5ee0beSSteven Rostedt close(IN); 17872b7d9b21SSteven Rostedt 17882b7d9b21SSteven Rostedt return 1; 17896c5ee0beSSteven Rostedt} 17906c5ee0beSSteven Rostedt 1791fcb3f16aSSteven Rostedtsub apply_min_config { 1792fcb3f16aSSteven Rostedt my $outconfig = "$output_config.new"; 1793612b9e9bSSteven Rostedt 1794fcb3f16aSSteven Rostedt # Read the config file and remove anything that 1795fcb3f16aSSteven Rostedt # is in the force_config hash (from minconfig and others) 1796fcb3f16aSSteven Rostedt # then add the force config back. 1797fcb3f16aSSteven Rostedt 1798fcb3f16aSSteven Rostedt doprint "Applying minimum configurations into $output_config.new\n"; 1799fcb3f16aSSteven Rostedt 1800fcb3f16aSSteven Rostedt open (OUT, ">$outconfig") or 1801fcb3f16aSSteven Rostedt dodie "Can't create $outconfig"; 1802fcb3f16aSSteven Rostedt 1803fcb3f16aSSteven Rostedt if (-f $output_config) { 1804fcb3f16aSSteven Rostedt open (IN, $output_config) or 1805fcb3f16aSSteven Rostedt dodie "Failed to open $output_config"; 1806fcb3f16aSSteven Rostedt while (<IN>) { 1807fcb3f16aSSteven Rostedt if (/^(# )?(CONFIG_[^\s=]*)/) { 1808fcb3f16aSSteven Rostedt next if (defined($force_config{$2})); 1809fcb3f16aSSteven Rostedt } 1810fcb3f16aSSteven Rostedt print OUT; 1811fcb3f16aSSteven Rostedt } 1812fcb3f16aSSteven Rostedt close IN; 1813fcb3f16aSSteven Rostedt } 1814fcb3f16aSSteven Rostedt foreach my $config (keys %force_config) { 1815fcb3f16aSSteven Rostedt print OUT "$force_config{$config}\n"; 1816fcb3f16aSSteven Rostedt } 1817fcb3f16aSSteven Rostedt close OUT; 1818fcb3f16aSSteven Rostedt 1819fcb3f16aSSteven Rostedt run_command "mv $outconfig $output_config"; 1820fcb3f16aSSteven Rostedt} 1821fcb3f16aSSteven Rostedt 1822fcb3f16aSSteven Rostedtsub make_oldconfig { 1823fcb3f16aSSteven Rostedt 18244c4ab120SSteven Rostedt my @force_list = keys %force_config; 18254c4ab120SSteven Rostedt 18264c4ab120SSteven Rostedt if ($#force_list >= 0) { 1827fcb3f16aSSteven Rostedt apply_min_config; 18284c4ab120SSteven Rostedt } 1829fcb3f16aSSteven Rostedt 1830fcb3f16aSSteven Rostedt if (!run_command "$make oldnoconfig") { 1831612b9e9bSSteven Rostedt # Perhaps oldnoconfig doesn't exist in this version of the kernel 1832612b9e9bSSteven Rostedt # try a yes '' | oldconfig 1833612b9e9bSSteven Rostedt doprint "oldnoconfig failed, trying yes '' | make oldconfig\n"; 1834fcb3f16aSSteven Rostedt run_command "yes '' | $make oldconfig" or 1835612b9e9bSSteven Rostedt dodie "failed make config oldconfig"; 1836612b9e9bSSteven Rostedt } 1837612b9e9bSSteven Rostedt} 1838612b9e9bSSteven Rostedt 1839fcb3f16aSSteven Rostedt# read a config file and use this to force new configs. 1840fcb3f16aSSteven Rostedtsub load_force_config { 1841fcb3f16aSSteven Rostedt my ($config) = @_; 1842fcb3f16aSSteven Rostedt 1843*cf79fab6SSteven Rostedt doprint "Loading force configs from $config\n"; 1844fcb3f16aSSteven Rostedt open(IN, $config) or 1845fcb3f16aSSteven Rostedt dodie "failed to read $config"; 1846fcb3f16aSSteven Rostedt while (<IN>) { 1847fcb3f16aSSteven Rostedt chomp; 1848fcb3f16aSSteven Rostedt if (/^(CONFIG[^\s=]*)(\s*=.*)/) { 1849fcb3f16aSSteven Rostedt $force_config{$1} = $_; 1850fcb3f16aSSteven Rostedt } elsif (/^# (CONFIG_\S*) is not set/) { 1851fcb3f16aSSteven Rostedt $force_config{$1} = $_; 1852fcb3f16aSSteven Rostedt } 1853fcb3f16aSSteven Rostedt } 1854fcb3f16aSSteven Rostedt close IN; 1855fcb3f16aSSteven Rostedt} 1856fcb3f16aSSteven Rostedt 18572545eb61SSteven Rostedtsub build { 18582545eb61SSteven Rostedt my ($type) = @_; 18592545eb61SSteven Rostedt 18607faafbd6SSteven Rostedt unlink $buildlog; 18617faafbd6SSteven Rostedt 18624ab1cce5SSteven Rostedt # Failed builds should not reboot the target 18634ab1cce5SSteven Rostedt my $save_no_reboot = $no_reboot; 18644ab1cce5SSteven Rostedt $no_reboot = 1; 18654ab1cce5SSteven Rostedt 1866683a3e64SSteven Rostedt # Calculate a new version from here. 1867683a3e64SSteven Rostedt $have_version = 0; 1868683a3e64SSteven Rostedt 18690bd6c1a3SSteven Rostedt if (defined($pre_build)) { 18700bd6c1a3SSteven Rostedt my $ret = run_command $pre_build; 18710bd6c1a3SSteven Rostedt if (!$ret && defined($pre_build_die) && 18720bd6c1a3SSteven Rostedt $pre_build_die) { 18730bd6c1a3SSteven Rostedt dodie "failed to pre_build\n"; 18740bd6c1a3SSteven Rostedt } 18750bd6c1a3SSteven Rostedt } 18760bd6c1a3SSteven Rostedt 187775c3fda7SSteven Rostedt if ($type =~ /^useconfig:(.*)/) { 187851ad1dd1SSteven Rostedt run_command "cp $1 $output_config" or 187975c3fda7SSteven Rostedt dodie "could not copy $1 to .config"; 18805f9b6cedSSteven Rostedt 188175c3fda7SSteven Rostedt $type = "oldconfig"; 188275c3fda7SSteven Rostedt } 188375c3fda7SSteven Rostedt 18845c42fc5bSSteven Rostedt # old config can ask questions 18855c42fc5bSSteven Rostedt if ($type eq "oldconfig") { 18869386c6abSSteven Rostedt $type = "oldnoconfig"; 188775c3fda7SSteven Rostedt 188875c3fda7SSteven Rostedt # allow for empty configs 188951ad1dd1SSteven Rostedt run_command "touch $output_config"; 189075c3fda7SSteven Rostedt 189113488231SAndrew Jones if (!$noclean) { 189251ad1dd1SSteven Rostedt run_command "mv $output_config $outputdir/config_temp" or 18935c42fc5bSSteven Rostedt dodie "moving .config"; 18945c42fc5bSSteven Rostedt 189513488231SAndrew Jones run_command "$make mrproper" or dodie "make mrproper"; 18965c42fc5bSSteven Rostedt 189751ad1dd1SSteven Rostedt run_command "mv $outputdir/config_temp $output_config" or 18985c42fc5bSSteven Rostedt dodie "moving config_temp"; 189913488231SAndrew Jones } 19005c42fc5bSSteven Rostedt 19015c42fc5bSSteven Rostedt } elsif (!$noclean) { 190251ad1dd1SSteven Rostedt unlink "$output_config"; 19035f9b6cedSSteven Rostedt run_command "$make mrproper" or 19045c42fc5bSSteven Rostedt dodie "make mrproper"; 19055c42fc5bSSteven Rostedt } 19062545eb61SSteven Rostedt 19072545eb61SSteven Rostedt # add something to distinguish this build 1908a75fececSSteven Rostedt open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file"); 1909a75fececSSteven Rostedt print OUT "$localversion\n"; 19102545eb61SSteven Rostedt close(OUT); 19112545eb61SSteven Rostedt 19125f9b6cedSSteven Rostedt if (defined($minconfig)) { 1913fcb3f16aSSteven Rostedt load_force_config($minconfig); 19142545eb61SSteven Rostedt } 19152545eb61SSteven Rostedt 1916fcb3f16aSSteven Rostedt if ($type ne "oldnoconfig") { 1917fcb3f16aSSteven Rostedt run_command "$make $type" or 19185c42fc5bSSteven Rostedt dodie "failed make config"; 1919612b9e9bSSteven Rostedt } 1920fcb3f16aSSteven Rostedt # Run old config regardless, to enforce min configurations 1921fcb3f16aSSteven Rostedt make_oldconfig; 19222545eb61SSteven Rostedt 1923a75fececSSteven Rostedt $redirect = "$buildlog"; 19240bd6c1a3SSteven Rostedt my $build_ret = run_command "$make $build_options"; 19256c5ee0beSSteven Rostedt undef $redirect; 19260bd6c1a3SSteven Rostedt 19270bd6c1a3SSteven Rostedt if (defined($post_build)) { 1928683a3e64SSteven Rostedt # Because a post build may change the kernel version 1929683a3e64SSteven Rostedt # do it now. 1930683a3e64SSteven Rostedt get_version; 19310bd6c1a3SSteven Rostedt my $ret = run_command $post_build; 19320bd6c1a3SSteven Rostedt if (!$ret && defined($post_build_die) && 19330bd6c1a3SSteven Rostedt $post_build_die) { 19340bd6c1a3SSteven Rostedt dodie "failed to post_build\n"; 19350bd6c1a3SSteven Rostedt } 19360bd6c1a3SSteven Rostedt } 19370bd6c1a3SSteven Rostedt 19380bd6c1a3SSteven Rostedt if (!$build_ret) { 19395f9b6cedSSteven Rostedt # bisect may need this to pass 19404ab1cce5SSteven Rostedt if ($in_bisect) { 19414ab1cce5SSteven Rostedt $no_reboot = $save_no_reboot; 19424ab1cce5SSteven Rostedt return 0; 19434ab1cce5SSteven Rostedt } 19442b7d9b21SSteven Rostedt fail "failed build" and return 0; 19452545eb61SSteven Rostedt } 19465f9b6cedSSteven Rostedt 19474ab1cce5SSteven Rostedt $no_reboot = $save_no_reboot; 19484ab1cce5SSteven Rostedt 19492b7d9b21SSteven Rostedt return 1; 19502545eb61SSteven Rostedt} 19512545eb61SSteven Rostedt 195275c3fda7SSteven Rostedtsub halt { 1953e48c5293SSteven Rostedt if (!run_ssh "halt" or defined($power_off)) { 1954576f627cSSteven Rostedt if (defined($poweroff_after_halt)) { 1955576f627cSSteven Rostedt sleep $poweroff_after_halt; 1956576f627cSSteven Rostedt run_command "$power_off"; 1957576f627cSSteven Rostedt } 1958576f627cSSteven Rostedt } else { 195975c3fda7SSteven Rostedt # nope? the zap it! 1960a75fececSSteven Rostedt run_command "$power_off"; 196175c3fda7SSteven Rostedt } 196275c3fda7SSteven Rostedt} 196375c3fda7SSteven Rostedt 19645f9b6cedSSteven Rostedtsub success { 19655f9b6cedSSteven Rostedt my ($i) = @_; 19665f9b6cedSSteven Rostedt 1967921ed4c7SSteven Rostedt if (defined($post_test)) { 1968921ed4c7SSteven Rostedt run_command $post_test; 1969921ed4c7SSteven Rostedt } 1970921ed4c7SSteven Rostedt 1971e48c5293SSteven Rostedt $successes++; 1972e48c5293SSteven Rostedt 19739064af52SSteven Rostedt my $name = ""; 19749064af52SSteven Rostedt 19759064af52SSteven Rostedt if (defined($test_name)) { 19769064af52SSteven Rostedt $name = " ($test_name)"; 19779064af52SSteven Rostedt } 19789064af52SSteven Rostedt 19795f9b6cedSSteven Rostedt doprint "\n\n*******************************************\n"; 19805f9b6cedSSteven Rostedt doprint "*******************************************\n"; 19819064af52SSteven Rostedt doprint "KTEST RESULT: TEST $i$name SUCCESS!!!! **\n"; 19825f9b6cedSSteven Rostedt doprint "*******************************************\n"; 19835f9b6cedSSteven Rostedt doprint "*******************************************\n"; 19845f9b6cedSSteven Rostedt 1985de5b6e3bSRabin Vincent if (defined($store_successes)) { 1986de5b6e3bSRabin Vincent save_logs "success", $store_successes; 1987de5b6e3bSRabin Vincent } 1988de5b6e3bSRabin Vincent 1989576f627cSSteven Rostedt if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) { 1990a75fececSSteven Rostedt doprint "Reboot and wait $sleep_time seconds\n"; 1991bc7c5803SSteven Rostedt reboot_to_good $sleep_time; 19925f9b6cedSSteven Rostedt } 19935f9b6cedSSteven Rostedt} 19945f9b6cedSSteven Rostedt 1995c960bb9fSSteven Rostedtsub answer_bisect { 1996c960bb9fSSteven Rostedt for (;;) { 1997c960bb9fSSteven Rostedt doprint "Pass or fail? [p/f]"; 1998c960bb9fSSteven Rostedt my $ans = <STDIN>; 1999c960bb9fSSteven Rostedt chomp $ans; 2000c960bb9fSSteven Rostedt if ($ans eq "p" || $ans eq "P") { 2001c960bb9fSSteven Rostedt return 1; 2002c960bb9fSSteven Rostedt } elsif ($ans eq "f" || $ans eq "F") { 2003c960bb9fSSteven Rostedt return 0; 2004c960bb9fSSteven Rostedt } else { 2005c960bb9fSSteven Rostedt print "Please answer 'P' or 'F'\n"; 2006c960bb9fSSteven Rostedt } 2007c960bb9fSSteven Rostedt } 2008c960bb9fSSteven Rostedt} 2009c960bb9fSSteven Rostedt 20105a391fbfSSteven Rostedtsub child_run_test { 20117faafbd6SSteven Rostedt my $failed = 0; 20125a391fbfSSteven Rostedt 20137faafbd6SSteven Rostedt # child should have no power 2014a75fececSSteven Rostedt $reboot_on_error = 0; 2015a75fececSSteven Rostedt $poweroff_on_error = 0; 2016a75fececSSteven Rostedt $die_on_failure = 1; 20177faafbd6SSteven Rostedt 2018a9dd5d63SRabin Vincent $redirect = "$testlog"; 20197faafbd6SSteven Rostedt run_command $run_test or $failed = 1; 2020a9dd5d63SRabin Vincent undef $redirect; 2021a9dd5d63SRabin Vincent 20225a391fbfSSteven Rostedt exit $failed; 20235a391fbfSSteven Rostedt} 20245a391fbfSSteven Rostedt 20255a391fbfSSteven Rostedtmy $child_done; 20265a391fbfSSteven Rostedt 20275a391fbfSSteven Rostedtsub child_finished { 20285a391fbfSSteven Rostedt $child_done = 1; 20295a391fbfSSteven Rostedt} 20305a391fbfSSteven Rostedt 20315a391fbfSSteven Rostedtsub do_run_test { 20325a391fbfSSteven Rostedt my $child_pid; 20335a391fbfSSteven Rostedt my $child_exit; 20345a391fbfSSteven Rostedt my $line; 20355a391fbfSSteven Rostedt my $full_line; 20365a391fbfSSteven Rostedt my $bug = 0; 20375a391fbfSSteven Rostedt 20387faafbd6SSteven Rostedt wait_for_monitor 1; 20395a391fbfSSteven Rostedt 20407faafbd6SSteven Rostedt doprint "run test $run_test\n"; 20415a391fbfSSteven Rostedt 20425a391fbfSSteven Rostedt $child_done = 0; 20435a391fbfSSteven Rostedt 20445a391fbfSSteven Rostedt $SIG{CHLD} = qw(child_finished); 20455a391fbfSSteven Rostedt 20465a391fbfSSteven Rostedt $child_pid = fork; 20475a391fbfSSteven Rostedt 20485a391fbfSSteven Rostedt child_run_test if (!$child_pid); 20495a391fbfSSteven Rostedt 20505a391fbfSSteven Rostedt $full_line = ""; 20515a391fbfSSteven Rostedt 20525a391fbfSSteven Rostedt do { 20537faafbd6SSteven Rostedt $line = wait_for_input($monitor_fp, 1); 20545a391fbfSSteven Rostedt if (defined($line)) { 20555a391fbfSSteven Rostedt 20565a391fbfSSteven Rostedt # we are not guaranteed to get a full line 20575a391fbfSSteven Rostedt $full_line .= $line; 20588ea0e063SSteven Rostedt doprint $line; 20595a391fbfSSteven Rostedt 20605a391fbfSSteven Rostedt if ($full_line =~ /call trace:/i) { 20615a391fbfSSteven Rostedt $bug = 1; 20625a391fbfSSteven Rostedt } 20635a391fbfSSteven Rostedt 20645a391fbfSSteven Rostedt if ($full_line =~ /Kernel panic -/) { 20655a391fbfSSteven Rostedt $bug = 1; 20665a391fbfSSteven Rostedt } 20675a391fbfSSteven Rostedt 20685a391fbfSSteven Rostedt if ($line =~ /\n/) { 20695a391fbfSSteven Rostedt $full_line = ""; 20705a391fbfSSteven Rostedt } 20715a391fbfSSteven Rostedt } 20725a391fbfSSteven Rostedt } while (!$child_done && !$bug); 20735a391fbfSSteven Rostedt 20745a391fbfSSteven Rostedt if ($bug) { 20758ea0e063SSteven Rostedt my $failure_start = time; 20768ea0e063SSteven Rostedt my $now; 20778ea0e063SSteven Rostedt do { 20788ea0e063SSteven Rostedt $line = wait_for_input($monitor_fp, 1); 20798ea0e063SSteven Rostedt if (defined($line)) { 20808ea0e063SSteven Rostedt doprint $line; 20818ea0e063SSteven Rostedt } 20828ea0e063SSteven Rostedt $now = time; 20838ea0e063SSteven Rostedt if ($now - $failure_start >= $stop_after_failure) { 20848ea0e063SSteven Rostedt last; 20858ea0e063SSteven Rostedt } 20868ea0e063SSteven Rostedt } while (defined($line)); 20878ea0e063SSteven Rostedt 20885a391fbfSSteven Rostedt doprint "Detected kernel crash!\n"; 20895a391fbfSSteven Rostedt # kill the child with extreme prejudice 20905a391fbfSSteven Rostedt kill 9, $child_pid; 20915a391fbfSSteven Rostedt } 20925a391fbfSSteven Rostedt 20935a391fbfSSteven Rostedt waitpid $child_pid, 0; 20945a391fbfSSteven Rostedt $child_exit = $?; 20955a391fbfSSteven Rostedt 2096c5dacb88SSteven Rostedt if (!$bug && $in_bisect) { 2097c5dacb88SSteven Rostedt if (defined($bisect_ret_good)) { 2098c5dacb88SSteven Rostedt if ($child_exit == $bisect_ret_good) { 2099c5dacb88SSteven Rostedt return 1; 2100c5dacb88SSteven Rostedt } 2101c5dacb88SSteven Rostedt } 2102c5dacb88SSteven Rostedt if (defined($bisect_ret_skip)) { 2103c5dacb88SSteven Rostedt if ($child_exit == $bisect_ret_skip) { 2104c5dacb88SSteven Rostedt return -1; 2105c5dacb88SSteven Rostedt } 2106c5dacb88SSteven Rostedt } 2107c5dacb88SSteven Rostedt if (defined($bisect_ret_abort)) { 2108c5dacb88SSteven Rostedt if ($child_exit == $bisect_ret_abort) { 2109c5dacb88SSteven Rostedt fail "test abort" and return -2; 2110c5dacb88SSteven Rostedt } 2111c5dacb88SSteven Rostedt } 2112c5dacb88SSteven Rostedt if (defined($bisect_ret_bad)) { 2113c5dacb88SSteven Rostedt if ($child_exit == $bisect_ret_skip) { 2114c5dacb88SSteven Rostedt return 0; 2115c5dacb88SSteven Rostedt } 2116c5dacb88SSteven Rostedt } 2117c5dacb88SSteven Rostedt if (defined($bisect_ret_default)) { 2118c5dacb88SSteven Rostedt if ($bisect_ret_default eq "good") { 2119c5dacb88SSteven Rostedt return 1; 2120c5dacb88SSteven Rostedt } elsif ($bisect_ret_default eq "bad") { 2121c5dacb88SSteven Rostedt return 0; 2122c5dacb88SSteven Rostedt } elsif ($bisect_ret_default eq "skip") { 2123c5dacb88SSteven Rostedt return -1; 2124c5dacb88SSteven Rostedt } elsif ($bisect_ret_default eq "abort") { 2125c5dacb88SSteven Rostedt return -2; 2126c5dacb88SSteven Rostedt } else { 2127c5dacb88SSteven Rostedt fail "unknown default action: $bisect_ret_default" 2128c5dacb88SSteven Rostedt and return -2; 2129c5dacb88SSteven Rostedt } 2130c5dacb88SSteven Rostedt } 2131c5dacb88SSteven Rostedt } 2132c5dacb88SSteven Rostedt 21335a391fbfSSteven Rostedt if ($bug || $child_exit) { 21342b7d9b21SSteven Rostedt return 0 if $in_bisect; 21352b7d9b21SSteven Rostedt fail "test failed" and return 0; 21365a391fbfSSteven Rostedt } 21372b7d9b21SSteven Rostedt return 1; 21385a391fbfSSteven Rostedt} 21395a391fbfSSteven Rostedt 2140a75fececSSteven Rostedtsub run_git_bisect { 2141a75fececSSteven Rostedt my ($command) = @_; 2142a75fececSSteven Rostedt 2143a75fececSSteven Rostedt doprint "$command ... "; 2144a75fececSSteven Rostedt 2145a75fececSSteven Rostedt my $output = `$command 2>&1`; 2146a75fececSSteven Rostedt my $ret = $?; 2147a75fececSSteven Rostedt 2148a75fececSSteven Rostedt logit $output; 2149a75fececSSteven Rostedt 2150a75fececSSteven Rostedt if ($ret) { 2151a75fececSSteven Rostedt doprint "FAILED\n"; 2152a75fececSSteven Rostedt dodie "Failed to git bisect"; 2153a75fececSSteven Rostedt } 2154a75fececSSteven Rostedt 2155a75fececSSteven Rostedt doprint "SUCCESS\n"; 2156a75fececSSteven Rostedt if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) { 2157a75fececSSteven Rostedt doprint "$1 [$2]\n"; 2158a75fececSSteven Rostedt } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) { 2159b5f4aea6SSteven Rostedt $bisect_bad_commit = $1; 2160a75fececSSteven Rostedt doprint "Found bad commit... $1\n"; 2161a75fececSSteven Rostedt return 0; 2162a75fececSSteven Rostedt } else { 2163a75fececSSteven Rostedt # we already logged it, just print it now. 2164a75fececSSteven Rostedt print $output; 2165a75fececSSteven Rostedt } 2166a75fececSSteven Rostedt 2167a75fececSSteven Rostedt return 1; 2168a75fececSSteven Rostedt} 2169a75fececSSteven Rostedt 2170c23dca7cSSteven Rostedtsub bisect_reboot { 2171c23dca7cSSteven Rostedt doprint "Reboot and sleep $bisect_sleep_time seconds\n"; 2172bc7c5803SSteven Rostedt reboot_to_good $bisect_sleep_time; 2173c23dca7cSSteven Rostedt} 2174c23dca7cSSteven Rostedt 2175c23dca7cSSteven Rostedt# returns 1 on success, 0 on failure, -1 on skip 21760a05c769SSteven Rostedtsub run_bisect_test { 21770a05c769SSteven Rostedt my ($type, $buildtype) = @_; 21785f9b6cedSSteven Rostedt 21792b7d9b21SSteven Rostedt my $failed = 0; 21805f9b6cedSSteven Rostedt my $result; 21815f9b6cedSSteven Rostedt my $output; 21825f9b6cedSSteven Rostedt my $ret; 21835f9b6cedSSteven Rostedt 21840a05c769SSteven Rostedt $in_bisect = 1; 21850a05c769SSteven Rostedt 21860a05c769SSteven Rostedt build $buildtype or $failed = 1; 21875f9b6cedSSteven Rostedt 21885f9b6cedSSteven Rostedt if ($type ne "build") { 2189c23dca7cSSteven Rostedt if ($failed && $bisect_skip) { 2190c23dca7cSSteven Rostedt $in_bisect = 0; 2191c23dca7cSSteven Rostedt return -1; 2192c23dca7cSSteven Rostedt } 21937faafbd6SSteven Rostedt dodie "Failed on build" if $failed; 21945f9b6cedSSteven Rostedt 21955f9b6cedSSteven Rostedt # Now boot the box 2196ddf607e5SSteven Rostedt start_monitor_and_boot or $failed = 1; 21975f9b6cedSSteven Rostedt 21985f9b6cedSSteven Rostedt if ($type ne "boot") { 2199c23dca7cSSteven Rostedt if ($failed && $bisect_skip) { 2200c23dca7cSSteven Rostedt end_monitor; 2201c23dca7cSSteven Rostedt bisect_reboot; 2202c23dca7cSSteven Rostedt $in_bisect = 0; 2203c23dca7cSSteven Rostedt return -1; 2204c23dca7cSSteven Rostedt } 22057faafbd6SSteven Rostedt dodie "Failed on boot" if $failed; 22065a391fbfSSteven Rostedt 22072b7d9b21SSteven Rostedt do_run_test or $failed = 1; 22085f9b6cedSSteven Rostedt } 22097faafbd6SSteven Rostedt end_monitor; 22105f9b6cedSSteven Rostedt } 22115f9b6cedSSteven Rostedt 22125f9b6cedSSteven Rostedt if ($failed) { 22130a05c769SSteven Rostedt $result = 0; 22145f9b6cedSSteven Rostedt } else { 22150a05c769SSteven Rostedt $result = 1; 22165f9b6cedSSteven Rostedt } 22174025bc62SSteven Rostedt 22184025bc62SSteven Rostedt # reboot the box to a kernel we can ssh to 22194025bc62SSteven Rostedt if ($type ne "build") { 22204025bc62SSteven Rostedt bisect_reboot; 22214025bc62SSteven Rostedt } 22220a05c769SSteven Rostedt $in_bisect = 0; 22230a05c769SSteven Rostedt 22240a05c769SSteven Rostedt return $result; 22250a05c769SSteven Rostedt} 22260a05c769SSteven Rostedt 22270a05c769SSteven Rostedtsub run_bisect { 22280a05c769SSteven Rostedt my ($type) = @_; 22290a05c769SSteven Rostedt my $buildtype = "oldconfig"; 22300a05c769SSteven Rostedt 22310a05c769SSteven Rostedt # We should have a minconfig to use? 22320a05c769SSteven Rostedt if (defined($minconfig)) { 22330a05c769SSteven Rostedt $buildtype = "useconfig:$minconfig"; 22340a05c769SSteven Rostedt } 22350a05c769SSteven Rostedt 22360a05c769SSteven Rostedt my $ret = run_bisect_test $type, $buildtype; 22370a05c769SSteven Rostedt 2238c960bb9fSSteven Rostedt if ($bisect_manual) { 2239c960bb9fSSteven Rostedt $ret = answer_bisect; 2240c960bb9fSSteven Rostedt } 22415f9b6cedSSteven Rostedt 2242d6ce2a0bSSteven Rostedt # Are we looking for where it worked, not failed? 22435158ba3eSRuss Dill if ($reverse_bisect && $ret >= 0) { 22440a05c769SSteven Rostedt $ret = !$ret; 2245d6ce2a0bSSteven Rostedt } 2246d6ce2a0bSSteven Rostedt 2247c23dca7cSSteven Rostedt if ($ret > 0) { 22480a05c769SSteven Rostedt return "good"; 2249c23dca7cSSteven Rostedt } elsif ($ret == 0) { 22500a05c769SSteven Rostedt return "bad"; 2251c23dca7cSSteven Rostedt } elsif ($bisect_skip) { 2252c23dca7cSSteven Rostedt doprint "HIT A BAD COMMIT ... SKIPPING\n"; 2253c23dca7cSSteven Rostedt return "skip"; 22540a05c769SSteven Rostedt } 22555f9b6cedSSteven Rostedt} 22565f9b6cedSSteven Rostedt 2257dad98754SSteven Rostedtsub update_bisect_replay { 2258dad98754SSteven Rostedt my $tmp_log = "$tmpdir/ktest_bisect_log"; 2259dad98754SSteven Rostedt run_command "git bisect log > $tmp_log" or 2260dad98754SSteven Rostedt die "can't create bisect log"; 2261dad98754SSteven Rostedt return $tmp_log; 2262dad98754SSteven Rostedt} 2263dad98754SSteven Rostedt 22645f9b6cedSSteven Rostedtsub bisect { 22655f9b6cedSSteven Rostedt my ($i) = @_; 22665f9b6cedSSteven Rostedt 22675f9b6cedSSteven Rostedt my $result; 22685f9b6cedSSteven Rostedt 2269b5f4aea6SSteven Rostedt die "BISECT_GOOD[$i] not defined\n" if (!defined($bisect_good)); 2270b5f4aea6SSteven Rostedt die "BISECT_BAD[$i] not defined\n" if (!defined($bisect_bad)); 2271b5f4aea6SSteven Rostedt die "BISECT_TYPE[$i] not defined\n" if (!defined($bisect_type)); 22725f9b6cedSSteven Rostedt 2273b5f4aea6SSteven Rostedt my $good = $bisect_good; 2274b5f4aea6SSteven Rostedt my $bad = $bisect_bad; 2275b5f4aea6SSteven Rostedt my $type = $bisect_type; 2276b5f4aea6SSteven Rostedt my $start = $bisect_start; 2277b5f4aea6SSteven Rostedt my $replay = $bisect_replay; 2278b5f4aea6SSteven Rostedt my $start_files = $bisect_files; 22793410f6fdSSteven Rostedt 22803410f6fdSSteven Rostedt if (defined($start_files)) { 22813410f6fdSSteven Rostedt $start_files = " -- " . $start_files; 22823410f6fdSSteven Rostedt } else { 22833410f6fdSSteven Rostedt $start_files = ""; 22843410f6fdSSteven Rostedt } 22855f9b6cedSSteven Rostedt 2286a57419b3SSteven Rostedt # convert to true sha1's 2287a57419b3SSteven Rostedt $good = get_sha1($good); 2288a57419b3SSteven Rostedt $bad = get_sha1($bad); 2289a57419b3SSteven Rostedt 2290b5f4aea6SSteven Rostedt if (defined($bisect_reverse) && $bisect_reverse == 1) { 2291d6ce2a0bSSteven Rostedt doprint "Performing a reverse bisect (bad is good, good is bad!)\n"; 2292d6ce2a0bSSteven Rostedt $reverse_bisect = 1; 2293d6ce2a0bSSteven Rostedt } else { 2294d6ce2a0bSSteven Rostedt $reverse_bisect = 0; 2295d6ce2a0bSSteven Rostedt } 2296d6ce2a0bSSteven Rostedt 22975a391fbfSSteven Rostedt # Can't have a test without having a test to run 22985a391fbfSSteven Rostedt if ($type eq "test" && !defined($run_test)) { 22995a391fbfSSteven Rostedt $type = "boot"; 23005a391fbfSSteven Rostedt } 23015a391fbfSSteven Rostedt 2302dad98754SSteven Rostedt # Check if a bisect was running 2303dad98754SSteven Rostedt my $bisect_start_file = "$builddir/.git/BISECT_START"; 2304dad98754SSteven Rostedt 2305b5f4aea6SSteven Rostedt my $check = $bisect_check; 2306dad98754SSteven Rostedt my $do_check = defined($check) && $check ne "0"; 2307dad98754SSteven Rostedt 2308dad98754SSteven Rostedt if ( -f $bisect_start_file ) { 2309dad98754SSteven Rostedt print "Bisect in progress found\n"; 2310dad98754SSteven Rostedt if ($do_check) { 2311dad98754SSteven Rostedt print " If you say yes, then no checks of good or bad will be done\n"; 2312dad98754SSteven Rostedt } 2313dad98754SSteven Rostedt if (defined($replay)) { 2314dad98754SSteven Rostedt print "** BISECT_REPLAY is defined in config file **"; 2315dad98754SSteven Rostedt print " Ignore config option and perform new git bisect log?\n"; 2316dad98754SSteven Rostedt if (read_ync " (yes, no, or cancel) ") { 2317dad98754SSteven Rostedt $replay = update_bisect_replay; 2318dad98754SSteven Rostedt $do_check = 0; 2319dad98754SSteven Rostedt } 2320dad98754SSteven Rostedt } elsif (read_yn "read git log and continue?") { 2321dad98754SSteven Rostedt $replay = update_bisect_replay; 2322dad98754SSteven Rostedt $do_check = 0; 2323dad98754SSteven Rostedt } 2324dad98754SSteven Rostedt } 2325dad98754SSteven Rostedt 2326dad98754SSteven Rostedt if ($do_check) { 2327a75fececSSteven Rostedt 2328a75fececSSteven Rostedt # get current HEAD 2329a57419b3SSteven Rostedt my $head = get_sha1("HEAD"); 2330a75fececSSteven Rostedt 2331a75fececSSteven Rostedt if ($check ne "good") { 2332a75fececSSteven Rostedt doprint "TESTING BISECT BAD [$bad]\n"; 2333a75fececSSteven Rostedt run_command "git checkout $bad" or 2334a75fececSSteven Rostedt die "Failed to checkout $bad"; 2335a75fececSSteven Rostedt 2336a75fececSSteven Rostedt $result = run_bisect $type; 2337a75fececSSteven Rostedt 2338a75fececSSteven Rostedt if ($result ne "bad") { 2339a75fececSSteven Rostedt fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0; 2340a75fececSSteven Rostedt } 2341a75fececSSteven Rostedt } 2342a75fececSSteven Rostedt 2343a75fececSSteven Rostedt if ($check ne "bad") { 2344a75fececSSteven Rostedt doprint "TESTING BISECT GOOD [$good]\n"; 2345a75fececSSteven Rostedt run_command "git checkout $good" or 2346a75fececSSteven Rostedt die "Failed to checkout $good"; 2347a75fececSSteven Rostedt 2348a75fececSSteven Rostedt $result = run_bisect $type; 2349a75fececSSteven Rostedt 2350a75fececSSteven Rostedt if ($result ne "good") { 2351a75fececSSteven Rostedt fail "Tested BISECT_GOOD [$good] and it failed" and return 0; 2352a75fececSSteven Rostedt } 2353a75fececSSteven Rostedt } 2354a75fececSSteven Rostedt 2355a75fececSSteven Rostedt # checkout where we started 2356a75fececSSteven Rostedt run_command "git checkout $head" or 2357a75fececSSteven Rostedt die "Failed to checkout $head"; 2358a75fececSSteven Rostedt } 2359a75fececSSteven Rostedt 23603410f6fdSSteven Rostedt run_command "git bisect start$start_files" or 2361a75fececSSteven Rostedt dodie "could not start bisect"; 2362a75fececSSteven Rostedt 2363a75fececSSteven Rostedt run_command "git bisect good $good" or 2364a75fececSSteven Rostedt dodie "could not set bisect good to $good"; 2365a75fececSSteven Rostedt 2366a75fececSSteven Rostedt run_git_bisect "git bisect bad $bad" or 2367a75fececSSteven Rostedt dodie "could not set bisect bad to $bad"; 2368a75fececSSteven Rostedt 2369a75fececSSteven Rostedt if (defined($replay)) { 2370a75fececSSteven Rostedt run_command "git bisect replay $replay" or 2371a75fececSSteven Rostedt dodie "failed to run replay"; 2372a75fececSSteven Rostedt } 2373a75fececSSteven Rostedt 2374a75fececSSteven Rostedt if (defined($start)) { 2375a75fececSSteven Rostedt run_command "git checkout $start" or 2376a75fececSSteven Rostedt dodie "failed to checkout $start"; 2377a75fececSSteven Rostedt } 2378a75fececSSteven Rostedt 2379a75fececSSteven Rostedt my $test; 23805f9b6cedSSteven Rostedt do { 23815f9b6cedSSteven Rostedt $result = run_bisect $type; 2382a75fececSSteven Rostedt $test = run_git_bisect "git bisect $result"; 2383a75fececSSteven Rostedt } while ($test); 23845f9b6cedSSteven Rostedt 23855f9b6cedSSteven Rostedt run_command "git bisect log" or 23865f9b6cedSSteven Rostedt dodie "could not capture git bisect log"; 23875f9b6cedSSteven Rostedt 23885f9b6cedSSteven Rostedt run_command "git bisect reset" or 23895f9b6cedSSteven Rostedt dodie "could not reset git bisect"; 23905f9b6cedSSteven Rostedt 2391b5f4aea6SSteven Rostedt doprint "Bad commit was [$bisect_bad_commit]\n"; 23925f9b6cedSSteven Rostedt 23930a05c769SSteven Rostedt success $i; 23940a05c769SSteven Rostedt} 23950a05c769SSteven Rostedt 2396*cf79fab6SSteven Rostedt# config_ignore holds the configs that were set (or unset) for 2397*cf79fab6SSteven Rostedt# a good config and we will ignore these configs for the rest 2398*cf79fab6SSteven Rostedt# of a config bisect. These configs stay as they were. 23990a05c769SSteven Rostedtmy %config_ignore; 2400*cf79fab6SSteven Rostedt 2401*cf79fab6SSteven Rostedt# config_set holds what all configs were set as. 24020a05c769SSteven Rostedtmy %config_set; 24030a05c769SSteven Rostedt 2404*cf79fab6SSteven Rostedt# config_off holds the set of configs that the bad config had disabled. 2405*cf79fab6SSteven Rostedt# We need to record them and set them in the .config when running 2406*cf79fab6SSteven Rostedt# oldnoconfig, because oldnoconfig does not turn off new symbols, but 2407*cf79fab6SSteven Rostedt# instead just keeps the defaults. 2408*cf79fab6SSteven Rostedtmy %config_off; 2409*cf79fab6SSteven Rostedt 2410*cf79fab6SSteven Rostedt# config_off_tmp holds a set of configs to turn off for now 2411*cf79fab6SSteven Rostedtmy @config_off_tmp; 2412*cf79fab6SSteven Rostedt 2413*cf79fab6SSteven Rostedt# config_list is the set of configs that are being tested 24140a05c769SSteven Rostedtmy %config_list; 24150a05c769SSteven Rostedtmy %null_config; 24160a05c769SSteven Rostedt 24170a05c769SSteven Rostedtmy %dependency; 24180a05c769SSteven Rostedt 24194c4ab120SSteven Rostedtsub assign_configs { 24204c4ab120SSteven Rostedt my ($hash, $config) = @_; 24210a05c769SSteven Rostedt 24220a05c769SSteven Rostedt open (IN, $config) 24230a05c769SSteven Rostedt or dodie "Failed to read $config"; 24240a05c769SSteven Rostedt 24250a05c769SSteven Rostedt while (<IN>) { 24269bf71749SSteven Rostedt if (/^((CONFIG\S*)=.*)/) { 24274c4ab120SSteven Rostedt ${$hash}{$2} = $1; 24280a05c769SSteven Rostedt } 24290a05c769SSteven Rostedt } 24300a05c769SSteven Rostedt 24310a05c769SSteven Rostedt close(IN); 24320a05c769SSteven Rostedt} 24330a05c769SSteven Rostedt 24344c4ab120SSteven Rostedtsub process_config_ignore { 24354c4ab120SSteven Rostedt my ($config) = @_; 24364c4ab120SSteven Rostedt 24374c4ab120SSteven Rostedt assign_configs \%config_ignore, $config; 24384c4ab120SSteven Rostedt} 24394c4ab120SSteven Rostedt 24400a05c769SSteven Rostedtsub read_current_config { 24410a05c769SSteven Rostedt my ($config_ref) = @_; 24420a05c769SSteven Rostedt 24430a05c769SSteven Rostedt %{$config_ref} = (); 24440a05c769SSteven Rostedt undef %{$config_ref}; 24450a05c769SSteven Rostedt 24460a05c769SSteven Rostedt my @key = keys %{$config_ref}; 24470a05c769SSteven Rostedt if ($#key >= 0) { 24480a05c769SSteven Rostedt print "did not delete!\n"; 24490a05c769SSteven Rostedt exit; 24500a05c769SSteven Rostedt } 24510a05c769SSteven Rostedt open (IN, "$output_config"); 24520a05c769SSteven Rostedt 24530a05c769SSteven Rostedt while (<IN>) { 24540a05c769SSteven Rostedt if (/^(CONFIG\S+)=(.*)/) { 24550a05c769SSteven Rostedt ${$config_ref}{$1} = $2; 24560a05c769SSteven Rostedt } 24570a05c769SSteven Rostedt } 24580a05c769SSteven Rostedt close(IN); 24590a05c769SSteven Rostedt} 24600a05c769SSteven Rostedt 24610a05c769SSteven Rostedtsub get_dependencies { 24620a05c769SSteven Rostedt my ($config) = @_; 24630a05c769SSteven Rostedt 24640a05c769SSteven Rostedt my $arr = $dependency{$config}; 24650a05c769SSteven Rostedt if (!defined($arr)) { 24660a05c769SSteven Rostedt return (); 24670a05c769SSteven Rostedt } 24680a05c769SSteven Rostedt 24690a05c769SSteven Rostedt my @deps = @{$arr}; 24700a05c769SSteven Rostedt 24710a05c769SSteven Rostedt foreach my $dep (@{$arr}) { 24720a05c769SSteven Rostedt print "ADD DEP $dep\n"; 24730a05c769SSteven Rostedt @deps = (@deps, get_dependencies $dep); 24740a05c769SSteven Rostedt } 24750a05c769SSteven Rostedt 24760a05c769SSteven Rostedt return @deps; 24770a05c769SSteven Rostedt} 24780a05c769SSteven Rostedt 24790a05c769SSteven Rostedtsub create_config { 24800a05c769SSteven Rostedt my @configs = @_; 24810a05c769SSteven Rostedt 24820a05c769SSteven Rostedt open(OUT, ">$output_config") or dodie "Can not write to $output_config"; 24830a05c769SSteven Rostedt 24840a05c769SSteven Rostedt foreach my $config (@configs) { 24850a05c769SSteven Rostedt print OUT "$config_set{$config}\n"; 24860a05c769SSteven Rostedt my @deps = get_dependencies $config; 24870a05c769SSteven Rostedt foreach my $dep (@deps) { 24880a05c769SSteven Rostedt print OUT "$config_set{$dep}\n"; 24890a05c769SSteven Rostedt } 24900a05c769SSteven Rostedt } 24910a05c769SSteven Rostedt 2492*cf79fab6SSteven Rostedt # turn off configs to keep off 2493*cf79fab6SSteven Rostedt foreach my $config (keys %config_off) { 2494*cf79fab6SSteven Rostedt print OUT "# $config is not set\n"; 2495*cf79fab6SSteven Rostedt } 2496*cf79fab6SSteven Rostedt 2497*cf79fab6SSteven Rostedt # turn off configs that should be off for now 2498*cf79fab6SSteven Rostedt foreach my $config (@config_off_tmp) { 2499*cf79fab6SSteven Rostedt print OUT "# $config is not set\n"; 2500*cf79fab6SSteven Rostedt } 2501*cf79fab6SSteven Rostedt 25020a05c769SSteven Rostedt foreach my $config (keys %config_ignore) { 25030a05c769SSteven Rostedt print OUT "$config_ignore{$config}\n"; 25040a05c769SSteven Rostedt } 25050a05c769SSteven Rostedt close(OUT); 25060a05c769SSteven Rostedt 2507fcb3f16aSSteven Rostedt make_oldconfig; 25080a05c769SSteven Rostedt} 25090a05c769SSteven Rostedt 25100a05c769SSteven Rostedtsub compare_configs { 25110a05c769SSteven Rostedt my (%a, %b) = @_; 25120a05c769SSteven Rostedt 25130a05c769SSteven Rostedt foreach my $item (keys %a) { 25140a05c769SSteven Rostedt if (!defined($b{$item})) { 25150a05c769SSteven Rostedt print "diff $item\n"; 25160a05c769SSteven Rostedt return 1; 25170a05c769SSteven Rostedt } 25180a05c769SSteven Rostedt delete $b{$item}; 25190a05c769SSteven Rostedt } 25200a05c769SSteven Rostedt 25210a05c769SSteven Rostedt my @keys = keys %b; 25220a05c769SSteven Rostedt if ($#keys) { 25230a05c769SSteven Rostedt print "diff2 $keys[0]\n"; 25240a05c769SSteven Rostedt } 25250a05c769SSteven Rostedt return -1 if ($#keys >= 0); 25260a05c769SSteven Rostedt 25270a05c769SSteven Rostedt return 0; 25280a05c769SSteven Rostedt} 25290a05c769SSteven Rostedt 25300a05c769SSteven Rostedtsub run_config_bisect_test { 25310a05c769SSteven Rostedt my ($type) = @_; 25320a05c769SSteven Rostedt 25330a05c769SSteven Rostedt return run_bisect_test $type, "oldconfig"; 25340a05c769SSteven Rostedt} 25350a05c769SSteven Rostedt 25360a05c769SSteven Rostedtsub process_passed { 25370a05c769SSteven Rostedt my (%configs) = @_; 25380a05c769SSteven Rostedt 25390a05c769SSteven Rostedt doprint "These configs had no failure: (Enabling them for further compiles)\n"; 25400a05c769SSteven Rostedt # Passed! All these configs are part of a good compile. 25410a05c769SSteven Rostedt # Add them to the min options. 25420a05c769SSteven Rostedt foreach my $config (keys %configs) { 25430a05c769SSteven Rostedt if (defined($config_list{$config})) { 25440a05c769SSteven Rostedt doprint " removing $config\n"; 25450a05c769SSteven Rostedt $config_ignore{$config} = $config_list{$config}; 25460a05c769SSteven Rostedt delete $config_list{$config}; 25470a05c769SSteven Rostedt } 25480a05c769SSteven Rostedt } 2549f1a27850SSteven Rostedt doprint "config copied to $outputdir/config_good\n"; 2550f1a27850SSteven Rostedt run_command "cp -f $output_config $outputdir/config_good"; 25510a05c769SSteven Rostedt} 25520a05c769SSteven Rostedt 25530a05c769SSteven Rostedtsub process_failed { 25540a05c769SSteven Rostedt my ($config) = @_; 25550a05c769SSteven Rostedt 25560a05c769SSteven Rostedt doprint "\n\n***************************************\n"; 25570a05c769SSteven Rostedt doprint "Found bad config: $config\n"; 25580a05c769SSteven Rostedt doprint "***************************************\n\n"; 25590a05c769SSteven Rostedt} 25600a05c769SSteven Rostedt 25610a05c769SSteven Rostedtsub run_config_bisect { 25620a05c769SSteven Rostedt 25630a05c769SSteven Rostedt my @start_list = keys %config_list; 25640a05c769SSteven Rostedt 25650a05c769SSteven Rostedt if ($#start_list < 0) { 25660a05c769SSteven Rostedt doprint "No more configs to test!!!\n"; 25670a05c769SSteven Rostedt return -1; 25680a05c769SSteven Rostedt } 25690a05c769SSteven Rostedt 25700a05c769SSteven Rostedt doprint "***** RUN TEST ***\n"; 2571b5f4aea6SSteven Rostedt my $type = $config_bisect_type; 25720a05c769SSteven Rostedt my $ret; 25730a05c769SSteven Rostedt my %current_config; 25740a05c769SSteven Rostedt 25750a05c769SSteven Rostedt my $count = $#start_list + 1; 25760a05c769SSteven Rostedt doprint " $count configs to test\n"; 25770a05c769SSteven Rostedt 25780a05c769SSteven Rostedt my $half = int($#start_list / 2); 25790a05c769SSteven Rostedt 25800a05c769SSteven Rostedt do { 25810a05c769SSteven Rostedt my @tophalf = @start_list[0 .. $half]; 25820a05c769SSteven Rostedt 2583*cf79fab6SSteven Rostedt # keep the bottom half off 2584*cf79fab6SSteven Rostedt if ($half < $#start_list) { 2585*cf79fab6SSteven Rostedt @config_off_tmp = @start_list[$half + 1 .. $#start_list]; 2586*cf79fab6SSteven Rostedt } else { 2587*cf79fab6SSteven Rostedt @config_off_tmp = (); 2588*cf79fab6SSteven Rostedt } 2589*cf79fab6SSteven Rostedt 25900a05c769SSteven Rostedt create_config @tophalf; 25910a05c769SSteven Rostedt read_current_config \%current_config; 25920a05c769SSteven Rostedt 25930a05c769SSteven Rostedt $count = $#tophalf + 1; 25940a05c769SSteven Rostedt doprint "Testing $count configs\n"; 25950a05c769SSteven Rostedt my $found = 0; 25960a05c769SSteven Rostedt # make sure we test something 25970a05c769SSteven Rostedt foreach my $config (@tophalf) { 25980a05c769SSteven Rostedt if (defined($current_config{$config})) { 25990a05c769SSteven Rostedt logit " $config\n"; 26000a05c769SSteven Rostedt $found = 1; 26010a05c769SSteven Rostedt } 26020a05c769SSteven Rostedt } 26030a05c769SSteven Rostedt if (!$found) { 26040a05c769SSteven Rostedt # try the other half 26050a05c769SSteven Rostedt doprint "Top half produced no set configs, trying bottom half\n"; 2606*cf79fab6SSteven Rostedt 2607*cf79fab6SSteven Rostedt # keep the top half off 2608*cf79fab6SSteven Rostedt @config_off_tmp = @tophalf; 26094c8cc55bSSteven Rostedt @tophalf = @start_list[$half + 1 .. $#start_list]; 2610*cf79fab6SSteven Rostedt 26110a05c769SSteven Rostedt create_config @tophalf; 26120a05c769SSteven Rostedt read_current_config \%current_config; 26130a05c769SSteven Rostedt foreach my $config (@tophalf) { 26140a05c769SSteven Rostedt if (defined($current_config{$config})) { 26150a05c769SSteven Rostedt logit " $config\n"; 26160a05c769SSteven Rostedt $found = 1; 26170a05c769SSteven Rostedt } 26180a05c769SSteven Rostedt } 26190a05c769SSteven Rostedt if (!$found) { 26200a05c769SSteven Rostedt doprint "Failed: Can't make new config with current configs\n"; 26210a05c769SSteven Rostedt foreach my $config (@start_list) { 26220a05c769SSteven Rostedt doprint " CONFIG: $config\n"; 26230a05c769SSteven Rostedt } 26240a05c769SSteven Rostedt return -1; 26250a05c769SSteven Rostedt } 26260a05c769SSteven Rostedt $count = $#tophalf + 1; 26270a05c769SSteven Rostedt doprint "Testing $count configs\n"; 26280a05c769SSteven Rostedt } 26290a05c769SSteven Rostedt 26300a05c769SSteven Rostedt $ret = run_config_bisect_test $type; 2631c960bb9fSSteven Rostedt if ($bisect_manual) { 2632c960bb9fSSteven Rostedt $ret = answer_bisect; 2633c960bb9fSSteven Rostedt } 26340a05c769SSteven Rostedt if ($ret) { 26350a05c769SSteven Rostedt process_passed %current_config; 26360a05c769SSteven Rostedt return 0; 26370a05c769SSteven Rostedt } 26380a05c769SSteven Rostedt 26390a05c769SSteven Rostedt doprint "This config had a failure.\n"; 26400a05c769SSteven Rostedt doprint "Removing these configs that were not set in this config:\n"; 2641f1a27850SSteven Rostedt doprint "config copied to $outputdir/config_bad\n"; 2642f1a27850SSteven Rostedt run_command "cp -f $output_config $outputdir/config_bad"; 26430a05c769SSteven Rostedt 26440a05c769SSteven Rostedt # A config exists in this group that was bad. 26450a05c769SSteven Rostedt foreach my $config (keys %config_list) { 26460a05c769SSteven Rostedt if (!defined($current_config{$config})) { 26470a05c769SSteven Rostedt doprint " removing $config\n"; 26480a05c769SSteven Rostedt delete $config_list{$config}; 26490a05c769SSteven Rostedt } 26500a05c769SSteven Rostedt } 26510a05c769SSteven Rostedt 26520a05c769SSteven Rostedt @start_list = @tophalf; 26530a05c769SSteven Rostedt 26540a05c769SSteven Rostedt if ($#start_list == 0) { 26550a05c769SSteven Rostedt process_failed $start_list[0]; 26560a05c769SSteven Rostedt return 1; 26570a05c769SSteven Rostedt } 26580a05c769SSteven Rostedt 26590a05c769SSteven Rostedt # remove half the configs we are looking at and see if 26600a05c769SSteven Rostedt # they are good. 26610a05c769SSteven Rostedt $half = int($#start_list / 2); 26624c8cc55bSSteven Rostedt } while ($#start_list > 0); 26630a05c769SSteven Rostedt 2664c960bb9fSSteven Rostedt # we found a single config, try it again unless we are running manually 2665c960bb9fSSteven Rostedt 2666c960bb9fSSteven Rostedt if ($bisect_manual) { 2667c960bb9fSSteven Rostedt process_failed $start_list[0]; 2668c960bb9fSSteven Rostedt return 1; 2669c960bb9fSSteven Rostedt } 2670c960bb9fSSteven Rostedt 26710a05c769SSteven Rostedt my @tophalf = @start_list[0 .. 0]; 26720a05c769SSteven Rostedt 26730a05c769SSteven Rostedt $ret = run_config_bisect_test $type; 26740a05c769SSteven Rostedt if ($ret) { 26750a05c769SSteven Rostedt process_passed %current_config; 26760a05c769SSteven Rostedt return 0; 26770a05c769SSteven Rostedt } 26780a05c769SSteven Rostedt 26790a05c769SSteven Rostedt process_failed $start_list[0]; 26800a05c769SSteven Rostedt return 1; 26810a05c769SSteven Rostedt} 26820a05c769SSteven Rostedt 26830a05c769SSteven Rostedtsub config_bisect { 26840a05c769SSteven Rostedt my ($i) = @_; 26850a05c769SSteven Rostedt 2686b5f4aea6SSteven Rostedt my $start_config = $config_bisect; 26870a05c769SSteven Rostedt 26880a05c769SSteven Rostedt my $tmpconfig = "$tmpdir/use_config"; 26890a05c769SSteven Rostedt 269030f75da5SSteven Rostedt if (defined($config_bisect_good)) { 269130f75da5SSteven Rostedt process_config_ignore $config_bisect_good; 269230f75da5SSteven Rostedt } 269330f75da5SSteven Rostedt 26940a05c769SSteven Rostedt # Make the file with the bad config and the min config 26950a05c769SSteven Rostedt if (defined($minconfig)) { 26960a05c769SSteven Rostedt # read the min config for things to ignore 26970a05c769SSteven Rostedt run_command "cp $minconfig $tmpconfig" or 26980a05c769SSteven Rostedt dodie "failed to copy $minconfig to $tmpconfig"; 26990a05c769SSteven Rostedt } else { 27000a05c769SSteven Rostedt unlink $tmpconfig; 27010a05c769SSteven Rostedt } 27020a05c769SSteven Rostedt 27030a05c769SSteven Rostedt if (-f $tmpconfig) { 2704fcb3f16aSSteven Rostedt load_force_config($tmpconfig); 27050a05c769SSteven Rostedt process_config_ignore $tmpconfig; 27060a05c769SSteven Rostedt } 27070a05c769SSteven Rostedt 27080a05c769SSteven Rostedt # now process the start config 27090a05c769SSteven Rostedt run_command "cp $start_config $output_config" or 27100a05c769SSteven Rostedt dodie "failed to copy $start_config to $output_config"; 27110a05c769SSteven Rostedt 27120a05c769SSteven Rostedt # read directly what we want to check 27130a05c769SSteven Rostedt my %config_check; 27140a05c769SSteven Rostedt open (IN, $output_config) 2715f9dee311SMasanari Iida or dodie "failed to open $output_config"; 27160a05c769SSteven Rostedt 27170a05c769SSteven Rostedt while (<IN>) { 27180a05c769SSteven Rostedt if (/^((CONFIG\S*)=.*)/) { 27190a05c769SSteven Rostedt $config_check{$2} = $1; 27200a05c769SSteven Rostedt } 27210a05c769SSteven Rostedt } 27220a05c769SSteven Rostedt close(IN); 27230a05c769SSteven Rostedt 2724250bae8bSSteven Rostedt # Now run oldconfig with the minconfig 2725fcb3f16aSSteven Rostedt make_oldconfig; 27260a05c769SSteven Rostedt 27270a05c769SSteven Rostedt # check to see what we lost (or gained) 27280a05c769SSteven Rostedt open (IN, $output_config) 27290a05c769SSteven Rostedt or dodie "Failed to read $start_config"; 27300a05c769SSteven Rostedt 27310a05c769SSteven Rostedt my %removed_configs; 27320a05c769SSteven Rostedt my %added_configs; 27330a05c769SSteven Rostedt 27340a05c769SSteven Rostedt while (<IN>) { 27350a05c769SSteven Rostedt if (/^((CONFIG\S*)=.*)/) { 27360a05c769SSteven Rostedt # save off all options 27370a05c769SSteven Rostedt $config_set{$2} = $1; 27380a05c769SSteven Rostedt if (defined($config_check{$2})) { 27390a05c769SSteven Rostedt if (defined($config_ignore{$2})) { 27400a05c769SSteven Rostedt $removed_configs{$2} = $1; 27410a05c769SSteven Rostedt } else { 27420a05c769SSteven Rostedt $config_list{$2} = $1; 27430a05c769SSteven Rostedt } 27440a05c769SSteven Rostedt } elsif (!defined($config_ignore{$2})) { 27450a05c769SSteven Rostedt $added_configs{$2} = $1; 27460a05c769SSteven Rostedt $config_list{$2} = $1; 27470a05c769SSteven Rostedt } 2748*cf79fab6SSteven Rostedt } elsif (/^# ((CONFIG\S*).*)/) { 2749*cf79fab6SSteven Rostedt # Keep these configs disabled 2750*cf79fab6SSteven Rostedt $config_set{$2} = $1; 2751*cf79fab6SSteven Rostedt $config_off{$2} = $1; 27520a05c769SSteven Rostedt } 27530a05c769SSteven Rostedt } 27540a05c769SSteven Rostedt close(IN); 27550a05c769SSteven Rostedt 27560a05c769SSteven Rostedt my @confs = keys %removed_configs; 27570a05c769SSteven Rostedt if ($#confs >= 0) { 27580a05c769SSteven Rostedt doprint "Configs overridden by default configs and removed from check:\n"; 27590a05c769SSteven Rostedt foreach my $config (@confs) { 27600a05c769SSteven Rostedt doprint " $config\n"; 27610a05c769SSteven Rostedt } 27620a05c769SSteven Rostedt } 27630a05c769SSteven Rostedt @confs = keys %added_configs; 27640a05c769SSteven Rostedt if ($#confs >= 0) { 27650a05c769SSteven Rostedt doprint "Configs appearing in make oldconfig and added:\n"; 27660a05c769SSteven Rostedt foreach my $config (@confs) { 27670a05c769SSteven Rostedt doprint " $config\n"; 27680a05c769SSteven Rostedt } 27690a05c769SSteven Rostedt } 27700a05c769SSteven Rostedt 27710a05c769SSteven Rostedt my %config_test; 27720a05c769SSteven Rostedt my $once = 0; 27730a05c769SSteven Rostedt 2774*cf79fab6SSteven Rostedt @config_off_tmp = (); 2775*cf79fab6SSteven Rostedt 27760a05c769SSteven Rostedt # Sometimes kconfig does weird things. We must make sure 27770a05c769SSteven Rostedt # that the config we autocreate has everything we need 27780a05c769SSteven Rostedt # to test, otherwise we may miss testing configs, or 27790a05c769SSteven Rostedt # may not be able to create a new config. 27800a05c769SSteven Rostedt # Here we create a config with everything set. 27810a05c769SSteven Rostedt create_config (keys %config_list); 27820a05c769SSteven Rostedt read_current_config \%config_test; 27830a05c769SSteven Rostedt foreach my $config (keys %config_list) { 27840a05c769SSteven Rostedt if (!defined($config_test{$config})) { 27850a05c769SSteven Rostedt if (!$once) { 27860a05c769SSteven Rostedt $once = 1; 27870a05c769SSteven Rostedt doprint "Configs not produced by kconfig (will not be checked):\n"; 27880a05c769SSteven Rostedt } 27890a05c769SSteven Rostedt doprint " $config\n"; 27900a05c769SSteven Rostedt delete $config_list{$config}; 27910a05c769SSteven Rostedt } 27920a05c769SSteven Rostedt } 27930a05c769SSteven Rostedt my $ret; 2794b0918612SSteven Rostedt 2795b0918612SSteven Rostedt if (defined($config_bisect_check) && $config_bisect_check) { 2796b0918612SSteven Rostedt doprint " Checking to make sure bad config with min config fails\n"; 2797b0918612SSteven Rostedt create_config keys %config_list; 2798b0918612SSteven Rostedt $ret = run_config_bisect_test $config_bisect_type; 2799b0918612SSteven Rostedt if ($ret) { 2800b0918612SSteven Rostedt doprint " FAILED! Bad config with min config boots fine\n"; 2801b0918612SSteven Rostedt return -1; 2802b0918612SSteven Rostedt } 2803b0918612SSteven Rostedt doprint " Bad config with min config fails as expected\n"; 2804b0918612SSteven Rostedt } 2805b0918612SSteven Rostedt 28060a05c769SSteven Rostedt do { 28070a05c769SSteven Rostedt $ret = run_config_bisect; 28080a05c769SSteven Rostedt } while (!$ret); 28090a05c769SSteven Rostedt 28100a05c769SSteven Rostedt return $ret if ($ret < 0); 28115f9b6cedSSteven Rostedt 28125f9b6cedSSteven Rostedt success $i; 28135f9b6cedSSteven Rostedt} 28145f9b6cedSSteven Rostedt 281527d934b2SSteven Rostedtsub patchcheck_reboot { 281627d934b2SSteven Rostedt doprint "Reboot and sleep $patchcheck_sleep_time seconds\n"; 2817bc7c5803SSteven Rostedt reboot_to_good $patchcheck_sleep_time; 281827d934b2SSteven Rostedt} 281927d934b2SSteven Rostedt 28206c5ee0beSSteven Rostedtsub patchcheck { 28216c5ee0beSSteven Rostedt my ($i) = @_; 28226c5ee0beSSteven Rostedt 28236c5ee0beSSteven Rostedt die "PATCHCHECK_START[$i] not defined\n" 2824b5f4aea6SSteven Rostedt if (!defined($patchcheck_start)); 28256c5ee0beSSteven Rostedt die "PATCHCHECK_TYPE[$i] not defined\n" 2826b5f4aea6SSteven Rostedt if (!defined($patchcheck_type)); 28276c5ee0beSSteven Rostedt 2828b5f4aea6SSteven Rostedt my $start = $patchcheck_start; 28296c5ee0beSSteven Rostedt 28306c5ee0beSSteven Rostedt my $end = "HEAD"; 2831b5f4aea6SSteven Rostedt if (defined($patchcheck_end)) { 2832b5f4aea6SSteven Rostedt $end = $patchcheck_end; 28336c5ee0beSSteven Rostedt } 28346c5ee0beSSteven Rostedt 2835a57419b3SSteven Rostedt # Get the true sha1's since we can use things like HEAD~3 2836a57419b3SSteven Rostedt $start = get_sha1($start); 2837a57419b3SSteven Rostedt $end = get_sha1($end); 2838a57419b3SSteven Rostedt 2839b5f4aea6SSteven Rostedt my $type = $patchcheck_type; 28406c5ee0beSSteven Rostedt 28416c5ee0beSSteven Rostedt # Can't have a test without having a test to run 28426c5ee0beSSteven Rostedt if ($type eq "test" && !defined($run_test)) { 28436c5ee0beSSteven Rostedt $type = "boot"; 28446c5ee0beSSteven Rostedt } 28456c5ee0beSSteven Rostedt 28466c5ee0beSSteven Rostedt open (IN, "git log --pretty=oneline $end|") or 28476c5ee0beSSteven Rostedt dodie "could not get git list"; 28486c5ee0beSSteven Rostedt 28496c5ee0beSSteven Rostedt my @list; 28506c5ee0beSSteven Rostedt 28516c5ee0beSSteven Rostedt while (<IN>) { 28526c5ee0beSSteven Rostedt chomp; 28536c5ee0beSSteven Rostedt $list[$#list+1] = $_; 28546c5ee0beSSteven Rostedt last if (/^$start/); 28556c5ee0beSSteven Rostedt } 28566c5ee0beSSteven Rostedt close(IN); 28576c5ee0beSSteven Rostedt 28586c5ee0beSSteven Rostedt if ($list[$#list] !~ /^$start/) { 28592b7d9b21SSteven Rostedt fail "SHA1 $start not found"; 28606c5ee0beSSteven Rostedt } 28616c5ee0beSSteven Rostedt 28626c5ee0beSSteven Rostedt # go backwards in the list 28636c5ee0beSSteven Rostedt @list = reverse @list; 28646c5ee0beSSteven Rostedt 28656c5ee0beSSteven Rostedt my $save_clean = $noclean; 28661990207dSSteven Rostedt my %ignored_warnings; 28671990207dSSteven Rostedt 28681990207dSSteven Rostedt if (defined($ignore_warnings)) { 28691990207dSSteven Rostedt foreach my $sha1 (split /\s+/, $ignore_warnings) { 28701990207dSSteven Rostedt $ignored_warnings{$sha1} = 1; 28711990207dSSteven Rostedt } 28721990207dSSteven Rostedt } 28736c5ee0beSSteven Rostedt 28746c5ee0beSSteven Rostedt $in_patchcheck = 1; 28756c5ee0beSSteven Rostedt foreach my $item (@list) { 28766c5ee0beSSteven Rostedt my $sha1 = $item; 28776c5ee0beSSteven Rostedt $sha1 =~ s/^([[:xdigit:]]+).*/$1/; 28786c5ee0beSSteven Rostedt 28796c5ee0beSSteven Rostedt doprint "\nProcessing commit $item\n\n"; 28806c5ee0beSSteven Rostedt 28816c5ee0beSSteven Rostedt run_command "git checkout $sha1" or 28826c5ee0beSSteven Rostedt die "Failed to checkout $sha1"; 28836c5ee0beSSteven Rostedt 28846c5ee0beSSteven Rostedt # only clean on the first and last patch 28856c5ee0beSSteven Rostedt if ($item eq $list[0] || 28866c5ee0beSSteven Rostedt $item eq $list[$#list]) { 28876c5ee0beSSteven Rostedt $noclean = $save_clean; 28886c5ee0beSSteven Rostedt } else { 28896c5ee0beSSteven Rostedt $noclean = 1; 28906c5ee0beSSteven Rostedt } 28916c5ee0beSSteven Rostedt 28926c5ee0beSSteven Rostedt if (defined($minconfig)) { 28932b7d9b21SSteven Rostedt build "useconfig:$minconfig" or return 0; 28946c5ee0beSSteven Rostedt } else { 28956c5ee0beSSteven Rostedt # ?? no config to use? 28962b7d9b21SSteven Rostedt build "oldconfig" or return 0; 28976c5ee0beSSteven Rostedt } 28986c5ee0beSSteven Rostedt 28991990207dSSteven Rostedt 29001990207dSSteven Rostedt if (!defined($ignored_warnings{$sha1})) { 29012b7d9b21SSteven Rostedt check_buildlog $sha1 or return 0; 29021990207dSSteven Rostedt } 29036c5ee0beSSteven Rostedt 29046c5ee0beSSteven Rostedt next if ($type eq "build"); 29056c5ee0beSSteven Rostedt 29067faafbd6SSteven Rostedt my $failed = 0; 29077faafbd6SSteven Rostedt 2908ddf607e5SSteven Rostedt start_monitor_and_boot or $failed = 1; 29097faafbd6SSteven Rostedt 29107faafbd6SSteven Rostedt if (!$failed && $type ne "boot"){ 29117faafbd6SSteven Rostedt do_run_test or $failed = 1; 29127faafbd6SSteven Rostedt } 29137faafbd6SSteven Rostedt end_monitor; 29147faafbd6SSteven Rostedt return 0 if ($failed); 29157faafbd6SSteven Rostedt 291627d934b2SSteven Rostedt patchcheck_reboot; 291727d934b2SSteven Rostedt 29186c5ee0beSSteven Rostedt } 29196c5ee0beSSteven Rostedt $in_patchcheck = 0; 29206c5ee0beSSteven Rostedt success $i; 29212b7d9b21SSteven Rostedt 29222b7d9b21SSteven Rostedt return 1; 29236c5ee0beSSteven Rostedt} 29246c5ee0beSSteven Rostedt 2925b9066f6cSSteven Rostedtmy %depends; 2926ac6974c7SSteven Rostedtmy %depcount; 2927b9066f6cSSteven Rostedtmy $iflevel = 0; 2928b9066f6cSSteven Rostedtmy @ifdeps; 2929b9066f6cSSteven Rostedt 2930b9066f6cSSteven Rostedt# prevent recursion 2931b9066f6cSSteven Rostedtmy %read_kconfigs; 2932b9066f6cSSteven Rostedt 2933ac6974c7SSteven Rostedtsub add_dep { 2934ac6974c7SSteven Rostedt # $config depends on $dep 2935ac6974c7SSteven Rostedt my ($config, $dep) = @_; 2936ac6974c7SSteven Rostedt 2937ac6974c7SSteven Rostedt if (defined($depends{$config})) { 2938ac6974c7SSteven Rostedt $depends{$config} .= " " . $dep; 2939ac6974c7SSteven Rostedt } else { 2940ac6974c7SSteven Rostedt $depends{$config} = $dep; 2941ac6974c7SSteven Rostedt } 2942ac6974c7SSteven Rostedt 2943ac6974c7SSteven Rostedt # record the number of configs depending on $dep 2944ac6974c7SSteven Rostedt if (defined $depcount{$dep}) { 2945ac6974c7SSteven Rostedt $depcount{$dep}++; 2946ac6974c7SSteven Rostedt } else { 2947ac6974c7SSteven Rostedt $depcount{$dep} = 1; 2948ac6974c7SSteven Rostedt } 2949ac6974c7SSteven Rostedt} 2950ac6974c7SSteven Rostedt 2951b9066f6cSSteven Rostedt# taken from streamline_config.pl 2952b9066f6cSSteven Rostedtsub read_kconfig { 2953b9066f6cSSteven Rostedt my ($kconfig) = @_; 2954b9066f6cSSteven Rostedt 2955b9066f6cSSteven Rostedt my $state = "NONE"; 2956b9066f6cSSteven Rostedt my $config; 2957b9066f6cSSteven Rostedt my @kconfigs; 2958b9066f6cSSteven Rostedt 2959b9066f6cSSteven Rostedt my $cont = 0; 2960b9066f6cSSteven Rostedt my $line; 2961b9066f6cSSteven Rostedt 2962b9066f6cSSteven Rostedt 2963b9066f6cSSteven Rostedt if (! -f $kconfig) { 2964b9066f6cSSteven Rostedt doprint "file $kconfig does not exist, skipping\n"; 2965b9066f6cSSteven Rostedt return; 2966b9066f6cSSteven Rostedt } 2967b9066f6cSSteven Rostedt 2968b9066f6cSSteven Rostedt open(KIN, "$kconfig") 2969b9066f6cSSteven Rostedt or die "Can't open $kconfig"; 2970b9066f6cSSteven Rostedt while (<KIN>) { 2971b9066f6cSSteven Rostedt chomp; 2972b9066f6cSSteven Rostedt 2973b9066f6cSSteven Rostedt # Make sure that lines ending with \ continue 2974b9066f6cSSteven Rostedt if ($cont) { 2975b9066f6cSSteven Rostedt $_ = $line . " " . $_; 2976b9066f6cSSteven Rostedt } 2977b9066f6cSSteven Rostedt 2978b9066f6cSSteven Rostedt if (s/\\$//) { 2979b9066f6cSSteven Rostedt $cont = 1; 2980b9066f6cSSteven Rostedt $line = $_; 2981b9066f6cSSteven Rostedt next; 2982b9066f6cSSteven Rostedt } 2983b9066f6cSSteven Rostedt 2984b9066f6cSSteven Rostedt $cont = 0; 2985b9066f6cSSteven Rostedt 2986b9066f6cSSteven Rostedt # collect any Kconfig sources 2987b9066f6cSSteven Rostedt if (/^source\s*"(.*)"/) { 2988b9066f6cSSteven Rostedt $kconfigs[$#kconfigs+1] = $1; 2989b9066f6cSSteven Rostedt } 2990b9066f6cSSteven Rostedt 2991b9066f6cSSteven Rostedt # configs found 2992b9066f6cSSteven Rostedt if (/^\s*(menu)?config\s+(\S+)\s*$/) { 2993b9066f6cSSteven Rostedt $state = "NEW"; 2994b9066f6cSSteven Rostedt $config = $2; 2995b9066f6cSSteven Rostedt 2996b9066f6cSSteven Rostedt for (my $i = 0; $i < $iflevel; $i++) { 2997ac6974c7SSteven Rostedt add_dep $config, $ifdeps[$i]; 2998b9066f6cSSteven Rostedt } 2999b9066f6cSSteven Rostedt 3000b9066f6cSSteven Rostedt # collect the depends for the config 3001b9066f6cSSteven Rostedt } elsif ($state eq "NEW" && /^\s*depends\s+on\s+(.*)$/) { 3002b9066f6cSSteven Rostedt 3003ac6974c7SSteven Rostedt add_dep $config, $1; 3004b9066f6cSSteven Rostedt 3005b9066f6cSSteven Rostedt # Get the configs that select this config 3006ac6974c7SSteven Rostedt } elsif ($state eq "NEW" && /^\s*select\s+(\S+)/) { 3007ac6974c7SSteven Rostedt 3008ac6974c7SSteven Rostedt # selected by depends on config 3009ac6974c7SSteven Rostedt add_dep $1, $config; 3010b9066f6cSSteven Rostedt 3011b9066f6cSSteven Rostedt # Check for if statements 3012b9066f6cSSteven Rostedt } elsif (/^if\s+(.*\S)\s*$/) { 3013b9066f6cSSteven Rostedt my $deps = $1; 3014b9066f6cSSteven Rostedt # remove beginning and ending non text 3015b9066f6cSSteven Rostedt $deps =~ s/^[^a-zA-Z0-9_]*//; 3016b9066f6cSSteven Rostedt $deps =~ s/[^a-zA-Z0-9_]*$//; 3017b9066f6cSSteven Rostedt 3018b9066f6cSSteven Rostedt my @deps = split /[^a-zA-Z0-9_]+/, $deps; 3019b9066f6cSSteven Rostedt 3020b9066f6cSSteven Rostedt $ifdeps[$iflevel++] = join ':', @deps; 3021b9066f6cSSteven Rostedt 3022b9066f6cSSteven Rostedt } elsif (/^endif/) { 3023b9066f6cSSteven Rostedt 3024b9066f6cSSteven Rostedt $iflevel-- if ($iflevel); 3025b9066f6cSSteven Rostedt 3026b9066f6cSSteven Rostedt # stop on "help" 3027b9066f6cSSteven Rostedt } elsif (/^\s*help\s*$/) { 3028b9066f6cSSteven Rostedt $state = "NONE"; 3029b9066f6cSSteven Rostedt } 3030b9066f6cSSteven Rostedt } 3031b9066f6cSSteven Rostedt close(KIN); 3032b9066f6cSSteven Rostedt 3033b9066f6cSSteven Rostedt # read in any configs that were found. 3034b9066f6cSSteven Rostedt foreach $kconfig (@kconfigs) { 3035b9066f6cSSteven Rostedt if (!defined($read_kconfigs{$kconfig})) { 3036b9066f6cSSteven Rostedt $read_kconfigs{$kconfig} = 1; 3037b9066f6cSSteven Rostedt read_kconfig("$builddir/$kconfig"); 3038b9066f6cSSteven Rostedt } 3039b9066f6cSSteven Rostedt } 3040b9066f6cSSteven Rostedt} 3041b9066f6cSSteven Rostedt 3042b9066f6cSSteven Rostedtsub read_depends { 3043b9066f6cSSteven Rostedt # find out which arch this is by the kconfig file 3044b9066f6cSSteven Rostedt open (IN, $output_config) 3045b9066f6cSSteven Rostedt or dodie "Failed to read $output_config"; 3046b9066f6cSSteven Rostedt my $arch; 3047b9066f6cSSteven Rostedt while (<IN>) { 3048b9066f6cSSteven Rostedt if (m,Linux/(\S+)\s+\S+\s+Kernel Configuration,) { 3049b9066f6cSSteven Rostedt $arch = $1; 3050b9066f6cSSteven Rostedt last; 3051b9066f6cSSteven Rostedt } 3052b9066f6cSSteven Rostedt } 3053b9066f6cSSteven Rostedt close IN; 3054b9066f6cSSteven Rostedt 3055b9066f6cSSteven Rostedt if (!defined($arch)) { 3056b9066f6cSSteven Rostedt doprint "Could not find arch from config file\n"; 3057b9066f6cSSteven Rostedt doprint "no dependencies used\n"; 3058b9066f6cSSteven Rostedt return; 3059b9066f6cSSteven Rostedt } 3060b9066f6cSSteven Rostedt 3061b9066f6cSSteven Rostedt # arch is really the subarch, we need to know 3062b9066f6cSSteven Rostedt # what directory to look at. 3063b9066f6cSSteven Rostedt if ($arch eq "i386" || $arch eq "x86_64") { 3064b9066f6cSSteven Rostedt $arch = "x86"; 3065b9066f6cSSteven Rostedt } elsif ($arch =~ /^tile/) { 3066b9066f6cSSteven Rostedt $arch = "tile"; 3067b9066f6cSSteven Rostedt } 3068b9066f6cSSteven Rostedt 3069b9066f6cSSteven Rostedt my $kconfig = "$builddir/arch/$arch/Kconfig"; 3070b9066f6cSSteven Rostedt 3071b9066f6cSSteven Rostedt if (! -f $kconfig && $arch =~ /\d$/) { 3072b9066f6cSSteven Rostedt my $orig = $arch; 3073b9066f6cSSteven Rostedt # some subarchs have numbers, truncate them 3074b9066f6cSSteven Rostedt $arch =~ s/\d*$//; 3075b9066f6cSSteven Rostedt $kconfig = "$builddir/arch/$arch/Kconfig"; 3076b9066f6cSSteven Rostedt if (! -f $kconfig) { 3077b9066f6cSSteven Rostedt doprint "No idea what arch dir $orig is for\n"; 3078b9066f6cSSteven Rostedt doprint "no dependencies used\n"; 3079b9066f6cSSteven Rostedt return; 3080b9066f6cSSteven Rostedt } 3081b9066f6cSSteven Rostedt } 3082b9066f6cSSteven Rostedt 3083b9066f6cSSteven Rostedt read_kconfig($kconfig); 3084b9066f6cSSteven Rostedt} 3085b9066f6cSSteven Rostedt 30864c4ab120SSteven Rostedtsub read_config_list { 30874c4ab120SSteven Rostedt my ($config) = @_; 30884c4ab120SSteven Rostedt 30894c4ab120SSteven Rostedt open (IN, $config) 30904c4ab120SSteven Rostedt or dodie "Failed to read $config"; 30914c4ab120SSteven Rostedt 30924c4ab120SSteven Rostedt while (<IN>) { 30934c4ab120SSteven Rostedt if (/^((CONFIG\S*)=.*)/) { 30944c4ab120SSteven Rostedt if (!defined($config_ignore{$2})) { 30954c4ab120SSteven Rostedt $config_list{$2} = $1; 30964c4ab120SSteven Rostedt } 30974c4ab120SSteven Rostedt } 30984c4ab120SSteven Rostedt } 30994c4ab120SSteven Rostedt 31004c4ab120SSteven Rostedt close(IN); 31014c4ab120SSteven Rostedt} 31024c4ab120SSteven Rostedt 31034c4ab120SSteven Rostedtsub read_output_config { 31044c4ab120SSteven Rostedt my ($config) = @_; 31054c4ab120SSteven Rostedt 31064c4ab120SSteven Rostedt assign_configs \%config_ignore, $config; 31074c4ab120SSteven Rostedt} 31084c4ab120SSteven Rostedt 31094c4ab120SSteven Rostedtsub make_new_config { 31104c4ab120SSteven Rostedt my @configs = @_; 31114c4ab120SSteven Rostedt 31124c4ab120SSteven Rostedt open (OUT, ">$output_config") 31134c4ab120SSteven Rostedt or dodie "Failed to write $output_config"; 31144c4ab120SSteven Rostedt 31154c4ab120SSteven Rostedt foreach my $config (@configs) { 31164c4ab120SSteven Rostedt print OUT "$config\n"; 31174c4ab120SSteven Rostedt } 31184c4ab120SSteven Rostedt close OUT; 31194c4ab120SSteven Rostedt} 31204c4ab120SSteven Rostedt 3121ac6974c7SSteven Rostedtsub chomp_config { 3122ac6974c7SSteven Rostedt my ($config) = @_; 3123ac6974c7SSteven Rostedt 3124ac6974c7SSteven Rostedt $config =~ s/CONFIG_//; 3125ac6974c7SSteven Rostedt 3126ac6974c7SSteven Rostedt return $config; 3127ac6974c7SSteven Rostedt} 3128ac6974c7SSteven Rostedt 3129b9066f6cSSteven Rostedtsub get_depends { 3130b9066f6cSSteven Rostedt my ($dep) = @_; 3131b9066f6cSSteven Rostedt 3132ac6974c7SSteven Rostedt my $kconfig = chomp_config $dep; 3133b9066f6cSSteven Rostedt 3134b9066f6cSSteven Rostedt $dep = $depends{"$kconfig"}; 3135b9066f6cSSteven Rostedt 3136b9066f6cSSteven Rostedt # the dep string we have saves the dependencies as they 3137b9066f6cSSteven Rostedt # were found, including expressions like ! && ||. We 3138b9066f6cSSteven Rostedt # want to split this out into just an array of configs. 3139b9066f6cSSteven Rostedt 3140b9066f6cSSteven Rostedt my $valid = "A-Za-z_0-9"; 3141b9066f6cSSteven Rostedt 3142b9066f6cSSteven Rostedt my @configs; 3143b9066f6cSSteven Rostedt 3144b9066f6cSSteven Rostedt while ($dep =~ /[$valid]/) { 3145b9066f6cSSteven Rostedt 3146b9066f6cSSteven Rostedt if ($dep =~ /^[^$valid]*([$valid]+)/) { 3147b9066f6cSSteven Rostedt my $conf = "CONFIG_" . $1; 3148b9066f6cSSteven Rostedt 3149b9066f6cSSteven Rostedt $configs[$#configs + 1] = $conf; 3150b9066f6cSSteven Rostedt 3151b9066f6cSSteven Rostedt $dep =~ s/^[^$valid]*[$valid]+//; 3152b9066f6cSSteven Rostedt } else { 3153b9066f6cSSteven Rostedt die "this should never happen"; 3154b9066f6cSSteven Rostedt } 3155b9066f6cSSteven Rostedt } 3156b9066f6cSSteven Rostedt 3157b9066f6cSSteven Rostedt return @configs; 3158b9066f6cSSteven Rostedt} 3159b9066f6cSSteven Rostedt 3160b9066f6cSSteven Rostedtmy %min_configs; 3161b9066f6cSSteven Rostedtmy %keep_configs; 316243d1b651SSteven Rostedtmy %save_configs; 3163b9066f6cSSteven Rostedtmy %processed_configs; 3164b9066f6cSSteven Rostedtmy %nochange_config; 3165b9066f6cSSteven Rostedt 3166b9066f6cSSteven Rostedtsub test_this_config { 3167b9066f6cSSteven Rostedt my ($config) = @_; 3168b9066f6cSSteven Rostedt 3169b9066f6cSSteven Rostedt my $found; 3170b9066f6cSSteven Rostedt 3171b9066f6cSSteven Rostedt # if we already processed this config, skip it 3172b9066f6cSSteven Rostedt if (defined($processed_configs{$config})) { 3173b9066f6cSSteven Rostedt return undef; 3174b9066f6cSSteven Rostedt } 3175b9066f6cSSteven Rostedt $processed_configs{$config} = 1; 3176b9066f6cSSteven Rostedt 3177b9066f6cSSteven Rostedt # if this config failed during this round, skip it 3178b9066f6cSSteven Rostedt if (defined($nochange_config{$config})) { 3179b9066f6cSSteven Rostedt return undef; 3180b9066f6cSSteven Rostedt } 3181b9066f6cSSteven Rostedt 3182ac6974c7SSteven Rostedt my $kconfig = chomp_config $config; 3183b9066f6cSSteven Rostedt 3184b9066f6cSSteven Rostedt # Test dependencies first 3185b9066f6cSSteven Rostedt if (defined($depends{"$kconfig"})) { 3186b9066f6cSSteven Rostedt my @parents = get_depends $config; 3187b9066f6cSSteven Rostedt foreach my $parent (@parents) { 3188b9066f6cSSteven Rostedt # if the parent is in the min config, check it first 3189b9066f6cSSteven Rostedt next if (!defined($min_configs{$parent})); 3190b9066f6cSSteven Rostedt $found = test_this_config($parent); 3191b9066f6cSSteven Rostedt if (defined($found)) { 3192b9066f6cSSteven Rostedt return $found; 3193b9066f6cSSteven Rostedt } 3194b9066f6cSSteven Rostedt } 3195b9066f6cSSteven Rostedt } 3196b9066f6cSSteven Rostedt 3197b9066f6cSSteven Rostedt # Remove this config from the list of configs 3198b9066f6cSSteven Rostedt # do a make oldnoconfig and then read the resulting 3199b9066f6cSSteven Rostedt # .config to make sure it is missing the config that 3200b9066f6cSSteven Rostedt # we had before 3201b9066f6cSSteven Rostedt my %configs = %min_configs; 3202b9066f6cSSteven Rostedt delete $configs{$config}; 3203b9066f6cSSteven Rostedt make_new_config ((values %configs), (values %keep_configs)); 3204b9066f6cSSteven Rostedt make_oldconfig; 3205b9066f6cSSteven Rostedt undef %configs; 3206b9066f6cSSteven Rostedt assign_configs \%configs, $output_config; 3207b9066f6cSSteven Rostedt 3208b9066f6cSSteven Rostedt return $config if (!defined($configs{$config})); 3209b9066f6cSSteven Rostedt 3210b9066f6cSSteven Rostedt doprint "disabling config $config did not change .config\n"; 3211b9066f6cSSteven Rostedt 3212b9066f6cSSteven Rostedt $nochange_config{$config} = 1; 3213b9066f6cSSteven Rostedt 3214b9066f6cSSteven Rostedt return undef; 3215b9066f6cSSteven Rostedt} 3216b9066f6cSSteven Rostedt 32174c4ab120SSteven Rostedtsub make_min_config { 32184c4ab120SSteven Rostedt my ($i) = @_; 32194c4ab120SSteven Rostedt 3220ccc513b6SSteven Rostedt my $type = $minconfig_type; 3221ccc513b6SSteven Rostedt if ($type ne "boot" && $type ne "test") { 3222ccc513b6SSteven Rostedt fail "Invalid MIN_CONFIG_TYPE '$minconfig_type'\n" . 3223ccc513b6SSteven Rostedt " make_min_config works only with 'boot' and 'test'\n" and return; 3224ccc513b6SSteven Rostedt } 3225ccc513b6SSteven Rostedt 32264c4ab120SSteven Rostedt if (!defined($output_minconfig)) { 32274c4ab120SSteven Rostedt fail "OUTPUT_MIN_CONFIG not defined" and return; 32284c4ab120SSteven Rostedt } 322935ce5952SSteven Rostedt 323035ce5952SSteven Rostedt # If output_minconfig exists, and the start_minconfig 323135ce5952SSteven Rostedt # came from min_config, than ask if we should use 323235ce5952SSteven Rostedt # that instead. 323335ce5952SSteven Rostedt if (-f $output_minconfig && !$start_minconfig_defined) { 323435ce5952SSteven Rostedt print "$output_minconfig exists\n"; 323543de3316SSteven Rostedt if (!defined($use_output_minconfig)) { 323635ce5952SSteven Rostedt if (read_yn " Use it as minconfig?") { 323735ce5952SSteven Rostedt $start_minconfig = $output_minconfig; 323835ce5952SSteven Rostedt } 323943de3316SSteven Rostedt } elsif ($use_output_minconfig > 0) { 324043de3316SSteven Rostedt doprint "Using $output_minconfig as MIN_CONFIG\n"; 324143de3316SSteven Rostedt $start_minconfig = $output_minconfig; 324243de3316SSteven Rostedt } else { 324343de3316SSteven Rostedt doprint "Set to still use MIN_CONFIG as starting point\n"; 324443de3316SSteven Rostedt } 324535ce5952SSteven Rostedt } 324635ce5952SSteven Rostedt 32474c4ab120SSteven Rostedt if (!defined($start_minconfig)) { 32484c4ab120SSteven Rostedt fail "START_MIN_CONFIG or MIN_CONFIG not defined" and return; 32494c4ab120SSteven Rostedt } 32504c4ab120SSteven Rostedt 325135ce5952SSteven Rostedt my $temp_config = "$tmpdir/temp_config"; 325235ce5952SSteven Rostedt 32534c4ab120SSteven Rostedt # First things first. We build an allnoconfig to find 32544c4ab120SSteven Rostedt # out what the defaults are that we can't touch. 32554c4ab120SSteven Rostedt # Some are selections, but we really can't handle selections. 32564c4ab120SSteven Rostedt 32574c4ab120SSteven Rostedt my $save_minconfig = $minconfig; 32584c4ab120SSteven Rostedt undef $minconfig; 32594c4ab120SSteven Rostedt 32604c4ab120SSteven Rostedt run_command "$make allnoconfig" or return 0; 32614c4ab120SSteven Rostedt 3262b9066f6cSSteven Rostedt read_depends; 3263b9066f6cSSteven Rostedt 32644c4ab120SSteven Rostedt process_config_ignore $output_config; 3265b9066f6cSSteven Rostedt 326643d1b651SSteven Rostedt undef %save_configs; 3267b9066f6cSSteven Rostedt undef %min_configs; 32684c4ab120SSteven Rostedt 32694c4ab120SSteven Rostedt if (defined($ignore_config)) { 32704c4ab120SSteven Rostedt # make sure the file exists 32714c4ab120SSteven Rostedt `touch $ignore_config`; 327243d1b651SSteven Rostedt assign_configs \%save_configs, $ignore_config; 32734c4ab120SSteven Rostedt } 32744c4ab120SSteven Rostedt 327543d1b651SSteven Rostedt %keep_configs = %save_configs; 327643d1b651SSteven Rostedt 32774c4ab120SSteven Rostedt doprint "Load initial configs from $start_minconfig\n"; 32784c4ab120SSteven Rostedt 32794c4ab120SSteven Rostedt # Look at the current min configs, and save off all the 32804c4ab120SSteven Rostedt # ones that were set via the allnoconfig 32814c4ab120SSteven Rostedt assign_configs \%min_configs, $start_minconfig; 32824c4ab120SSteven Rostedt 32834c4ab120SSteven Rostedt my @config_keys = keys %min_configs; 32844c4ab120SSteven Rostedt 3285ac6974c7SSteven Rostedt # All configs need a depcount 3286ac6974c7SSteven Rostedt foreach my $config (@config_keys) { 3287ac6974c7SSteven Rostedt my $kconfig = chomp_config $config; 3288ac6974c7SSteven Rostedt if (!defined $depcount{$kconfig}) { 3289ac6974c7SSteven Rostedt $depcount{$kconfig} = 0; 3290ac6974c7SSteven Rostedt } 3291ac6974c7SSteven Rostedt } 3292ac6974c7SSteven Rostedt 32934c4ab120SSteven Rostedt # Remove anything that was set by the make allnoconfig 32944c4ab120SSteven Rostedt # we shouldn't need them as they get set for us anyway. 32954c4ab120SSteven Rostedt foreach my $config (@config_keys) { 32964c4ab120SSteven Rostedt # Remove anything in the ignore_config 32974c4ab120SSteven Rostedt if (defined($keep_configs{$config})) { 32984c4ab120SSteven Rostedt my $file = $ignore_config; 32994c4ab120SSteven Rostedt $file =~ s,.*/(.*?)$,$1,; 33004c4ab120SSteven Rostedt doprint "$config set by $file ... ignored\n"; 33014c4ab120SSteven Rostedt delete $min_configs{$config}; 33024c4ab120SSteven Rostedt next; 33034c4ab120SSteven Rostedt } 33044c4ab120SSteven Rostedt # But make sure the settings are the same. If a min config 33054c4ab120SSteven Rostedt # sets a selection, we do not want to get rid of it if 33064c4ab120SSteven Rostedt # it is not the same as what we have. Just move it into 33074c4ab120SSteven Rostedt # the keep configs. 33084c4ab120SSteven Rostedt if (defined($config_ignore{$config})) { 33094c4ab120SSteven Rostedt if ($config_ignore{$config} ne $min_configs{$config}) { 33104c4ab120SSteven Rostedt doprint "$config is in allnoconfig as '$config_ignore{$config}'"; 33114c4ab120SSteven Rostedt doprint " but it is '$min_configs{$config}' in minconfig .. keeping\n"; 33124c4ab120SSteven Rostedt $keep_configs{$config} = $min_configs{$config}; 33134c4ab120SSteven Rostedt } else { 33144c4ab120SSteven Rostedt doprint "$config set by allnoconfig ... ignored\n"; 33154c4ab120SSteven Rostedt } 33164c4ab120SSteven Rostedt delete $min_configs{$config}; 33174c4ab120SSteven Rostedt } 33184c4ab120SSteven Rostedt } 33194c4ab120SSteven Rostedt 33204c4ab120SSteven Rostedt my $done = 0; 3321b9066f6cSSteven Rostedt my $take_two = 0; 33224c4ab120SSteven Rostedt 33234c4ab120SSteven Rostedt while (!$done) { 33244c4ab120SSteven Rostedt 33254c4ab120SSteven Rostedt my $config; 33264c4ab120SSteven Rostedt my $found; 33274c4ab120SSteven Rostedt 33284c4ab120SSteven Rostedt # Now disable each config one by one and do a make oldconfig 33294c4ab120SSteven Rostedt # till we find a config that changes our list. 33304c4ab120SSteven Rostedt 33314c4ab120SSteven Rostedt my @test_configs = keys %min_configs; 3332ac6974c7SSteven Rostedt 3333ac6974c7SSteven Rostedt # Sort keys by who is most dependent on 3334ac6974c7SSteven Rostedt @test_configs = sort { $depcount{chomp_config($b)} <=> $depcount{chomp_config($a)} } 3335ac6974c7SSteven Rostedt @test_configs ; 3336ac6974c7SSteven Rostedt 3337ac6974c7SSteven Rostedt # Put configs that did not modify the config at the end. 33384c4ab120SSteven Rostedt my $reset = 1; 33394c4ab120SSteven Rostedt for (my $i = 0; $i < $#test_configs; $i++) { 33404c4ab120SSteven Rostedt if (!defined($nochange_config{$test_configs[0]})) { 33414c4ab120SSteven Rostedt $reset = 0; 33424c4ab120SSteven Rostedt last; 33434c4ab120SSteven Rostedt } 33444c4ab120SSteven Rostedt # This config didn't change the .config last time. 33454c4ab120SSteven Rostedt # Place it at the end 33464c4ab120SSteven Rostedt my $config = shift @test_configs; 33474c4ab120SSteven Rostedt push @test_configs, $config; 33484c4ab120SSteven Rostedt } 33494c4ab120SSteven Rostedt 33504c4ab120SSteven Rostedt # if every test config has failed to modify the .config file 33514c4ab120SSteven Rostedt # in the past, then reset and start over. 33524c4ab120SSteven Rostedt if ($reset) { 33534c4ab120SSteven Rostedt undef %nochange_config; 33544c4ab120SSteven Rostedt } 33554c4ab120SSteven Rostedt 3356b9066f6cSSteven Rostedt undef %processed_configs; 3357b9066f6cSSteven Rostedt 33584c4ab120SSteven Rostedt foreach my $config (@test_configs) { 33594c4ab120SSteven Rostedt 3360b9066f6cSSteven Rostedt $found = test_this_config $config; 33614c4ab120SSteven Rostedt 3362b9066f6cSSteven Rostedt last if (defined($found)); 33634c4ab120SSteven Rostedt 33644c4ab120SSteven Rostedt # oh well, try another config 33654c4ab120SSteven Rostedt } 33664c4ab120SSteven Rostedt 33674c4ab120SSteven Rostedt if (!defined($found)) { 3368b9066f6cSSteven Rostedt # we could have failed due to the nochange_config hash 3369b9066f6cSSteven Rostedt # reset and try again 3370b9066f6cSSteven Rostedt if (!$take_two) { 3371b9066f6cSSteven Rostedt undef %nochange_config; 3372b9066f6cSSteven Rostedt $take_two = 1; 3373b9066f6cSSteven Rostedt next; 3374b9066f6cSSteven Rostedt } 33754c4ab120SSteven Rostedt doprint "No more configs found that we can disable\n"; 33764c4ab120SSteven Rostedt $done = 1; 33774c4ab120SSteven Rostedt last; 33784c4ab120SSteven Rostedt } 3379b9066f6cSSteven Rostedt $take_two = 0; 33804c4ab120SSteven Rostedt 33814c4ab120SSteven Rostedt $config = $found; 33824c4ab120SSteven Rostedt 33834c4ab120SSteven Rostedt doprint "Test with $config disabled\n"; 33844c4ab120SSteven Rostedt 33854c4ab120SSteven Rostedt # set in_bisect to keep build and monitor from dieing 33864c4ab120SSteven Rostedt $in_bisect = 1; 33874c4ab120SSteven Rostedt 33884c4ab120SSteven Rostedt my $failed = 0; 3389bf1c95abSSteven Rostedt build "oldconfig" or $failed = 1; 3390bf1c95abSSteven Rostedt if (!$failed) { 33914c4ab120SSteven Rostedt start_monitor_and_boot or $failed = 1; 3392ccc513b6SSteven Rostedt 3393ccc513b6SSteven Rostedt if ($type eq "test" && !$failed) { 3394ccc513b6SSteven Rostedt do_run_test or $failed = 1; 3395ccc513b6SSteven Rostedt } 3396ccc513b6SSteven Rostedt 33974c4ab120SSteven Rostedt end_monitor; 3398bf1c95abSSteven Rostedt } 33994c4ab120SSteven Rostedt 34004c4ab120SSteven Rostedt $in_bisect = 0; 34014c4ab120SSteven Rostedt 34024c4ab120SSteven Rostedt if ($failed) { 3403b9066f6cSSteven Rostedt doprint "$min_configs{$config} is needed to boot the box... keeping\n"; 34044c4ab120SSteven Rostedt # this config is needed, add it to the ignore list. 34054c4ab120SSteven Rostedt $keep_configs{$config} = $min_configs{$config}; 340643d1b651SSteven Rostedt $save_configs{$config} = $min_configs{$config}; 34074c4ab120SSteven Rostedt delete $min_configs{$config}; 340835ce5952SSteven Rostedt 340935ce5952SSteven Rostedt # update new ignore configs 341035ce5952SSteven Rostedt if (defined($ignore_config)) { 341135ce5952SSteven Rostedt open (OUT, ">$temp_config") 341235ce5952SSteven Rostedt or die "Can't write to $temp_config"; 341343d1b651SSteven Rostedt foreach my $config (keys %save_configs) { 341443d1b651SSteven Rostedt print OUT "$save_configs{$config}\n"; 341535ce5952SSteven Rostedt } 341635ce5952SSteven Rostedt close OUT; 341735ce5952SSteven Rostedt run_command "mv $temp_config $ignore_config" or 341835ce5952SSteven Rostedt dodie "failed to copy update to $ignore_config"; 341935ce5952SSteven Rostedt } 342035ce5952SSteven Rostedt 34214c4ab120SSteven Rostedt } else { 34224c4ab120SSteven Rostedt # We booted without this config, remove it from the minconfigs. 34234c4ab120SSteven Rostedt doprint "$config is not needed, disabling\n"; 34244c4ab120SSteven Rostedt 34254c4ab120SSteven Rostedt delete $min_configs{$config}; 34264c4ab120SSteven Rostedt 34274c4ab120SSteven Rostedt # Also disable anything that is not enabled in this config 34284c4ab120SSteven Rostedt my %configs; 34294c4ab120SSteven Rostedt assign_configs \%configs, $output_config; 34304c4ab120SSteven Rostedt my @config_keys = keys %min_configs; 34314c4ab120SSteven Rostedt foreach my $config (@config_keys) { 34324c4ab120SSteven Rostedt if (!defined($configs{$config})) { 34334c4ab120SSteven Rostedt doprint "$config is not set, disabling\n"; 34344c4ab120SSteven Rostedt delete $min_configs{$config}; 34354c4ab120SSteven Rostedt } 34364c4ab120SSteven Rostedt } 34374c4ab120SSteven Rostedt 34384c4ab120SSteven Rostedt # Save off all the current mandidory configs 343935ce5952SSteven Rostedt open (OUT, ">$temp_config") 344035ce5952SSteven Rostedt or die "Can't write to $temp_config"; 34414c4ab120SSteven Rostedt foreach my $config (keys %keep_configs) { 34424c4ab120SSteven Rostedt print OUT "$keep_configs{$config}\n"; 34434c4ab120SSteven Rostedt } 34444c4ab120SSteven Rostedt foreach my $config (keys %min_configs) { 34454c4ab120SSteven Rostedt print OUT "$min_configs{$config}\n"; 34464c4ab120SSteven Rostedt } 34474c4ab120SSteven Rostedt close OUT; 344835ce5952SSteven Rostedt 344935ce5952SSteven Rostedt run_command "mv $temp_config $output_minconfig" or 345035ce5952SSteven Rostedt dodie "failed to copy update to $output_minconfig"; 34514c4ab120SSteven Rostedt } 34524c4ab120SSteven Rostedt 34534c4ab120SSteven Rostedt doprint "Reboot and wait $sleep_time seconds\n"; 3454bc7c5803SSteven Rostedt reboot_to_good $sleep_time; 34554c4ab120SSteven Rostedt } 34564c4ab120SSteven Rostedt 34574c4ab120SSteven Rostedt success $i; 34584c4ab120SSteven Rostedt return 1; 34594c4ab120SSteven Rostedt} 34604c4ab120SSteven Rostedt 34618d1491baSSteven Rostedt$#ARGV < 1 or die "ktest.pl version: $VERSION\n usage: ktest.pl config-file\n"; 34622545eb61SSteven Rostedt 34638d1491baSSteven Rostedtif ($#ARGV == 0) { 34648d1491baSSteven Rostedt $ktest_config = $ARGV[0]; 34658d1491baSSteven Rostedt if (! -f $ktest_config) { 34668d1491baSSteven Rostedt print "$ktest_config does not exist.\n"; 346735ce5952SSteven Rostedt if (!read_yn "Create it?") { 34688d1491baSSteven Rostedt exit 0; 34698d1491baSSteven Rostedt } 34708d1491baSSteven Rostedt } 34718d1491baSSteven Rostedt} else { 34728d1491baSSteven Rostedt $ktest_config = "ktest.conf"; 34738d1491baSSteven Rostedt} 34748d1491baSSteven Rostedt 34758d1491baSSteven Rostedtif (! -f $ktest_config) { 3476dbd3783bSSteven Rostedt $newconfig = 1; 3477c4261d0fSSteven Rostedt get_test_case; 34788d1491baSSteven Rostedt open(OUT, ">$ktest_config") or die "Can not create $ktest_config"; 34798d1491baSSteven Rostedt print OUT << "EOF" 34808d1491baSSteven Rostedt# Generated by ktest.pl 34818d1491baSSteven Rostedt# 34820e7a22deSSteven Rostedt 34830e7a22deSSteven Rostedt# PWD is a ktest.pl variable that will result in the process working 34840e7a22deSSteven Rostedt# directory that ktest.pl is executed in. 34850e7a22deSSteven Rostedt 34860e7a22deSSteven Rostedt# THIS_DIR is automatically assigned the PWD of the path that generated 34870e7a22deSSteven Rostedt# the config file. It is best to use this variable when assigning other 34880e7a22deSSteven Rostedt# directory paths within this directory. This allows you to easily 34890e7a22deSSteven Rostedt# move the test cases to other locations or to other machines. 34900e7a22deSSteven Rostedt# 34910e7a22deSSteven RostedtTHIS_DIR := $variable{"PWD"} 34920e7a22deSSteven Rostedt 34938d1491baSSteven Rostedt# Define each test with TEST_START 34948d1491baSSteven Rostedt# The config options below it will override the defaults 34958d1491baSSteven RostedtTEST_START 3496c4261d0fSSteven RostedtTEST_TYPE = $default{"TEST_TYPE"} 34978d1491baSSteven Rostedt 34988d1491baSSteven RostedtDEFAULTS 34998d1491baSSteven RostedtEOF 35008d1491baSSteven Rostedt; 35018d1491baSSteven Rostedt close(OUT); 35028d1491baSSteven Rostedt} 35038d1491baSSteven Rostedtread_config $ktest_config; 35048d1491baSSteven Rostedt 350523715c3cSSteven Rostedtif (defined($opt{"LOG_FILE"})) { 350623715c3cSSteven Rostedt $opt{"LOG_FILE"} = eval_option($opt{"LOG_FILE"}, -1); 350723715c3cSSteven Rostedt} 350823715c3cSSteven Rostedt 35098d1491baSSteven Rostedt# Append any configs entered in manually to the config file. 35108d1491baSSteven Rostedtmy @new_configs = keys %entered_configs; 35118d1491baSSteven Rostedtif ($#new_configs >= 0) { 35128d1491baSSteven Rostedt print "\nAppending entered in configs to $ktest_config\n"; 35138d1491baSSteven Rostedt open(OUT, ">>$ktest_config") or die "Can not append to $ktest_config"; 35148d1491baSSteven Rostedt foreach my $config (@new_configs) { 35158d1491baSSteven Rostedt print OUT "$config = $entered_configs{$config}\n"; 35160e7a22deSSteven Rostedt $opt{$config} = process_variables($entered_configs{$config}); 35178d1491baSSteven Rostedt } 35188d1491baSSteven Rostedt} 35192545eb61SSteven Rostedt 35202b7d9b21SSteven Rostedtif ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) { 35212b7d9b21SSteven Rostedt unlink $opt{"LOG_FILE"}; 35222b7d9b21SSteven Rostedt} 35232545eb61SSteven Rostedt 35242b7d9b21SSteven Rostedtdoprint "\n\nSTARTING AUTOMATED TESTS\n\n"; 35252b7d9b21SSteven Rostedt 3526a57419b3SSteven Rostedtfor (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) { 3527a57419b3SSteven Rostedt 3528a57419b3SSteven Rostedt if (!$i) { 3529a57419b3SSteven Rostedt doprint "DEFAULT OPTIONS:\n"; 3530a57419b3SSteven Rostedt } else { 3531a57419b3SSteven Rostedt doprint "\nTEST $i OPTIONS"; 3532a57419b3SSteven Rostedt if (defined($repeat_tests{$i})) { 3533a57419b3SSteven Rostedt $repeat = $repeat_tests{$i}; 3534a57419b3SSteven Rostedt doprint " ITERATE $repeat"; 3535a57419b3SSteven Rostedt } 3536a57419b3SSteven Rostedt doprint "\n"; 3537a57419b3SSteven Rostedt } 3538a57419b3SSteven Rostedt 35392b7d9b21SSteven Rostedt foreach my $option (sort keys %opt) { 3540a57419b3SSteven Rostedt 3541a57419b3SSteven Rostedt if ($option =~ /\[(\d+)\]$/) { 3542a57419b3SSteven Rostedt next if ($i != $1); 3543a57419b3SSteven Rostedt } else { 3544a57419b3SSteven Rostedt next if ($i); 3545a57419b3SSteven Rostedt } 3546a57419b3SSteven Rostedt 35472b7d9b21SSteven Rostedt doprint "$option = $opt{$option}\n"; 35482b7d9b21SSteven Rostedt } 3549a57419b3SSteven Rostedt} 35502545eb61SSteven Rostedt 35512a62512bSSteven Rostedtsub __set_test_option { 35525a391fbfSSteven Rostedt my ($name, $i) = @_; 35535a391fbfSSteven Rostedt 35545a391fbfSSteven Rostedt my $option = "$name\[$i\]"; 35555a391fbfSSteven Rostedt 35565a391fbfSSteven Rostedt if (defined($opt{$option})) { 35575a391fbfSSteven Rostedt return $opt{$option}; 35585a391fbfSSteven Rostedt } 35595a391fbfSSteven Rostedt 3560a57419b3SSteven Rostedt foreach my $test (keys %repeat_tests) { 3561a57419b3SSteven Rostedt if ($i >= $test && 3562a57419b3SSteven Rostedt $i < $test + $repeat_tests{$test}) { 3563a57419b3SSteven Rostedt $option = "$name\[$test\]"; 3564a57419b3SSteven Rostedt if (defined($opt{$option})) { 3565a57419b3SSteven Rostedt return $opt{$option}; 3566a57419b3SSteven Rostedt } 3567a57419b3SSteven Rostedt } 3568a57419b3SSteven Rostedt } 3569a57419b3SSteven Rostedt 35705a391fbfSSteven Rostedt if (defined($opt{$name})) { 35715a391fbfSSteven Rostedt return $opt{$name}; 35725a391fbfSSteven Rostedt } 35735a391fbfSSteven Rostedt 35745a391fbfSSteven Rostedt return undef; 35755a391fbfSSteven Rostedt} 35765a391fbfSSteven Rostedt 35772a62512bSSteven Rostedtsub set_test_option { 35782a62512bSSteven Rostedt my ($name, $i) = @_; 35792a62512bSSteven Rostedt 35802a62512bSSteven Rostedt my $option = __set_test_option($name, $i); 35812a62512bSSteven Rostedt return $option if (!defined($option)); 35822a62512bSSteven Rostedt 358323715c3cSSteven Rostedt return eval_option($option, $i); 35842a62512bSSteven Rostedt} 35852a62512bSSteven Rostedt 35862545eb61SSteven Rostedt# First we need to do is the builds 3587a75fececSSteven Rostedtfor (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) { 35882545eb61SSteven Rostedt 35894ab1cce5SSteven Rostedt # Do not reboot on failing test options 35904ab1cce5SSteven Rostedt $no_reboot = 1; 3591759a3cc6SSteven Rostedt $reboot_success = 0; 35924ab1cce5SSteven Rostedt 3593683a3e64SSteven Rostedt $have_version = 0; 3594683a3e64SSteven Rostedt 3595576f627cSSteven Rostedt $iteration = $i; 3596576f627cSSteven Rostedt 3597a75fececSSteven Rostedt my $makecmd = set_test_option("MAKE_CMD", $i); 3598a75fececSSteven Rostedt 35999cc9e091SSteven Rostedt # Load all the options into their mapped variable names 36009cc9e091SSteven Rostedt foreach my $opt (keys %option_map) { 36019cc9e091SSteven Rostedt ${$option_map{$opt}} = set_test_option($opt, $i); 36029cc9e091SSteven Rostedt } 3603b5f4aea6SSteven Rostedt 360435ce5952SSteven Rostedt $start_minconfig_defined = 1; 360535ce5952SSteven Rostedt 3606921ed4c7SSteven Rostedt # The first test may override the PRE_KTEST option 3607921ed4c7SSteven Rostedt if (defined($pre_ktest) && $i == 1) { 3608921ed4c7SSteven Rostedt doprint "\n"; 3609921ed4c7SSteven Rostedt run_command $pre_ktest; 3610921ed4c7SSteven Rostedt } 3611921ed4c7SSteven Rostedt 3612921ed4c7SSteven Rostedt # Any test can override the POST_KTEST option 3613921ed4c7SSteven Rostedt # The last test takes precedence. 3614921ed4c7SSteven Rostedt if (defined($post_ktest)) { 3615921ed4c7SSteven Rostedt $final_post_ktest = $post_ktest; 3616921ed4c7SSteven Rostedt } 3617921ed4c7SSteven Rostedt 36184c4ab120SSteven Rostedt if (!defined($start_minconfig)) { 361935ce5952SSteven Rostedt $start_minconfig_defined = 0; 36204c4ab120SSteven Rostedt $start_minconfig = $minconfig; 36214c4ab120SSteven Rostedt } 36224c4ab120SSteven Rostedt 3623a75fececSSteven Rostedt chdir $builddir || die "can't change directory to $builddir"; 3624a75fececSSteven Rostedt 3625a908a665SAndrew Jones foreach my $dir ($tmpdir, $outputdir) { 3626a908a665SAndrew Jones if (!-d $dir) { 3627a908a665SAndrew Jones mkpath($dir) or 3628a908a665SAndrew Jones die "can't create $dir"; 3629a908a665SAndrew Jones } 3630a75fececSSteven Rostedt } 3631a75fececSSteven Rostedt 3632e48c5293SSteven Rostedt $ENV{"SSH_USER"} = $ssh_user; 3633e48c5293SSteven Rostedt $ENV{"MACHINE"} = $machine; 3634e48c5293SSteven Rostedt 3635a75fececSSteven Rostedt $buildlog = "$tmpdir/buildlog-$machine"; 3636a9dd5d63SRabin Vincent $testlog = "$tmpdir/testlog-$machine"; 3637a75fececSSteven Rostedt $dmesg = "$tmpdir/dmesg-$machine"; 3638a75fececSSteven Rostedt $make = "$makecmd O=$outputdir"; 363951ad1dd1SSteven Rostedt $output_config = "$outputdir/.config"; 3640a75fececSSteven Rostedt 3641bb8474b1SSteven Rostedt if (!$buildonly) { 3642bb8474b1SSteven Rostedt $target = "$ssh_user\@$machine"; 3643a75fececSSteven Rostedt if ($reboot_type eq "grub") { 3644576f627cSSteven Rostedt dodie "GRUB_MENU not defined" if (!defined($grub_menu)); 3645a75fececSSteven Rostedt } 3646bb8474b1SSteven Rostedt } 3647a75fececSSteven Rostedt 3648a75fececSSteven Rostedt my $run_type = $build_type; 3649a75fececSSteven Rostedt if ($test_type eq "patchcheck") { 3650b5f4aea6SSteven Rostedt $run_type = $patchcheck_type; 3651a75fececSSteven Rostedt } elsif ($test_type eq "bisect") { 3652b5f4aea6SSteven Rostedt $run_type = $bisect_type; 36530a05c769SSteven Rostedt } elsif ($test_type eq "config_bisect") { 3654b5f4aea6SSteven Rostedt $run_type = $config_bisect_type; 3655a75fececSSteven Rostedt } 3656a75fececSSteven Rostedt 36574c4ab120SSteven Rostedt if ($test_type eq "make_min_config") { 36584c4ab120SSteven Rostedt $run_type = ""; 36594c4ab120SSteven Rostedt } 36604c4ab120SSteven Rostedt 3661a75fececSSteven Rostedt # mistake in config file? 3662a75fececSSteven Rostedt if (!defined($run_type)) { 3663a75fececSSteven Rostedt $run_type = "ERROR"; 3664a75fececSSteven Rostedt } 36652545eb61SSteven Rostedt 3666e0a8742eSSteven Rostedt my $installme = ""; 3667e0a8742eSSteven Rostedt $installme = " no_install" if ($no_install); 3668e0a8742eSSteven Rostedt 36692545eb61SSteven Rostedt doprint "\n\n"; 3670e0a8742eSSteven Rostedt doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type$installme\n\n"; 36717faafbd6SSteven Rostedt 3672921ed4c7SSteven Rostedt if (defined($pre_test)) { 3673921ed4c7SSteven Rostedt run_command $pre_test; 3674921ed4c7SSteven Rostedt } 3675921ed4c7SSteven Rostedt 36767faafbd6SSteven Rostedt unlink $dmesg; 36777faafbd6SSteven Rostedt unlink $buildlog; 3678a9dd5d63SRabin Vincent unlink $testlog; 36792545eb61SSteven Rostedt 3680250bae8bSSteven Rostedt if (defined($addconfig)) { 3681250bae8bSSteven Rostedt my $min = $minconfig; 36822b7d9b21SSteven Rostedt if (!defined($minconfig)) { 3683250bae8bSSteven Rostedt $min = ""; 3684250bae8bSSteven Rostedt } 3685250bae8bSSteven Rostedt run_command "cat $addconfig $min > $tmpdir/add_config" or 36862b7d9b21SSteven Rostedt dodie "Failed to create temp config"; 36879be2e6b5SSteven Rostedt $minconfig = "$tmpdir/add_config"; 36882b7d9b21SSteven Rostedt } 36892b7d9b21SSteven Rostedt 36906c5ee0beSSteven Rostedt if (defined($checkout)) { 36916c5ee0beSSteven Rostedt run_command "git checkout $checkout" or 36926c5ee0beSSteven Rostedt die "failed to checkout $checkout"; 36936c5ee0beSSteven Rostedt } 36946c5ee0beSSteven Rostedt 3695759a3cc6SSteven Rostedt $no_reboot = 0; 3696759a3cc6SSteven Rostedt 3697648a182cSSteven Rostedt # A test may opt to not reboot the box 3698648a182cSSteven Rostedt if ($reboot_on_success) { 3699759a3cc6SSteven Rostedt $reboot_success = 1; 3700648a182cSSteven Rostedt } 37014ab1cce5SSteven Rostedt 3702a75fececSSteven Rostedt if ($test_type eq "bisect") { 37035f9b6cedSSteven Rostedt bisect $i; 37045f9b6cedSSteven Rostedt next; 37050a05c769SSteven Rostedt } elsif ($test_type eq "config_bisect") { 37060a05c769SSteven Rostedt config_bisect $i; 37070a05c769SSteven Rostedt next; 3708a75fececSSteven Rostedt } elsif ($test_type eq "patchcheck") { 37096c5ee0beSSteven Rostedt patchcheck $i; 37106c5ee0beSSteven Rostedt next; 37114c4ab120SSteven Rostedt } elsif ($test_type eq "make_min_config") { 37124c4ab120SSteven Rostedt make_min_config $i; 37134c4ab120SSteven Rostedt next; 37145f9b6cedSSteven Rostedt } 37155f9b6cedSSteven Rostedt 37167faafbd6SSteven Rostedt if ($build_type ne "nobuild") { 37177faafbd6SSteven Rostedt build $build_type or next; 37182545eb61SSteven Rostedt } 37192545eb61SSteven Rostedt 3720cd8e368fSSteven Rostedt if ($test_type eq "install") { 3721cd8e368fSSteven Rostedt get_version; 3722cd8e368fSSteven Rostedt install; 3723cd8e368fSSteven Rostedt success $i; 3724cd8e368fSSteven Rostedt next; 3725cd8e368fSSteven Rostedt } 3726cd8e368fSSteven Rostedt 3727a75fececSSteven Rostedt if ($test_type ne "build") { 37287faafbd6SSteven Rostedt my $failed = 0; 3729ddf607e5SSteven Rostedt start_monitor_and_boot or $failed = 1; 3730a75fececSSteven Rostedt 3731a75fececSSteven Rostedt if (!$failed && $test_type ne "boot" && defined($run_test)) { 37327faafbd6SSteven Rostedt do_run_test or $failed = 1; 37335a391fbfSSteven Rostedt } 37347faafbd6SSteven Rostedt end_monitor; 37357faafbd6SSteven Rostedt next if ($failed); 3736a75fececSSteven Rostedt } 37375a391fbfSSteven Rostedt 37385f9b6cedSSteven Rostedt success $i; 373975c3fda7SSteven Rostedt} 37402545eb61SSteven Rostedt 3741921ed4c7SSteven Rostedtif (defined($final_post_ktest)) { 3742921ed4c7SSteven Rostedt run_command $final_post_ktest; 3743921ed4c7SSteven Rostedt} 3744921ed4c7SSteven Rostedt 37455c42fc5bSSteven Rostedtif ($opt{"POWEROFF_ON_SUCCESS"}) { 374675c3fda7SSteven Rostedt halt; 3747759a3cc6SSteven Rostedt} elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot && $reboot_success) { 3748bc7c5803SSteven Rostedt reboot_to_good; 3749648a182cSSteven Rostedt} elsif (defined($switch_to_good)) { 3750648a182cSSteven Rostedt # still need to get to the good kernel 3751648a182cSSteven Rostedt run_command $switch_to_good; 37525c42fc5bSSteven Rostedt} 375375c3fda7SSteven Rostedt 3754648a182cSSteven Rostedt 3755e48c5293SSteven Rostedtdoprint "\n $successes of $opt{NUM_TESTS} tests were successful\n\n"; 3756e48c5293SSteven Rostedt 37572545eb61SSteven Rostedtexit 0; 3758