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 my $prvalue = process_variables($rvalue);
421 if ($buildonly && $lvalue =~ /^TEST_TYPE(\[.*\])?$/ && $prvalue ne "build") {
422 # Note if a test is something other than build, then we
423 # will need other manditory options.
424 if ($prvalue ne "install") {
427 # install still limits some manditory options.
432 if (defined($opt{$lvalue})) {
433 if (!$override || defined(${$overrides}{$lvalue})) {
436 $extra = "In the same override section!\n";
438 die "$name: $.: Option $lvalue defined more than once!\n$extra";
440 ${$overrides}{$lvalue} = $prvalue;
442 if ($rvalue =~ /^\s*$/) {
443 delete $opt{$lvalue};
445 $opt{$lvalue} = $prvalue;
450 my ($lvalue, $rvalue) = @_;
452 if ($rvalue =~ /^\s*$/) {
453 delete $variable{$lvalue};
455 $rvalue = process_variables($rvalue);
456 $variable{$lvalue} = $rvalue;
460 sub process_compare {
461 my ($lval, $cmp, $rval) = @_;
472 return $lval eq $rval;
473 } elsif ($cmp eq "!=") {
474 return $lval ne $rval;
477 my $statement = "$lval $cmp $rval";
478 my $ret = eval $statement;
480 # $@ stores error of eval
491 return defined($variable{$2}) ||
496 sub process_expression {
497 my ($name, $val) = @_;
501 while ($val =~ s/\(([^\(]*?)\)/\&\&\&\&VAL\&\&\&\&/) {
504 if (process_expression($name, $express)) {
505 $val =~ s/\&\&\&\&VAL\&\&\&\&/ 1 /;
507 $val =~ s/\&\&\&\&VAL\&\&\&\&/ 0 /;
515 while ($val =~ s/^(.*?)($OR|$AND)//) {
519 if (process_expression($name, $express)) {
530 if ($val =~ /(.*)(==|\!=|>=|<=|>|<)(.*)/) {
531 my $ret = process_compare($1, $2, $3);
533 die "$name: $.: Unable to process comparison\n";
538 if ($val =~ /^\s*(NOT\s*)?DEFINED\s+(\S+)\s*$/) {
540 return !value_defined($2);
542 return value_defined($2);
546 if ($val =~ /^\s*0\s*$/) {
548 } elsif ($val =~ /^\s*\d+\s*$/) {
552 die ("$name: $.: Undefined content $val in if statement\n");
556 my ($name, $value) = @_;
558 # Convert variables and replace undefined ones with 0
559 my $val = process_variables($value, 1);
560 my $ret = process_expression $name, $val;
566 my ($config, $current_test_num) = @_;
569 open($in, $config) || die "can't read file $config";
572 $name =~ s,.*/(.*),$1,;
574 my $test_num = $$current_test_num;
577 my $num_tests_set = 0;
590 # ignore blank lines and comments
591 next if (/^\s*$/ || /\s*\#/);
593 if (/^\s*(TEST_START|DEFAULTS)\b(.*)/) {
603 if ($type eq "TEST_START") {
605 if ($num_tests_set) {
606 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
609 $old_test_num = $test_num;
610 $old_repeat = $repeat;
612 $test_num += $repeat;
619 # If SKIP is anywhere in the line, the command will be skipped
620 if ($rest =~ s/\s+SKIP\b//) {
627 if ($rest =~ s/\sELSE\b//) {
629 die "$name: $.: ELSE found with out matching IF section\n$_";
640 if ($rest =~ s/\sIF\s+(.*)//) {
641 if (process_if($name, $1)) {
653 if ($type eq "TEST_START") {
654 if ($rest =~ s/\s+ITERATE\s+(\d+)//) {
656 $repeat_tests{"$test_num"} = $repeat;
658 } elsif ($rest =~ s/\sOVERRIDE\b//) {
661 # Clear previous overrides
666 if (!$skip && $rest !~ /^\s*$/) {
667 die "$name: $.: Gargbage found after $type\n$_";
670 if ($skip && $type eq "TEST_START") {
671 $test_num = $old_test_num;
672 $repeat = $old_repeat;
675 } elsif (/^\s*ELSE\b(.*)$/) {
677 die "$name: $.: ELSE found with out matching IF section\n$_";
686 if ($rest =~ /\sIF\s+(.*)/) {
687 # May be a ELSE IF section.
688 if (!process_if($name, $1)) {
697 if ($rest !~ /^\s*$/) {
698 die "$name: $.: Gargbage found after DEFAULTS\n$_";
701 } elsif (/^\s*INCLUDE\s+(\S+)/) {
706 die "$name: $.: INCLUDE can only be done in default sections\n$_";
709 my $file = process_variables($1);
711 if ($file !~ m,^/,) {
712 # check the path of the config file first
713 if ($config =~ m,(.*)/,) {
721 die "$name: $.: Can't read file $file\n$_";
724 if (__read_config($file, \$test_num)) {
728 } elsif (/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) {
736 ($lvalue eq "NUM_TESTS" ||
737 $lvalue eq "LOG_FILE" ||
738 $lvalue eq "CLEAR_LOG")) {
739 die "$name: $.: $lvalue must be set in DEFAULTS section\n";
742 if ($lvalue eq "NUM_TESTS") {
744 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
747 die "$name: $.: NUM_TESTS must be set in default section\n";
752 if ($default || $lvalue =~ /\[\d+\]$/) {
753 set_value($lvalue, $rvalue, $override, \%overrides, $name);
755 my $val = "$lvalue\[$test_num\]";
756 set_value($val, $rvalue, $override, \%overrides, $name);
759 $repeats{$val} = $repeat;
762 } elsif (/^\s*([A-Z_\[\]\d]+)\s*:=\s*(.*?)\s*$/) {
768 # process config variables.
769 # Config variables are only active while reading the
770 # config and can be defined anywhere. They also ignore
771 # TEST_START and DEFAULTS, but are skipped if they are in
772 # on of these sections that have SKIP defined.
773 # The save variable can be
774 # defined multiple times and the new one simply overrides
776 set_variable($lvalue, $rvalue);
779 die "$name: $.: Garbage found in config\n$_";
784 $test_num += $repeat - 1;
785 $opt{"NUM_TESTS"} = $test_num;
790 $$current_test_num = $test_num;
796 print "What test case would you like to run?\n";
797 print " (build, install or boot)\n";
798 print " Other tests are available but require editing the config file\n";
801 $default{"TEST_TYPE"} = $ans;
810 $test_case = __read_config $config, \$test_num;
812 # make sure we have all mandatory configs
815 # was a test specified?
817 print "No test case specified.\n";
823 foreach my $default (keys %default) {
824 if (!defined($opt{$default})) {
825 $opt{$default} = $default{$default};
831 my ($option, $i) = @_;
833 # Add space to evaluate the character before $
834 $option = " $option";
839 foreach my $test (keys %repeat_tests) {
841 $i < $test + $repeat_tests{$test}) {
849 while ($option =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
854 # Append beginning of line
855 $retval = "$retval$start";
857 # If the iteration option OPT[$i] exists, then use that.
858 # otherwise see if the default OPT (without [$i]) exists.
860 my $o = "$var\[$i\]";
861 my $parento = "$var\[$parent\]";
863 if (defined($opt{$o})) {
865 $retval = "$retval$o";
866 } elsif ($repeated && defined($opt{$parento})) {
868 $retval = "$retval$o";
869 } elsif (defined($opt{$var})) {
871 $retval = "$retval$o";
873 $retval = "$retval\$\{$var\}";
879 $retval = "$retval$option";
887 my ($option, $i) = @_;
891 # Since an option can evaluate to another option,
892 # keep iterating until we do not evaluate any more
895 while ($prev ne $option) {
896 # Check for recursive evaluations.
897 # 100 deep should be more than enough.
899 die "Over 100 evaluations accurred with $option\n" .
900 "Check for recursive variables\n";
903 $option = __eval_option($option, $i);
910 if (defined($opt{"LOG_FILE"})) {
911 open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}";
918 if (defined($opt{"LOG_FILE"})) {
933 sub wait_for_monitor;
938 if (defined($time)) {
940 # flush out current monitor
941 # May contain the reboot success line
945 # try to reboot normally
946 if (run_command $reboot) {
947 if (defined($powercycle_after_reboot)) {
948 sleep $powercycle_after_reboot;
949 run_command "$power_cycle";
952 # nope? power cycle it.
953 run_command "$power_cycle";
956 if (defined($time)) {
957 wait_for_monitor($time, $reboot_success_line);
965 return $test_type eq "build" || $no_reboot ||
966 ($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") ||
967 ($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build");
971 doprint "CRITICAL FAILURE... ", @_, "\n";
975 if ($reboot_on_error && !do_not_reboot) {
977 doprint "REBOOTING\n";
980 } elsif ($poweroff_on_error && defined($power_off)) {
981 doprint "POWERING OFF\n";
985 if (defined($opt{"LOG_FILE"})) {
986 print " See $opt{LOG_FILE} for more info.\n";
997 my $pid = open($fp, "$console|") or
998 dodie "Can't open console $console";
1000 $flags = fcntl($fp, F_GETFL, 0) or
1001 dodie "Can't get flags for the socket: $!";
1002 $flags = fcntl($fp, F_SETFL, $flags | O_NONBLOCK) or
1003 dodie "Can't set flags for the socket: $!";
1009 my ($fp, $pid) = @_;
1011 doprint "kill child process $pid\n";
1019 if ($monitor_cnt++) {
1022 $monitor_fp = \*MONFD;
1023 $monitor_pid = open_console $monitor_fp;
1027 open(MONFD, "Stop perl from warning about single use of MONFD");
1031 if (--$monitor_cnt) {
1034 close_console($monitor_fp, $monitor_pid);
1037 sub wait_for_monitor {
1038 my ($time, $stop) = @_;
1043 doprint "** Wait for monitor to settle down **\n";
1045 # read the monitor and wait for the system to calm down
1047 $line = wait_for_input($monitor_fp, $time);
1048 last if (!defined($line));
1050 $full_line .= $line;
1052 if (defined($stop) && $full_line =~ /$stop/) {
1053 doprint "wait for monitor detected $stop\n";
1057 if ($line =~ /\n/) {
1061 print "** Monitor flushed **\n";
1065 my ($result, $basedir) = @_;
1067 my $date = sprintf "%04d%02d%02d%02d%02d%02d",
1068 1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0];
1070 my $type = $build_type;
1071 if ($type =~ /useconfig/) {
1072 $type = "useconfig";
1075 my $dir = "$machine-$test_type-$type-$result-$date";
1077 $dir = "$basedir/$dir";
1081 die "can't create $dir";
1085 "config" => $output_config,
1086 "buildlog" => $buildlog,
1088 "testlog" => $testlog,
1091 while (my ($name, $source) = each(%files)) {
1093 cp "$source", "$dir/$name" or
1094 die "failed to copy $source";
1098 doprint "*** Saved info to $dir ***\n";
1103 if ($die_on_failure) {
1111 # no need to reboot for just building.
1112 if (!do_not_reboot) {
1113 doprint "REBOOTING\n";
1119 if (defined($test_name)) {
1120 $name = " ($test_name)";
1123 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1124 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1125 doprint "KTEST RESULT: TEST $i$name Failed: ", @_, "\n";
1126 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1127 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
1129 if (defined($store_failures)) {
1130 save_logs "fail", $store_failures;
1142 $command =~ s/\$SSH_USER/$ssh_user/g;
1143 $command =~ s/\$MACHINE/$machine/g;
1145 doprint("$command ... ");
1147 $pid = open(CMD, "$command 2>&1 |") or
1148 (fail "unable to exec $command" and return 0);
1150 if (defined($opt{"LOG_FILE"})) {
1151 open(LOG, ">>$opt{LOG_FILE}") or
1152 dodie "failed to write to log";
1156 if (defined($redirect)) {
1157 open (RD, ">$redirect") or
1158 dodie "failed to write to redirect $redirect";
1163 print LOG if ($dolog);
1164 print RD if ($dord);
1171 close(LOG) if ($dolog);
1172 close(RD) if ($dord);
1175 doprint "FAILED!\n";
1177 doprint "SUCCESS\n";
1185 my $cp_exec = $ssh_exec;
1187 $cp_exec =~ s/\$SSH_COMMAND/$cmd/g;
1188 return run_command "$cp_exec";
1192 my ($src, $dst) = @_;
1193 my $cp_scp = $scp_to_target;
1195 $cp_scp =~ s/\$SRC_FILE/$src/g;
1196 $cp_scp =~ s/\$DST_FILE/$dst/g;
1198 return run_command "$cp_scp";
1201 sub get_grub_index {
1203 if ($reboot_type ne "grub") {
1206 return if (defined($grub_number));
1208 doprint "Find grub menu ... ";
1211 my $ssh_grub = $ssh_exec;
1212 $ssh_grub =~ s,\$SSH_COMMAND,cat /boot/grub/menu.lst,g;
1214 open(IN, "$ssh_grub |")
1215 or die "unable to get menu.lst";
1220 if (/^\s*title\s+$grub_menu\s*$/) {
1224 } elsif (/^\s*title\s/) {
1230 die "Could not find '$grub_menu' in /boot/grub/menu on $machine"
1232 doprint "$grub_number\n";
1237 my ($fp, $time) = @_;
1243 if (!defined($time)) {
1248 vec($rin, fileno($fp), 1) = 1;
1249 $ready = select($rin, undef, undef, $time);
1253 # try to read one char at a time
1254 while (sysread $fp, $ch, 1) {
1256 last if ($ch eq "\n");
1259 if (!length($line)) {
1267 if ($reboot_type eq "grub") {
1268 run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch)'";
1273 run_command "$reboot_script";
1279 doprint "git rev-list --max-count=1 $commit ... ";
1280 my $sha1 = `git rev-list --max-count=1 $commit`;
1287 dodie "Failed to get git $commit";
1300 my $skip_call_trace = 0;
1308 open(DMESG, "> $dmesg") or
1309 die "unable to write to $dmesg";
1315 my $monitor_start = time;
1317 my $version_found = 0;
1321 if ($bug && defined($stop_after_failure) &&
1322 $stop_after_failure >= 0) {
1323 my $time = $stop_after_failure - (time - $failure_start);
1324 $line = wait_for_input($monitor_fp, $time);
1325 if (!defined($line)) {
1326 doprint "bug timed out after $booted_timeout seconds\n";
1327 doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
1331 $line = wait_for_input($monitor_fp, $booted_timeout);
1332 if (!defined($line)) {
1333 my $s = $booted_timeout == 1 ? "" : "s";
1334 doprint "Successful boot found: break after $booted_timeout second$s\n";
1338 $line = wait_for_input($monitor_fp);
1339 if (!defined($line)) {
1340 my $s = $timeout == 1 ? "" : "s";
1341 doprint "Timed out after $timeout second$s\n";
1349 # we are not guaranteed to get a full line
1350 $full_line .= $line;
1352 if ($full_line =~ /$success_line/) {
1354 $success_start = time;
1357 if ($booted && defined($stop_after_success) &&
1358 $stop_after_success >= 0) {
1360 if ($now - $success_start >= $stop_after_success) {
1361 doprint "Test forced to stop after $stop_after_success seconds after success\n";
1366 if ($full_line =~ /\[ backtrace testing \]/) {
1367 $skip_call_trace = 1;
1370 if ($full_line =~ /call trace:/i) {
1371 if (!$bug && !$skip_call_trace) {
1373 $failure_start = time;
1377 if ($bug && defined($stop_after_failure) &&
1378 $stop_after_failure >= 0) {
1380 if ($now - $failure_start >= $stop_after_failure) {
1381 doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
1386 if ($full_line =~ /\[ end of backtrace testing \]/) {
1387 $skip_call_trace = 0;
1390 if ($full_line =~ /Kernel panic -/) {
1391 $failure_start = time;
1395 # Detect triple faults by testing the banner
1396 if ($full_line =~ /\bLinux version (\S+).*\n/) {
1397 if ($1 eq $version) {
1399 } elsif ($version_found && $detect_triplefault) {
1400 # We already booted into the kernel we are testing,
1401 # but now we booted into another kernel?
1402 # Consider this a triple fault.
1403 doprint "Aleady booted in Linux kernel $version, but now\n";
1404 doprint "we booted into Linux kernel $1.\n";
1405 doprint "Assuming that this is a triple fault.\n";
1406 doprint "To disable this: set DETECT_TRIPLE_FAULT to 0\n";
1411 if ($line =~ /\n/) {
1415 if ($stop_test_after > 0 && !$booted && !$bug) {
1416 if (time - $monitor_start > $stop_test_after) {
1417 doprint "STOP_TEST_AFTER ($stop_test_after seconds) timed out\n";
1426 return 0 if ($in_bisect);
1427 fail "failed - got a bug report" and return 0;
1431 return 0 if ($in_bisect);
1432 fail "failed - never got a boot prompt." and return 0;
1438 sub eval_kernel_version {
1441 $option =~ s/\$KERNEL_VERSION/$version/g;
1446 sub do_post_install {
1448 return if (!defined($post_install));
1450 my $cp_post_install = eval_kernel_version $post_install;
1451 run_command "$cp_post_install" or
1452 dodie "Failed to run post install";
1457 return if ($no_install);
1459 my $cp_target = eval_kernel_version $target_image;
1461 run_scp "$outputdir/$build_target", "$cp_target" or
1462 dodie "failed to copy image";
1464 my $install_mods = 0;
1466 # should we process modules?
1468 open(IN, "$output_config") or dodie("Can't read config file");
1470 if (/CONFIG_MODULES(=y)?/) {
1471 $install_mods = 1 if (defined($1));
1477 if (!$install_mods) {
1479 doprint "No modules needed\n";
1483 run_command "$make INSTALL_MOD_PATH=$tmpdir modules_install" or
1484 dodie "Failed to install modules";
1486 my $modlib = "/lib/modules/$version";
1487 my $modtar = "ktest-mods.tar.bz2";
1489 run_ssh "rm -rf $modlib" or
1490 dodie "failed to remove old mods: $modlib";
1492 # would be nice if scp -r did not follow symbolic links
1493 run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or
1494 dodie "making tarball";
1496 run_scp "$tmpdir/$modtar", "/tmp" or
1497 dodie "failed to copy modules";
1499 unlink "$tmpdir/$modtar";
1501 run_ssh "'(cd / && tar xjf /tmp/$modtar)'" or
1502 dodie "failed to tar modules";
1504 run_ssh "rm -f /tmp/$modtar";
1510 # get the release name
1511 doprint "$make kernelrelease ... ";
1512 $version = `$make kernelrelease | tail -1`;
1514 doprint "$version\n";
1517 sub start_monitor_and_boot {
1518 # Make sure the stable kernel has finished booting
1531 sub check_buildlog {
1534 my @files = `git show $patch | diffstat -l`;
1536 open(IN, "git show $patch |") or
1537 dodie "failed to show $patch";
1539 if (m,^--- a/(.*),) {
1541 $files[$#files] = $1;
1546 open(IN, $buildlog) or dodie "Can't open $buildlog";
1548 if (/^\s*(.*?):.*(warning|error)/) {
1550 foreach my $file (@files) {
1551 my $fullpath = "$builddir/$file";
1552 if ($file eq $err || $fullpath eq $err) {
1553 fail "$file built with warnings" and return 0;
1563 sub apply_min_config {
1564 my $outconfig = "$output_config.new";
1566 # Read the config file and remove anything that
1567 # is in the force_config hash (from minconfig and others)
1568 # then add the force config back.
1570 doprint "Applying minimum configurations into $output_config.new\n";
1572 open (OUT, ">$outconfig") or
1573 dodie "Can't create $outconfig";
1575 if (-f $output_config) {
1576 open (IN, $output_config) or
1577 dodie "Failed to open $output_config";
1579 if (/^(# )?(CONFIG_[^\s=]*)/) {
1580 next if (defined($force_config{$2}));
1586 foreach my $config (keys %force_config) {
1587 print OUT "$force_config{$config}\n";
1591 run_command "mv $outconfig $output_config";
1594 sub make_oldconfig {
1596 my @force_list = keys %force_config;
1598 if ($#force_list >= 0) {
1602 if (!run_command "$make oldnoconfig") {
1603 # Perhaps oldnoconfig doesn't exist in this version of the kernel
1604 # try a yes '' | oldconfig
1605 doprint "oldnoconfig failed, trying yes '' | make oldconfig\n";
1606 run_command "yes '' | $make oldconfig" or
1607 dodie "failed make config oldconfig";
1611 # read a config file and use this to force new configs.
1612 sub load_force_config {
1615 open(IN, $config) or
1616 dodie "failed to read $config";
1619 if (/^(CONFIG[^\s=]*)(\s*=.*)/) {
1620 $force_config{$1} = $_;
1621 } elsif (/^# (CONFIG_\S*) is not set/) {
1622 $force_config{$1} = $_;
1633 # Failed builds should not reboot the target
1634 my $save_no_reboot = $no_reboot;
1637 if (defined($pre_build)) {
1638 my $ret = run_command $pre_build;
1639 if (!$ret && defined($pre_build_die) &&
1641 dodie "failed to pre_build\n";
1645 if ($type =~ /^useconfig:(.*)/) {
1646 run_command "cp $1 $output_config" or
1647 dodie "could not copy $1 to .config";
1649 $type = "oldconfig";
1652 # old config can ask questions
1653 if ($type eq "oldconfig") {
1654 $type = "oldnoconfig";
1656 # allow for empty configs
1657 run_command "touch $output_config";
1660 run_command "mv $output_config $outputdir/config_temp" or
1661 dodie "moving .config";
1663 run_command "$make mrproper" or dodie "make mrproper";
1665 run_command "mv $outputdir/config_temp $output_config" or
1666 dodie "moving config_temp";
1669 } elsif (!$noclean) {
1670 unlink "$output_config";
1671 run_command "$make mrproper" or
1672 dodie "make mrproper";
1675 # add something to distinguish this build
1676 open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file");
1677 print OUT "$localversion\n";
1680 if (defined($minconfig)) {
1681 load_force_config($minconfig);
1684 if ($type ne "oldnoconfig") {
1685 run_command "$make $type" or
1686 dodie "failed make config";
1688 # Run old config regardless, to enforce min configurations
1691 $redirect = "$buildlog";
1692 my $build_ret = run_command "$make $build_options";
1695 if (defined($post_build)) {
1696 my $ret = run_command $post_build;
1697 if (!$ret && defined($post_build_die) &&
1699 dodie "failed to post_build\n";
1704 # bisect may need this to pass
1706 $no_reboot = $save_no_reboot;
1709 fail "failed build" and return 0;
1712 $no_reboot = $save_no_reboot;
1718 if (!run_ssh "halt" or defined($power_off)) {
1719 if (defined($poweroff_after_halt)) {
1720 sleep $poweroff_after_halt;
1721 run_command "$power_off";
1725 run_command "$power_off";
1736 if (defined($test_name)) {
1737 $name = " ($test_name)";
1740 doprint "\n\n*******************************************\n";
1741 doprint "*******************************************\n";
1742 doprint "KTEST RESULT: TEST $i$name SUCCESS!!!! **\n";
1743 doprint "*******************************************\n";
1744 doprint "*******************************************\n";
1746 if (defined($store_successes)) {
1747 save_logs "success", $store_successes;
1750 if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) {
1751 doprint "Reboot and wait $sleep_time seconds\n";
1758 doprint "Pass or fail? [p/f]";
1761 if ($ans eq "p" || $ans eq "P") {
1763 } elsif ($ans eq "f" || $ans eq "F") {
1766 print "Please answer 'P' or 'F'\n";
1771 sub child_run_test {
1774 # child should have no power
1775 $reboot_on_error = 0;
1776 $poweroff_on_error = 0;
1777 $die_on_failure = 1;
1779 $redirect = "$testlog";
1780 run_command $run_test or $failed = 1;
1788 sub child_finished {
1801 doprint "run test $run_test\n";
1805 $SIG{CHLD} = qw(child_finished);
1809 child_run_test if (!$child_pid);
1814 $line = wait_for_input($monitor_fp, 1);
1815 if (defined($line)) {
1817 # we are not guaranteed to get a full line
1818 $full_line .= $line;
1821 if ($full_line =~ /call trace:/i) {
1825 if ($full_line =~ /Kernel panic -/) {
1829 if ($line =~ /\n/) {
1833 } while (!$child_done && !$bug);
1836 my $failure_start = time;
1839 $line = wait_for_input($monitor_fp, 1);
1840 if (defined($line)) {
1844 if ($now - $failure_start >= $stop_after_failure) {
1847 } while (defined($line));
1849 doprint "Detected kernel crash!\n";
1850 # kill the child with extreme prejudice
1854 waitpid $child_pid, 0;
1857 if ($bug || $child_exit) {
1858 return 0 if $in_bisect;
1859 fail "test failed" and return 0;
1864 sub run_git_bisect {
1867 doprint "$command ... ";
1869 my $output = `$command 2>&1`;
1876 dodie "Failed to git bisect";
1879 doprint "SUCCESS\n";
1880 if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) {
1881 doprint "$1 [$2]\n";
1882 } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) {
1884 doprint "Found bad commit... $1\n";
1887 # we already logged it, just print it now.
1895 doprint "Reboot and sleep $bisect_sleep_time seconds\n";
1896 reboot $bisect_sleep_time;
1899 # returns 1 on success, 0 on failure, -1 on skip
1900 sub run_bisect_test {
1901 my ($type, $buildtype) = @_;
1910 build $buildtype or $failed = 1;
1912 if ($type ne "build") {
1913 if ($failed && $bisect_skip) {
1917 dodie "Failed on build" if $failed;
1920 start_monitor_and_boot or $failed = 1;
1922 if ($type ne "boot") {
1923 if ($failed && $bisect_skip) {
1929 dodie "Failed on boot" if $failed;
1931 do_run_test or $failed = 1;
1942 # reboot the box to a kernel we can ssh to
1943 if ($type ne "build") {
1953 my $buildtype = "oldconfig";
1955 # We should have a minconfig to use?
1956 if (defined($minconfig)) {
1957 $buildtype = "useconfig:$minconfig";
1960 my $ret = run_bisect_test $type, $buildtype;
1962 if ($bisect_manual) {
1963 $ret = answer_bisect;
1966 # Are we looking for where it worked, not failed?
1967 if ($reverse_bisect) {
1973 } elsif ($ret == 0) {
1975 } elsif ($bisect_skip) {
1976 doprint "HIT A BAD COMMIT ... SKIPPING\n";
1981 sub update_bisect_replay {
1982 my $tmp_log = "$tmpdir/ktest_bisect_log";
1983 run_command "git bisect log > $tmp_log" or
1984 die "can't create bisect log";
1993 die "BISECT_GOOD[$i] not defined\n" if (!defined($opt{"BISECT_GOOD[$i]"}));
1994 die "BISECT_BAD[$i] not defined\n" if (!defined($opt{"BISECT_BAD[$i]"}));
1995 die "BISECT_TYPE[$i] not defined\n" if (!defined($opt{"BISECT_TYPE[$i]"}));
1997 my $good = $opt{"BISECT_GOOD[$i]"};
1998 my $bad = $opt{"BISECT_BAD[$i]"};
1999 my $type = $opt{"BISECT_TYPE[$i]"};
2000 my $start = $opt{"BISECT_START[$i]"};
2001 my $replay = $opt{"BISECT_REPLAY[$i]"};
2002 my $start_files = $opt{"BISECT_FILES[$i]"};
2004 if (defined($start_files)) {
2005 $start_files = " -- " . $start_files;
2010 # convert to true sha1's
2011 $good = get_sha1($good);
2012 $bad = get_sha1($bad);
2014 if (defined($opt{"BISECT_REVERSE[$i]"}) &&
2015 $opt{"BISECT_REVERSE[$i]"} == 1) {
2016 doprint "Performing a reverse bisect (bad is good, good is bad!)\n";
2017 $reverse_bisect = 1;
2019 $reverse_bisect = 0;
2022 # Can't have a test without having a test to run
2023 if ($type eq "test" && !defined($run_test)) {
2027 # Check if a bisect was running
2028 my $bisect_start_file = "$builddir/.git/BISECT_START";
2030 my $check = $opt{"BISECT_CHECK[$i]"};
2031 my $do_check = defined($check) && $check ne "0";
2033 if ( -f $bisect_start_file ) {
2034 print "Bisect in progress found\n";
2036 print " If you say yes, then no checks of good or bad will be done\n";
2038 if (defined($replay)) {
2039 print "** BISECT_REPLAY is defined in config file **";
2040 print " Ignore config option and perform new git bisect log?\n";
2041 if (read_ync " (yes, no, or cancel) ") {
2042 $replay = update_bisect_replay;
2045 } elsif (read_yn "read git log and continue?") {
2046 $replay = update_bisect_replay;
2054 my $head = get_sha1("HEAD");
2056 if ($check ne "good") {
2057 doprint "TESTING BISECT BAD [$bad]\n";
2058 run_command "git checkout $bad" or
2059 die "Failed to checkout $bad";
2061 $result = run_bisect $type;
2063 if ($result ne "bad") {
2064 fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0;
2068 if ($check ne "bad") {
2069 doprint "TESTING BISECT GOOD [$good]\n";
2070 run_command "git checkout $good" or
2071 die "Failed to checkout $good";
2073 $result = run_bisect $type;
2075 if ($result ne "good") {
2076 fail "Tested BISECT_GOOD [$good] and it failed" and return 0;
2080 # checkout where we started
2081 run_command "git checkout $head" or
2082 die "Failed to checkout $head";
2085 run_command "git bisect start$start_files" or
2086 dodie "could not start bisect";
2088 run_command "git bisect good $good" or
2089 dodie "could not set bisect good to $good";
2091 run_git_bisect "git bisect bad $bad" or
2092 dodie "could not set bisect bad to $bad";
2094 if (defined($replay)) {
2095 run_command "git bisect replay $replay" or
2096 dodie "failed to run replay";
2099 if (defined($start)) {
2100 run_command "git checkout $start" or
2101 dodie "failed to checkout $start";
2106 $result = run_bisect $type;
2107 $test = run_git_bisect "git bisect $result";
2110 run_command "git bisect log" or
2111 dodie "could not capture git bisect log";
2113 run_command "git bisect reset" or
2114 dodie "could not reset git bisect";
2116 doprint "Bad commit was [$bisect_bad]\n";
2129 sub assign_configs {
2130 my ($hash, $config) = @_;
2133 or dodie "Failed to read $config";
2136 if (/^((CONFIG\S*)=.*)/) {
2144 sub process_config_ignore {
2147 assign_configs \%config_ignore, $config;
2150 sub read_current_config {
2151 my ($config_ref) = @_;
2153 %{$config_ref} = ();
2154 undef %{$config_ref};
2156 my @key = keys %{$config_ref};
2158 print "did not delete!\n";
2161 open (IN, "$output_config");
2164 if (/^(CONFIG\S+)=(.*)/) {
2165 ${$config_ref}{$1} = $2;
2171 sub get_dependencies {
2174 my $arr = $dependency{$config};
2175 if (!defined($arr)) {
2181 foreach my $dep (@{$arr}) {
2182 print "ADD DEP $dep\n";
2183 @deps = (@deps, get_dependencies $dep);
2192 open(OUT, ">$output_config") or dodie "Can not write to $output_config";
2194 foreach my $config (@configs) {
2195 print OUT "$config_set{$config}\n";
2196 my @deps = get_dependencies $config;
2197 foreach my $dep (@deps) {
2198 print OUT "$config_set{$dep}\n";
2202 foreach my $config (keys %config_ignore) {
2203 print OUT "$config_ignore{$config}\n";
2211 sub compare_configs {
2214 foreach my $item (keys %a) {
2215 if (!defined($b{$item})) {
2216 print "diff $item\n";
2224 print "diff2 $keys[0]\n";
2226 return -1 if ($#keys >= 0);
2231 sub run_config_bisect_test {
2234 return run_bisect_test $type, "oldconfig";
2237 sub process_passed {
2240 doprint "These configs had no failure: (Enabling them for further compiles)\n";
2241 # Passed! All these configs are part of a good compile.
2242 # Add them to the min options.
2243 foreach my $config (keys %configs) {
2244 if (defined($config_list{$config})) {
2245 doprint " removing $config\n";
2246 $config_ignore{$config} = $config_list{$config};
2247 delete $config_list{$config};
2250 doprint "config copied to $outputdir/config_good\n";
2251 run_command "cp -f $output_config $outputdir/config_good";
2254 sub process_failed {
2257 doprint "\n\n***************************************\n";
2258 doprint "Found bad config: $config\n";
2259 doprint "***************************************\n\n";
2262 sub run_config_bisect {
2264 my @start_list = keys %config_list;
2266 if ($#start_list < 0) {
2267 doprint "No more configs to test!!!\n";
2271 doprint "***** RUN TEST ***\n";
2272 my $type = $opt{"CONFIG_BISECT_TYPE[$iteration]"};
2276 my $count = $#start_list + 1;
2277 doprint " $count configs to test\n";
2279 my $half = int($#start_list / 2);
2282 my @tophalf = @start_list[0 .. $half];
2284 create_config @tophalf;
2285 read_current_config \%current_config;
2287 $count = $#tophalf + 1;
2288 doprint "Testing $count configs\n";
2290 # make sure we test something
2291 foreach my $config (@tophalf) {
2292 if (defined($current_config{$config})) {
2298 # try the other half
2299 doprint "Top half produced no set configs, trying bottom half\n";
2300 @tophalf = @start_list[$half + 1 .. $#start_list];
2301 create_config @tophalf;
2302 read_current_config \%current_config;
2303 foreach my $config (@tophalf) {
2304 if (defined($current_config{$config})) {
2310 doprint "Failed: Can't make new config with current configs\n";
2311 foreach my $config (@start_list) {
2312 doprint " CONFIG: $config\n";
2316 $count = $#tophalf + 1;
2317 doprint "Testing $count configs\n";
2320 $ret = run_config_bisect_test $type;
2321 if ($bisect_manual) {
2322 $ret = answer_bisect;
2325 process_passed %current_config;
2329 doprint "This config had a failure.\n";
2330 doprint "Removing these configs that were not set in this config:\n";
2331 doprint "config copied to $outputdir/config_bad\n";
2332 run_command "cp -f $output_config $outputdir/config_bad";
2334 # A config exists in this group that was bad.
2335 foreach my $config (keys %config_list) {
2336 if (!defined($current_config{$config})) {
2337 doprint " removing $config\n";
2338 delete $config_list{$config};
2342 @start_list = @tophalf;
2344 if ($#start_list == 0) {
2345 process_failed $start_list[0];
2349 # remove half the configs we are looking at and see if
2351 $half = int($#start_list / 2);
2352 } while ($#start_list > 0);
2354 # we found a single config, try it again unless we are running manually
2356 if ($bisect_manual) {
2357 process_failed $start_list[0];
2361 my @tophalf = @start_list[0 .. 0];
2363 $ret = run_config_bisect_test $type;
2365 process_passed %current_config;
2369 process_failed $start_list[0];
2376 my $start_config = $opt{"CONFIG_BISECT[$i]"};
2378 my $tmpconfig = "$tmpdir/use_config";
2380 if (defined($config_bisect_good)) {
2381 process_config_ignore $config_bisect_good;
2384 # Make the file with the bad config and the min config
2385 if (defined($minconfig)) {
2386 # read the min config for things to ignore
2387 run_command "cp $minconfig $tmpconfig" or
2388 dodie "failed to copy $minconfig to $tmpconfig";
2393 if (-f $tmpconfig) {
2394 load_force_config($tmpconfig);
2395 process_config_ignore $tmpconfig;
2398 # now process the start config
2399 run_command "cp $start_config $output_config" or
2400 dodie "failed to copy $start_config to $output_config";
2402 # read directly what we want to check
2404 open (IN, $output_config)
2405 or dodie "faied to open $output_config";
2408 if (/^((CONFIG\S*)=.*)/) {
2409 $config_check{$2} = $1;
2414 # Now run oldconfig with the minconfig
2417 # check to see what we lost (or gained)
2418 open (IN, $output_config)
2419 or dodie "Failed to read $start_config";
2421 my %removed_configs;
2425 if (/^((CONFIG\S*)=.*)/) {
2426 # save off all options
2427 $config_set{$2} = $1;
2428 if (defined($config_check{$2})) {
2429 if (defined($config_ignore{$2})) {
2430 $removed_configs{$2} = $1;
2432 $config_list{$2} = $1;
2434 } elsif (!defined($config_ignore{$2})) {
2435 $added_configs{$2} = $1;
2436 $config_list{$2} = $1;
2442 my @confs = keys %removed_configs;
2444 doprint "Configs overridden by default configs and removed from check:\n";
2445 foreach my $config (@confs) {
2446 doprint " $config\n";
2449 @confs = keys %added_configs;
2451 doprint "Configs appearing in make oldconfig and added:\n";
2452 foreach my $config (@confs) {
2453 doprint " $config\n";
2460 # Sometimes kconfig does weird things. We must make sure
2461 # that the config we autocreate has everything we need
2462 # to test, otherwise we may miss testing configs, or
2463 # may not be able to create a new config.
2464 # Here we create a config with everything set.
2465 create_config (keys %config_list);
2466 read_current_config \%config_test;
2467 foreach my $config (keys %config_list) {
2468 if (!defined($config_test{$config})) {
2471 doprint "Configs not produced by kconfig (will not be checked):\n";
2473 doprint " $config\n";
2474 delete $config_list{$config};
2479 $ret = run_config_bisect;
2482 return $ret if ($ret < 0);
2487 sub patchcheck_reboot {
2488 doprint "Reboot and sleep $patchcheck_sleep_time seconds\n";
2489 reboot $patchcheck_sleep_time;
2495 die "PATCHCHECK_START[$i] not defined\n"
2496 if (!defined($opt{"PATCHCHECK_START[$i]"}));
2497 die "PATCHCHECK_TYPE[$i] not defined\n"
2498 if (!defined($opt{"PATCHCHECK_TYPE[$i]"}));
2500 my $start = $opt{"PATCHCHECK_START[$i]"};
2503 if (defined($opt{"PATCHCHECK_END[$i]"})) {
2504 $end = $opt{"PATCHCHECK_END[$i]"};
2507 # Get the true sha1's since we can use things like HEAD~3
2508 $start = get_sha1($start);
2509 $end = get_sha1($end);
2511 my $type = $opt{"PATCHCHECK_TYPE[$i]"};
2513 # Can't have a test without having a test to run
2514 if ($type eq "test" && !defined($run_test)) {
2518 open (IN, "git log --pretty=oneline $end|") or
2519 dodie "could not get git list";
2525 $list[$#list+1] = $_;
2526 last if (/^$start/);
2530 if ($list[$#list] !~ /^$start/) {
2531 fail "SHA1 $start not found";
2534 # go backwards in the list
2535 @list = reverse @list;
2537 my $save_clean = $noclean;
2538 my %ignored_warnings;
2540 if (defined($ignore_warnings)) {
2541 foreach my $sha1 (split /\s+/, $ignore_warnings) {
2542 $ignored_warnings{$sha1} = 1;
2547 foreach my $item (@list) {
2549 $sha1 =~ s/^([[:xdigit:]]+).*/$1/;
2551 doprint "\nProcessing commit $item\n\n";
2553 run_command "git checkout $sha1" or
2554 die "Failed to checkout $sha1";
2556 # only clean on the first and last patch
2557 if ($item eq $list[0] ||
2558 $item eq $list[$#list]) {
2559 $noclean = $save_clean;
2564 if (defined($minconfig)) {
2565 build "useconfig:$minconfig" or return 0;
2567 # ?? no config to use?
2568 build "oldconfig" or return 0;
2572 if (!defined($ignored_warnings{$sha1})) {
2573 check_buildlog $sha1 or return 0;
2576 next if ($type eq "build");
2580 start_monitor_and_boot or $failed = 1;
2582 if (!$failed && $type ne "boot"){
2583 do_run_test or $failed = 1;
2586 return 0 if ($failed);
2606 # $config depends on $dep
2607 my ($config, $dep) = @_;
2609 if (defined($depends{$config})) {
2610 $depends{$config} .= " " . $dep;
2612 $depends{$config} = $dep;
2615 # record the number of configs depending on $dep
2616 if (defined $depcount{$dep}) {
2619 $depcount{$dep} = 1;
2623 # taken from streamline_config.pl
2635 if (! -f $kconfig) {
2636 doprint "file $kconfig does not exist, skipping\n";
2640 open(KIN, "$kconfig")
2641 or die "Can't open $kconfig";
2645 # Make sure that lines ending with \ continue
2647 $_ = $line . " " . $_;
2658 # collect any Kconfig sources
2659 if (/^source\s*"(.*)"/) {
2660 $kconfigs[$#kconfigs+1] = $1;
2664 if (/^\s*(menu)?config\s+(\S+)\s*$/) {
2668 for (my $i = 0; $i < $iflevel; $i++) {
2669 add_dep $config, $ifdeps[$i];
2672 # collect the depends for the config
2673 } elsif ($state eq "NEW" && /^\s*depends\s+on\s+(.*)$/) {
2675 add_dep $config, $1;
2677 # Get the configs that select this config
2678 } elsif ($state eq "NEW" && /^\s*select\s+(\S+)/) {
2680 # selected by depends on config
2681 add_dep $1, $config;
2683 # Check for if statements
2684 } elsif (/^if\s+(.*\S)\s*$/) {
2686 # remove beginning and ending non text
2687 $deps =~ s/^[^a-zA-Z0-9_]*//;
2688 $deps =~ s/[^a-zA-Z0-9_]*$//;
2690 my @deps = split /[^a-zA-Z0-9_]+/, $deps;
2692 $ifdeps[$iflevel++] = join ':', @deps;
2694 } elsif (/^endif/) {
2696 $iflevel-- if ($iflevel);
2699 } elsif (/^\s*help\s*$/) {
2705 # read in any configs that were found.
2706 foreach $kconfig (@kconfigs) {
2707 if (!defined($read_kconfigs{$kconfig})) {
2708 $read_kconfigs{$kconfig} = 1;
2709 read_kconfig("$builddir/$kconfig");
2715 # find out which arch this is by the kconfig file
2716 open (IN, $output_config)
2717 or dodie "Failed to read $output_config";
2720 if (m,Linux/(\S+)\s+\S+\s+Kernel Configuration,) {
2727 if (!defined($arch)) {
2728 doprint "Could not find arch from config file\n";
2729 doprint "no dependencies used\n";
2733 # arch is really the subarch, we need to know
2734 # what directory to look at.
2735 if ($arch eq "i386" || $arch eq "x86_64") {
2737 } elsif ($arch =~ /^tile/) {
2741 my $kconfig = "$builddir/arch/$arch/Kconfig";
2743 if (! -f $kconfig && $arch =~ /\d$/) {
2745 # some subarchs have numbers, truncate them
2747 $kconfig = "$builddir/arch/$arch/Kconfig";
2748 if (! -f $kconfig) {
2749 doprint "No idea what arch dir $orig is for\n";
2750 doprint "no dependencies used\n";
2755 read_kconfig($kconfig);
2758 sub read_config_list {
2762 or dodie "Failed to read $config";
2765 if (/^((CONFIG\S*)=.*)/) {
2766 if (!defined($config_ignore{$2})) {
2767 $config_list{$2} = $1;
2775 sub read_output_config {
2778 assign_configs \%config_ignore, $config;
2781 sub make_new_config {
2784 open (OUT, ">$output_config")
2785 or dodie "Failed to write $output_config";
2787 foreach my $config (@configs) {
2788 print OUT "$config\n";
2796 $config =~ s/CONFIG_//;
2804 my $kconfig = chomp_config $dep;
2806 $dep = $depends{"$kconfig"};
2808 # the dep string we have saves the dependencies as they
2809 # were found, including expressions like ! && ||. We
2810 # want to split this out into just an array of configs.
2812 my $valid = "A-Za-z_0-9";
2816 while ($dep =~ /[$valid]/) {
2818 if ($dep =~ /^[^$valid]*([$valid]+)/) {
2819 my $conf = "CONFIG_" . $1;
2821 $configs[$#configs + 1] = $conf;
2823 $dep =~ s/^[^$valid]*[$valid]+//;
2825 die "this should never happen";
2835 my %processed_configs;
2836 my %nochange_config;
2838 sub test_this_config {
2843 # if we already processed this config, skip it
2844 if (defined($processed_configs{$config})) {
2847 $processed_configs{$config} = 1;
2849 # if this config failed during this round, skip it
2850 if (defined($nochange_config{$config})) {
2854 my $kconfig = chomp_config $config;
2856 # Test dependencies first
2857 if (defined($depends{"$kconfig"})) {
2858 my @parents = get_depends $config;
2859 foreach my $parent (@parents) {
2860 # if the parent is in the min config, check it first
2861 next if (!defined($min_configs{$parent}));
2862 $found = test_this_config($parent);
2863 if (defined($found)) {
2869 # Remove this config from the list of configs
2870 # do a make oldnoconfig and then read the resulting
2871 # .config to make sure it is missing the config that
2873 my %configs = %min_configs;
2874 delete $configs{$config};
2875 make_new_config ((values %configs), (values %keep_configs));
2878 assign_configs \%configs, $output_config;
2880 return $config if (!defined($configs{$config}));
2882 doprint "disabling config $config did not change .config\n";
2884 $nochange_config{$config} = 1;
2889 sub make_min_config {
2892 if (!defined($output_minconfig)) {
2893 fail "OUTPUT_MIN_CONFIG not defined" and return;
2896 # If output_minconfig exists, and the start_minconfig
2897 # came from min_config, than ask if we should use
2899 if (-f $output_minconfig && !$start_minconfig_defined) {
2900 print "$output_minconfig exists\n";
2901 if (read_yn " Use it as minconfig?") {
2902 $start_minconfig = $output_minconfig;
2906 if (!defined($start_minconfig)) {
2907 fail "START_MIN_CONFIG or MIN_CONFIG not defined" and return;
2910 my $temp_config = "$tmpdir/temp_config";
2912 # First things first. We build an allnoconfig to find
2913 # out what the defaults are that we can't touch.
2914 # Some are selections, but we really can't handle selections.
2916 my $save_minconfig = $minconfig;
2919 run_command "$make allnoconfig" or return 0;
2923 process_config_ignore $output_config;
2925 undef %save_configs;
2928 if (defined($ignore_config)) {
2929 # make sure the file exists
2930 `touch $ignore_config`;
2931 assign_configs \%save_configs, $ignore_config;
2934 %keep_configs = %save_configs;
2936 doprint "Load initial configs from $start_minconfig\n";
2938 # Look at the current min configs, and save off all the
2939 # ones that were set via the allnoconfig
2940 assign_configs \%min_configs, $start_minconfig;
2942 my @config_keys = keys %min_configs;
2944 # All configs need a depcount
2945 foreach my $config (@config_keys) {
2946 my $kconfig = chomp_config $config;
2947 if (!defined $depcount{$kconfig}) {
2948 $depcount{$kconfig} = 0;
2952 # Remove anything that was set by the make allnoconfig
2953 # we shouldn't need them as they get set for us anyway.
2954 foreach my $config (@config_keys) {
2955 # Remove anything in the ignore_config
2956 if (defined($keep_configs{$config})) {
2957 my $file = $ignore_config;
2958 $file =~ s,.*/(.*?)$,$1,;
2959 doprint "$config set by $file ... ignored\n";
2960 delete $min_configs{$config};
2963 # But make sure the settings are the same. If a min config
2964 # sets a selection, we do not want to get rid of it if
2965 # it is not the same as what we have. Just move it into
2967 if (defined($config_ignore{$config})) {
2968 if ($config_ignore{$config} ne $min_configs{$config}) {
2969 doprint "$config is in allnoconfig as '$config_ignore{$config}'";
2970 doprint " but it is '$min_configs{$config}' in minconfig .. keeping\n";
2971 $keep_configs{$config} = $min_configs{$config};
2973 doprint "$config set by allnoconfig ... ignored\n";
2975 delete $min_configs{$config};
2987 # Now disable each config one by one and do a make oldconfig
2988 # till we find a config that changes our list.
2990 my @test_configs = keys %min_configs;
2992 # Sort keys by who is most dependent on
2993 @test_configs = sort { $depcount{chomp_config($b)} <=> $depcount{chomp_config($a)} }
2996 # Put configs that did not modify the config at the end.
2998 for (my $i = 0; $i < $#test_configs; $i++) {
2999 if (!defined($nochange_config{$test_configs[0]})) {
3003 # This config didn't change the .config last time.
3004 # Place it at the end
3005 my $config = shift @test_configs;
3006 push @test_configs, $config;
3009 # if every test config has failed to modify the .config file
3010 # in the past, then reset and start over.
3012 undef %nochange_config;
3015 undef %processed_configs;
3017 foreach my $config (@test_configs) {
3019 $found = test_this_config $config;
3021 last if (defined($found));
3023 # oh well, try another config
3026 if (!defined($found)) {
3027 # we could have failed due to the nochange_config hash
3028 # reset and try again
3030 undef %nochange_config;
3034 doprint "No more configs found that we can disable\n";
3042 doprint "Test with $config disabled\n";
3044 # set in_bisect to keep build and monitor from dieing
3049 start_monitor_and_boot or $failed = 1;
3055 doprint "$min_configs{$config} is needed to boot the box... keeping\n";
3056 # this config is needed, add it to the ignore list.
3057 $keep_configs{$config} = $min_configs{$config};
3058 $save_configs{$config} = $min_configs{$config};
3059 delete $min_configs{$config};
3061 # update new ignore configs
3062 if (defined($ignore_config)) {
3063 open (OUT, ">$temp_config")
3064 or die "Can't write to $temp_config";
3065 foreach my $config (keys %save_configs) {
3066 print OUT "$save_configs{$config}\n";
3069 run_command "mv $temp_config $ignore_config" or
3070 dodie "failed to copy update to $ignore_config";
3074 # We booted without this config, remove it from the minconfigs.
3075 doprint "$config is not needed, disabling\n";
3077 delete $min_configs{$config};
3079 # Also disable anything that is not enabled in this config
3081 assign_configs \%configs, $output_config;
3082 my @config_keys = keys %min_configs;
3083 foreach my $config (@config_keys) {
3084 if (!defined($configs{$config})) {
3085 doprint "$config is not set, disabling\n";
3086 delete $min_configs{$config};
3090 # Save off all the current mandidory configs
3091 open (OUT, ">$temp_config")
3092 or die "Can't write to $temp_config";
3093 foreach my $config (keys %keep_configs) {
3094 print OUT "$keep_configs{$config}\n";
3096 foreach my $config (keys %min_configs) {
3097 print OUT "$min_configs{$config}\n";
3101 run_command "mv $temp_config $output_minconfig" or
3102 dodie "failed to copy update to $output_minconfig";
3105 doprint "Reboot and wait $sleep_time seconds\n";
3113 $#ARGV < 1 or die "ktest.pl version: $VERSION\n usage: ktest.pl config-file\n";
3116 $ktest_config = $ARGV[0];
3117 if (! -f $ktest_config) {
3118 print "$ktest_config does not exist.\n";
3119 if (!read_yn "Create it?") {
3124 $ktest_config = "ktest.conf";
3127 if (! -f $ktest_config) {
3130 open(OUT, ">$ktest_config") or die "Can not create $ktest_config";
3132 # Generated by ktest.pl
3135 # PWD is a ktest.pl variable that will result in the process working
3136 # directory that ktest.pl is executed in.
3138 # THIS_DIR is automatically assigned the PWD of the path that generated
3139 # the config file. It is best to use this variable when assigning other
3140 # directory paths within this directory. This allows you to easily
3141 # move the test cases to other locations or to other machines.
3143 THIS_DIR := $variable{"PWD"}
3145 # Define each test with TEST_START
3146 # The config options below it will override the defaults
3148 TEST_TYPE = $default{"TEST_TYPE"}
3155 read_config $ktest_config;
3157 if (defined($opt{"LOG_FILE"})) {
3158 $opt{"LOG_FILE"} = eval_option($opt{"LOG_FILE"}, -1);
3161 # Append any configs entered in manually to the config file.
3162 my @new_configs = keys %entered_configs;
3163 if ($#new_configs >= 0) {
3164 print "\nAppending entered in configs to $ktest_config\n";
3165 open(OUT, ">>$ktest_config") or die "Can not append to $ktest_config";
3166 foreach my $config (@new_configs) {
3167 print OUT "$config = $entered_configs{$config}\n";
3168 $opt{$config} = process_variables($entered_configs{$config});
3172 if ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) {
3173 unlink $opt{"LOG_FILE"};
3176 doprint "\n\nSTARTING AUTOMATED TESTS\n\n";
3178 for (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) {
3181 doprint "DEFAULT OPTIONS:\n";
3183 doprint "\nTEST $i OPTIONS";
3184 if (defined($repeat_tests{$i})) {
3185 $repeat = $repeat_tests{$i};
3186 doprint " ITERATE $repeat";
3191 foreach my $option (sort keys %opt) {
3193 if ($option =~ /\[(\d+)\]$/) {
3199 doprint "$option = $opt{$option}\n";
3203 sub __set_test_option {
3204 my ($name, $i) = @_;
3206 my $option = "$name\[$i\]";
3208 if (defined($opt{$option})) {
3209 return $opt{$option};
3212 foreach my $test (keys %repeat_tests) {
3214 $i < $test + $repeat_tests{$test}) {
3215 $option = "$name\[$test\]";
3216 if (defined($opt{$option})) {
3217 return $opt{$option};
3222 if (defined($opt{$name})) {
3229 sub set_test_option {
3230 my ($name, $i) = @_;
3232 my $option = __set_test_option($name, $i);
3233 return $option if (!defined($option));
3235 return eval_option($option, $i);
3238 # First we need to do is the builds
3239 for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
3241 # Do not reboot on failing test options
3246 my $makecmd = set_test_option("MAKE_CMD", $i);
3248 $machine = set_test_option("MACHINE", $i);
3249 $ssh_user = set_test_option("SSH_USER", $i);
3250 $tmpdir = set_test_option("TMP_DIR", $i);
3251 $outputdir = set_test_option("OUTPUT_DIR", $i);
3252 $builddir = set_test_option("BUILD_DIR", $i);
3253 $test_type = set_test_option("TEST_TYPE", $i);
3254 $build_type = set_test_option("BUILD_TYPE", $i);
3255 $build_options = set_test_option("BUILD_OPTIONS", $i);
3256 $pre_build = set_test_option("PRE_BUILD", $i);
3257 $post_build = set_test_option("POST_BUILD", $i);
3258 $pre_build_die = set_test_option("PRE_BUILD_DIE", $i);
3259 $post_build_die = set_test_option("POST_BUILD_DIE", $i);
3260 $power_cycle = set_test_option("POWER_CYCLE", $i);
3261 $reboot = set_test_option("REBOOT", $i);
3262 $noclean = set_test_option("BUILD_NOCLEAN", $i);
3263 $minconfig = set_test_option("MIN_CONFIG", $i);
3264 $output_minconfig = set_test_option("OUTPUT_MIN_CONFIG", $i);
3265 $start_minconfig = set_test_option("START_MIN_CONFIG", $i);
3266 $ignore_config = set_test_option("IGNORE_CONFIG", $i);
3267 $run_test = set_test_option("TEST", $i);
3268 $addconfig = set_test_option("ADD_CONFIG", $i);
3269 $reboot_type = set_test_option("REBOOT_TYPE", $i);
3270 $grub_menu = set_test_option("GRUB_MENU", $i);
3271 $post_install = set_test_option("POST_INSTALL", $i);
3272 $no_install = set_test_option("NO_INSTALL", $i);
3273 $reboot_script = set_test_option("REBOOT_SCRIPT", $i);
3274 $reboot_on_error = set_test_option("REBOOT_ON_ERROR", $i);
3275 $poweroff_on_error = set_test_option("POWEROFF_ON_ERROR", $i);
3276 $die_on_failure = set_test_option("DIE_ON_FAILURE", $i);
3277 $power_off = set_test_option("POWER_OFF", $i);
3278 $powercycle_after_reboot = set_test_option("POWERCYCLE_AFTER_REBOOT", $i);
3279 $poweroff_after_halt = set_test_option("POWEROFF_AFTER_HALT", $i);
3280 $sleep_time = set_test_option("SLEEP_TIME", $i);
3281 $bisect_sleep_time = set_test_option("BISECT_SLEEP_TIME", $i);
3282 $patchcheck_sleep_time = set_test_option("PATCHCHECK_SLEEP_TIME", $i);
3283 $ignore_warnings = set_test_option("IGNORE_WARNINGS", $i);
3284 $bisect_manual = set_test_option("BISECT_MANUAL", $i);
3285 $bisect_skip = set_test_option("BISECT_SKIP", $i);
3286 $config_bisect_good = set_test_option("CONFIG_BISECT_GOOD", $i);
3287 $store_failures = set_test_option("STORE_FAILURES", $i);
3288 $store_successes = set_test_option("STORE_SUCCESSES", $i);
3289 $test_name = set_test_option("TEST_NAME", $i);
3290 $timeout = set_test_option("TIMEOUT", $i);
3291 $booted_timeout = set_test_option("BOOTED_TIMEOUT", $i);
3292 $console = set_test_option("CONSOLE", $i);
3293 $detect_triplefault = set_test_option("DETECT_TRIPLE_FAULT", $i);
3294 $success_line = set_test_option("SUCCESS_LINE", $i);
3295 $reboot_success_line = set_test_option("REBOOT_SUCCESS_LINE", $i);
3296 $stop_after_success = set_test_option("STOP_AFTER_SUCCESS", $i);
3297 $stop_after_failure = set_test_option("STOP_AFTER_FAILURE", $i);
3298 $stop_test_after = set_test_option("STOP_TEST_AFTER", $i);
3299 $build_target = set_test_option("BUILD_TARGET", $i);
3300 $ssh_exec = set_test_option("SSH_EXEC", $i);
3301 $scp_to_target = set_test_option("SCP_TO_TARGET", $i);
3302 $target_image = set_test_option("TARGET_IMAGE", $i);
3303 $localversion = set_test_option("LOCALVERSION", $i);
3305 $start_minconfig_defined = 1;
3307 if (!defined($start_minconfig)) {
3308 $start_minconfig_defined = 0;
3309 $start_minconfig = $minconfig;
3312 chdir $builddir || die "can't change directory to $builddir";
3314 foreach my $dir ($tmpdir, $outputdir) {
3317 die "can't create $dir";
3321 $ENV{"SSH_USER"} = $ssh_user;
3322 $ENV{"MACHINE"} = $machine;
3324 $buildlog = "$tmpdir/buildlog-$machine";
3325 $testlog = "$tmpdir/testlog-$machine";
3326 $dmesg = "$tmpdir/dmesg-$machine";
3327 $make = "$makecmd O=$outputdir";
3328 $output_config = "$outputdir/.config";
3331 $target = "$ssh_user\@$machine";
3332 if ($reboot_type eq "grub") {
3333 dodie "GRUB_MENU not defined" if (!defined($grub_menu));
3334 } elsif (!defined($reboot_script)) {
3335 dodie "REBOOT_SCRIPT not defined"
3339 my $run_type = $build_type;
3340 if ($test_type eq "patchcheck") {
3341 $run_type = $opt{"PATCHCHECK_TYPE[$i]"};
3342 } elsif ($test_type eq "bisect") {
3343 $run_type = $opt{"BISECT_TYPE[$i]"};
3344 } elsif ($test_type eq "config_bisect") {
3345 $run_type = $opt{"CONFIG_BISECT_TYPE[$i]"};
3348 if ($test_type eq "make_min_config") {
3352 # mistake in config file?
3353 if (!defined($run_type)) {
3354 $run_type = "ERROR";
3358 $installme = " no_install" if ($no_install);
3361 doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type$installme\n\n";
3367 if (defined($addconfig)) {
3368 my $min = $minconfig;
3369 if (!defined($minconfig)) {
3372 run_command "cat $addconfig $min > $tmpdir/add_config" or
3373 dodie "Failed to create temp config";
3374 $minconfig = "$tmpdir/add_config";
3377 my $checkout = $opt{"CHECKOUT[$i]"};
3378 if (defined($checkout)) {
3379 run_command "git checkout $checkout" or
3380 die "failed to checkout $checkout";
3386 if ($test_type eq "bisect") {
3389 } elsif ($test_type eq "config_bisect") {
3392 } elsif ($test_type eq "patchcheck") {
3395 } elsif ($test_type eq "make_min_config") {
3400 if ($build_type ne "nobuild") {
3401 build $build_type or next;
3404 if ($test_type eq "install") {
3411 if ($test_type ne "build") {
3413 start_monitor_and_boot or $failed = 1;
3415 if (!$failed && $test_type ne "boot" && defined($run_test)) {
3416 do_run_test or $failed = 1;
3425 if ($opt{"POWEROFF_ON_SUCCESS"}) {
3427 } elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot) {
3431 doprint "\n $successes of $opt{NUM_TESTS} tests were successful\n\n";