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 "MIN_CONFIG_TYPE" => "boot",
43 "SUCCESS_LINE" => "login:",
44 "DETECT_TRIPLE_FAULT" => 1,
46 "BOOTED_TIMEOUT" => 1,
47 "DIE_ON_FAILURE" => 1,
48 "SSH_EXEC" => "ssh \$SSH_USER\@\$MACHINE \$SSH_COMMAND",
49 "SCP_TO_TARGET" => "scp \$SRC_FILE \$SSH_USER\@\$MACHINE:\$DST_FILE",
50 "SCP_TO_TARGET_INSTALL" => "\${SCP_TO_TARGET}",
51 "REBOOT" => "ssh \$SSH_USER\@\$MACHINE reboot",
52 "STOP_AFTER_SUCCESS" => 10,
53 "STOP_AFTER_FAILURE" => 60,
54 "STOP_TEST_AFTER" => 600,
56 # required, and we will ask users if they don't have them but we keep the default
57 # value something that is common.
58 "REBOOT_TYPE" => "grub",
59 "LOCALVERSION" => "-test",
61 "BUILD_TARGET" => "arch/x86/boot/bzImage",
62 "TARGET_IMAGE" => "/boot/vmlinuz-test",
96 my $poweroff_on_error;
97 my $reboot_on_success;
99 my $powercycle_after_reboot;
100 my $poweroff_after_halt;
103 my $scp_to_target_install;
115 my $start_minconfig_defined;
116 my $output_minconfig;
118 my $use_output_minconfig;
123 my $bisect_bad_commit = "";
127 my $config_bisect_good;
131 my $bisect_ret_abort;
132 my $bisect_ret_default;
133 my $in_patchcheck = 0;
143 my $bisect_sleep_time;
144 my $patchcheck_sleep_time;
151 my $detect_triplefault;
153 my $reboot_success_line;
155 my $stop_after_success;
156 my $stop_after_failure;
175 my $config_bisect_type;
178 my $patchcheck_start;
181 # set when a test is something other that just building or install
182 # which would require more options.
185 # set when creating a new config
193 # do not force reboots on config problems
197 my $reboot_success = 0;
200 "MACHINE" => \$machine,
201 "SSH_USER" => \$ssh_user,
202 "TMP_DIR" => \$tmpdir,
203 "OUTPUT_DIR" => \$outputdir,
204 "BUILD_DIR" => \$builddir,
205 "TEST_TYPE" => \$test_type,
206 "PRE_KTEST" => \$pre_ktest,
207 "POST_KTEST" => \$post_ktest,
208 "PRE_TEST" => \$pre_test,
209 "POST_TEST" => \$post_test,
210 "BUILD_TYPE" => \$build_type,
211 "BUILD_OPTIONS" => \$build_options,
212 "PRE_BUILD" => \$pre_build,
213 "POST_BUILD" => \$post_build,
214 "PRE_BUILD_DIE" => \$pre_build_die,
215 "POST_BUILD_DIE" => \$post_build_die,
216 "POWER_CYCLE" => \$power_cycle,
217 "REBOOT" => \$reboot,
218 "BUILD_NOCLEAN" => \$noclean,
219 "MIN_CONFIG" => \$minconfig,
220 "OUTPUT_MIN_CONFIG" => \$output_minconfig,
221 "START_MIN_CONFIG" => \$start_minconfig,
222 "MIN_CONFIG_TYPE" => \$minconfig_type,
223 "USE_OUTPUT_MIN_CONFIG" => \$use_output_minconfig,
224 "IGNORE_CONFIG" => \$ignore_config,
225 "TEST" => \$run_test,
226 "ADD_CONFIG" => \$addconfig,
227 "REBOOT_TYPE" => \$reboot_type,
228 "GRUB_MENU" => \$grub_menu,
229 "PRE_INSTALL" => \$pre_install,
230 "POST_INSTALL" => \$post_install,
231 "NO_INSTALL" => \$no_install,
232 "REBOOT_SCRIPT" => \$reboot_script,
233 "REBOOT_ON_ERROR" => \$reboot_on_error,
234 "SWITCH_TO_GOOD" => \$switch_to_good,
235 "SWITCH_TO_TEST" => \$switch_to_test,
236 "POWEROFF_ON_ERROR" => \$poweroff_on_error,
237 "REBOOT_ON_SUCCESS" => \$reboot_on_success,
238 "DIE_ON_FAILURE" => \$die_on_failure,
239 "POWER_OFF" => \$power_off,
240 "POWERCYCLE_AFTER_REBOOT" => \$powercycle_after_reboot,
241 "POWEROFF_AFTER_HALT" => \$poweroff_after_halt,
242 "SLEEP_TIME" => \$sleep_time,
243 "BISECT_SLEEP_TIME" => \$bisect_sleep_time,
244 "PATCHCHECK_SLEEP_TIME" => \$patchcheck_sleep_time,
245 "IGNORE_WARNINGS" => \$ignore_warnings,
246 "IGNORE_ERRORS" => \$ignore_errors,
247 "BISECT_MANUAL" => \$bisect_manual,
248 "BISECT_SKIP" => \$bisect_skip,
249 "CONFIG_BISECT_GOOD" => \$config_bisect_good,
250 "BISECT_RET_GOOD" => \$bisect_ret_good,
251 "BISECT_RET_BAD" => \$bisect_ret_bad,
252 "BISECT_RET_SKIP" => \$bisect_ret_skip,
253 "BISECT_RET_ABORT" => \$bisect_ret_abort,
254 "BISECT_RET_DEFAULT" => \$bisect_ret_default,
255 "STORE_FAILURES" => \$store_failures,
256 "STORE_SUCCESSES" => \$store_successes,
257 "TEST_NAME" => \$test_name,
258 "TIMEOUT" => \$timeout,
259 "BOOTED_TIMEOUT" => \$booted_timeout,
260 "CONSOLE" => \$console,
261 "DETECT_TRIPLE_FAULT" => \$detect_triplefault,
262 "SUCCESS_LINE" => \$success_line,
263 "REBOOT_SUCCESS_LINE" => \$reboot_success_line,
264 "STOP_AFTER_SUCCESS" => \$stop_after_success,
265 "STOP_AFTER_FAILURE" => \$stop_after_failure,
266 "STOP_TEST_AFTER" => \$stop_test_after,
267 "BUILD_TARGET" => \$build_target,
268 "SSH_EXEC" => \$ssh_exec,
269 "SCP_TO_TARGET" => \$scp_to_target,
270 "SCP_TO_TARGET_INSTALL" => \$scp_to_target_install,
271 "CHECKOUT" => \$checkout,
272 "TARGET_IMAGE" => \$target_image,
273 "LOCALVERSION" => \$localversion,
275 "BISECT_GOOD" => \$bisect_good,
276 "BISECT_BAD" => \$bisect_bad,
277 "BISECT_TYPE" => \$bisect_type,
278 "BISECT_START" => \$bisect_start,
279 "BISECT_REPLAY" => \$bisect_replay,
280 "BISECT_FILES" => \$bisect_files,
281 "BISECT_REVERSE" => \$bisect_reverse,
282 "BISECT_CHECK" => \$bisect_check,
284 "CONFIG_BISECT" => \$config_bisect,
285 "CONFIG_BISECT_TYPE" => \$config_bisect_type,
287 "PATCHCHECK_TYPE" => \$patchcheck_type,
288 "PATCHCHECK_START" => \$patchcheck_start,
289 "PATCHCHECK_END" => \$patchcheck_end,
292 # Options may be used by other options, record them.
295 # default variables that can be used
296 chomp ($variable{"PWD"} = `pwd`);
298 $config_help{"MACHINE"} = << "EOF"
299 The machine hostname that you will test.
300 For build only tests, it is still needed to differentiate log files.
303 $config_help{"SSH_USER"} = << "EOF"
304 The box is expected to have ssh on normal bootup, provide the user
305 (most likely root, since you need privileged operations)
308 $config_help{"BUILD_DIR"} = << "EOF"
309 The directory that contains the Linux source code (full path).
310 You can use \${PWD} that will be the path where ktest.pl is run, or use
311 \${THIS_DIR} which is assigned \${PWD} but may be changed later.
314 $config_help{"OUTPUT_DIR"} = << "EOF"
315 The directory that the objects will be built (full path).
316 (can not be same as BUILD_DIR)
317 You can use \${PWD} that will be the path where ktest.pl is run, or use
318 \${THIS_DIR} which is assigned \${PWD} but may be changed later.
321 $config_help{"BUILD_TARGET"} = << "EOF"
322 The location of the compiled file to copy to the target.
323 (relative to OUTPUT_DIR)
326 $config_help{"BUILD_OPTIONS"} = << "EOF"
327 Options to add to \"make\" when building.
331 $config_help{"TARGET_IMAGE"} = << "EOF"
332 The place to put your image on the test machine.
335 $config_help{"POWER_CYCLE"} = << "EOF"
336 A script or command to reboot the box.
338 Here is a digital loggers power switch example
339 POWER_CYCLE = wget --no-proxy -O /dev/null -q --auth-no-challenge 'http://admin:admin\@power/outlet?5=CCL'
341 Here is an example to reboot a virtual box on the current host
342 with the name "Guest".
343 POWER_CYCLE = virsh destroy Guest; sleep 5; virsh start Guest
346 $config_help{"CONSOLE"} = << "EOF"
347 The script or command that reads the console
349 If you use ttywatch server, something like the following would work.
350 CONSOLE = nc -d localhost 3001
352 For a virtual machine with guest name "Guest".
353 CONSOLE = virsh console Guest
356 $config_help{"LOCALVERSION"} = << "EOF"
357 Required version ending to differentiate the test
358 from other linux builds on the system.
361 $config_help{"REBOOT_TYPE"} = << "EOF"
362 Way to reboot the box to the test kernel.
363 Only valid options so far are "grub" and "script".
365 If you specify grub, it will assume grub version 1
366 and will search in /boot/grub/menu.lst for the title \$GRUB_MENU
367 and select that target to reboot to the kernel. If this is not
368 your setup, then specify "script" and have a command or script
369 specified in REBOOT_SCRIPT to boot to the target.
371 The entry in /boot/grub/menu.lst must be entered in manually.
372 The test will not modify that file.
375 $config_help{"GRUB_MENU"} = << "EOF"
376 The grub title name for the test kernel to boot
377 (Only mandatory if REBOOT_TYPE = grub)
379 Note, ktest.pl will not update the grub menu.lst, you need to
380 manually add an option for the test. ktest.pl will search
381 the grub menu.lst for this option to find what kernel to
384 For example, if in the /boot/grub/menu.lst the test kernel title has:
387 GRUB_MENU = Test Kernel
390 $config_help{"REBOOT_SCRIPT"} = << "EOF"
391 A script to reboot the target into the test kernel
392 (Only mandatory if REBOOT_TYPE = script)
397 my ($cancel, $prompt) = @_;
403 print "$prompt [y/n/C] ";
405 print "$prompt [Y/n] ";
409 if ($ans =~ /^\s*$/) {
416 last if ($ans =~ /^y$/i || $ans =~ /^n$/i);
418 last if ($ans =~ /^c$/i);
419 print "Please answer either 'y', 'n' or 'c'.\n";
421 print "Please answer either 'y' or 'n'.\n";
427 if ($ans !~ /^y$/i) {
436 return read_prompt 0, $prompt;
442 return read_prompt 1, $prompt;
445 sub get_ktest_config {
449 return if (defined($opt{$config}));
451 if (defined($config_help{$config})) {
453 print $config_help{$config};
458 if (defined($default{$config}) && length($default{$config})) {
459 print "\[$default{$config}\] ";
462 $ans =~ s/^\s*(.*\S)\s*$/$1/;
463 if ($ans =~ /^\s*$/) {
464 if ($default{$config}) {
465 $ans = $default{$config};
467 print "Your answer can not be blank\n";
471 $entered_configs{$config} = ${ans};
476 sub get_ktest_configs {
477 get_ktest_config("MACHINE");
478 get_ktest_config("BUILD_DIR");
479 get_ktest_config("OUTPUT_DIR");
482 get_ktest_config("BUILD_OPTIONS");
485 # options required for other than just building a kernel
487 get_ktest_config("POWER_CYCLE");
488 get_ktest_config("CONSOLE");
491 # options required for install and more
492 if ($buildonly != 1) {
493 get_ktest_config("SSH_USER");
494 get_ktest_config("BUILD_TARGET");
495 get_ktest_config("TARGET_IMAGE");
498 get_ktest_config("LOCALVERSION");
500 return if ($buildonly);
502 my $rtype = $opt{"REBOOT_TYPE"};
504 if (!defined($rtype)) {
505 if (!defined($opt{"GRUB_MENU"})) {
506 get_ktest_config("REBOOT_TYPE");
507 $rtype = $entered_configs{"REBOOT_TYPE"};
513 if ($rtype eq "grub") {
514 get_ktest_config("GRUB_MENU");
518 sub process_variables {
519 my ($value, $remove_undef) = @_;
522 # We want to check for '\', and it is just easier
523 # to check the previous characet of '$' and not need
524 # to worry if '$' is the first character. By adding
525 # a space to $value, we can just check [^\\]\$ and
526 # it will still work.
529 while ($value =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
533 # append beginning of value to retval
534 $retval = "$retval$begin";
535 if (defined($variable{$var})) {
536 $retval = "$retval$variable{$var}";
537 } elsif (defined($remove_undef) && $remove_undef) {
538 # for if statements, any variable that is not defined,
539 # we simple convert to 0
540 $retval = "${retval}0";
542 # put back the origin piece.
543 $retval = "$retval\$\{$var\}";
544 # This could be an option that is used later, save
545 # it so we don't warn if this option is not one of
547 $used_options{$var} = 1;
551 $retval = "$retval$value";
553 # remove the space added in the beginning
560 my ($lvalue, $rvalue, $override, $overrides, $name) = @_;
562 my $prvalue = process_variables($rvalue);
564 if ($buildonly && $lvalue =~ /^TEST_TYPE(\[.*\])?$/ && $prvalue ne "build") {
565 # Note if a test is something other than build, then we
566 # will need other manditory options.
567 if ($prvalue ne "install") {
570 # install still limits some manditory options.
575 if (defined($opt{$lvalue})) {
576 if (!$override || defined(${$overrides}{$lvalue})) {
579 $extra = "In the same override section!\n";
581 die "$name: $.: Option $lvalue defined more than once!\n$extra";
583 ${$overrides}{$lvalue} = $prvalue;
585 if ($rvalue =~ /^\s*$/) {
586 delete $opt{$lvalue};
588 $opt{$lvalue} = $prvalue;
593 my ($lvalue, $rvalue) = @_;
595 if ($rvalue =~ /^\s*$/) {
596 delete $variable{$lvalue};
598 $rvalue = process_variables($rvalue);
599 $variable{$lvalue} = $rvalue;
603 sub process_compare {
604 my ($lval, $cmp, $rval) = @_;
615 return $lval eq $rval;
616 } elsif ($cmp eq "!=") {
617 return $lval ne $rval;
620 my $statement = "$lval $cmp $rval";
621 my $ret = eval $statement;
623 # $@ stores error of eval
634 return defined($variable{$2}) ||
639 sub process_expression {
640 my ($name, $val) = @_;
644 while ($val =~ s/\(([^\(]*?)\)/\&\&\&\&VAL\&\&\&\&/) {
647 if (process_expression($name, $express)) {
648 $val =~ s/\&\&\&\&VAL\&\&\&\&/ 1 /;
650 $val =~ s/\&\&\&\&VAL\&\&\&\&/ 0 /;
658 while ($val =~ s/^(.*?)($OR|$AND)//) {
662 if (process_expression($name, $express)) {
673 if ($val =~ /(.*)(==|\!=|>=|<=|>|<)(.*)/) {
674 my $ret = process_compare($1, $2, $3);
676 die "$name: $.: Unable to process comparison\n";
681 if ($val =~ /^\s*(NOT\s*)?DEFINED\s+(\S+)\s*$/) {
683 return !value_defined($2);
685 return value_defined($2);
689 if ($val =~ /^\s*0\s*$/) {
691 } elsif ($val =~ /^\s*\d+\s*$/) {
695 die ("$name: $.: Undefined content $val in if statement\n");
699 my ($name, $value) = @_;
701 # Convert variables and replace undefined ones with 0
702 my $val = process_variables($value, 1);
703 my $ret = process_expression $name, $val;
709 my ($config, $current_test_num) = @_;
712 open($in, $config) || die "can't read file $config";
715 $name =~ s,.*/(.*),$1,;
717 my $test_num = $$current_test_num;
720 my $num_tests_set = 0;
733 # ignore blank lines and comments
734 next if (/^\s*$/ || /\s*\#/);
736 if (/^\s*(TEST_START|DEFAULTS)\b(.*)/) {
746 if ($type eq "TEST_START") {
748 if ($num_tests_set) {
749 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
752 $old_test_num = $test_num;
753 $old_repeat = $repeat;
755 $test_num += $repeat;
762 # If SKIP is anywhere in the line, the command will be skipped
763 if ($rest =~ s/\s+SKIP\b//) {
770 if ($rest =~ s/\sELSE\b//) {
772 die "$name: $.: ELSE found with out matching IF section\n$_";
783 if ($rest =~ s/\sIF\s+(.*)//) {
784 if (process_if($name, $1)) {
796 if ($type eq "TEST_START") {
797 if ($rest =~ s/\s+ITERATE\s+(\d+)//) {
799 $repeat_tests{"$test_num"} = $repeat;
801 } elsif ($rest =~ s/\sOVERRIDE\b//) {
804 # Clear previous overrides
809 if (!$skip && $rest !~ /^\s*$/) {
810 die "$name: $.: Gargbage found after $type\n$_";
813 if ($skip && $type eq "TEST_START") {
814 $test_num = $old_test_num;
815 $repeat = $old_repeat;
818 } elsif (/^\s*ELSE\b(.*)$/) {
820 die "$name: $.: ELSE found with out matching IF section\n$_";
829 if ($rest =~ /\sIF\s+(.*)/) {
830 # May be a ELSE IF section.
831 if (!process_if($name, $1)) {
840 if ($rest !~ /^\s*$/) {
841 die "$name: $.: Gargbage found after DEFAULTS\n$_";
844 } elsif (/^\s*INCLUDE\s+(\S+)/) {
849 die "$name: $.: INCLUDE can only be done in default sections\n$_";
852 my $file = process_variables($1);
854 if ($file !~ m,^/,) {
855 # check the path of the config file first
856 if ($config =~ m,(.*)/,) {
864 die "$name: $.: Can't read file $file\n$_";
867 if (__read_config($file, \$test_num)) {
871 } elsif (/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) {
879 ($lvalue eq "NUM_TESTS" ||
880 $lvalue eq "LOG_FILE" ||
881 $lvalue eq "CLEAR_LOG")) {
882 die "$name: $.: $lvalue must be set in DEFAULTS section\n";
885 if ($lvalue eq "NUM_TESTS") {
887 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
890 die "$name: $.: NUM_TESTS must be set in default section\n";
895 if ($default || $lvalue =~ /\[\d+\]$/) {
896 set_value($lvalue, $rvalue, $override, \%overrides, $name);
898 my $val = "$lvalue\[$test_num\]";
899 set_value($val, $rvalue, $override, \%overrides, $name);
902 $repeats{$val} = $repeat;
905 } elsif (/^\s*([A-Z_\[\]\d]+)\s*:=\s*(.*?)\s*$/) {
911 # process config variables.
912 # Config variables are only active while reading the
913 # config and can be defined anywhere. They also ignore
914 # TEST_START and DEFAULTS, but are skipped if they are in
915 # on of these sections that have SKIP defined.
916 # The save variable can be
917 # defined multiple times and the new one simply overrides
919 set_variable($lvalue, $rvalue);
922 die "$name: $.: Garbage found in config\n$_";
927 $test_num += $repeat - 1;
928 $opt{"NUM_TESTS"} = $test_num;
933 $$current_test_num = $test_num;
939 print "What test case would you like to run?\n";
940 print " (build, install or boot)\n";
941 print " Other tests are available but require editing the config file\n";
944 $default{"TEST_TYPE"} = $ans;
953 $test_case = __read_config $config, \$test_num;
955 # make sure we have all mandatory configs
958 # was a test specified?
960 print "No test case specified.\n";
966 foreach my $default (keys %default) {
967 if (!defined($opt{$default})) {
968 $opt{$default} = $default{$default};
972 if ($opt{"IGNORE_UNUSED"} == 1) {
978 # check if there are any stragglers (typos?)
979 foreach my $option (keys %opt) {
981 # remove per test labels.
983 if (!exists($option_map{$op}) &&
984 !exists($default{$op}) &&
985 !exists($used_options{$op})) {
992 $s = " is" if (keys %not_used == 1);
993 print "The following option$s not used; could be a typo:\n";
994 foreach my $option (keys %not_used) {
997 print "Set IGRNORE_UNUSED = 1 to have ktest ignore unused variables\n";
998 if (!read_yn "Do you want to continue?") {
1005 my ($option, $i) = @_;
1007 # Add space to evaluate the character before $
1008 $option = " $option";
1013 foreach my $test (keys %repeat_tests) {
1015 $i < $test + $repeat_tests{$test}) {
1023 while ($option =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
1028 # Append beginning of line
1029 $retval = "$retval$start";
1031 # If the iteration option OPT[$i] exists, then use that.
1032 # otherwise see if the default OPT (without [$i]) exists.
1034 my $o = "$var\[$i\]";
1035 my $parento = "$var\[$parent\]";
1037 if (defined($opt{$o})) {
1039 $retval = "$retval$o";
1040 } elsif ($repeated && defined($opt{$parento})) {
1041 $o = $opt{$parento};
1042 $retval = "$retval$o";
1043 } elsif (defined($opt{$var})) {
1045 $retval = "$retval$o";
1047 $retval = "$retval\$\{$var\}";
1053 $retval = "$retval$option";
1061 my ($option, $i) = @_;
1065 # Since an option can evaluate to another option,
1066 # keep iterating until we do not evaluate any more
1069 while ($prev ne $option) {
1070 # Check for recursive evaluations.
1071 # 100 deep should be more than enough.
1073 die "Over 100 evaluations accurred with $option\n" .
1074 "Check for recursive variables\n";
1077 $option = __eval_option($option, $i);
1084 if (defined($opt{"LOG_FILE"})) {
1085 open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}";
1092 if (defined($opt{"LOG_FILE"})) {
1107 sub wait_for_monitor;
1112 if (defined($time)) {
1114 # flush out current monitor
1115 # May contain the reboot success line
1119 # try to reboot normally
1120 if (run_command $reboot) {
1121 if (defined($powercycle_after_reboot)) {
1122 sleep $powercycle_after_reboot;
1123 run_command "$power_cycle";
1126 # nope? power cycle it.
1127 run_command "$power_cycle";
1130 if (defined($time)) {
1131 wait_for_monitor($time, $reboot_success_line);
1136 sub reboot_to_good {
1139 if (defined($switch_to_good)) {
1140 run_command $switch_to_good;
1149 return $test_type eq "build" || $no_reboot ||
1150 ($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") ||
1151 ($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build");
1155 doprint "CRITICAL FAILURE... ", @_, "\n";
1159 if ($reboot_on_error && !do_not_reboot) {
1161 doprint "REBOOTING\n";
1164 } elsif ($poweroff_on_error && defined($power_off)) {
1165 doprint "POWERING OFF\n";
1169 if (defined($opt{"LOG_FILE"})) {
1170 print " See $opt{LOG_FILE} for more info.\n";
1181 my $pid = open($fp, "$console|") or
1182 dodie "Can't open console $console";
1184 $flags = fcntl($fp, F_GETFL, 0) or
1185 dodie "Can't get flags for the socket: $!";
1186 $flags = fcntl($fp, F_SETFL, $flags | O_NONBLOCK) or
1187 dodie "Can't set flags for the socket: $!";
1193 my ($fp, $pid) = @_;
1195 doprint "kill child process $pid\n";
1203 if ($monitor_cnt++) {
1206 $monitor_fp = \*MONFD;
1207 $monitor_pid = open_console $monitor_fp;
1211 open(MONFD, "Stop perl from warning about single use of MONFD");
1215 if (--$monitor_cnt) {
1218 close_console($monitor_fp, $monitor_pid);
1221 sub wait_for_monitor {
1222 my ($time, $stop) = @_;
1227 doprint "** Wait for monitor to settle down **\n";
1229 # read the monitor and wait for the system to calm down
1231 $line = wait_for_input($monitor_fp, $time);
1232 last if (!defined($line));
1234 $full_line .= $line;
1236 if (defined($stop) && $full_line =~ /$stop/) {
1237 doprint "wait for monitor detected $stop\n";
1241 if ($line =~ /\n/) {
1245 print "** Monitor flushed **\n";
1249 my ($result, $basedir) = @_;
1251 my $date = sprintf "%04d%02d%02d%02d%02d%02d",
1252 1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0];
1254 my $type = $build_type;
1255 if ($type =~ /useconfig/) {
1256 $type = "useconfig";
1259 my $dir = "$machine-$test_type-$type-$result-$date";
1261 $dir = "$basedir/$dir";
1265 die "can't create $dir";
1269 "config" => $output_config,
1270 "buildlog" => $buildlog,
1272 "testlog" => $testlog,
1275 while (my ($name, $source) = each(%files)) {
1277 cp "$source", "$dir/$name" or
1278 die "failed to copy $source";
1282 doprint "*** Saved info to $dir ***\n";
1287 if (defined($post_test)) {
1288 run_command $post_test;
1291 if ($die_on_failure) {
1299 # no need to reboot for just building.
1300 if (!do_not_reboot) {
1301 doprint "REBOOTING\n";
1302 reboot_to_good $sleep_time;
1307 if (defined($test_name)) {
1308 $name = " ($test_name)";
1311 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1312 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1313 doprint "KTEST RESULT: TEST $i$name Failed: ", @_, "\n";
1314 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1315 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1317 if (defined($store_failures)) {
1318 save_logs "fail", $store_failures;
1330 $command =~ s/\$SSH_USER/$ssh_user/g;
1331 $command =~ s/\$MACHINE/$machine/g;
1333 doprint("$command ... ");
1335 $pid = open(CMD, "$command 2>&1 |") or
1336 (fail "unable to exec $command" and return 0);
1338 if (defined($opt{"LOG_FILE"})) {
1339 open(LOG, ">>$opt{LOG_FILE}") or
1340 dodie "failed to write to log";
1344 if (defined($redirect)) {
1345 open (RD, ">$redirect") or
1346 dodie "failed to write to redirect $redirect";
1351 print LOG if ($dolog);
1352 print RD if ($dord);
1359 close(LOG) if ($dolog);
1360 close(RD) if ($dord);
1363 doprint "FAILED!\n";
1365 doprint "SUCCESS\n";
1373 my $cp_exec = $ssh_exec;
1375 $cp_exec =~ s/\$SSH_COMMAND/$cmd/g;
1376 return run_command "$cp_exec";
1380 my ($src, $dst, $cp_scp) = @_;
1382 $cp_scp =~ s/\$SRC_FILE/$src/g;
1383 $cp_scp =~ s/\$DST_FILE/$dst/g;
1385 return run_command "$cp_scp";
1388 sub run_scp_install {
1389 my ($src, $dst) = @_;
1391 my $cp_scp = $scp_to_target_install;
1393 return run_scp($src, $dst, $cp_scp);
1397 my ($src, $dst) = @_;
1399 my $cp_scp = $scp_to_target;
1401 return run_scp($src, $dst, $cp_scp);
1404 sub get_grub_index {
1406 if ($reboot_type ne "grub") {
1409 return if (defined($grub_number));
1411 doprint "Find grub menu ... ";
1414 my $ssh_grub = $ssh_exec;
1415 $ssh_grub =~ s,\$SSH_COMMAND,cat /boot/grub/menu.lst,g;
1417 open(IN, "$ssh_grub |")
1418 or die "unable to get menu.lst";
1423 if (/^\s*title\s+$grub_menu\s*$/) {
1427 } elsif (/^\s*title\s/) {
1433 die "Could not find '$grub_menu' in /boot/grub/menu on $machine"
1435 doprint "$grub_number\n";
1440 my ($fp, $time) = @_;
1446 if (!defined($time)) {
1451 vec($rin, fileno($fp), 1) = 1;
1452 $ready = select($rin, undef, undef, $time);
1456 # try to read one char at a time
1457 while (sysread $fp, $ch, 1) {
1459 last if ($ch eq "\n");
1462 if (!length($line)) {
1470 if (defined($switch_to_test)) {
1471 run_command $switch_to_test;
1474 if ($reboot_type eq "grub") {
1475 run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch)'";
1476 } elsif (defined $reboot_script) {
1477 run_command "$reboot_script";
1485 doprint "git rev-list --max-count=1 $commit ... ";
1486 my $sha1 = `git rev-list --max-count=1 $commit`;
1493 dodie "Failed to get git $commit";
1506 my $bug_ignored = 0;
1507 my $skip_call_trace = 0;
1515 open(DMESG, "> $dmesg") or
1516 die "unable to write to $dmesg";
1522 my $monitor_start = time;
1524 my $version_found = 0;
1528 if ($bug && defined($stop_after_failure) &&
1529 $stop_after_failure >= 0) {
1530 my $time = $stop_after_failure - (time - $failure_start);
1531 $line = wait_for_input($monitor_fp, $time);
1532 if (!defined($line)) {
1533 doprint "bug timed out after $booted_timeout seconds\n";
1534 doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
1538 $line = wait_for_input($monitor_fp, $booted_timeout);
1539 if (!defined($line)) {
1540 my $s = $booted_timeout == 1 ? "" : "s";
1541 doprint "Successful boot found: break after $booted_timeout second$s\n";
1545 $line = wait_for_input($monitor_fp);
1546 if (!defined($line)) {
1547 my $s = $timeout == 1 ? "" : "s";
1548 doprint "Timed out after $timeout second$s\n";
1556 # we are not guaranteed to get a full line
1557 $full_line .= $line;
1559 if ($full_line =~ /$success_line/) {
1561 $success_start = time;
1564 if ($booted && defined($stop_after_success) &&
1565 $stop_after_success >= 0) {
1567 if ($now - $success_start >= $stop_after_success) {
1568 doprint "Test forced to stop after $stop_after_success seconds after success\n";
1573 if ($full_line =~ /\[ backtrace testing \]/) {
1574 $skip_call_trace = 1;
1577 if ($full_line =~ /call trace:/i) {
1578 if (!$bug && !$skip_call_trace) {
1579 if ($ignore_errors) {
1583 $failure_start = time;
1588 if ($bug && defined($stop_after_failure) &&
1589 $stop_after_failure >= 0) {
1591 if ($now - $failure_start >= $stop_after_failure) {
1592 doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
1597 if ($full_line =~ /\[ end of backtrace testing \]/) {
1598 $skip_call_trace = 0;
1601 if ($full_line =~ /Kernel panic -/) {
1602 $failure_start = time;
1606 # Detect triple faults by testing the banner
1607 if ($full_line =~ /\bLinux version (\S+).*\n/) {
1608 if ($1 eq $version) {
1610 } elsif ($version_found && $detect_triplefault) {
1611 # We already booted into the kernel we are testing,
1612 # but now we booted into another kernel?
1613 # Consider this a triple fault.
1614 doprint "Aleady booted in Linux kernel $version, but now\n";
1615 doprint "we booted into Linux kernel $1.\n";
1616 doprint "Assuming that this is a triple fault.\n";
1617 doprint "To disable this: set DETECT_TRIPLE_FAULT to 0\n";
1622 if ($line =~ /\n/) {
1626 if ($stop_test_after > 0 && !$booted && !$bug) {
1627 if (time - $monitor_start > $stop_test_after) {
1628 doprint "STOP_TEST_AFTER ($stop_test_after seconds) timed out\n";
1637 return 0 if ($in_bisect);
1638 fail "failed - got a bug report" and return 0;
1642 return 0 if ($in_bisect);
1643 fail "failed - never got a boot prompt." and return 0;
1647 doprint "WARNING: Call Trace detected but ignored due to IGNORE_ERRORS=1\n";
1653 sub eval_kernel_version {
1656 $option =~ s/\$KERNEL_VERSION/$version/g;
1661 sub do_post_install {
1663 return if (!defined($post_install));
1665 my $cp_post_install = eval_kernel_version $post_install;
1666 run_command "$cp_post_install" or
1667 dodie "Failed to run post install";
1672 return if ($no_install);
1674 if (defined($pre_install)) {
1675 my $cp_pre_install = eval_kernel_version $pre_install;
1676 run_command "$cp_pre_install" or
1677 dodie "Failed to run pre install";
1680 my $cp_target = eval_kernel_version $target_image;
1682 run_scp_install "$outputdir/$build_target", "$cp_target" or
1683 dodie "failed to copy image";
1685 my $install_mods = 0;
1687 # should we process modules?
1689 open(IN, "$output_config") or dodie("Can't read config file");
1691 if (/CONFIG_MODULES(=y)?/) {
1692 $install_mods = 1 if (defined($1));
1698 if (!$install_mods) {
1700 doprint "No modules needed\n";
1704 run_command "$make INSTALL_MOD_STRIP=1 INSTALL_MOD_PATH=$tmpdir modules_install" or
1705 dodie "Failed to install modules";
1707 my $modlib = "/lib/modules/$version";
1708 my $modtar = "ktest-mods.tar.bz2";
1710 run_ssh "rm -rf $modlib" or
1711 dodie "failed to remove old mods: $modlib";
1713 # would be nice if scp -r did not follow symbolic links
1714 run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or
1715 dodie "making tarball";
1717 run_scp_mod "$tmpdir/$modtar", "/tmp" or
1718 dodie "failed to copy modules";
1720 unlink "$tmpdir/$modtar";
1722 run_ssh "'(cd / && tar xjf /tmp/$modtar)'" or
1723 dodie "failed to tar modules";
1725 run_ssh "rm -f /tmp/$modtar";
1731 # get the release name
1732 return if ($have_version);
1733 doprint "$make kernelrelease ... ";
1734 $version = `$make kernelrelease | tail -1`;
1736 doprint "$version\n";
1740 sub start_monitor_and_boot {
1741 # Make sure the stable kernel has finished booting
1754 sub check_buildlog {
1757 my @files = `git show $patch | diffstat -l`;
1759 open(IN, "git show $patch |") or
1760 dodie "failed to show $patch";
1762 if (m,^--- a/(.*),) {
1764 $files[$#files] = $1;
1769 open(IN, $buildlog) or dodie "Can't open $buildlog";
1771 if (/^\s*(.*?):.*(warning|error)/) {
1773 foreach my $file (@files) {
1774 my $fullpath = "$builddir/$file";
1775 if ($file eq $err || $fullpath eq $err) {
1776 fail "$file built with warnings" and return 0;
1786 sub apply_min_config {
1787 my $outconfig = "$output_config.new";
1789 # Read the config file and remove anything that
1790 # is in the force_config hash (from minconfig and others)
1791 # then add the force config back.
1793 doprint "Applying minimum configurations into $output_config.new\n";
1795 open (OUT, ">$outconfig") or
1796 dodie "Can't create $outconfig";
1798 if (-f $output_config) {
1799 open (IN, $output_config) or
1800 dodie "Failed to open $output_config";
1802 if (/^(# )?(CONFIG_[^\s=]*)/) {
1803 next if (defined($force_config{$2}));
1809 foreach my $config (keys %force_config) {
1810 print OUT "$force_config{$config}\n";
1814 run_command "mv $outconfig $output_config";
1817 sub make_oldconfig {
1819 my @force_list = keys %force_config;
1821 if ($#force_list >= 0) {
1825 if (!run_command "$make oldnoconfig") {
1826 # Perhaps oldnoconfig doesn't exist in this version of the kernel
1827 # try a yes '' | oldconfig
1828 doprint "oldnoconfig failed, trying yes '' | make oldconfig\n";
1829 run_command "yes '' | $make oldconfig" or
1830 dodie "failed make config oldconfig";
1834 # read a config file and use this to force new configs.
1835 sub load_force_config {
1838 open(IN, $config) or
1839 dodie "failed to read $config";
1842 if (/^(CONFIG[^\s=]*)(\s*=.*)/) {
1843 $force_config{$1} = $_;
1844 } elsif (/^# (CONFIG_\S*) is not set/) {
1845 $force_config{$1} = $_;
1856 # Failed builds should not reboot the target
1857 my $save_no_reboot = $no_reboot;
1860 # Calculate a new version from here.
1863 if (defined($pre_build)) {
1864 my $ret = run_command $pre_build;
1865 if (!$ret && defined($pre_build_die) &&
1867 dodie "failed to pre_build\n";
1871 if ($type =~ /^useconfig:(.*)/) {
1872 run_command "cp $1 $output_config" or
1873 dodie "could not copy $1 to .config";
1875 $type = "oldconfig";
1878 # old config can ask questions
1879 if ($type eq "oldconfig") {
1880 $type = "oldnoconfig";
1882 # allow for empty configs
1883 run_command "touch $output_config";
1886 run_command "mv $output_config $outputdir/config_temp" or
1887 dodie "moving .config";
1889 run_command "$make mrproper" or dodie "make mrproper";
1891 run_command "mv $outputdir/config_temp $output_config" or
1892 dodie "moving config_temp";
1895 } elsif (!$noclean) {
1896 unlink "$output_config";
1897 run_command "$make mrproper" or
1898 dodie "make mrproper";
1901 # add something to distinguish this build
1902 open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file");
1903 print OUT "$localversion\n";
1906 if (defined($minconfig)) {
1907 load_force_config($minconfig);
1910 if ($type ne "oldnoconfig") {
1911 run_command "$make $type" or
1912 dodie "failed make config";
1914 # Run old config regardless, to enforce min configurations
1917 $redirect = "$buildlog";
1918 my $build_ret = run_command "$make $build_options";
1921 if (defined($post_build)) {
1922 # Because a post build may change the kernel version
1925 my $ret = run_command $post_build;
1926 if (!$ret && defined($post_build_die) &&
1928 dodie "failed to post_build\n";
1933 # bisect may need this to pass
1935 $no_reboot = $save_no_reboot;
1938 fail "failed build" and return 0;
1941 $no_reboot = $save_no_reboot;
1947 if (!run_ssh "halt" or defined($power_off)) {
1948 if (defined($poweroff_after_halt)) {
1949 sleep $poweroff_after_halt;
1950 run_command "$power_off";
1954 run_command "$power_off";
1961 if (defined($post_test)) {
1962 run_command $post_test;
1969 if (defined($test_name)) {
1970 $name = " ($test_name)";
1973 doprint "\n\n*******************************************\n";
1974 doprint "*******************************************\n";
1975 doprint "KTEST RESULT: TEST $i$name SUCCESS!!!! **\n";
1976 doprint "*******************************************\n";
1977 doprint "*******************************************\n";
1979 if (defined($store_successes)) {
1980 save_logs "success", $store_successes;
1983 if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) {
1984 doprint "Reboot and wait $sleep_time seconds\n";
1985 reboot_to_good $sleep_time;
1991 doprint "Pass or fail? [p/f]";
1994 if ($ans eq "p" || $ans eq "P") {
1996 } elsif ($ans eq "f" || $ans eq "F") {
1999 print "Please answer 'P' or 'F'\n";
2004 sub child_run_test {
2007 # child should have no power
2008 $reboot_on_error = 0;
2009 $poweroff_on_error = 0;
2010 $die_on_failure = 1;
2012 $redirect = "$testlog";
2013 run_command $run_test or $failed = 1;
2021 sub child_finished {
2034 doprint "run test $run_test\n";
2038 $SIG{CHLD} = qw(child_finished);
2042 child_run_test if (!$child_pid);
2047 $line = wait_for_input($monitor_fp, 1);
2048 if (defined($line)) {
2050 # we are not guaranteed to get a full line
2051 $full_line .= $line;
2054 if ($full_line =~ /call trace:/i) {
2058 if ($full_line =~ /Kernel panic -/) {
2062 if ($line =~ /\n/) {
2066 } while (!$child_done && !$bug);
2069 my $failure_start = time;
2072 $line = wait_for_input($monitor_fp, 1);
2073 if (defined($line)) {
2077 if ($now - $failure_start >= $stop_after_failure) {
2080 } while (defined($line));
2082 doprint "Detected kernel crash!\n";
2083 # kill the child with extreme prejudice
2087 waitpid $child_pid, 0;
2090 if (!$bug && $in_bisect) {
2091 if (defined($bisect_ret_good)) {
2092 if ($child_exit == $bisect_ret_good) {
2096 if (defined($bisect_ret_skip)) {
2097 if ($child_exit == $bisect_ret_skip) {
2101 if (defined($bisect_ret_abort)) {
2102 if ($child_exit == $bisect_ret_abort) {
2103 fail "test abort" and return -2;
2106 if (defined($bisect_ret_bad)) {
2107 if ($child_exit == $bisect_ret_skip) {
2111 if (defined($bisect_ret_default)) {
2112 if ($bisect_ret_default eq "good") {
2114 } elsif ($bisect_ret_default eq "bad") {
2116 } elsif ($bisect_ret_default eq "skip") {
2118 } elsif ($bisect_ret_default eq "abort") {
2121 fail "unknown default action: $bisect_ret_default"
2127 if ($bug || $child_exit) {
2128 return 0 if $in_bisect;
2129 fail "test failed" and return 0;
2134 sub run_git_bisect {
2137 doprint "$command ... ";
2139 my $output = `$command 2>&1`;
2146 dodie "Failed to git bisect";
2149 doprint "SUCCESS\n";
2150 if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) {
2151 doprint "$1 [$2]\n";
2152 } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) {
2153 $bisect_bad_commit = $1;
2154 doprint "Found bad commit... $1\n";
2157 # we already logged it, just print it now.
2165 doprint "Reboot and sleep $bisect_sleep_time seconds\n";
2166 reboot_to_good $bisect_sleep_time;
2169 # returns 1 on success, 0 on failure, -1 on skip
2170 sub run_bisect_test {
2171 my ($type, $buildtype) = @_;
2180 build $buildtype or $failed = 1;
2182 if ($type ne "build") {
2183 if ($failed && $bisect_skip) {
2187 dodie "Failed on build" if $failed;
2190 start_monitor_and_boot or $failed = 1;
2192 if ($type ne "boot") {
2193 if ($failed && $bisect_skip) {
2199 dodie "Failed on boot" if $failed;
2201 do_run_test or $failed = 1;
2212 # reboot the box to a kernel we can ssh to
2213 if ($type ne "build") {
2223 my $buildtype = "oldconfig";
2225 # We should have a minconfig to use?
2226 if (defined($minconfig)) {
2227 $buildtype = "useconfig:$minconfig";
2230 my $ret = run_bisect_test $type, $buildtype;
2232 if ($bisect_manual) {
2233 $ret = answer_bisect;
2236 # Are we looking for where it worked, not failed?
2237 if ($reverse_bisect && $ret >= 0) {
2243 } elsif ($ret == 0) {
2245 } elsif ($bisect_skip) {
2246 doprint "HIT A BAD COMMIT ... SKIPPING\n";
2251 sub update_bisect_replay {
2252 my $tmp_log = "$tmpdir/ktest_bisect_log";
2253 run_command "git bisect log > $tmp_log" or
2254 die "can't create bisect log";
2263 die "BISECT_GOOD[$i] not defined\n" if (!defined($bisect_good));
2264 die "BISECT_BAD[$i] not defined\n" if (!defined($bisect_bad));
2265 die "BISECT_TYPE[$i] not defined\n" if (!defined($bisect_type));
2267 my $good = $bisect_good;
2268 my $bad = $bisect_bad;
2269 my $type = $bisect_type;
2270 my $start = $bisect_start;
2271 my $replay = $bisect_replay;
2272 my $start_files = $bisect_files;
2274 if (defined($start_files)) {
2275 $start_files = " -- " . $start_files;
2280 # convert to true sha1's
2281 $good = get_sha1($good);
2282 $bad = get_sha1($bad);
2284 if (defined($bisect_reverse) && $bisect_reverse == 1) {
2285 doprint "Performing a reverse bisect (bad is good, good is bad!)\n";
2286 $reverse_bisect = 1;
2288 $reverse_bisect = 0;
2291 # Can't have a test without having a test to run
2292 if ($type eq "test" && !defined($run_test)) {
2296 # Check if a bisect was running
2297 my $bisect_start_file = "$builddir/.git/BISECT_START";
2299 my $check = $bisect_check;
2300 my $do_check = defined($check) && $check ne "0";
2302 if ( -f $bisect_start_file ) {
2303 print "Bisect in progress found\n";
2305 print " If you say yes, then no checks of good or bad will be done\n";
2307 if (defined($replay)) {
2308 print "** BISECT_REPLAY is defined in config file **";
2309 print " Ignore config option and perform new git bisect log?\n";
2310 if (read_ync " (yes, no, or cancel) ") {
2311 $replay = update_bisect_replay;
2314 } elsif (read_yn "read git log and continue?") {
2315 $replay = update_bisect_replay;
2323 my $head = get_sha1("HEAD");
2325 if ($check ne "good") {
2326 doprint "TESTING BISECT BAD [$bad]\n";
2327 run_command "git checkout $bad" or
2328 die "Failed to checkout $bad";
2330 $result = run_bisect $type;
2332 if ($result ne "bad") {
2333 fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0;
2337 if ($check ne "bad") {
2338 doprint "TESTING BISECT GOOD [$good]\n";
2339 run_command "git checkout $good" or
2340 die "Failed to checkout $good";
2342 $result = run_bisect $type;
2344 if ($result ne "good") {
2345 fail "Tested BISECT_GOOD [$good] and it failed" and return 0;
2349 # checkout where we started
2350 run_command "git checkout $head" or
2351 die "Failed to checkout $head";
2354 run_command "git bisect start$start_files" or
2355 dodie "could not start bisect";
2357 run_command "git bisect good $good" or
2358 dodie "could not set bisect good to $good";
2360 run_git_bisect "git bisect bad $bad" or
2361 dodie "could not set bisect bad to $bad";
2363 if (defined($replay)) {
2364 run_command "git bisect replay $replay" or
2365 dodie "failed to run replay";
2368 if (defined($start)) {
2369 run_command "git checkout $start" or
2370 dodie "failed to checkout $start";
2375 $result = run_bisect $type;
2376 $test = run_git_bisect "git bisect $result";
2379 run_command "git bisect log" or
2380 dodie "could not capture git bisect log";
2382 run_command "git bisect reset" or
2383 dodie "could not reset git bisect";
2385 doprint "Bad commit was [$bisect_bad_commit]\n";
2398 sub assign_configs {
2399 my ($hash, $config) = @_;
2402 or dodie "Failed to read $config";
2405 if (/^((CONFIG\S*)=.*)/) {
2413 sub process_config_ignore {
2416 assign_configs \%config_ignore, $config;
2419 sub read_current_config {
2420 my ($config_ref) = @_;
2422 %{$config_ref} = ();
2423 undef %{$config_ref};
2425 my @key = keys %{$config_ref};
2427 print "did not delete!\n";
2430 open (IN, "$output_config");
2433 if (/^(CONFIG\S+)=(.*)/) {
2434 ${$config_ref}{$1} = $2;
2440 sub get_dependencies {
2443 my $arr = $dependency{$config};
2444 if (!defined($arr)) {
2450 foreach my $dep (@{$arr}) {
2451 print "ADD DEP $dep\n";
2452 @deps = (@deps, get_dependencies $dep);
2461 open(OUT, ">$output_config") or dodie "Can not write to $output_config";
2463 foreach my $config (@configs) {
2464 print OUT "$config_set{$config}\n";
2465 my @deps = get_dependencies $config;
2466 foreach my $dep (@deps) {
2467 print OUT "$config_set{$dep}\n";
2471 foreach my $config (keys %config_ignore) {
2472 print OUT "$config_ignore{$config}\n";
2479 sub compare_configs {
2482 foreach my $item (keys %a) {
2483 if (!defined($b{$item})) {
2484 print "diff $item\n";
2492 print "diff2 $keys[0]\n";
2494 return -1 if ($#keys >= 0);
2499 sub run_config_bisect_test {
2502 return run_bisect_test $type, "oldconfig";
2505 sub process_passed {
2508 doprint "These configs had no failure: (Enabling them for further compiles)\n";
2509 # Passed! All these configs are part of a good compile.
2510 # Add them to the min options.
2511 foreach my $config (keys %configs) {
2512 if (defined($config_list{$config})) {
2513 doprint " removing $config\n";
2514 $config_ignore{$config} = $config_list{$config};
2515 delete $config_list{$config};
2518 doprint "config copied to $outputdir/config_good\n";
2519 run_command "cp -f $output_config $outputdir/config_good";
2522 sub process_failed {
2525 doprint "\n\n***************************************\n";
2526 doprint "Found bad config: $config\n";
2527 doprint "***************************************\n\n";
2530 sub run_config_bisect {
2532 my @start_list = keys %config_list;
2534 if ($#start_list < 0) {
2535 doprint "No more configs to test!!!\n";
2539 doprint "***** RUN TEST ***\n";
2540 my $type = $config_bisect_type;
2544 my $count = $#start_list + 1;
2545 doprint " $count configs to test\n";
2547 my $half = int($#start_list / 2);
2550 my @tophalf = @start_list[0 .. $half];
2552 create_config @tophalf;
2553 read_current_config \%current_config;
2555 $count = $#tophalf + 1;
2556 doprint "Testing $count configs\n";
2558 # make sure we test something
2559 foreach my $config (@tophalf) {
2560 if (defined($current_config{$config})) {
2566 # try the other half
2567 doprint "Top half produced no set configs, trying bottom half\n";
2568 @tophalf = @start_list[$half + 1 .. $#start_list];
2569 create_config @tophalf;
2570 read_current_config \%current_config;
2571 foreach my $config (@tophalf) {
2572 if (defined($current_config{$config})) {
2578 doprint "Failed: Can't make new config with current configs\n";
2579 foreach my $config (@start_list) {
2580 doprint " CONFIG: $config\n";
2584 $count = $#tophalf + 1;
2585 doprint "Testing $count configs\n";
2588 $ret = run_config_bisect_test $type;
2589 if ($bisect_manual) {
2590 $ret = answer_bisect;
2593 process_passed %current_config;
2597 doprint "This config had a failure.\n";
2598 doprint "Removing these configs that were not set in this config:\n";
2599 doprint "config copied to $outputdir/config_bad\n";
2600 run_command "cp -f $output_config $outputdir/config_bad";
2602 # A config exists in this group that was bad.
2603 foreach my $config (keys %config_list) {
2604 if (!defined($current_config{$config})) {
2605 doprint " removing $config\n";
2606 delete $config_list{$config};
2610 @start_list = @tophalf;
2612 if ($#start_list == 0) {
2613 process_failed $start_list[0];
2617 # remove half the configs we are looking at and see if
2619 $half = int($#start_list / 2);
2620 } while ($#start_list > 0);
2622 # we found a single config, try it again unless we are running manually
2624 if ($bisect_manual) {
2625 process_failed $start_list[0];
2629 my @tophalf = @start_list[0 .. 0];
2631 $ret = run_config_bisect_test $type;
2633 process_passed %current_config;
2637 process_failed $start_list[0];
2644 my $start_config = $config_bisect;
2646 my $tmpconfig = "$tmpdir/use_config";
2648 if (defined($config_bisect_good)) {
2649 process_config_ignore $config_bisect_good;
2652 # Make the file with the bad config and the min config
2653 if (defined($minconfig)) {
2654 # read the min config for things to ignore
2655 run_command "cp $minconfig $tmpconfig" or
2656 dodie "failed to copy $minconfig to $tmpconfig";
2661 if (-f $tmpconfig) {
2662 load_force_config($tmpconfig);
2663 process_config_ignore $tmpconfig;
2666 # now process the start config
2667 run_command "cp $start_config $output_config" or
2668 dodie "failed to copy $start_config to $output_config";
2670 # read directly what we want to check
2672 open (IN, $output_config)
2673 or dodie "failed to open $output_config";
2676 if (/^((CONFIG\S*)=.*)/) {
2677 $config_check{$2} = $1;
2682 # Now run oldconfig with the minconfig
2685 # check to see what we lost (or gained)
2686 open (IN, $output_config)
2687 or dodie "Failed to read $start_config";
2689 my %removed_configs;
2693 if (/^((CONFIG\S*)=.*)/) {
2694 # save off all options
2695 $config_set{$2} = $1;
2696 if (defined($config_check{$2})) {
2697 if (defined($config_ignore{$2})) {
2698 $removed_configs{$2} = $1;
2700 $config_list{$2} = $1;
2702 } elsif (!defined($config_ignore{$2})) {
2703 $added_configs{$2} = $1;
2704 $config_list{$2} = $1;
2710 my @confs = keys %removed_configs;
2712 doprint "Configs overridden by default configs and removed from check:\n";
2713 foreach my $config (@confs) {
2714 doprint " $config\n";
2717 @confs = keys %added_configs;
2719 doprint "Configs appearing in make oldconfig and added:\n";
2720 foreach my $config (@confs) {
2721 doprint " $config\n";
2728 # Sometimes kconfig does weird things. We must make sure
2729 # that the config we autocreate has everything we need
2730 # to test, otherwise we may miss testing configs, or
2731 # may not be able to create a new config.
2732 # Here we create a config with everything set.
2733 create_config (keys %config_list);
2734 read_current_config \%config_test;
2735 foreach my $config (keys %config_list) {
2736 if (!defined($config_test{$config})) {
2739 doprint "Configs not produced by kconfig (will not be checked):\n";
2741 doprint " $config\n";
2742 delete $config_list{$config};
2747 $ret = run_config_bisect;
2750 return $ret if ($ret < 0);
2755 sub patchcheck_reboot {
2756 doprint "Reboot and sleep $patchcheck_sleep_time seconds\n";
2757 reboot_to_good $patchcheck_sleep_time;
2763 die "PATCHCHECK_START[$i] not defined\n"
2764 if (!defined($patchcheck_start));
2765 die "PATCHCHECK_TYPE[$i] not defined\n"
2766 if (!defined($patchcheck_type));
2768 my $start = $patchcheck_start;
2771 if (defined($patchcheck_end)) {
2772 $end = $patchcheck_end;
2775 # Get the true sha1's since we can use things like HEAD~3
2776 $start = get_sha1($start);
2777 $end = get_sha1($end);
2779 my $type = $patchcheck_type;
2781 # Can't have a test without having a test to run
2782 if ($type eq "test" && !defined($run_test)) {
2786 open (IN, "git log --pretty=oneline $end|") or
2787 dodie "could not get git list";
2793 $list[$#list+1] = $_;
2794 last if (/^$start/);
2798 if ($list[$#list] !~ /^$start/) {
2799 fail "SHA1 $start not found";
2802 # go backwards in the list
2803 @list = reverse @list;
2805 my $save_clean = $noclean;
2806 my %ignored_warnings;
2808 if (defined($ignore_warnings)) {
2809 foreach my $sha1 (split /\s+/, $ignore_warnings) {
2810 $ignored_warnings{$sha1} = 1;
2815 foreach my $item (@list) {
2817 $sha1 =~ s/^([[:xdigit:]]+).*/$1/;
2819 doprint "\nProcessing commit $item\n\n";
2821 run_command "git checkout $sha1" or
2822 die "Failed to checkout $sha1";
2824 # only clean on the first and last patch
2825 if ($item eq $list[0] ||
2826 $item eq $list[$#list]) {
2827 $noclean = $save_clean;
2832 if (defined($minconfig)) {
2833 build "useconfig:$minconfig" or return 0;
2835 # ?? no config to use?
2836 build "oldconfig" or return 0;
2840 if (!defined($ignored_warnings{$sha1})) {
2841 check_buildlog $sha1 or return 0;
2844 next if ($type eq "build");
2848 start_monitor_and_boot or $failed = 1;
2850 if (!$failed && $type ne "boot"){
2851 do_run_test or $failed = 1;
2854 return 0 if ($failed);
2874 # $config depends on $dep
2875 my ($config, $dep) = @_;
2877 if (defined($depends{$config})) {
2878 $depends{$config} .= " " . $dep;
2880 $depends{$config} = $dep;
2883 # record the number of configs depending on $dep
2884 if (defined $depcount{$dep}) {
2887 $depcount{$dep} = 1;
2891 # taken from streamline_config.pl
2903 if (! -f $kconfig) {
2904 doprint "file $kconfig does not exist, skipping\n";
2908 open(KIN, "$kconfig")
2909 or die "Can't open $kconfig";
2913 # Make sure that lines ending with \ continue
2915 $_ = $line . " " . $_;
2926 # collect any Kconfig sources
2927 if (/^source\s*"(.*)"/) {
2928 $kconfigs[$#kconfigs+1] = $1;
2932 if (/^\s*(menu)?config\s+(\S+)\s*$/) {
2936 for (my $i = 0; $i < $iflevel; $i++) {
2937 add_dep $config, $ifdeps[$i];
2940 # collect the depends for the config
2941 } elsif ($state eq "NEW" && /^\s*depends\s+on\s+(.*)$/) {
2943 add_dep $config, $1;
2945 # Get the configs that select this config
2946 } elsif ($state eq "NEW" && /^\s*select\s+(\S+)/) {
2948 # selected by depends on config
2949 add_dep $1, $config;
2951 # Check for if statements
2952 } elsif (/^if\s+(.*\S)\s*$/) {
2954 # remove beginning and ending non text
2955 $deps =~ s/^[^a-zA-Z0-9_]*//;
2956 $deps =~ s/[^a-zA-Z0-9_]*$//;
2958 my @deps = split /[^a-zA-Z0-9_]+/, $deps;
2960 $ifdeps[$iflevel++] = join ':', @deps;
2962 } elsif (/^endif/) {
2964 $iflevel-- if ($iflevel);
2967 } elsif (/^\s*help\s*$/) {
2973 # read in any configs that were found.
2974 foreach $kconfig (@kconfigs) {
2975 if (!defined($read_kconfigs{$kconfig})) {
2976 $read_kconfigs{$kconfig} = 1;
2977 read_kconfig("$builddir/$kconfig");
2983 # find out which arch this is by the kconfig file
2984 open (IN, $output_config)
2985 or dodie "Failed to read $output_config";
2988 if (m,Linux/(\S+)\s+\S+\s+Kernel Configuration,) {
2995 if (!defined($arch)) {
2996 doprint "Could not find arch from config file\n";
2997 doprint "no dependencies used\n";
3001 # arch is really the subarch, we need to know
3002 # what directory to look at.
3003 if ($arch eq "i386" || $arch eq "x86_64") {
3005 } elsif ($arch =~ /^tile/) {
3009 my $kconfig = "$builddir/arch/$arch/Kconfig";
3011 if (! -f $kconfig && $arch =~ /\d$/) {
3013 # some subarchs have numbers, truncate them
3015 $kconfig = "$builddir/arch/$arch/Kconfig";
3016 if (! -f $kconfig) {
3017 doprint "No idea what arch dir $orig is for\n";
3018 doprint "no dependencies used\n";
3023 read_kconfig($kconfig);
3026 sub read_config_list {
3030 or dodie "Failed to read $config";
3033 if (/^((CONFIG\S*)=.*)/) {
3034 if (!defined($config_ignore{$2})) {
3035 $config_list{$2} = $1;
3043 sub read_output_config {
3046 assign_configs \%config_ignore, $config;
3049 sub make_new_config {
3052 open (OUT, ">$output_config")
3053 or dodie "Failed to write $output_config";
3055 foreach my $config (@configs) {
3056 print OUT "$config\n";
3064 $config =~ s/CONFIG_//;
3072 my $kconfig = chomp_config $dep;
3074 $dep = $depends{"$kconfig"};
3076 # the dep string we have saves the dependencies as they
3077 # were found, including expressions like ! && ||. We
3078 # want to split this out into just an array of configs.
3080 my $valid = "A-Za-z_0-9";
3084 while ($dep =~ /[$valid]/) {
3086 if ($dep =~ /^[^$valid]*([$valid]+)/) {
3087 my $conf = "CONFIG_" . $1;
3089 $configs[$#configs + 1] = $conf;
3091 $dep =~ s/^[^$valid]*[$valid]+//;
3093 die "this should never happen";
3103 my %processed_configs;
3104 my %nochange_config;
3106 sub test_this_config {
3111 # if we already processed this config, skip it
3112 if (defined($processed_configs{$config})) {
3115 $processed_configs{$config} = 1;
3117 # if this config failed during this round, skip it
3118 if (defined($nochange_config{$config})) {
3122 my $kconfig = chomp_config $config;
3124 # Test dependencies first
3125 if (defined($depends{"$kconfig"})) {
3126 my @parents = get_depends $config;
3127 foreach my $parent (@parents) {
3128 # if the parent is in the min config, check it first
3129 next if (!defined($min_configs{$parent}));
3130 $found = test_this_config($parent);
3131 if (defined($found)) {
3137 # Remove this config from the list of configs
3138 # do a make oldnoconfig and then read the resulting
3139 # .config to make sure it is missing the config that
3141 my %configs = %min_configs;
3142 delete $configs{$config};
3143 make_new_config ((values %configs), (values %keep_configs));
3146 assign_configs \%configs, $output_config;
3148 return $config if (!defined($configs{$config}));
3150 doprint "disabling config $config did not change .config\n";
3152 $nochange_config{$config} = 1;
3157 sub make_min_config {
3160 my $type = $minconfig_type;
3161 if ($type ne "boot" && $type ne "test") {
3162 fail "Invalid MIN_CONFIG_TYPE '$minconfig_type'\n" .
3163 " make_min_config works only with 'boot' and 'test'\n" and return;
3166 if (!defined($output_minconfig)) {
3167 fail "OUTPUT_MIN_CONFIG not defined" and return;
3170 # If output_minconfig exists, and the start_minconfig
3171 # came from min_config, than ask if we should use
3173 if (-f $output_minconfig && !$start_minconfig_defined) {
3174 print "$output_minconfig exists\n";
3175 if (!defined($use_output_minconfig)) {
3176 if (read_yn " Use it as minconfig?") {
3177 $start_minconfig = $output_minconfig;
3179 } elsif ($use_output_minconfig > 0) {
3180 doprint "Using $output_minconfig as MIN_CONFIG\n";
3181 $start_minconfig = $output_minconfig;
3183 doprint "Set to still use MIN_CONFIG as starting point\n";
3187 if (!defined($start_minconfig)) {
3188 fail "START_MIN_CONFIG or MIN_CONFIG not defined" and return;
3191 my $temp_config = "$tmpdir/temp_config";
3193 # First things first. We build an allnoconfig to find
3194 # out what the defaults are that we can't touch.
3195 # Some are selections, but we really can't handle selections.
3197 my $save_minconfig = $minconfig;
3200 run_command "$make allnoconfig" or return 0;
3204 process_config_ignore $output_config;
3206 undef %save_configs;
3209 if (defined($ignore_config)) {
3210 # make sure the file exists
3211 `touch $ignore_config`;
3212 assign_configs \%save_configs, $ignore_config;
3215 %keep_configs = %save_configs;
3217 doprint "Load initial configs from $start_minconfig\n";
3219 # Look at the current min configs, and save off all the
3220 # ones that were set via the allnoconfig
3221 assign_configs \%min_configs, $start_minconfig;
3223 my @config_keys = keys %min_configs;
3225 # All configs need a depcount
3226 foreach my $config (@config_keys) {
3227 my $kconfig = chomp_config $config;
3228 if (!defined $depcount{$kconfig}) {
3229 $depcount{$kconfig} = 0;
3233 # Remove anything that was set by the make allnoconfig
3234 # we shouldn't need them as they get set for us anyway.
3235 foreach my $config (@config_keys) {
3236 # Remove anything in the ignore_config
3237 if (defined($keep_configs{$config})) {
3238 my $file = $ignore_config;
3239 $file =~ s,.*/(.*?)$,$1,;
3240 doprint "$config set by $file ... ignored\n";
3241 delete $min_configs{$config};
3244 # But make sure the settings are the same. If a min config
3245 # sets a selection, we do not want to get rid of it if
3246 # it is not the same as what we have. Just move it into
3248 if (defined($config_ignore{$config})) {
3249 if ($config_ignore{$config} ne $min_configs{$config}) {
3250 doprint "$config is in allnoconfig as '$config_ignore{$config}'";
3251 doprint " but it is '$min_configs{$config}' in minconfig .. keeping\n";
3252 $keep_configs{$config} = $min_configs{$config};
3254 doprint "$config set by allnoconfig ... ignored\n";
3256 delete $min_configs{$config};
3268 # Now disable each config one by one and do a make oldconfig
3269 # till we find a config that changes our list.
3271 my @test_configs = keys %min_configs;
3273 # Sort keys by who is most dependent on
3274 @test_configs = sort { $depcount{chomp_config($b)} <=> $depcount{chomp_config($a)} }
3277 # Put configs that did not modify the config at the end.
3279 for (my $i = 0; $i < $#test_configs; $i++) {
3280 if (!defined($nochange_config{$test_configs[0]})) {
3284 # This config didn't change the .config last time.
3285 # Place it at the end
3286 my $config = shift @test_configs;
3287 push @test_configs, $config;
3290 # if every test config has failed to modify the .config file
3291 # in the past, then reset and start over.
3293 undef %nochange_config;
3296 undef %processed_configs;
3298 foreach my $config (@test_configs) {
3300 $found = test_this_config $config;
3302 last if (defined($found));
3304 # oh well, try another config
3307 if (!defined($found)) {
3308 # we could have failed due to the nochange_config hash
3309 # reset and try again
3311 undef %nochange_config;
3315 doprint "No more configs found that we can disable\n";
3323 doprint "Test with $config disabled\n";
3325 # set in_bisect to keep build and monitor from dieing
3329 build "oldconfig" or $failed = 1;
3331 start_monitor_and_boot or $failed = 1;
3333 if ($type eq "test" && !$failed) {
3334 do_run_test or $failed = 1;
3343 doprint "$min_configs{$config} is needed to boot the box... keeping\n";
3344 # this config is needed, add it to the ignore list.
3345 $keep_configs{$config} = $min_configs{$config};
3346 $save_configs{$config} = $min_configs{$config};
3347 delete $min_configs{$config};
3349 # update new ignore configs
3350 if (defined($ignore_config)) {
3351 open (OUT, ">$temp_config")
3352 or die "Can't write to $temp_config";
3353 foreach my $config (keys %save_configs) {
3354 print OUT "$save_configs{$config}\n";
3357 run_command "mv $temp_config $ignore_config" or
3358 dodie "failed to copy update to $ignore_config";
3362 # We booted without this config, remove it from the minconfigs.
3363 doprint "$config is not needed, disabling\n";
3365 delete $min_configs{$config};
3367 # Also disable anything that is not enabled in this config
3369 assign_configs \%configs, $output_config;
3370 my @config_keys = keys %min_configs;
3371 foreach my $config (@config_keys) {
3372 if (!defined($configs{$config})) {
3373 doprint "$config is not set, disabling\n";
3374 delete $min_configs{$config};
3378 # Save off all the current mandidory configs
3379 open (OUT, ">$temp_config")
3380 or die "Can't write to $temp_config";
3381 foreach my $config (keys %keep_configs) {
3382 print OUT "$keep_configs{$config}\n";
3384 foreach my $config (keys %min_configs) {
3385 print OUT "$min_configs{$config}\n";
3389 run_command "mv $temp_config $output_minconfig" or
3390 dodie "failed to copy update to $output_minconfig";
3393 doprint "Reboot and wait $sleep_time seconds\n";
3394 reboot_to_good $sleep_time;
3401 $#ARGV < 1 or die "ktest.pl version: $VERSION\n usage: ktest.pl config-file\n";
3404 $ktest_config = $ARGV[0];
3405 if (! -f $ktest_config) {
3406 print "$ktest_config does not exist.\n";
3407 if (!read_yn "Create it?") {
3412 $ktest_config = "ktest.conf";
3415 if (! -f $ktest_config) {
3418 open(OUT, ">$ktest_config") or die "Can not create $ktest_config";
3420 # Generated by ktest.pl
3423 # PWD is a ktest.pl variable that will result in the process working
3424 # directory that ktest.pl is executed in.
3426 # THIS_DIR is automatically assigned the PWD of the path that generated
3427 # the config file. It is best to use this variable when assigning other
3428 # directory paths within this directory. This allows you to easily
3429 # move the test cases to other locations or to other machines.
3431 THIS_DIR := $variable{"PWD"}
3433 # Define each test with TEST_START
3434 # The config options below it will override the defaults
3436 TEST_TYPE = $default{"TEST_TYPE"}
3443 read_config $ktest_config;
3445 if (defined($opt{"LOG_FILE"})) {
3446 $opt{"LOG_FILE"} = eval_option($opt{"LOG_FILE"}, -1);
3449 # Append any configs entered in manually to the config file.
3450 my @new_configs = keys %entered_configs;
3451 if ($#new_configs >= 0) {
3452 print "\nAppending entered in configs to $ktest_config\n";
3453 open(OUT, ">>$ktest_config") or die "Can not append to $ktest_config";
3454 foreach my $config (@new_configs) {
3455 print OUT "$config = $entered_configs{$config}\n";
3456 $opt{$config} = process_variables($entered_configs{$config});
3460 if ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) {
3461 unlink $opt{"LOG_FILE"};
3464 doprint "\n\nSTARTING AUTOMATED TESTS\n\n";
3466 for (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) {
3469 doprint "DEFAULT OPTIONS:\n";
3471 doprint "\nTEST $i OPTIONS";
3472 if (defined($repeat_tests{$i})) {
3473 $repeat = $repeat_tests{$i};
3474 doprint " ITERATE $repeat";
3479 foreach my $option (sort keys %opt) {
3481 if ($option =~ /\[(\d+)\]$/) {
3487 doprint "$option = $opt{$option}\n";
3491 sub __set_test_option {
3492 my ($name, $i) = @_;
3494 my $option = "$name\[$i\]";
3496 if (defined($opt{$option})) {
3497 return $opt{$option};
3500 foreach my $test (keys %repeat_tests) {
3502 $i < $test + $repeat_tests{$test}) {
3503 $option = "$name\[$test\]";
3504 if (defined($opt{$option})) {
3505 return $opt{$option};
3510 if (defined($opt{$name})) {
3517 sub set_test_option {
3518 my ($name, $i) = @_;
3520 my $option = __set_test_option($name, $i);
3521 return $option if (!defined($option));
3523 return eval_option($option, $i);
3526 # First we need to do is the builds
3527 for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
3529 # Do not reboot on failing test options
3531 $reboot_success = 0;
3537 my $makecmd = set_test_option("MAKE_CMD", $i);
3539 # Load all the options into their mapped variable names
3540 foreach my $opt (keys %option_map) {
3541 ${$option_map{$opt}} = set_test_option($opt, $i);
3544 $start_minconfig_defined = 1;
3546 # The first test may override the PRE_KTEST option
3547 if (defined($pre_ktest) && $i == 1) {
3549 run_command $pre_ktest;
3552 # Any test can override the POST_KTEST option
3553 # The last test takes precedence.
3554 if (defined($post_ktest)) {
3555 $final_post_ktest = $post_ktest;
3558 if (!defined($start_minconfig)) {
3559 $start_minconfig_defined = 0;
3560 $start_minconfig = $minconfig;
3563 chdir $builddir || die "can't change directory to $builddir";
3565 foreach my $dir ($tmpdir, $outputdir) {
3568 die "can't create $dir";
3572 $ENV{"SSH_USER"} = $ssh_user;
3573 $ENV{"MACHINE"} = $machine;
3575 $buildlog = "$tmpdir/buildlog-$machine";
3576 $testlog = "$tmpdir/testlog-$machine";
3577 $dmesg = "$tmpdir/dmesg-$machine";
3578 $make = "$makecmd O=$outputdir";
3579 $output_config = "$outputdir/.config";
3582 $target = "$ssh_user\@$machine";
3583 if ($reboot_type eq "grub") {
3584 dodie "GRUB_MENU not defined" if (!defined($grub_menu));
3588 my $run_type = $build_type;
3589 if ($test_type eq "patchcheck") {
3590 $run_type = $patchcheck_type;
3591 } elsif ($test_type eq "bisect") {
3592 $run_type = $bisect_type;
3593 } elsif ($test_type eq "config_bisect") {
3594 $run_type = $config_bisect_type;
3597 if ($test_type eq "make_min_config") {
3601 # mistake in config file?
3602 if (!defined($run_type)) {
3603 $run_type = "ERROR";
3607 $installme = " no_install" if ($no_install);
3610 doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type$installme\n\n";
3612 if (defined($pre_test)) {
3613 run_command $pre_test;
3620 if (defined($addconfig)) {
3621 my $min = $minconfig;
3622 if (!defined($minconfig)) {
3625 run_command "cat $addconfig $min > $tmpdir/add_config" or
3626 dodie "Failed to create temp config";
3627 $minconfig = "$tmpdir/add_config";
3630 if (defined($checkout)) {
3631 run_command "git checkout $checkout" or
3632 die "failed to checkout $checkout";
3637 # A test may opt to not reboot the box
3638 if ($reboot_on_success) {
3639 $reboot_success = 1;
3642 if ($test_type eq "bisect") {
3645 } elsif ($test_type eq "config_bisect") {
3648 } elsif ($test_type eq "patchcheck") {
3651 } elsif ($test_type eq "make_min_config") {
3656 if ($build_type ne "nobuild") {
3657 build $build_type or next;
3660 if ($test_type eq "install") {
3667 if ($test_type ne "build") {
3669 start_monitor_and_boot or $failed = 1;
3671 if (!$failed && $test_type ne "boot" && defined($run_test)) {
3672 do_run_test or $failed = 1;
3681 if (defined($final_post_ktest)) {
3682 run_command $final_post_ktest;
3685 if ($opt{"POWEROFF_ON_SUCCESS"}) {
3687 } elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot && $reboot_success) {
3689 } elsif (defined($switch_to_good)) {
3690 # still need to get to the good kernel
3691 run_command $switch_to_good;
3695 doprint "\n $successes of $opt{NUM_TESTS} tests were successful\n\n";