]> git.karo-electronics.de Git - mv-sheeva.git/blob - tools/testing/ktest/ktest.pl
1e1fe835df48e1a7019eea0ea46ff6914396ea5b
[mv-sheeva.git] / tools / testing / ktest / ktest.pl
1 #!/usr/bin/perl -w
2 #
3 # Copyright 2010 - Steven Rostedt <srostedt@redhat.com>, Red Hat Inc.
4 # Licensed under the terms of the GNU GPL License version 2
5 #
6
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;
13
14 my $VERSION = "0.2";
15
16 $| = 1;
17
18 my %opt;
19 my %repeat_tests;
20 my %repeats;
21 my %default;
22
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";
54
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;
118
119 my %entered_configs;
120 my %config_help;
121 my %variable;
122 my %force_config;
123
124 $config_help{"MACHINE"} = << "EOF"
125  The machine hostname that you will test.
126 EOF
127     ;
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)
131 EOF
132     ;
133 $config_help{"BUILD_DIR"} = << "EOF"
134  The directory that contains the Linux source code (full path).
135 EOF
136     ;
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)
140 EOF
141     ;
142 $config_help{"BUILD_TARGET"} = << "EOF"
143  The location of the compiled file to copy to the target.
144  (relative to OUTPUT_DIR)
145 EOF
146     ;
147 $config_help{"TARGET_IMAGE"} = << "EOF"
148  The place to put your image on the test machine.
149 EOF
150     ;
151 $config_help{"POWER_CYCLE"} = << "EOF"
152  A script or command to reboot the box.
153
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'
156
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
160 EOF
161     ;
162 $config_help{"CONSOLE"} = << "EOF"
163  The script or command that reads the console
164
165   If you use ttywatch server, something like the following would work.
166 CONSOLE = nc -d localhost 3001
167
168  For a virtual machine with guest name "Guest".
169 CONSOLE =  virsh console Guest
170 EOF
171     ;
172 $config_help{"LOCALVERSION"} = << "EOF"
173  Required version ending to differentiate the test
174  from other linux builds on the system.
175 EOF
176     ;
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".
180
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.
186
187  The entry in /boot/grub/menu.lst must be entered in manually.
188  The test will not modify that file.
189 EOF
190     ;
191 $config_help{"GRUB_MENU"} = << "EOF"
192  The grub title name for the test kernel to boot
193  (Only mandatory if REBOOT_TYPE = grub)
194
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.
199
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
204 EOF
205     ;
206 $config_help{"REBOOT_SCRIPT"} = << "EOF"
207  A script to reboot the target into the test kernel
208  (Only mandatory if REBOOT_TYPE = script)
209 EOF
210     ;
211
212
213 sub get_ktest_config {
214     my ($config) = @_;
215
216     return if (defined($opt{$config}));
217
218     if (defined($config_help{$config})) {
219         print "\n";
220         print $config_help{$config};
221     }
222
223     for (;;) {
224         print "$config = ";
225         if (defined($default{$config})) {
226             print "\[$default{$config}\] ";
227         }
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;
236             }
237         }
238         last;
239     }
240 }
241
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");
252
253     my $rtype = $opt{"REBOOT_TYPE"};
254
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";
261         }
262     }
263
264     if ($rtype eq "grub") {
265         get_ktest_config("GRUB_MENU");
266     } else {
267         get_ktest_config("REBOOT_SCRIPT");
268     }
269 }
270
271 sub process_variables {
272     my ($value) = @_;
273     my $retval = "";
274
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";
281
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\}";
293         }
294         $value = $end;
295     }
296     $retval = "$retval$value";
297
298     # remove the space added in the beginning
299     $retval =~ s/ //;
300
301     return "$retval"
302 }
303
304 sub set_value {
305     my ($lvalue, $rvalue) = @_;
306
307     if (defined($opt{$lvalue})) {
308         die "Error: Option $lvalue defined more than once!\n";
309     }
310     if ($rvalue =~ /^\s*$/) {
311         delete $opt{$lvalue};
312     } else {
313         $rvalue = process_variables($rvalue);
314         $opt{$lvalue} = $rvalue;
315     }
316 }
317
318 sub set_variable {
319     my ($lvalue, $rvalue) = @_;
320
321     if ($rvalue =~ /^\s*$/) {
322         delete $variable{$lvalue};
323     } else {
324         $rvalue = process_variables($rvalue);
325         $variable{$lvalue} = $rvalue;
326     }
327 }
328
329 sub read_config {
330     my ($config) = @_;
331
332     open(IN, $config) || die "can't read file $config";
333
334     my $name = $config;
335     $name =~ s,.*/(.*),$1,;
336
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;
343
344     while (<IN>) {
345
346         # ignore blank lines and comments
347         next if (/^\s*$/ || /\s*\#/);
348
349         if (/^\s*TEST_START(.*)/) {
350
351             $rest = $1;
352
353             if ($num_tests_set) {
354                 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
355             }
356
357             my $old_test_num = $test_num;
358             my $old_repeat = $repeat;
359
360             $test_num += $repeat;
361             $default = 0;
362             $repeat = 1;
363
364             if ($rest =~ /\s+SKIP(.*)/) {
365                 $rest = $1;
366                 $skip = 1;
367             } else {
368                 $skip = 0;
369             }
370
371             if ($rest =~ /\s+ITERATE\s+(\d+)(.*)$/) {
372                 $repeat = $1;
373                 $rest = $2;
374                 $repeat_tests{"$test_num"} = $repeat;
375             }
376
377             if ($rest =~ /\s+SKIP(.*)/) {
378                 $rest = $1;
379                 $skip = 1;
380             }
381
382             if ($rest !~ /^\s*$/) {
383                 die "$name: $.: Gargbage found after TEST_START\n$_";
384             }
385
386             if ($skip) {
387                 $test_num = $old_test_num;
388                 $repeat = $old_repeat;
389             }
390
391         } elsif (/^\s*DEFAULTS(.*)$/) {
392             $default = 1;
393
394             $rest = $1;
395
396             if ($rest =~ /\s+SKIP(.*)/) {
397                 $rest = $1;
398                 $skip = 1;
399             } else {
400                 $skip = 0;
401             }
402
403             if ($rest !~ /^\s*$/) {
404                 die "$name: $.: Gargbage found after DEFAULTS\n$_";
405             }
406
407         } elsif (/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) {
408
409             next if ($skip);
410
411             my $lvalue = $1;
412             my $rvalue = $2;
413
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";
419             }
420
421             if ($lvalue eq "NUM_TESTS") {
422                 if ($test_num) {
423                     die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
424                 }
425                 if (!$default) {
426                     die "$name: $.: NUM_TESTS must be set in default section\n";
427                 }
428                 $num_tests_set = 1;
429             }
430
431             if ($default || $lvalue =~ /\[\d+\]$/) {
432                 set_value($lvalue, $rvalue);
433             } else {
434                 my $val = "$lvalue\[$test_num\]";
435                 set_value($val, $rvalue);
436
437                 if ($repeat > 1) {
438                     $repeats{$val} = $repeat;
439                 }
440             }
441         } elsif (/^\s*([A-Z_\[\]\d]+)\s*:=\s*(.*?)\s*$/) {
442             next if ($skip);
443
444             my $lvalue = $1;
445             my $rvalue = $2;
446
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);
456
457         } else {
458             die "$name: $.: Garbage found in config\n$_";
459         }
460     }
461
462     close(IN);
463
464     if ($test_num) {
465         $test_num += $repeat - 1;
466         $opt{"NUM_TESTS"} = $test_num;
467     }
468
469     # make sure we have all mandatory configs
470     get_ktest_configs;
471
472     # set any defaults
473
474     foreach my $default (keys %default) {
475         if (!defined($opt{$default})) {
476             $opt{$default} = $default{$default};
477         }
478     }
479 }
480
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);
486     }
487 }
488
489 sub logit {
490     if (defined($opt{"LOG_FILE"})) {
491         _logit @_;
492     } else {
493         print @_;
494     }
495 }
496
497 sub doprint {
498     print @_;
499     _logit @_;
500 }
501
502 sub run_command;
503
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";
510         }
511     } else {
512         # nope? power cycle it.
513         run_command "$power_cycle";
514     }
515 }
516
517 sub do_not_reboot {
518     my $i = $iteration;
519
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");
523 }
524
525 sub dodie {
526     doprint "CRITICAL FAILURE... ", @_, "\n";
527
528     my $i = $iteration;
529
530     if ($reboot_on_error && !do_not_reboot) {
531
532         doprint "REBOOTING\n";
533         reboot;
534
535     } elsif ($poweroff_on_error && defined($power_off)) {
536         doprint "POWERING OFF\n";
537         `$power_off`;
538     }
539
540     if (defined($opt{"LOG_FILE"})) {
541         print " See $opt{LOG_FILE} for more info.\n";
542     }
543
544     die @_, "\n";
545 }
546
547 sub open_console {
548     my ($fp) = @_;
549
550     my $flags;
551
552     my $pid = open($fp, "$console|") or
553         dodie "Can't open console $console";
554
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: $!";
559
560     return $pid;
561 }
562
563 sub close_console {
564     my ($fp, $pid) = @_;
565
566     doprint "kill child process $pid\n";
567     kill 2, $pid;
568
569     print "closing!\n";
570     close($fp);
571 }
572
573 sub start_monitor {
574     if ($monitor_cnt++) {
575         return;
576     }
577     $monitor_fp = \*MONFD;
578     $monitor_pid = open_console $monitor_fp;
579
580     return;
581
582     open(MONFD, "Stop perl from warning about single use of MONFD");
583 }
584
585 sub end_monitor {
586     if (--$monitor_cnt) {
587         return;
588     }
589     close_console($monitor_fp, $monitor_pid);
590 }
591
592 sub wait_for_monitor {
593     my ($time) = @_;
594     my $line;
595
596     doprint "** Wait for monitor to settle down **\n";
597
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";
604 }
605
606 sub fail {
607
608         if ($die_on_failure) {
609                 dodie @_;
610         }
611
612         doprint "FAILED\n";
613
614         my $i = $iteration;
615
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;
623         }
624
625         my $name = "";
626
627         if (defined($test_name)) {
628             $name = " ($test_name)";
629         }
630
631         doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
632         doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
633         doprint "KTEST RESULT: TEST $i$name Failed: ", @_, "\n";
634         doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
635         doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
636
637         return 1 if (!defined($store_failures));
638
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];
642
643         my $type = $build_type;
644         if ($type =~ /useconfig/) {
645             $type = "useconfig";
646         }
647
648         my $dir = "$machine-$test_type-$type-fail-$date";
649         my $faildir = "$store_failures/$dir";
650
651         if (!-d $faildir) {
652             mkpath($faildir) or
653                 die "can't create $faildir";
654         }
655         if (-f "$output_config") {
656             cp "$output_config", "$faildir/config" or
657                 die "failed to copy .config";
658         }
659         if (-f $buildlog) {
660             cp $buildlog, "$faildir/buildlog" or
661                 die "failed to move $buildlog";
662         }
663         if (-f $dmesg) {
664             cp $dmesg, "$faildir/dmesg" or
665                 die "failed to move $dmesg";
666         }
667
668         doprint "*** Saved info to $faildir ***\n";
669
670         return 1;
671 }
672
673 sub run_command {
674     my ($command) = @_;
675     my $dolog = 0;
676     my $dord = 0;
677     my $pid;
678
679     $command =~ s/\$SSH_USER/$ssh_user/g;
680     $command =~ s/\$MACHINE/$machine/g;
681
682     doprint("$command ... ");
683
684     $pid = open(CMD, "$command 2>&1 |") or
685         (fail "unable to exec $command" and return 0);
686
687     if (defined($opt{"LOG_FILE"})) {
688         open(LOG, ">>$opt{LOG_FILE}") or
689             dodie "failed to write to log";
690         $dolog = 1;
691     }
692
693     if (defined($redirect)) {
694         open (RD, ">$redirect") or
695             dodie "failed to write to redirect $redirect";
696         $dord = 1;
697     }
698
699     while (<CMD>) {
700         print LOG if ($dolog);
701         print RD  if ($dord);
702     }
703
704     waitpid($pid, 0);
705     my $failed = $?;
706
707     close(CMD);
708     close(LOG) if ($dolog);
709     close(RD)  if ($dord);
710
711     if ($failed) {
712         doprint "FAILED!\n";
713     } else {
714         doprint "SUCCESS\n";
715     }
716
717     return !$failed;
718 }
719
720 sub run_ssh {
721     my ($cmd) = @_;
722     my $cp_exec = $ssh_exec;
723
724     $cp_exec =~ s/\$SSH_COMMAND/$cmd/g;
725     return run_command "$cp_exec";
726 }
727
728 sub run_scp {
729     my ($src, $dst) = @_;
730     my $cp_scp = $scp_to_target;
731
732     $cp_scp =~ s/\$SRC_FILE/$src/g;
733     $cp_scp =~ s/\$DST_FILE/$dst/g;
734
735     return run_command "$cp_scp";
736 }
737
738 sub get_grub_index {
739
740     if ($reboot_type ne "grub") {
741         return;
742     }
743     return if (defined($grub_number));
744
745     doprint "Find grub menu ... ";
746     $grub_number = -1;
747
748     my $ssh_grub = $ssh_exec;
749     $ssh_grub =~ s,\$SSH_COMMAND,cat /boot/grub/menu.lst,g;
750
751     open(IN, "$ssh_grub |")
752         or die "unable to get menu.lst";
753
754     while (<IN>) {
755         if (/^\s*title\s+$grub_menu\s*$/) {
756             $grub_number++;
757             last;
758         } elsif (/^\s*title\s/) {
759             $grub_number++;
760         }
761     }
762     close(IN);
763
764     die "Could not find '$grub_menu' in /boot/grub/menu on $machine"
765         if ($grub_number < 0);
766     doprint "$grub_number\n";
767 }
768
769 sub wait_for_input
770 {
771     my ($fp, $time) = @_;
772     my $rin;
773     my $ready;
774     my $line;
775     my $ch;
776
777     if (!defined($time)) {
778         $time = $timeout;
779     }
780
781     $rin = '';
782     vec($rin, fileno($fp), 1) = 1;
783     $ready = select($rin, undef, undef, $time);
784
785     $line = "";
786
787     # try to read one char at a time
788     while (sysread $fp, $ch, 1) {
789         $line .= $ch;
790         last if ($ch eq "\n");
791     }
792
793     if (!length($line)) {
794         return undef;
795     }
796
797     return $line;
798 }
799
800 sub reboot_to {
801     if ($reboot_type eq "grub") {
802         run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch && reboot)'";
803         return;
804     }
805
806     run_command "$reboot_script";
807 }
808
809 sub get_sha1 {
810     my ($commit) = @_;
811
812     doprint "git rev-list --max-count=1 $commit ... ";
813     my $sha1 = `git rev-list --max-count=1 $commit`;
814     my $ret = $?;
815
816     logit $sha1;
817
818     if ($ret) {
819         doprint "FAILED\n";
820         dodie "Failed to get git $commit";
821     }
822
823     print "SUCCESS\n";
824
825     chomp $sha1;
826
827     return $sha1;
828 }
829
830 sub monitor {
831     my $booted = 0;
832     my $bug = 0;
833     my $skip_call_trace = 0;
834     my $loops;
835
836     wait_for_monitor 5;
837
838     my $line;
839     my $full_line = "";
840
841     open(DMESG, "> $dmesg") or
842         die "unable to write to $dmesg";
843
844     reboot_to;
845
846     my $success_start;
847     my $failure_start;
848     my $monitor_start = time;
849     my $done = 0;
850     my $version_found = 0;
851
852     while (!$done) {
853
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;
862             }
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;
869             }
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;
876             }
877         }
878
879         doprint $line;
880         print DMESG $line;
881
882         # we are not guaranteed to get a full line
883         $full_line .= $line;
884
885         if ($full_line =~ /$success_line/) {
886             $booted = 1;
887             $success_start = time;
888         }
889
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;
896             }
897         }
898
899         if ($full_line =~ /\[ backtrace testing \]/) {
900             $skip_call_trace = 1;
901         }
902
903         if ($full_line =~ /call trace:/i) {
904             if (!$bug && !$skip_call_trace) {
905                 $bug = 1;
906                 $failure_start = time;
907             }
908         }
909
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;
916             }
917         }
918
919         if ($full_line =~ /\[ end of backtrace testing \]/) {
920             $skip_call_trace = 0;
921         }
922
923         if ($full_line =~ /Kernel panic -/) {
924             $failure_start = time;
925             $bug = 1;
926         }
927
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;
941             }
942         }
943
944         if ($line =~ /\n/) {
945             $full_line = "";
946         }
947
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;
952             }
953         }
954     }
955
956     close(DMESG);
957
958     if ($bug) {
959         return 0 if ($in_bisect);
960         fail "failed - got a bug report" and return 0;
961     }
962
963     if (!$booted) {
964         return 0 if ($in_bisect);
965         fail "failed - never got a boot prompt." and return 0;
966     }
967
968     return 1;
969 }
970
971 sub install {
972
973     run_scp "$outputdir/$build_target", "$target_image" or
974         dodie "failed to copy image";
975
976     my $install_mods = 0;
977
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;
985         }
986     }
987     close(IN);
988
989     if (!$install_mods) {
990         doprint "No modules needed\n";
991         return;
992     }
993
994     run_command "$make INSTALL_MOD_PATH=$tmpdir modules_install" or
995         dodie "Failed to install modules";
996
997     my $modlib = "/lib/modules/$version";
998     my $modtar = "ktest-mods.tar.bz2";
999
1000     run_ssh "rm -rf $modlib" or
1001         dodie "failed to remove old mods: $modlib";
1002
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";
1006
1007     run_scp "$tmpdir/$modtar", "/tmp" or
1008         dodie "failed to copy modules";
1009
1010     unlink "$tmpdir/$modtar";
1011
1012     run_ssh "'(cd / && tar xf /tmp/$modtar)'" or
1013         dodie "failed to tar modules";
1014
1015     run_ssh "rm -f /tmp/$modtar";
1016
1017     return if (!defined($post_install));
1018
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";
1023 }
1024
1025 sub check_buildlog {
1026     my ($patch) = @_;
1027
1028     my @files = `git show $patch | diffstat -l`;
1029
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;
1036         }
1037     }
1038     close(IN);
1039
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;
1048                 }
1049             }
1050         }
1051     }
1052     close(IN);
1053
1054     return 1;
1055 }
1056
1057 sub apply_min_config {
1058     my $outconfig = "$output_config.new";
1059
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.
1063
1064     doprint "Applying minimum configurations into $output_config.new\n";
1065
1066     open (OUT, ">$outconfig") or
1067         dodie "Can't create $outconfig";
1068
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}));
1075             }
1076             print OUT;
1077         }
1078         close IN;
1079     }
1080     foreach my $config (keys %force_config) {
1081         print OUT "$force_config{$config}\n";
1082     }
1083     close OUT;
1084
1085     run_command "mv $outconfig $output_config";
1086 }
1087
1088 sub make_oldconfig {
1089
1090     apply_min_config;
1091
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";
1098     }
1099 }
1100
1101 # read a config file and use this to force new configs.
1102 sub load_force_config {
1103     my ($config) = @_;
1104
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} = $_;
1113         }
1114     }
1115     close IN;
1116 }
1117
1118 sub build {
1119     my ($type) = @_;
1120
1121     unlink $buildlog;
1122
1123     if ($type =~ /^useconfig:(.*)/) {
1124         run_command "cp $1 $output_config" or
1125             dodie "could not copy $1 to .config";
1126
1127         $type = "oldconfig";
1128     }
1129
1130     # old config can ask questions
1131     if ($type eq "oldconfig") {
1132         $type = "oldnoconfig";
1133
1134         # allow for empty configs
1135         run_command "touch $output_config";
1136
1137         run_command "mv $output_config $outputdir/config_temp" or
1138             dodie "moving .config";
1139
1140         if (!$noclean && !run_command "$make mrproper") {
1141             dodie "make mrproper";
1142         }
1143
1144         run_command "mv $outputdir/config_temp $output_config" or
1145             dodie "moving config_temp";
1146
1147     } elsif (!$noclean) {
1148         unlink "$output_config";
1149         run_command "$make mrproper" or
1150             dodie "make mrproper";
1151     }
1152
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);
1157
1158     if (defined($minconfig)) {
1159         load_force_config($minconfig);
1160     }
1161
1162     if ($type ne "oldnoconfig") {
1163         run_command "$make $type" or
1164             dodie "failed make config";
1165     }
1166     # Run old config regardless, to enforce min configurations
1167     make_oldconfig;
1168
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;
1175     }
1176     undef $redirect;
1177
1178     return 1;
1179 }
1180
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";
1186         }
1187     } else {
1188         # nope? the zap it!
1189         run_command "$power_off";
1190     }
1191 }
1192
1193 sub success {
1194     my ($i) = @_;
1195
1196     $successes++;
1197
1198     my $name = "";
1199
1200     if (defined($test_name)) {
1201         $name = " ($test_name)";
1202     }
1203
1204     doprint "\n\n*******************************************\n";
1205     doprint     "*******************************************\n";
1206     doprint     "KTEST RESULT: TEST $i$name SUCCESS!!!!         **\n";
1207     doprint     "*******************************************\n";
1208     doprint     "*******************************************\n";
1209
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;
1216     }
1217 }
1218
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";
1225 }
1226
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";
1238         }
1239     }
1240 }
1241
1242 sub child_run_test {
1243     my $failed = 0;
1244
1245     # child should have no power
1246     $reboot_on_error = 0;
1247     $poweroff_on_error = 0;
1248     $die_on_failure = 1;
1249
1250     run_command $run_test or $failed = 1;
1251     exit $failed;
1252 }
1253
1254 my $child_done;
1255
1256 sub child_finished {
1257     $child_done = 1;
1258 }
1259
1260 sub do_run_test {
1261     my $child_pid;
1262     my $child_exit;
1263     my $line;
1264     my $full_line;
1265     my $bug = 0;
1266
1267     wait_for_monitor 1;
1268
1269     doprint "run test $run_test\n";
1270
1271     $child_done = 0;
1272
1273     $SIG{CHLD} = qw(child_finished);
1274
1275     $child_pid = fork;
1276
1277     child_run_test if (!$child_pid);
1278
1279     $full_line = "";
1280
1281     do {
1282         $line = wait_for_input($monitor_fp, 1);
1283         if (defined($line)) {
1284
1285             # we are not guaranteed to get a full line
1286             $full_line .= $line;
1287             doprint $line;
1288
1289             if ($full_line =~ /call trace:/i) {
1290                 $bug = 1;
1291             }
1292
1293             if ($full_line =~ /Kernel panic -/) {
1294                 $bug = 1;
1295             }
1296
1297             if ($line =~ /\n/) {
1298                 $full_line = "";
1299             }
1300         }
1301     } while (!$child_done && !$bug);
1302
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;
1310             }
1311             $now = time;
1312             if ($now - $failure_start >= $stop_after_failure) {
1313                 last;
1314             }
1315         } while (defined($line));
1316
1317         doprint "Detected kernel crash!\n";
1318         # kill the child with extreme prejudice
1319         kill 9, $child_pid;
1320     }
1321
1322     waitpid $child_pid, 0;
1323     $child_exit = $?;
1324
1325     if ($bug || $child_exit) {
1326         return 0 if $in_bisect;
1327         fail "test failed" and return 0;
1328     }
1329     return 1;
1330 }
1331
1332 sub run_git_bisect {
1333     my ($command) = @_;
1334
1335     doprint "$command ... ";
1336
1337     my $output = `$command 2>&1`;
1338     my $ret = $?;
1339
1340     logit $output;
1341
1342     if ($ret) {
1343         doprint "FAILED\n";
1344         dodie "Failed to git bisect";
1345     }
1346
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;
1357     }
1358
1359     return 1;
1360 }
1361
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;
1368 }
1369
1370 # returns 1 on success, 0 on failure, -1 on skip
1371 sub run_bisect_test {
1372     my ($type, $buildtype) = @_;
1373
1374     my $failed = 0;
1375     my $result;
1376     my $output;
1377     my $ret;
1378
1379     $in_bisect = 1;
1380
1381     build $buildtype or $failed = 1;
1382
1383     if ($type ne "build") {
1384         if ($failed && $bisect_skip) {
1385             $in_bisect = 0;
1386             return -1;
1387         }
1388         dodie "Failed on build" if $failed;
1389
1390         # Now boot the box
1391         get_grub_index;
1392         get_version;
1393         install;
1394
1395         start_monitor;
1396         monitor or $failed = 1;
1397
1398         if ($type ne "boot") {
1399             if ($failed && $bisect_skip) {
1400                 end_monitor;
1401                 bisect_reboot;
1402                 $in_bisect = 0;
1403                 return -1;
1404             }
1405             dodie "Failed on boot" if $failed;
1406
1407             do_run_test or $failed = 1;
1408         }
1409         end_monitor;
1410     }
1411
1412     if ($failed) {
1413         $result = 0;
1414     } else {
1415         $result = 1;
1416     }
1417
1418     # reboot the box to a kernel we can ssh to
1419     if ($type ne "build") {
1420         bisect_reboot;
1421     }
1422     $in_bisect = 0;
1423
1424     return $result;
1425 }
1426
1427 sub run_bisect {
1428     my ($type) = @_;
1429     my $buildtype = "oldconfig";
1430
1431     # We should have a minconfig to use?
1432     if (defined($minconfig)) {
1433         $buildtype = "useconfig:$minconfig";
1434     }
1435
1436     my $ret = run_bisect_test $type, $buildtype;
1437
1438     if ($bisect_manual) {
1439         $ret = answer_bisect;
1440     }
1441
1442     # Are we looking for where it worked, not failed?
1443     if ($reverse_bisect) {
1444         $ret = !$ret;
1445     }
1446
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";
1454     }
1455 }
1456
1457 sub bisect {
1458     my ($i) = @_;
1459
1460     my $result;
1461
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]"}));
1465
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]"};
1472
1473     if (defined($start_files)) {
1474         $start_files = " -- " . $start_files;
1475     } else {
1476         $start_files = "";
1477     }
1478
1479     # convert to true sha1's
1480     $good = get_sha1($good);
1481     $bad = get_sha1($bad);
1482
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;
1489     }
1490
1491     # Can't have a test without having a test to run
1492     if ($type eq "test" && !defined($run_test)) {
1493         $type = "boot";
1494     }
1495
1496     my $check = $opt{"BISECT_CHECK[$i]"};
1497     if (defined($check) && $check ne "0") {
1498
1499         # get current HEAD
1500         my $head = get_sha1("HEAD");
1501
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";
1506
1507             $result = run_bisect $type;
1508
1509             if ($result ne "bad") {
1510                 fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0;
1511             }
1512         }
1513
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";
1518
1519             $result = run_bisect $type;
1520
1521             if ($result ne "good") {
1522                 fail "Tested BISECT_GOOD [$good] and it failed" and return 0;
1523             }
1524         }
1525
1526         # checkout where we started
1527         run_command "git checkout $head" or
1528             die "Failed to checkout $head";
1529     }
1530
1531     run_command "git bisect start$start_files" or
1532         dodie "could not start bisect";
1533
1534     run_command "git bisect good $good" or
1535         dodie "could not set bisect good to $good";
1536
1537     run_git_bisect "git bisect bad $bad" or
1538         dodie "could not set bisect bad to $bad";
1539
1540     if (defined($replay)) {
1541         run_command "git bisect replay $replay" or
1542             dodie "failed to run replay";
1543     }
1544
1545     if (defined($start)) {
1546         run_command "git checkout $start" or
1547             dodie "failed to checkout $start";
1548     }
1549
1550     my $test;
1551     do {
1552         $result = run_bisect $type;
1553         $test = run_git_bisect "git bisect $result";
1554     } while ($test);
1555
1556     run_command "git bisect log" or
1557         dodie "could not capture git bisect log";
1558
1559     run_command "git bisect reset" or
1560         dodie "could not reset git bisect";
1561
1562     doprint "Bad commit was [$bisect_bad]\n";
1563
1564     success $i;
1565 }
1566
1567 my %config_ignore;
1568 my %config_set;
1569
1570 my %config_list;
1571 my %null_config;
1572
1573 my %dependency;
1574
1575 sub process_config_ignore {
1576     my ($config) = @_;
1577
1578     open (IN, $config)
1579         or dodie "Failed to read $config";
1580
1581     while (<IN>) {
1582         if (/^((CONFIG\S*)=.*)/) {
1583             $config_ignore{$2} = $1;
1584         }
1585     }
1586
1587     close(IN);
1588 }
1589
1590 sub read_current_config {
1591     my ($config_ref) = @_;
1592
1593     %{$config_ref} = ();
1594     undef %{$config_ref};
1595
1596     my @key = keys %{$config_ref};
1597     if ($#key >= 0) {
1598         print "did not delete!\n";
1599         exit;
1600     }
1601     open (IN, "$output_config");
1602
1603     while (<IN>) {
1604         if (/^(CONFIG\S+)=(.*)/) {
1605             ${$config_ref}{$1} = $2;
1606         }
1607     }
1608     close(IN);
1609 }
1610
1611 sub get_dependencies {
1612     my ($config) = @_;
1613
1614     my $arr = $dependency{$config};
1615     if (!defined($arr)) {
1616         return ();
1617     }
1618
1619     my @deps = @{$arr};
1620
1621     foreach my $dep (@{$arr}) {
1622         print "ADD DEP $dep\n";
1623         @deps = (@deps, get_dependencies $dep);
1624     }
1625
1626     return @deps;
1627 }
1628
1629 sub create_config {
1630     my @configs = @_;
1631
1632     open(OUT, ">$output_config") or dodie "Can not write to $output_config";
1633
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";
1639         }
1640     }
1641
1642     foreach my $config (keys %config_ignore) {
1643         print OUT "$config_ignore{$config}\n";
1644     }
1645     close(OUT);
1646
1647 #    exit;
1648     make_oldconfig;
1649 }
1650
1651 sub compare_configs {
1652     my (%a, %b) = @_;
1653
1654     foreach my $item (keys %a) {
1655         if (!defined($b{$item})) {
1656             print "diff $item\n";
1657             return 1;
1658         }
1659         delete $b{$item};
1660     }
1661
1662     my @keys = keys %b;
1663     if ($#keys) {
1664         print "diff2 $keys[0]\n";
1665     }
1666     return -1 if ($#keys >= 0);
1667
1668     return 0;
1669 }
1670
1671 sub run_config_bisect_test {
1672     my ($type) = @_;
1673
1674     return run_bisect_test $type, "oldconfig";
1675 }
1676
1677 sub process_passed {
1678     my (%configs) = @_;
1679
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};
1688         }
1689     }
1690     doprint "config copied to $outputdir/config_good\n";
1691     run_command "cp -f $output_config $outputdir/config_good";
1692 }
1693
1694 sub process_failed {
1695     my ($config) = @_;
1696
1697     doprint "\n\n***************************************\n";
1698     doprint "Found bad config: $config\n";
1699     doprint "***************************************\n\n";
1700 }
1701
1702 sub run_config_bisect {
1703
1704     my @start_list = keys %config_list;
1705
1706     if ($#start_list < 0) {
1707         doprint "No more configs to test!!!\n";
1708         return -1;
1709     }
1710
1711     doprint "***** RUN TEST ***\n";
1712     my $type = $opt{"CONFIG_BISECT_TYPE[$iteration]"};
1713     my $ret;
1714     my %current_config;
1715
1716     my $count = $#start_list + 1;
1717     doprint "  $count configs to test\n";
1718
1719     my $half = int($#start_list / 2);
1720
1721     do {
1722         my @tophalf = @start_list[0 .. $half];
1723
1724         create_config @tophalf;
1725         read_current_config \%current_config;
1726
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;
1735             }
1736         }
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;
1747                 }
1748             }
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";
1753                 }
1754                 return -1;
1755             }
1756             $count = $#tophalf + 1;
1757             doprint "Testing $count configs\n";
1758         }
1759
1760         $ret = run_config_bisect_test $type;
1761         if ($bisect_manual) {
1762             $ret = answer_bisect;
1763         }
1764         if ($ret) {
1765             process_passed %current_config;
1766             return 0;
1767         }
1768
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";
1773
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};
1779             }
1780         }
1781
1782         @start_list = @tophalf;
1783
1784         if ($#start_list == 0) {
1785             process_failed $start_list[0];
1786             return 1;
1787         }
1788
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);
1793
1794     # we found a single config, try it again unless we are running manually
1795
1796     if ($bisect_manual) {
1797         process_failed $start_list[0];
1798         return 1;
1799     }
1800
1801     my @tophalf = @start_list[0 .. 0];
1802
1803     $ret = run_config_bisect_test $type;
1804     if ($ret) {
1805         process_passed %current_config;
1806         return 0;
1807     }
1808
1809     process_failed $start_list[0];
1810     return 1;
1811 }
1812
1813 sub config_bisect {
1814     my ($i) = @_;
1815
1816     my $start_config = $opt{"CONFIG_BISECT[$i]"};
1817
1818     my $tmpconfig = "$tmpdir/use_config";
1819
1820     if (defined($config_bisect_good)) {
1821         process_config_ignore $config_bisect_good;
1822     }
1823
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;
1831     }
1832
1833     # Add other configs
1834     if (defined($addconfig)) {
1835         run_command "cat $addconfig >> $tmpconfig" or
1836             dodie "failed to append $addconfig";
1837     }
1838
1839     if (-f $tmpconfig) {
1840         load_force_config($tmpconfig);
1841         process_config_ignore $tmpconfig;
1842     }
1843
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";
1847
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";
1852
1853     while (<IN>) {
1854         if (/^((CONFIG\S*)=.*)/) {
1855             $config_check{$2} = $1;
1856         }
1857     }
1858     close(IN);
1859
1860     # Now run oldconfig with the minconfig (and addconfigs)
1861     make_oldconfig;
1862
1863     # check to see what we lost (or gained)
1864     open (IN, $output_config)
1865         or dodie "Failed to read $start_config";
1866
1867     my %removed_configs;
1868     my %added_configs;
1869
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;
1879                 }
1880             } elsif (!defined($config_ignore{$2})) {
1881                 $added_configs{$2} = $1;
1882                 $config_list{$2} = $1;
1883             }
1884         }
1885     }
1886     close(IN);
1887
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";
1893         }
1894     }
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";
1900         }
1901     }
1902
1903     my %config_test;
1904     my $once = 0;
1905
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";
1918             }
1919             doprint "  $config\n";
1920             delete $config_list{$config};
1921         }
1922     }
1923     my $ret;
1924     do {
1925         $ret = run_config_bisect;
1926     } while (!$ret);
1927
1928     return $ret if ($ret < 0);
1929
1930     success $i;
1931 }
1932
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;
1939 }
1940
1941 sub patchcheck {
1942     my ($i) = @_;
1943
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]"}));
1948
1949     my $start = $opt{"PATCHCHECK_START[$i]"};
1950
1951     my $end = "HEAD";
1952     if (defined($opt{"PATCHCHECK_END[$i]"})) {
1953         $end = $opt{"PATCHCHECK_END[$i]"};
1954     }
1955
1956     # Get the true sha1's since we can use things like HEAD~3
1957     $start = get_sha1($start);
1958     $end = get_sha1($end);
1959
1960     my $type = $opt{"PATCHCHECK_TYPE[$i]"};
1961
1962     # Can't have a test without having a test to run
1963     if ($type eq "test" && !defined($run_test)) {
1964         $type = "boot";
1965     }
1966
1967     open (IN, "git log --pretty=oneline $end|") or
1968         dodie "could not get git list";
1969
1970     my @list;
1971
1972     while (<IN>) {
1973         chomp;
1974         $list[$#list+1] = $_;
1975         last if (/^$start/);
1976     }
1977     close(IN);
1978
1979     if ($list[$#list] !~ /^$start/) {
1980         fail "SHA1 $start not found";
1981     }
1982
1983     # go backwards in the list
1984     @list = reverse @list;
1985
1986     my $save_clean = $noclean;
1987
1988     $in_patchcheck = 1;
1989     foreach my $item (@list) {
1990         my $sha1 = $item;
1991         $sha1 =~ s/^([[:xdigit:]]+).*/$1/;
1992
1993         doprint "\nProcessing commit $item\n\n";
1994
1995         run_command "git checkout $sha1" or
1996             die "Failed to checkout $sha1";
1997
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;
2004         }
2005
2006         if (defined($minconfig)) {
2007             build "useconfig:$minconfig" or return 0;
2008         } else {
2009             # ?? no config to use?
2010             build "oldconfig" or return 0;
2011         }
2012
2013         check_buildlog $sha1 or return 0;
2014
2015         next if ($type eq "build");
2016
2017         get_grub_index;
2018         get_version;
2019         install;
2020
2021         my $failed = 0;
2022
2023         start_monitor;
2024         monitor or $failed = 1;
2025
2026         if (!$failed && $type ne "boot"){
2027             do_run_test or $failed = 1;
2028         }
2029         end_monitor;
2030         return 0 if ($failed);
2031
2032         patchcheck_reboot;
2033
2034     }
2035     $in_patchcheck = 0;
2036     success $i;
2037
2038     return 1;
2039 }
2040
2041 $#ARGV < 1 or die "ktest.pl version: $VERSION\n   usage: ktest.pl config-file\n";
2042
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";
2054             }
2055             last if ($ans =~ /^y$/i || $ans =~ /^n$/i);
2056             print "Please answer either 'y' or 'n'.\n";
2057         }
2058         if ($ans !~ /^y$/i) {
2059             exit 0;
2060         }
2061     }
2062 } else {
2063     $ktest_config = "ktest.conf";
2064 }
2065
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
2070 #
2071 # Define each test with TEST_START
2072 # The config options below it will override the defaults
2073 TEST_START
2074
2075 DEFAULTS
2076 EOF
2077 ;
2078     close(OUT);
2079 }
2080 read_config $ktest_config;
2081
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};
2090     }
2091 }
2092
2093 if ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) {
2094     unlink $opt{"LOG_FILE"};
2095 }
2096
2097 doprint "\n\nSTARTING AUTOMATED TESTS\n\n";
2098
2099 for (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) {
2100
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";
2108         }
2109         doprint "\n";
2110     }
2111
2112     foreach my $option (sort keys %opt) {
2113
2114         if ($option =~ /\[(\d+)\]$/) {
2115             next if ($i != $1);
2116         } else {
2117             next if ($i);
2118         }
2119
2120         doprint "$option = $opt{$option}\n";
2121     }
2122 }
2123
2124 sub __set_test_option {
2125     my ($name, $i) = @_;
2126
2127     my $option = "$name\[$i\]";
2128
2129     if (defined($opt{$option})) {
2130         return $opt{$option};
2131     }
2132
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};
2139             }
2140         }
2141     }
2142
2143     if (defined($opt{$name})) {
2144         return $opt{$name};
2145     }
2146
2147     return undef;
2148 }
2149
2150 sub eval_option {
2151     my ($option, $i) = @_;
2152
2153     # Add space to evaluate the character before $
2154     $option = " $option";
2155     my $retval = "";
2156
2157     while ($option =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
2158         my $start = $1;
2159         my $var = $2;
2160         my $end = $3;
2161
2162         # Append beginning of line
2163         $retval = "$retval$start";
2164
2165         # If the iteration option OPT[$i] exists, then use that.
2166         # otherwise see if the default OPT (without [$i]) exists.
2167
2168         my $o = "$var\[$i\]";
2169
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\}";
2178         }
2179
2180         $option = $end;
2181     }
2182
2183     $retval = "$retval$option";
2184
2185     $retval =~ s/^ //;
2186
2187     return $retval;
2188 }
2189
2190 sub set_test_option {
2191     my ($name, $i) = @_;
2192
2193     my $option = __set_test_option($name, $i);
2194     return $option if (!defined($option));
2195
2196     my $prev = "";
2197
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";
2208         }
2209         $prev = $option;
2210         $option = eval_option($option, $i);
2211     }
2212
2213     return $option;
2214 }
2215
2216 # First we need to do is the builds
2217 for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
2218
2219     $iteration = $i;
2220
2221     my $makecmd = set_test_option("MAKE_CMD", $i);
2222
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);
2268
2269     chdir $builddir || die "can't change directory to $builddir";
2270
2271     if (!-d $tmpdir) {
2272         mkpath($tmpdir) or
2273             die "can't create $tmpdir";
2274     }
2275
2276     $ENV{"SSH_USER"} = $ssh_user;
2277     $ENV{"MACHINE"} = $machine;
2278
2279     $target = "$ssh_user\@$machine";
2280
2281     $buildlog = "$tmpdir/buildlog-$machine";
2282     $dmesg = "$tmpdir/dmesg-$machine";
2283     $make = "$makecmd O=$outputdir";
2284     $output_config = "$outputdir/.config";
2285
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"
2290     }
2291
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]"};
2299     }
2300
2301     # mistake in config file?
2302     if (!defined($run_type)) {
2303         $run_type = "ERROR";
2304     }
2305
2306     doprint "\n\n";
2307     doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type\n\n";
2308
2309     unlink $dmesg;
2310     unlink $buildlog;
2311
2312     if (!defined($minconfig)) {
2313         $minconfig = $addconfig;
2314
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";
2319     }
2320
2321     my $checkout = $opt{"CHECKOUT[$i]"};
2322     if (defined($checkout)) {
2323         run_command "git checkout $checkout" or
2324             die "failed to checkout $checkout";
2325     }
2326
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;
2336     }
2337
2338     if ($build_type ne "nobuild") {
2339         build $build_type or next;
2340     }
2341
2342     if ($test_type ne "build") {
2343         get_grub_index;
2344         get_version;
2345         install;
2346
2347         my $failed = 0;
2348         start_monitor;
2349         monitor or $failed = 1;;
2350
2351         if (!$failed && $test_type ne "boot" && defined($run_test)) {
2352             do_run_test or $failed = 1;
2353         }
2354         end_monitor;
2355         next if ($failed);
2356     }
2357
2358     success $i;
2359 }
2360
2361 if ($opt{"POWEROFF_ON_SUCCESS"}) {
2362     halt;
2363 } elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot) {
2364     reboot;
2365 }
2366
2367 doprint "\n    $successes of $opt{NUM_TESTS} tests were successful\n\n";
2368
2369 exit 0;