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{"REBOOT_TYPE"} = "grub";
26 $default{"TEST_TYPE"} = "test";
27 $default{"BUILD_TYPE"} = "randconfig";
28 $default{"MAKE_CMD"} = "make";
29 $default{"TIMEOUT"} = 120;
30 $default{"TMP_DIR"} = "/tmp/ktest";
31 $default{"SLEEP_TIME"} = 60; # sleep time between tests
32 $default{"BUILD_NOCLEAN"} = 0;
33 $default{"REBOOT_ON_ERROR"} = 0;
34 $default{"POWEROFF_ON_ERROR"} = 0;
35 $default{"REBOOT_ON_SUCCESS"} = 1;
36 $default{"POWEROFF_ON_SUCCESS"} = 0;
37 $default{"BUILD_OPTIONS"} = "";
38 $default{"BISECT_SLEEP_TIME"} = 60; # sleep time between bisects
39 $default{"PATCHCHECK_SLEEP_TIME"} = 60; # sleep time between patch checks
40 $default{"CLEAR_LOG"} = 0;
41 $default{"BISECT_MANUAL"} = 0;
42 $default{"BISECT_SKIP"} = 1;
43 $default{"SUCCESS_LINE"} = "login:";
44 $default{"DETECT_TRIPLE_FAULT"} = 1;
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;
53 $default{"LOCALVERSION"} = "-test";
71 my $poweroff_on_error;
73 my $powercycle_after_reboot;
74 my $poweroff_after_halt;
91 my $config_bisect_good;
92 my $in_patchcheck = 0;
101 my $bisect_sleep_time;
102 my $patchcheck_sleep_time;
107 my $detect_triplefault;
110 my $stop_after_success;
111 my $stop_after_failure;
124 $config_help{"MACHINE"} = << "EOF"
125 The machine hostname that you will test.
128 $config_help{"SSH_USER"} = << "EOF"
129 The box is expected to have ssh on normal bootup, provide the user
130 (most likely root, since you need privileged operations)
133 $config_help{"BUILD_DIR"} = << "EOF"
134 The directory that contains the Linux source code (full path).
137 $config_help{"OUTPUT_DIR"} = << "EOF"
138 The directory that the objects will be built (full path).
139 (can not be same as BUILD_DIR)
142 $config_help{"BUILD_TARGET"} = << "EOF"
143 The location of the compiled file to copy to the target.
144 (relative to OUTPUT_DIR)
147 $config_help{"TARGET_IMAGE"} = << "EOF"
148 The place to put your image on the test machine.
151 $config_help{"POWER_CYCLE"} = << "EOF"
152 A script or command to reboot the box.
154 Here is a digital loggers power switch example
155 POWER_CYCLE = wget --no-proxy -O /dev/null -q --auth-no-challenge 'http://admin:admin\@power/outlet?5=CCL'
157 Here is an example to reboot a virtual box on the current host
158 with the name "Guest".
159 POWER_CYCLE = virsh destroy Guest; sleep 5; virsh start Guest
162 $config_help{"CONSOLE"} = << "EOF"
163 The script or command that reads the console
165 If you use ttywatch server, something like the following would work.
166 CONSOLE = nc -d localhost 3001
168 For a virtual machine with guest name "Guest".
169 CONSOLE = virsh console Guest
172 $config_help{"LOCALVERSION"} = << "EOF"
173 Required version ending to differentiate the test
174 from other linux builds on the system.
177 $config_help{"REBOOT_TYPE"} = << "EOF"
178 Way to reboot the box to the test kernel.
179 Only valid options so far are "grub" and "script".
181 If you specify grub, it will assume grub version 1
182 and will search in /boot/grub/menu.lst for the title \$GRUB_MENU
183 and select that target to reboot to the kernel. If this is not
184 your setup, then specify "script" and have a command or script
185 specified in REBOOT_SCRIPT to boot to the target.
187 The entry in /boot/grub/menu.lst must be entered in manually.
188 The test will not modify that file.
191 $config_help{"GRUB_MENU"} = << "EOF"
192 The grub title name for the test kernel to boot
193 (Only mandatory if REBOOT_TYPE = grub)
195 Note, ktest.pl will not update the grub menu.lst, you need to
196 manually add an option for the test. ktest.pl will search
197 the grub menu.lst for this option to find what kernel to
200 For example, if in the /boot/grub/menu.lst the test kernel title has:
203 GRUB_MENU = Test Kernel
206 $config_help{"REBOOT_SCRIPT"} = << "EOF"
207 A script to reboot the target into the test kernel
208 (Only mandatory if REBOOT_TYPE = script)
213 sub get_ktest_config {
216 return if (defined($opt{$config}));
218 if (defined($config_help{$config})) {
220 print $config_help{$config};
225 if (defined($default{$config})) {
226 print "\[$default{$config}\] ";
228 $entered_configs{$config} = <STDIN>;
229 $entered_configs{$config} =~ s/^\s*(.*\S)\s*$/$1/;
230 if ($entered_configs{$config} =~ /^\s*$/) {
231 if ($default{$config}) {
232 $entered_configs{$config} = $default{$config};
234 print "Your answer can not be blank\n";
242 sub get_ktest_configs {
243 get_ktest_config("MACHINE");
244 get_ktest_config("SSH_USER");
245 get_ktest_config("BUILD_DIR");
246 get_ktest_config("OUTPUT_DIR");
247 get_ktest_config("BUILD_TARGET");
248 get_ktest_config("TARGET_IMAGE");
249 get_ktest_config("POWER_CYCLE");
250 get_ktest_config("CONSOLE");
251 get_ktest_config("LOCALVERSION");
253 my $rtype = $opt{"REBOOT_TYPE"};
255 if (!defined($rtype)) {
256 if (!defined($opt{"GRUB_MENU"})) {
257 get_ktest_config("REBOOT_TYPE");
258 $rtype = $entered_configs{"REBOOT_TYPE"};
264 if ($rtype eq "grub") {
265 get_ktest_config("GRUB_MENU");
267 get_ktest_config("REBOOT_SCRIPT");
271 sub process_variables {
275 # We want to check for '\', and it is just easier
276 # to check the previous characet of '$' and not need
277 # to worry if '$' is the first character. By adding
278 # a space to $value, we can just check [^\\]\$ and
279 # it will still work.
282 while ($value =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
286 # append beginning of value to retval
287 $retval = "$retval$begin";
288 if (defined($variable{$var})) {
289 $retval = "$retval$variable{$var}";
291 # put back the origin piece.
292 $retval = "$retval\$\{$var\}";
296 $retval = "$retval$value";
298 # remove the space added in the beginning
305 my ($lvalue, $rvalue) = @_;
307 if (defined($opt{$lvalue})) {
308 die "Error: Option $lvalue defined more than once!\n";
310 if ($rvalue =~ /^\s*$/) {
311 delete $opt{$lvalue};
313 $rvalue = process_variables($rvalue);
314 $opt{$lvalue} = $rvalue;
319 my ($lvalue, $rvalue) = @_;
321 if ($rvalue =~ /^\s*$/) {
322 delete $variable{$lvalue};
324 $rvalue = process_variables($rvalue);
325 $variable{$lvalue} = $rvalue;
332 open(IN, $config) || die "can't read file $config";
335 $name =~ s,.*/(.*),$1,;
340 my $num_tests_set = 0;
346 # ignore blank lines and comments
347 next if (/^\s*$/ || /\s*\#/);
349 if (/^\s*TEST_START(.*)/) {
353 if ($num_tests_set) {
354 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
357 my $old_test_num = $test_num;
358 my $old_repeat = $repeat;
360 $test_num += $repeat;
364 if ($rest =~ /\s+SKIP(.*)/) {
371 if ($rest =~ /\s+ITERATE\s+(\d+)(.*)$/) {
374 $repeat_tests{"$test_num"} = $repeat;
377 if ($rest =~ /\s+SKIP(.*)/) {
382 if ($rest !~ /^\s*$/) {
383 die "$name: $.: Gargbage found after TEST_START\n$_";
387 $test_num = $old_test_num;
388 $repeat = $old_repeat;
391 } elsif (/^\s*DEFAULTS(.*)$/) {
396 if ($rest =~ /\s+SKIP(.*)/) {
403 if ($rest !~ /^\s*$/) {
404 die "$name: $.: Gargbage found after DEFAULTS\n$_";
407 } elsif (/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) {
415 ($lvalue eq "NUM_TESTS" ||
416 $lvalue eq "LOG_FILE" ||
417 $lvalue eq "CLEAR_LOG")) {
418 die "$name: $.: $lvalue must be set in DEFAULTS section\n";
421 if ($lvalue eq "NUM_TESTS") {
423 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
426 die "$name: $.: NUM_TESTS must be set in default section\n";
431 if ($default || $lvalue =~ /\[\d+\]$/) {
432 set_value($lvalue, $rvalue);
434 my $val = "$lvalue\[$test_num\]";
435 set_value($val, $rvalue);
438 $repeats{$val} = $repeat;
441 } elsif (/^\s*([A-Z_\[\]\d]+)\s*:=\s*(.*?)\s*$/) {
447 # process config variables.
448 # Config variables are only active while reading the
449 # config and can be defined anywhere. They also ignore
450 # TEST_START and DEFAULTS, but are skipped if they are in
451 # on of these sections that have SKIP defined.
452 # The save variable can be
453 # defined multiple times and the new one simply overrides
455 set_variable($lvalue, $rvalue);
458 die "$name: $.: Garbage found in config\n$_";
465 $test_num += $repeat - 1;
466 $opt{"NUM_TESTS"} = $test_num;
469 # make sure we have all mandatory configs
474 foreach my $default (keys %default) {
475 if (!defined($opt{$default})) {
476 $opt{$default} = $default{$default};
482 my ($option, $i) = @_;
484 # Add space to evaluate the character before $
485 $option = " $option";
488 while ($option =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
493 # Append beginning of line
494 $retval = "$retval$start";
496 # If the iteration option OPT[$i] exists, then use that.
497 # otherwise see if the default OPT (without [$i]) exists.
499 my $o = "$var\[$i\]";
501 if (defined($opt{$o})) {
503 $retval = "$retval$o";
504 } elsif (defined($opt{$var})) {
506 $retval = "$retval$o";
508 $retval = "$retval\$\{$var\}";
514 $retval = "$retval$option";
522 my ($option, $i) = @_;
526 # Since an option can evaluate to another option,
527 # keep iterating until we do not evaluate any more
530 while ($prev ne $option) {
531 # Check for recursive evaluations.
532 # 100 deep should be more than enough.
534 die "Over 100 evaluations accurred with $option\n" .
535 "Check for recursive variables\n";
538 $option = __eval_option($option, $i);
545 if (defined($opt{"LOG_FILE"})) {
546 open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}";
553 if (defined($opt{"LOG_FILE"})) {
568 # try to reboot normally
569 if (run_command $reboot) {
570 if (defined($powercycle_after_reboot)) {
571 sleep $powercycle_after_reboot;
572 run_command "$power_cycle";
575 # nope? power cycle it.
576 run_command "$power_cycle";
583 return $test_type eq "build" ||
584 ($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") ||
585 ($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build");
589 doprint "CRITICAL FAILURE... ", @_, "\n";
593 if ($reboot_on_error && !do_not_reboot) {
595 doprint "REBOOTING\n";
598 } elsif ($poweroff_on_error && defined($power_off)) {
599 doprint "POWERING OFF\n";
603 if (defined($opt{"LOG_FILE"})) {
604 print " See $opt{LOG_FILE} for more info.\n";
615 my $pid = open($fp, "$console|") or
616 dodie "Can't open console $console";
618 $flags = fcntl($fp, F_GETFL, 0) or
619 dodie "Can't get flags for the socket: $!";
620 $flags = fcntl($fp, F_SETFL, $flags | O_NONBLOCK) or
621 dodie "Can't set flags for the socket: $!";
629 doprint "kill child process $pid\n";
637 if ($monitor_cnt++) {
640 $monitor_fp = \*MONFD;
641 $monitor_pid = open_console $monitor_fp;
645 open(MONFD, "Stop perl from warning about single use of MONFD");
649 if (--$monitor_cnt) {
652 close_console($monitor_fp, $monitor_pid);
655 sub wait_for_monitor {
659 doprint "** Wait for monitor to settle down **\n";
661 # read the monitor and wait for the system to calm down
663 $line = wait_for_input($monitor_fp, $time);
664 print "$line" if (defined($line));
665 } while (defined($line));
666 print "** Monitor flushed **\n";
671 if ($die_on_failure) {
679 # no need to reboot for just building.
680 if (!do_not_reboot) {
681 doprint "REBOOTING\n";
684 wait_for_monitor $sleep_time;
690 if (defined($test_name)) {
691 $name = " ($test_name)";
694 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
695 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
696 doprint "KTEST RESULT: TEST $i$name Failed: ", @_, "\n";
697 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
698 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
700 return 1 if (!defined($store_failures));
703 my $date = sprintf "%04d%02d%02d%02d%02d%02d",
704 1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0];
706 my $type = $build_type;
707 if ($type =~ /useconfig/) {
711 my $dir = "$machine-$test_type-$type-fail-$date";
712 my $faildir = "$store_failures/$dir";
716 die "can't create $faildir";
718 if (-f "$output_config") {
719 cp "$output_config", "$faildir/config" or
720 die "failed to copy .config";
723 cp $buildlog, "$faildir/buildlog" or
724 die "failed to move $buildlog";
727 cp $dmesg, "$faildir/dmesg" or
728 die "failed to move $dmesg";
731 doprint "*** Saved info to $faildir ***\n";
742 $command =~ s/\$SSH_USER/$ssh_user/g;
743 $command =~ s/\$MACHINE/$machine/g;
745 doprint("$command ... ");
747 $pid = open(CMD, "$command 2>&1 |") or
748 (fail "unable to exec $command" and return 0);
750 if (defined($opt{"LOG_FILE"})) {
751 open(LOG, ">>$opt{LOG_FILE}") or
752 dodie "failed to write to log";
756 if (defined($redirect)) {
757 open (RD, ">$redirect") or
758 dodie "failed to write to redirect $redirect";
763 print LOG if ($dolog);
771 close(LOG) if ($dolog);
772 close(RD) if ($dord);
785 my $cp_exec = $ssh_exec;
787 $cp_exec =~ s/\$SSH_COMMAND/$cmd/g;
788 return run_command "$cp_exec";
792 my ($src, $dst) = @_;
793 my $cp_scp = $scp_to_target;
795 $cp_scp =~ s/\$SRC_FILE/$src/g;
796 $cp_scp =~ s/\$DST_FILE/$dst/g;
798 return run_command "$cp_scp";
803 if ($reboot_type ne "grub") {
806 return if (defined($grub_number));
808 doprint "Find grub menu ... ";
811 my $ssh_grub = $ssh_exec;
812 $ssh_grub =~ s,\$SSH_COMMAND,cat /boot/grub/menu.lst,g;
814 open(IN, "$ssh_grub |")
815 or die "unable to get menu.lst";
818 if (/^\s*title\s+$grub_menu\s*$/) {
821 } elsif (/^\s*title\s/) {
827 die "Could not find '$grub_menu' in /boot/grub/menu on $machine"
828 if ($grub_number < 0);
829 doprint "$grub_number\n";
834 my ($fp, $time) = @_;
840 if (!defined($time)) {
845 vec($rin, fileno($fp), 1) = 1;
846 $ready = select($rin, undef, undef, $time);
850 # try to read one char at a time
851 while (sysread $fp, $ch, 1) {
853 last if ($ch eq "\n");
856 if (!length($line)) {
864 if ($reboot_type eq "grub") {
865 run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch && reboot)'";
869 run_command "$reboot_script";
875 doprint "git rev-list --max-count=1 $commit ... ";
876 my $sha1 = `git rev-list --max-count=1 $commit`;
883 dodie "Failed to get git $commit";
896 my $skip_call_trace = 0;
904 open(DMESG, "> $dmesg") or
905 die "unable to write to $dmesg";
911 my $monitor_start = time;
913 my $version_found = 0;
917 if ($bug && defined($stop_after_failure) &&
918 $stop_after_failure >= 0) {
919 my $time = $stop_after_failure - (time - $failure_start);
920 $line = wait_for_input($monitor_fp, $time);
921 if (!defined($line)) {
922 doprint "bug timed out after $booted_timeout seconds\n";
923 doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
927 $line = wait_for_input($monitor_fp, $booted_timeout);
928 if (!defined($line)) {
929 my $s = $booted_timeout == 1 ? "" : "s";
930 doprint "Successful boot found: break after $booted_timeout second$s\n";
934 $line = wait_for_input($monitor_fp);
935 if (!defined($line)) {
936 my $s = $timeout == 1 ? "" : "s";
937 doprint "Timed out after $timeout second$s\n";
945 # we are not guaranteed to get a full line
948 if ($full_line =~ /$success_line/) {
950 $success_start = time;
953 if ($booted && defined($stop_after_success) &&
954 $stop_after_success >= 0) {
956 if ($now - $success_start >= $stop_after_success) {
957 doprint "Test forced to stop after $stop_after_success seconds after success\n";
962 if ($full_line =~ /\[ backtrace testing \]/) {
963 $skip_call_trace = 1;
966 if ($full_line =~ /call trace:/i) {
967 if (!$bug && !$skip_call_trace) {
969 $failure_start = time;
973 if ($bug && defined($stop_after_failure) &&
974 $stop_after_failure >= 0) {
976 if ($now - $failure_start >= $stop_after_failure) {
977 doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
982 if ($full_line =~ /\[ end of backtrace testing \]/) {
983 $skip_call_trace = 0;
986 if ($full_line =~ /Kernel panic -/) {
987 $failure_start = time;
991 # Detect triple faults by testing the banner
992 if ($full_line =~ /\bLinux version (\S+).*\n/) {
993 if ($1 eq $version) {
995 } elsif ($version_found && $detect_triplefault) {
996 # We already booted into the kernel we are testing,
997 # but now we booted into another kernel?
998 # Consider this a triple fault.
999 doprint "Aleady booted in Linux kernel $version, but now\n";
1000 doprint "we booted into Linux kernel $1.\n";
1001 doprint "Assuming that this is a triple fault.\n";
1002 doprint "To disable this: set DETECT_TRIPLE_FAULT to 0\n";
1007 if ($line =~ /\n/) {
1011 if ($stop_test_after > 0 && !$booted && !$bug) {
1012 if (time - $monitor_start > $stop_test_after) {
1013 doprint "STOP_TEST_AFTER ($stop_test_after seconds) timed out\n";
1022 return 0 if ($in_bisect);
1023 fail "failed - got a bug report" and return 0;
1027 return 0 if ($in_bisect);
1028 fail "failed - never got a boot prompt." and return 0;
1036 run_scp "$outputdir/$build_target", "$target_image" or
1037 dodie "failed to copy image";
1039 my $install_mods = 0;
1041 # should we process modules?
1043 open(IN, "$output_config") or dodie("Can't read config file");
1045 if (/CONFIG_MODULES(=y)?/) {
1046 $install_mods = 1 if (defined($1));
1052 if (!$install_mods) {
1053 doprint "No modules needed\n";
1057 run_command "$make INSTALL_MOD_PATH=$tmpdir modules_install" or
1058 dodie "Failed to install modules";
1060 my $modlib = "/lib/modules/$version";
1061 my $modtar = "ktest-mods.tar.bz2";
1063 run_ssh "rm -rf $modlib" or
1064 dodie "failed to remove old mods: $modlib";
1066 # would be nice if scp -r did not follow symbolic links
1067 run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or
1068 dodie "making tarball";
1070 run_scp "$tmpdir/$modtar", "/tmp" or
1071 dodie "failed to copy modules";
1073 unlink "$tmpdir/$modtar";
1075 run_ssh "'(cd / && tar xf /tmp/$modtar)'" or
1076 dodie "failed to tar modules";
1078 run_ssh "rm -f /tmp/$modtar";
1080 return if (!defined($post_install));
1082 my $cp_post_install = $post_install;
1083 $cp_post_install =~ s/\$KERNEL_VERSION/$version/g;
1084 run_command "$cp_post_install" or
1085 dodie "Failed to run post install";
1088 sub check_buildlog {
1091 my @files = `git show $patch | diffstat -l`;
1093 open(IN, "git show $patch |") or
1094 dodie "failed to show $patch";
1096 if (m,^--- a/(.*),) {
1098 $files[$#files] = $1;
1103 open(IN, $buildlog) or dodie "Can't open $buildlog";
1105 if (/^\s*(.*?):.*(warning|error)/) {
1107 foreach my $file (@files) {
1108 my $fullpath = "$builddir/$file";
1109 if ($file eq $err || $fullpath eq $err) {
1110 fail "$file built with warnings" and return 0;
1120 sub apply_min_config {
1121 my $outconfig = "$output_config.new";
1123 # Read the config file and remove anything that
1124 # is in the force_config hash (from minconfig and others)
1125 # then add the force config back.
1127 doprint "Applying minimum configurations into $output_config.new\n";
1129 open (OUT, ">$outconfig") or
1130 dodie "Can't create $outconfig";
1132 if (-f $output_config) {
1133 open (IN, $output_config) or
1134 dodie "Failed to open $output_config";
1136 if (/^(# )?(CONFIG_[^\s=]*)/) {
1137 next if (defined($force_config{$2}));
1143 foreach my $config (keys %force_config) {
1144 print OUT "$force_config{$config}\n";
1148 run_command "mv $outconfig $output_config";
1151 sub make_oldconfig {
1155 if (!run_command "$make oldnoconfig") {
1156 # Perhaps oldnoconfig doesn't exist in this version of the kernel
1157 # try a yes '' | oldconfig
1158 doprint "oldnoconfig failed, trying yes '' | make oldconfig\n";
1159 run_command "yes '' | $make oldconfig" or
1160 dodie "failed make config oldconfig";
1164 # read a config file and use this to force new configs.
1165 sub load_force_config {
1168 open(IN, $config) or
1169 dodie "failed to read $config";
1172 if (/^(CONFIG[^\s=]*)(\s*=.*)/) {
1173 $force_config{$1} = $_;
1174 } elsif (/^# (CONFIG_\S*) is not set/) {
1175 $force_config{$1} = $_;
1186 if ($type =~ /^useconfig:(.*)/) {
1187 run_command "cp $1 $output_config" or
1188 dodie "could not copy $1 to .config";
1190 $type = "oldconfig";
1193 # old config can ask questions
1194 if ($type eq "oldconfig") {
1195 $type = "oldnoconfig";
1197 # allow for empty configs
1198 run_command "touch $output_config";
1200 run_command "mv $output_config $outputdir/config_temp" or
1201 dodie "moving .config";
1203 if (!$noclean && !run_command "$make mrproper") {
1204 dodie "make mrproper";
1207 run_command "mv $outputdir/config_temp $output_config" or
1208 dodie "moving config_temp";
1210 } elsif (!$noclean) {
1211 unlink "$output_config";
1212 run_command "$make mrproper" or
1213 dodie "make mrproper";
1216 # add something to distinguish this build
1217 open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file");
1218 print OUT "$localversion\n";
1221 if (defined($minconfig)) {
1222 load_force_config($minconfig);
1225 if ($type ne "oldnoconfig") {
1226 run_command "$make $type" or
1227 dodie "failed make config";
1229 # Run old config regardless, to enforce min configurations
1232 $redirect = "$buildlog";
1233 if (!run_command "$make $build_options") {
1235 # bisect may need this to pass
1236 return 0 if ($in_bisect);
1237 fail "failed build" and return 0;
1245 if (!run_ssh "halt" or defined($power_off)) {
1246 if (defined($poweroff_after_halt)) {
1247 sleep $poweroff_after_halt;
1248 run_command "$power_off";
1252 run_command "$power_off";
1263 if (defined($test_name)) {
1264 $name = " ($test_name)";
1267 doprint "\n\n*******************************************\n";
1268 doprint "*******************************************\n";
1269 doprint "KTEST RESULT: TEST $i$name SUCCESS!!!! **\n";
1270 doprint "*******************************************\n";
1271 doprint "*******************************************\n";
1273 if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) {
1274 doprint "Reboot and wait $sleep_time seconds\n";
1277 wait_for_monitor $sleep_time;
1283 # get the release name
1284 doprint "$make kernelrelease ... ";
1285 $version = `$make kernelrelease | tail -1`;
1287 doprint "$version\n";
1292 doprint "Pass or fail? [p/f]";
1295 if ($ans eq "p" || $ans eq "P") {
1297 } elsif ($ans eq "f" || $ans eq "F") {
1300 print "Please answer 'P' or 'F'\n";
1305 sub child_run_test {
1308 # child should have no power
1309 $reboot_on_error = 0;
1310 $poweroff_on_error = 0;
1311 $die_on_failure = 1;
1313 run_command $run_test or $failed = 1;
1319 sub child_finished {
1332 doprint "run test $run_test\n";
1336 $SIG{CHLD} = qw(child_finished);
1340 child_run_test if (!$child_pid);
1345 $line = wait_for_input($monitor_fp, 1);
1346 if (defined($line)) {
1348 # we are not guaranteed to get a full line
1349 $full_line .= $line;
1352 if ($full_line =~ /call trace:/i) {
1356 if ($full_line =~ /Kernel panic -/) {
1360 if ($line =~ /\n/) {
1364 } while (!$child_done && !$bug);
1367 my $failure_start = time;
1370 $line = wait_for_input($monitor_fp, 1);
1371 if (defined($line)) {
1375 if ($now - $failure_start >= $stop_after_failure) {
1378 } while (defined($line));
1380 doprint "Detected kernel crash!\n";
1381 # kill the child with extreme prejudice
1385 waitpid $child_pid, 0;
1388 if ($bug || $child_exit) {
1389 return 0 if $in_bisect;
1390 fail "test failed" and return 0;
1395 sub run_git_bisect {
1398 doprint "$command ... ";
1400 my $output = `$command 2>&1`;
1407 dodie "Failed to git bisect";
1410 doprint "SUCCESS\n";
1411 if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) {
1412 doprint "$1 [$2]\n";
1413 } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) {
1415 doprint "Found bad commit... $1\n";
1418 # we already logged it, just print it now.
1426 doprint "Reboot and sleep $bisect_sleep_time seconds\n";
1429 wait_for_monitor $bisect_sleep_time;
1433 # returns 1 on success, 0 on failure, -1 on skip
1434 sub run_bisect_test {
1435 my ($type, $buildtype) = @_;
1444 build $buildtype or $failed = 1;
1446 if ($type ne "build") {
1447 if ($failed && $bisect_skip) {
1451 dodie "Failed on build" if $failed;
1459 monitor or $failed = 1;
1461 if ($type ne "boot") {
1462 if ($failed && $bisect_skip) {
1468 dodie "Failed on boot" if $failed;
1470 do_run_test or $failed = 1;
1481 # reboot the box to a kernel we can ssh to
1482 if ($type ne "build") {
1492 my $buildtype = "oldconfig";
1494 # We should have a minconfig to use?
1495 if (defined($minconfig)) {
1496 $buildtype = "useconfig:$minconfig";
1499 my $ret = run_bisect_test $type, $buildtype;
1501 if ($bisect_manual) {
1502 $ret = answer_bisect;
1505 # Are we looking for where it worked, not failed?
1506 if ($reverse_bisect) {
1512 } elsif ($ret == 0) {
1514 } elsif ($bisect_skip) {
1515 doprint "HIT A BAD COMMIT ... SKIPPING\n";
1525 die "BISECT_GOOD[$i] not defined\n" if (!defined($opt{"BISECT_GOOD[$i]"}));
1526 die "BISECT_BAD[$i] not defined\n" if (!defined($opt{"BISECT_BAD[$i]"}));
1527 die "BISECT_TYPE[$i] not defined\n" if (!defined($opt{"BISECT_TYPE[$i]"}));
1529 my $good = $opt{"BISECT_GOOD[$i]"};
1530 my $bad = $opt{"BISECT_BAD[$i]"};
1531 my $type = $opt{"BISECT_TYPE[$i]"};
1532 my $start = $opt{"BISECT_START[$i]"};
1533 my $replay = $opt{"BISECT_REPLAY[$i]"};
1534 my $start_files = $opt{"BISECT_FILES[$i]"};
1536 if (defined($start_files)) {
1537 $start_files = " -- " . $start_files;
1542 # convert to true sha1's
1543 $good = get_sha1($good);
1544 $bad = get_sha1($bad);
1546 if (defined($opt{"BISECT_REVERSE[$i]"}) &&
1547 $opt{"BISECT_REVERSE[$i]"} == 1) {
1548 doprint "Performing a reverse bisect (bad is good, good is bad!)\n";
1549 $reverse_bisect = 1;
1551 $reverse_bisect = 0;
1554 # Can't have a test without having a test to run
1555 if ($type eq "test" && !defined($run_test)) {
1559 my $check = $opt{"BISECT_CHECK[$i]"};
1560 if (defined($check) && $check ne "0") {
1563 my $head = get_sha1("HEAD");
1565 if ($check ne "good") {
1566 doprint "TESTING BISECT BAD [$bad]\n";
1567 run_command "git checkout $bad" or
1568 die "Failed to checkout $bad";
1570 $result = run_bisect $type;
1572 if ($result ne "bad") {
1573 fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0;
1577 if ($check ne "bad") {
1578 doprint "TESTING BISECT GOOD [$good]\n";
1579 run_command "git checkout $good" or
1580 die "Failed to checkout $good";
1582 $result = run_bisect $type;
1584 if ($result ne "good") {
1585 fail "Tested BISECT_GOOD [$good] and it failed" and return 0;
1589 # checkout where we started
1590 run_command "git checkout $head" or
1591 die "Failed to checkout $head";
1594 run_command "git bisect start$start_files" or
1595 dodie "could not start bisect";
1597 run_command "git bisect good $good" or
1598 dodie "could not set bisect good to $good";
1600 run_git_bisect "git bisect bad $bad" or
1601 dodie "could not set bisect bad to $bad";
1603 if (defined($replay)) {
1604 run_command "git bisect replay $replay" or
1605 dodie "failed to run replay";
1608 if (defined($start)) {
1609 run_command "git checkout $start" or
1610 dodie "failed to checkout $start";
1615 $result = run_bisect $type;
1616 $test = run_git_bisect "git bisect $result";
1619 run_command "git bisect log" or
1620 dodie "could not capture git bisect log";
1622 run_command "git bisect reset" or
1623 dodie "could not reset git bisect";
1625 doprint "Bad commit was [$bisect_bad]\n";
1638 sub process_config_ignore {
1642 or dodie "Failed to read $config";
1645 if (/^((CONFIG\S*)=.*)/) {
1646 $config_ignore{$2} = $1;
1653 sub read_current_config {
1654 my ($config_ref) = @_;
1656 %{$config_ref} = ();
1657 undef %{$config_ref};
1659 my @key = keys %{$config_ref};
1661 print "did not delete!\n";
1664 open (IN, "$output_config");
1667 if (/^(CONFIG\S+)=(.*)/) {
1668 ${$config_ref}{$1} = $2;
1674 sub get_dependencies {
1677 my $arr = $dependency{$config};
1678 if (!defined($arr)) {
1684 foreach my $dep (@{$arr}) {
1685 print "ADD DEP $dep\n";
1686 @deps = (@deps, get_dependencies $dep);
1695 open(OUT, ">$output_config") or dodie "Can not write to $output_config";
1697 foreach my $config (@configs) {
1698 print OUT "$config_set{$config}\n";
1699 my @deps = get_dependencies $config;
1700 foreach my $dep (@deps) {
1701 print OUT "$config_set{$dep}\n";
1705 foreach my $config (keys %config_ignore) {
1706 print OUT "$config_ignore{$config}\n";
1714 sub compare_configs {
1717 foreach my $item (keys %a) {
1718 if (!defined($b{$item})) {
1719 print "diff $item\n";
1727 print "diff2 $keys[0]\n";
1729 return -1 if ($#keys >= 0);
1734 sub run_config_bisect_test {
1737 return run_bisect_test $type, "oldconfig";
1740 sub process_passed {
1743 doprint "These configs had no failure: (Enabling them for further compiles)\n";
1744 # Passed! All these configs are part of a good compile.
1745 # Add them to the min options.
1746 foreach my $config (keys %configs) {
1747 if (defined($config_list{$config})) {
1748 doprint " removing $config\n";
1749 $config_ignore{$config} = $config_list{$config};
1750 delete $config_list{$config};
1753 doprint "config copied to $outputdir/config_good\n";
1754 run_command "cp -f $output_config $outputdir/config_good";
1757 sub process_failed {
1760 doprint "\n\n***************************************\n";
1761 doprint "Found bad config: $config\n";
1762 doprint "***************************************\n\n";
1765 sub run_config_bisect {
1767 my @start_list = keys %config_list;
1769 if ($#start_list < 0) {
1770 doprint "No more configs to test!!!\n";
1774 doprint "***** RUN TEST ***\n";
1775 my $type = $opt{"CONFIG_BISECT_TYPE[$iteration]"};
1779 my $count = $#start_list + 1;
1780 doprint " $count configs to test\n";
1782 my $half = int($#start_list / 2);
1785 my @tophalf = @start_list[0 .. $half];
1787 create_config @tophalf;
1788 read_current_config \%current_config;
1790 $count = $#tophalf + 1;
1791 doprint "Testing $count configs\n";
1793 # make sure we test something
1794 foreach my $config (@tophalf) {
1795 if (defined($current_config{$config})) {
1801 # try the other half
1802 doprint "Top half produced no set configs, trying bottom half\n";
1803 @tophalf = @start_list[$half + 1 .. $#start_list];
1804 create_config @tophalf;
1805 read_current_config \%current_config;
1806 foreach my $config (@tophalf) {
1807 if (defined($current_config{$config})) {
1813 doprint "Failed: Can't make new config with current configs\n";
1814 foreach my $config (@start_list) {
1815 doprint " CONFIG: $config\n";
1819 $count = $#tophalf + 1;
1820 doprint "Testing $count configs\n";
1823 $ret = run_config_bisect_test $type;
1824 if ($bisect_manual) {
1825 $ret = answer_bisect;
1828 process_passed %current_config;
1832 doprint "This config had a failure.\n";
1833 doprint "Removing these configs that were not set in this config:\n";
1834 doprint "config copied to $outputdir/config_bad\n";
1835 run_command "cp -f $output_config $outputdir/config_bad";
1837 # A config exists in this group that was bad.
1838 foreach my $config (keys %config_list) {
1839 if (!defined($current_config{$config})) {
1840 doprint " removing $config\n";
1841 delete $config_list{$config};
1845 @start_list = @tophalf;
1847 if ($#start_list == 0) {
1848 process_failed $start_list[0];
1852 # remove half the configs we are looking at and see if
1854 $half = int($#start_list / 2);
1855 } while ($#start_list > 0);
1857 # we found a single config, try it again unless we are running manually
1859 if ($bisect_manual) {
1860 process_failed $start_list[0];
1864 my @tophalf = @start_list[0 .. 0];
1866 $ret = run_config_bisect_test $type;
1868 process_passed %current_config;
1872 process_failed $start_list[0];
1879 my $start_config = $opt{"CONFIG_BISECT[$i]"};
1881 my $tmpconfig = "$tmpdir/use_config";
1883 if (defined($config_bisect_good)) {
1884 process_config_ignore $config_bisect_good;
1887 # Make the file with the bad config and the min config
1888 if (defined($minconfig)) {
1889 # read the min config for things to ignore
1890 run_command "cp $minconfig $tmpconfig" or
1891 dodie "failed to copy $minconfig to $tmpconfig";
1897 if (defined($addconfig)) {
1898 run_command "cat $addconfig >> $tmpconfig" or
1899 dodie "failed to append $addconfig";
1902 if (-f $tmpconfig) {
1903 load_force_config($tmpconfig);
1904 process_config_ignore $tmpconfig;
1907 # now process the start config
1908 run_command "cp $start_config $output_config" or
1909 dodie "failed to copy $start_config to $output_config";
1911 # read directly what we want to check
1913 open (IN, $output_config)
1914 or dodie "faied to open $output_config";
1917 if (/^((CONFIG\S*)=.*)/) {
1918 $config_check{$2} = $1;
1923 # Now run oldconfig with the minconfig (and addconfigs)
1926 # check to see what we lost (or gained)
1927 open (IN, $output_config)
1928 or dodie "Failed to read $start_config";
1930 my %removed_configs;
1934 if (/^((CONFIG\S*)=.*)/) {
1935 # save off all options
1936 $config_set{$2} = $1;
1937 if (defined($config_check{$2})) {
1938 if (defined($config_ignore{$2})) {
1939 $removed_configs{$2} = $1;
1941 $config_list{$2} = $1;
1943 } elsif (!defined($config_ignore{$2})) {
1944 $added_configs{$2} = $1;
1945 $config_list{$2} = $1;
1951 my @confs = keys %removed_configs;
1953 doprint "Configs overridden by default configs and removed from check:\n";
1954 foreach my $config (@confs) {
1955 doprint " $config\n";
1958 @confs = keys %added_configs;
1960 doprint "Configs appearing in make oldconfig and added:\n";
1961 foreach my $config (@confs) {
1962 doprint " $config\n";
1969 # Sometimes kconfig does weird things. We must make sure
1970 # that the config we autocreate has everything we need
1971 # to test, otherwise we may miss testing configs, or
1972 # may not be able to create a new config.
1973 # Here we create a config with everything set.
1974 create_config (keys %config_list);
1975 read_current_config \%config_test;
1976 foreach my $config (keys %config_list) {
1977 if (!defined($config_test{$config})) {
1980 doprint "Configs not produced by kconfig (will not be checked):\n";
1982 doprint " $config\n";
1983 delete $config_list{$config};
1988 $ret = run_config_bisect;
1991 return $ret if ($ret < 0);
1996 sub patchcheck_reboot {
1997 doprint "Reboot and sleep $patchcheck_sleep_time seconds\n";
2000 wait_for_monitor $patchcheck_sleep_time;
2007 die "PATCHCHECK_START[$i] not defined\n"
2008 if (!defined($opt{"PATCHCHECK_START[$i]"}));
2009 die "PATCHCHECK_TYPE[$i] not defined\n"
2010 if (!defined($opt{"PATCHCHECK_TYPE[$i]"}));
2012 my $start = $opt{"PATCHCHECK_START[$i]"};
2015 if (defined($opt{"PATCHCHECK_END[$i]"})) {
2016 $end = $opt{"PATCHCHECK_END[$i]"};
2019 # Get the true sha1's since we can use things like HEAD~3
2020 $start = get_sha1($start);
2021 $end = get_sha1($end);
2023 my $type = $opt{"PATCHCHECK_TYPE[$i]"};
2025 # Can't have a test without having a test to run
2026 if ($type eq "test" && !defined($run_test)) {
2030 open (IN, "git log --pretty=oneline $end|") or
2031 dodie "could not get git list";
2037 $list[$#list+1] = $_;
2038 last if (/^$start/);
2042 if ($list[$#list] !~ /^$start/) {
2043 fail "SHA1 $start not found";
2046 # go backwards in the list
2047 @list = reverse @list;
2049 my $save_clean = $noclean;
2052 foreach my $item (@list) {
2054 $sha1 =~ s/^([[:xdigit:]]+).*/$1/;
2056 doprint "\nProcessing commit $item\n\n";
2058 run_command "git checkout $sha1" or
2059 die "Failed to checkout $sha1";
2061 # only clean on the first and last patch
2062 if ($item eq $list[0] ||
2063 $item eq $list[$#list]) {
2064 $noclean = $save_clean;
2069 if (defined($minconfig)) {
2070 build "useconfig:$minconfig" or return 0;
2072 # ?? no config to use?
2073 build "oldconfig" or return 0;
2076 check_buildlog $sha1 or return 0;
2078 next if ($type eq "build");
2087 monitor or $failed = 1;
2089 if (!$failed && $type ne "boot"){
2090 do_run_test or $failed = 1;
2093 return 0 if ($failed);
2104 $#ARGV < 1 or die "ktest.pl version: $VERSION\n usage: ktest.pl config-file\n";
2107 $ktest_config = $ARGV[0];
2108 if (! -f $ktest_config) {
2109 print "$ktest_config does not exist.\n";
2112 print "Create it? [Y/n] ";
2115 if ($ans =~ /^\s*$/) {
2118 last if ($ans =~ /^y$/i || $ans =~ /^n$/i);
2119 print "Please answer either 'y' or 'n'.\n";
2121 if ($ans !~ /^y$/i) {
2126 $ktest_config = "ktest.conf";
2129 if (! -f $ktest_config) {
2130 open(OUT, ">$ktest_config") or die "Can not create $ktest_config";
2132 # Generated by ktest.pl
2134 # Define each test with TEST_START
2135 # The config options below it will override the defaults
2143 read_config $ktest_config;
2145 if (defined($opt{"LOG_FILE"})) {
2146 $opt{"LOG_FILE"} = eval_option($opt{"LOG_FILE"}, -1);
2149 # Append any configs entered in manually to the config file.
2150 my @new_configs = keys %entered_configs;
2151 if ($#new_configs >= 0) {
2152 print "\nAppending entered in configs to $ktest_config\n";
2153 open(OUT, ">>$ktest_config") or die "Can not append to $ktest_config";
2154 foreach my $config (@new_configs) {
2155 print OUT "$config = $entered_configs{$config}\n";
2156 $opt{$config} = $entered_configs{$config};
2160 if ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) {
2161 unlink $opt{"LOG_FILE"};
2164 doprint "\n\nSTARTING AUTOMATED TESTS\n\n";
2166 for (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) {
2169 doprint "DEFAULT OPTIONS:\n";
2171 doprint "\nTEST $i OPTIONS";
2172 if (defined($repeat_tests{$i})) {
2173 $repeat = $repeat_tests{$i};
2174 doprint " ITERATE $repeat";
2179 foreach my $option (sort keys %opt) {
2181 if ($option =~ /\[(\d+)\]$/) {
2187 doprint "$option = $opt{$option}\n";
2191 sub __set_test_option {
2192 my ($name, $i) = @_;
2194 my $option = "$name\[$i\]";
2196 if (defined($opt{$option})) {
2197 return $opt{$option};
2200 foreach my $test (keys %repeat_tests) {
2202 $i < $test + $repeat_tests{$test}) {
2203 $option = "$name\[$test\]";
2204 if (defined($opt{$option})) {
2205 return $opt{$option};
2210 if (defined($opt{$name})) {
2217 sub set_test_option {
2218 my ($name, $i) = @_;
2220 my $option = __set_test_option($name, $i);
2221 return $option if (!defined($option));
2223 return eval_option($option, $i);
2226 # First we need to do is the builds
2227 for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
2231 my $makecmd = set_test_option("MAKE_CMD", $i);
2233 $machine = set_test_option("MACHINE", $i);
2234 $ssh_user = set_test_option("SSH_USER", $i);
2235 $tmpdir = set_test_option("TMP_DIR", $i);
2236 $outputdir = set_test_option("OUTPUT_DIR", $i);
2237 $builddir = set_test_option("BUILD_DIR", $i);
2238 $test_type = set_test_option("TEST_TYPE", $i);
2239 $build_type = set_test_option("BUILD_TYPE", $i);
2240 $build_options = set_test_option("BUILD_OPTIONS", $i);
2241 $power_cycle = set_test_option("POWER_CYCLE", $i);
2242 $reboot = set_test_option("REBOOT", $i);
2243 $noclean = set_test_option("BUILD_NOCLEAN", $i);
2244 $minconfig = set_test_option("MIN_CONFIG", $i);
2245 $run_test = set_test_option("TEST", $i);
2246 $addconfig = set_test_option("ADD_CONFIG", $i);
2247 $reboot_type = set_test_option("REBOOT_TYPE", $i);
2248 $grub_menu = set_test_option("GRUB_MENU", $i);
2249 $post_install = set_test_option("POST_INSTALL", $i);
2250 $reboot_script = set_test_option("REBOOT_SCRIPT", $i);
2251 $reboot_on_error = set_test_option("REBOOT_ON_ERROR", $i);
2252 $poweroff_on_error = set_test_option("POWEROFF_ON_ERROR", $i);
2253 $die_on_failure = set_test_option("DIE_ON_FAILURE", $i);
2254 $power_off = set_test_option("POWER_OFF", $i);
2255 $powercycle_after_reboot = set_test_option("POWERCYCLE_AFTER_REBOOT", $i);
2256 $poweroff_after_halt = set_test_option("POWEROFF_AFTER_HALT", $i);
2257 $sleep_time = set_test_option("SLEEP_TIME", $i);
2258 $bisect_sleep_time = set_test_option("BISECT_SLEEP_TIME", $i);
2259 $patchcheck_sleep_time = set_test_option("PATCHCHECK_SLEEP_TIME", $i);
2260 $bisect_manual = set_test_option("BISECT_MANUAL", $i);
2261 $bisect_skip = set_test_option("BISECT_SKIP", $i);
2262 $config_bisect_good = set_test_option("CONFIG_BISECT_GOOD", $i);
2263 $store_failures = set_test_option("STORE_FAILURES", $i);
2264 $test_name = set_test_option("TEST_NAME", $i);
2265 $timeout = set_test_option("TIMEOUT", $i);
2266 $booted_timeout = set_test_option("BOOTED_TIMEOUT", $i);
2267 $console = set_test_option("CONSOLE", $i);
2268 $detect_triplefault = set_test_option("DETECT_TRIPLE_FAULT", $i);
2269 $success_line = set_test_option("SUCCESS_LINE", $i);
2270 $stop_after_success = set_test_option("STOP_AFTER_SUCCESS", $i);
2271 $stop_after_failure = set_test_option("STOP_AFTER_FAILURE", $i);
2272 $stop_test_after = set_test_option("STOP_TEST_AFTER", $i);
2273 $build_target = set_test_option("BUILD_TARGET", $i);
2274 $ssh_exec = set_test_option("SSH_EXEC", $i);
2275 $scp_to_target = set_test_option("SCP_TO_TARGET", $i);
2276 $target_image = set_test_option("TARGET_IMAGE", $i);
2277 $localversion = set_test_option("LOCALVERSION", $i);
2279 chdir $builddir || die "can't change directory to $builddir";
2283 die "can't create $tmpdir";
2286 $ENV{"SSH_USER"} = $ssh_user;
2287 $ENV{"MACHINE"} = $machine;
2289 $target = "$ssh_user\@$machine";
2291 $buildlog = "$tmpdir/buildlog-$machine";
2292 $dmesg = "$tmpdir/dmesg-$machine";
2293 $make = "$makecmd O=$outputdir";
2294 $output_config = "$outputdir/.config";
2296 if ($reboot_type eq "grub") {
2297 dodie "GRUB_MENU not defined" if (!defined($grub_menu));
2298 } elsif (!defined($reboot_script)) {
2299 dodie "REBOOT_SCRIPT not defined"
2302 my $run_type = $build_type;
2303 if ($test_type eq "patchcheck") {
2304 $run_type = $opt{"PATCHCHECK_TYPE[$i]"};
2305 } elsif ($test_type eq "bisect") {
2306 $run_type = $opt{"BISECT_TYPE[$i]"};
2307 } elsif ($test_type eq "config_bisect") {
2308 $run_type = $opt{"CONFIG_BISECT_TYPE[$i]"};
2311 # mistake in config file?
2312 if (!defined($run_type)) {
2313 $run_type = "ERROR";
2317 doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type\n\n";
2322 if (!defined($minconfig)) {
2323 $minconfig = $addconfig;
2325 } elsif (defined($addconfig)) {
2326 run_command "cat $addconfig $minconfig > $tmpdir/add_config" or
2327 dodie "Failed to create temp config";
2328 $minconfig = "$tmpdir/add_config";
2331 my $checkout = $opt{"CHECKOUT[$i]"};
2332 if (defined($checkout)) {
2333 run_command "git checkout $checkout" or
2334 die "failed to checkout $checkout";
2337 if ($test_type eq "bisect") {
2340 } elsif ($test_type eq "config_bisect") {
2343 } elsif ($test_type eq "patchcheck") {
2348 if ($build_type ne "nobuild") {
2349 build $build_type or next;
2352 if ($test_type ne "build") {
2359 monitor or $failed = 1;;
2361 if (!$failed && $test_type ne "boot" && defined($run_test)) {
2362 do_run_test or $failed = 1;
2371 if ($opt{"POWEROFF_ON_SUCCESS"}) {
2373 } elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot) {
2377 doprint "\n $successes of $opt{NUM_TESTS} tests were successful\n\n";