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);
24 $default{"NUM_TESTS"} = 1;
25 $default{"TEST_TYPE"} = "build";
26 $default{"BUILD_TYPE"} = "randconfig";
27 $default{"MAKE_CMD"} = "make";
28 $default{"TIMEOUT"} = 120;
29 $default{"TMP_DIR"} = "/tmp/ktest/\${MACHINE}";
30 $default{"SLEEP_TIME"} = 60; # sleep time between tests
31 $default{"BUILD_NOCLEAN"} = 0;
32 $default{"REBOOT_ON_ERROR"} = 0;
33 $default{"POWEROFF_ON_ERROR"} = 0;
34 $default{"REBOOT_ON_SUCCESS"} = 1;
35 $default{"POWEROFF_ON_SUCCESS"} = 0;
36 $default{"BUILD_OPTIONS"} = "";
37 $default{"BISECT_SLEEP_TIME"} = 60; # sleep time between bisects
38 $default{"PATCHCHECK_SLEEP_TIME"} = 60; # sleep time between patch checks
39 $default{"CLEAR_LOG"} = 0;
40 $default{"BISECT_MANUAL"} = 0;
41 $default{"BISECT_SKIP"} = 1;
42 $default{"SUCCESS_LINE"} = "login:";
43 $default{"DETECT_TRIPLE_FAULT"} = 1;
44 $default{"NO_INSTALL"} = 0;
45 $default{"BOOTED_TIMEOUT"} = 1;
46 $default{"DIE_ON_FAILURE"} = 1;
47 $default{"SSH_EXEC"} = "ssh \$SSH_USER\@\$MACHINE \$SSH_COMMAND";
48 $default{"SCP_TO_TARGET"} = "scp \$SRC_FILE \$SSH_USER\@\$MACHINE:\$DST_FILE";
49 $default{"REBOOT"} = "ssh \$SSH_USER\@\$MACHINE reboot";
50 $default{"STOP_AFTER_SUCCESS"} = 10;
51 $default{"STOP_AFTER_FAILURE"} = 60;
52 $default{"STOP_TEST_AFTER"} = 600;
54 # required, and we will ask users if they don't have them but we keep the default
55 # value something that is common.
56 $default{"REBOOT_TYPE"} = "grub";
57 $default{"LOCALVERSION"} = "-test";
58 $default{"SSH_USER"} = "root";
59 $default{"BUILD_TARGET"} = "arch/x86/boot/bzImage";
60 $default{"TARGET_IMAGE"} = "/boot/vmlinuz-test";
82 my $poweroff_on_error;
84 my $powercycle_after_reboot;
85 my $poweroff_after_halt;
98 my $start_minconfig_defined;
107 my $config_bisect_good;
108 my $in_patchcheck = 0;
118 my $bisect_sleep_time;
119 my $patchcheck_sleep_time;
126 my $detect_triplefault;
128 my $reboot_success_line;
130 my $stop_after_success;
131 my $stop_after_failure;
139 # set when a test is something other that just building or install
140 # which would require more options.
143 # set when creating a new config
151 # do not force reboots on config problems
154 # default variables that can be used
155 chomp ($variable{"PWD"} = `pwd`);
157 $config_help{"MACHINE"} = << "EOF"
158 The machine hostname that you will test.
159 For build only tests, it is still needed to differentiate log files.
162 $config_help{"SSH_USER"} = << "EOF"
163 The box is expected to have ssh on normal bootup, provide the user
164 (most likely root, since you need privileged operations)
167 $config_help{"BUILD_DIR"} = << "EOF"
168 The directory that contains the Linux source code (full path).
169 You can use \${PWD} that will be the path where ktest.pl is run, or use
170 \${THIS_DIR} which is assigned \${PWD} but may be changed later.
173 $config_help{"OUTPUT_DIR"} = << "EOF"
174 The directory that the objects will be built (full path).
175 (can not be same as BUILD_DIR)
176 You can use \${PWD} that will be the path where ktest.pl is run, or use
177 \${THIS_DIR} which is assigned \${PWD} but may be changed later.
180 $config_help{"BUILD_TARGET"} = << "EOF"
181 The location of the compiled file to copy to the target.
182 (relative to OUTPUT_DIR)
185 $config_help{"BUILD_OPTIONS"} = << "EOF"
186 Options to add to \"make\" when building.
190 $config_help{"TARGET_IMAGE"} = << "EOF"
191 The place to put your image on the test machine.
194 $config_help{"POWER_CYCLE"} = << "EOF"
195 A script or command to reboot the box.
197 Here is a digital loggers power switch example
198 POWER_CYCLE = wget --no-proxy -O /dev/null -q --auth-no-challenge 'http://admin:admin\@power/outlet?5=CCL'
200 Here is an example to reboot a virtual box on the current host
201 with the name "Guest".
202 POWER_CYCLE = virsh destroy Guest; sleep 5; virsh start Guest
205 $config_help{"CONSOLE"} = << "EOF"
206 The script or command that reads the console
208 If you use ttywatch server, something like the following would work.
209 CONSOLE = nc -d localhost 3001
211 For a virtual machine with guest name "Guest".
212 CONSOLE = virsh console Guest
215 $config_help{"LOCALVERSION"} = << "EOF"
216 Required version ending to differentiate the test
217 from other linux builds on the system.
220 $config_help{"REBOOT_TYPE"} = << "EOF"
221 Way to reboot the box to the test kernel.
222 Only valid options so far are "grub" and "script".
224 If you specify grub, it will assume grub version 1
225 and will search in /boot/grub/menu.lst for the title \$GRUB_MENU
226 and select that target to reboot to the kernel. If this is not
227 your setup, then specify "script" and have a command or script
228 specified in REBOOT_SCRIPT to boot to the target.
230 The entry in /boot/grub/menu.lst must be entered in manually.
231 The test will not modify that file.
234 $config_help{"GRUB_MENU"} = << "EOF"
235 The grub title name for the test kernel to boot
236 (Only mandatory if REBOOT_TYPE = grub)
238 Note, ktest.pl will not update the grub menu.lst, you need to
239 manually add an option for the test. ktest.pl will search
240 the grub menu.lst for this option to find what kernel to
243 For example, if in the /boot/grub/menu.lst the test kernel title has:
246 GRUB_MENU = Test Kernel
249 $config_help{"REBOOT_SCRIPT"} = << "EOF"
250 A script to reboot the target into the test kernel
251 (Only mandatory if REBOOT_TYPE = script)
256 my ($cancel, $prompt) = @_;
262 print "$prompt [y/n/C] ";
264 print "$prompt [Y/n] ";
268 if ($ans =~ /^\s*$/) {
275 last if ($ans =~ /^y$/i || $ans =~ /^n$/i);
277 last if ($ans =~ /^c$/i);
278 print "Please answer either 'y', 'n' or 'c'.\n";
280 print "Please answer either 'y' or 'n'.\n";
286 if ($ans !~ /^y$/i) {
295 return read_prompt 0, $prompt;
301 return read_prompt 1, $prompt;
304 sub get_ktest_config {
308 return if (defined($opt{$config}));
310 if (defined($config_help{$config})) {
312 print $config_help{$config};
317 if (defined($default{$config}) && length($default{$config})) {
318 print "\[$default{$config}\] ";
321 $ans =~ s/^\s*(.*\S)\s*$/$1/;
322 if ($ans =~ /^\s*$/) {
323 if ($default{$config}) {
324 $ans = $default{$config};
326 print "Your answer can not be blank\n";
330 $entered_configs{$config} = ${ans};
335 sub get_ktest_configs {
336 get_ktest_config("MACHINE");
337 get_ktest_config("BUILD_DIR");
338 get_ktest_config("OUTPUT_DIR");
341 get_ktest_config("BUILD_OPTIONS");
344 # options required for other than just building a kernel
346 get_ktest_config("POWER_CYCLE");
347 get_ktest_config("CONSOLE");
350 # options required for install and more
351 if ($buildonly != 1) {
352 get_ktest_config("SSH_USER");
353 get_ktest_config("BUILD_TARGET");
354 get_ktest_config("TARGET_IMAGE");
357 get_ktest_config("LOCALVERSION");
359 return if ($buildonly);
361 my $rtype = $opt{"REBOOT_TYPE"};
363 if (!defined($rtype)) {
364 if (!defined($opt{"GRUB_MENU"})) {
365 get_ktest_config("REBOOT_TYPE");
366 $rtype = $entered_configs{"REBOOT_TYPE"};
372 if ($rtype eq "grub") {
373 get_ktest_config("GRUB_MENU");
375 get_ktest_config("REBOOT_SCRIPT");
379 sub process_variables {
380 my ($value, $remove_undef) = @_;
383 # We want to check for '\', and it is just easier
384 # to check the previous characet of '$' and not need
385 # to worry if '$' is the first character. By adding
386 # a space to $value, we can just check [^\\]\$ and
387 # it will still work.
390 while ($value =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
394 # append beginning of value to retval
395 $retval = "$retval$begin";
396 if (defined($variable{$var})) {
397 $retval = "$retval$variable{$var}";
398 } elsif (defined($remove_undef) && $remove_undef) {
399 # for if statements, any variable that is not defined,
400 # we simple convert to 0
401 $retval = "${retval}0";
403 # put back the origin piece.
404 $retval = "$retval\$\{$var\}";
408 $retval = "$retval$value";
410 # remove the space added in the beginning
417 my ($lvalue, $rvalue, $override, $overrides, $name) = @_;
419 if ($buildonly && $lvalue =~ /^TEST_TYPE(\[.*\])?$/ && $rvalue ne "build") {
420 # Note if a test is something other than build, then we
421 # will need other manditory options.
422 if ($rvalue ne "install") {
425 # install still limits some manditory options.
430 if (defined($opt{$lvalue})) {
431 if (!$override || defined(${$overrides}{$lvalue})) {
434 $extra = "In the same override section!\n";
436 die "$name: $.: Option $lvalue defined more than once!\n$extra";
438 ${$overrides}{$lvalue} = $rvalue;
440 if ($rvalue =~ /^\s*$/) {
441 delete $opt{$lvalue};
443 $rvalue = process_variables($rvalue);
444 $opt{$lvalue} = $rvalue;
449 my ($lvalue, $rvalue) = @_;
451 if ($rvalue =~ /^\s*$/) {
452 delete $variable{$lvalue};
454 $rvalue = process_variables($rvalue);
455 $variable{$lvalue} = $rvalue;
459 sub process_compare {
460 my ($lval, $cmp, $rval) = @_;
471 return $lval eq $rval;
472 } elsif ($cmp eq "!=") {
473 return $lval ne $rval;
476 my $statement = "$lval $cmp $rval";
477 my $ret = eval $statement;
479 # $@ stores error of eval
490 return defined($variable{$2}) ||
495 sub process_expression {
496 my ($name, $val) = @_;
500 while ($val =~ s/\(([^\(]*?)\)/\&\&\&\&VAL\&\&\&\&/) {
503 if (process_expression($name, $express)) {
504 $val =~ s/\&\&\&\&VAL\&\&\&\&/ 1 /;
506 $val =~ s/\&\&\&\&VAL\&\&\&\&/ 0 /;
514 while ($val =~ s/^(.*?)($OR|$AND)//) {
518 if (process_expression($name, $express)) {
529 if ($val =~ /(.*)(==|\!=|>=|<=|>|<)(.*)/) {
530 my $ret = process_compare($1, $2, $3);
532 die "$name: $.: Unable to process comparison\n";
537 if ($val =~ /^\s*(NOT\s*)?DEFINED\s+(\S+)\s*$/) {
539 return !value_defined($2);
541 return value_defined($2);
545 if ($val =~ /^\s*0\s*$/) {
547 } elsif ($val =~ /^\s*\d+\s*$/) {
551 die ("$name: $.: Undefined content $val in if statement\n");
555 my ($name, $value) = @_;
557 # Convert variables and replace undefined ones with 0
558 my $val = process_variables($value, 1);
559 my $ret = process_expression $name, $val;
565 my ($config, $current_test_num) = @_;
568 open($in, $config) || die "can't read file $config";
571 $name =~ s,.*/(.*),$1,;
573 my $test_num = $$current_test_num;
576 my $num_tests_set = 0;
589 # ignore blank lines and comments
590 next if (/^\s*$/ || /\s*\#/);
592 if (/^\s*(TEST_START|DEFAULTS)\b(.*)/) {
602 if ($type eq "TEST_START") {
604 if ($num_tests_set) {
605 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
608 $old_test_num = $test_num;
609 $old_repeat = $repeat;
611 $test_num += $repeat;
618 # If SKIP is anywhere in the line, the command will be skipped
619 if ($rest =~ s/\s+SKIP\b//) {
626 if ($rest =~ s/\sELSE\b//) {
628 die "$name: $.: ELSE found with out matching IF section\n$_";
639 if ($rest =~ s/\sIF\s+(.*)//) {
640 if (process_if($name, $1)) {
652 if ($type eq "TEST_START") {
653 if ($rest =~ s/\s+ITERATE\s+(\d+)//) {
655 $repeat_tests{"$test_num"} = $repeat;
657 } elsif ($rest =~ s/\sOVERRIDE\b//) {
660 # Clear previous overrides
665 if (!$skip && $rest !~ /^\s*$/) {
666 die "$name: $.: Gargbage found after $type\n$_";
669 if ($skip && $type eq "TEST_START") {
670 $test_num = $old_test_num;
671 $repeat = $old_repeat;
674 } elsif (/^\s*ELSE\b(.*)$/) {
676 die "$name: $.: ELSE found with out matching IF section\n$_";
685 if ($rest =~ /\sIF\s+(.*)/) {
686 # May be a ELSE IF section.
687 if (!process_if($name, $1)) {
696 if ($rest !~ /^\s*$/) {
697 die "$name: $.: Gargbage found after DEFAULTS\n$_";
700 } elsif (/^\s*INCLUDE\s+(\S+)/) {
705 die "$name: $.: INCLUDE can only be done in default sections\n$_";
708 my $file = process_variables($1);
710 if ($file !~ m,^/,) {
711 # check the path of the config file first
712 if ($config =~ m,(.*)/,) {
720 die "$name: $.: Can't read file $file\n$_";
723 if (__read_config($file, \$test_num)) {
727 } elsif (/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) {
735 ($lvalue eq "NUM_TESTS" ||
736 $lvalue eq "LOG_FILE" ||
737 $lvalue eq "CLEAR_LOG")) {
738 die "$name: $.: $lvalue must be set in DEFAULTS section\n";
741 if ($lvalue eq "NUM_TESTS") {
743 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
746 die "$name: $.: NUM_TESTS must be set in default section\n";
751 if ($default || $lvalue =~ /\[\d+\]$/) {
752 set_value($lvalue, $rvalue, $override, \%overrides, $name);
754 my $val = "$lvalue\[$test_num\]";
755 set_value($val, $rvalue, $override, \%overrides, $name);
758 $repeats{$val} = $repeat;
761 } elsif (/^\s*([A-Z_\[\]\d]+)\s*:=\s*(.*?)\s*$/) {
767 # process config variables.
768 # Config variables are only active while reading the
769 # config and can be defined anywhere. They also ignore
770 # TEST_START and DEFAULTS, but are skipped if they are in
771 # on of these sections that have SKIP defined.
772 # The save variable can be
773 # defined multiple times and the new one simply overrides
775 set_variable($lvalue, $rvalue);
778 die "$name: $.: Garbage found in config\n$_";
783 $test_num += $repeat - 1;
784 $opt{"NUM_TESTS"} = $test_num;
789 $$current_test_num = $test_num;
795 print "What test case would you like to run?\n";
796 print " (build, install or boot)\n";
797 print " Other tests are available but require editing the config file\n";
800 $default{"TEST_TYPE"} = $ans;
809 $test_case = __read_config $config, \$test_num;
811 # make sure we have all mandatory configs
814 # was a test specified?
816 print "No test case specified.\n";
822 foreach my $default (keys %default) {
823 if (!defined($opt{$default})) {
824 $opt{$default} = $default{$default};
830 my ($option, $i) = @_;
832 # Add space to evaluate the character before $
833 $option = " $option";
838 foreach my $test (keys %repeat_tests) {
840 $i < $test + $repeat_tests{$test}) {
848 while ($option =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
853 # Append beginning of line
854 $retval = "$retval$start";
856 # If the iteration option OPT[$i] exists, then use that.
857 # otherwise see if the default OPT (without [$i]) exists.
859 my $o = "$var\[$i\]";
860 my $parento = "$var\[$parent\]";
862 if (defined($opt{$o})) {
864 $retval = "$retval$o";
865 } elsif ($repeated && defined($opt{$parento})) {
867 $retval = "$retval$o";
868 } elsif (defined($opt{$var})) {
870 $retval = "$retval$o";
872 $retval = "$retval\$\{$var\}";
878 $retval = "$retval$option";
886 my ($option, $i) = @_;
890 # Since an option can evaluate to another option,
891 # keep iterating until we do not evaluate any more
894 while ($prev ne $option) {
895 # Check for recursive evaluations.
896 # 100 deep should be more than enough.
898 die "Over 100 evaluations accurred with $option\n" .
899 "Check for recursive variables\n";
902 $option = __eval_option($option, $i);
909 if (defined($opt{"LOG_FILE"})) {
910 open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}";
917 if (defined($opt{"LOG_FILE"})) {
932 sub wait_for_monitor;
937 if (defined($time)) {
939 # flush out current monitor
940 # May contain the reboot success line
944 # try to reboot normally
945 if (run_command $reboot) {
946 if (defined($powercycle_after_reboot)) {
947 sleep $powercycle_after_reboot;
948 run_command "$power_cycle";
951 # nope? power cycle it.
952 run_command "$power_cycle";
955 if (defined($time)) {
956 wait_for_monitor($time, $reboot_success_line);
964 return $test_type eq "build" || $no_reboot ||
965 ($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") ||
966 ($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build");
970 doprint "CRITICAL FAILURE... ", @_, "\n";
974 if ($reboot_on_error && !do_not_reboot) {
976 doprint "REBOOTING\n";
979 } elsif ($poweroff_on_error && defined($power_off)) {
980 doprint "POWERING OFF\n";
984 if (defined($opt{"LOG_FILE"})) {
985 print " See $opt{LOG_FILE} for more info.\n";
996 my $pid = open($fp, "$console|") or
997 dodie "Can't open console $console";
999 $flags = fcntl($fp, F_GETFL, 0) or
1000 dodie "Can't get flags for the socket: $!";
1001 $flags = fcntl($fp, F_SETFL, $flags | O_NONBLOCK) or
1002 dodie "Can't set flags for the socket: $!";
1008 my ($fp, $pid) = @_;
1010 doprint "kill child process $pid\n";
1018 if ($monitor_cnt++) {
1021 $monitor_fp = \*MONFD;
1022 $monitor_pid = open_console $monitor_fp;
1026 open(MONFD, "Stop perl from warning about single use of MONFD");
1030 if (--$monitor_cnt) {
1033 close_console($monitor_fp, $monitor_pid);
1036 sub wait_for_monitor {
1037 my ($time, $stop) = @_;
1042 doprint "** Wait for monitor to settle down **\n";
1044 # read the monitor and wait for the system to calm down
1046 $line = wait_for_input($monitor_fp, $time);
1047 last if (!defined($line));
1049 $full_line .= $line;
1051 if (defined($stop) && $full_line =~ /$stop/) {
1052 doprint "wait for monitor detected $stop\n";
1056 if ($line =~ /\n/) {
1060 print "** Monitor flushed **\n";
1064 my ($result, $basedir) = @_;
1066 my $date = sprintf "%04d%02d%02d%02d%02d%02d",
1067 1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0];
1069 my $type = $build_type;
1070 if ($type =~ /useconfig/) {
1071 $type = "useconfig";
1074 my $dir = "$machine-$test_type-$type-$result-$date";
1076 $dir = "$basedir/$dir";
1080 die "can't create $dir";
1084 "config" => $output_config,
1085 "buildlog" => $buildlog,
1087 "testlog" => $testlog,
1090 while (my ($name, $source) = each(%files)) {
1092 cp "$source", "$dir/$name" or
1093 die "failed to copy $source";
1097 doprint "*** Saved info to $dir ***\n";
1102 if ($die_on_failure) {
1110 # no need to reboot for just building.
1111 if (!do_not_reboot) {
1112 doprint "REBOOTING\n";
1118 if (defined($test_name)) {
1119 $name = " ($test_name)";
1122 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1123 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1124 doprint "KTEST RESULT: TEST $i$name Failed: ", @_, "\n";
1125 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1126 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1128 if (defined($store_failures)) {
1129 save_logs "fail", $store_failures;
1141 $command =~ s/\$SSH_USER/$ssh_user/g;
1142 $command =~ s/\$MACHINE/$machine/g;
1144 doprint("$command ... ");
1146 $pid = open(CMD, "$command 2>&1 |") or
1147 (fail "unable to exec $command" and return 0);
1149 if (defined($opt{"LOG_FILE"})) {
1150 open(LOG, ">>$opt{LOG_FILE}") or
1151 dodie "failed to write to log";
1155 if (defined($redirect)) {
1156 open (RD, ">$redirect") or
1157 dodie "failed to write to redirect $redirect";
1162 print LOG if ($dolog);
1163 print RD if ($dord);
1170 close(LOG) if ($dolog);
1171 close(RD) if ($dord);
1174 doprint "FAILED!\n";
1176 doprint "SUCCESS\n";
1184 my $cp_exec = $ssh_exec;
1186 $cp_exec =~ s/\$SSH_COMMAND/$cmd/g;
1187 return run_command "$cp_exec";
1191 my ($src, $dst) = @_;
1192 my $cp_scp = $scp_to_target;
1194 $cp_scp =~ s/\$SRC_FILE/$src/g;
1195 $cp_scp =~ s/\$DST_FILE/$dst/g;
1197 return run_command "$cp_scp";
1200 sub get_grub_index {
1202 if ($reboot_type ne "grub") {
1205 return if (defined($grub_number));
1207 doprint "Find grub menu ... ";
1210 my $ssh_grub = $ssh_exec;
1211 $ssh_grub =~ s,\$SSH_COMMAND,cat /boot/grub/menu.lst,g;
1213 open(IN, "$ssh_grub |")
1214 or die "unable to get menu.lst";
1219 if (/^\s*title\s+$grub_menu\s*$/) {
1223 } elsif (/^\s*title\s/) {
1229 die "Could not find '$grub_menu' in /boot/grub/menu on $machine"
1231 doprint "$grub_number\n";
1236 my ($fp, $time) = @_;
1242 if (!defined($time)) {
1247 vec($rin, fileno($fp), 1) = 1;
1248 $ready = select($rin, undef, undef, $time);
1252 # try to read one char at a time
1253 while (sysread $fp, $ch, 1) {
1255 last if ($ch eq "\n");
1258 if (!length($line)) {
1266 if ($reboot_type eq "grub") {
1267 run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch)'";
1272 run_command "$reboot_script";
1278 doprint "git rev-list --max-count=1 $commit ... ";
1279 my $sha1 = `git rev-list --max-count=1 $commit`;
1286 dodie "Failed to get git $commit";
1299 my $skip_call_trace = 0;
1307 open(DMESG, "> $dmesg") or
1308 die "unable to write to $dmesg";
1314 my $monitor_start = time;
1316 my $version_found = 0;
1320 if ($bug && defined($stop_after_failure) &&
1321 $stop_after_failure >= 0) {
1322 my $time = $stop_after_failure - (time - $failure_start);
1323 $line = wait_for_input($monitor_fp, $time);
1324 if (!defined($line)) {
1325 doprint "bug timed out after $booted_timeout seconds\n";
1326 doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
1330 $line = wait_for_input($monitor_fp, $booted_timeout);
1331 if (!defined($line)) {
1332 my $s = $booted_timeout == 1 ? "" : "s";
1333 doprint "Successful boot found: break after $booted_timeout second$s\n";
1337 $line = wait_for_input($monitor_fp);
1338 if (!defined($line)) {
1339 my $s = $timeout == 1 ? "" : "s";
1340 doprint "Timed out after $timeout second$s\n";
1348 # we are not guaranteed to get a full line
1349 $full_line .= $line;
1351 if ($full_line =~ /$success_line/) {
1353 $success_start = time;
1356 if ($booted && defined($stop_after_success) &&
1357 $stop_after_success >= 0) {
1359 if ($now - $success_start >= $stop_after_success) {
1360 doprint "Test forced to stop after $stop_after_success seconds after success\n";
1365 if ($full_line =~ /\[ backtrace testing \]/) {
1366 $skip_call_trace = 1;
1369 if ($full_line =~ /call trace:/i) {
1370 if (!$bug && !$skip_call_trace) {
1372 $failure_start = time;
1376 if ($bug && defined($stop_after_failure) &&
1377 $stop_after_failure >= 0) {
1379 if ($now - $failure_start >= $stop_after_failure) {
1380 doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
1385 if ($full_line =~ /\[ end of backtrace testing \]/) {
1386 $skip_call_trace = 0;
1389 if ($full_line =~ /Kernel panic -/) {
1390 $failure_start = time;
1394 # Detect triple faults by testing the banner
1395 if ($full_line =~ /\bLinux version (\S+).*\n/) {
1396 if ($1 eq $version) {
1398 } elsif ($version_found && $detect_triplefault) {
1399 # We already booted into the kernel we are testing,
1400 # but now we booted into another kernel?
1401 # Consider this a triple fault.
1402 doprint "Aleady booted in Linux kernel $version, but now\n";
1403 doprint "we booted into Linux kernel $1.\n";
1404 doprint "Assuming that this is a triple fault.\n";
1405 doprint "To disable this: set DETECT_TRIPLE_FAULT to 0\n";
1410 if ($line =~ /\n/) {
1414 if ($stop_test_after > 0 && !$booted && !$bug) {
1415 if (time - $monitor_start > $stop_test_after) {
1416 doprint "STOP_TEST_AFTER ($stop_test_after seconds) timed out\n";
1425 return 0 if ($in_bisect);
1426 fail "failed - got a bug report" and return 0;
1430 return 0 if ($in_bisect);
1431 fail "failed - never got a boot prompt." and return 0;
1437 sub eval_kernel_version {
1440 $option =~ s/\$KERNEL_VERSION/$version/g;
1445 sub do_post_install {
1447 return if (!defined($post_install));
1449 my $cp_post_install = eval_kernel_version $post_install;
1450 run_command "$cp_post_install" or
1451 dodie "Failed to run post install";
1456 return if ($no_install);
1458 my $cp_target = eval_kernel_version $target_image;
1460 run_scp "$outputdir/$build_target", "$cp_target" or
1461 dodie "failed to copy image";
1463 my $install_mods = 0;
1465 # should we process modules?
1467 open(IN, "$output_config") or dodie("Can't read config file");
1469 if (/CONFIG_MODULES(=y)?/) {
1470 $install_mods = 1 if (defined($1));
1476 if (!$install_mods) {
1478 doprint "No modules needed\n";
1482 run_command "$make INSTALL_MOD_PATH=$tmpdir modules_install" or
1483 dodie "Failed to install modules";
1485 my $modlib = "/lib/modules/$version";
1486 my $modtar = "ktest-mods.tar.bz2";
1488 run_ssh "rm -rf $modlib" or
1489 dodie "failed to remove old mods: $modlib";
1491 # would be nice if scp -r did not follow symbolic links
1492 run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or
1493 dodie "making tarball";
1495 run_scp "$tmpdir/$modtar", "/tmp" or
1496 dodie "failed to copy modules";
1498 unlink "$tmpdir/$modtar";
1500 run_ssh "'(cd / && tar xjf /tmp/$modtar)'" or
1501 dodie "failed to tar modules";
1503 run_ssh "rm -f /tmp/$modtar";
1509 # get the release name
1510 doprint "$make kernelrelease ... ";
1511 $version = `$make kernelrelease | tail -1`;
1513 doprint "$version\n";
1516 sub start_monitor_and_boot {
1517 # Make sure the stable kernel has finished booting
1530 sub check_buildlog {
1533 my @files = `git show $patch | diffstat -l`;
1535 open(IN, "git show $patch |") or
1536 dodie "failed to show $patch";
1538 if (m,^--- a/(.*),) {
1540 $files[$#files] = $1;
1545 open(IN, $buildlog) or dodie "Can't open $buildlog";
1547 if (/^\s*(.*?):.*(warning|error)/) {
1549 foreach my $file (@files) {
1550 my $fullpath = "$builddir/$file";
1551 if ($file eq $err || $fullpath eq $err) {
1552 fail "$file built with warnings" and return 0;
1562 sub apply_min_config {
1563 my $outconfig = "$output_config.new";
1565 # Read the config file and remove anything that
1566 # is in the force_config hash (from minconfig and others)
1567 # then add the force config back.
1569 doprint "Applying minimum configurations into $output_config.new\n";
1571 open (OUT, ">$outconfig") or
1572 dodie "Can't create $outconfig";
1574 if (-f $output_config) {
1575 open (IN, $output_config) or
1576 dodie "Failed to open $output_config";
1578 if (/^(# )?(CONFIG_[^\s=]*)/) {
1579 next if (defined($force_config{$2}));
1585 foreach my $config (keys %force_config) {
1586 print OUT "$force_config{$config}\n";
1590 run_command "mv $outconfig $output_config";
1593 sub make_oldconfig {
1595 my @force_list = keys %force_config;
1597 if ($#force_list >= 0) {
1601 if (!run_command "$make oldnoconfig") {
1602 # Perhaps oldnoconfig doesn't exist in this version of the kernel
1603 # try a yes '' | oldconfig
1604 doprint "oldnoconfig failed, trying yes '' | make oldconfig\n";
1605 run_command "yes '' | $make oldconfig" or
1606 dodie "failed make config oldconfig";
1610 # read a config file and use this to force new configs.
1611 sub load_force_config {
1614 open(IN, $config) or
1615 dodie "failed to read $config";
1618 if (/^(CONFIG[^\s=]*)(\s*=.*)/) {
1619 $force_config{$1} = $_;
1620 } elsif (/^# (CONFIG_\S*) is not set/) {
1621 $force_config{$1} = $_;
1632 # Failed builds should not reboot the target
1633 my $save_no_reboot = $no_reboot;
1636 if (defined($pre_build)) {
1637 my $ret = run_command $pre_build;
1638 if (!$ret && defined($pre_build_die) &&
1640 dodie "failed to pre_build\n";
1644 if ($type =~ /^useconfig:(.*)/) {
1645 run_command "cp $1 $output_config" or
1646 dodie "could not copy $1 to .config";
1648 $type = "oldconfig";
1651 # old config can ask questions
1652 if ($type eq "oldconfig") {
1653 $type = "oldnoconfig";
1655 # allow for empty configs
1656 run_command "touch $output_config";
1659 run_command "mv $output_config $outputdir/config_temp" or
1660 dodie "moving .config";
1662 run_command "$make mrproper" or dodie "make mrproper";
1664 run_command "mv $outputdir/config_temp $output_config" or
1665 dodie "moving config_temp";
1668 } elsif (!$noclean) {
1669 unlink "$output_config";
1670 run_command "$make mrproper" or
1671 dodie "make mrproper";
1674 # add something to distinguish this build
1675 open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file");
1676 print OUT "$localversion\n";
1679 if (defined($minconfig)) {
1680 load_force_config($minconfig);
1683 if ($type ne "oldnoconfig") {
1684 run_command "$make $type" or
1685 dodie "failed make config";
1687 # Run old config regardless, to enforce min configurations
1690 $redirect = "$buildlog";
1691 my $build_ret = run_command "$make $build_options";
1694 if (defined($post_build)) {
1695 my $ret = run_command $post_build;
1696 if (!$ret && defined($post_build_die) &&
1698 dodie "failed to post_build\n";
1703 # bisect may need this to pass
1705 $no_reboot = $save_no_reboot;
1708 fail "failed build" and return 0;
1711 $no_reboot = $save_no_reboot;
1717 if (!run_ssh "halt" or defined($power_off)) {
1718 if (defined($poweroff_after_halt)) {
1719 sleep $poweroff_after_halt;
1720 run_command "$power_off";
1724 run_command "$power_off";
1735 if (defined($test_name)) {
1736 $name = " ($test_name)";
1739 doprint "\n\n*******************************************\n";
1740 doprint "*******************************************\n";
1741 doprint "KTEST RESULT: TEST $i$name SUCCESS!!!! **\n";
1742 doprint "*******************************************\n";
1743 doprint "*******************************************\n";
1745 if (defined($store_successes)) {
1746 save_logs "success", $store_successes;
1749 if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) {
1750 doprint "Reboot and wait $sleep_time seconds\n";
1757 doprint "Pass or fail? [p/f]";
1760 if ($ans eq "p" || $ans eq "P") {
1762 } elsif ($ans eq "f" || $ans eq "F") {
1765 print "Please answer 'P' or 'F'\n";
1770 sub child_run_test {
1773 # child should have no power
1774 $reboot_on_error = 0;
1775 $poweroff_on_error = 0;
1776 $die_on_failure = 1;
1778 $redirect = "$testlog";
1779 run_command $run_test or $failed = 1;
1787 sub child_finished {
1800 doprint "run test $run_test\n";
1804 $SIG{CHLD} = qw(child_finished);
1808 child_run_test if (!$child_pid);
1813 $line = wait_for_input($monitor_fp, 1);
1814 if (defined($line)) {
1816 # we are not guaranteed to get a full line
1817 $full_line .= $line;
1820 if ($full_line =~ /call trace:/i) {
1824 if ($full_line =~ /Kernel panic -/) {
1828 if ($line =~ /\n/) {
1832 } while (!$child_done && !$bug);
1835 my $failure_start = time;
1838 $line = wait_for_input($monitor_fp, 1);
1839 if (defined($line)) {
1843 if ($now - $failure_start >= $stop_after_failure) {
1846 } while (defined($line));
1848 doprint "Detected kernel crash!\n";
1849 # kill the child with extreme prejudice
1853 waitpid $child_pid, 0;
1856 if ($bug || $child_exit) {
1857 return 0 if $in_bisect;
1858 fail "test failed" and return 0;
1863 sub run_git_bisect {
1866 doprint "$command ... ";
1868 my $output = `$command 2>&1`;
1875 dodie "Failed to git bisect";
1878 doprint "SUCCESS\n";
1879 if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) {
1880 doprint "$1 [$2]\n";
1881 } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) {
1883 doprint "Found bad commit... $1\n";
1886 # we already logged it, just print it now.
1894 doprint "Reboot and sleep $bisect_sleep_time seconds\n";
1895 reboot $bisect_sleep_time;
1898 # returns 1 on success, 0 on failure, -1 on skip
1899 sub run_bisect_test {
1900 my ($type, $buildtype) = @_;
1909 build $buildtype or $failed = 1;
1911 if ($type ne "build") {
1912 if ($failed && $bisect_skip) {
1916 dodie "Failed on build" if $failed;
1919 start_monitor_and_boot or $failed = 1;
1921 if ($type ne "boot") {
1922 if ($failed && $bisect_skip) {
1928 dodie "Failed on boot" if $failed;
1930 do_run_test or $failed = 1;
1941 # reboot the box to a kernel we can ssh to
1942 if ($type ne "build") {
1952 my $buildtype = "oldconfig";
1954 # We should have a minconfig to use?
1955 if (defined($minconfig)) {
1956 $buildtype = "useconfig:$minconfig";
1959 my $ret = run_bisect_test $type, $buildtype;
1961 if ($bisect_manual) {
1962 $ret = answer_bisect;
1965 # Are we looking for where it worked, not failed?
1966 if ($reverse_bisect) {
1972 } elsif ($ret == 0) {
1974 } elsif ($bisect_skip) {
1975 doprint "HIT A BAD COMMIT ... SKIPPING\n";
1980 sub update_bisect_replay {
1981 my $tmp_log = "$tmpdir/ktest_bisect_log";
1982 run_command "git bisect log > $tmp_log" or
1983 die "can't create bisect log";
1992 die "BISECT_GOOD[$i] not defined\n" if (!defined($opt{"BISECT_GOOD[$i]"}));
1993 die "BISECT_BAD[$i] not defined\n" if (!defined($opt{"BISECT_BAD[$i]"}));
1994 die "BISECT_TYPE[$i] not defined\n" if (!defined($opt{"BISECT_TYPE[$i]"}));
1996 my $good = $opt{"BISECT_GOOD[$i]"};
1997 my $bad = $opt{"BISECT_BAD[$i]"};
1998 my $type = $opt{"BISECT_TYPE[$i]"};
1999 my $start = $opt{"BISECT_START[$i]"};
2000 my $replay = $opt{"BISECT_REPLAY[$i]"};
2001 my $start_files = $opt{"BISECT_FILES[$i]"};
2003 if (defined($start_files)) {
2004 $start_files = " -- " . $start_files;
2009 # convert to true sha1's
2010 $good = get_sha1($good);
2011 $bad = get_sha1($bad);
2013 if (defined($opt{"BISECT_REVERSE[$i]"}) &&
2014 $opt{"BISECT_REVERSE[$i]"} == 1) {
2015 doprint "Performing a reverse bisect (bad is good, good is bad!)\n";
2016 $reverse_bisect = 1;
2018 $reverse_bisect = 0;
2021 # Can't have a test without having a test to run
2022 if ($type eq "test" && !defined($run_test)) {
2026 # Check if a bisect was running
2027 my $bisect_start_file = "$builddir/.git/BISECT_START";
2029 my $check = $opt{"BISECT_CHECK[$i]"};
2030 my $do_check = defined($check) && $check ne "0";
2032 if ( -f $bisect_start_file ) {
2033 print "Bisect in progress found\n";
2035 print " If you say yes, then no checks of good or bad will be done\n";
2037 if (defined($replay)) {
2038 print "** BISECT_REPLAY is defined in config file **";
2039 print " Ignore config option and perform new git bisect log?\n";
2040 if (read_ync " (yes, no, or cancel) ") {
2041 $replay = update_bisect_replay;
2044 } elsif (read_yn "read git log and continue?") {
2045 $replay = update_bisect_replay;
2053 my $head = get_sha1("HEAD");
2055 if ($check ne "good") {
2056 doprint "TESTING BISECT BAD [$bad]\n";
2057 run_command "git checkout $bad" or
2058 die "Failed to checkout $bad";
2060 $result = run_bisect $type;
2062 if ($result ne "bad") {
2063 fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0;
2067 if ($check ne "bad") {
2068 doprint "TESTING BISECT GOOD [$good]\n";
2069 run_command "git checkout $good" or
2070 die "Failed to checkout $good";
2072 $result = run_bisect $type;
2074 if ($result ne "good") {
2075 fail "Tested BISECT_GOOD [$good] and it failed" and return 0;
2079 # checkout where we started
2080 run_command "git checkout $head" or
2081 die "Failed to checkout $head";
2084 run_command "git bisect start$start_files" or
2085 dodie "could not start bisect";
2087 run_command "git bisect good $good" or
2088 dodie "could not set bisect good to $good";
2090 run_git_bisect "git bisect bad $bad" or
2091 dodie "could not set bisect bad to $bad";
2093 if (defined($replay)) {
2094 run_command "git bisect replay $replay" or
2095 dodie "failed to run replay";
2098 if (defined($start)) {
2099 run_command "git checkout $start" or
2100 dodie "failed to checkout $start";
2105 $result = run_bisect $type;
2106 $test = run_git_bisect "git bisect $result";
2109 run_command "git bisect log" or
2110 dodie "could not capture git bisect log";
2112 run_command "git bisect reset" or
2113 dodie "could not reset git bisect";
2115 doprint "Bad commit was [$bisect_bad]\n";
2128 sub assign_configs {
2129 my ($hash, $config) = @_;
2132 or dodie "Failed to read $config";
2135 if (/^((CONFIG\S*)=.*)/) {
2143 sub process_config_ignore {
2146 assign_configs \%config_ignore, $config;
2149 sub read_current_config {
2150 my ($config_ref) = @_;
2152 %{$config_ref} = ();
2153 undef %{$config_ref};
2155 my @key = keys %{$config_ref};
2157 print "did not delete!\n";
2160 open (IN, "$output_config");
2163 if (/^(CONFIG\S+)=(.*)/) {
2164 ${$config_ref}{$1} = $2;
2170 sub get_dependencies {
2173 my $arr = $dependency{$config};
2174 if (!defined($arr)) {
2180 foreach my $dep (@{$arr}) {
2181 print "ADD DEP $dep\n";
2182 @deps = (@deps, get_dependencies $dep);
2191 open(OUT, ">$output_config") or dodie "Can not write to $output_config";
2193 foreach my $config (@configs) {
2194 print OUT "$config_set{$config}\n";
2195 my @deps = get_dependencies $config;
2196 foreach my $dep (@deps) {
2197 print OUT "$config_set{$dep}\n";
2201 foreach my $config (keys %config_ignore) {
2202 print OUT "$config_ignore{$config}\n";
2210 sub compare_configs {
2213 foreach my $item (keys %a) {
2214 if (!defined($b{$item})) {
2215 print "diff $item\n";
2223 print "diff2 $keys[0]\n";
2225 return -1 if ($#keys >= 0);
2230 sub run_config_bisect_test {
2233 return run_bisect_test $type, "oldconfig";
2236 sub process_passed {
2239 doprint "These configs had no failure: (Enabling them for further compiles)\n";
2240 # Passed! All these configs are part of a good compile.
2241 # Add them to the min options.
2242 foreach my $config (keys %configs) {
2243 if (defined($config_list{$config})) {
2244 doprint " removing $config\n";
2245 $config_ignore{$config} = $config_list{$config};
2246 delete $config_list{$config};
2249 doprint "config copied to $outputdir/config_good\n";
2250 run_command "cp -f $output_config $outputdir/config_good";
2253 sub process_failed {
2256 doprint "\n\n***************************************\n";
2257 doprint "Found bad config: $config\n";
2258 doprint "***************************************\n\n";
2261 sub run_config_bisect {
2263 my @start_list = keys %config_list;
2265 if ($#start_list < 0) {
2266 doprint "No more configs to test!!!\n";
2270 doprint "***** RUN TEST ***\n";
2271 my $type = $opt{"CONFIG_BISECT_TYPE[$iteration]"};
2275 my $count = $#start_list + 1;
2276 doprint " $count configs to test\n";
2278 my $half = int($#start_list / 2);
2281 my @tophalf = @start_list[0 .. $half];
2283 create_config @tophalf;
2284 read_current_config \%current_config;
2286 $count = $#tophalf + 1;
2287 doprint "Testing $count configs\n";
2289 # make sure we test something
2290 foreach my $config (@tophalf) {
2291 if (defined($current_config{$config})) {
2297 # try the other half
2298 doprint "Top half produced no set configs, trying bottom half\n";
2299 @tophalf = @start_list[$half + 1 .. $#start_list];
2300 create_config @tophalf;
2301 read_current_config \%current_config;
2302 foreach my $config (@tophalf) {
2303 if (defined($current_config{$config})) {
2309 doprint "Failed: Can't make new config with current configs\n";
2310 foreach my $config (@start_list) {
2311 doprint " CONFIG: $config\n";
2315 $count = $#tophalf + 1;
2316 doprint "Testing $count configs\n";
2319 $ret = run_config_bisect_test $type;
2320 if ($bisect_manual) {
2321 $ret = answer_bisect;
2324 process_passed %current_config;
2328 doprint "This config had a failure.\n";
2329 doprint "Removing these configs that were not set in this config:\n";
2330 doprint "config copied to $outputdir/config_bad\n";
2331 run_command "cp -f $output_config $outputdir/config_bad";
2333 # A config exists in this group that was bad.
2334 foreach my $config (keys %config_list) {
2335 if (!defined($current_config{$config})) {
2336 doprint " removing $config\n";
2337 delete $config_list{$config};
2341 @start_list = @tophalf;
2343 if ($#start_list == 0) {
2344 process_failed $start_list[0];
2348 # remove half the configs we are looking at and see if
2350 $half = int($#start_list / 2);
2351 } while ($#start_list > 0);
2353 # we found a single config, try it again unless we are running manually
2355 if ($bisect_manual) {
2356 process_failed $start_list[0];
2360 my @tophalf = @start_list[0 .. 0];
2362 $ret = run_config_bisect_test $type;
2364 process_passed %current_config;
2368 process_failed $start_list[0];
2375 my $start_config = $opt{"CONFIG_BISECT[$i]"};
2377 my $tmpconfig = "$tmpdir/use_config";
2379 if (defined($config_bisect_good)) {
2380 process_config_ignore $config_bisect_good;
2383 # Make the file with the bad config and the min config
2384 if (defined($minconfig)) {
2385 # read the min config for things to ignore
2386 run_command "cp $minconfig $tmpconfig" or
2387 dodie "failed to copy $minconfig to $tmpconfig";
2392 if (-f $tmpconfig) {
2393 load_force_config($tmpconfig);
2394 process_config_ignore $tmpconfig;
2397 # now process the start config
2398 run_command "cp $start_config $output_config" or
2399 dodie "failed to copy $start_config to $output_config";
2401 # read directly what we want to check
2403 open (IN, $output_config)
2404 or dodie "faied to open $output_config";
2407 if (/^((CONFIG\S*)=.*)/) {
2408 $config_check{$2} = $1;
2413 # Now run oldconfig with the minconfig
2416 # check to see what we lost (or gained)
2417 open (IN, $output_config)
2418 or dodie "Failed to read $start_config";
2420 my %removed_configs;
2424 if (/^((CONFIG\S*)=.*)/) {
2425 # save off all options
2426 $config_set{$2} = $1;
2427 if (defined($config_check{$2})) {
2428 if (defined($config_ignore{$2})) {
2429 $removed_configs{$2} = $1;
2431 $config_list{$2} = $1;
2433 } elsif (!defined($config_ignore{$2})) {
2434 $added_configs{$2} = $1;
2435 $config_list{$2} = $1;
2441 my @confs = keys %removed_configs;
2443 doprint "Configs overridden by default configs and removed from check:\n";
2444 foreach my $config (@confs) {
2445 doprint " $config\n";
2448 @confs = keys %added_configs;
2450 doprint "Configs appearing in make oldconfig and added:\n";
2451 foreach my $config (@confs) {
2452 doprint " $config\n";
2459 # Sometimes kconfig does weird things. We must make sure
2460 # that the config we autocreate has everything we need
2461 # to test, otherwise we may miss testing configs, or
2462 # may not be able to create a new config.
2463 # Here we create a config with everything set.
2464 create_config (keys %config_list);
2465 read_current_config \%config_test;
2466 foreach my $config (keys %config_list) {
2467 if (!defined($config_test{$config})) {
2470 doprint "Configs not produced by kconfig (will not be checked):\n";
2472 doprint " $config\n";
2473 delete $config_list{$config};
2478 $ret = run_config_bisect;
2481 return $ret if ($ret < 0);
2486 sub patchcheck_reboot {
2487 doprint "Reboot and sleep $patchcheck_sleep_time seconds\n";
2488 reboot $patchcheck_sleep_time;
2494 die "PATCHCHECK_START[$i] not defined\n"
2495 if (!defined($opt{"PATCHCHECK_START[$i]"}));
2496 die "PATCHCHECK_TYPE[$i] not defined\n"
2497 if (!defined($opt{"PATCHCHECK_TYPE[$i]"}));
2499 my $start = $opt{"PATCHCHECK_START[$i]"};
2502 if (defined($opt{"PATCHCHECK_END[$i]"})) {
2503 $end = $opt{"PATCHCHECK_END[$i]"};
2506 # Get the true sha1's since we can use things like HEAD~3
2507 $start = get_sha1($start);
2508 $end = get_sha1($end);
2510 my $type = $opt{"PATCHCHECK_TYPE[$i]"};
2512 # Can't have a test without having a test to run
2513 if ($type eq "test" && !defined($run_test)) {
2517 open (IN, "git log --pretty=oneline $end|") or
2518 dodie "could not get git list";
2524 $list[$#list+1] = $_;
2525 last if (/^$start/);
2529 if ($list[$#list] !~ /^$start/) {
2530 fail "SHA1 $start not found";
2533 # go backwards in the list
2534 @list = reverse @list;
2536 my $save_clean = $noclean;
2537 my %ignored_warnings;
2539 if (defined($ignore_warnings)) {
2540 foreach my $sha1 (split /\s+/, $ignore_warnings) {
2541 $ignored_warnings{$sha1} = 1;
2546 foreach my $item (@list) {
2548 $sha1 =~ s/^([[:xdigit:]]+).*/$1/;
2550 doprint "\nProcessing commit $item\n\n";
2552 run_command "git checkout $sha1" or
2553 die "Failed to checkout $sha1";
2555 # only clean on the first and last patch
2556 if ($item eq $list[0] ||
2557 $item eq $list[$#list]) {
2558 $noclean = $save_clean;
2563 if (defined($minconfig)) {
2564 build "useconfig:$minconfig" or return 0;
2566 # ?? no config to use?
2567 build "oldconfig" or return 0;
2571 if (!defined($ignored_warnings{$sha1})) {
2572 check_buildlog $sha1 or return 0;
2575 next if ($type eq "build");
2579 start_monitor_and_boot or $failed = 1;
2581 if (!$failed && $type ne "boot"){
2582 do_run_test or $failed = 1;
2585 return 0 if ($failed);
2605 # $config depends on $dep
2606 my ($config, $dep) = @_;
2608 if (defined($depends{$config})) {
2609 $depends{$config} .= " " . $dep;
2611 $depends{$config} = $dep;
2614 # record the number of configs depending on $dep
2615 if (defined $depcount{$dep}) {
2618 $depcount{$dep} = 1;
2622 # taken from streamline_config.pl
2634 if (! -f $kconfig) {
2635 doprint "file $kconfig does not exist, skipping\n";
2639 open(KIN, "$kconfig")
2640 or die "Can't open $kconfig";
2644 # Make sure that lines ending with \ continue
2646 $_ = $line . " " . $_;
2657 # collect any Kconfig sources
2658 if (/^source\s*"(.*)"/) {
2659 $kconfigs[$#kconfigs+1] = $1;
2663 if (/^\s*(menu)?config\s+(\S+)\s*$/) {
2667 for (my $i = 0; $i < $iflevel; $i++) {
2668 add_dep $config, $ifdeps[$i];
2671 # collect the depends for the config
2672 } elsif ($state eq "NEW" && /^\s*depends\s+on\s+(.*)$/) {
2674 add_dep $config, $1;
2676 # Get the configs that select this config
2677 } elsif ($state eq "NEW" && /^\s*select\s+(\S+)/) {
2679 # selected by depends on config
2680 add_dep $1, $config;
2682 # Check for if statements
2683 } elsif (/^if\s+(.*\S)\s*$/) {
2685 # remove beginning and ending non text
2686 $deps =~ s/^[^a-zA-Z0-9_]*//;
2687 $deps =~ s/[^a-zA-Z0-9_]*$//;
2689 my @deps = split /[^a-zA-Z0-9_]+/, $deps;
2691 $ifdeps[$iflevel++] = join ':', @deps;
2693 } elsif (/^endif/) {
2695 $iflevel-- if ($iflevel);
2698 } elsif (/^\s*help\s*$/) {
2704 # read in any configs that were found.
2705 foreach $kconfig (@kconfigs) {
2706 if (!defined($read_kconfigs{$kconfig})) {
2707 $read_kconfigs{$kconfig} = 1;
2708 read_kconfig("$builddir/$kconfig");
2714 # find out which arch this is by the kconfig file
2715 open (IN, $output_config)
2716 or dodie "Failed to read $output_config";
2719 if (m,Linux/(\S+)\s+\S+\s+Kernel Configuration,) {
2726 if (!defined($arch)) {
2727 doprint "Could not find arch from config file\n";
2728 doprint "no dependencies used\n";
2732 # arch is really the subarch, we need to know
2733 # what directory to look at.
2734 if ($arch eq "i386" || $arch eq "x86_64") {
2736 } elsif ($arch =~ /^tile/) {
2740 my $kconfig = "$builddir/arch/$arch/Kconfig";
2742 if (! -f $kconfig && $arch =~ /\d$/) {
2744 # some subarchs have numbers, truncate them
2746 $kconfig = "$builddir/arch/$arch/Kconfig";
2747 if (! -f $kconfig) {
2748 doprint "No idea what arch dir $orig is for\n";
2749 doprint "no dependencies used\n";
2754 read_kconfig($kconfig);
2757 sub read_config_list {
2761 or dodie "Failed to read $config";
2764 if (/^((CONFIG\S*)=.*)/) {
2765 if (!defined($config_ignore{$2})) {
2766 $config_list{$2} = $1;
2774 sub read_output_config {
2777 assign_configs \%config_ignore, $config;
2780 sub make_new_config {
2783 open (OUT, ">$output_config")
2784 or dodie "Failed to write $output_config";
2786 foreach my $config (@configs) {
2787 print OUT "$config\n";
2795 $config =~ s/CONFIG_//;
2803 my $kconfig = chomp_config $dep;
2805 $dep = $depends{"$kconfig"};
2807 # the dep string we have saves the dependencies as they
2808 # were found, including expressions like ! && ||. We
2809 # want to split this out into just an array of configs.
2811 my $valid = "A-Za-z_0-9";
2815 while ($dep =~ /[$valid]/) {
2817 if ($dep =~ /^[^$valid]*([$valid]+)/) {
2818 my $conf = "CONFIG_" . $1;
2820 $configs[$#configs + 1] = $conf;
2822 $dep =~ s/^[^$valid]*[$valid]+//;
2824 die "this should never happen";
2834 my %processed_configs;
2835 my %nochange_config;
2837 sub test_this_config {
2842 # if we already processed this config, skip it
2843 if (defined($processed_configs{$config})) {
2846 $processed_configs{$config} = 1;
2848 # if this config failed during this round, skip it
2849 if (defined($nochange_config{$config})) {
2853 my $kconfig = chomp_config $config;
2855 # Test dependencies first
2856 if (defined($depends{"$kconfig"})) {
2857 my @parents = get_depends $config;
2858 foreach my $parent (@parents) {
2859 # if the parent is in the min config, check it first
2860 next if (!defined($min_configs{$parent}));
2861 $found = test_this_config($parent);
2862 if (defined($found)) {
2868 # Remove this config from the list of configs
2869 # do a make oldnoconfig and then read the resulting
2870 # .config to make sure it is missing the config that
2872 my %configs = %min_configs;
2873 delete $configs{$config};
2874 make_new_config ((values %configs), (values %keep_configs));
2877 assign_configs \%configs, $output_config;
2879 return $config if (!defined($configs{$config}));
2881 doprint "disabling config $config did not change .config\n";
2883 $nochange_config{$config} = 1;
2888 sub make_min_config {
2891 if (!defined($output_minconfig)) {
2892 fail "OUTPUT_MIN_CONFIG not defined" and return;
2895 # If output_minconfig exists, and the start_minconfig
2896 # came from min_config, than ask if we should use
2898 if (-f $output_minconfig && !$start_minconfig_defined) {
2899 print "$output_minconfig exists\n";
2900 if (read_yn " Use it as minconfig?") {
2901 $start_minconfig = $output_minconfig;
2905 if (!defined($start_minconfig)) {
2906 fail "START_MIN_CONFIG or MIN_CONFIG not defined" and return;
2909 my $temp_config = "$tmpdir/temp_config";
2911 # First things first. We build an allnoconfig to find
2912 # out what the defaults are that we can't touch.
2913 # Some are selections, but we really can't handle selections.
2915 my $save_minconfig = $minconfig;
2918 run_command "$make allnoconfig" or return 0;
2922 process_config_ignore $output_config;
2924 undef %save_configs;
2927 if (defined($ignore_config)) {
2928 # make sure the file exists
2929 `touch $ignore_config`;
2930 assign_configs \%save_configs, $ignore_config;
2933 %keep_configs = %save_configs;
2935 doprint "Load initial configs from $start_minconfig\n";
2937 # Look at the current min configs, and save off all the
2938 # ones that were set via the allnoconfig
2939 assign_configs \%min_configs, $start_minconfig;
2941 my @config_keys = keys %min_configs;
2943 # All configs need a depcount
2944 foreach my $config (@config_keys) {
2945 my $kconfig = chomp_config $config;
2946 if (!defined $depcount{$kconfig}) {
2947 $depcount{$kconfig} = 0;
2951 # Remove anything that was set by the make allnoconfig
2952 # we shouldn't need them as they get set for us anyway.
2953 foreach my $config (@config_keys) {
2954 # Remove anything in the ignore_config
2955 if (defined($keep_configs{$config})) {
2956 my $file = $ignore_config;
2957 $file =~ s,.*/(.*?)$,$1,;
2958 doprint "$config set by $file ... ignored\n";
2959 delete $min_configs{$config};
2962 # But make sure the settings are the same. If a min config
2963 # sets a selection, we do not want to get rid of it if
2964 # it is not the same as what we have. Just move it into
2966 if (defined($config_ignore{$config})) {
2967 if ($config_ignore{$config} ne $min_configs{$config}) {
2968 doprint "$config is in allnoconfig as '$config_ignore{$config}'";
2969 doprint " but it is '$min_configs{$config}' in minconfig .. keeping\n";
2970 $keep_configs{$config} = $min_configs{$config};
2972 doprint "$config set by allnoconfig ... ignored\n";
2974 delete $min_configs{$config};
2986 # Now disable each config one by one and do a make oldconfig
2987 # till we find a config that changes our list.
2989 my @test_configs = keys %min_configs;
2991 # Sort keys by who is most dependent on
2992 @test_configs = sort { $depcount{chomp_config($b)} <=> $depcount{chomp_config($a)} }
2995 # Put configs that did not modify the config at the end.
2997 for (my $i = 0; $i < $#test_configs; $i++) {
2998 if (!defined($nochange_config{$test_configs[0]})) {
3002 # This config didn't change the .config last time.
3003 # Place it at the end
3004 my $config = shift @test_configs;
3005 push @test_configs, $config;
3008 # if every test config has failed to modify the .config file
3009 # in the past, then reset and start over.
3011 undef %nochange_config;
3014 undef %processed_configs;
3016 foreach my $config (@test_configs) {
3018 $found = test_this_config $config;
3020 last if (defined($found));
3022 # oh well, try another config
3025 if (!defined($found)) {
3026 # we could have failed due to the nochange_config hash
3027 # reset and try again
3029 undef %nochange_config;
3033 doprint "No more configs found that we can disable\n";
3041 doprint "Test with $config disabled\n";
3043 # set in_bisect to keep build and monitor from dieing
3048 start_monitor_and_boot or $failed = 1;
3054 doprint "$min_configs{$config} is needed to boot the box... keeping\n";
3055 # this config is needed, add it to the ignore list.
3056 $keep_configs{$config} = $min_configs{$config};
3057 $save_configs{$config} = $min_configs{$config};
3058 delete $min_configs{$config};
3060 # update new ignore configs
3061 if (defined($ignore_config)) {
3062 open (OUT, ">$temp_config")
3063 or die "Can't write to $temp_config";
3064 foreach my $config (keys %save_configs) {
3065 print OUT "$save_configs{$config}\n";
3068 run_command "mv $temp_config $ignore_config" or
3069 dodie "failed to copy update to $ignore_config";
3073 # We booted without this config, remove it from the minconfigs.
3074 doprint "$config is not needed, disabling\n";
3076 delete $min_configs{$config};
3078 # Also disable anything that is not enabled in this config
3080 assign_configs \%configs, $output_config;
3081 my @config_keys = keys %min_configs;
3082 foreach my $config (@config_keys) {
3083 if (!defined($configs{$config})) {
3084 doprint "$config is not set, disabling\n";
3085 delete $min_configs{$config};
3089 # Save off all the current mandidory configs
3090 open (OUT, ">$temp_config")
3091 or die "Can't write to $temp_config";
3092 foreach my $config (keys %keep_configs) {
3093 print OUT "$keep_configs{$config}\n";
3095 foreach my $config (keys %min_configs) {
3096 print OUT "$min_configs{$config}\n";
3100 run_command "mv $temp_config $output_minconfig" or
3101 dodie "failed to copy update to $output_minconfig";
3104 doprint "Reboot and wait $sleep_time seconds\n";
3112 $#ARGV < 1 or die "ktest.pl version: $VERSION\n usage: ktest.pl config-file\n";
3115 $ktest_config = $ARGV[0];
3116 if (! -f $ktest_config) {
3117 print "$ktest_config does not exist.\n";
3118 if (!read_yn "Create it?") {
3123 $ktest_config = "ktest.conf";
3126 if (! -f $ktest_config) {
3129 open(OUT, ">$ktest_config") or die "Can not create $ktest_config";
3131 # Generated by ktest.pl
3134 # PWD is a ktest.pl variable that will result in the process working
3135 # directory that ktest.pl is executed in.
3137 # THIS_DIR is automatically assigned the PWD of the path that generated
3138 # the config file. It is best to use this variable when assigning other
3139 # directory paths within this directory. This allows you to easily
3140 # move the test cases to other locations or to other machines.
3142 THIS_DIR := $variable{"PWD"}
3144 # Define each test with TEST_START
3145 # The config options below it will override the defaults
3147 TEST_TYPE = $default{"TEST_TYPE"}
3154 read_config $ktest_config;
3156 if (defined($opt{"LOG_FILE"})) {
3157 $opt{"LOG_FILE"} = eval_option($opt{"LOG_FILE"}, -1);
3160 # Append any configs entered in manually to the config file.
3161 my @new_configs = keys %entered_configs;
3162 if ($#new_configs >= 0) {
3163 print "\nAppending entered in configs to $ktest_config\n";
3164 open(OUT, ">>$ktest_config") or die "Can not append to $ktest_config";
3165 foreach my $config (@new_configs) {
3166 print OUT "$config = $entered_configs{$config}\n";
3167 $opt{$config} = process_variables($entered_configs{$config});
3171 if ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) {
3172 unlink $opt{"LOG_FILE"};
3175 doprint "\n\nSTARTING AUTOMATED TESTS\n\n";
3177 for (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) {
3180 doprint "DEFAULT OPTIONS:\n";
3182 doprint "\nTEST $i OPTIONS";
3183 if (defined($repeat_tests{$i})) {
3184 $repeat = $repeat_tests{$i};
3185 doprint " ITERATE $repeat";
3190 foreach my $option (sort keys %opt) {
3192 if ($option =~ /\[(\d+)\]$/) {
3198 doprint "$option = $opt{$option}\n";
3202 sub __set_test_option {
3203 my ($name, $i) = @_;
3205 my $option = "$name\[$i\]";
3207 if (defined($opt{$option})) {
3208 return $opt{$option};
3211 foreach my $test (keys %repeat_tests) {
3213 $i < $test + $repeat_tests{$test}) {
3214 $option = "$name\[$test\]";
3215 if (defined($opt{$option})) {
3216 return $opt{$option};
3221 if (defined($opt{$name})) {
3228 sub set_test_option {
3229 my ($name, $i) = @_;
3231 my $option = __set_test_option($name, $i);
3232 return $option if (!defined($option));
3234 return eval_option($option, $i);
3237 # First we need to do is the builds
3238 for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
3240 # Do not reboot on failing test options
3245 my $makecmd = set_test_option("MAKE_CMD", $i);
3247 $machine = set_test_option("MACHINE", $i);
3248 $ssh_user = set_test_option("SSH_USER", $i);
3249 $tmpdir = set_test_option("TMP_DIR", $i);
3250 $outputdir = set_test_option("OUTPUT_DIR", $i);
3251 $builddir = set_test_option("BUILD_DIR", $i);
3252 $test_type = set_test_option("TEST_TYPE", $i);
3253 $build_type = set_test_option("BUILD_TYPE", $i);
3254 $build_options = set_test_option("BUILD_OPTIONS", $i);
3255 $pre_build = set_test_option("PRE_BUILD", $i);
3256 $post_build = set_test_option("POST_BUILD", $i);
3257 $pre_build_die = set_test_option("PRE_BUILD_DIE", $i);
3258 $post_build_die = set_test_option("POST_BUILD_DIE", $i);
3259 $power_cycle = set_test_option("POWER_CYCLE", $i);
3260 $reboot = set_test_option("REBOOT", $i);
3261 $noclean = set_test_option("BUILD_NOCLEAN", $i);
3262 $minconfig = set_test_option("MIN_CONFIG", $i);
3263 $output_minconfig = set_test_option("OUTPUT_MIN_CONFIG", $i);
3264 $start_minconfig = set_test_option("START_MIN_CONFIG", $i);
3265 $ignore_config = set_test_option("IGNORE_CONFIG", $i);
3266 $run_test = set_test_option("TEST", $i);
3267 $addconfig = set_test_option("ADD_CONFIG", $i);
3268 $reboot_type = set_test_option("REBOOT_TYPE", $i);
3269 $grub_menu = set_test_option("GRUB_MENU", $i);
3270 $post_install = set_test_option("POST_INSTALL", $i);
3271 $no_install = set_test_option("NO_INSTALL", $i);
3272 $reboot_script = set_test_option("REBOOT_SCRIPT", $i);
3273 $reboot_on_error = set_test_option("REBOOT_ON_ERROR", $i);
3274 $poweroff_on_error = set_test_option("POWEROFF_ON_ERROR", $i);
3275 $die_on_failure = set_test_option("DIE_ON_FAILURE", $i);
3276 $power_off = set_test_option("POWER_OFF", $i);
3277 $powercycle_after_reboot = set_test_option("POWERCYCLE_AFTER_REBOOT", $i);
3278 $poweroff_after_halt = set_test_option("POWEROFF_AFTER_HALT", $i);
3279 $sleep_time = set_test_option("SLEEP_TIME", $i);
3280 $bisect_sleep_time = set_test_option("BISECT_SLEEP_TIME", $i);
3281 $patchcheck_sleep_time = set_test_option("PATCHCHECK_SLEEP_TIME", $i);
3282 $ignore_warnings = set_test_option("IGNORE_WARNINGS", $i);
3283 $bisect_manual = set_test_option("BISECT_MANUAL", $i);
3284 $bisect_skip = set_test_option("BISECT_SKIP", $i);
3285 $config_bisect_good = set_test_option("CONFIG_BISECT_GOOD", $i);
3286 $store_failures = set_test_option("STORE_FAILURES", $i);
3287 $store_successes = set_test_option("STORE_SUCCESSES", $i);
3288 $test_name = set_test_option("TEST_NAME", $i);
3289 $timeout = set_test_option("TIMEOUT", $i);
3290 $booted_timeout = set_test_option("BOOTED_TIMEOUT", $i);
3291 $console = set_test_option("CONSOLE", $i);
3292 $detect_triplefault = set_test_option("DETECT_TRIPLE_FAULT", $i);
3293 $success_line = set_test_option("SUCCESS_LINE", $i);
3294 $reboot_success_line = set_test_option("REBOOT_SUCCESS_LINE", $i);
3295 $stop_after_success = set_test_option("STOP_AFTER_SUCCESS", $i);
3296 $stop_after_failure = set_test_option("STOP_AFTER_FAILURE", $i);
3297 $stop_test_after = set_test_option("STOP_TEST_AFTER", $i);
3298 $build_target = set_test_option("BUILD_TARGET", $i);
3299 $ssh_exec = set_test_option("SSH_EXEC", $i);
3300 $scp_to_target = set_test_option("SCP_TO_TARGET", $i);
3301 $target_image = set_test_option("TARGET_IMAGE", $i);
3302 $localversion = set_test_option("LOCALVERSION", $i);
3304 $start_minconfig_defined = 1;
3306 if (!defined($start_minconfig)) {
3307 $start_minconfig_defined = 0;
3308 $start_minconfig = $minconfig;
3311 chdir $builddir || die "can't change directory to $builddir";
3313 foreach my $dir ($tmpdir, $outputdir) {
3316 die "can't create $dir";
3320 $ENV{"SSH_USER"} = $ssh_user;
3321 $ENV{"MACHINE"} = $machine;
3323 $buildlog = "$tmpdir/buildlog-$machine";
3324 $testlog = "$tmpdir/testlog-$machine";
3325 $dmesg = "$tmpdir/dmesg-$machine";
3326 $make = "$makecmd O=$outputdir";
3327 $output_config = "$outputdir/.config";
3330 $target = "$ssh_user\@$machine";
3331 if ($reboot_type eq "grub") {
3332 dodie "GRUB_MENU not defined" if (!defined($grub_menu));
3333 } elsif (!defined($reboot_script)) {
3334 dodie "REBOOT_SCRIPT not defined"
3338 my $run_type = $build_type;
3339 if ($test_type eq "patchcheck") {
3340 $run_type = $opt{"PATCHCHECK_TYPE[$i]"};
3341 } elsif ($test_type eq "bisect") {
3342 $run_type = $opt{"BISECT_TYPE[$i]"};
3343 } elsif ($test_type eq "config_bisect") {
3344 $run_type = $opt{"CONFIG_BISECT_TYPE[$i]"};
3347 if ($test_type eq "make_min_config") {
3351 # mistake in config file?
3352 if (!defined($run_type)) {
3353 $run_type = "ERROR";
3357 $installme = " no_install" if ($no_install);
3360 doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type$installme\n\n";
3366 if (defined($addconfig)) {
3367 my $min = $minconfig;
3368 if (!defined($minconfig)) {
3371 run_command "cat $addconfig $min > $tmpdir/add_config" or
3372 dodie "Failed to create temp config";
3373 $minconfig = "$tmpdir/add_config";
3376 my $checkout = $opt{"CHECKOUT[$i]"};
3377 if (defined($checkout)) {
3378 run_command "git checkout $checkout" or
3379 die "failed to checkout $checkout";
3385 if ($test_type eq "bisect") {
3388 } elsif ($test_type eq "config_bisect") {
3391 } elsif ($test_type eq "patchcheck") {
3394 } elsif ($test_type eq "make_min_config") {
3399 if ($build_type ne "nobuild") {
3400 build $build_type or next;
3403 if ($test_type eq "install") {
3410 if ($test_type ne "build") {
3412 start_monitor_and_boot or $failed = 1;
3414 if (!$failed && $test_type ne "boot" && defined($run_test)) {
3415 do_run_test or $failed = 1;
3424 if ($opt{"POWEROFF_ON_SUCCESS"}) {
3426 } elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot) {
3430 doprint "\n $successes of $opt{NUM_TESTS} tests were successful\n\n";