ktest: Have wait on stdio honor bug timeout
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / tools / testing / ktest / ktest.pl
blob1e1fe835df48e1a7019eea0ea46ff6914396ea5b
1 #!/usr/bin/perl -w
3 # Copyright 2010 - Steven Rostedt <srostedt@redhat.com>, Red Hat Inc.
4 # Licensed under the terms of the GNU GPL License version 2
7 use strict;
8 use IPC::Open2;
9 use Fcntl qw(F_GETFL F_SETFL O_NONBLOCK);
10 use File::Path qw(mkpath);
11 use File::Copy qw(cp);
12 use FileHandle;
14 my $VERSION = "0.2";
16 $| = 1;
18 my %opt;
19 my %repeat_tests;
20 my %repeats;
21 my %default;
23 #default opts
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";
55 my $ktest_config;
56 my $version;
57 my $machine;
58 my $ssh_user;
59 my $tmpdir;
60 my $builddir;
61 my $outputdir;
62 my $output_config;
63 my $test_type;
64 my $build_type;
65 my $build_options;
66 my $reboot_type;
67 my $reboot_script;
68 my $power_cycle;
69 my $reboot;
70 my $reboot_on_error;
71 my $poweroff_on_error;
72 my $die_on_failure;
73 my $powercycle_after_reboot;
74 my $poweroff_after_halt;
75 my $ssh_exec;
76 my $scp_to_target;
77 my $power_off;
78 my $grub_menu;
79 my $grub_number;
80 my $target;
81 my $make;
82 my $post_install;
83 my $noclean;
84 my $minconfig;
85 my $addconfig;
86 my $in_bisect = 0;
87 my $bisect_bad = "";
88 my $reverse_bisect;
89 my $bisect_manual;
90 my $bisect_skip;
91 my $config_bisect_good;
92 my $in_patchcheck = 0;
93 my $run_test;
94 my $redirect;
95 my $buildlog;
96 my $dmesg;
97 my $monitor_fp;
98 my $monitor_pid;
99 my $monitor_cnt = 0;
100 my $sleep_time;
101 my $bisect_sleep_time;
102 my $patchcheck_sleep_time;
103 my $store_failures;
104 my $test_name;
105 my $timeout;
106 my $booted_timeout;
107 my $detect_triplefault;
108 my $console;
109 my $success_line;
110 my $stop_after_success;
111 my $stop_after_failure;
112 my $stop_test_after;
113 my $build_target;
114 my $target_image;
115 my $localversion;
116 my $iteration = 0;
117 my $successes = 0;
119 my %entered_configs;
120 my %config_help;
121 my %variable;
122 my %force_config;
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
198 reboot into.
200 For example, if in the /boot/grub/menu.lst the test kernel title has:
201 title Test Kernel
202 kernel vmlinuz-test
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 {
214 my ($config) = @_;
216 return if (defined($opt{$config}));
218 if (defined($config_help{$config})) {
219 print "\n";
220 print $config_help{$config};
223 for (;;) {
224 print "$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};
233 } else {
234 print "Your answer can not be blank\n";
235 next;
238 last;
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"};
259 } else {
260 $rtype = "grub";
264 if ($rtype eq "grub") {
265 get_ktest_config("GRUB_MENU");
266 } else {
267 get_ktest_config("REBOOT_SCRIPT");
271 sub process_variables {
272 my ($value) = @_;
273 my $retval = "";
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.
280 $value = " $value";
282 while ($value =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
283 my $begin = $1;
284 my $var = $2;
285 my $end = $3;
286 # append beginning of value to retval
287 $retval = "$retval$begin";
288 if (defined($variable{$var})) {
289 $retval = "$retval$variable{$var}";
290 } else {
291 # put back the origin piece.
292 $retval = "$retval\$\{$var\}";
294 $value = $end;
296 $retval = "$retval$value";
298 # remove the space added in the beginning
299 $retval =~ s/ //;
301 return "$retval"
304 sub set_value {
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};
312 } else {
313 $rvalue = process_variables($rvalue);
314 $opt{$lvalue} = $rvalue;
318 sub set_variable {
319 my ($lvalue, $rvalue) = @_;
321 if ($rvalue =~ /^\s*$/) {
322 delete $variable{$lvalue};
323 } else {
324 $rvalue = process_variables($rvalue);
325 $variable{$lvalue} = $rvalue;
329 sub read_config {
330 my ($config) = @_;
332 open(IN, $config) || die "can't read file $config";
334 my $name = $config;
335 $name =~ s,.*/(.*),$1,;
337 my $test_num = 0;
338 my $default = 1;
339 my $repeat = 1;
340 my $num_tests_set = 0;
341 my $skip = 0;
342 my $rest;
344 while (<IN>) {
346 # ignore blank lines and comments
347 next if (/^\s*$/ || /\s*\#/);
349 if (/^\s*TEST_START(.*)/) {
351 $rest = $1;
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;
361 $default = 0;
362 $repeat = 1;
364 if ($rest =~ /\s+SKIP(.*)/) {
365 $rest = $1;
366 $skip = 1;
367 } else {
368 $skip = 0;
371 if ($rest =~ /\s+ITERATE\s+(\d+)(.*)$/) {
372 $repeat = $1;
373 $rest = $2;
374 $repeat_tests{"$test_num"} = $repeat;
377 if ($rest =~ /\s+SKIP(.*)/) {
378 $rest = $1;
379 $skip = 1;
382 if ($rest !~ /^\s*$/) {
383 die "$name: $.: Gargbage found after TEST_START\n$_";
386 if ($skip) {
387 $test_num = $old_test_num;
388 $repeat = $old_repeat;
391 } elsif (/^\s*DEFAULTS(.*)$/) {
392 $default = 1;
394 $rest = $1;
396 if ($rest =~ /\s+SKIP(.*)/) {
397 $rest = $1;
398 $skip = 1;
399 } else {
400 $skip = 0;
403 if ($rest !~ /^\s*$/) {
404 die "$name: $.: Gargbage found after DEFAULTS\n$_";
407 } elsif (/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) {
409 next if ($skip);
411 my $lvalue = $1;
412 my $rvalue = $2;
414 if (!$default &&
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") {
422 if ($test_num) {
423 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
425 if (!$default) {
426 die "$name: $.: NUM_TESTS must be set in default section\n";
428 $num_tests_set = 1;
431 if ($default || $lvalue =~ /\[\d+\]$/) {
432 set_value($lvalue, $rvalue);
433 } else {
434 my $val = "$lvalue\[$test_num\]";
435 set_value($val, $rvalue);
437 if ($repeat > 1) {
438 $repeats{$val} = $repeat;
441 } elsif (/^\s*([A-Z_\[\]\d]+)\s*:=\s*(.*?)\s*$/) {
442 next if ($skip);
444 my $lvalue = $1;
445 my $rvalue = $2;
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
454 # the prevous one.
455 set_variable($lvalue, $rvalue);
457 } else {
458 die "$name: $.: Garbage found in config\n$_";
462 close(IN);
464 if ($test_num) {
465 $test_num += $repeat - 1;
466 $opt{"NUM_TESTS"} = $test_num;
469 # make sure we have all mandatory configs
470 get_ktest_configs;
472 # set any defaults
474 foreach my $default (keys %default) {
475 if (!defined($opt{$default})) {
476 $opt{$default} = $default{$default};
481 sub _logit {
482 if (defined($opt{"LOG_FILE"})) {
483 open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}";
484 print OUT @_;
485 close(OUT);
489 sub logit {
490 if (defined($opt{"LOG_FILE"})) {
491 _logit @_;
492 } else {
493 print @_;
497 sub doprint {
498 print @_;
499 _logit @_;
502 sub run_command;
504 sub reboot {
505 # try to reboot normally
506 if (run_command $reboot) {
507 if (defined($powercycle_after_reboot)) {
508 sleep $powercycle_after_reboot;
509 run_command "$power_cycle";
511 } else {
512 # nope? power cycle it.
513 run_command "$power_cycle";
517 sub do_not_reboot {
518 my $i = $iteration;
520 return $test_type eq "build" ||
521 ($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") ||
522 ($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build");
525 sub dodie {
526 doprint "CRITICAL FAILURE... ", @_, "\n";
528 my $i = $iteration;
530 if ($reboot_on_error && !do_not_reboot) {
532 doprint "REBOOTING\n";
533 reboot;
535 } elsif ($poweroff_on_error && defined($power_off)) {
536 doprint "POWERING OFF\n";
537 `$power_off`;
540 if (defined($opt{"LOG_FILE"})) {
541 print " See $opt{LOG_FILE} for more info.\n";
544 die @_, "\n";
547 sub open_console {
548 my ($fp) = @_;
550 my $flags;
552 my $pid = open($fp, "$console|") or
553 dodie "Can't open console $console";
555 $flags = fcntl($fp, F_GETFL, 0) or
556 dodie "Can't get flags for the socket: $!";
557 $flags = fcntl($fp, F_SETFL, $flags | O_NONBLOCK) or
558 dodie "Can't set flags for the socket: $!";
560 return $pid;
563 sub close_console {
564 my ($fp, $pid) = @_;
566 doprint "kill child process $pid\n";
567 kill 2, $pid;
569 print "closing!\n";
570 close($fp);
573 sub start_monitor {
574 if ($monitor_cnt++) {
575 return;
577 $monitor_fp = \*MONFD;
578 $monitor_pid = open_console $monitor_fp;
580 return;
582 open(MONFD, "Stop perl from warning about single use of MONFD");
585 sub end_monitor {
586 if (--$monitor_cnt) {
587 return;
589 close_console($monitor_fp, $monitor_pid);
592 sub wait_for_monitor {
593 my ($time) = @_;
594 my $line;
596 doprint "** Wait for monitor to settle down **\n";
598 # read the monitor and wait for the system to calm down
599 do {
600 $line = wait_for_input($monitor_fp, $time);
601 print "$line" if (defined($line));
602 } while (defined($line));
603 print "** Monitor flushed **\n";
606 sub fail {
608 if ($die_on_failure) {
609 dodie @_;
612 doprint "FAILED\n";
614 my $i = $iteration;
616 # no need to reboot for just building.
617 if (!do_not_reboot) {
618 doprint "REBOOTING\n";
619 reboot;
620 start_monitor;
621 wait_for_monitor $sleep_time;
622 end_monitor;
625 my $name = "";
627 if (defined($test_name)) {
628 $name = " ($test_name)";
631 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
632 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
633 doprint "KTEST RESULT: TEST $i$name Failed: ", @_, "\n";
634 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
635 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
637 return 1 if (!defined($store_failures));
639 my @t = localtime;
640 my $date = sprintf "%04d%02d%02d%02d%02d%02d",
641 1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0];
643 my $type = $build_type;
644 if ($type =~ /useconfig/) {
645 $type = "useconfig";
648 my $dir = "$machine-$test_type-$type-fail-$date";
649 my $faildir = "$store_failures/$dir";
651 if (!-d $faildir) {
652 mkpath($faildir) or
653 die "can't create $faildir";
655 if (-f "$output_config") {
656 cp "$output_config", "$faildir/config" or
657 die "failed to copy .config";
659 if (-f $buildlog) {
660 cp $buildlog, "$faildir/buildlog" or
661 die "failed to move $buildlog";
663 if (-f $dmesg) {
664 cp $dmesg, "$faildir/dmesg" or
665 die "failed to move $dmesg";
668 doprint "*** Saved info to $faildir ***\n";
670 return 1;
673 sub run_command {
674 my ($command) = @_;
675 my $dolog = 0;
676 my $dord = 0;
677 my $pid;
679 $command =~ s/\$SSH_USER/$ssh_user/g;
680 $command =~ s/\$MACHINE/$machine/g;
682 doprint("$command ... ");
684 $pid = open(CMD, "$command 2>&1 |") or
685 (fail "unable to exec $command" and return 0);
687 if (defined($opt{"LOG_FILE"})) {
688 open(LOG, ">>$opt{LOG_FILE}") or
689 dodie "failed to write to log";
690 $dolog = 1;
693 if (defined($redirect)) {
694 open (RD, ">$redirect") or
695 dodie "failed to write to redirect $redirect";
696 $dord = 1;
699 while (<CMD>) {
700 print LOG if ($dolog);
701 print RD if ($dord);
704 waitpid($pid, 0);
705 my $failed = $?;
707 close(CMD);
708 close(LOG) if ($dolog);
709 close(RD) if ($dord);
711 if ($failed) {
712 doprint "FAILED!\n";
713 } else {
714 doprint "SUCCESS\n";
717 return !$failed;
720 sub run_ssh {
721 my ($cmd) = @_;
722 my $cp_exec = $ssh_exec;
724 $cp_exec =~ s/\$SSH_COMMAND/$cmd/g;
725 return run_command "$cp_exec";
728 sub run_scp {
729 my ($src, $dst) = @_;
730 my $cp_scp = $scp_to_target;
732 $cp_scp =~ s/\$SRC_FILE/$src/g;
733 $cp_scp =~ s/\$DST_FILE/$dst/g;
735 return run_command "$cp_scp";
738 sub get_grub_index {
740 if ($reboot_type ne "grub") {
741 return;
743 return if (defined($grub_number));
745 doprint "Find grub menu ... ";
746 $grub_number = -1;
748 my $ssh_grub = $ssh_exec;
749 $ssh_grub =~ s,\$SSH_COMMAND,cat /boot/grub/menu.lst,g;
751 open(IN, "$ssh_grub |")
752 or die "unable to get menu.lst";
754 while (<IN>) {
755 if (/^\s*title\s+$grub_menu\s*$/) {
756 $grub_number++;
757 last;
758 } elsif (/^\s*title\s/) {
759 $grub_number++;
762 close(IN);
764 die "Could not find '$grub_menu' in /boot/grub/menu on $machine"
765 if ($grub_number < 0);
766 doprint "$grub_number\n";
769 sub wait_for_input
771 my ($fp, $time) = @_;
772 my $rin;
773 my $ready;
774 my $line;
775 my $ch;
777 if (!defined($time)) {
778 $time = $timeout;
781 $rin = '';
782 vec($rin, fileno($fp), 1) = 1;
783 $ready = select($rin, undef, undef, $time);
785 $line = "";
787 # try to read one char at a time
788 while (sysread $fp, $ch, 1) {
789 $line .= $ch;
790 last if ($ch eq "\n");
793 if (!length($line)) {
794 return undef;
797 return $line;
800 sub reboot_to {
801 if ($reboot_type eq "grub") {
802 run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch && reboot)'";
803 return;
806 run_command "$reboot_script";
809 sub get_sha1 {
810 my ($commit) = @_;
812 doprint "git rev-list --max-count=1 $commit ... ";
813 my $sha1 = `git rev-list --max-count=1 $commit`;
814 my $ret = $?;
816 logit $sha1;
818 if ($ret) {
819 doprint "FAILED\n";
820 dodie "Failed to get git $commit";
823 print "SUCCESS\n";
825 chomp $sha1;
827 return $sha1;
830 sub monitor {
831 my $booted = 0;
832 my $bug = 0;
833 my $skip_call_trace = 0;
834 my $loops;
836 wait_for_monitor 5;
838 my $line;
839 my $full_line = "";
841 open(DMESG, "> $dmesg") or
842 die "unable to write to $dmesg";
844 reboot_to;
846 my $success_start;
847 my $failure_start;
848 my $monitor_start = time;
849 my $done = 0;
850 my $version_found = 0;
852 while (!$done) {
854 if ($bug && defined($stop_after_failure) &&
855 $stop_after_failure >= 0) {
856 my $time = $stop_after_failure - (time - $failure_start);
857 $line = wait_for_input($monitor_fp, $time);
858 if (!defined($line)) {
859 doprint "bug timed out after $booted_timeout seconds\n";
860 doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
861 last;
863 } elsif ($booted) {
864 $line = wait_for_input($monitor_fp, $booted_timeout);
865 if (!defined($line)) {
866 my $s = $booted_timeout == 1 ? "" : "s";
867 doprint "Successful boot found: break after $booted_timeout second$s\n";
868 last;
870 } else {
871 $line = wait_for_input($monitor_fp);
872 if (!defined($line)) {
873 my $s = $timeout == 1 ? "" : "s";
874 doprint "Timed out after $timeout second$s\n";
875 last;
879 doprint $line;
880 print DMESG $line;
882 # we are not guaranteed to get a full line
883 $full_line .= $line;
885 if ($full_line =~ /$success_line/) {
886 $booted = 1;
887 $success_start = time;
890 if ($booted && defined($stop_after_success) &&
891 $stop_after_success >= 0) {
892 my $now = time;
893 if ($now - $success_start >= $stop_after_success) {
894 doprint "Test forced to stop after $stop_after_success seconds after success\n";
895 last;
899 if ($full_line =~ /\[ backtrace testing \]/) {
900 $skip_call_trace = 1;
903 if ($full_line =~ /call trace:/i) {
904 if (!$bug && !$skip_call_trace) {
905 $bug = 1;
906 $failure_start = time;
910 if ($bug && defined($stop_after_failure) &&
911 $stop_after_failure >= 0) {
912 my $now = time;
913 if ($now - $failure_start >= $stop_after_failure) {
914 doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
915 last;
919 if ($full_line =~ /\[ end of backtrace testing \]/) {
920 $skip_call_trace = 0;
923 if ($full_line =~ /Kernel panic -/) {
924 $failure_start = time;
925 $bug = 1;
928 # Detect triple faults by testing the banner
929 if ($full_line =~ /\bLinux version (\S+).*\n/) {
930 if ($1 eq $version) {
931 $version_found = 1;
932 } elsif ($version_found && $detect_triplefault) {
933 # We already booted into the kernel we are testing,
934 # but now we booted into another kernel?
935 # Consider this a triple fault.
936 doprint "Aleady booted in Linux kernel $version, but now\n";
937 doprint "we booted into Linux kernel $1.\n";
938 doprint "Assuming that this is a triple fault.\n";
939 doprint "To disable this: set DETECT_TRIPLE_FAULT to 0\n";
940 last;
944 if ($line =~ /\n/) {
945 $full_line = "";
948 if ($stop_test_after > 0 && !$booted && !$bug) {
949 if (time - $monitor_start > $stop_test_after) {
950 doprint "STOP_TEST_AFTER ($stop_test_after seconds) timed out\n";
951 $done = 1;
956 close(DMESG);
958 if ($bug) {
959 return 0 if ($in_bisect);
960 fail "failed - got a bug report" and return 0;
963 if (!$booted) {
964 return 0 if ($in_bisect);
965 fail "failed - never got a boot prompt." and return 0;
968 return 1;
971 sub install {
973 run_scp "$outputdir/$build_target", "$target_image" or
974 dodie "failed to copy image";
976 my $install_mods = 0;
978 # should we process modules?
979 $install_mods = 0;
980 open(IN, "$output_config") or dodie("Can't read config file");
981 while (<IN>) {
982 if (/CONFIG_MODULES(=y)?/) {
983 $install_mods = 1 if (defined($1));
984 last;
987 close(IN);
989 if (!$install_mods) {
990 doprint "No modules needed\n";
991 return;
994 run_command "$make INSTALL_MOD_PATH=$tmpdir modules_install" or
995 dodie "Failed to install modules";
997 my $modlib = "/lib/modules/$version";
998 my $modtar = "ktest-mods.tar.bz2";
1000 run_ssh "rm -rf $modlib" or
1001 dodie "failed to remove old mods: $modlib";
1003 # would be nice if scp -r did not follow symbolic links
1004 run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or
1005 dodie "making tarball";
1007 run_scp "$tmpdir/$modtar", "/tmp" or
1008 dodie "failed to copy modules";
1010 unlink "$tmpdir/$modtar";
1012 run_ssh "'(cd / && tar xf /tmp/$modtar)'" or
1013 dodie "failed to tar modules";
1015 run_ssh "rm -f /tmp/$modtar";
1017 return if (!defined($post_install));
1019 my $cp_post_install = $post_install;
1020 $cp_post_install =~ s/\$KERNEL_VERSION/$version/g;
1021 run_command "$cp_post_install" or
1022 dodie "Failed to run post install";
1025 sub check_buildlog {
1026 my ($patch) = @_;
1028 my @files = `git show $patch | diffstat -l`;
1030 open(IN, "git show $patch |") or
1031 dodie "failed to show $patch";
1032 while (<IN>) {
1033 if (m,^--- a/(.*),) {
1034 chomp $1;
1035 $files[$#files] = $1;
1038 close(IN);
1040 open(IN, $buildlog) or dodie "Can't open $buildlog";
1041 while (<IN>) {
1042 if (/^\s*(.*?):.*(warning|error)/) {
1043 my $err = $1;
1044 foreach my $file (@files) {
1045 my $fullpath = "$builddir/$file";
1046 if ($file eq $err || $fullpath eq $err) {
1047 fail "$file built with warnings" and return 0;
1052 close(IN);
1054 return 1;
1057 sub apply_min_config {
1058 my $outconfig = "$output_config.new";
1060 # Read the config file and remove anything that
1061 # is in the force_config hash (from minconfig and others)
1062 # then add the force config back.
1064 doprint "Applying minimum configurations into $output_config.new\n";
1066 open (OUT, ">$outconfig") or
1067 dodie "Can't create $outconfig";
1069 if (-f $output_config) {
1070 open (IN, $output_config) or
1071 dodie "Failed to open $output_config";
1072 while (<IN>) {
1073 if (/^(# )?(CONFIG_[^\s=]*)/) {
1074 next if (defined($force_config{$2}));
1076 print OUT;
1078 close IN;
1080 foreach my $config (keys %force_config) {
1081 print OUT "$force_config{$config}\n";
1083 close OUT;
1085 run_command "mv $outconfig $output_config";
1088 sub make_oldconfig {
1090 apply_min_config;
1092 if (!run_command "$make oldnoconfig") {
1093 # Perhaps oldnoconfig doesn't exist in this version of the kernel
1094 # try a yes '' | oldconfig
1095 doprint "oldnoconfig failed, trying yes '' | make oldconfig\n";
1096 run_command "yes '' | $make oldconfig" or
1097 dodie "failed make config oldconfig";
1101 # read a config file and use this to force new configs.
1102 sub load_force_config {
1103 my ($config) = @_;
1105 open(IN, $config) or
1106 dodie "failed to read $config";
1107 while (<IN>) {
1108 chomp;
1109 if (/^(CONFIG[^\s=]*)(\s*=.*)/) {
1110 $force_config{$1} = $_;
1111 } elsif (/^# (CONFIG_\S*) is not set/) {
1112 $force_config{$1} = $_;
1115 close IN;
1118 sub build {
1119 my ($type) = @_;
1121 unlink $buildlog;
1123 if ($type =~ /^useconfig:(.*)/) {
1124 run_command "cp $1 $output_config" or
1125 dodie "could not copy $1 to .config";
1127 $type = "oldconfig";
1130 # old config can ask questions
1131 if ($type eq "oldconfig") {
1132 $type = "oldnoconfig";
1134 # allow for empty configs
1135 run_command "touch $output_config";
1137 run_command "mv $output_config $outputdir/config_temp" or
1138 dodie "moving .config";
1140 if (!$noclean && !run_command "$make mrproper") {
1141 dodie "make mrproper";
1144 run_command "mv $outputdir/config_temp $output_config" or
1145 dodie "moving config_temp";
1147 } elsif (!$noclean) {
1148 unlink "$output_config";
1149 run_command "$make mrproper" or
1150 dodie "make mrproper";
1153 # add something to distinguish this build
1154 open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file");
1155 print OUT "$localversion\n";
1156 close(OUT);
1158 if (defined($minconfig)) {
1159 load_force_config($minconfig);
1162 if ($type ne "oldnoconfig") {
1163 run_command "$make $type" or
1164 dodie "failed make config";
1166 # Run old config regardless, to enforce min configurations
1167 make_oldconfig;
1169 $redirect = "$buildlog";
1170 if (!run_command "$make $build_options") {
1171 undef $redirect;
1172 # bisect may need this to pass
1173 return 0 if ($in_bisect);
1174 fail "failed build" and return 0;
1176 undef $redirect;
1178 return 1;
1181 sub halt {
1182 if (!run_ssh "halt" or defined($power_off)) {
1183 if (defined($poweroff_after_halt)) {
1184 sleep $poweroff_after_halt;
1185 run_command "$power_off";
1187 } else {
1188 # nope? the zap it!
1189 run_command "$power_off";
1193 sub success {
1194 my ($i) = @_;
1196 $successes++;
1198 my $name = "";
1200 if (defined($test_name)) {
1201 $name = " ($test_name)";
1204 doprint "\n\n*******************************************\n";
1205 doprint "*******************************************\n";
1206 doprint "KTEST RESULT: TEST $i$name SUCCESS!!!! **\n";
1207 doprint "*******************************************\n";
1208 doprint "*******************************************\n";
1210 if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) {
1211 doprint "Reboot and wait $sleep_time seconds\n";
1212 reboot;
1213 start_monitor;
1214 wait_for_monitor $sleep_time;
1215 end_monitor;
1219 sub get_version {
1220 # get the release name
1221 doprint "$make kernelrelease ... ";
1222 $version = `$make kernelrelease | tail -1`;
1223 chomp($version);
1224 doprint "$version\n";
1227 sub answer_bisect {
1228 for (;;) {
1229 doprint "Pass or fail? [p/f]";
1230 my $ans = <STDIN>;
1231 chomp $ans;
1232 if ($ans eq "p" || $ans eq "P") {
1233 return 1;
1234 } elsif ($ans eq "f" || $ans eq "F") {
1235 return 0;
1236 } else {
1237 print "Please answer 'P' or 'F'\n";
1242 sub child_run_test {
1243 my $failed = 0;
1245 # child should have no power
1246 $reboot_on_error = 0;
1247 $poweroff_on_error = 0;
1248 $die_on_failure = 1;
1250 run_command $run_test or $failed = 1;
1251 exit $failed;
1254 my $child_done;
1256 sub child_finished {
1257 $child_done = 1;
1260 sub do_run_test {
1261 my $child_pid;
1262 my $child_exit;
1263 my $line;
1264 my $full_line;
1265 my $bug = 0;
1267 wait_for_monitor 1;
1269 doprint "run test $run_test\n";
1271 $child_done = 0;
1273 $SIG{CHLD} = qw(child_finished);
1275 $child_pid = fork;
1277 child_run_test if (!$child_pid);
1279 $full_line = "";
1281 do {
1282 $line = wait_for_input($monitor_fp, 1);
1283 if (defined($line)) {
1285 # we are not guaranteed to get a full line
1286 $full_line .= $line;
1287 doprint $line;
1289 if ($full_line =~ /call trace:/i) {
1290 $bug = 1;
1293 if ($full_line =~ /Kernel panic -/) {
1294 $bug = 1;
1297 if ($line =~ /\n/) {
1298 $full_line = "";
1301 } while (!$child_done && !$bug);
1303 if ($bug) {
1304 my $failure_start = time;
1305 my $now;
1306 do {
1307 $line = wait_for_input($monitor_fp, 1);
1308 if (defined($line)) {
1309 doprint $line;
1311 $now = time;
1312 if ($now - $failure_start >= $stop_after_failure) {
1313 last;
1315 } while (defined($line));
1317 doprint "Detected kernel crash!\n";
1318 # kill the child with extreme prejudice
1319 kill 9, $child_pid;
1322 waitpid $child_pid, 0;
1323 $child_exit = $?;
1325 if ($bug || $child_exit) {
1326 return 0 if $in_bisect;
1327 fail "test failed" and return 0;
1329 return 1;
1332 sub run_git_bisect {
1333 my ($command) = @_;
1335 doprint "$command ... ";
1337 my $output = `$command 2>&1`;
1338 my $ret = $?;
1340 logit $output;
1342 if ($ret) {
1343 doprint "FAILED\n";
1344 dodie "Failed to git bisect";
1347 doprint "SUCCESS\n";
1348 if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) {
1349 doprint "$1 [$2]\n";
1350 } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) {
1351 $bisect_bad = $1;
1352 doprint "Found bad commit... $1\n";
1353 return 0;
1354 } else {
1355 # we already logged it, just print it now.
1356 print $output;
1359 return 1;
1362 sub bisect_reboot {
1363 doprint "Reboot and sleep $bisect_sleep_time seconds\n";
1364 reboot;
1365 start_monitor;
1366 wait_for_monitor $bisect_sleep_time;
1367 end_monitor;
1370 # returns 1 on success, 0 on failure, -1 on skip
1371 sub run_bisect_test {
1372 my ($type, $buildtype) = @_;
1374 my $failed = 0;
1375 my $result;
1376 my $output;
1377 my $ret;
1379 $in_bisect = 1;
1381 build $buildtype or $failed = 1;
1383 if ($type ne "build") {
1384 if ($failed && $bisect_skip) {
1385 $in_bisect = 0;
1386 return -1;
1388 dodie "Failed on build" if $failed;
1390 # Now boot the box
1391 get_grub_index;
1392 get_version;
1393 install;
1395 start_monitor;
1396 monitor or $failed = 1;
1398 if ($type ne "boot") {
1399 if ($failed && $bisect_skip) {
1400 end_monitor;
1401 bisect_reboot;
1402 $in_bisect = 0;
1403 return -1;
1405 dodie "Failed on boot" if $failed;
1407 do_run_test or $failed = 1;
1409 end_monitor;
1412 if ($failed) {
1413 $result = 0;
1414 } else {
1415 $result = 1;
1418 # reboot the box to a kernel we can ssh to
1419 if ($type ne "build") {
1420 bisect_reboot;
1422 $in_bisect = 0;
1424 return $result;
1427 sub run_bisect {
1428 my ($type) = @_;
1429 my $buildtype = "oldconfig";
1431 # We should have a minconfig to use?
1432 if (defined($minconfig)) {
1433 $buildtype = "useconfig:$minconfig";
1436 my $ret = run_bisect_test $type, $buildtype;
1438 if ($bisect_manual) {
1439 $ret = answer_bisect;
1442 # Are we looking for where it worked, not failed?
1443 if ($reverse_bisect) {
1444 $ret = !$ret;
1447 if ($ret > 0) {
1448 return "good";
1449 } elsif ($ret == 0) {
1450 return "bad";
1451 } elsif ($bisect_skip) {
1452 doprint "HIT A BAD COMMIT ... SKIPPING\n";
1453 return "skip";
1457 sub bisect {
1458 my ($i) = @_;
1460 my $result;
1462 die "BISECT_GOOD[$i] not defined\n" if (!defined($opt{"BISECT_GOOD[$i]"}));
1463 die "BISECT_BAD[$i] not defined\n" if (!defined($opt{"BISECT_BAD[$i]"}));
1464 die "BISECT_TYPE[$i] not defined\n" if (!defined($opt{"BISECT_TYPE[$i]"}));
1466 my $good = $opt{"BISECT_GOOD[$i]"};
1467 my $bad = $opt{"BISECT_BAD[$i]"};
1468 my $type = $opt{"BISECT_TYPE[$i]"};
1469 my $start = $opt{"BISECT_START[$i]"};
1470 my $replay = $opt{"BISECT_REPLAY[$i]"};
1471 my $start_files = $opt{"BISECT_FILES[$i]"};
1473 if (defined($start_files)) {
1474 $start_files = " -- " . $start_files;
1475 } else {
1476 $start_files = "";
1479 # convert to true sha1's
1480 $good = get_sha1($good);
1481 $bad = get_sha1($bad);
1483 if (defined($opt{"BISECT_REVERSE[$i]"}) &&
1484 $opt{"BISECT_REVERSE[$i]"} == 1) {
1485 doprint "Performing a reverse bisect (bad is good, good is bad!)\n";
1486 $reverse_bisect = 1;
1487 } else {
1488 $reverse_bisect = 0;
1491 # Can't have a test without having a test to run
1492 if ($type eq "test" && !defined($run_test)) {
1493 $type = "boot";
1496 my $check = $opt{"BISECT_CHECK[$i]"};
1497 if (defined($check) && $check ne "0") {
1499 # get current HEAD
1500 my $head = get_sha1("HEAD");
1502 if ($check ne "good") {
1503 doprint "TESTING BISECT BAD [$bad]\n";
1504 run_command "git checkout $bad" or
1505 die "Failed to checkout $bad";
1507 $result = run_bisect $type;
1509 if ($result ne "bad") {
1510 fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0;
1514 if ($check ne "bad") {
1515 doprint "TESTING BISECT GOOD [$good]\n";
1516 run_command "git checkout $good" or
1517 die "Failed to checkout $good";
1519 $result = run_bisect $type;
1521 if ($result ne "good") {
1522 fail "Tested BISECT_GOOD [$good] and it failed" and return 0;
1526 # checkout where we started
1527 run_command "git checkout $head" or
1528 die "Failed to checkout $head";
1531 run_command "git bisect start$start_files" or
1532 dodie "could not start bisect";
1534 run_command "git bisect good $good" or
1535 dodie "could not set bisect good to $good";
1537 run_git_bisect "git bisect bad $bad" or
1538 dodie "could not set bisect bad to $bad";
1540 if (defined($replay)) {
1541 run_command "git bisect replay $replay" or
1542 dodie "failed to run replay";
1545 if (defined($start)) {
1546 run_command "git checkout $start" or
1547 dodie "failed to checkout $start";
1550 my $test;
1551 do {
1552 $result = run_bisect $type;
1553 $test = run_git_bisect "git bisect $result";
1554 } while ($test);
1556 run_command "git bisect log" or
1557 dodie "could not capture git bisect log";
1559 run_command "git bisect reset" or
1560 dodie "could not reset git bisect";
1562 doprint "Bad commit was [$bisect_bad]\n";
1564 success $i;
1567 my %config_ignore;
1568 my %config_set;
1570 my %config_list;
1571 my %null_config;
1573 my %dependency;
1575 sub process_config_ignore {
1576 my ($config) = @_;
1578 open (IN, $config)
1579 or dodie "Failed to read $config";
1581 while (<IN>) {
1582 if (/^((CONFIG\S*)=.*)/) {
1583 $config_ignore{$2} = $1;
1587 close(IN);
1590 sub read_current_config {
1591 my ($config_ref) = @_;
1593 %{$config_ref} = ();
1594 undef %{$config_ref};
1596 my @key = keys %{$config_ref};
1597 if ($#key >= 0) {
1598 print "did not delete!\n";
1599 exit;
1601 open (IN, "$output_config");
1603 while (<IN>) {
1604 if (/^(CONFIG\S+)=(.*)/) {
1605 ${$config_ref}{$1} = $2;
1608 close(IN);
1611 sub get_dependencies {
1612 my ($config) = @_;
1614 my $arr = $dependency{$config};
1615 if (!defined($arr)) {
1616 return ();
1619 my @deps = @{$arr};
1621 foreach my $dep (@{$arr}) {
1622 print "ADD DEP $dep\n";
1623 @deps = (@deps, get_dependencies $dep);
1626 return @deps;
1629 sub create_config {
1630 my @configs = @_;
1632 open(OUT, ">$output_config") or dodie "Can not write to $output_config";
1634 foreach my $config (@configs) {
1635 print OUT "$config_set{$config}\n";
1636 my @deps = get_dependencies $config;
1637 foreach my $dep (@deps) {
1638 print OUT "$config_set{$dep}\n";
1642 foreach my $config (keys %config_ignore) {
1643 print OUT "$config_ignore{$config}\n";
1645 close(OUT);
1647 # exit;
1648 make_oldconfig;
1651 sub compare_configs {
1652 my (%a, %b) = @_;
1654 foreach my $item (keys %a) {
1655 if (!defined($b{$item})) {
1656 print "diff $item\n";
1657 return 1;
1659 delete $b{$item};
1662 my @keys = keys %b;
1663 if ($#keys) {
1664 print "diff2 $keys[0]\n";
1666 return -1 if ($#keys >= 0);
1668 return 0;
1671 sub run_config_bisect_test {
1672 my ($type) = @_;
1674 return run_bisect_test $type, "oldconfig";
1677 sub process_passed {
1678 my (%configs) = @_;
1680 doprint "These configs had no failure: (Enabling them for further compiles)\n";
1681 # Passed! All these configs are part of a good compile.
1682 # Add them to the min options.
1683 foreach my $config (keys %configs) {
1684 if (defined($config_list{$config})) {
1685 doprint " removing $config\n";
1686 $config_ignore{$config} = $config_list{$config};
1687 delete $config_list{$config};
1690 doprint "config copied to $outputdir/config_good\n";
1691 run_command "cp -f $output_config $outputdir/config_good";
1694 sub process_failed {
1695 my ($config) = @_;
1697 doprint "\n\n***************************************\n";
1698 doprint "Found bad config: $config\n";
1699 doprint "***************************************\n\n";
1702 sub run_config_bisect {
1704 my @start_list = keys %config_list;
1706 if ($#start_list < 0) {
1707 doprint "No more configs to test!!!\n";
1708 return -1;
1711 doprint "***** RUN TEST ***\n";
1712 my $type = $opt{"CONFIG_BISECT_TYPE[$iteration]"};
1713 my $ret;
1714 my %current_config;
1716 my $count = $#start_list + 1;
1717 doprint " $count configs to test\n";
1719 my $half = int($#start_list / 2);
1721 do {
1722 my @tophalf = @start_list[0 .. $half];
1724 create_config @tophalf;
1725 read_current_config \%current_config;
1727 $count = $#tophalf + 1;
1728 doprint "Testing $count configs\n";
1729 my $found = 0;
1730 # make sure we test something
1731 foreach my $config (@tophalf) {
1732 if (defined($current_config{$config})) {
1733 logit " $config\n";
1734 $found = 1;
1737 if (!$found) {
1738 # try the other half
1739 doprint "Top half produced no set configs, trying bottom half\n";
1740 @tophalf = @start_list[$half + 1 .. $#start_list];
1741 create_config @tophalf;
1742 read_current_config \%current_config;
1743 foreach my $config (@tophalf) {
1744 if (defined($current_config{$config})) {
1745 logit " $config\n";
1746 $found = 1;
1749 if (!$found) {
1750 doprint "Failed: Can't make new config with current configs\n";
1751 foreach my $config (@start_list) {
1752 doprint " CONFIG: $config\n";
1754 return -1;
1756 $count = $#tophalf + 1;
1757 doprint "Testing $count configs\n";
1760 $ret = run_config_bisect_test $type;
1761 if ($bisect_manual) {
1762 $ret = answer_bisect;
1764 if ($ret) {
1765 process_passed %current_config;
1766 return 0;
1769 doprint "This config had a failure.\n";
1770 doprint "Removing these configs that were not set in this config:\n";
1771 doprint "config copied to $outputdir/config_bad\n";
1772 run_command "cp -f $output_config $outputdir/config_bad";
1774 # A config exists in this group that was bad.
1775 foreach my $config (keys %config_list) {
1776 if (!defined($current_config{$config})) {
1777 doprint " removing $config\n";
1778 delete $config_list{$config};
1782 @start_list = @tophalf;
1784 if ($#start_list == 0) {
1785 process_failed $start_list[0];
1786 return 1;
1789 # remove half the configs we are looking at and see if
1790 # they are good.
1791 $half = int($#start_list / 2);
1792 } while ($#start_list > 0);
1794 # we found a single config, try it again unless we are running manually
1796 if ($bisect_manual) {
1797 process_failed $start_list[0];
1798 return 1;
1801 my @tophalf = @start_list[0 .. 0];
1803 $ret = run_config_bisect_test $type;
1804 if ($ret) {
1805 process_passed %current_config;
1806 return 0;
1809 process_failed $start_list[0];
1810 return 1;
1813 sub config_bisect {
1814 my ($i) = @_;
1816 my $start_config = $opt{"CONFIG_BISECT[$i]"};
1818 my $tmpconfig = "$tmpdir/use_config";
1820 if (defined($config_bisect_good)) {
1821 process_config_ignore $config_bisect_good;
1824 # Make the file with the bad config and the min config
1825 if (defined($minconfig)) {
1826 # read the min config for things to ignore
1827 run_command "cp $minconfig $tmpconfig" or
1828 dodie "failed to copy $minconfig to $tmpconfig";
1829 } else {
1830 unlink $tmpconfig;
1833 # Add other configs
1834 if (defined($addconfig)) {
1835 run_command "cat $addconfig >> $tmpconfig" or
1836 dodie "failed to append $addconfig";
1839 if (-f $tmpconfig) {
1840 load_force_config($tmpconfig);
1841 process_config_ignore $tmpconfig;
1844 # now process the start config
1845 run_command "cp $start_config $output_config" or
1846 dodie "failed to copy $start_config to $output_config";
1848 # read directly what we want to check
1849 my %config_check;
1850 open (IN, $output_config)
1851 or dodie "faied to open $output_config";
1853 while (<IN>) {
1854 if (/^((CONFIG\S*)=.*)/) {
1855 $config_check{$2} = $1;
1858 close(IN);
1860 # Now run oldconfig with the minconfig (and addconfigs)
1861 make_oldconfig;
1863 # check to see what we lost (or gained)
1864 open (IN, $output_config)
1865 or dodie "Failed to read $start_config";
1867 my %removed_configs;
1868 my %added_configs;
1870 while (<IN>) {
1871 if (/^((CONFIG\S*)=.*)/) {
1872 # save off all options
1873 $config_set{$2} = $1;
1874 if (defined($config_check{$2})) {
1875 if (defined($config_ignore{$2})) {
1876 $removed_configs{$2} = $1;
1877 } else {
1878 $config_list{$2} = $1;
1880 } elsif (!defined($config_ignore{$2})) {
1881 $added_configs{$2} = $1;
1882 $config_list{$2} = $1;
1886 close(IN);
1888 my @confs = keys %removed_configs;
1889 if ($#confs >= 0) {
1890 doprint "Configs overridden by default configs and removed from check:\n";
1891 foreach my $config (@confs) {
1892 doprint " $config\n";
1895 @confs = keys %added_configs;
1896 if ($#confs >= 0) {
1897 doprint "Configs appearing in make oldconfig and added:\n";
1898 foreach my $config (@confs) {
1899 doprint " $config\n";
1903 my %config_test;
1904 my $once = 0;
1906 # Sometimes kconfig does weird things. We must make sure
1907 # that the config we autocreate has everything we need
1908 # to test, otherwise we may miss testing configs, or
1909 # may not be able to create a new config.
1910 # Here we create a config with everything set.
1911 create_config (keys %config_list);
1912 read_current_config \%config_test;
1913 foreach my $config (keys %config_list) {
1914 if (!defined($config_test{$config})) {
1915 if (!$once) {
1916 $once = 1;
1917 doprint "Configs not produced by kconfig (will not be checked):\n";
1919 doprint " $config\n";
1920 delete $config_list{$config};
1923 my $ret;
1924 do {
1925 $ret = run_config_bisect;
1926 } while (!$ret);
1928 return $ret if ($ret < 0);
1930 success $i;
1933 sub patchcheck_reboot {
1934 doprint "Reboot and sleep $patchcheck_sleep_time seconds\n";
1935 reboot;
1936 start_monitor;
1937 wait_for_monitor $patchcheck_sleep_time;
1938 end_monitor;
1941 sub patchcheck {
1942 my ($i) = @_;
1944 die "PATCHCHECK_START[$i] not defined\n"
1945 if (!defined($opt{"PATCHCHECK_START[$i]"}));
1946 die "PATCHCHECK_TYPE[$i] not defined\n"
1947 if (!defined($opt{"PATCHCHECK_TYPE[$i]"}));
1949 my $start = $opt{"PATCHCHECK_START[$i]"};
1951 my $end = "HEAD";
1952 if (defined($opt{"PATCHCHECK_END[$i]"})) {
1953 $end = $opt{"PATCHCHECK_END[$i]"};
1956 # Get the true sha1's since we can use things like HEAD~3
1957 $start = get_sha1($start);
1958 $end = get_sha1($end);
1960 my $type = $opt{"PATCHCHECK_TYPE[$i]"};
1962 # Can't have a test without having a test to run
1963 if ($type eq "test" && !defined($run_test)) {
1964 $type = "boot";
1967 open (IN, "git log --pretty=oneline $end|") or
1968 dodie "could not get git list";
1970 my @list;
1972 while (<IN>) {
1973 chomp;
1974 $list[$#list+1] = $_;
1975 last if (/^$start/);
1977 close(IN);
1979 if ($list[$#list] !~ /^$start/) {
1980 fail "SHA1 $start not found";
1983 # go backwards in the list
1984 @list = reverse @list;
1986 my $save_clean = $noclean;
1988 $in_patchcheck = 1;
1989 foreach my $item (@list) {
1990 my $sha1 = $item;
1991 $sha1 =~ s/^([[:xdigit:]]+).*/$1/;
1993 doprint "\nProcessing commit $item\n\n";
1995 run_command "git checkout $sha1" or
1996 die "Failed to checkout $sha1";
1998 # only clean on the first and last patch
1999 if ($item eq $list[0] ||
2000 $item eq $list[$#list]) {
2001 $noclean = $save_clean;
2002 } else {
2003 $noclean = 1;
2006 if (defined($minconfig)) {
2007 build "useconfig:$minconfig" or return 0;
2008 } else {
2009 # ?? no config to use?
2010 build "oldconfig" or return 0;
2013 check_buildlog $sha1 or return 0;
2015 next if ($type eq "build");
2017 get_grub_index;
2018 get_version;
2019 install;
2021 my $failed = 0;
2023 start_monitor;
2024 monitor or $failed = 1;
2026 if (!$failed && $type ne "boot"){
2027 do_run_test or $failed = 1;
2029 end_monitor;
2030 return 0 if ($failed);
2032 patchcheck_reboot;
2035 $in_patchcheck = 0;
2036 success $i;
2038 return 1;
2041 $#ARGV < 1 or die "ktest.pl version: $VERSION\n usage: ktest.pl config-file\n";
2043 if ($#ARGV == 0) {
2044 $ktest_config = $ARGV[0];
2045 if (! -f $ktest_config) {
2046 print "$ktest_config does not exist.\n";
2047 my $ans;
2048 for (;;) {
2049 print "Create it? [Y/n] ";
2050 $ans = <STDIN>;
2051 chomp $ans;
2052 if ($ans =~ /^\s*$/) {
2053 $ans = "y";
2055 last if ($ans =~ /^y$/i || $ans =~ /^n$/i);
2056 print "Please answer either 'y' or 'n'.\n";
2058 if ($ans !~ /^y$/i) {
2059 exit 0;
2062 } else {
2063 $ktest_config = "ktest.conf";
2066 if (! -f $ktest_config) {
2067 open(OUT, ">$ktest_config") or die "Can not create $ktest_config";
2068 print OUT << "EOF"
2069 # Generated by ktest.pl
2071 # Define each test with TEST_START
2072 # The config options below it will override the defaults
2073 TEST_START
2075 DEFAULTS
2078 close(OUT);
2080 read_config $ktest_config;
2082 # Append any configs entered in manually to the config file.
2083 my @new_configs = keys %entered_configs;
2084 if ($#new_configs >= 0) {
2085 print "\nAppending entered in configs to $ktest_config\n";
2086 open(OUT, ">>$ktest_config") or die "Can not append to $ktest_config";
2087 foreach my $config (@new_configs) {
2088 print OUT "$config = $entered_configs{$config}\n";
2089 $opt{$config} = $entered_configs{$config};
2093 if ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) {
2094 unlink $opt{"LOG_FILE"};
2097 doprint "\n\nSTARTING AUTOMATED TESTS\n\n";
2099 for (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) {
2101 if (!$i) {
2102 doprint "DEFAULT OPTIONS:\n";
2103 } else {
2104 doprint "\nTEST $i OPTIONS";
2105 if (defined($repeat_tests{$i})) {
2106 $repeat = $repeat_tests{$i};
2107 doprint " ITERATE $repeat";
2109 doprint "\n";
2112 foreach my $option (sort keys %opt) {
2114 if ($option =~ /\[(\d+)\]$/) {
2115 next if ($i != $1);
2116 } else {
2117 next if ($i);
2120 doprint "$option = $opt{$option}\n";
2124 sub __set_test_option {
2125 my ($name, $i) = @_;
2127 my $option = "$name\[$i\]";
2129 if (defined($opt{$option})) {
2130 return $opt{$option};
2133 foreach my $test (keys %repeat_tests) {
2134 if ($i >= $test &&
2135 $i < $test + $repeat_tests{$test}) {
2136 $option = "$name\[$test\]";
2137 if (defined($opt{$option})) {
2138 return $opt{$option};
2143 if (defined($opt{$name})) {
2144 return $opt{$name};
2147 return undef;
2150 sub eval_option {
2151 my ($option, $i) = @_;
2153 # Add space to evaluate the character before $
2154 $option = " $option";
2155 my $retval = "";
2157 while ($option =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
2158 my $start = $1;
2159 my $var = $2;
2160 my $end = $3;
2162 # Append beginning of line
2163 $retval = "$retval$start";
2165 # If the iteration option OPT[$i] exists, then use that.
2166 # otherwise see if the default OPT (without [$i]) exists.
2168 my $o = "$var\[$i\]";
2170 if (defined($opt{$o})) {
2171 $o = $opt{$o};
2172 $retval = "$retval$o";
2173 } elsif (defined($opt{$var})) {
2174 $o = $opt{$var};
2175 $retval = "$retval$o";
2176 } else {
2177 $retval = "$retval\$\{$var\}";
2180 $option = $end;
2183 $retval = "$retval$option";
2185 $retval =~ s/^ //;
2187 return $retval;
2190 sub set_test_option {
2191 my ($name, $i) = @_;
2193 my $option = __set_test_option($name, $i);
2194 return $option if (!defined($option));
2196 my $prev = "";
2198 # Since an option can evaluate to another option,
2199 # keep iterating until we do not evaluate any more
2200 # options.
2201 my $r = 0;
2202 while ($prev ne $option) {
2203 # Check for recursive evaluations.
2204 # 100 deep should be more than enough.
2205 if ($r++ > 100) {
2206 die "Over 100 evaluations accurred with $name\n" .
2207 "Check for recursive variables\n";
2209 $prev = $option;
2210 $option = eval_option($option, $i);
2213 return $option;
2216 # First we need to do is the builds
2217 for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
2219 $iteration = $i;
2221 my $makecmd = set_test_option("MAKE_CMD", $i);
2223 $machine = set_test_option("MACHINE", $i);
2224 $ssh_user = set_test_option("SSH_USER", $i);
2225 $tmpdir = set_test_option("TMP_DIR", $i);
2226 $outputdir = set_test_option("OUTPUT_DIR", $i);
2227 $builddir = set_test_option("BUILD_DIR", $i);
2228 $test_type = set_test_option("TEST_TYPE", $i);
2229 $build_type = set_test_option("BUILD_TYPE", $i);
2230 $build_options = set_test_option("BUILD_OPTIONS", $i);
2231 $power_cycle = set_test_option("POWER_CYCLE", $i);
2232 $reboot = set_test_option("REBOOT", $i);
2233 $noclean = set_test_option("BUILD_NOCLEAN", $i);
2234 $minconfig = set_test_option("MIN_CONFIG", $i);
2235 $run_test = set_test_option("TEST", $i);
2236 $addconfig = set_test_option("ADD_CONFIG", $i);
2237 $reboot_type = set_test_option("REBOOT_TYPE", $i);
2238 $grub_menu = set_test_option("GRUB_MENU", $i);
2239 $post_install = set_test_option("POST_INSTALL", $i);
2240 $reboot_script = set_test_option("REBOOT_SCRIPT", $i);
2241 $reboot_on_error = set_test_option("REBOOT_ON_ERROR", $i);
2242 $poweroff_on_error = set_test_option("POWEROFF_ON_ERROR", $i);
2243 $die_on_failure = set_test_option("DIE_ON_FAILURE", $i);
2244 $power_off = set_test_option("POWER_OFF", $i);
2245 $powercycle_after_reboot = set_test_option("POWERCYCLE_AFTER_REBOOT", $i);
2246 $poweroff_after_halt = set_test_option("POWEROFF_AFTER_HALT", $i);
2247 $sleep_time = set_test_option("SLEEP_TIME", $i);
2248 $bisect_sleep_time = set_test_option("BISECT_SLEEP_TIME", $i);
2249 $patchcheck_sleep_time = set_test_option("PATCHCHECK_SLEEP_TIME", $i);
2250 $bisect_manual = set_test_option("BISECT_MANUAL", $i);
2251 $bisect_skip = set_test_option("BISECT_SKIP", $i);
2252 $config_bisect_good = set_test_option("CONFIG_BISECT_GOOD", $i);
2253 $store_failures = set_test_option("STORE_FAILURES", $i);
2254 $test_name = set_test_option("TEST_NAME", $i);
2255 $timeout = set_test_option("TIMEOUT", $i);
2256 $booted_timeout = set_test_option("BOOTED_TIMEOUT", $i);
2257 $console = set_test_option("CONSOLE", $i);
2258 $detect_triplefault = set_test_option("DETECT_TRIPLE_FAULT", $i);
2259 $success_line = set_test_option("SUCCESS_LINE", $i);
2260 $stop_after_success = set_test_option("STOP_AFTER_SUCCESS", $i);
2261 $stop_after_failure = set_test_option("STOP_AFTER_FAILURE", $i);
2262 $stop_test_after = set_test_option("STOP_TEST_AFTER", $i);
2263 $build_target = set_test_option("BUILD_TARGET", $i);
2264 $ssh_exec = set_test_option("SSH_EXEC", $i);
2265 $scp_to_target = set_test_option("SCP_TO_TARGET", $i);
2266 $target_image = set_test_option("TARGET_IMAGE", $i);
2267 $localversion = set_test_option("LOCALVERSION", $i);
2269 chdir $builddir || die "can't change directory to $builddir";
2271 if (!-d $tmpdir) {
2272 mkpath($tmpdir) or
2273 die "can't create $tmpdir";
2276 $ENV{"SSH_USER"} = $ssh_user;
2277 $ENV{"MACHINE"} = $machine;
2279 $target = "$ssh_user\@$machine";
2281 $buildlog = "$tmpdir/buildlog-$machine";
2282 $dmesg = "$tmpdir/dmesg-$machine";
2283 $make = "$makecmd O=$outputdir";
2284 $output_config = "$outputdir/.config";
2286 if ($reboot_type eq "grub") {
2287 dodie "GRUB_MENU not defined" if (!defined($grub_menu));
2288 } elsif (!defined($reboot_script)) {
2289 dodie "REBOOT_SCRIPT not defined"
2292 my $run_type = $build_type;
2293 if ($test_type eq "patchcheck") {
2294 $run_type = $opt{"PATCHCHECK_TYPE[$i]"};
2295 } elsif ($test_type eq "bisect") {
2296 $run_type = $opt{"BISECT_TYPE[$i]"};
2297 } elsif ($test_type eq "config_bisect") {
2298 $run_type = $opt{"CONFIG_BISECT_TYPE[$i]"};
2301 # mistake in config file?
2302 if (!defined($run_type)) {
2303 $run_type = "ERROR";
2306 doprint "\n\n";
2307 doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type\n\n";
2309 unlink $dmesg;
2310 unlink $buildlog;
2312 if (!defined($minconfig)) {
2313 $minconfig = $addconfig;
2315 } elsif (defined($addconfig)) {
2316 run_command "cat $addconfig $minconfig > $tmpdir/add_config" or
2317 dodie "Failed to create temp config";
2318 $minconfig = "$tmpdir/add_config";
2321 my $checkout = $opt{"CHECKOUT[$i]"};
2322 if (defined($checkout)) {
2323 run_command "git checkout $checkout" or
2324 die "failed to checkout $checkout";
2327 if ($test_type eq "bisect") {
2328 bisect $i;
2329 next;
2330 } elsif ($test_type eq "config_bisect") {
2331 config_bisect $i;
2332 next;
2333 } elsif ($test_type eq "patchcheck") {
2334 patchcheck $i;
2335 next;
2338 if ($build_type ne "nobuild") {
2339 build $build_type or next;
2342 if ($test_type ne "build") {
2343 get_grub_index;
2344 get_version;
2345 install;
2347 my $failed = 0;
2348 start_monitor;
2349 monitor or $failed = 1;;
2351 if (!$failed && $test_type ne "boot" && defined($run_test)) {
2352 do_run_test or $failed = 1;
2354 end_monitor;
2355 next if ($failed);
2358 success $i;
2361 if ($opt{"POWEROFF_ON_SUCCESS"}) {
2362 halt;
2363 } elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot) {
2364 reboot;
2367 doprint "\n $successes of $opt{NUM_TESTS} tests were successful\n\n";
2369 exit 0;