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;
1034 sub do_post_install {
1036 return if (!defined($post_install));
1038 my $cp_post_install = $post_install;
1039 $cp_post_install =~ s/\$KERNEL_VERSION/$version/g;
1040 run_command "$cp_post_install" or
1041 dodie "Failed to run post install";
1046 run_scp "$outputdir/$build_target", "$target_image" or
1047 dodie "failed to copy image";
1049 my $install_mods = 0;
1051 # should we process modules?
1053 open(IN, "$output_config") or dodie("Can't read config file");
1055 if (/CONFIG_MODULES(=y)?/) {
1056 $install_mods = 1 if (defined($1));
1062 if (!$install_mods) {
1064 doprint "No modules needed\n";
1068 run_command "$make INSTALL_MOD_PATH=$tmpdir modules_install" or
1069 dodie "Failed to install modules";
1071 my $modlib = "/lib/modules/$version";
1072 my $modtar = "ktest-mods.tar.bz2";
1074 run_ssh "rm -rf $modlib" or
1075 dodie "failed to remove old mods: $modlib";
1077 # would be nice if scp -r did not follow symbolic links
1078 run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or
1079 dodie "making tarball";
1081 run_scp "$tmpdir/$modtar", "/tmp" or
1082 dodie "failed to copy modules";
1084 unlink "$tmpdir/$modtar";
1086 run_ssh "'(cd / && tar xf /tmp/$modtar)'" or
1087 dodie "failed to tar modules";
1089 run_ssh "rm -f /tmp/$modtar";
1094 sub check_buildlog {
1097 my @files = `git show $patch | diffstat -l`;
1099 open(IN, "git show $patch |") or
1100 dodie "failed to show $patch";
1102 if (m,^--- a/(.*),) {
1104 $files[$#files] = $1;
1109 open(IN, $buildlog) or dodie "Can't open $buildlog";
1111 if (/^\s*(.*?):.*(warning|error)/) {
1113 foreach my $file (@files) {
1114 my $fullpath = "$builddir/$file";
1115 if ($file eq $err || $fullpath eq $err) {
1116 fail "$file built with warnings" and return 0;
1126 sub apply_min_config {
1127 my $outconfig = "$output_config.new";
1129 # Read the config file and remove anything that
1130 # is in the force_config hash (from minconfig and others)
1131 # then add the force config back.
1133 doprint "Applying minimum configurations into $output_config.new\n";
1135 open (OUT, ">$outconfig") or
1136 dodie "Can't create $outconfig";
1138 if (-f $output_config) {
1139 open (IN, $output_config) or
1140 dodie "Failed to open $output_config";
1142 if (/^(# )?(CONFIG_[^\s=]*)/) {
1143 next if (defined($force_config{$2}));
1149 foreach my $config (keys %force_config) {
1150 print OUT "$force_config{$config}\n";
1154 run_command "mv $outconfig $output_config";
1157 sub make_oldconfig {
1161 if (!run_command "$make oldnoconfig") {
1162 # Perhaps oldnoconfig doesn't exist in this version of the kernel
1163 # try a yes '' | oldconfig
1164 doprint "oldnoconfig failed, trying yes '' | make oldconfig\n";
1165 run_command "yes '' | $make oldconfig" or
1166 dodie "failed make config oldconfig";
1170 # read a config file and use this to force new configs.
1171 sub load_force_config {
1174 open(IN, $config) or
1175 dodie "failed to read $config";
1178 if (/^(CONFIG[^\s=]*)(\s*=.*)/) {
1179 $force_config{$1} = $_;
1180 } elsif (/^# (CONFIG_\S*) is not set/) {
1181 $force_config{$1} = $_;
1192 if ($type =~ /^useconfig:(.*)/) {
1193 run_command "cp $1 $output_config" or
1194 dodie "could not copy $1 to .config";
1196 $type = "oldconfig";
1199 # old config can ask questions
1200 if ($type eq "oldconfig") {
1201 $type = "oldnoconfig";
1203 # allow for empty configs
1204 run_command "touch $output_config";
1206 run_command "mv $output_config $outputdir/config_temp" or
1207 dodie "moving .config";
1209 if (!$noclean && !run_command "$make mrproper") {
1210 dodie "make mrproper";
1213 run_command "mv $outputdir/config_temp $output_config" or
1214 dodie "moving config_temp";
1216 } elsif (!$noclean) {
1217 unlink "$output_config";
1218 run_command "$make mrproper" or
1219 dodie "make mrproper";
1222 # add something to distinguish this build
1223 open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file");
1224 print OUT "$localversion\n";
1227 if (defined($minconfig)) {
1228 load_force_config($minconfig);
1231 if ($type ne "oldnoconfig") {
1232 run_command "$make $type" or
1233 dodie "failed make config";
1235 # Run old config regardless, to enforce min configurations
1238 $redirect = "$buildlog";
1239 if (!run_command "$make $build_options") {
1241 # bisect may need this to pass
1242 return 0 if ($in_bisect);
1243 fail "failed build" and return 0;
1251 if (!run_ssh "halt" or defined($power_off)) {
1252 if (defined($poweroff_after_halt)) {
1253 sleep $poweroff_after_halt;
1254 run_command "$power_off";
1258 run_command "$power_off";
1269 if (defined($test_name)) {
1270 $name = " ($test_name)";
1273 doprint "\n\n*******************************************\n";
1274 doprint "*******************************************\n";
1275 doprint "KTEST RESULT: TEST $i$name SUCCESS!!!! **\n";
1276 doprint "*******************************************\n";
1277 doprint "*******************************************\n";
1279 if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) {
1280 doprint "Reboot and wait $sleep_time seconds\n";
1283 wait_for_monitor $sleep_time;
1289 # get the release name
1290 doprint "$make kernelrelease ... ";
1291 $version = `$make kernelrelease | tail -1`;
1293 doprint "$version\n";
1298 doprint "Pass or fail? [p/f]";
1301 if ($ans eq "p" || $ans eq "P") {
1303 } elsif ($ans eq "f" || $ans eq "F") {
1306 print "Please answer 'P' or 'F'\n";
1311 sub child_run_test {
1314 # child should have no power
1315 $reboot_on_error = 0;
1316 $poweroff_on_error = 0;
1317 $die_on_failure = 1;
1319 run_command $run_test or $failed = 1;
1325 sub child_finished {
1338 doprint "run test $run_test\n";
1342 $SIG{CHLD} = qw(child_finished);
1346 child_run_test if (!$child_pid);
1351 $line = wait_for_input($monitor_fp, 1);
1352 if (defined($line)) {
1354 # we are not guaranteed to get a full line
1355 $full_line .= $line;
1358 if ($full_line =~ /call trace:/i) {
1362 if ($full_line =~ /Kernel panic -/) {
1366 if ($line =~ /\n/) {
1370 } while (!$child_done && !$bug);
1373 my $failure_start = time;
1376 $line = wait_for_input($monitor_fp, 1);
1377 if (defined($line)) {
1381 if ($now - $failure_start >= $stop_after_failure) {
1384 } while (defined($line));
1386 doprint "Detected kernel crash!\n";
1387 # kill the child with extreme prejudice
1391 waitpid $child_pid, 0;
1394 if ($bug || $child_exit) {
1395 return 0 if $in_bisect;
1396 fail "test failed" and return 0;
1401 sub run_git_bisect {
1404 doprint "$command ... ";
1406 my $output = `$command 2>&1`;
1413 dodie "Failed to git bisect";
1416 doprint "SUCCESS\n";
1417 if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) {
1418 doprint "$1 [$2]\n";
1419 } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) {
1421 doprint "Found bad commit... $1\n";
1424 # we already logged it, just print it now.
1432 doprint "Reboot and sleep $bisect_sleep_time seconds\n";
1435 wait_for_monitor $bisect_sleep_time;
1439 # returns 1 on success, 0 on failure, -1 on skip
1440 sub run_bisect_test {
1441 my ($type, $buildtype) = @_;
1450 build $buildtype or $failed = 1;
1452 if ($type ne "build") {
1453 if ($failed && $bisect_skip) {
1457 dodie "Failed on build" if $failed;
1465 monitor or $failed = 1;
1467 if ($type ne "boot") {
1468 if ($failed && $bisect_skip) {
1474 dodie "Failed on boot" if $failed;
1476 do_run_test or $failed = 1;
1487 # reboot the box to a kernel we can ssh to
1488 if ($type ne "build") {
1498 my $buildtype = "oldconfig";
1500 # We should have a minconfig to use?
1501 if (defined($minconfig)) {
1502 $buildtype = "useconfig:$minconfig";
1505 my $ret = run_bisect_test $type, $buildtype;
1507 if ($bisect_manual) {
1508 $ret = answer_bisect;
1511 # Are we looking for where it worked, not failed?
1512 if ($reverse_bisect) {
1518 } elsif ($ret == 0) {
1520 } elsif ($bisect_skip) {
1521 doprint "HIT A BAD COMMIT ... SKIPPING\n";
1531 die "BISECT_GOOD[$i] not defined\n" if (!defined($opt{"BISECT_GOOD[$i]"}));
1532 die "BISECT_BAD[$i] not defined\n" if (!defined($opt{"BISECT_BAD[$i]"}));
1533 die "BISECT_TYPE[$i] not defined\n" if (!defined($opt{"BISECT_TYPE[$i]"}));
1535 my $good = $opt{"BISECT_GOOD[$i]"};
1536 my $bad = $opt{"BISECT_BAD[$i]"};
1537 my $type = $opt{"BISECT_TYPE[$i]"};
1538 my $start = $opt{"BISECT_START[$i]"};
1539 my $replay = $opt{"BISECT_REPLAY[$i]"};
1540 my $start_files = $opt{"BISECT_FILES[$i]"};
1542 if (defined($start_files)) {
1543 $start_files = " -- " . $start_files;
1548 # convert to true sha1's
1549 $good = get_sha1($good);
1550 $bad = get_sha1($bad);
1552 if (defined($opt{"BISECT_REVERSE[$i]"}) &&
1553 $opt{"BISECT_REVERSE[$i]"} == 1) {
1554 doprint "Performing a reverse bisect (bad is good, good is bad!)\n";
1555 $reverse_bisect = 1;
1557 $reverse_bisect = 0;
1560 # Can't have a test without having a test to run
1561 if ($type eq "test" && !defined($run_test)) {
1565 my $check = $opt{"BISECT_CHECK[$i]"};
1566 if (defined($check) && $check ne "0") {
1569 my $head = get_sha1("HEAD");
1571 if ($check ne "good") {
1572 doprint "TESTING BISECT BAD [$bad]\n";
1573 run_command "git checkout $bad" or
1574 die "Failed to checkout $bad";
1576 $result = run_bisect $type;
1578 if ($result ne "bad") {
1579 fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0;
1583 if ($check ne "bad") {
1584 doprint "TESTING BISECT GOOD [$good]\n";
1585 run_command "git checkout $good" or
1586 die "Failed to checkout $good";
1588 $result = run_bisect $type;
1590 if ($result ne "good") {
1591 fail "Tested BISECT_GOOD [$good] and it failed" and return 0;
1595 # checkout where we started
1596 run_command "git checkout $head" or
1597 die "Failed to checkout $head";
1600 run_command "git bisect start$start_files" or
1601 dodie "could not start bisect";
1603 run_command "git bisect good $good" or
1604 dodie "could not set bisect good to $good";
1606 run_git_bisect "git bisect bad $bad" or
1607 dodie "could not set bisect bad to $bad";
1609 if (defined($replay)) {
1610 run_command "git bisect replay $replay" or
1611 dodie "failed to run replay";
1614 if (defined($start)) {
1615 run_command "git checkout $start" or
1616 dodie "failed to checkout $start";
1621 $result = run_bisect $type;
1622 $test = run_git_bisect "git bisect $result";
1625 run_command "git bisect log" or
1626 dodie "could not capture git bisect log";
1628 run_command "git bisect reset" or
1629 dodie "could not reset git bisect";
1631 doprint "Bad commit was [$bisect_bad]\n";
1644 sub process_config_ignore {
1648 or dodie "Failed to read $config";
1651 if (/^((CONFIG\S*)=.*)/) {
1652 $config_ignore{$2} = $1;
1659 sub read_current_config {
1660 my ($config_ref) = @_;
1662 %{$config_ref} = ();
1663 undef %{$config_ref};
1665 my @key = keys %{$config_ref};
1667 print "did not delete!\n";
1670 open (IN, "$output_config");
1673 if (/^(CONFIG\S+)=(.*)/) {
1674 ${$config_ref}{$1} = $2;
1680 sub get_dependencies {
1683 my $arr = $dependency{$config};
1684 if (!defined($arr)) {
1690 foreach my $dep (@{$arr}) {
1691 print "ADD DEP $dep\n";
1692 @deps = (@deps, get_dependencies $dep);
1701 open(OUT, ">$output_config") or dodie "Can not write to $output_config";
1703 foreach my $config (@configs) {
1704 print OUT "$config_set{$config}\n";
1705 my @deps = get_dependencies $config;
1706 foreach my $dep (@deps) {
1707 print OUT "$config_set{$dep}\n";
1711 foreach my $config (keys %config_ignore) {
1712 print OUT "$config_ignore{$config}\n";
1720 sub compare_configs {
1723 foreach my $item (keys %a) {
1724 if (!defined($b{$item})) {
1725 print "diff $item\n";
1733 print "diff2 $keys[0]\n";
1735 return -1 if ($#keys >= 0);
1740 sub run_config_bisect_test {
1743 return run_bisect_test $type, "oldconfig";
1746 sub process_passed {
1749 doprint "These configs had no failure: (Enabling them for further compiles)\n";
1750 # Passed! All these configs are part of a good compile.
1751 # Add them to the min options.
1752 foreach my $config (keys %configs) {
1753 if (defined($config_list{$config})) {
1754 doprint " removing $config\n";
1755 $config_ignore{$config} = $config_list{$config};
1756 delete $config_list{$config};
1759 doprint "config copied to $outputdir/config_good\n";
1760 run_command "cp -f $output_config $outputdir/config_good";
1763 sub process_failed {
1766 doprint "\n\n***************************************\n";
1767 doprint "Found bad config: $config\n";
1768 doprint "***************************************\n\n";
1771 sub run_config_bisect {
1773 my @start_list = keys %config_list;
1775 if ($#start_list < 0) {
1776 doprint "No more configs to test!!!\n";
1780 doprint "***** RUN TEST ***\n";
1781 my $type = $opt{"CONFIG_BISECT_TYPE[$iteration]"};
1785 my $count = $#start_list + 1;
1786 doprint " $count configs to test\n";
1788 my $half = int($#start_list / 2);
1791 my @tophalf = @start_list[0 .. $half];
1793 create_config @tophalf;
1794 read_current_config \%current_config;
1796 $count = $#tophalf + 1;
1797 doprint "Testing $count configs\n";
1799 # make sure we test something
1800 foreach my $config (@tophalf) {
1801 if (defined($current_config{$config})) {
1807 # try the other half
1808 doprint "Top half produced no set configs, trying bottom half\n";
1809 @tophalf = @start_list[$half + 1 .. $#start_list];
1810 create_config @tophalf;
1811 read_current_config \%current_config;
1812 foreach my $config (@tophalf) {
1813 if (defined($current_config{$config})) {
1819 doprint "Failed: Can't make new config with current configs\n";
1820 foreach my $config (@start_list) {
1821 doprint " CONFIG: $config\n";
1825 $count = $#tophalf + 1;
1826 doprint "Testing $count configs\n";
1829 $ret = run_config_bisect_test $type;
1830 if ($bisect_manual) {
1831 $ret = answer_bisect;
1834 process_passed %current_config;
1838 doprint "This config had a failure.\n";
1839 doprint "Removing these configs that were not set in this config:\n";
1840 doprint "config copied to $outputdir/config_bad\n";
1841 run_command "cp -f $output_config $outputdir/config_bad";
1843 # A config exists in this group that was bad.
1844 foreach my $config (keys %config_list) {
1845 if (!defined($current_config{$config})) {
1846 doprint " removing $config\n";
1847 delete $config_list{$config};
1851 @start_list = @tophalf;
1853 if ($#start_list == 0) {
1854 process_failed $start_list[0];
1858 # remove half the configs we are looking at and see if
1860 $half = int($#start_list / 2);
1861 } while ($#start_list > 0);
1863 # we found a single config, try it again unless we are running manually
1865 if ($bisect_manual) {
1866 process_failed $start_list[0];
1870 my @tophalf = @start_list[0 .. 0];
1872 $ret = run_config_bisect_test $type;
1874 process_passed %current_config;
1878 process_failed $start_list[0];
1885 my $start_config = $opt{"CONFIG_BISECT[$i]"};
1887 my $tmpconfig = "$tmpdir/use_config";
1889 if (defined($config_bisect_good)) {
1890 process_config_ignore $config_bisect_good;
1893 # Make the file with the bad config and the min config
1894 if (defined($minconfig)) {
1895 # read the min config for things to ignore
1896 run_command "cp $minconfig $tmpconfig" or
1897 dodie "failed to copy $minconfig to $tmpconfig";
1903 if (defined($addconfig)) {
1904 run_command "cat $addconfig >> $tmpconfig" or
1905 dodie "failed to append $addconfig";
1908 if (-f $tmpconfig) {
1909 load_force_config($tmpconfig);
1910 process_config_ignore $tmpconfig;
1913 # now process the start config
1914 run_command "cp $start_config $output_config" or
1915 dodie "failed to copy $start_config to $output_config";
1917 # read directly what we want to check
1919 open (IN, $output_config)
1920 or dodie "faied to open $output_config";
1923 if (/^((CONFIG\S*)=.*)/) {
1924 $config_check{$2} = $1;
1929 # Now run oldconfig with the minconfig (and addconfigs)
1932 # check to see what we lost (or gained)
1933 open (IN, $output_config)
1934 or dodie "Failed to read $start_config";
1936 my %removed_configs;
1940 if (/^((CONFIG\S*)=.*)/) {
1941 # save off all options
1942 $config_set{$2} = $1;
1943 if (defined($config_check{$2})) {
1944 if (defined($config_ignore{$2})) {
1945 $removed_configs{$2} = $1;
1947 $config_list{$2} = $1;
1949 } elsif (!defined($config_ignore{$2})) {
1950 $added_configs{$2} = $1;
1951 $config_list{$2} = $1;
1957 my @confs = keys %removed_configs;
1959 doprint "Configs overridden by default configs and removed from check:\n";
1960 foreach my $config (@confs) {
1961 doprint " $config\n";
1964 @confs = keys %added_configs;
1966 doprint "Configs appearing in make oldconfig and added:\n";
1967 foreach my $config (@confs) {
1968 doprint " $config\n";
1975 # Sometimes kconfig does weird things. We must make sure
1976 # that the config we autocreate has everything we need
1977 # to test, otherwise we may miss testing configs, or
1978 # may not be able to create a new config.
1979 # Here we create a config with everything set.
1980 create_config (keys %config_list);
1981 read_current_config \%config_test;
1982 foreach my $config (keys %config_list) {
1983 if (!defined($config_test{$config})) {
1986 doprint "Configs not produced by kconfig (will not be checked):\n";
1988 doprint " $config\n";
1989 delete $config_list{$config};
1994 $ret = run_config_bisect;
1997 return $ret if ($ret < 0);
2002 sub patchcheck_reboot {
2003 doprint "Reboot and sleep $patchcheck_sleep_time seconds\n";
2006 wait_for_monitor $patchcheck_sleep_time;
2013 die "PATCHCHECK_START[$i] not defined\n"
2014 if (!defined($opt{"PATCHCHECK_START[$i]"}));
2015 die "PATCHCHECK_TYPE[$i] not defined\n"
2016 if (!defined($opt{"PATCHCHECK_TYPE[$i]"}));
2018 my $start = $opt{"PATCHCHECK_START[$i]"};
2021 if (defined($opt{"PATCHCHECK_END[$i]"})) {
2022 $end = $opt{"PATCHCHECK_END[$i]"};
2025 # Get the true sha1's since we can use things like HEAD~3
2026 $start = get_sha1($start);
2027 $end = get_sha1($end);
2029 my $type = $opt{"PATCHCHECK_TYPE[$i]"};
2031 # Can't have a test without having a test to run
2032 if ($type eq "test" && !defined($run_test)) {
2036 open (IN, "git log --pretty=oneline $end|") or
2037 dodie "could not get git list";
2043 $list[$#list+1] = $_;
2044 last if (/^$start/);
2048 if ($list[$#list] !~ /^$start/) {
2049 fail "SHA1 $start not found";
2052 # go backwards in the list
2053 @list = reverse @list;
2055 my $save_clean = $noclean;
2058 foreach my $item (@list) {
2060 $sha1 =~ s/^([[:xdigit:]]+).*/$1/;
2062 doprint "\nProcessing commit $item\n\n";
2064 run_command "git checkout $sha1" or
2065 die "Failed to checkout $sha1";
2067 # only clean on the first and last patch
2068 if ($item eq $list[0] ||
2069 $item eq $list[$#list]) {
2070 $noclean = $save_clean;
2075 if (defined($minconfig)) {
2076 build "useconfig:$minconfig" or return 0;
2078 # ?? no config to use?
2079 build "oldconfig" or return 0;
2082 check_buildlog $sha1 or return 0;
2084 next if ($type eq "build");
2093 monitor or $failed = 1;
2095 if (!$failed && $type ne "boot"){
2096 do_run_test or $failed = 1;
2099 return 0 if ($failed);
2110 $#ARGV < 1 or die "ktest.pl version: $VERSION\n usage: ktest.pl config-file\n";
2113 $ktest_config = $ARGV[0];
2114 if (! -f $ktest_config) {
2115 print "$ktest_config does not exist.\n";
2118 print "Create it? [Y/n] ";
2121 if ($ans =~ /^\s*$/) {
2124 last if ($ans =~ /^y$/i || $ans =~ /^n$/i);
2125 print "Please answer either 'y' or 'n'.\n";
2127 if ($ans !~ /^y$/i) {
2132 $ktest_config = "ktest.conf";
2135 if (! -f $ktest_config) {
2136 open(OUT, ">$ktest_config") or die "Can not create $ktest_config";
2138 # Generated by ktest.pl
2140 # Define each test with TEST_START
2141 # The config options below it will override the defaults
2149 read_config $ktest_config;
2151 if (defined($opt{"LOG_FILE"})) {
2152 $opt{"LOG_FILE"} = eval_option($opt{"LOG_FILE"}, -1);
2155 # Append any configs entered in manually to the config file.
2156 my @new_configs = keys %entered_configs;
2157 if ($#new_configs >= 0) {
2158 print "\nAppending entered in configs to $ktest_config\n";
2159 open(OUT, ">>$ktest_config") or die "Can not append to $ktest_config";
2160 foreach my $config (@new_configs) {
2161 print OUT "$config = $entered_configs{$config}\n";
2162 $opt{$config} = $entered_configs{$config};
2166 if ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) {
2167 unlink $opt{"LOG_FILE"};
2170 doprint "\n\nSTARTING AUTOMATED TESTS\n\n";
2172 for (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) {
2175 doprint "DEFAULT OPTIONS:\n";
2177 doprint "\nTEST $i OPTIONS";
2178 if (defined($repeat_tests{$i})) {
2179 $repeat = $repeat_tests{$i};
2180 doprint " ITERATE $repeat";
2185 foreach my $option (sort keys %opt) {
2187 if ($option =~ /\[(\d+)\]$/) {
2193 doprint "$option = $opt{$option}\n";
2197 sub __set_test_option {
2198 my ($name, $i) = @_;
2200 my $option = "$name\[$i\]";
2202 if (defined($opt{$option})) {
2203 return $opt{$option};
2206 foreach my $test (keys %repeat_tests) {
2208 $i < $test + $repeat_tests{$test}) {
2209 $option = "$name\[$test\]";
2210 if (defined($opt{$option})) {
2211 return $opt{$option};
2216 if (defined($opt{$name})) {
2223 sub set_test_option {
2224 my ($name, $i) = @_;
2226 my $option = __set_test_option($name, $i);
2227 return $option if (!defined($option));
2229 return eval_option($option, $i);
2232 # First we need to do is the builds
2233 for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
2237 my $makecmd = set_test_option("MAKE_CMD", $i);
2239 $machine = set_test_option("MACHINE", $i);
2240 $ssh_user = set_test_option("SSH_USER", $i);
2241 $tmpdir = set_test_option("TMP_DIR", $i);
2242 $outputdir = set_test_option("OUTPUT_DIR", $i);
2243 $builddir = set_test_option("BUILD_DIR", $i);
2244 $test_type = set_test_option("TEST_TYPE", $i);
2245 $build_type = set_test_option("BUILD_TYPE", $i);
2246 $build_options = set_test_option("BUILD_OPTIONS", $i);
2247 $power_cycle = set_test_option("POWER_CYCLE", $i);
2248 $reboot = set_test_option("REBOOT", $i);
2249 $noclean = set_test_option("BUILD_NOCLEAN", $i);
2250 $minconfig = set_test_option("MIN_CONFIG", $i);
2251 $run_test = set_test_option("TEST", $i);
2252 $addconfig = set_test_option("ADD_CONFIG", $i);
2253 $reboot_type = set_test_option("REBOOT_TYPE", $i);
2254 $grub_menu = set_test_option("GRUB_MENU", $i);
2255 $post_install = set_test_option("POST_INSTALL", $i);
2256 $reboot_script = set_test_option("REBOOT_SCRIPT", $i);
2257 $reboot_on_error = set_test_option("REBOOT_ON_ERROR", $i);
2258 $poweroff_on_error = set_test_option("POWEROFF_ON_ERROR", $i);
2259 $die_on_failure = set_test_option("DIE_ON_FAILURE", $i);
2260 $power_off = set_test_option("POWER_OFF", $i);
2261 $powercycle_after_reboot = set_test_option("POWERCYCLE_AFTER_REBOOT", $i);
2262 $poweroff_after_halt = set_test_option("POWEROFF_AFTER_HALT", $i);
2263 $sleep_time = set_test_option("SLEEP_TIME", $i);
2264 $bisect_sleep_time = set_test_option("BISECT_SLEEP_TIME", $i);
2265 $patchcheck_sleep_time = set_test_option("PATCHCHECK_SLEEP_TIME", $i);
2266 $bisect_manual = set_test_option("BISECT_MANUAL", $i);
2267 $bisect_skip = set_test_option("BISECT_SKIP", $i);
2268 $config_bisect_good = set_test_option("CONFIG_BISECT_GOOD", $i);
2269 $store_failures = set_test_option("STORE_FAILURES", $i);
2270 $test_name = set_test_option("TEST_NAME", $i);
2271 $timeout = set_test_option("TIMEOUT", $i);
2272 $booted_timeout = set_test_option("BOOTED_TIMEOUT", $i);
2273 $console = set_test_option("CONSOLE", $i);
2274 $detect_triplefault = set_test_option("DETECT_TRIPLE_FAULT", $i);
2275 $success_line = set_test_option("SUCCESS_LINE", $i);
2276 $stop_after_success = set_test_option("STOP_AFTER_SUCCESS", $i);
2277 $stop_after_failure = set_test_option("STOP_AFTER_FAILURE", $i);
2278 $stop_test_after = set_test_option("STOP_TEST_AFTER", $i);
2279 $build_target = set_test_option("BUILD_TARGET", $i);
2280 $ssh_exec = set_test_option("SSH_EXEC", $i);
2281 $scp_to_target = set_test_option("SCP_TO_TARGET", $i);
2282 $target_image = set_test_option("TARGET_IMAGE", $i);
2283 $localversion = set_test_option("LOCALVERSION", $i);
2285 chdir $builddir || die "can't change directory to $builddir";
2289 die "can't create $tmpdir";
2292 $ENV{"SSH_USER"} = $ssh_user;
2293 $ENV{"MACHINE"} = $machine;
2295 $target = "$ssh_user\@$machine";
2297 $buildlog = "$tmpdir/buildlog-$machine";
2298 $dmesg = "$tmpdir/dmesg-$machine";
2299 $make = "$makecmd O=$outputdir";
2300 $output_config = "$outputdir/.config";
2302 if ($reboot_type eq "grub") {
2303 dodie "GRUB_MENU not defined" if (!defined($grub_menu));
2304 } elsif (!defined($reboot_script)) {
2305 dodie "REBOOT_SCRIPT not defined"
2308 my $run_type = $build_type;
2309 if ($test_type eq "patchcheck") {
2310 $run_type = $opt{"PATCHCHECK_TYPE[$i]"};
2311 } elsif ($test_type eq "bisect") {
2312 $run_type = $opt{"BISECT_TYPE[$i]"};
2313 } elsif ($test_type eq "config_bisect") {
2314 $run_type = $opt{"CONFIG_BISECT_TYPE[$i]"};
2317 # mistake in config file?
2318 if (!defined($run_type)) {
2319 $run_type = "ERROR";
2323 doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type\n\n";
2328 if (!defined($minconfig)) {
2329 $minconfig = $addconfig;
2331 } elsif (defined($addconfig)) {
2332 run_command "cat $addconfig $minconfig > $tmpdir/add_config" or
2333 dodie "Failed to create temp config";
2334 $minconfig = "$tmpdir/add_config";
2337 my $checkout = $opt{"CHECKOUT[$i]"};
2338 if (defined($checkout)) {
2339 run_command "git checkout $checkout" or
2340 die "failed to checkout $checkout";
2343 if ($test_type eq "bisect") {
2346 } elsif ($test_type eq "config_bisect") {
2349 } elsif ($test_type eq "patchcheck") {
2354 if ($build_type ne "nobuild") {
2355 build $build_type or next;
2358 if ($test_type ne "build") {
2365 monitor or $failed = 1;;
2367 if (!$failed && $test_type ne "boot" && defined($run_test)) {
2368 do_run_test or $failed = 1;
2377 if ($opt{"POWEROFF_ON_SUCCESS"}) {
2379 } elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot) {
2383 doprint "\n $successes of $opt{NUM_TESTS} tests were successful\n\n";