3 # Copywrite 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{"CLEAR_LOG"} = 0;
40 $default{"SUCCESS_LINE"} = "login:";
41 $default{"BOOTED_TIMEOUT"} = 1;
42 $default{"DIE_ON_FAILURE"} = 1;
43 $default{"SSH_EXEC"} = "ssh \$SSH_USER\@\$MACHINE \$SSH_COMMAND";
44 $default{"SCP_TO_TARGET"} = "scp \$SRC_FILE \$SSH_USER\@\$MACHINE:\$DST_FILE";
45 $default{"REBOOT"} = "ssh \$SSH_USER\@\$MACHINE reboot";
46 $default{"STOP_AFTER_SUCCESS"} = 10;
47 $default{"STOP_AFTER_FAILURE"} = 60;
48 $default{"LOCALVERSION"} = "-test";
66 my $poweroff_on_error;
68 my $powercycle_after_reboot;
69 my $poweroff_after_halt;
84 my $in_patchcheck = 0;
93 my $bisect_sleep_time;
99 my $stop_after_success;
100 my $stop_after_failure;
110 $config_help{"MACHINE"} = << "EOF"
111 The machine hostname that you will test.
114 $config_help{"SSH_USER"} = << "EOF"
115 The box is expected to have ssh on normal bootup, provide the user
116 (most likely root, since you need privileged operations)
119 $config_help{"BUILD_DIR"} = << "EOF"
120 The directory that contains the Linux source code (full path).
123 $config_help{"OUTPUT_DIR"} = << "EOF"
124 The directory that the objects will be built (full path).
125 (can not be same as BUILD_DIR)
128 $config_help{"BUILD_TARGET"} = << "EOF"
129 The location of the compiled file to copy to the target.
130 (relative to OUTPUT_DIR)
133 $config_help{"TARGET_IMAGE"} = << "EOF"
134 The place to put your image on the test machine.
137 $config_help{"POWER_CYCLE"} = << "EOF"
138 A script or command to reboot the box.
140 Here is a digital loggers power switch example
141 POWER_CYCLE = wget --no-proxy -O /dev/null -q --auth-no-challenge 'http://admin:admin\@power/outlet?5=CCL'
143 Here is an example to reboot a virtual box on the current host
144 with the name "Guest".
145 POWER_CYCLE = virsh destroy Guest; sleep 5; virsh start Guest
148 $config_help{"CONSOLE"} = << "EOF"
149 The script or command that reads the console
151 If you use ttywatch server, something like the following would work.
152 CONSOLE = nc -d localhost 3001
154 For a virtual machine with guest name "Guest".
155 CONSOLE = virsh console Guest
158 $config_help{"LOCALVERSION"} = << "EOF"
159 Required version ending to differentiate the test
160 from other linux builds on the system.
163 $config_help{"REBOOT_TYPE"} = << "EOF"
164 Way to reboot the box to the test kernel.
165 Only valid options so far are "grub" and "script".
167 If you specify grub, it will assume grub version 1
168 and will search in /boot/grub/menu.lst for the title \$GRUB_MENU
169 and select that target to reboot to the kernel. If this is not
170 your setup, then specify "script" and have a command or script
171 specified in REBOOT_SCRIPT to boot to the target.
173 The entry in /boot/grub/menu.lst must be entered in manually.
174 The test will not modify that file.
177 $config_help{"GRUB_MENU"} = << "EOF"
178 The grub title name for the test kernel to boot
179 (Only mandatory if REBOOT_TYPE = grub)
181 Note, ktest.pl will not update the grub menu.lst, you need to
182 manually add an option for the test. ktest.pl will search
183 the grub menu.lst for this option to find what kernel to
186 For example, if in the /boot/grub/menu.lst the test kernel title has:
189 GRUB_MENU = Test Kernel
192 $config_help{"REBOOT_SCRIPT"} = << "EOF"
193 A script to reboot the target into the test kernel
194 (Only mandatory if REBOOT_TYPE = script)
199 sub get_ktest_config {
202 return if (defined($opt{$config}));
204 if (defined($config_help{$config})) {
206 print $config_help{$config};
211 if (defined($default{$config})) {
212 print "\[$default{$config}\] ";
214 $entered_configs{$config} = <STDIN>;
215 $entered_configs{$config} =~ s/^\s*(.*\S)\s*$/$1/;
216 if ($entered_configs{$config} =~ /^\s*$/) {
217 if ($default{$config}) {
218 $entered_configs{$config} = $default{$config};
220 print "Your answer can not be blank\n";
228 sub get_ktest_configs {
229 get_ktest_config("MACHINE");
230 get_ktest_config("SSH_USER");
231 get_ktest_config("BUILD_DIR");
232 get_ktest_config("OUTPUT_DIR");
233 get_ktest_config("BUILD_TARGET");
234 get_ktest_config("TARGET_IMAGE");
235 get_ktest_config("POWER_CYCLE");
236 get_ktest_config("CONSOLE");
237 get_ktest_config("LOCALVERSION");
239 my $rtype = $opt{"REBOOT_TYPE"};
241 if (!defined($rtype)) {
242 if (!defined($opt{"GRUB_MENU"})) {
243 get_ktest_config("REBOOT_TYPE");
244 $rtype = $entered_configs{"REBOOT_TYPE"};
250 if ($rtype eq "grub") {
251 get_ktest_config("GRUB_MENU");
253 get_ktest_config("REBOOT_SCRIPT");
258 my ($lvalue, $rvalue) = @_;
260 if (defined($opt{$lvalue})) {
261 die "Error: Option $lvalue defined more than once!\n";
263 if ($rvalue =~ /^\s*$/) {
264 delete $opt{$lvalue};
266 $opt{$lvalue} = $rvalue;
273 open(IN, $config) || die "can't read file $config";
276 $name =~ s,.*/(.*),$1,;
281 my $num_tests_set = 0;
287 # ignore blank lines and comments
288 next if (/^\s*$/ || /\s*\#/);
290 if (/^\s*TEST_START(.*)/) {
294 if ($num_tests_set) {
295 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
298 my $old_test_num = $test_num;
299 my $old_repeat = $repeat;
301 $test_num += $repeat;
305 if ($rest =~ /\s+SKIP(.*)/) {
312 if ($rest =~ /\s+ITERATE\s+(\d+)(.*)$/) {
315 $repeat_tests{"$test_num"} = $repeat;
318 if ($rest =~ /\s+SKIP(.*)/) {
323 if ($rest !~ /^\s*$/) {
324 die "$name: $.: Gargbage found after TEST_START\n$_";
328 $test_num = $old_test_num;
329 $repeat = $old_repeat;
332 } elsif (/^\s*DEFAULTS(.*)$/) {
337 if ($rest =~ /\s+SKIP(.*)/) {
344 if ($rest !~ /^\s*$/) {
345 die "$name: $.: Gargbage found after DEFAULTS\n$_";
348 } elsif (/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) {
356 ($lvalue eq "NUM_TESTS" ||
357 $lvalue eq "LOG_FILE" ||
358 $lvalue eq "CLEAR_LOG")) {
359 die "$name: $.: $lvalue must be set in DEFAULTS section\n";
362 if ($lvalue eq "NUM_TESTS") {
364 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
367 die "$name: $.: NUM_TESTS must be set in default section\n";
372 if ($default || $lvalue =~ /\[\d+\]$/) {
373 set_value($lvalue, $rvalue);
375 my $val = "$lvalue\[$test_num\]";
376 set_value($val, $rvalue);
379 $repeats{$val} = $repeat;
383 die "$name: $.: Garbage found in config\n$_";
390 $test_num += $repeat - 1;
391 $opt{"NUM_TESTS"} = $test_num;
394 # make sure we have all mandatory configs
399 foreach my $default (keys %default) {
400 if (!defined($opt{$default})) {
401 $opt{$default} = $default{$default};
407 if (defined($opt{"LOG_FILE"})) {
408 open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}";
415 if (defined($opt{"LOG_FILE"})) {
430 # try to reboot normally
431 if (run_command $reboot) {
432 if (defined($powercycle_after_reboot)) {
433 sleep $powercycle_after_reboot;
434 run_command "$power_cycle";
437 # nope? power cycle it.
438 run_command "$power_cycle";
445 return $test_type eq "build" ||
446 ($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") ||
447 ($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build");
451 doprint "CRITICAL FAILURE... ", @_, "\n";
455 if ($reboot_on_error && !do_not_reboot) {
457 doprint "REBOOTING\n";
460 } elsif ($poweroff_on_error && defined($power_off)) {
461 doprint "POWERING OFF\n";
473 my $pid = open($fp, "$console|") or
474 dodie "Can't open console $console";
476 $flags = fcntl($fp, F_GETFL, 0) or
477 dodie "Can't get flags for the socket: $!";
478 $flags = fcntl($fp, F_SETFL, $flags | O_NONBLOCK) or
479 dodie "Can't set flags for the socket: $!";
487 doprint "kill child process $pid\n";
495 if ($monitor_cnt++) {
498 $monitor_fp = \*MONFD;
499 $monitor_pid = open_console $monitor_fp;
503 open(MONFD, "Stop perl from warning about single use of MONFD");
507 if (--$monitor_cnt) {
510 close_console($monitor_fp, $monitor_pid);
513 sub wait_for_monitor {
517 doprint "** Wait for monitor to settle down **\n";
519 # read the monitor and wait for the system to calm down
521 $line = wait_for_input($monitor_fp, $time);
522 print "$line" if (defined($line));
523 } while (defined($line));
524 print "** Monitor flushed **\n";
529 if ($die_on_failure) {
537 # no need to reboot for just building.
538 if (!do_not_reboot) {
539 doprint "REBOOTING\n";
542 wait_for_monitor $sleep_time;
546 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
547 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
548 doprint "KTEST RESULT: TEST $i Failed: ", @_, "\n";
549 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
550 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
552 return 1 if (!defined($store_failures));
555 my $date = sprintf "%04d%02d%02d%02d%02d%02d",
556 1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0];
558 my $type = $build_type;
559 if ($type =~ /useconfig/) {
563 my $dir = "$machine-$test_type-$type-fail-$date";
564 my $faildir = "$store_failures/$dir";
568 die "can't create $faildir";
570 if (-f "$output_config") {
571 cp "$output_config", "$faildir/config" or
572 die "failed to copy .config";
575 cp $buildlog, "$faildir/buildlog" or
576 die "failed to move $buildlog";
579 cp $dmesg, "$faildir/dmesg" or
580 die "failed to move $dmesg";
583 doprint "*** Saved info to $faildir ***\n";
594 $command =~ s/\$SSH_USER/$ssh_user/g;
595 $command =~ s/\$MACHINE/$machine/g;
597 doprint("$command ... ");
599 $pid = open(CMD, "$command 2>&1 |") or
600 (fail "unable to exec $command" and return 0);
602 if (defined($opt{"LOG_FILE"})) {
603 open(LOG, ">>$opt{LOG_FILE}") or
604 dodie "failed to write to log";
608 if (defined($redirect)) {
609 open (RD, ">$redirect") or
610 dodie "failed to write to redirect $redirect";
615 print LOG if ($dolog);
623 close(LOG) if ($dolog);
624 close(RD) if ($dord);
637 my $cp_exec = $ssh_exec;
639 $cp_exec =~ s/\$SSH_COMMAND/$cmd/g;
640 return run_command "$cp_exec";
644 my ($src, $dst) = @_;
645 my $cp_scp = $scp_to_target;
647 $cp_scp =~ s/\$SRC_FILE/$src/g;
648 $cp_scp =~ s/\$DST_FILE/$dst/g;
650 return run_command "$cp_scp";
655 if ($reboot_type ne "grub") {
658 return if (defined($grub_number));
660 doprint "Find grub menu ... ";
663 my $ssh_grub = $ssh_exec;
664 $ssh_grub =~ s,\$SSH_COMMAND,cat /boot/grub/menu.lst,g;
666 open(IN, "$ssh_grub |")
667 or die "unable to get menu.lst";
670 if (/^\s*title\s+$grub_menu\s*$/) {
673 } elsif (/^\s*title\s/) {
679 die "Could not find '$grub_menu' in /boot/grub/menu on $machine"
680 if ($grub_number < 0);
681 doprint "$grub_number\n";
686 my ($fp, $time) = @_;
692 if (!defined($time)) {
697 vec($rin, fileno($fp), 1) = 1;
698 $ready = select($rin, undef, undef, $time);
702 # try to read one char at a time
703 while (sysread $fp, $ch, 1) {
705 last if ($ch eq "\n");
708 if (!length($line)) {
716 if ($reboot_type eq "grub") {
717 run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch; reboot)'";
721 run_command "$reboot_script";
727 doprint "git rev-list --max-count=1 $commit ... ";
728 my $sha1 = `git rev-list --max-count=1 $commit`;
735 dodie "Failed to get git $commit";
748 my $skip_call_trace = 0;
756 open(DMESG, "> $dmesg") or
757 die "unable to write to $dmesg";
767 $line = wait_for_input($monitor_fp, $booted_timeout);
769 $line = wait_for_input($monitor_fp);
772 last if (!defined($line));
777 # we are not guaranteed to get a full line
780 if ($full_line =~ /$success_line/) {
782 $success_start = time;
785 if ($booted && defined($stop_after_success) &&
786 $stop_after_success >= 0) {
788 if ($now - $success_start >= $stop_after_success) {
789 doprint "Test forced to stop after $stop_after_success seconds after success\n";
794 if ($full_line =~ /\[ backtrace testing \]/) {
795 $skip_call_trace = 1;
798 if ($full_line =~ /call trace:/i) {
799 if (!$skip_call_trace) {
801 $failure_start = time;
805 if ($bug && defined($stop_after_failure) &&
806 $stop_after_failure >= 0) {
808 if ($now - $failure_start >= $stop_after_failure) {
809 doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
814 if ($full_line =~ /\[ end of backtrace testing \]/) {
815 $skip_call_trace = 0;
818 if ($full_line =~ /Kernel panic -/) {
830 return 0 if ($in_bisect);
831 fail "failed - got a bug report" and return 0;
835 return 0 if ($in_bisect);
836 fail "failed - never got a boot prompt." and return 0;
844 run_scp "$outputdir/$build_target", "$target_image" or
845 dodie "failed to copy image";
847 my $install_mods = 0;
849 # should we process modules?
851 open(IN, "$output_config") or dodie("Can't read config file");
853 if (/CONFIG_MODULES(=y)?/) {
854 $install_mods = 1 if (defined($1));
860 if (!$install_mods) {
861 doprint "No modules needed\n";
865 run_command "$make INSTALL_MOD_PATH=$tmpdir modules_install" or
866 dodie "Failed to install modules";
868 my $modlib = "/lib/modules/$version";
869 my $modtar = "ktest-mods.tar.bz2";
871 run_ssh "rm -rf $modlib" or
872 dodie "failed to remove old mods: $modlib";
874 # would be nice if scp -r did not follow symbolic links
875 run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or
876 dodie "making tarball";
878 run_scp "$tmpdir/$modtar", "/tmp" or
879 dodie "failed to copy modules";
881 unlink "$tmpdir/$modtar";
883 run_ssh "'(cd / && tar xf /tmp/$modtar)'" or
884 dodie "failed to tar modules";
886 run_ssh "rm -f /tmp/$modtar";
888 return if (!defined($post_install));
890 my $cp_post_install = $post_install;
891 $cp_post_install = s/\$KERNEL_VERSION/$version/g;
892 run_command "$cp_post_install" or
893 dodie "Failed to run post install";
899 my @files = `git show $patch | diffstat -l`;
901 open(IN, "git show $patch |") or
902 dodie "failed to show $patch";
904 if (m,^--- a/(.*),) {
906 $files[$#files] = $1;
911 open(IN, $buildlog) or dodie "Can't open $buildlog";
913 if (/^\s*(.*?):.*(warning|error)/) {
915 foreach my $file (@files) {
916 my $fullpath = "$builddir/$file";
917 if ($file eq $err || $fullpath eq $err) {
918 fail "$file built with warnings" and return 0;
934 if ($type =~ /^useconfig:(.*)/) {
935 run_command "cp $1 $output_config" or
936 dodie "could not copy $1 to .config";
941 # old config can ask questions
942 if ($type eq "oldconfig") {
943 $type = "oldnoconfig";
945 # allow for empty configs
946 run_command "touch $output_config";
948 run_command "mv $output_config $outputdir/config_temp" or
949 dodie "moving .config";
951 if (!$noclean && !run_command "$make mrproper") {
952 dodie "make mrproper";
955 run_command "mv $outputdir/config_temp $output_config" or
956 dodie "moving config_temp";
958 } elsif (!$noclean) {
959 unlink "$output_config";
960 run_command "$make mrproper" or
961 dodie "make mrproper";
964 # add something to distinguish this build
965 open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file");
966 print OUT "$localversion\n";
969 if (defined($minconfig)) {
970 $defconfig = "KCONFIG_ALLCONFIG=$minconfig";
973 run_command "$defconfig $make $type" or
974 dodie "failed make config";
976 $redirect = "$buildlog";
977 if (!run_command "$make $build_options") {
979 # bisect may need this to pass
980 return 0 if ($in_bisect);
981 fail "failed build" and return 0;
989 if (!run_ssh "halt" or defined($power_off)) {
990 if (defined($poweroff_after_halt)) {
991 sleep $poweroff_after_halt;
992 run_command "$power_off";
996 run_command "$power_off";
1005 doprint "\n\n*******************************************\n";
1006 doprint "*******************************************\n";
1007 doprint "KTEST RESULT: TEST $i SUCCESS!!!! **\n";
1008 doprint "*******************************************\n";
1009 doprint "*******************************************\n";
1011 if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) {
1012 doprint "Reboot and wait $sleep_time seconds\n";
1015 wait_for_monitor $sleep_time;
1021 # get the release name
1022 doprint "$make kernelrelease ... ";
1023 $version = `$make kernelrelease | tail -1`;
1025 doprint "$version\n";
1028 sub child_run_test {
1031 # child should have no power
1032 $reboot_on_error = 0;
1033 $poweroff_on_error = 0;
1034 $die_on_failure = 1;
1036 run_command $run_test or $failed = 1;
1042 sub child_finished {
1055 doprint "run test $run_test\n";
1059 $SIG{CHLD} = qw(child_finished);
1063 child_run_test if (!$child_pid);
1068 $line = wait_for_input($monitor_fp, 1);
1069 if (defined($line)) {
1071 # we are not guaranteed to get a full line
1072 $full_line .= $line;
1074 if ($full_line =~ /call trace:/i) {
1078 if ($full_line =~ /Kernel panic -/) {
1082 if ($line =~ /\n/) {
1086 } while (!$child_done && !$bug);
1089 doprint "Detected kernel crash!\n";
1090 # kill the child with extreme prejudice
1094 waitpid $child_pid, 0;
1097 if ($bug || $child_exit) {
1098 return 0 if $in_bisect;
1099 fail "test failed" and return 0;
1104 sub run_git_bisect {
1107 doprint "$command ... ";
1109 my $output = `$command 2>&1`;
1116 dodie "Failed to git bisect";
1119 doprint "SUCCESS\n";
1120 if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) {
1121 doprint "$1 [$2]\n";
1122 } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) {
1124 doprint "Found bad commit... $1\n";
1127 # we already logged it, just print it now.
1134 # returns 1 on success, 0 on failure
1135 sub run_bisect_test {
1136 my ($type, $buildtype) = @_;
1145 build $buildtype or $failed = 1;
1147 if ($type ne "build") {
1148 dodie "Failed on build" if $failed;
1156 monitor or $failed = 1;
1158 if ($type ne "boot") {
1159 dodie "Failed on boot" if $failed;
1161 do_run_test or $failed = 1;
1169 # reboot the box to a good kernel
1170 if ($type ne "build") {
1171 doprint "Reboot and sleep $bisect_sleep_time seconds\n";
1174 wait_for_monitor $bisect_sleep_time;
1187 my $buildtype = "oldconfig";
1189 # We should have a minconfig to use?
1190 if (defined($minconfig)) {
1191 $buildtype = "useconfig:$minconfig";
1194 my $ret = run_bisect_test $type, $buildtype;
1197 # Are we looking for where it worked, not failed?
1198 if ($reverse_bisect) {
1214 die "BISECT_GOOD[$i] not defined\n" if (!defined($opt{"BISECT_GOOD[$i]"}));
1215 die "BISECT_BAD[$i] not defined\n" if (!defined($opt{"BISECT_BAD[$i]"}));
1216 die "BISECT_TYPE[$i] not defined\n" if (!defined($opt{"BISECT_TYPE[$i]"}));
1218 my $good = $opt{"BISECT_GOOD[$i]"};
1219 my $bad = $opt{"BISECT_BAD[$i]"};
1220 my $type = $opt{"BISECT_TYPE[$i]"};
1221 my $start = $opt{"BISECT_START[$i]"};
1222 my $replay = $opt{"BISECT_REPLAY[$i]"};
1224 # convert to true sha1's
1225 $good = get_sha1($good);
1226 $bad = get_sha1($bad);
1228 if (defined($opt{"BISECT_REVERSE[$i]"}) &&
1229 $opt{"BISECT_REVERSE[$i]"} == 1) {
1230 doprint "Performing a reverse bisect (bad is good, good is bad!)\n";
1231 $reverse_bisect = 1;
1233 $reverse_bisect = 0;
1236 # Can't have a test without having a test to run
1237 if ($type eq "test" && !defined($run_test)) {
1241 my $check = $opt{"BISECT_CHECK[$i]"};
1242 if (defined($check) && $check ne "0") {
1245 my $head = get_sha1("HEAD");
1247 if ($check ne "good") {
1248 doprint "TESTING BISECT BAD [$bad]\n";
1249 run_command "git checkout $bad" or
1250 die "Failed to checkout $bad";
1252 $result = run_bisect $type;
1254 if ($result ne "bad") {
1255 fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0;
1259 if ($check ne "bad") {
1260 doprint "TESTING BISECT GOOD [$good]\n";
1261 run_command "git checkout $good" or
1262 die "Failed to checkout $good";
1264 $result = run_bisect $type;
1266 if ($result ne "good") {
1267 fail "Tested BISECT_GOOD [$good] and it failed" and return 0;
1271 # checkout where we started
1272 run_command "git checkout $head" or
1273 die "Failed to checkout $head";
1276 run_command "git bisect start" or
1277 dodie "could not start bisect";
1279 run_command "git bisect good $good" or
1280 dodie "could not set bisect good to $good";
1282 run_git_bisect "git bisect bad $bad" or
1283 dodie "could not set bisect bad to $bad";
1285 if (defined($replay)) {
1286 run_command "git bisect replay $replay" or
1287 dodie "failed to run replay";
1290 if (defined($start)) {
1291 run_command "git checkout $start" or
1292 dodie "failed to checkout $start";
1297 $result = run_bisect $type;
1298 $test = run_git_bisect "git bisect $result";
1301 run_command "git bisect log" or
1302 dodie "could not capture git bisect log";
1304 run_command "git bisect reset" or
1305 dodie "could not reset git bisect";
1307 doprint "Bad commit was [$bisect_bad]\n";
1320 sub process_config_ignore {
1324 or dodie "Failed to read $config";
1327 if (/^(.*?(CONFIG\S*)(=.*| is not set))/) {
1328 $config_ignore{$2} = $1;
1335 sub read_current_config {
1336 my ($config_ref) = @_;
1338 %{$config_ref} = ();
1339 undef %{$config_ref};
1341 my @key = keys %{$config_ref};
1343 print "did not delete!\n";
1346 open (IN, "$output_config");
1349 if (/^(CONFIG\S+)=(.*)/) {
1350 ${$config_ref}{$1} = $2;
1356 sub get_dependencies {
1359 my $arr = $dependency{$config};
1360 if (!defined($arr)) {
1366 foreach my $dep (@{$arr}) {
1367 print "ADD DEP $dep\n";
1368 @deps = (@deps, get_dependencies $dep);
1377 open(OUT, ">$output_config") or dodie "Can not write to $output_config";
1379 foreach my $config (@configs) {
1380 print OUT "$config_set{$config}\n";
1381 my @deps = get_dependencies $config;
1382 foreach my $dep (@deps) {
1383 print OUT "$config_set{$dep}\n";
1387 foreach my $config (keys %config_ignore) {
1388 print OUT "$config_ignore{$config}\n";
1393 run_command "$make oldnoconfig" or
1394 dodie "failed make config oldconfig";
1398 sub compare_configs {
1401 foreach my $item (keys %a) {
1402 if (!defined($b{$item})) {
1403 print "diff $item\n";
1411 print "diff2 $keys[0]\n";
1413 return -1 if ($#keys >= 0);
1418 sub run_config_bisect_test {
1421 return run_bisect_test $type, "oldconfig";
1424 sub process_passed {
1427 doprint "These configs had no failure: (Enabling them for further compiles)\n";
1428 # Passed! All these configs are part of a good compile.
1429 # Add them to the min options.
1430 foreach my $config (keys %configs) {
1431 if (defined($config_list{$config})) {
1432 doprint " removing $config\n";
1433 $config_ignore{$config} = $config_list{$config};
1434 delete $config_list{$config};
1437 doprint "config copied to $outputdir/config_good\n";
1438 run_command "cp -f $output_config $outputdir/config_good";
1441 sub process_failed {
1444 doprint "\n\n***************************************\n";
1445 doprint "Found bad config: $config\n";
1446 doprint "***************************************\n\n";
1449 sub run_config_bisect {
1451 my @start_list = keys %config_list;
1453 if ($#start_list < 0) {
1454 doprint "No more configs to test!!!\n";
1458 doprint "***** RUN TEST ***\n";
1459 my $type = $opt{"CONFIG_BISECT_TYPE[$iteration]"};
1463 my $count = $#start_list + 1;
1464 doprint " $count configs to test\n";
1466 my $half = int($#start_list / 2);
1469 my @tophalf = @start_list[0 .. $half];
1471 create_config @tophalf;
1472 read_current_config \%current_config;
1474 $count = $#tophalf + 1;
1475 doprint "Testing $count configs\n";
1477 # make sure we test something
1478 foreach my $config (@tophalf) {
1479 if (defined($current_config{$config})) {
1485 # try the other half
1486 doprint "Top half produced no set configs, trying bottom half\n";
1487 @tophalf = @start_list[$half .. $#start_list];
1488 create_config @tophalf;
1489 read_current_config \%current_config;
1490 foreach my $config (@tophalf) {
1491 if (defined($current_config{$config})) {
1497 doprint "Failed: Can't make new config with current configs\n";
1498 foreach my $config (@start_list) {
1499 doprint " CONFIG: $config\n";
1503 $count = $#tophalf + 1;
1504 doprint "Testing $count configs\n";
1507 $ret = run_config_bisect_test $type;
1510 process_passed %current_config;
1514 doprint "This config had a failure.\n";
1515 doprint "Removing these configs that were not set in this config:\n";
1516 doprint "config copied to $outputdir/config_bad\n";
1517 run_command "cp -f $output_config $outputdir/config_bad";
1519 # A config exists in this group that was bad.
1520 foreach my $config (keys %config_list) {
1521 if (!defined($current_config{$config})) {
1522 doprint " removing $config\n";
1523 delete $config_list{$config};
1527 @start_list = @tophalf;
1529 if ($#start_list == 0) {
1530 process_failed $start_list[0];
1534 # remove half the configs we are looking at and see if
1536 $half = int($#start_list / 2);
1537 } while ($half > 0);
1539 # we found a single config, try it again
1540 my @tophalf = @start_list[0 .. 0];
1542 $ret = run_config_bisect_test $type;
1544 process_passed %current_config;
1548 process_failed $start_list[0];
1555 my $start_config = $opt{"CONFIG_BISECT[$i]"};
1557 my $tmpconfig = "$tmpdir/use_config";
1559 # Make the file with the bad config and the min config
1560 if (defined($minconfig)) {
1561 # read the min config for things to ignore
1562 run_command "cp $minconfig $tmpconfig" or
1563 dodie "failed to copy $minconfig to $tmpconfig";
1569 if (defined($addconfig)) {
1570 run_command "cat $addconfig >> $tmpconfig" or
1571 dodie "failed to append $addconfig";
1575 if (-f $tmpconfig) {
1576 $defconfig = "KCONFIG_ALLCONFIG=$tmpconfig";
1577 process_config_ignore $tmpconfig;
1580 # now process the start config
1581 run_command "cp $start_config $output_config" or
1582 dodie "failed to copy $start_config to $output_config";
1584 # read directly what we want to check
1586 open (IN, $output_config)
1587 or dodie "faied to open $output_config";
1590 if (/^((CONFIG\S*)=.*)/) {
1591 $config_check{$2} = $1;
1596 # Now run oldconfig with the minconfig (and addconfigs)
1597 run_command "$defconfig $make oldnoconfig" or
1598 dodie "failed make config oldconfig";
1600 # check to see what we lost (or gained)
1601 open (IN, $output_config)
1602 or dodie "Failed to read $start_config";
1604 my %removed_configs;
1608 if (/^((CONFIG\S*)=.*)/) {
1609 # save off all options
1610 $config_set{$2} = $1;
1611 if (defined($config_check{$2})) {
1612 if (defined($config_ignore{$2})) {
1613 $removed_configs{$2} = $1;
1615 $config_list{$2} = $1;
1617 } elsif (!defined($config_ignore{$2})) {
1618 $added_configs{$2} = $1;
1619 $config_list{$2} = $1;
1625 my @confs = keys %removed_configs;
1627 doprint "Configs overridden by default configs and removed from check:\n";
1628 foreach my $config (@confs) {
1629 doprint " $config\n";
1632 @confs = keys %added_configs;
1634 doprint "Configs appearing in make oldconfig and added:\n";
1635 foreach my $config (@confs) {
1636 doprint " $config\n";
1643 # Sometimes kconfig does weird things. We must make sure
1644 # that the config we autocreate has everything we need
1645 # to test, otherwise we may miss testing configs, or
1646 # may not be able to create a new config.
1647 # Here we create a config with everything set.
1648 create_config (keys %config_list);
1649 read_current_config \%config_test;
1650 foreach my $config (keys %config_list) {
1651 if (!defined($config_test{$config})) {
1654 doprint "Configs not produced by kconfig (will not be checked):\n";
1656 doprint " $config\n";
1657 delete $config_list{$config};
1662 $ret = run_config_bisect;
1665 return $ret if ($ret < 0);
1673 die "PATCHCHECK_START[$i] not defined\n"
1674 if (!defined($opt{"PATCHCHECK_START[$i]"}));
1675 die "PATCHCHECK_TYPE[$i] not defined\n"
1676 if (!defined($opt{"PATCHCHECK_TYPE[$i]"}));
1678 my $start = $opt{"PATCHCHECK_START[$i]"};
1681 if (defined($opt{"PATCHCHECK_END[$i]"})) {
1682 $end = $opt{"PATCHCHECK_END[$i]"};
1685 # Get the true sha1's since we can use things like HEAD~3
1686 $start = get_sha1($start);
1687 $end = get_sha1($end);
1689 my $type = $opt{"PATCHCHECK_TYPE[$i]"};
1691 # Can't have a test without having a test to run
1692 if ($type eq "test" && !defined($run_test)) {
1696 open (IN, "git log --pretty=oneline $end|") or
1697 dodie "could not get git list";
1703 $list[$#list+1] = $_;
1704 last if (/^$start/);
1708 if ($list[$#list] !~ /^$start/) {
1709 fail "SHA1 $start not found";
1712 # go backwards in the list
1713 @list = reverse @list;
1715 my $save_clean = $noclean;
1718 foreach my $item (@list) {
1720 $sha1 =~ s/^([[:xdigit:]]+).*/$1/;
1722 doprint "\nProcessing commit $item\n\n";
1724 run_command "git checkout $sha1" or
1725 die "Failed to checkout $sha1";
1727 # only clean on the first and last patch
1728 if ($item eq $list[0] ||
1729 $item eq $list[$#list]) {
1730 $noclean = $save_clean;
1735 if (defined($minconfig)) {
1736 build "useconfig:$minconfig" or return 0;
1738 # ?? no config to use?
1739 build "oldconfig" or return 0;
1742 check_buildlog $sha1 or return 0;
1744 next if ($type eq "build");
1753 monitor or $failed = 1;
1755 if (!$failed && $type ne "boot"){
1756 do_run_test or $failed = 1;
1759 return 0 if ($failed);
1768 $#ARGV < 1 or die "ktest.pl version: $VERSION\n usage: ktest.pl config-file\n";
1771 $ktest_config = $ARGV[0];
1772 if (! -f $ktest_config) {
1773 print "$ktest_config does not exist.\n";
1776 print "Create it? [Y/n] ";
1779 if ($ans =~ /^\s*$/) {
1782 last if ($ans =~ /^y$/i || $ans =~ /^n$/i);
1783 print "Please answer either 'y' or 'n'.\n";
1785 if ($ans !~ /^y$/i) {
1790 $ktest_config = "ktest.conf";
1793 if (! -f $ktest_config) {
1794 open(OUT, ">$ktest_config") or die "Can not create $ktest_config";
1796 # Generated by ktest.pl
1798 # Define each test with TEST_START
1799 # The config options below it will override the defaults
1807 read_config $ktest_config;
1809 # Append any configs entered in manually to the config file.
1810 my @new_configs = keys %entered_configs;
1811 if ($#new_configs >= 0) {
1812 print "\nAppending entered in configs to $ktest_config\n";
1813 open(OUT, ">>$ktest_config") or die "Can not append to $ktest_config";
1814 foreach my $config (@new_configs) {
1815 print OUT "$config = $entered_configs{$config}\n";
1816 $opt{$config} = $entered_configs{$config};
1820 if ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) {
1821 unlink $opt{"LOG_FILE"};
1824 doprint "\n\nSTARTING AUTOMATED TESTS\n\n";
1826 for (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) {
1829 doprint "DEFAULT OPTIONS:\n";
1831 doprint "\nTEST $i OPTIONS";
1832 if (defined($repeat_tests{$i})) {
1833 $repeat = $repeat_tests{$i};
1834 doprint " ITERATE $repeat";
1839 foreach my $option (sort keys %opt) {
1841 if ($option =~ /\[(\d+)\]$/) {
1847 doprint "$option = $opt{$option}\n";
1851 sub set_test_option {
1852 my ($name, $i) = @_;
1854 my $option = "$name\[$i\]";
1856 if (defined($opt{$option})) {
1857 return $opt{$option};
1860 foreach my $test (keys %repeat_tests) {
1862 $i < $test + $repeat_tests{$test}) {
1863 $option = "$name\[$test\]";
1864 if (defined($opt{$option})) {
1865 return $opt{$option};
1870 if (defined($opt{$name})) {
1877 # First we need to do is the builds
1878 for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
1882 my $makecmd = set_test_option("MAKE_CMD", $i);
1884 $machine = set_test_option("MACHINE", $i);
1885 $ssh_user = set_test_option("SSH_USER", $i);
1886 $tmpdir = set_test_option("TMP_DIR", $i);
1887 $outputdir = set_test_option("OUTPUT_DIR", $i);
1888 $builddir = set_test_option("BUILD_DIR", $i);
1889 $test_type = set_test_option("TEST_TYPE", $i);
1890 $build_type = set_test_option("BUILD_TYPE", $i);
1891 $build_options = set_test_option("BUILD_OPTIONS", $i);
1892 $power_cycle = set_test_option("POWER_CYCLE", $i);
1893 $reboot = set_test_option("REBOOT", $i);
1894 $noclean = set_test_option("BUILD_NOCLEAN", $i);
1895 $minconfig = set_test_option("MIN_CONFIG", $i);
1896 $run_test = set_test_option("TEST", $i);
1897 $addconfig = set_test_option("ADD_CONFIG", $i);
1898 $reboot_type = set_test_option("REBOOT_TYPE", $i);
1899 $grub_menu = set_test_option("GRUB_MENU", $i);
1900 $post_install = set_test_option("POST_INSTALL", $i);
1901 $reboot_script = set_test_option("REBOOT_SCRIPT", $i);
1902 $reboot_on_error = set_test_option("REBOOT_ON_ERROR", $i);
1903 $poweroff_on_error = set_test_option("POWEROFF_ON_ERROR", $i);
1904 $die_on_failure = set_test_option("DIE_ON_FAILURE", $i);
1905 $power_off = set_test_option("POWER_OFF", $i);
1906 $powercycle_after_reboot = set_test_option("POWERCYCLE_AFTER_REBOOT", $i);
1907 $poweroff_after_halt = set_test_option("POWEROFF_AFTER_HALT", $i);
1908 $sleep_time = set_test_option("SLEEP_TIME", $i);
1909 $bisect_sleep_time = set_test_option("BISECT_SLEEP_TIME", $i);
1910 $store_failures = set_test_option("STORE_FAILURES", $i);
1911 $timeout = set_test_option("TIMEOUT", $i);
1912 $booted_timeout = set_test_option("BOOTED_TIMEOUT", $i);
1913 $console = set_test_option("CONSOLE", $i);
1914 $success_line = set_test_option("SUCCESS_LINE", $i);
1915 $stop_after_success = set_test_option("STOP_AFTER_SUCCESS", $i);
1916 $stop_after_failure = set_test_option("STOP_AFTER_FAILURE", $i);
1917 $build_target = set_test_option("BUILD_TARGET", $i);
1918 $ssh_exec = set_test_option("SSH_EXEC", $i);
1919 $scp_to_target = set_test_option("SCP_TO_TARGET", $i);
1920 $target_image = set_test_option("TARGET_IMAGE", $i);
1921 $localversion = set_test_option("LOCALVERSION", $i);
1923 chdir $builddir || die "can't change directory to $builddir";
1927 die "can't create $tmpdir";
1930 $ENV{"SSH_USER"} = $ssh_user;
1931 $ENV{"MACHINE"} = $machine;
1933 $target = "$ssh_user\@$machine";
1935 $buildlog = "$tmpdir/buildlog-$machine";
1936 $dmesg = "$tmpdir/dmesg-$machine";
1937 $make = "$makecmd O=$outputdir";
1938 $output_config = "$outputdir/.config";
1940 if ($reboot_type eq "grub") {
1941 dodie "GRUB_MENU not defined" if (!defined($grub_menu));
1942 } elsif (!defined($reboot_script)) {
1943 dodie "REBOOT_SCRIPT not defined"
1946 my $run_type = $build_type;
1947 if ($test_type eq "patchcheck") {
1948 $run_type = $opt{"PATCHCHECK_TYPE[$i]"};
1949 } elsif ($test_type eq "bisect") {
1950 $run_type = $opt{"BISECT_TYPE[$i]"};
1951 } elsif ($test_type eq "config_bisect") {
1952 $run_type = $opt{"CONFIG_BISECT_TYPE[$i]"};
1955 # mistake in config file?
1956 if (!defined($run_type)) {
1957 $run_type = "ERROR";
1961 doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type\n\n";
1966 if (!defined($minconfig)) {
1967 $minconfig = $addconfig;
1969 } elsif (defined($addconfig)) {
1970 run_command "cat $addconfig $minconfig > $tmpdir/add_config" or
1971 dodie "Failed to create temp config";
1972 $minconfig = "$tmpdir/add_config";
1975 my $checkout = $opt{"CHECKOUT[$i]"};
1976 if (defined($checkout)) {
1977 run_command "git checkout $checkout" or
1978 die "failed to checkout $checkout";
1981 if ($test_type eq "bisect") {
1984 } elsif ($test_type eq "config_bisect") {
1987 } elsif ($test_type eq "patchcheck") {
1992 if ($build_type ne "nobuild") {
1993 build $build_type or next;
1996 if ($test_type ne "build") {
2003 monitor or $failed = 1;;
2005 if (!$failed && $test_type ne "boot" && defined($run_test)) {
2006 do_run_test or $failed = 1;
2015 if ($opt{"POWEROFF_ON_SUCCESS"}) {
2017 } elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot) {
2021 doprint "\n $successes of $opt{NUM_TESTS} tests were successful\n\n";