3 # Copyright 2010 - Steven Rostedt <srostedt@redhat.com>, Red Hat Inc.
4 # Licensed under the terms of the GNU GPL License version 2
9 use Fcntl qw(F_GETFL F_SETFL O_NONBLOCK);
10 use File::Path qw(mkpath);
11 use File::Copy qw(cp);
25 "TEST_TYPE" => "build",
26 "BUILD_TYPE" => "randconfig",
29 "TMP_DIR" => "/tmp/ktest/\${MACHINE}",
30 "SLEEP_TIME" => 60, # sleep time between tests
32 "REBOOT_ON_ERROR" => 0,
33 "POWEROFF_ON_ERROR" => 0,
34 "REBOOT_ON_SUCCESS" => 1,
35 "POWEROFF_ON_SUCCESS" => 0,
36 "BUILD_OPTIONS" => "",
37 "BISECT_SLEEP_TIME" => 60, # sleep time between bisects
38 "PATCHCHECK_SLEEP_TIME" => 60, # sleep time between patch checks
42 "SUCCESS_LINE" => "login:",
43 "DETECT_TRIPLE_FAULT" => 1,
45 "BOOTED_TIMEOUT" => 1,
46 "DIE_ON_FAILURE" => 1,
47 "SSH_EXEC" => "ssh \$SSH_USER\@\$MACHINE \$SSH_COMMAND",
48 "SCP_TO_TARGET" => "scp \$SRC_FILE \$SSH_USER\@\$MACHINE:\$DST_FILE",
49 "SCP_TO_TARGET_INSTALL" => "\${SCP_TO_TARGET}",
50 "REBOOT" => "ssh \$SSH_USER\@\$MACHINE reboot",
51 "STOP_AFTER_SUCCESS" => 10,
52 "STOP_AFTER_FAILURE" => 60,
53 "STOP_TEST_AFTER" => 600,
55 # required, and we will ask users if they don't have them but we keep the default
56 # value something that is common.
57 "REBOOT_TYPE" => "grub",
58 "LOCALVERSION" => "-test",
60 "BUILD_TARGET" => "arch/x86/boot/bzImage",
61 "TARGET_IMAGE" => "/boot/vmlinuz-test",
89 my $poweroff_on_error;
90 my $reboot_on_success;
92 my $powercycle_after_reboot;
93 my $poweroff_after_halt;
96 my $scp_to_target_install;
107 my $start_minconfig_defined;
108 my $output_minconfig;
113 my $bisect_bad_commit = "";
117 my $config_bisect_good;
121 my $bisect_ret_abort;
122 my $bisect_ret_default;
123 my $in_patchcheck = 0;
133 my $bisect_sleep_time;
134 my $patchcheck_sleep_time;
141 my $detect_triplefault;
143 my $reboot_success_line;
145 my $stop_after_success;
146 my $stop_after_failure;
165 my $config_bisect_type;
168 my $patchcheck_start;
171 # set when a test is something other that just building or install
172 # which would require more options.
175 # set when creating a new config
183 # do not force reboots on config problems
187 "MACHINE" => \$machine,
188 "SSH_USER" => \$ssh_user,
189 "TMP_DIR" => \$tmpdir,
190 "OUTPUT_DIR" => \$outputdir,
191 "BUILD_DIR" => \$builddir,
192 "TEST_TYPE" => \$test_type,
193 "BUILD_TYPE" => \$build_type,
194 "BUILD_OPTIONS" => \$build_options,
195 "PRE_BUILD" => \$pre_build,
196 "POST_BUILD" => \$post_build,
197 "PRE_BUILD_DIE" => \$pre_build_die,
198 "POST_BUILD_DIE" => \$post_build_die,
199 "POWER_CYCLE" => \$power_cycle,
200 "REBOOT" => \$reboot,
201 "BUILD_NOCLEAN" => \$noclean,
202 "MIN_CONFIG" => \$minconfig,
203 "OUTPUT_MIN_CONFIG" => \$output_minconfig,
204 "START_MIN_CONFIG" => \$start_minconfig,
205 "IGNORE_CONFIG" => \$ignore_config,
206 "TEST" => \$run_test,
207 "ADD_CONFIG" => \$addconfig,
208 "REBOOT_TYPE" => \$reboot_type,
209 "GRUB_MENU" => \$grub_menu,
210 "POST_INSTALL" => \$post_install,
211 "NO_INSTALL" => \$no_install,
212 "REBOOT_SCRIPT" => \$reboot_script,
213 "REBOOT_ON_ERROR" => \$reboot_on_error,
214 "SWITCH_TO_GOOD" => \$switch_to_good,
215 "SWITCH_TO_TEST" => \$switch_to_test,
216 "POWEROFF_ON_ERROR" => \$poweroff_on_error,
217 "REBOOT_ON_SUCCESS" => \$reboot_on_success,
218 "DIE_ON_FAILURE" => \$die_on_failure,
219 "POWER_OFF" => \$power_off,
220 "POWERCYCLE_AFTER_REBOOT" => \$powercycle_after_reboot,
221 "POWEROFF_AFTER_HALT" => \$poweroff_after_halt,
222 "SLEEP_TIME" => \$sleep_time,
223 "BISECT_SLEEP_TIME" => \$bisect_sleep_time,
224 "PATCHCHECK_SLEEP_TIME" => \$patchcheck_sleep_time,
225 "IGNORE_WARNINGS" => \$ignore_warnings,
226 "IGNORE_ERRORS" => \$ignore_errors,
227 "BISECT_MANUAL" => \$bisect_manual,
228 "BISECT_SKIP" => \$bisect_skip,
229 "CONFIG_BISECT_GOOD" => \$config_bisect_good,
230 "BISECT_RET_GOOD" => \$bisect_ret_good,
231 "BISECT_RET_BAD" => \$bisect_ret_bad,
232 "BISECT_RET_SKIP" => \$bisect_ret_skip,
233 "BISECT_RET_ABORT" => \$bisect_ret_abort,
234 "BISECT_RET_DEFAULT" => \$bisect_ret_default,
235 "STORE_FAILURES" => \$store_failures,
236 "STORE_SUCCESSES" => \$store_successes,
237 "TEST_NAME" => \$test_name,
238 "TIMEOUT" => \$timeout,
239 "BOOTED_TIMEOUT" => \$booted_timeout,
240 "CONSOLE" => \$console,
241 "DETECT_TRIPLE_FAULT" => \$detect_triplefault,
242 "SUCCESS_LINE" => \$success_line,
243 "REBOOT_SUCCESS_LINE" => \$reboot_success_line,
244 "STOP_AFTER_SUCCESS" => \$stop_after_success,
245 "STOP_AFTER_FAILURE" => \$stop_after_failure,
246 "STOP_TEST_AFTER" => \$stop_test_after,
247 "BUILD_TARGET" => \$build_target,
248 "SSH_EXEC" => \$ssh_exec,
249 "SCP_TO_TARGET" => \$scp_to_target,
250 "SCP_TO_TARGET_INSTALL" => \$scp_to_target_install,
251 "CHECKOUT" => \$checkout,
252 "TARGET_IMAGE" => \$target_image,
253 "LOCALVERSION" => \$localversion,
255 "BISECT_GOOD" => \$bisect_good,
256 "BISECT_BAD" => \$bisect_bad,
257 "BISECT_TYPE" => \$bisect_type,
258 "BISECT_START" => \$bisect_start,
259 "BISECT_REPLAY" => \$bisect_replay,
260 "BISECT_FILES" => \$bisect_files,
261 "BISECT_REVERSE" => \$bisect_reverse,
262 "BISECT_CHECK" => \$bisect_check,
264 "CONFIG_BISECT" => \$config_bisect,
265 "CONFIG_BISECT_TYPE" => \$config_bisect_type,
267 "PATCHCHECK_TYPE" => \$patchcheck_type,
268 "PATCHCHECK_START" => \$patchcheck_start,
269 "PATCHCHECK_END" => \$patchcheck_end,
272 # Options may be used by other options, record them.
275 # default variables that can be used
276 chomp ($variable{"PWD"} = `pwd`);
278 $config_help{"MACHINE"} = << "EOF"
279 The machine hostname that you will test.
280 For build only tests, it is still needed to differentiate log files.
283 $config_help{"SSH_USER"} = << "EOF"
284 The box is expected to have ssh on normal bootup, provide the user
285 (most likely root, since you need privileged operations)
288 $config_help{"BUILD_DIR"} = << "EOF"
289 The directory that contains the Linux source code (full path).
290 You can use \${PWD} that will be the path where ktest.pl is run, or use
291 \${THIS_DIR} which is assigned \${PWD} but may be changed later.
294 $config_help{"OUTPUT_DIR"} = << "EOF"
295 The directory that the objects will be built (full path).
296 (can not be same as BUILD_DIR)
297 You can use \${PWD} that will be the path where ktest.pl is run, or use
298 \${THIS_DIR} which is assigned \${PWD} but may be changed later.
301 $config_help{"BUILD_TARGET"} = << "EOF"
302 The location of the compiled file to copy to the target.
303 (relative to OUTPUT_DIR)
306 $config_help{"BUILD_OPTIONS"} = << "EOF"
307 Options to add to \"make\" when building.
311 $config_help{"TARGET_IMAGE"} = << "EOF"
312 The place to put your image on the test machine.
315 $config_help{"POWER_CYCLE"} = << "EOF"
316 A script or command to reboot the box.
318 Here is a digital loggers power switch example
319 POWER_CYCLE = wget --no-proxy -O /dev/null -q --auth-no-challenge 'http://admin:admin\@power/outlet?5=CCL'
321 Here is an example to reboot a virtual box on the current host
322 with the name "Guest".
323 POWER_CYCLE = virsh destroy Guest; sleep 5; virsh start Guest
326 $config_help{"CONSOLE"} = << "EOF"
327 The script or command that reads the console
329 If you use ttywatch server, something like the following would work.
330 CONSOLE = nc -d localhost 3001
332 For a virtual machine with guest name "Guest".
333 CONSOLE = virsh console Guest
336 $config_help{"LOCALVERSION"} = << "EOF"
337 Required version ending to differentiate the test
338 from other linux builds on the system.
341 $config_help{"REBOOT_TYPE"} = << "EOF"
342 Way to reboot the box to the test kernel.
343 Only valid options so far are "grub" and "script".
345 If you specify grub, it will assume grub version 1
346 and will search in /boot/grub/menu.lst for the title \$GRUB_MENU
347 and select that target to reboot to the kernel. If this is not
348 your setup, then specify "script" and have a command or script
349 specified in REBOOT_SCRIPT to boot to the target.
351 The entry in /boot/grub/menu.lst must be entered in manually.
352 The test will not modify that file.
355 $config_help{"GRUB_MENU"} = << "EOF"
356 The grub title name for the test kernel to boot
357 (Only mandatory if REBOOT_TYPE = grub)
359 Note, ktest.pl will not update the grub menu.lst, you need to
360 manually add an option for the test. ktest.pl will search
361 the grub menu.lst for this option to find what kernel to
364 For example, if in the /boot/grub/menu.lst the test kernel title has:
367 GRUB_MENU = Test Kernel
370 $config_help{"REBOOT_SCRIPT"} = << "EOF"
371 A script to reboot the target into the test kernel
372 (Only mandatory if REBOOT_TYPE = script)
377 my ($cancel, $prompt) = @_;
383 print "$prompt [y/n/C] ";
385 print "$prompt [Y/n] ";
389 if ($ans =~ /^\s*$/) {
396 last if ($ans =~ /^y$/i || $ans =~ /^n$/i);
398 last if ($ans =~ /^c$/i);
399 print "Please answer either 'y', 'n' or 'c'.\n";
401 print "Please answer either 'y' or 'n'.\n";
407 if ($ans !~ /^y$/i) {
416 return read_prompt 0, $prompt;
422 return read_prompt 1, $prompt;
425 sub get_ktest_config {
429 return if (defined($opt{$config}));
431 if (defined($config_help{$config})) {
433 print $config_help{$config};
438 if (defined($default{$config}) && length($default{$config})) {
439 print "\[$default{$config}\] ";
442 $ans =~ s/^\s*(.*\S)\s*$/$1/;
443 if ($ans =~ /^\s*$/) {
444 if ($default{$config}) {
445 $ans = $default{$config};
447 print "Your answer can not be blank\n";
451 $entered_configs{$config} = ${ans};
456 sub get_ktest_configs {
457 get_ktest_config("MACHINE");
458 get_ktest_config("BUILD_DIR");
459 get_ktest_config("OUTPUT_DIR");
462 get_ktest_config("BUILD_OPTIONS");
465 # options required for other than just building a kernel
467 get_ktest_config("POWER_CYCLE");
468 get_ktest_config("CONSOLE");
471 # options required for install and more
472 if ($buildonly != 1) {
473 get_ktest_config("SSH_USER");
474 get_ktest_config("BUILD_TARGET");
475 get_ktest_config("TARGET_IMAGE");
478 get_ktest_config("LOCALVERSION");
480 return if ($buildonly);
482 my $rtype = $opt{"REBOOT_TYPE"};
484 if (!defined($rtype)) {
485 if (!defined($opt{"GRUB_MENU"})) {
486 get_ktest_config("REBOOT_TYPE");
487 $rtype = $entered_configs{"REBOOT_TYPE"};
493 if ($rtype eq "grub") {
494 get_ktest_config("GRUB_MENU");
498 sub process_variables {
499 my ($value, $remove_undef) = @_;
502 # We want to check for '\', and it is just easier
503 # to check the previous characet of '$' and not need
504 # to worry if '$' is the first character. By adding
505 # a space to $value, we can just check [^\\]\$ and
506 # it will still work.
509 while ($value =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
513 # append beginning of value to retval
514 $retval = "$retval$begin";
515 if (defined($variable{$var})) {
516 $retval = "$retval$variable{$var}";
517 } elsif (defined($remove_undef) && $remove_undef) {
518 # for if statements, any variable that is not defined,
519 # we simple convert to 0
520 $retval = "${retval}0";
522 # put back the origin piece.
523 $retval = "$retval\$\{$var\}";
524 # This could be an option that is used later, save
525 # it so we don't warn if this option is not one of
527 $used_options{$var} = 1;
531 $retval = "$retval$value";
533 # remove the space added in the beginning
540 my ($lvalue, $rvalue, $override, $overrides, $name) = @_;
542 my $prvalue = process_variables($rvalue);
544 if ($buildonly && $lvalue =~ /^TEST_TYPE(\[.*\])?$/ && $prvalue ne "build") {
545 # Note if a test is something other than build, then we
546 # will need other manditory options.
547 if ($prvalue ne "install") {
550 # install still limits some manditory options.
555 if (defined($opt{$lvalue})) {
556 if (!$override || defined(${$overrides}{$lvalue})) {
559 $extra = "In the same override section!\n";
561 die "$name: $.: Option $lvalue defined more than once!\n$extra";
563 ${$overrides}{$lvalue} = $prvalue;
565 if ($rvalue =~ /^\s*$/) {
566 delete $opt{$lvalue};
568 $opt{$lvalue} = $prvalue;
573 my ($lvalue, $rvalue) = @_;
575 if ($rvalue =~ /^\s*$/) {
576 delete $variable{$lvalue};
578 $rvalue = process_variables($rvalue);
579 $variable{$lvalue} = $rvalue;
583 sub process_compare {
584 my ($lval, $cmp, $rval) = @_;
595 return $lval eq $rval;
596 } elsif ($cmp eq "!=") {
597 return $lval ne $rval;
600 my $statement = "$lval $cmp $rval";
601 my $ret = eval $statement;
603 # $@ stores error of eval
614 return defined($variable{$2}) ||
619 sub process_expression {
620 my ($name, $val) = @_;
624 while ($val =~ s/\(([^\(]*?)\)/\&\&\&\&VAL\&\&\&\&/) {
627 if (process_expression($name, $express)) {
628 $val =~ s/\&\&\&\&VAL\&\&\&\&/ 1 /;
630 $val =~ s/\&\&\&\&VAL\&\&\&\&/ 0 /;
638 while ($val =~ s/^(.*?)($OR|$AND)//) {
642 if (process_expression($name, $express)) {
653 if ($val =~ /(.*)(==|\!=|>=|<=|>|<)(.*)/) {
654 my $ret = process_compare($1, $2, $3);
656 die "$name: $.: Unable to process comparison\n";
661 if ($val =~ /^\s*(NOT\s*)?DEFINED\s+(\S+)\s*$/) {
663 return !value_defined($2);
665 return value_defined($2);
669 if ($val =~ /^\s*0\s*$/) {
671 } elsif ($val =~ /^\s*\d+\s*$/) {
675 die ("$name: $.: Undefined content $val in if statement\n");
679 my ($name, $value) = @_;
681 # Convert variables and replace undefined ones with 0
682 my $val = process_variables($value, 1);
683 my $ret = process_expression $name, $val;
689 my ($config, $current_test_num) = @_;
692 open($in, $config) || die "can't read file $config";
695 $name =~ s,.*/(.*),$1,;
697 my $test_num = $$current_test_num;
700 my $num_tests_set = 0;
713 # ignore blank lines and comments
714 next if (/^\s*$/ || /\s*\#/);
716 if (/^\s*(TEST_START|DEFAULTS)\b(.*)/) {
726 if ($type eq "TEST_START") {
728 if ($num_tests_set) {
729 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
732 $old_test_num = $test_num;
733 $old_repeat = $repeat;
735 $test_num += $repeat;
742 # If SKIP is anywhere in the line, the command will be skipped
743 if ($rest =~ s/\s+SKIP\b//) {
750 if ($rest =~ s/\sELSE\b//) {
752 die "$name: $.: ELSE found with out matching IF section\n$_";
763 if ($rest =~ s/\sIF\s+(.*)//) {
764 if (process_if($name, $1)) {
776 if ($type eq "TEST_START") {
777 if ($rest =~ s/\s+ITERATE\s+(\d+)//) {
779 $repeat_tests{"$test_num"} = $repeat;
781 } elsif ($rest =~ s/\sOVERRIDE\b//) {
784 # Clear previous overrides
789 if (!$skip && $rest !~ /^\s*$/) {
790 die "$name: $.: Gargbage found after $type\n$_";
793 if ($skip && $type eq "TEST_START") {
794 $test_num = $old_test_num;
795 $repeat = $old_repeat;
798 } elsif (/^\s*ELSE\b(.*)$/) {
800 die "$name: $.: ELSE found with out matching IF section\n$_";
809 if ($rest =~ /\sIF\s+(.*)/) {
810 # May be a ELSE IF section.
811 if (!process_if($name, $1)) {
820 if ($rest !~ /^\s*$/) {
821 die "$name: $.: Gargbage found after DEFAULTS\n$_";
824 } elsif (/^\s*INCLUDE\s+(\S+)/) {
829 die "$name: $.: INCLUDE can only be done in default sections\n$_";
832 my $file = process_variables($1);
834 if ($file !~ m,^/,) {
835 # check the path of the config file first
836 if ($config =~ m,(.*)/,) {
844 die "$name: $.: Can't read file $file\n$_";
847 if (__read_config($file, \$test_num)) {
851 } elsif (/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) {
859 ($lvalue eq "NUM_TESTS" ||
860 $lvalue eq "LOG_FILE" ||
861 $lvalue eq "CLEAR_LOG")) {
862 die "$name: $.: $lvalue must be set in DEFAULTS section\n";
865 if ($lvalue eq "NUM_TESTS") {
867 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
870 die "$name: $.: NUM_TESTS must be set in default section\n";
875 if ($default || $lvalue =~ /\[\d+\]$/) {
876 set_value($lvalue, $rvalue, $override, \%overrides, $name);
878 my $val = "$lvalue\[$test_num\]";
879 set_value($val, $rvalue, $override, \%overrides, $name);
882 $repeats{$val} = $repeat;
885 } elsif (/^\s*([A-Z_\[\]\d]+)\s*:=\s*(.*?)\s*$/) {
891 # process config variables.
892 # Config variables are only active while reading the
893 # config and can be defined anywhere. They also ignore
894 # TEST_START and DEFAULTS, but are skipped if they are in
895 # on of these sections that have SKIP defined.
896 # The save variable can be
897 # defined multiple times and the new one simply overrides
899 set_variable($lvalue, $rvalue);
902 die "$name: $.: Garbage found in config\n$_";
907 $test_num += $repeat - 1;
908 $opt{"NUM_TESTS"} = $test_num;
913 $$current_test_num = $test_num;
919 print "What test case would you like to run?\n";
920 print " (build, install or boot)\n";
921 print " Other tests are available but require editing the config file\n";
924 $default{"TEST_TYPE"} = $ans;
933 $test_case = __read_config $config, \$test_num;
935 # make sure we have all mandatory configs
938 # was a test specified?
940 print "No test case specified.\n";
946 foreach my $default (keys %default) {
947 if (!defined($opt{$default})) {
948 $opt{$default} = $default{$default};
952 if ($opt{"IGNORE_UNUSED"} == 1) {
958 # check if there are any stragglers (typos?)
959 foreach my $option (keys %opt) {
961 # remove per test labels.
963 if (!exists($option_map{$op}) &&
964 !exists($default{$op}) &&
965 !exists($used_options{$op})) {
972 $s = " is" if (keys %not_used == 1);
973 print "The following option$s not used; could be a typo:\n";
974 foreach my $option (keys %not_used) {
977 print "Set IGRNORE_UNUSED = 1 to have ktest ignore unused variables\n";
978 if (!read_yn "Do you want to continue?") {
985 my ($option, $i) = @_;
987 # Add space to evaluate the character before $
988 $option = " $option";
993 foreach my $test (keys %repeat_tests) {
995 $i < $test + $repeat_tests{$test}) {
1003 while ($option =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
1008 # Append beginning of line
1009 $retval = "$retval$start";
1011 # If the iteration option OPT[$i] exists, then use that.
1012 # otherwise see if the default OPT (without [$i]) exists.
1014 my $o = "$var\[$i\]";
1015 my $parento = "$var\[$parent\]";
1017 if (defined($opt{$o})) {
1019 $retval = "$retval$o";
1020 } elsif ($repeated && defined($opt{$parento})) {
1021 $o = $opt{$parento};
1022 $retval = "$retval$o";
1023 } elsif (defined($opt{$var})) {
1025 $retval = "$retval$o";
1027 $retval = "$retval\$\{$var\}";
1033 $retval = "$retval$option";
1041 my ($option, $i) = @_;
1045 # Since an option can evaluate to another option,
1046 # keep iterating until we do not evaluate any more
1049 while ($prev ne $option) {
1050 # Check for recursive evaluations.
1051 # 100 deep should be more than enough.
1053 die "Over 100 evaluations accurred with $option\n" .
1054 "Check for recursive variables\n";
1057 $option = __eval_option($option, $i);
1064 if (defined($opt{"LOG_FILE"})) {
1065 open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}";
1072 if (defined($opt{"LOG_FILE"})) {
1087 sub wait_for_monitor;
1092 if (defined($time)) {
1094 # flush out current monitor
1095 # May contain the reboot success line
1099 # try to reboot normally
1100 if (run_command $reboot) {
1101 if (defined($powercycle_after_reboot)) {
1102 sleep $powercycle_after_reboot;
1103 run_command "$power_cycle";
1106 # nope? power cycle it.
1107 run_command "$power_cycle";
1110 if (defined($time)) {
1111 wait_for_monitor($time, $reboot_success_line);
1116 sub reboot_to_good {
1119 if (defined($switch_to_good)) {
1120 run_command $switch_to_good;
1129 return $test_type eq "build" || $no_reboot ||
1130 ($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") ||
1131 ($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build");
1135 doprint "CRITICAL FAILURE... ", @_, "\n";
1139 if ($reboot_on_error && !do_not_reboot) {
1141 doprint "REBOOTING\n";
1144 } elsif ($poweroff_on_error && defined($power_off)) {
1145 doprint "POWERING OFF\n";
1149 if (defined($opt{"LOG_FILE"})) {
1150 print " See $opt{LOG_FILE} for more info.\n";
1161 my $pid = open($fp, "$console|") or
1162 dodie "Can't open console $console";
1164 $flags = fcntl($fp, F_GETFL, 0) or
1165 dodie "Can't get flags for the socket: $!";
1166 $flags = fcntl($fp, F_SETFL, $flags | O_NONBLOCK) or
1167 dodie "Can't set flags for the socket: $!";
1173 my ($fp, $pid) = @_;
1175 doprint "kill child process $pid\n";
1183 if ($monitor_cnt++) {
1186 $monitor_fp = \*MONFD;
1187 $monitor_pid = open_console $monitor_fp;
1191 open(MONFD, "Stop perl from warning about single use of MONFD");
1195 if (--$monitor_cnt) {
1198 close_console($monitor_fp, $monitor_pid);
1201 sub wait_for_monitor {
1202 my ($time, $stop) = @_;
1207 doprint "** Wait for monitor to settle down **\n";
1209 # read the monitor and wait for the system to calm down
1211 $line = wait_for_input($monitor_fp, $time);
1212 last if (!defined($line));
1214 $full_line .= $line;
1216 if (defined($stop) && $full_line =~ /$stop/) {
1217 doprint "wait for monitor detected $stop\n";
1221 if ($line =~ /\n/) {
1225 print "** Monitor flushed **\n";
1229 my ($result, $basedir) = @_;
1231 my $date = sprintf "%04d%02d%02d%02d%02d%02d",
1232 1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0];
1234 my $type = $build_type;
1235 if ($type =~ /useconfig/) {
1236 $type = "useconfig";
1239 my $dir = "$machine-$test_type-$type-$result-$date";
1241 $dir = "$basedir/$dir";
1245 die "can't create $dir";
1249 "config" => $output_config,
1250 "buildlog" => $buildlog,
1252 "testlog" => $testlog,
1255 while (my ($name, $source) = each(%files)) {
1257 cp "$source", "$dir/$name" or
1258 die "failed to copy $source";
1262 doprint "*** Saved info to $dir ***\n";
1267 if ($die_on_failure) {
1275 # no need to reboot for just building.
1276 if (!do_not_reboot) {
1277 doprint "REBOOTING\n";
1278 reboot_to_good $sleep_time;
1283 if (defined($test_name)) {
1284 $name = " ($test_name)";
1287 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1288 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1289 doprint "KTEST RESULT: TEST $i$name Failed: ", @_, "\n";
1290 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1291 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1293 if (defined($store_failures)) {
1294 save_logs "fail", $store_failures;
1306 $command =~ s/\$SSH_USER/$ssh_user/g;
1307 $command =~ s/\$MACHINE/$machine/g;
1309 doprint("$command ... ");
1311 $pid = open(CMD, "$command 2>&1 |") or
1312 (fail "unable to exec $command" and return 0);
1314 if (defined($opt{"LOG_FILE"})) {
1315 open(LOG, ">>$opt{LOG_FILE}") or
1316 dodie "failed to write to log";
1320 if (defined($redirect)) {
1321 open (RD, ">$redirect") or
1322 dodie "failed to write to redirect $redirect";
1327 print LOG if ($dolog);
1328 print RD if ($dord);
1335 close(LOG) if ($dolog);
1336 close(RD) if ($dord);
1339 doprint "FAILED!\n";
1341 doprint "SUCCESS\n";
1349 my $cp_exec = $ssh_exec;
1351 $cp_exec =~ s/\$SSH_COMMAND/$cmd/g;
1352 return run_command "$cp_exec";
1356 my ($src, $dst, $cp_scp) = @_;
1358 $cp_scp =~ s/\$SRC_FILE/$src/g;
1359 $cp_scp =~ s/\$DST_FILE/$dst/g;
1361 return run_command "$cp_scp";
1364 sub run_scp_install {
1365 my ($src, $dst) = @_;
1367 my $cp_scp = $scp_to_target_install;
1369 return run_scp($src, $dst, $cp_scp);
1373 my ($src, $dst) = @_;
1375 my $cp_scp = $scp_to_target;
1377 return run_scp($src, $dst, $cp_scp);
1380 sub get_grub_index {
1382 if ($reboot_type ne "grub") {
1385 return if (defined($grub_number));
1387 doprint "Find grub menu ... ";
1390 my $ssh_grub = $ssh_exec;
1391 $ssh_grub =~ s,\$SSH_COMMAND,cat /boot/grub/menu.lst,g;
1393 open(IN, "$ssh_grub |")
1394 or die "unable to get menu.lst";
1399 if (/^\s*title\s+$grub_menu\s*$/) {
1403 } elsif (/^\s*title\s/) {
1409 die "Could not find '$grub_menu' in /boot/grub/menu on $machine"
1411 doprint "$grub_number\n";
1416 my ($fp, $time) = @_;
1422 if (!defined($time)) {
1427 vec($rin, fileno($fp), 1) = 1;
1428 $ready = select($rin, undef, undef, $time);
1432 # try to read one char at a time
1433 while (sysread $fp, $ch, 1) {
1435 last if ($ch eq "\n");
1438 if (!length($line)) {
1446 if (defined($switch_to_test)) {
1447 run_command $switch_to_test;
1450 if ($reboot_type eq "grub") {
1451 run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch)'";
1452 } elsif (defined $reboot_script) {
1453 run_command "$reboot_script";
1461 doprint "git rev-list --max-count=1 $commit ... ";
1462 my $sha1 = `git rev-list --max-count=1 $commit`;
1469 dodie "Failed to get git $commit";
1482 my $bug_ignored = 0;
1483 my $skip_call_trace = 0;
1491 open(DMESG, "> $dmesg") or
1492 die "unable to write to $dmesg";
1498 my $monitor_start = time;
1500 my $version_found = 0;
1504 if ($bug && defined($stop_after_failure) &&
1505 $stop_after_failure >= 0) {
1506 my $time = $stop_after_failure - (time - $failure_start);
1507 $line = wait_for_input($monitor_fp, $time);
1508 if (!defined($line)) {
1509 doprint "bug timed out after $booted_timeout seconds\n";
1510 doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
1514 $line = wait_for_input($monitor_fp, $booted_timeout);
1515 if (!defined($line)) {
1516 my $s = $booted_timeout == 1 ? "" : "s";
1517 doprint "Successful boot found: break after $booted_timeout second$s\n";
1521 $line = wait_for_input($monitor_fp);
1522 if (!defined($line)) {
1523 my $s = $timeout == 1 ? "" : "s";
1524 doprint "Timed out after $timeout second$s\n";
1532 # we are not guaranteed to get a full line
1533 $full_line .= $line;
1535 if ($full_line =~ /$success_line/) {
1537 $success_start = time;
1540 if ($booted && defined($stop_after_success) &&
1541 $stop_after_success >= 0) {
1543 if ($now - $success_start >= $stop_after_success) {
1544 doprint "Test forced to stop after $stop_after_success seconds after success\n";
1549 if ($full_line =~ /\[ backtrace testing \]/) {
1550 $skip_call_trace = 1;
1553 if ($full_line =~ /call trace:/i) {
1554 if (!$bug && !$skip_call_trace) {
1555 if ($ignore_errors) {
1559 $failure_start = time;
1564 if ($bug && defined($stop_after_failure) &&
1565 $stop_after_failure >= 0) {
1567 if ($now - $failure_start >= $stop_after_failure) {
1568 doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
1573 if ($full_line =~ /\[ end of backtrace testing \]/) {
1574 $skip_call_trace = 0;
1577 if ($full_line =~ /Kernel panic -/) {
1578 $failure_start = time;
1582 # Detect triple faults by testing the banner
1583 if ($full_line =~ /\bLinux version (\S+).*\n/) {
1584 if ($1 eq $version) {
1586 } elsif ($version_found && $detect_triplefault) {
1587 # We already booted into the kernel we are testing,
1588 # but now we booted into another kernel?
1589 # Consider this a triple fault.
1590 doprint "Aleady booted in Linux kernel $version, but now\n";
1591 doprint "we booted into Linux kernel $1.\n";
1592 doprint "Assuming that this is a triple fault.\n";
1593 doprint "To disable this: set DETECT_TRIPLE_FAULT to 0\n";
1598 if ($line =~ /\n/) {
1602 if ($stop_test_after > 0 && !$booted && !$bug) {
1603 if (time - $monitor_start > $stop_test_after) {
1604 doprint "STOP_TEST_AFTER ($stop_test_after seconds) timed out\n";
1613 return 0 if ($in_bisect);
1614 fail "failed - got a bug report" and return 0;
1618 return 0 if ($in_bisect);
1619 fail "failed - never got a boot prompt." and return 0;
1623 doprint "WARNING: Call Trace detected but ignored due to IGNORE_ERRORS=1\n";
1629 sub eval_kernel_version {
1632 $option =~ s/\$KERNEL_VERSION/$version/g;
1637 sub do_post_install {
1639 return if (!defined($post_install));
1641 my $cp_post_install = eval_kernel_version $post_install;
1642 run_command "$cp_post_install" or
1643 dodie "Failed to run post install";
1648 return if ($no_install);
1650 my $cp_target = eval_kernel_version $target_image;
1652 run_scp_install "$outputdir/$build_target", "$cp_target" or
1653 dodie "failed to copy image";
1655 my $install_mods = 0;
1657 # should we process modules?
1659 open(IN, "$output_config") or dodie("Can't read config file");
1661 if (/CONFIG_MODULES(=y)?/) {
1662 $install_mods = 1 if (defined($1));
1668 if (!$install_mods) {
1670 doprint "No modules needed\n";
1674 run_command "$make INSTALL_MOD_STRIP=1 INSTALL_MOD_PATH=$tmpdir modules_install" or
1675 dodie "Failed to install modules";
1677 my $modlib = "/lib/modules/$version";
1678 my $modtar = "ktest-mods.tar.bz2";
1680 run_ssh "rm -rf $modlib" or
1681 dodie "failed to remove old mods: $modlib";
1683 # would be nice if scp -r did not follow symbolic links
1684 run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or
1685 dodie "making tarball";
1687 run_scp_mod "$tmpdir/$modtar", "/tmp" or
1688 dodie "failed to copy modules";
1690 unlink "$tmpdir/$modtar";
1692 run_ssh "'(cd / && tar xjf /tmp/$modtar)'" or
1693 dodie "failed to tar modules";
1695 run_ssh "rm -f /tmp/$modtar";
1701 # get the release name
1702 doprint "$make kernelrelease ... ";
1703 $version = `$make kernelrelease | tail -1`;
1705 doprint "$version\n";
1708 sub start_monitor_and_boot {
1709 # Make sure the stable kernel has finished booting
1722 sub check_buildlog {
1725 my @files = `git show $patch | diffstat -l`;
1727 open(IN, "git show $patch |") or
1728 dodie "failed to show $patch";
1730 if (m,^--- a/(.*),) {
1732 $files[$#files] = $1;
1737 open(IN, $buildlog) or dodie "Can't open $buildlog";
1739 if (/^\s*(.*?):.*(warning|error)/) {
1741 foreach my $file (@files) {
1742 my $fullpath = "$builddir/$file";
1743 if ($file eq $err || $fullpath eq $err) {
1744 fail "$file built with warnings" and return 0;
1754 sub apply_min_config {
1755 my $outconfig = "$output_config.new";
1757 # Read the config file and remove anything that
1758 # is in the force_config hash (from minconfig and others)
1759 # then add the force config back.
1761 doprint "Applying minimum configurations into $output_config.new\n";
1763 open (OUT, ">$outconfig") or
1764 dodie "Can't create $outconfig";
1766 if (-f $output_config) {
1767 open (IN, $output_config) or
1768 dodie "Failed to open $output_config";
1770 if (/^(# )?(CONFIG_[^\s=]*)/) {
1771 next if (defined($force_config{$2}));
1777 foreach my $config (keys %force_config) {
1778 print OUT "$force_config{$config}\n";
1782 run_command "mv $outconfig $output_config";
1785 sub make_oldconfig {
1787 my @force_list = keys %force_config;
1789 if ($#force_list >= 0) {
1793 if (!run_command "$make oldnoconfig") {
1794 # Perhaps oldnoconfig doesn't exist in this version of the kernel
1795 # try a yes '' | oldconfig
1796 doprint "oldnoconfig failed, trying yes '' | make oldconfig\n";
1797 run_command "yes '' | $make oldconfig" or
1798 dodie "failed make config oldconfig";
1802 # read a config file and use this to force new configs.
1803 sub load_force_config {
1806 open(IN, $config) or
1807 dodie "failed to read $config";
1810 if (/^(CONFIG[^\s=]*)(\s*=.*)/) {
1811 $force_config{$1} = $_;
1812 } elsif (/^# (CONFIG_\S*) is not set/) {
1813 $force_config{$1} = $_;
1824 # Failed builds should not reboot the target
1825 my $save_no_reboot = $no_reboot;
1828 if (defined($pre_build)) {
1829 my $ret = run_command $pre_build;
1830 if (!$ret && defined($pre_build_die) &&
1832 dodie "failed to pre_build\n";
1836 if ($type =~ /^useconfig:(.*)/) {
1837 run_command "cp $1 $output_config" or
1838 dodie "could not copy $1 to .config";
1840 $type = "oldconfig";
1843 # old config can ask questions
1844 if ($type eq "oldconfig") {
1845 $type = "oldnoconfig";
1847 # allow for empty configs
1848 run_command "touch $output_config";
1851 run_command "mv $output_config $outputdir/config_temp" or
1852 dodie "moving .config";
1854 run_command "$make mrproper" or dodie "make mrproper";
1856 run_command "mv $outputdir/config_temp $output_config" or
1857 dodie "moving config_temp";
1860 } elsif (!$noclean) {
1861 unlink "$output_config";
1862 run_command "$make mrproper" or
1863 dodie "make mrproper";
1866 # add something to distinguish this build
1867 open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file");
1868 print OUT "$localversion\n";
1871 if (defined($minconfig)) {
1872 load_force_config($minconfig);
1875 if ($type ne "oldnoconfig") {
1876 run_command "$make $type" or
1877 dodie "failed make config";
1879 # Run old config regardless, to enforce min configurations
1882 $redirect = "$buildlog";
1883 my $build_ret = run_command "$make $build_options";
1886 if (defined($post_build)) {
1887 my $ret = run_command $post_build;
1888 if (!$ret && defined($post_build_die) &&
1890 dodie "failed to post_build\n";
1895 # bisect may need this to pass
1897 $no_reboot = $save_no_reboot;
1900 fail "failed build" and return 0;
1903 $no_reboot = $save_no_reboot;
1909 if (!run_ssh "halt" or defined($power_off)) {
1910 if (defined($poweroff_after_halt)) {
1911 sleep $poweroff_after_halt;
1912 run_command "$power_off";
1916 run_command "$power_off";
1927 if (defined($test_name)) {
1928 $name = " ($test_name)";
1931 doprint "\n\n*******************************************\n";
1932 doprint "*******************************************\n";
1933 doprint "KTEST RESULT: TEST $i$name SUCCESS!!!! **\n";
1934 doprint "*******************************************\n";
1935 doprint "*******************************************\n";
1937 if (defined($store_successes)) {
1938 save_logs "success", $store_successes;
1941 if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) {
1942 doprint "Reboot and wait $sleep_time seconds\n";
1943 reboot_to_good $sleep_time;
1949 doprint "Pass or fail? [p/f]";
1952 if ($ans eq "p" || $ans eq "P") {
1954 } elsif ($ans eq "f" || $ans eq "F") {
1957 print "Please answer 'P' or 'F'\n";
1962 sub child_run_test {
1965 # child should have no power
1966 $reboot_on_error = 0;
1967 $poweroff_on_error = 0;
1968 $die_on_failure = 1;
1970 $redirect = "$testlog";
1971 run_command $run_test or $failed = 1;
1979 sub child_finished {
1992 doprint "run test $run_test\n";
1996 $SIG{CHLD} = qw(child_finished);
2000 child_run_test if (!$child_pid);
2005 $line = wait_for_input($monitor_fp, 1);
2006 if (defined($line)) {
2008 # we are not guaranteed to get a full line
2009 $full_line .= $line;
2012 if ($full_line =~ /call trace:/i) {
2016 if ($full_line =~ /Kernel panic -/) {
2020 if ($line =~ /\n/) {
2024 } while (!$child_done && !$bug);
2027 my $failure_start = time;
2030 $line = wait_for_input($monitor_fp, 1);
2031 if (defined($line)) {
2035 if ($now - $failure_start >= $stop_after_failure) {
2038 } while (defined($line));
2040 doprint "Detected kernel crash!\n";
2041 # kill the child with extreme prejudice
2045 waitpid $child_pid, 0;
2048 if (!$bug && $in_bisect) {
2049 if (defined($bisect_ret_good)) {
2050 if ($child_exit == $bisect_ret_good) {
2054 if (defined($bisect_ret_skip)) {
2055 if ($child_exit == $bisect_ret_skip) {
2059 if (defined($bisect_ret_abort)) {
2060 if ($child_exit == $bisect_ret_abort) {
2061 fail "test abort" and return -2;
2064 if (defined($bisect_ret_bad)) {
2065 if ($child_exit == $bisect_ret_skip) {
2069 if (defined($bisect_ret_default)) {
2070 if ($bisect_ret_default eq "good") {
2072 } elsif ($bisect_ret_default eq "bad") {
2074 } elsif ($bisect_ret_default eq "skip") {
2076 } elsif ($bisect_ret_default eq "abort") {
2079 fail "unknown default action: $bisect_ret_default"
2085 if ($bug || $child_exit) {
2086 return 0 if $in_bisect;
2087 fail "test failed" and return 0;
2092 sub run_git_bisect {
2095 doprint "$command ... ";
2097 my $output = `$command 2>&1`;
2104 dodie "Failed to git bisect";
2107 doprint "SUCCESS\n";
2108 if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) {
2109 doprint "$1 [$2]\n";
2110 } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) {
2111 $bisect_bad_commit = $1;
2112 doprint "Found bad commit... $1\n";
2115 # we already logged it, just print it now.
2123 doprint "Reboot and sleep $bisect_sleep_time seconds\n";
2124 reboot_to_good $bisect_sleep_time;
2127 # returns 1 on success, 0 on failure, -1 on skip
2128 sub run_bisect_test {
2129 my ($type, $buildtype) = @_;
2138 build $buildtype or $failed = 1;
2140 if ($type ne "build") {
2141 if ($failed && $bisect_skip) {
2145 dodie "Failed on build" if $failed;
2148 start_monitor_and_boot or $failed = 1;
2150 if ($type ne "boot") {
2151 if ($failed && $bisect_skip) {
2157 dodie "Failed on boot" if $failed;
2159 do_run_test or $failed = 1;
2170 # reboot the box to a kernel we can ssh to
2171 if ($type ne "build") {
2181 my $buildtype = "oldconfig";
2183 # We should have a minconfig to use?
2184 if (defined($minconfig)) {
2185 $buildtype = "useconfig:$minconfig";
2188 my $ret = run_bisect_test $type, $buildtype;
2190 if ($bisect_manual) {
2191 $ret = answer_bisect;
2194 # Are we looking for where it worked, not failed?
2195 if ($reverse_bisect) {
2201 } elsif ($ret == 0) {
2203 } elsif ($bisect_skip) {
2204 doprint "HIT A BAD COMMIT ... SKIPPING\n";
2209 sub update_bisect_replay {
2210 my $tmp_log = "$tmpdir/ktest_bisect_log";
2211 run_command "git bisect log > $tmp_log" or
2212 die "can't create bisect log";
2221 die "BISECT_GOOD[$i] not defined\n" if (!defined($bisect_good));
2222 die "BISECT_BAD[$i] not defined\n" if (!defined($bisect_bad));
2223 die "BISECT_TYPE[$i] not defined\n" if (!defined($bisect_type));
2225 my $good = $bisect_good;
2226 my $bad = $bisect_bad;
2227 my $type = $bisect_type;
2228 my $start = $bisect_start;
2229 my $replay = $bisect_replay;
2230 my $start_files = $bisect_files;
2232 if (defined($start_files)) {
2233 $start_files = " -- " . $start_files;
2238 # convert to true sha1's
2239 $good = get_sha1($good);
2240 $bad = get_sha1($bad);
2242 if (defined($bisect_reverse) && $bisect_reverse == 1) {
2243 doprint "Performing a reverse bisect (bad is good, good is bad!)\n";
2244 $reverse_bisect = 1;
2246 $reverse_bisect = 0;
2249 # Can't have a test without having a test to run
2250 if ($type eq "test" && !defined($run_test)) {
2254 # Check if a bisect was running
2255 my $bisect_start_file = "$builddir/.git/BISECT_START";
2257 my $check = $bisect_check;
2258 my $do_check = defined($check) && $check ne "0";
2260 if ( -f $bisect_start_file ) {
2261 print "Bisect in progress found\n";
2263 print " If you say yes, then no checks of good or bad will be done\n";
2265 if (defined($replay)) {
2266 print "** BISECT_REPLAY is defined in config file **";
2267 print " Ignore config option and perform new git bisect log?\n";
2268 if (read_ync " (yes, no, or cancel) ") {
2269 $replay = update_bisect_replay;
2272 } elsif (read_yn "read git log and continue?") {
2273 $replay = update_bisect_replay;
2281 my $head = get_sha1("HEAD");
2283 if ($check ne "good") {
2284 doprint "TESTING BISECT BAD [$bad]\n";
2285 run_command "git checkout $bad" or
2286 die "Failed to checkout $bad";
2288 $result = run_bisect $type;
2290 if ($result ne "bad") {
2291 fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0;
2295 if ($check ne "bad") {
2296 doprint "TESTING BISECT GOOD [$good]\n";
2297 run_command "git checkout $good" or
2298 die "Failed to checkout $good";
2300 $result = run_bisect $type;
2302 if ($result ne "good") {
2303 fail "Tested BISECT_GOOD [$good] and it failed" and return 0;
2307 # checkout where we started
2308 run_command "git checkout $head" or
2309 die "Failed to checkout $head";
2312 run_command "git bisect start$start_files" or
2313 dodie "could not start bisect";
2315 run_command "git bisect good $good" or
2316 dodie "could not set bisect good to $good";
2318 run_git_bisect "git bisect bad $bad" or
2319 dodie "could not set bisect bad to $bad";
2321 if (defined($replay)) {
2322 run_command "git bisect replay $replay" or
2323 dodie "failed to run replay";
2326 if (defined($start)) {
2327 run_command "git checkout $start" or
2328 dodie "failed to checkout $start";
2333 $result = run_bisect $type;
2334 $test = run_git_bisect "git bisect $result";
2337 run_command "git bisect log" or
2338 dodie "could not capture git bisect log";
2340 run_command "git bisect reset" or
2341 dodie "could not reset git bisect";
2343 doprint "Bad commit was [$bisect_bad_commit]\n";
2356 sub assign_configs {
2357 my ($hash, $config) = @_;
2360 or dodie "Failed to read $config";
2363 if (/^((CONFIG\S*)=.*)/) {
2371 sub process_config_ignore {
2374 assign_configs \%config_ignore, $config;
2377 sub read_current_config {
2378 my ($config_ref) = @_;
2380 %{$config_ref} = ();
2381 undef %{$config_ref};
2383 my @key = keys %{$config_ref};
2385 print "did not delete!\n";
2388 open (IN, "$output_config");
2391 if (/^(CONFIG\S+)=(.*)/) {
2392 ${$config_ref}{$1} = $2;
2398 sub get_dependencies {
2401 my $arr = $dependency{$config};
2402 if (!defined($arr)) {
2408 foreach my $dep (@{$arr}) {
2409 print "ADD DEP $dep\n";
2410 @deps = (@deps, get_dependencies $dep);
2419 open(OUT, ">$output_config") or dodie "Can not write to $output_config";
2421 foreach my $config (@configs) {
2422 print OUT "$config_set{$config}\n";
2423 my @deps = get_dependencies $config;
2424 foreach my $dep (@deps) {
2425 print OUT "$config_set{$dep}\n";
2429 foreach my $config (keys %config_ignore) {
2430 print OUT "$config_ignore{$config}\n";
2438 sub compare_configs {
2441 foreach my $item (keys %a) {
2442 if (!defined($b{$item})) {
2443 print "diff $item\n";
2451 print "diff2 $keys[0]\n";
2453 return -1 if ($#keys >= 0);
2458 sub run_config_bisect_test {
2461 return run_bisect_test $type, "oldconfig";
2464 sub process_passed {
2467 doprint "These configs had no failure: (Enabling them for further compiles)\n";
2468 # Passed! All these configs are part of a good compile.
2469 # Add them to the min options.
2470 foreach my $config (keys %configs) {
2471 if (defined($config_list{$config})) {
2472 doprint " removing $config\n";
2473 $config_ignore{$config} = $config_list{$config};
2474 delete $config_list{$config};
2477 doprint "config copied to $outputdir/config_good\n";
2478 run_command "cp -f $output_config $outputdir/config_good";
2481 sub process_failed {
2484 doprint "\n\n***************************************\n";
2485 doprint "Found bad config: $config\n";
2486 doprint "***************************************\n\n";
2489 sub run_config_bisect {
2491 my @start_list = keys %config_list;
2493 if ($#start_list < 0) {
2494 doprint "No more configs to test!!!\n";
2498 doprint "***** RUN TEST ***\n";
2499 my $type = $config_bisect_type;
2503 my $count = $#start_list + 1;
2504 doprint " $count configs to test\n";
2506 my $half = int($#start_list / 2);
2509 my @tophalf = @start_list[0 .. $half];
2511 create_config @tophalf;
2512 read_current_config \%current_config;
2514 $count = $#tophalf + 1;
2515 doprint "Testing $count configs\n";
2517 # make sure we test something
2518 foreach my $config (@tophalf) {
2519 if (defined($current_config{$config})) {
2525 # try the other half
2526 doprint "Top half produced no set configs, trying bottom half\n";
2527 @tophalf = @start_list[$half + 1 .. $#start_list];
2528 create_config @tophalf;
2529 read_current_config \%current_config;
2530 foreach my $config (@tophalf) {
2531 if (defined($current_config{$config})) {
2537 doprint "Failed: Can't make new config with current configs\n";
2538 foreach my $config (@start_list) {
2539 doprint " CONFIG: $config\n";
2543 $count = $#tophalf + 1;
2544 doprint "Testing $count configs\n";
2547 $ret = run_config_bisect_test $type;
2548 if ($bisect_manual) {
2549 $ret = answer_bisect;
2552 process_passed %current_config;
2556 doprint "This config had a failure.\n";
2557 doprint "Removing these configs that were not set in this config:\n";
2558 doprint "config copied to $outputdir/config_bad\n";
2559 run_command "cp -f $output_config $outputdir/config_bad";
2561 # A config exists in this group that was bad.
2562 foreach my $config (keys %config_list) {
2563 if (!defined($current_config{$config})) {
2564 doprint " removing $config\n";
2565 delete $config_list{$config};
2569 @start_list = @tophalf;
2571 if ($#start_list == 0) {
2572 process_failed $start_list[0];
2576 # remove half the configs we are looking at and see if
2578 $half = int($#start_list / 2);
2579 } while ($#start_list > 0);
2581 # we found a single config, try it again unless we are running manually
2583 if ($bisect_manual) {
2584 process_failed $start_list[0];
2588 my @tophalf = @start_list[0 .. 0];
2590 $ret = run_config_bisect_test $type;
2592 process_passed %current_config;
2596 process_failed $start_list[0];
2603 my $start_config = $config_bisect;
2605 my $tmpconfig = "$tmpdir/use_config";
2607 if (defined($config_bisect_good)) {
2608 process_config_ignore $config_bisect_good;
2611 # Make the file with the bad config and the min config
2612 if (defined($minconfig)) {
2613 # read the min config for things to ignore
2614 run_command "cp $minconfig $tmpconfig" or
2615 dodie "failed to copy $minconfig to $tmpconfig";
2620 if (-f $tmpconfig) {
2621 load_force_config($tmpconfig);
2622 process_config_ignore $tmpconfig;
2625 # now process the start config
2626 run_command "cp $start_config $output_config" or
2627 dodie "failed to copy $start_config to $output_config";
2629 # read directly what we want to check
2631 open (IN, $output_config)
2632 or dodie "failed to open $output_config";
2635 if (/^((CONFIG\S*)=.*)/) {
2636 $config_check{$2} = $1;
2641 # Now run oldconfig with the minconfig
2644 # check to see what we lost (or gained)
2645 open (IN, $output_config)
2646 or dodie "Failed to read $start_config";
2648 my %removed_configs;
2652 if (/^((CONFIG\S*)=.*)/) {
2653 # save off all options
2654 $config_set{$2} = $1;
2655 if (defined($config_check{$2})) {
2656 if (defined($config_ignore{$2})) {
2657 $removed_configs{$2} = $1;
2659 $config_list{$2} = $1;
2661 } elsif (!defined($config_ignore{$2})) {
2662 $added_configs{$2} = $1;
2663 $config_list{$2} = $1;
2669 my @confs = keys %removed_configs;
2671 doprint "Configs overridden by default configs and removed from check:\n";
2672 foreach my $config (@confs) {
2673 doprint " $config\n";
2676 @confs = keys %added_configs;
2678 doprint "Configs appearing in make oldconfig and added:\n";
2679 foreach my $config (@confs) {
2680 doprint " $config\n";
2687 # Sometimes kconfig does weird things. We must make sure
2688 # that the config we autocreate has everything we need
2689 # to test, otherwise we may miss testing configs, or
2690 # may not be able to create a new config.
2691 # Here we create a config with everything set.
2692 create_config (keys %config_list);
2693 read_current_config \%config_test;
2694 foreach my $config (keys %config_list) {
2695 if (!defined($config_test{$config})) {
2698 doprint "Configs not produced by kconfig (will not be checked):\n";
2700 doprint " $config\n";
2701 delete $config_list{$config};
2706 $ret = run_config_bisect;
2709 return $ret if ($ret < 0);
2714 sub patchcheck_reboot {
2715 doprint "Reboot and sleep $patchcheck_sleep_time seconds\n";
2716 reboot_to_good $patchcheck_sleep_time;
2722 die "PATCHCHECK_START[$i] not defined\n"
2723 if (!defined($patchcheck_start));
2724 die "PATCHCHECK_TYPE[$i] not defined\n"
2725 if (!defined($patchcheck_type));
2727 my $start = $patchcheck_start;
2730 if (defined($patchcheck_end)) {
2731 $end = $patchcheck_end;
2734 # Get the true sha1's since we can use things like HEAD~3
2735 $start = get_sha1($start);
2736 $end = get_sha1($end);
2738 my $type = $patchcheck_type;
2740 # Can't have a test without having a test to run
2741 if ($type eq "test" && !defined($run_test)) {
2745 open (IN, "git log --pretty=oneline $end|") or
2746 dodie "could not get git list";
2752 $list[$#list+1] = $_;
2753 last if (/^$start/);
2757 if ($list[$#list] !~ /^$start/) {
2758 fail "SHA1 $start not found";
2761 # go backwards in the list
2762 @list = reverse @list;
2764 my $save_clean = $noclean;
2765 my %ignored_warnings;
2767 if (defined($ignore_warnings)) {
2768 foreach my $sha1 (split /\s+/, $ignore_warnings) {
2769 $ignored_warnings{$sha1} = 1;
2774 foreach my $item (@list) {
2776 $sha1 =~ s/^([[:xdigit:]]+).*/$1/;
2778 doprint "\nProcessing commit $item\n\n";
2780 run_command "git checkout $sha1" or
2781 die "Failed to checkout $sha1";
2783 # only clean on the first and last patch
2784 if ($item eq $list[0] ||
2785 $item eq $list[$#list]) {
2786 $noclean = $save_clean;
2791 if (defined($minconfig)) {
2792 build "useconfig:$minconfig" or return 0;
2794 # ?? no config to use?
2795 build "oldconfig" or return 0;
2799 if (!defined($ignored_warnings{$sha1})) {
2800 check_buildlog $sha1 or return 0;
2803 next if ($type eq "build");
2807 start_monitor_and_boot or $failed = 1;
2809 if (!$failed && $type ne "boot"){
2810 do_run_test or $failed = 1;
2813 return 0 if ($failed);
2833 # $config depends on $dep
2834 my ($config, $dep) = @_;
2836 if (defined($depends{$config})) {
2837 $depends{$config} .= " " . $dep;
2839 $depends{$config} = $dep;
2842 # record the number of configs depending on $dep
2843 if (defined $depcount{$dep}) {
2846 $depcount{$dep} = 1;
2850 # taken from streamline_config.pl
2862 if (! -f $kconfig) {
2863 doprint "file $kconfig does not exist, skipping\n";
2867 open(KIN, "$kconfig")
2868 or die "Can't open $kconfig";
2872 # Make sure that lines ending with \ continue
2874 $_ = $line . " " . $_;
2885 # collect any Kconfig sources
2886 if (/^source\s*"(.*)"/) {
2887 $kconfigs[$#kconfigs+1] = $1;
2891 if (/^\s*(menu)?config\s+(\S+)\s*$/) {
2895 for (my $i = 0; $i < $iflevel; $i++) {
2896 add_dep $config, $ifdeps[$i];
2899 # collect the depends for the config
2900 } elsif ($state eq "NEW" && /^\s*depends\s+on\s+(.*)$/) {
2902 add_dep $config, $1;
2904 # Get the configs that select this config
2905 } elsif ($state eq "NEW" && /^\s*select\s+(\S+)/) {
2907 # selected by depends on config
2908 add_dep $1, $config;
2910 # Check for if statements
2911 } elsif (/^if\s+(.*\S)\s*$/) {
2913 # remove beginning and ending non text
2914 $deps =~ s/^[^a-zA-Z0-9_]*//;
2915 $deps =~ s/[^a-zA-Z0-9_]*$//;
2917 my @deps = split /[^a-zA-Z0-9_]+/, $deps;
2919 $ifdeps[$iflevel++] = join ':', @deps;
2921 } elsif (/^endif/) {
2923 $iflevel-- if ($iflevel);
2926 } elsif (/^\s*help\s*$/) {
2932 # read in any configs that were found.
2933 foreach $kconfig (@kconfigs) {
2934 if (!defined($read_kconfigs{$kconfig})) {
2935 $read_kconfigs{$kconfig} = 1;
2936 read_kconfig("$builddir/$kconfig");
2942 # find out which arch this is by the kconfig file
2943 open (IN, $output_config)
2944 or dodie "Failed to read $output_config";
2947 if (m,Linux/(\S+)\s+\S+\s+Kernel Configuration,) {
2954 if (!defined($arch)) {
2955 doprint "Could not find arch from config file\n";
2956 doprint "no dependencies used\n";
2960 # arch is really the subarch, we need to know
2961 # what directory to look at.
2962 if ($arch eq "i386" || $arch eq "x86_64") {
2964 } elsif ($arch =~ /^tile/) {
2968 my $kconfig = "$builddir/arch/$arch/Kconfig";
2970 if (! -f $kconfig && $arch =~ /\d$/) {
2972 # some subarchs have numbers, truncate them
2974 $kconfig = "$builddir/arch/$arch/Kconfig";
2975 if (! -f $kconfig) {
2976 doprint "No idea what arch dir $orig is for\n";
2977 doprint "no dependencies used\n";
2982 read_kconfig($kconfig);
2985 sub read_config_list {
2989 or dodie "Failed to read $config";
2992 if (/^((CONFIG\S*)=.*)/) {
2993 if (!defined($config_ignore{$2})) {
2994 $config_list{$2} = $1;
3002 sub read_output_config {
3005 assign_configs \%config_ignore, $config;
3008 sub make_new_config {
3011 open (OUT, ">$output_config")
3012 or dodie "Failed to write $output_config";
3014 foreach my $config (@configs) {
3015 print OUT "$config\n";
3023 $config =~ s/CONFIG_//;
3031 my $kconfig = chomp_config $dep;
3033 $dep = $depends{"$kconfig"};
3035 # the dep string we have saves the dependencies as they
3036 # were found, including expressions like ! && ||. We
3037 # want to split this out into just an array of configs.
3039 my $valid = "A-Za-z_0-9";
3043 while ($dep =~ /[$valid]/) {
3045 if ($dep =~ /^[^$valid]*([$valid]+)/) {
3046 my $conf = "CONFIG_" . $1;
3048 $configs[$#configs + 1] = $conf;
3050 $dep =~ s/^[^$valid]*[$valid]+//;
3052 die "this should never happen";
3062 my %processed_configs;
3063 my %nochange_config;
3065 sub test_this_config {
3070 # if we already processed this config, skip it
3071 if (defined($processed_configs{$config})) {
3074 $processed_configs{$config} = 1;
3076 # if this config failed during this round, skip it
3077 if (defined($nochange_config{$config})) {
3081 my $kconfig = chomp_config $config;
3083 # Test dependencies first
3084 if (defined($depends{"$kconfig"})) {
3085 my @parents = get_depends $config;
3086 foreach my $parent (@parents) {
3087 # if the parent is in the min config, check it first
3088 next if (!defined($min_configs{$parent}));
3089 $found = test_this_config($parent);
3090 if (defined($found)) {
3096 # Remove this config from the list of configs
3097 # do a make oldnoconfig and then read the resulting
3098 # .config to make sure it is missing the config that
3100 my %configs = %min_configs;
3101 delete $configs{$config};
3102 make_new_config ((values %configs), (values %keep_configs));
3105 assign_configs \%configs, $output_config;
3107 return $config if (!defined($configs{$config}));
3109 doprint "disabling config $config did not change .config\n";
3111 $nochange_config{$config} = 1;
3116 sub make_min_config {
3119 if (!defined($output_minconfig)) {
3120 fail "OUTPUT_MIN_CONFIG not defined" and return;
3123 # If output_minconfig exists, and the start_minconfig
3124 # came from min_config, than ask if we should use
3126 if (-f $output_minconfig && !$start_minconfig_defined) {
3127 print "$output_minconfig exists\n";
3128 if (read_yn " Use it as minconfig?") {
3129 $start_minconfig = $output_minconfig;
3133 if (!defined($start_minconfig)) {
3134 fail "START_MIN_CONFIG or MIN_CONFIG not defined" and return;
3137 my $temp_config = "$tmpdir/temp_config";
3139 # First things first. We build an allnoconfig to find
3140 # out what the defaults are that we can't touch.
3141 # Some are selections, but we really can't handle selections.
3143 my $save_minconfig = $minconfig;
3146 run_command "$make allnoconfig" or return 0;
3150 process_config_ignore $output_config;
3152 undef %save_configs;
3155 if (defined($ignore_config)) {
3156 # make sure the file exists
3157 `touch $ignore_config`;
3158 assign_configs \%save_configs, $ignore_config;
3161 %keep_configs = %save_configs;
3163 doprint "Load initial configs from $start_minconfig\n";
3165 # Look at the current min configs, and save off all the
3166 # ones that were set via the allnoconfig
3167 assign_configs \%min_configs, $start_minconfig;
3169 my @config_keys = keys %min_configs;
3171 # All configs need a depcount
3172 foreach my $config (@config_keys) {
3173 my $kconfig = chomp_config $config;
3174 if (!defined $depcount{$kconfig}) {
3175 $depcount{$kconfig} = 0;
3179 # Remove anything that was set by the make allnoconfig
3180 # we shouldn't need them as they get set for us anyway.
3181 foreach my $config (@config_keys) {
3182 # Remove anything in the ignore_config
3183 if (defined($keep_configs{$config})) {
3184 my $file = $ignore_config;
3185 $file =~ s,.*/(.*?)$,$1,;
3186 doprint "$config set by $file ... ignored\n";
3187 delete $min_configs{$config};
3190 # But make sure the settings are the same. If a min config
3191 # sets a selection, we do not want to get rid of it if
3192 # it is not the same as what we have. Just move it into
3194 if (defined($config_ignore{$config})) {
3195 if ($config_ignore{$config} ne $min_configs{$config}) {
3196 doprint "$config is in allnoconfig as '$config_ignore{$config}'";
3197 doprint " but it is '$min_configs{$config}' in minconfig .. keeping\n";
3198 $keep_configs{$config} = $min_configs{$config};
3200 doprint "$config set by allnoconfig ... ignored\n";
3202 delete $min_configs{$config};
3214 # Now disable each config one by one and do a make oldconfig
3215 # till we find a config that changes our list.
3217 my @test_configs = keys %min_configs;
3219 # Sort keys by who is most dependent on
3220 @test_configs = sort { $depcount{chomp_config($b)} <=> $depcount{chomp_config($a)} }
3223 # Put configs that did not modify the config at the end.
3225 for (my $i = 0; $i < $#test_configs; $i++) {
3226 if (!defined($nochange_config{$test_configs[0]})) {
3230 # This config didn't change the .config last time.
3231 # Place it at the end
3232 my $config = shift @test_configs;
3233 push @test_configs, $config;
3236 # if every test config has failed to modify the .config file
3237 # in the past, then reset and start over.
3239 undef %nochange_config;
3242 undef %processed_configs;
3244 foreach my $config (@test_configs) {
3246 $found = test_this_config $config;
3248 last if (defined($found));
3250 # oh well, try another config
3253 if (!defined($found)) {
3254 # we could have failed due to the nochange_config hash
3255 # reset and try again
3257 undef %nochange_config;
3261 doprint "No more configs found that we can disable\n";
3269 doprint "Test with $config disabled\n";
3271 # set in_bisect to keep build and monitor from dieing
3275 build "oldconfig" or $failed = 1;
3277 start_monitor_and_boot or $failed = 1;
3284 doprint "$min_configs{$config} is needed to boot the box... keeping\n";
3285 # this config is needed, add it to the ignore list.
3286 $keep_configs{$config} = $min_configs{$config};
3287 $save_configs{$config} = $min_configs{$config};
3288 delete $min_configs{$config};
3290 # update new ignore configs
3291 if (defined($ignore_config)) {
3292 open (OUT, ">$temp_config")
3293 or die "Can't write to $temp_config";
3294 foreach my $config (keys %save_configs) {
3295 print OUT "$save_configs{$config}\n";
3298 run_command "mv $temp_config $ignore_config" or
3299 dodie "failed to copy update to $ignore_config";
3303 # We booted without this config, remove it from the minconfigs.
3304 doprint "$config is not needed, disabling\n";
3306 delete $min_configs{$config};
3308 # Also disable anything that is not enabled in this config
3310 assign_configs \%configs, $output_config;
3311 my @config_keys = keys %min_configs;
3312 foreach my $config (@config_keys) {
3313 if (!defined($configs{$config})) {
3314 doprint "$config is not set, disabling\n";
3315 delete $min_configs{$config};
3319 # Save off all the current mandidory configs
3320 open (OUT, ">$temp_config")
3321 or die "Can't write to $temp_config";
3322 foreach my $config (keys %keep_configs) {
3323 print OUT "$keep_configs{$config}\n";
3325 foreach my $config (keys %min_configs) {
3326 print OUT "$min_configs{$config}\n";
3330 run_command "mv $temp_config $output_minconfig" or
3331 dodie "failed to copy update to $output_minconfig";
3334 doprint "Reboot and wait $sleep_time seconds\n";
3335 reboot_to_good $sleep_time;
3342 $#ARGV < 1 or die "ktest.pl version: $VERSION\n usage: ktest.pl config-file\n";
3345 $ktest_config = $ARGV[0];
3346 if (! -f $ktest_config) {
3347 print "$ktest_config does not exist.\n";
3348 if (!read_yn "Create it?") {
3353 $ktest_config = "ktest.conf";
3356 if (! -f $ktest_config) {
3359 open(OUT, ">$ktest_config") or die "Can not create $ktest_config";
3361 # Generated by ktest.pl
3364 # PWD is a ktest.pl variable that will result in the process working
3365 # directory that ktest.pl is executed in.
3367 # THIS_DIR is automatically assigned the PWD of the path that generated
3368 # the config file. It is best to use this variable when assigning other
3369 # directory paths within this directory. This allows you to easily
3370 # move the test cases to other locations or to other machines.
3372 THIS_DIR := $variable{"PWD"}
3374 # Define each test with TEST_START
3375 # The config options below it will override the defaults
3377 TEST_TYPE = $default{"TEST_TYPE"}
3384 read_config $ktest_config;
3386 if (defined($opt{"LOG_FILE"})) {
3387 $opt{"LOG_FILE"} = eval_option($opt{"LOG_FILE"}, -1);
3390 # Append any configs entered in manually to the config file.
3391 my @new_configs = keys %entered_configs;
3392 if ($#new_configs >= 0) {
3393 print "\nAppending entered in configs to $ktest_config\n";
3394 open(OUT, ">>$ktest_config") or die "Can not append to $ktest_config";
3395 foreach my $config (@new_configs) {
3396 print OUT "$config = $entered_configs{$config}\n";
3397 $opt{$config} = process_variables($entered_configs{$config});
3401 if ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) {
3402 unlink $opt{"LOG_FILE"};
3405 doprint "\n\nSTARTING AUTOMATED TESTS\n\n";
3407 for (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) {
3410 doprint "DEFAULT OPTIONS:\n";
3412 doprint "\nTEST $i OPTIONS";
3413 if (defined($repeat_tests{$i})) {
3414 $repeat = $repeat_tests{$i};
3415 doprint " ITERATE $repeat";
3420 foreach my $option (sort keys %opt) {
3422 if ($option =~ /\[(\d+)\]$/) {
3428 doprint "$option = $opt{$option}\n";
3432 sub __set_test_option {
3433 my ($name, $i) = @_;
3435 my $option = "$name\[$i\]";
3437 if (defined($opt{$option})) {
3438 return $opt{$option};
3441 foreach my $test (keys %repeat_tests) {
3443 $i < $test + $repeat_tests{$test}) {
3444 $option = "$name\[$test\]";
3445 if (defined($opt{$option})) {
3446 return $opt{$option};
3451 if (defined($opt{$name})) {
3458 sub set_test_option {
3459 my ($name, $i) = @_;
3461 my $option = __set_test_option($name, $i);
3462 return $option if (!defined($option));
3464 return eval_option($option, $i);
3467 # First we need to do is the builds
3468 for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
3470 # Do not reboot on failing test options
3475 my $makecmd = set_test_option("MAKE_CMD", $i);
3477 # Load all the options into their mapped variable names
3478 foreach my $opt (keys %option_map) {
3479 ${$option_map{$opt}} = set_test_option($opt, $i);
3482 $start_minconfig_defined = 1;
3484 if (!defined($start_minconfig)) {
3485 $start_minconfig_defined = 0;
3486 $start_minconfig = $minconfig;
3489 chdir $builddir || die "can't change directory to $builddir";
3491 foreach my $dir ($tmpdir, $outputdir) {
3494 die "can't create $dir";
3498 $ENV{"SSH_USER"} = $ssh_user;
3499 $ENV{"MACHINE"} = $machine;
3501 $buildlog = "$tmpdir/buildlog-$machine";
3502 $testlog = "$tmpdir/testlog-$machine";
3503 $dmesg = "$tmpdir/dmesg-$machine";
3504 $make = "$makecmd O=$outputdir";
3505 $output_config = "$outputdir/.config";
3508 $target = "$ssh_user\@$machine";
3509 if ($reboot_type eq "grub") {
3510 dodie "GRUB_MENU not defined" if (!defined($grub_menu));
3514 my $run_type = $build_type;
3515 if ($test_type eq "patchcheck") {
3516 $run_type = $patchcheck_type;
3517 } elsif ($test_type eq "bisect") {
3518 $run_type = $bisect_type;
3519 } elsif ($test_type eq "config_bisect") {
3520 $run_type = $config_bisect_type;
3523 if ($test_type eq "make_min_config") {
3527 # mistake in config file?
3528 if (!defined($run_type)) {
3529 $run_type = "ERROR";
3533 $installme = " no_install" if ($no_install);
3536 doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type$installme\n\n";
3542 if (defined($addconfig)) {
3543 my $min = $minconfig;
3544 if (!defined($minconfig)) {
3547 run_command "cat $addconfig $min > $tmpdir/add_config" or
3548 dodie "Failed to create temp config";
3549 $minconfig = "$tmpdir/add_config";
3552 if (defined($checkout)) {
3553 run_command "git checkout $checkout" or
3554 die "failed to checkout $checkout";
3557 # A test may opt to not reboot the box
3558 if ($reboot_on_success) {
3562 if ($test_type eq "bisect") {
3565 } elsif ($test_type eq "config_bisect") {
3568 } elsif ($test_type eq "patchcheck") {
3571 } elsif ($test_type eq "make_min_config") {
3576 if ($build_type ne "nobuild") {
3577 build $build_type or next;
3580 if ($test_type eq "install") {
3587 if ($test_type ne "build") {
3589 start_monitor_and_boot or $failed = 1;
3591 if (!$failed && $test_type ne "boot" && defined($run_test)) {
3592 do_run_test or $failed = 1;
3601 if ($opt{"POWEROFF_ON_SUCCESS"}) {
3603 } elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot) {
3605 } elsif (defined($switch_to_good)) {
3606 # still need to get to the good kernel
3607 run_command $switch_to_good;
3611 doprint "\n $successes of $opt{NUM_TESTS} tests were successful\n\n";