ktest: Add test type make_min_config
[pandora-kernel.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/\${MACHINE}";
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 $pre_build;
67 my $post_build;
68 my $pre_build_die;
69 my $post_build_die;
70 my $reboot_type;
71 my $reboot_script;
72 my $power_cycle;
73 my $reboot;
74 my $reboot_on_error;
75 my $poweroff_on_error;
76 my $die_on_failure;
77 my $powercycle_after_reboot;
78 my $poweroff_after_halt;
79 my $ssh_exec;
80 my $scp_to_target;
81 my $power_off;
82 my $grub_menu;
83 my $grub_number;
84 my $target;
85 my $make;
86 my $post_install;
87 my $noclean;
88 my $minconfig;
89 my $start_minconfig;
90 my $output_minconfig;
91 my $ignore_config;
92 my $addconfig;
93 my $in_bisect = 0;
94 my $bisect_bad = "";
95 my $reverse_bisect;
96 my $bisect_manual;
97 my $bisect_skip;
98 my $config_bisect_good;
99 my $in_patchcheck = 0;
100 my $run_test;
101 my $redirect;
102 my $buildlog;
103 my $dmesg;
104 my $monitor_fp;
105 my $monitor_pid;
106 my $monitor_cnt = 0;
107 my $sleep_time;
108 my $bisect_sleep_time;
109 my $patchcheck_sleep_time;
110 my $ignore_warnings;
111 my $store_failures;
112 my $test_name;
113 my $timeout;
114 my $booted_timeout;
115 my $detect_triplefault;
116 my $console;
117 my $success_line;
118 my $stop_after_success;
119 my $stop_after_failure;
120 my $stop_test_after;
121 my $build_target;
122 my $target_image;
123 my $localversion;
124 my $iteration = 0;
125 my $successes = 0;
126
127 my %entered_configs;
128 my %config_help;
129 my %variable;
130 my %force_config;
131
132 $config_help{"MACHINE"} = << "EOF"
133  The machine hostname that you will test.
134 EOF
135     ;
136 $config_help{"SSH_USER"} = << "EOF"
137  The box is expected to have ssh on normal bootup, provide the user
138   (most likely root, since you need privileged operations)
139 EOF
140     ;
141 $config_help{"BUILD_DIR"} = << "EOF"
142  The directory that contains the Linux source code (full path).
143 EOF
144     ;
145 $config_help{"OUTPUT_DIR"} = << "EOF"
146  The directory that the objects will be built (full path).
147  (can not be same as BUILD_DIR)
148 EOF
149     ;
150 $config_help{"BUILD_TARGET"} = << "EOF"
151  The location of the compiled file to copy to the target.
152  (relative to OUTPUT_DIR)
153 EOF
154     ;
155 $config_help{"TARGET_IMAGE"} = << "EOF"
156  The place to put your image on the test machine.
157 EOF
158     ;
159 $config_help{"POWER_CYCLE"} = << "EOF"
160  A script or command to reboot the box.
161
162  Here is a digital loggers power switch example
163  POWER_CYCLE = wget --no-proxy -O /dev/null -q  --auth-no-challenge 'http://admin:admin\@power/outlet?5=CCL'
164
165  Here is an example to reboot a virtual box on the current host
166  with the name "Guest".
167  POWER_CYCLE = virsh destroy Guest; sleep 5; virsh start Guest
168 EOF
169     ;
170 $config_help{"CONSOLE"} = << "EOF"
171  The script or command that reads the console
172
173   If you use ttywatch server, something like the following would work.
174 CONSOLE = nc -d localhost 3001
175
176  For a virtual machine with guest name "Guest".
177 CONSOLE =  virsh console Guest
178 EOF
179     ;
180 $config_help{"LOCALVERSION"} = << "EOF"
181  Required version ending to differentiate the test
182  from other linux builds on the system.
183 EOF
184     ;
185 $config_help{"REBOOT_TYPE"} = << "EOF"
186  Way to reboot the box to the test kernel.
187  Only valid options so far are "grub" and "script".
188
189  If you specify grub, it will assume grub version 1
190  and will search in /boot/grub/menu.lst for the title \$GRUB_MENU
191  and select that target to reboot to the kernel. If this is not
192  your setup, then specify "script" and have a command or script
193  specified in REBOOT_SCRIPT to boot to the target.
194
195  The entry in /boot/grub/menu.lst must be entered in manually.
196  The test will not modify that file.
197 EOF
198     ;
199 $config_help{"GRUB_MENU"} = << "EOF"
200  The grub title name for the test kernel to boot
201  (Only mandatory if REBOOT_TYPE = grub)
202
203  Note, ktest.pl will not update the grub menu.lst, you need to
204  manually add an option for the test. ktest.pl will search
205  the grub menu.lst for this option to find what kernel to
206  reboot into.
207
208  For example, if in the /boot/grub/menu.lst the test kernel title has:
209  title Test Kernel
210  kernel vmlinuz-test
211  GRUB_MENU = Test Kernel
212 EOF
213     ;
214 $config_help{"REBOOT_SCRIPT"} = << "EOF"
215  A script to reboot the target into the test kernel
216  (Only mandatory if REBOOT_TYPE = script)
217 EOF
218     ;
219
220
221 sub get_ktest_config {
222     my ($config) = @_;
223
224     return if (defined($opt{$config}));
225
226     if (defined($config_help{$config})) {
227         print "\n";
228         print $config_help{$config};
229     }
230
231     for (;;) {
232         print "$config = ";
233         if (defined($default{$config})) {
234             print "\[$default{$config}\] ";
235         }
236         $entered_configs{$config} = <STDIN>;
237         $entered_configs{$config} =~ s/^\s*(.*\S)\s*$/$1/;
238         if ($entered_configs{$config} =~ /^\s*$/) {
239             if ($default{$config}) {
240                 $entered_configs{$config} = $default{$config};
241             } else {
242                 print "Your answer can not be blank\n";
243                 next;
244             }
245         }
246         last;
247     }
248 }
249
250 sub get_ktest_configs {
251     get_ktest_config("MACHINE");
252     get_ktest_config("SSH_USER");
253     get_ktest_config("BUILD_DIR");
254     get_ktest_config("OUTPUT_DIR");
255     get_ktest_config("BUILD_TARGET");
256     get_ktest_config("TARGET_IMAGE");
257     get_ktest_config("POWER_CYCLE");
258     get_ktest_config("CONSOLE");
259     get_ktest_config("LOCALVERSION");
260
261     my $rtype = $opt{"REBOOT_TYPE"};
262
263     if (!defined($rtype)) {
264         if (!defined($opt{"GRUB_MENU"})) {
265             get_ktest_config("REBOOT_TYPE");
266             $rtype = $entered_configs{"REBOOT_TYPE"};
267         } else {
268             $rtype = "grub";
269         }
270     }
271
272     if ($rtype eq "grub") {
273         get_ktest_config("GRUB_MENU");
274     } else {
275         get_ktest_config("REBOOT_SCRIPT");
276     }
277 }
278
279 sub process_variables {
280     my ($value) = @_;
281     my $retval = "";
282
283     # We want to check for '\', and it is just easier
284     # to check the previous characet of '$' and not need
285     # to worry if '$' is the first character. By adding
286     # a space to $value, we can just check [^\\]\$ and
287     # it will still work.
288     $value = " $value";
289
290     while ($value =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
291         my $begin = $1;
292         my $var = $2;
293         my $end = $3;
294         # append beginning of value to retval
295         $retval = "$retval$begin";
296         if (defined($variable{$var})) {
297             $retval = "$retval$variable{$var}";
298         } else {
299             # put back the origin piece.
300             $retval = "$retval\$\{$var\}";
301         }
302         $value = $end;
303     }
304     $retval = "$retval$value";
305
306     # remove the space added in the beginning
307     $retval =~ s/ //;
308
309     return "$retval"
310 }
311
312 sub set_value {
313     my ($lvalue, $rvalue) = @_;
314
315     if (defined($opt{$lvalue})) {
316         die "Error: Option $lvalue defined more than once!\n";
317     }
318     if ($rvalue =~ /^\s*$/) {
319         delete $opt{$lvalue};
320     } else {
321         $rvalue = process_variables($rvalue);
322         $opt{$lvalue} = $rvalue;
323     }
324 }
325
326 sub set_variable {
327     my ($lvalue, $rvalue) = @_;
328
329     if ($rvalue =~ /^\s*$/) {
330         delete $variable{$lvalue};
331     } else {
332         $rvalue = process_variables($rvalue);
333         $variable{$lvalue} = $rvalue;
334     }
335 }
336
337 sub read_config {
338     my ($config) = @_;
339
340     open(IN, $config) || die "can't read file $config";
341
342     my $name = $config;
343     $name =~ s,.*/(.*),$1,;
344
345     my $test_num = 0;
346     my $default = 1;
347     my $repeat = 1;
348     my $num_tests_set = 0;
349     my $skip = 0;
350     my $rest;
351     my $test_case = 0;
352
353     while (<IN>) {
354
355         # ignore blank lines and comments
356         next if (/^\s*$/ || /\s*\#/);
357
358         if (/^\s*TEST_START(.*)/) {
359
360             $rest = $1;
361
362             if ($num_tests_set) {
363                 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
364             }
365
366             my $old_test_num = $test_num;
367             my $old_repeat = $repeat;
368
369             $test_num += $repeat;
370             $default = 0;
371             $repeat = 1;
372
373             if ($rest =~ /\s+SKIP(.*)/) {
374                 $rest = $1;
375                 $skip = 1;
376             } else {
377                 $test_case = 1;
378                 $skip = 0;
379             }
380
381             if ($rest =~ /\s+ITERATE\s+(\d+)(.*)$/) {
382                 $repeat = $1;
383                 $rest = $2;
384                 $repeat_tests{"$test_num"} = $repeat;
385             }
386
387             if ($rest =~ /\s+SKIP(.*)/) {
388                 $rest = $1;
389                 $skip = 1;
390             }
391
392             if ($rest !~ /^\s*$/) {
393                 die "$name: $.: Gargbage found after TEST_START\n$_";
394             }
395
396             if ($skip) {
397                 $test_num = $old_test_num;
398                 $repeat = $old_repeat;
399             }
400
401         } elsif (/^\s*DEFAULTS(.*)$/) {
402             $default = 1;
403
404             $rest = $1;
405
406             if ($rest =~ /\s+SKIP(.*)/) {
407                 $rest = $1;
408                 $skip = 1;
409             } else {
410                 $skip = 0;
411             }
412
413             if ($rest !~ /^\s*$/) {
414                 die "$name: $.: Gargbage found after DEFAULTS\n$_";
415             }
416
417         } elsif (/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) {
418
419             next if ($skip);
420
421             my $lvalue = $1;
422             my $rvalue = $2;
423
424             if (!$default &&
425                 ($lvalue eq "NUM_TESTS" ||
426                  $lvalue eq "LOG_FILE" ||
427                  $lvalue eq "CLEAR_LOG")) {
428                 die "$name: $.: $lvalue must be set in DEFAULTS section\n";
429             }
430
431             if ($lvalue eq "NUM_TESTS") {
432                 if ($test_num) {
433                     die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
434                 }
435                 if (!$default) {
436                     die "$name: $.: NUM_TESTS must be set in default section\n";
437                 }
438                 $num_tests_set = 1;
439             }
440
441             if ($default || $lvalue =~ /\[\d+\]$/) {
442                 set_value($lvalue, $rvalue);
443             } else {
444                 my $val = "$lvalue\[$test_num\]";
445                 set_value($val, $rvalue);
446
447                 if ($repeat > 1) {
448                     $repeats{$val} = $repeat;
449                 }
450             }
451         } elsif (/^\s*([A-Z_\[\]\d]+)\s*:=\s*(.*?)\s*$/) {
452             next if ($skip);
453
454             my $lvalue = $1;
455             my $rvalue = $2;
456
457             # process config variables.
458             # Config variables are only active while reading the
459             # config and can be defined anywhere. They also ignore
460             # TEST_START and DEFAULTS, but are skipped if they are in
461             # on of these sections that have SKIP defined.
462             # The save variable can be
463             # defined multiple times and the new one simply overrides
464             # the prevous one.
465             set_variable($lvalue, $rvalue);
466
467         } else {
468             die "$name: $.: Garbage found in config\n$_";
469         }
470     }
471
472     close(IN);
473
474     if ($test_num) {
475         $test_num += $repeat - 1;
476         $opt{"NUM_TESTS"} = $test_num;
477     }
478
479     # make sure we have all mandatory configs
480     get_ktest_configs;
481
482     # was a test specified?
483     if (!$test_case) {
484         print "No test case specified.\n";
485         print "What test case would you like to run?\n";
486         my $ans = <STDIN>;
487         chomp $ans;
488         $default{"TEST_TYPE"} = $ans;
489     }
490
491     # set any defaults
492
493     foreach my $default (keys %default) {
494         if (!defined($opt{$default})) {
495             $opt{$default} = $default{$default};
496         }
497     }
498 }
499
500 sub __eval_option {
501     my ($option, $i) = @_;
502
503     # Add space to evaluate the character before $
504     $option = " $option";
505     my $retval = "";
506
507     while ($option =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
508         my $start = $1;
509         my $var = $2;
510         my $end = $3;
511
512         # Append beginning of line
513         $retval = "$retval$start";
514
515         # If the iteration option OPT[$i] exists, then use that.
516         # otherwise see if the default OPT (without [$i]) exists.
517
518         my $o = "$var\[$i\]";
519
520         if (defined($opt{$o})) {
521             $o = $opt{$o};
522             $retval = "$retval$o";
523         } elsif (defined($opt{$var})) {
524             $o = $opt{$var};
525             $retval = "$retval$o";
526         } else {
527             $retval = "$retval\$\{$var\}";
528         }
529
530         $option = $end;
531     }
532
533     $retval = "$retval$option";
534
535     $retval =~ s/^ //;
536
537     return $retval;
538 }
539
540 sub eval_option {
541     my ($option, $i) = @_;
542
543     my $prev = "";
544
545     # Since an option can evaluate to another option,
546     # keep iterating until we do not evaluate any more
547     # options.
548     my $r = 0;
549     while ($prev ne $option) {
550         # Check for recursive evaluations.
551         # 100 deep should be more than enough.
552         if ($r++ > 100) {
553             die "Over 100 evaluations accurred with $option\n" .
554                 "Check for recursive variables\n";
555         }
556         $prev = $option;
557         $option = __eval_option($option, $i);
558     }
559
560     return $option;
561 }
562
563 sub _logit {
564     if (defined($opt{"LOG_FILE"})) {
565         open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}";
566         print OUT @_;
567         close(OUT);
568     }
569 }
570
571 sub logit {
572     if (defined($opt{"LOG_FILE"})) {
573         _logit @_;
574     } else {
575         print @_;
576     }
577 }
578
579 sub doprint {
580     print @_;
581     _logit @_;
582 }
583
584 sub run_command;
585
586 sub reboot {
587     # try to reboot normally
588     if (run_command $reboot) {
589         if (defined($powercycle_after_reboot)) {
590             sleep $powercycle_after_reboot;
591             run_command "$power_cycle";
592         }
593     } else {
594         # nope? power cycle it.
595         run_command "$power_cycle";
596     }
597 }
598
599 sub do_not_reboot {
600     my $i = $iteration;
601
602     return $test_type eq "build" ||
603         ($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") ||
604         ($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build");
605 }
606
607 sub dodie {
608     doprint "CRITICAL FAILURE... ", @_, "\n";
609
610     my $i = $iteration;
611
612     if ($reboot_on_error && !do_not_reboot) {
613
614         doprint "REBOOTING\n";
615         reboot;
616
617     } elsif ($poweroff_on_error && defined($power_off)) {
618         doprint "POWERING OFF\n";
619         `$power_off`;
620     }
621
622     if (defined($opt{"LOG_FILE"})) {
623         print " See $opt{LOG_FILE} for more info.\n";
624     }
625
626     die @_, "\n";
627 }
628
629 sub open_console {
630     my ($fp) = @_;
631
632     my $flags;
633
634     my $pid = open($fp, "$console|") or
635         dodie "Can't open console $console";
636
637     $flags = fcntl($fp, F_GETFL, 0) or
638         dodie "Can't get flags for the socket: $!";
639     $flags = fcntl($fp, F_SETFL, $flags | O_NONBLOCK) or
640         dodie "Can't set flags for the socket: $!";
641
642     return $pid;
643 }
644
645 sub close_console {
646     my ($fp, $pid) = @_;
647
648     doprint "kill child process $pid\n";
649     kill 2, $pid;
650
651     print "closing!\n";
652     close($fp);
653 }
654
655 sub start_monitor {
656     if ($monitor_cnt++) {
657         return;
658     }
659     $monitor_fp = \*MONFD;
660     $monitor_pid = open_console $monitor_fp;
661
662     return;
663
664     open(MONFD, "Stop perl from warning about single use of MONFD");
665 }
666
667 sub end_monitor {
668     if (--$monitor_cnt) {
669         return;
670     }
671     close_console($monitor_fp, $monitor_pid);
672 }
673
674 sub wait_for_monitor {
675     my ($time) = @_;
676     my $line;
677
678     doprint "** Wait for monitor to settle down **\n";
679
680     # read the monitor and wait for the system to calm down
681     do {
682         $line = wait_for_input($monitor_fp, $time);
683         print "$line" if (defined($line));
684     } while (defined($line));
685     print "** Monitor flushed **\n";
686 }
687
688 sub fail {
689
690         if ($die_on_failure) {
691                 dodie @_;
692         }
693
694         doprint "FAILED\n";
695
696         my $i = $iteration;
697
698         # no need to reboot for just building.
699         if (!do_not_reboot) {
700             doprint "REBOOTING\n";
701             reboot;
702             start_monitor;
703             wait_for_monitor $sleep_time;
704             end_monitor;
705         }
706
707         my $name = "";
708
709         if (defined($test_name)) {
710             $name = " ($test_name)";
711         }
712
713         doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
714         doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
715         doprint "KTEST RESULT: TEST $i$name Failed: ", @_, "\n";
716         doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
717         doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
718
719         return 1 if (!defined($store_failures));
720
721         my @t = localtime;
722         my $date = sprintf "%04d%02d%02d%02d%02d%02d",
723                 1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0];
724
725         my $type = $build_type;
726         if ($type =~ /useconfig/) {
727             $type = "useconfig";
728         }
729
730         my $dir = "$machine-$test_type-$type-fail-$date";
731         my $faildir = "$store_failures/$dir";
732
733         if (!-d $faildir) {
734             mkpath($faildir) or
735                 die "can't create $faildir";
736         }
737         if (-f "$output_config") {
738             cp "$output_config", "$faildir/config" or
739                 die "failed to copy .config";
740         }
741         if (-f $buildlog) {
742             cp $buildlog, "$faildir/buildlog" or
743                 die "failed to move $buildlog";
744         }
745         if (-f $dmesg) {
746             cp $dmesg, "$faildir/dmesg" or
747                 die "failed to move $dmesg";
748         }
749
750         doprint "*** Saved info to $faildir ***\n";
751
752         return 1;
753 }
754
755 sub run_command {
756     my ($command) = @_;
757     my $dolog = 0;
758     my $dord = 0;
759     my $pid;
760
761     $command =~ s/\$SSH_USER/$ssh_user/g;
762     $command =~ s/\$MACHINE/$machine/g;
763
764     doprint("$command ... ");
765
766     $pid = open(CMD, "$command 2>&1 |") or
767         (fail "unable to exec $command" and return 0);
768
769     if (defined($opt{"LOG_FILE"})) {
770         open(LOG, ">>$opt{LOG_FILE}") or
771             dodie "failed to write to log";
772         $dolog = 1;
773     }
774
775     if (defined($redirect)) {
776         open (RD, ">$redirect") or
777             dodie "failed to write to redirect $redirect";
778         $dord = 1;
779     }
780
781     while (<CMD>) {
782         print LOG if ($dolog);
783         print RD  if ($dord);
784     }
785
786     waitpid($pid, 0);
787     my $failed = $?;
788
789     close(CMD);
790     close(LOG) if ($dolog);
791     close(RD)  if ($dord);
792
793     if ($failed) {
794         doprint "FAILED!\n";
795     } else {
796         doprint "SUCCESS\n";
797     }
798
799     return !$failed;
800 }
801
802 sub run_ssh {
803     my ($cmd) = @_;
804     my $cp_exec = $ssh_exec;
805
806     $cp_exec =~ s/\$SSH_COMMAND/$cmd/g;
807     return run_command "$cp_exec";
808 }
809
810 sub run_scp {
811     my ($src, $dst) = @_;
812     my $cp_scp = $scp_to_target;
813
814     $cp_scp =~ s/\$SRC_FILE/$src/g;
815     $cp_scp =~ s/\$DST_FILE/$dst/g;
816
817     return run_command "$cp_scp";
818 }
819
820 sub get_grub_index {
821
822     if ($reboot_type ne "grub") {
823         return;
824     }
825     return if (defined($grub_number));
826
827     doprint "Find grub menu ... ";
828     $grub_number = -1;
829
830     my $ssh_grub = $ssh_exec;
831     $ssh_grub =~ s,\$SSH_COMMAND,cat /boot/grub/menu.lst,g;
832
833     open(IN, "$ssh_grub |")
834         or die "unable to get menu.lst";
835
836     while (<IN>) {
837         if (/^\s*title\s+$grub_menu\s*$/) {
838             $grub_number++;
839             last;
840         } elsif (/^\s*title\s/) {
841             $grub_number++;
842         }
843     }
844     close(IN);
845
846     die "Could not find '$grub_menu' in /boot/grub/menu on $machine"
847         if ($grub_number < 0);
848     doprint "$grub_number\n";
849 }
850
851 sub wait_for_input
852 {
853     my ($fp, $time) = @_;
854     my $rin;
855     my $ready;
856     my $line;
857     my $ch;
858
859     if (!defined($time)) {
860         $time = $timeout;
861     }
862
863     $rin = '';
864     vec($rin, fileno($fp), 1) = 1;
865     $ready = select($rin, undef, undef, $time);
866
867     $line = "";
868
869     # try to read one char at a time
870     while (sysread $fp, $ch, 1) {
871         $line .= $ch;
872         last if ($ch eq "\n");
873     }
874
875     if (!length($line)) {
876         return undef;
877     }
878
879     return $line;
880 }
881
882 sub reboot_to {
883     if ($reboot_type eq "grub") {
884         run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch && reboot)'";
885         return;
886     }
887
888     run_command "$reboot_script";
889 }
890
891 sub get_sha1 {
892     my ($commit) = @_;
893
894     doprint "git rev-list --max-count=1 $commit ... ";
895     my $sha1 = `git rev-list --max-count=1 $commit`;
896     my $ret = $?;
897
898     logit $sha1;
899
900     if ($ret) {
901         doprint "FAILED\n";
902         dodie "Failed to get git $commit";
903     }
904
905     print "SUCCESS\n";
906
907     chomp $sha1;
908
909     return $sha1;
910 }
911
912 sub monitor {
913     my $booted = 0;
914     my $bug = 0;
915     my $skip_call_trace = 0;
916     my $loops;
917
918     wait_for_monitor 5;
919
920     my $line;
921     my $full_line = "";
922
923     open(DMESG, "> $dmesg") or
924         die "unable to write to $dmesg";
925
926     reboot_to;
927
928     my $success_start;
929     my $failure_start;
930     my $monitor_start = time;
931     my $done = 0;
932     my $version_found = 0;
933
934     while (!$done) {
935
936         if ($bug && defined($stop_after_failure) &&
937             $stop_after_failure >= 0) {
938             my $time = $stop_after_failure - (time - $failure_start);
939             $line = wait_for_input($monitor_fp, $time);
940             if (!defined($line)) {
941                 doprint "bug timed out after $booted_timeout seconds\n";
942                 doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
943                 last;
944             }
945         } elsif ($booted) {
946             $line = wait_for_input($monitor_fp, $booted_timeout);
947             if (!defined($line)) {
948                 my $s = $booted_timeout == 1 ? "" : "s";
949                 doprint "Successful boot found: break after $booted_timeout second$s\n";
950                 last;
951             }
952         } else {
953             $line = wait_for_input($monitor_fp);
954             if (!defined($line)) {
955                 my $s = $timeout == 1 ? "" : "s";
956                 doprint "Timed out after $timeout second$s\n";
957                 last;
958             }
959         }
960
961         doprint $line;
962         print DMESG $line;
963
964         # we are not guaranteed to get a full line
965         $full_line .= $line;
966
967         if ($full_line =~ /$success_line/) {
968             $booted = 1;
969             $success_start = time;
970         }
971
972         if ($booted && defined($stop_after_success) &&
973             $stop_after_success >= 0) {
974             my $now = time;
975             if ($now - $success_start >= $stop_after_success) {
976                 doprint "Test forced to stop after $stop_after_success seconds after success\n";
977                 last;
978             }
979         }
980
981         if ($full_line =~ /\[ backtrace testing \]/) {
982             $skip_call_trace = 1;
983         }
984
985         if ($full_line =~ /call trace:/i) {
986             if (!$bug && !$skip_call_trace) {
987                 $bug = 1;
988                 $failure_start = time;
989             }
990         }
991
992         if ($bug && defined($stop_after_failure) &&
993             $stop_after_failure >= 0) {
994             my $now = time;
995             if ($now - $failure_start >= $stop_after_failure) {
996                 doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
997                 last;
998             }
999         }
1000
1001         if ($full_line =~ /\[ end of backtrace testing \]/) {
1002             $skip_call_trace = 0;
1003         }
1004
1005         if ($full_line =~ /Kernel panic -/) {
1006             $failure_start = time;
1007             $bug = 1;
1008         }
1009
1010         # Detect triple faults by testing the banner
1011         if ($full_line =~ /\bLinux version (\S+).*\n/) {
1012             if ($1 eq $version) {
1013                 $version_found = 1;
1014             } elsif ($version_found && $detect_triplefault) {
1015                 # We already booted into the kernel we are testing,
1016                 # but now we booted into another kernel?
1017                 # Consider this a triple fault.
1018                 doprint "Aleady booted in Linux kernel $version, but now\n";
1019                 doprint "we booted into Linux kernel $1.\n";
1020                 doprint "Assuming that this is a triple fault.\n";
1021                 doprint "To disable this: set DETECT_TRIPLE_FAULT to 0\n";
1022                 last;
1023             }
1024         }
1025
1026         if ($line =~ /\n/) {
1027             $full_line = "";
1028         }
1029
1030         if ($stop_test_after > 0 && !$booted && !$bug) {
1031             if (time - $monitor_start > $stop_test_after) {
1032                 doprint "STOP_TEST_AFTER ($stop_test_after seconds) timed out\n";
1033                 $done = 1;
1034             }
1035         }
1036     }
1037
1038     close(DMESG);
1039
1040     if ($bug) {
1041         return 0 if ($in_bisect);
1042         fail "failed - got a bug report" and return 0;
1043     }
1044
1045     if (!$booted) {
1046         return 0 if ($in_bisect);
1047         fail "failed - never got a boot prompt." and return 0;
1048     }
1049
1050     return 1;
1051 }
1052
1053 sub do_post_install {
1054
1055     return if (!defined($post_install));
1056
1057     my $cp_post_install = $post_install;
1058     $cp_post_install =~ s/\$KERNEL_VERSION/$version/g;
1059     run_command "$cp_post_install" or
1060         dodie "Failed to run post install";
1061 }
1062
1063 sub install {
1064
1065     run_scp "$outputdir/$build_target", "$target_image" or
1066         dodie "failed to copy image";
1067
1068     my $install_mods = 0;
1069
1070     # should we process modules?
1071     $install_mods = 0;
1072     open(IN, "$output_config") or dodie("Can't read config file");
1073     while (<IN>) {
1074         if (/CONFIG_MODULES(=y)?/) {
1075             $install_mods = 1 if (defined($1));
1076             last;
1077         }
1078     }
1079     close(IN);
1080
1081     if (!$install_mods) {
1082         do_post_install;
1083         doprint "No modules needed\n";
1084         return;
1085     }
1086
1087     run_command "$make INSTALL_MOD_PATH=$tmpdir modules_install" or
1088         dodie "Failed to install modules";
1089
1090     my $modlib = "/lib/modules/$version";
1091     my $modtar = "ktest-mods.tar.bz2";
1092
1093     run_ssh "rm -rf $modlib" or
1094         dodie "failed to remove old mods: $modlib";
1095
1096     # would be nice if scp -r did not follow symbolic links
1097     run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or
1098         dodie "making tarball";
1099
1100     run_scp "$tmpdir/$modtar", "/tmp" or
1101         dodie "failed to copy modules";
1102
1103     unlink "$tmpdir/$modtar";
1104
1105     run_ssh "'(cd / && tar xjf /tmp/$modtar)'" or
1106         dodie "failed to tar modules";
1107
1108     run_ssh "rm -f /tmp/$modtar";
1109
1110     do_post_install;
1111 }
1112
1113 sub get_version {
1114     # get the release name
1115     doprint "$make kernelrelease ... ";
1116     $version = `$make kernelrelease | tail -1`;
1117     chomp($version);
1118     doprint "$version\n";
1119 }
1120
1121 sub start_monitor_and_boot {
1122     get_grub_index;
1123     get_version;
1124     install;
1125
1126     start_monitor;
1127     return monitor;
1128 }
1129
1130 sub check_buildlog {
1131     my ($patch) = @_;
1132
1133     my @files = `git show $patch | diffstat -l`;
1134
1135     open(IN, "git show $patch |") or
1136         dodie "failed to show $patch";
1137     while (<IN>) {
1138         if (m,^--- a/(.*),) {
1139             chomp $1;
1140             $files[$#files] = $1;
1141         }
1142     }
1143     close(IN);
1144
1145     open(IN, $buildlog) or dodie "Can't open $buildlog";
1146     while (<IN>) {
1147         if (/^\s*(.*?):.*(warning|error)/) {
1148             my $err = $1;
1149             foreach my $file (@files) {
1150                 my $fullpath = "$builddir/$file";
1151                 if ($file eq $err || $fullpath eq $err) {
1152                     fail "$file built with warnings" and return 0;
1153                 }
1154             }
1155         }
1156     }
1157     close(IN);
1158
1159     return 1;
1160 }
1161
1162 sub apply_min_config {
1163     my $outconfig = "$output_config.new";
1164
1165     # Read the config file and remove anything that
1166     # is in the force_config hash (from minconfig and others)
1167     # then add the force config back.
1168
1169     doprint "Applying minimum configurations into $output_config.new\n";
1170
1171     open (OUT, ">$outconfig") or
1172         dodie "Can't create $outconfig";
1173
1174     if (-f $output_config) {
1175         open (IN, $output_config) or
1176             dodie "Failed to open $output_config";
1177         while (<IN>) {
1178             if (/^(# )?(CONFIG_[^\s=]*)/) {
1179                 next if (defined($force_config{$2}));
1180             }
1181             print OUT;
1182         }
1183         close IN;
1184     }
1185     foreach my $config (keys %force_config) {
1186         print OUT "$force_config{$config}\n";
1187     }
1188     close OUT;
1189
1190     run_command "mv $outconfig $output_config";
1191 }
1192
1193 sub make_oldconfig {
1194
1195     my @force_list = keys %force_config;
1196
1197     if ($#force_list >= 0) {
1198         apply_min_config;
1199     }
1200
1201     if (!run_command "$make oldnoconfig") {
1202         # Perhaps oldnoconfig doesn't exist in this version of the kernel
1203         # try a yes '' | oldconfig
1204         doprint "oldnoconfig failed, trying yes '' | make oldconfig\n";
1205         run_command "yes '' | $make oldconfig" or
1206             dodie "failed make config oldconfig";
1207     }
1208 }
1209
1210 # read a config file and use this to force new configs.
1211 sub load_force_config {
1212     my ($config) = @_;
1213
1214     open(IN, $config) or
1215         dodie "failed to read $config";
1216     while (<IN>) {
1217         chomp;
1218         if (/^(CONFIG[^\s=]*)(\s*=.*)/) {
1219             $force_config{$1} = $_;
1220         } elsif (/^# (CONFIG_\S*) is not set/) {
1221             $force_config{$1} = $_;
1222         }
1223     }
1224     close IN;
1225 }
1226
1227 sub build {
1228     my ($type) = @_;
1229
1230     unlink $buildlog;
1231
1232     if (defined($pre_build)) {
1233         my $ret = run_command $pre_build;
1234         if (!$ret && defined($pre_build_die) &&
1235             $pre_build_die) {
1236             dodie "failed to pre_build\n";
1237         }
1238     }
1239
1240     if ($type =~ /^useconfig:(.*)/) {
1241         run_command "cp $1 $output_config" or
1242             dodie "could not copy $1 to .config";
1243
1244         $type = "oldconfig";
1245     }
1246
1247     # old config can ask questions
1248     if ($type eq "oldconfig") {
1249         $type = "oldnoconfig";
1250
1251         # allow for empty configs
1252         run_command "touch $output_config";
1253
1254         run_command "mv $output_config $outputdir/config_temp" or
1255             dodie "moving .config";
1256
1257         if (!$noclean && !run_command "$make mrproper") {
1258             dodie "make mrproper";
1259         }
1260
1261         run_command "mv $outputdir/config_temp $output_config" or
1262             dodie "moving config_temp";
1263
1264     } elsif (!$noclean) {
1265         unlink "$output_config";
1266         run_command "$make mrproper" or
1267             dodie "make mrproper";
1268     }
1269
1270     # add something to distinguish this build
1271     open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file");
1272     print OUT "$localversion\n";
1273     close(OUT);
1274
1275     if (defined($minconfig)) {
1276         load_force_config($minconfig);
1277     }
1278
1279     if ($type ne "oldnoconfig") {
1280         run_command "$make $type" or
1281             dodie "failed make config";
1282     }
1283     # Run old config regardless, to enforce min configurations
1284     make_oldconfig;
1285
1286     $redirect = "$buildlog";
1287     my $build_ret = run_command "$make $build_options";
1288     undef $redirect;
1289
1290     if (defined($post_build)) {
1291         my $ret = run_command $post_build;
1292         if (!$ret && defined($post_build_die) &&
1293             $post_build_die) {
1294             dodie "failed to post_build\n";
1295         }
1296     }
1297
1298     if (!$build_ret) {
1299         # bisect may need this to pass
1300         return 0 if ($in_bisect);
1301         fail "failed build" and return 0;
1302     }
1303
1304     return 1;
1305 }
1306
1307 sub halt {
1308     if (!run_ssh "halt" or defined($power_off)) {
1309         if (defined($poweroff_after_halt)) {
1310             sleep $poweroff_after_halt;
1311             run_command "$power_off";
1312         }
1313     } else {
1314         # nope? the zap it!
1315         run_command "$power_off";
1316     }
1317 }
1318
1319 sub success {
1320     my ($i) = @_;
1321
1322     $successes++;
1323
1324     my $name = "";
1325
1326     if (defined($test_name)) {
1327         $name = " ($test_name)";
1328     }
1329
1330     doprint "\n\n*******************************************\n";
1331     doprint     "*******************************************\n";
1332     doprint     "KTEST RESULT: TEST $i$name SUCCESS!!!!         **\n";
1333     doprint     "*******************************************\n";
1334     doprint     "*******************************************\n";
1335
1336     if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) {
1337         doprint "Reboot and wait $sleep_time seconds\n";
1338         reboot;
1339         start_monitor;
1340         wait_for_monitor $sleep_time;
1341         end_monitor;
1342     }
1343 }
1344
1345 sub answer_bisect {
1346     for (;;) {
1347         doprint "Pass or fail? [p/f]";
1348         my $ans = <STDIN>;
1349         chomp $ans;
1350         if ($ans eq "p" || $ans eq "P") {
1351             return 1;
1352         } elsif ($ans eq "f" || $ans eq "F") {
1353             return 0;
1354         } else {
1355             print "Please answer 'P' or 'F'\n";
1356         }
1357     }
1358 }
1359
1360 sub child_run_test {
1361     my $failed = 0;
1362
1363     # child should have no power
1364     $reboot_on_error = 0;
1365     $poweroff_on_error = 0;
1366     $die_on_failure = 1;
1367
1368     run_command $run_test or $failed = 1;
1369     exit $failed;
1370 }
1371
1372 my $child_done;
1373
1374 sub child_finished {
1375     $child_done = 1;
1376 }
1377
1378 sub do_run_test {
1379     my $child_pid;
1380     my $child_exit;
1381     my $line;
1382     my $full_line;
1383     my $bug = 0;
1384
1385     wait_for_monitor 1;
1386
1387     doprint "run test $run_test\n";
1388
1389     $child_done = 0;
1390
1391     $SIG{CHLD} = qw(child_finished);
1392
1393     $child_pid = fork;
1394
1395     child_run_test if (!$child_pid);
1396
1397     $full_line = "";
1398
1399     do {
1400         $line = wait_for_input($monitor_fp, 1);
1401         if (defined($line)) {
1402
1403             # we are not guaranteed to get a full line
1404             $full_line .= $line;
1405             doprint $line;
1406
1407             if ($full_line =~ /call trace:/i) {
1408                 $bug = 1;
1409             }
1410
1411             if ($full_line =~ /Kernel panic -/) {
1412                 $bug = 1;
1413             }
1414
1415             if ($line =~ /\n/) {
1416                 $full_line = "";
1417             }
1418         }
1419     } while (!$child_done && !$bug);
1420
1421     if ($bug) {
1422         my $failure_start = time;
1423         my $now;
1424         do {
1425             $line = wait_for_input($monitor_fp, 1);
1426             if (defined($line)) {
1427                 doprint $line;
1428             }
1429             $now = time;
1430             if ($now - $failure_start >= $stop_after_failure) {
1431                 last;
1432             }
1433         } while (defined($line));
1434
1435         doprint "Detected kernel crash!\n";
1436         # kill the child with extreme prejudice
1437         kill 9, $child_pid;
1438     }
1439
1440     waitpid $child_pid, 0;
1441     $child_exit = $?;
1442
1443     if ($bug || $child_exit) {
1444         return 0 if $in_bisect;
1445         fail "test failed" and return 0;
1446     }
1447     return 1;
1448 }
1449
1450 sub run_git_bisect {
1451     my ($command) = @_;
1452
1453     doprint "$command ... ";
1454
1455     my $output = `$command 2>&1`;
1456     my $ret = $?;
1457
1458     logit $output;
1459
1460     if ($ret) {
1461         doprint "FAILED\n";
1462         dodie "Failed to git bisect";
1463     }
1464
1465     doprint "SUCCESS\n";
1466     if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) {
1467         doprint "$1 [$2]\n";
1468     } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) {
1469         $bisect_bad = $1;
1470         doprint "Found bad commit... $1\n";
1471         return 0;
1472     } else {
1473         # we already logged it, just print it now.
1474         print $output;
1475     }
1476
1477     return 1;
1478 }
1479
1480 sub bisect_reboot {
1481     doprint "Reboot and sleep $bisect_sleep_time seconds\n";
1482     reboot;
1483     start_monitor;
1484     wait_for_monitor $bisect_sleep_time;
1485     end_monitor;
1486 }
1487
1488 # returns 1 on success, 0 on failure, -1 on skip
1489 sub run_bisect_test {
1490     my ($type, $buildtype) = @_;
1491
1492     my $failed = 0;
1493     my $result;
1494     my $output;
1495     my $ret;
1496
1497     $in_bisect = 1;
1498
1499     build $buildtype or $failed = 1;
1500
1501     if ($type ne "build") {
1502         if ($failed && $bisect_skip) {
1503             $in_bisect = 0;
1504             return -1;
1505         }
1506         dodie "Failed on build" if $failed;
1507
1508         # Now boot the box
1509         start_monitor_and_boot or $failed = 1;
1510
1511         if ($type ne "boot") {
1512             if ($failed && $bisect_skip) {
1513                 end_monitor;
1514                 bisect_reboot;
1515                 $in_bisect = 0;
1516                 return -1;
1517             }
1518             dodie "Failed on boot" if $failed;
1519
1520             do_run_test or $failed = 1;
1521         }
1522         end_monitor;
1523     }
1524
1525     if ($failed) {
1526         $result = 0;
1527     } else {
1528         $result = 1;
1529     }
1530
1531     # reboot the box to a kernel we can ssh to
1532     if ($type ne "build") {
1533         bisect_reboot;
1534     }
1535     $in_bisect = 0;
1536
1537     return $result;
1538 }
1539
1540 sub run_bisect {
1541     my ($type) = @_;
1542     my $buildtype = "oldconfig";
1543
1544     # We should have a minconfig to use?
1545     if (defined($minconfig)) {
1546         $buildtype = "useconfig:$minconfig";
1547     }
1548
1549     my $ret = run_bisect_test $type, $buildtype;
1550
1551     if ($bisect_manual) {
1552         $ret = answer_bisect;
1553     }
1554
1555     # Are we looking for where it worked, not failed?
1556     if ($reverse_bisect) {
1557         $ret = !$ret;
1558     }
1559
1560     if ($ret > 0) {
1561         return "good";
1562     } elsif ($ret == 0) {
1563         return  "bad";
1564     } elsif ($bisect_skip) {
1565         doprint "HIT A BAD COMMIT ... SKIPPING\n";
1566         return "skip";
1567     }
1568 }
1569
1570 sub bisect {
1571     my ($i) = @_;
1572
1573     my $result;
1574
1575     die "BISECT_GOOD[$i] not defined\n" if (!defined($opt{"BISECT_GOOD[$i]"}));
1576     die "BISECT_BAD[$i] not defined\n"  if (!defined($opt{"BISECT_BAD[$i]"}));
1577     die "BISECT_TYPE[$i] not defined\n" if (!defined($opt{"BISECT_TYPE[$i]"}));
1578
1579     my $good = $opt{"BISECT_GOOD[$i]"};
1580     my $bad = $opt{"BISECT_BAD[$i]"};
1581     my $type = $opt{"BISECT_TYPE[$i]"};
1582     my $start = $opt{"BISECT_START[$i]"};
1583     my $replay = $opt{"BISECT_REPLAY[$i]"};
1584     my $start_files = $opt{"BISECT_FILES[$i]"};
1585
1586     if (defined($start_files)) {
1587         $start_files = " -- " . $start_files;
1588     } else {
1589         $start_files = "";
1590     }
1591
1592     # convert to true sha1's
1593     $good = get_sha1($good);
1594     $bad = get_sha1($bad);
1595
1596     if (defined($opt{"BISECT_REVERSE[$i]"}) &&
1597         $opt{"BISECT_REVERSE[$i]"} == 1) {
1598         doprint "Performing a reverse bisect (bad is good, good is bad!)\n";
1599         $reverse_bisect = 1;
1600     } else {
1601         $reverse_bisect = 0;
1602     }
1603
1604     # Can't have a test without having a test to run
1605     if ($type eq "test" && !defined($run_test)) {
1606         $type = "boot";
1607     }
1608
1609     my $check = $opt{"BISECT_CHECK[$i]"};
1610     if (defined($check) && $check ne "0") {
1611
1612         # get current HEAD
1613         my $head = get_sha1("HEAD");
1614
1615         if ($check ne "good") {
1616             doprint "TESTING BISECT BAD [$bad]\n";
1617             run_command "git checkout $bad" or
1618                 die "Failed to checkout $bad";
1619
1620             $result = run_bisect $type;
1621
1622             if ($result ne "bad") {
1623                 fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0;
1624             }
1625         }
1626
1627         if ($check ne "bad") {
1628             doprint "TESTING BISECT GOOD [$good]\n";
1629             run_command "git checkout $good" or
1630                 die "Failed to checkout $good";
1631
1632             $result = run_bisect $type;
1633
1634             if ($result ne "good") {
1635                 fail "Tested BISECT_GOOD [$good] and it failed" and return 0;
1636             }
1637         }
1638
1639         # checkout where we started
1640         run_command "git checkout $head" or
1641             die "Failed to checkout $head";
1642     }
1643
1644     run_command "git bisect start$start_files" or
1645         dodie "could not start bisect";
1646
1647     run_command "git bisect good $good" or
1648         dodie "could not set bisect good to $good";
1649
1650     run_git_bisect "git bisect bad $bad" or
1651         dodie "could not set bisect bad to $bad";
1652
1653     if (defined($replay)) {
1654         run_command "git bisect replay $replay" or
1655             dodie "failed to run replay";
1656     }
1657
1658     if (defined($start)) {
1659         run_command "git checkout $start" or
1660             dodie "failed to checkout $start";
1661     }
1662
1663     my $test;
1664     do {
1665         $result = run_bisect $type;
1666         $test = run_git_bisect "git bisect $result";
1667     } while ($test);
1668
1669     run_command "git bisect log" or
1670         dodie "could not capture git bisect log";
1671
1672     run_command "git bisect reset" or
1673         dodie "could not reset git bisect";
1674
1675     doprint "Bad commit was [$bisect_bad]\n";
1676
1677     success $i;
1678 }
1679
1680 my %config_ignore;
1681 my %config_set;
1682
1683 my %config_list;
1684 my %null_config;
1685
1686 my %dependency;
1687
1688 sub assign_configs {
1689     my ($hash, $config) = @_;
1690
1691     open (IN, $config)
1692         or dodie "Failed to read $config";
1693
1694     while (<IN>) {
1695         if (/^((CONFIG\S*)=.*)/) {
1696             ${$hash}{$2} = $1;
1697         }
1698     }
1699
1700     close(IN);
1701 }
1702
1703 sub process_config_ignore {
1704     my ($config) = @_;
1705
1706     assign_configs \%config_ignore, $config;
1707 }
1708
1709 sub read_current_config {
1710     my ($config_ref) = @_;
1711
1712     %{$config_ref} = ();
1713     undef %{$config_ref};
1714
1715     my @key = keys %{$config_ref};
1716     if ($#key >= 0) {
1717         print "did not delete!\n";
1718         exit;
1719     }
1720     open (IN, "$output_config");
1721
1722     while (<IN>) {
1723         if (/^(CONFIG\S+)=(.*)/) {
1724             ${$config_ref}{$1} = $2;
1725         }
1726     }
1727     close(IN);
1728 }
1729
1730 sub get_dependencies {
1731     my ($config) = @_;
1732
1733     my $arr = $dependency{$config};
1734     if (!defined($arr)) {
1735         return ();
1736     }
1737
1738     my @deps = @{$arr};
1739
1740     foreach my $dep (@{$arr}) {
1741         print "ADD DEP $dep\n";
1742         @deps = (@deps, get_dependencies $dep);
1743     }
1744
1745     return @deps;
1746 }
1747
1748 sub create_config {
1749     my @configs = @_;
1750
1751     open(OUT, ">$output_config") or dodie "Can not write to $output_config";
1752
1753     foreach my $config (@configs) {
1754         print OUT "$config_set{$config}\n";
1755         my @deps = get_dependencies $config;
1756         foreach my $dep (@deps) {
1757             print OUT "$config_set{$dep}\n";
1758         }
1759     }
1760
1761     foreach my $config (keys %config_ignore) {
1762         print OUT "$config_ignore{$config}\n";
1763     }
1764     close(OUT);
1765
1766 #    exit;
1767     make_oldconfig;
1768 }
1769
1770 sub compare_configs {
1771     my (%a, %b) = @_;
1772
1773     foreach my $item (keys %a) {
1774         if (!defined($b{$item})) {
1775             print "diff $item\n";
1776             return 1;
1777         }
1778         delete $b{$item};
1779     }
1780
1781     my @keys = keys %b;
1782     if ($#keys) {
1783         print "diff2 $keys[0]\n";
1784     }
1785     return -1 if ($#keys >= 0);
1786
1787     return 0;
1788 }
1789
1790 sub run_config_bisect_test {
1791     my ($type) = @_;
1792
1793     return run_bisect_test $type, "oldconfig";
1794 }
1795
1796 sub process_passed {
1797     my (%configs) = @_;
1798
1799     doprint "These configs had no failure: (Enabling them for further compiles)\n";
1800     # Passed! All these configs are part of a good compile.
1801     # Add them to the min options.
1802     foreach my $config (keys %configs) {
1803         if (defined($config_list{$config})) {
1804             doprint " removing $config\n";
1805             $config_ignore{$config} = $config_list{$config};
1806             delete $config_list{$config};
1807         }
1808     }
1809     doprint "config copied to $outputdir/config_good\n";
1810     run_command "cp -f $output_config $outputdir/config_good";
1811 }
1812
1813 sub process_failed {
1814     my ($config) = @_;
1815
1816     doprint "\n\n***************************************\n";
1817     doprint "Found bad config: $config\n";
1818     doprint "***************************************\n\n";
1819 }
1820
1821 sub run_config_bisect {
1822
1823     my @start_list = keys %config_list;
1824
1825     if ($#start_list < 0) {
1826         doprint "No more configs to test!!!\n";
1827         return -1;
1828     }
1829
1830     doprint "***** RUN TEST ***\n";
1831     my $type = $opt{"CONFIG_BISECT_TYPE[$iteration]"};
1832     my $ret;
1833     my %current_config;
1834
1835     my $count = $#start_list + 1;
1836     doprint "  $count configs to test\n";
1837
1838     my $half = int($#start_list / 2);
1839
1840     do {
1841         my @tophalf = @start_list[0 .. $half];
1842
1843         create_config @tophalf;
1844         read_current_config \%current_config;
1845
1846         $count = $#tophalf + 1;
1847         doprint "Testing $count configs\n";
1848         my $found = 0;
1849         # make sure we test something
1850         foreach my $config (@tophalf) {
1851             if (defined($current_config{$config})) {
1852                 logit " $config\n";
1853                 $found = 1;
1854             }
1855         }
1856         if (!$found) {
1857             # try the other half
1858             doprint "Top half produced no set configs, trying bottom half\n";
1859             @tophalf = @start_list[$half + 1 .. $#start_list];
1860             create_config @tophalf;
1861             read_current_config \%current_config;
1862             foreach my $config (@tophalf) {
1863                 if (defined($current_config{$config})) {
1864                     logit " $config\n";
1865                     $found = 1;
1866                 }
1867             }
1868             if (!$found) {
1869                 doprint "Failed: Can't make new config with current configs\n";
1870                 foreach my $config (@start_list) {
1871                     doprint "  CONFIG: $config\n";
1872                 }
1873                 return -1;
1874             }
1875             $count = $#tophalf + 1;
1876             doprint "Testing $count configs\n";
1877         }
1878
1879         $ret = run_config_bisect_test $type;
1880         if ($bisect_manual) {
1881             $ret = answer_bisect;
1882         }
1883         if ($ret) {
1884             process_passed %current_config;
1885             return 0;
1886         }
1887
1888         doprint "This config had a failure.\n";
1889         doprint "Removing these configs that were not set in this config:\n";
1890         doprint "config copied to $outputdir/config_bad\n";
1891         run_command "cp -f $output_config $outputdir/config_bad";
1892
1893         # A config exists in this group that was bad.
1894         foreach my $config (keys %config_list) {
1895             if (!defined($current_config{$config})) {
1896                 doprint " removing $config\n";
1897                 delete $config_list{$config};
1898             }
1899         }
1900
1901         @start_list = @tophalf;
1902
1903         if ($#start_list == 0) {
1904             process_failed $start_list[0];
1905             return 1;
1906         }
1907
1908         # remove half the configs we are looking at and see if
1909         # they are good.
1910         $half = int($#start_list / 2);
1911     } while ($#start_list > 0);
1912
1913     # we found a single config, try it again unless we are running manually
1914
1915     if ($bisect_manual) {
1916         process_failed $start_list[0];
1917         return 1;
1918     }
1919
1920     my @tophalf = @start_list[0 .. 0];
1921
1922     $ret = run_config_bisect_test $type;
1923     if ($ret) {
1924         process_passed %current_config;
1925         return 0;
1926     }
1927
1928     process_failed $start_list[0];
1929     return 1;
1930 }
1931
1932 sub config_bisect {
1933     my ($i) = @_;
1934
1935     my $start_config = $opt{"CONFIG_BISECT[$i]"};
1936
1937     my $tmpconfig = "$tmpdir/use_config";
1938
1939     if (defined($config_bisect_good)) {
1940         process_config_ignore $config_bisect_good;
1941     }
1942
1943     # Make the file with the bad config and the min config
1944     if (defined($minconfig)) {
1945         # read the min config for things to ignore
1946         run_command "cp $minconfig $tmpconfig" or
1947             dodie "failed to copy $minconfig to $tmpconfig";
1948     } else {
1949         unlink $tmpconfig;
1950     }
1951
1952     # Add other configs
1953     if (defined($addconfig)) {
1954         run_command "cat $addconfig >> $tmpconfig" or
1955             dodie "failed to append $addconfig";
1956     }
1957
1958     if (-f $tmpconfig) {
1959         load_force_config($tmpconfig);
1960         process_config_ignore $tmpconfig;
1961     }
1962
1963     # now process the start config
1964     run_command "cp $start_config $output_config" or
1965         dodie "failed to copy $start_config to $output_config";
1966
1967     # read directly what we want to check
1968     my %config_check;
1969     open (IN, $output_config)
1970         or dodie "faied to open $output_config";
1971
1972     while (<IN>) {
1973         if (/^((CONFIG\S*)=.*)/) {
1974             $config_check{$2} = $1;
1975         }
1976     }
1977     close(IN);
1978
1979     # Now run oldconfig with the minconfig (and addconfigs)
1980     make_oldconfig;
1981
1982     # check to see what we lost (or gained)
1983     open (IN, $output_config)
1984         or dodie "Failed to read $start_config";
1985
1986     my %removed_configs;
1987     my %added_configs;
1988
1989     while (<IN>) {
1990         if (/^((CONFIG\S*)=.*)/) {
1991             # save off all options
1992             $config_set{$2} = $1;
1993             if (defined($config_check{$2})) {
1994                 if (defined($config_ignore{$2})) {
1995                     $removed_configs{$2} = $1;
1996                 } else {
1997                     $config_list{$2} = $1;
1998                 }
1999             } elsif (!defined($config_ignore{$2})) {
2000                 $added_configs{$2} = $1;
2001                 $config_list{$2} = $1;
2002             }
2003         }
2004     }
2005     close(IN);
2006
2007     my @confs = keys %removed_configs;
2008     if ($#confs >= 0) {
2009         doprint "Configs overridden by default configs and removed from check:\n";
2010         foreach my $config (@confs) {
2011             doprint " $config\n";
2012         }
2013     }
2014     @confs = keys %added_configs;
2015     if ($#confs >= 0) {
2016         doprint "Configs appearing in make oldconfig and added:\n";
2017         foreach my $config (@confs) {
2018             doprint " $config\n";
2019         }
2020     }
2021
2022     my %config_test;
2023     my $once = 0;
2024
2025     # Sometimes kconfig does weird things. We must make sure
2026     # that the config we autocreate has everything we need
2027     # to test, otherwise we may miss testing configs, or
2028     # may not be able to create a new config.
2029     # Here we create a config with everything set.
2030     create_config (keys %config_list);
2031     read_current_config \%config_test;
2032     foreach my $config (keys %config_list) {
2033         if (!defined($config_test{$config})) {
2034             if (!$once) {
2035                 $once = 1;
2036                 doprint "Configs not produced by kconfig (will not be checked):\n";
2037             }
2038             doprint "  $config\n";
2039             delete $config_list{$config};
2040         }
2041     }
2042     my $ret;
2043     do {
2044         $ret = run_config_bisect;
2045     } while (!$ret);
2046
2047     return $ret if ($ret < 0);
2048
2049     success $i;
2050 }
2051
2052 sub patchcheck_reboot {
2053     doprint "Reboot and sleep $patchcheck_sleep_time seconds\n";
2054     reboot;
2055     start_monitor;
2056     wait_for_monitor $patchcheck_sleep_time;
2057     end_monitor;
2058 }
2059
2060 sub patchcheck {
2061     my ($i) = @_;
2062
2063     die "PATCHCHECK_START[$i] not defined\n"
2064         if (!defined($opt{"PATCHCHECK_START[$i]"}));
2065     die "PATCHCHECK_TYPE[$i] not defined\n"
2066         if (!defined($opt{"PATCHCHECK_TYPE[$i]"}));
2067
2068     my $start = $opt{"PATCHCHECK_START[$i]"};
2069
2070     my $end = "HEAD";
2071     if (defined($opt{"PATCHCHECK_END[$i]"})) {
2072         $end = $opt{"PATCHCHECK_END[$i]"};
2073     }
2074
2075     # Get the true sha1's since we can use things like HEAD~3
2076     $start = get_sha1($start);
2077     $end = get_sha1($end);
2078
2079     my $type = $opt{"PATCHCHECK_TYPE[$i]"};
2080
2081     # Can't have a test without having a test to run
2082     if ($type eq "test" && !defined($run_test)) {
2083         $type = "boot";
2084     }
2085
2086     open (IN, "git log --pretty=oneline $end|") or
2087         dodie "could not get git list";
2088
2089     my @list;
2090
2091     while (<IN>) {
2092         chomp;
2093         $list[$#list+1] = $_;
2094         last if (/^$start/);
2095     }
2096     close(IN);
2097
2098     if ($list[$#list] !~ /^$start/) {
2099         fail "SHA1 $start not found";
2100     }
2101
2102     # go backwards in the list
2103     @list = reverse @list;
2104
2105     my $save_clean = $noclean;
2106     my %ignored_warnings;
2107
2108     if (defined($ignore_warnings)) {
2109         foreach my $sha1 (split /\s+/, $ignore_warnings) {
2110             $ignored_warnings{$sha1} = 1;
2111         }
2112     }
2113
2114     $in_patchcheck = 1;
2115     foreach my $item (@list) {
2116         my $sha1 = $item;
2117         $sha1 =~ s/^([[:xdigit:]]+).*/$1/;
2118
2119         doprint "\nProcessing commit $item\n\n";
2120
2121         run_command "git checkout $sha1" or
2122             die "Failed to checkout $sha1";
2123
2124         # only clean on the first and last patch
2125         if ($item eq $list[0] ||
2126             $item eq $list[$#list]) {
2127             $noclean = $save_clean;
2128         } else {
2129             $noclean = 1;
2130         }
2131
2132         if (defined($minconfig)) {
2133             build "useconfig:$minconfig" or return 0;
2134         } else {
2135             # ?? no config to use?
2136             build "oldconfig" or return 0;
2137         }
2138
2139
2140         if (!defined($ignored_warnings{$sha1})) {
2141             check_buildlog $sha1 or return 0;
2142         }
2143
2144         next if ($type eq "build");
2145
2146         my $failed = 0;
2147
2148         start_monitor_and_boot or $failed = 1;
2149
2150         if (!$failed && $type ne "boot"){
2151             do_run_test or $failed = 1;
2152         }
2153         end_monitor;
2154         return 0 if ($failed);
2155
2156         patchcheck_reboot;
2157
2158     }
2159     $in_patchcheck = 0;
2160     success $i;
2161
2162     return 1;
2163 }
2164
2165 sub read_config_list {
2166     my ($config) = @_;
2167
2168     open (IN, $config)
2169         or dodie "Failed to read $config";
2170
2171     while (<IN>) {
2172         if (/^((CONFIG\S*)=.*)/) {
2173             if (!defined($config_ignore{$2})) {
2174                 $config_list{$2} = $1;
2175             }
2176         }
2177     }
2178
2179     close(IN);
2180 }
2181
2182 sub read_output_config {
2183     my ($config) = @_;
2184
2185     assign_configs \%config_ignore, $config;
2186 }
2187
2188 sub make_new_config {
2189     my @configs = @_;
2190
2191     open (OUT, ">$output_config")
2192         or dodie "Failed to write $output_config";
2193
2194     foreach my $config (@configs) {
2195         print OUT "$config\n";
2196     }
2197     close OUT;
2198 }
2199
2200 sub make_min_config {
2201     my ($i) = @_;
2202
2203     if (!defined($output_minconfig)) {
2204         fail "OUTPUT_MIN_CONFIG not defined" and return;
2205     }
2206     if (!defined($start_minconfig)) {
2207         fail "START_MIN_CONFIG or MIN_CONFIG not defined" and return;
2208     }
2209
2210     # First things first. We build an allnoconfig to find
2211     # out what the defaults are that we can't touch.
2212     # Some are selections, but we really can't handle selections.
2213
2214     my $save_minconfig = $minconfig;
2215     undef $minconfig;
2216
2217     run_command "$make allnoconfig" or return 0;
2218
2219     process_config_ignore $output_config;
2220     my %keep_configs;
2221
2222     if (defined($ignore_config)) {
2223         # make sure the file exists
2224         `touch $ignore_config`;
2225         assign_configs \%keep_configs, $ignore_config;
2226     }
2227
2228     doprint "Load initial configs from $start_minconfig\n";
2229
2230     # Look at the current min configs, and save off all the
2231     # ones that were set via the allnoconfig
2232     my %min_configs;
2233     assign_configs \%min_configs, $start_minconfig;
2234
2235     my @config_keys = keys %min_configs;
2236
2237     # Remove anything that was set by the make allnoconfig
2238     # we shouldn't need them as they get set for us anyway.
2239     foreach my $config (@config_keys) {
2240         # Remove anything in the ignore_config
2241         if (defined($keep_configs{$config})) {
2242             my $file = $ignore_config;
2243             $file =~ s,.*/(.*?)$,$1,;
2244             doprint "$config set by $file ... ignored\n";
2245             delete $min_configs{$config};
2246             next;
2247         }
2248         # But make sure the settings are the same. If a min config
2249         # sets a selection, we do not want to get rid of it if
2250         # it is not the same as what we have. Just move it into
2251         # the keep configs.
2252         if (defined($config_ignore{$config})) {
2253             if ($config_ignore{$config} ne $min_configs{$config}) {
2254                 doprint "$config is in allnoconfig as '$config_ignore{$config}'";
2255                 doprint " but it is '$min_configs{$config}' in minconfig .. keeping\n";
2256                 $keep_configs{$config} = $min_configs{$config};
2257             } else {
2258                 doprint "$config set by allnoconfig ... ignored\n";
2259             }
2260             delete $min_configs{$config};
2261         }
2262     }
2263
2264     my %nochange_config;
2265
2266     my $done = 0;
2267
2268     while (!$done) {
2269
2270         my $config;
2271         my $found;
2272
2273         # Now disable each config one by one and do a make oldconfig
2274         # till we find a config that changes our list.
2275
2276         # Put configs that did not modify the config at the end.
2277         my @test_configs = keys %min_configs;
2278         my $reset = 1;
2279         for (my $i = 0; $i < $#test_configs; $i++) {
2280             if (!defined($nochange_config{$test_configs[0]})) {
2281                 $reset = 0;
2282                 last;
2283             }
2284             # This config didn't change the .config last time.
2285             # Place it at the end
2286             my $config = shift @test_configs;
2287             push @test_configs, $config;
2288         }
2289
2290         # if every test config has failed to modify the .config file
2291         # in the past, then reset and start over.
2292         if ($reset) {
2293             undef %nochange_config;
2294         }
2295
2296         foreach my $config (@test_configs) {
2297
2298             # Remove this config from the list of configs
2299             # do a make oldnoconfig and then read the resulting
2300             # .config to make sure it is missing the config that
2301             # we had before
2302             my %configs = %min_configs;
2303             delete $configs{$config};
2304             make_new_config ((values %configs), (values %keep_configs));
2305             make_oldconfig;
2306             undef %configs;
2307             assign_configs \%configs, $output_config;
2308
2309             if (!defined($configs{$config})) {
2310                 $found = $config;
2311                 last;
2312             }
2313
2314             doprint "disabling config $config did not change .config\n";
2315
2316             # oh well, try another config
2317             $nochange_config{$config} = 1;
2318         }
2319
2320         if (!defined($found)) {
2321             doprint "No more configs found that we can disable\n";
2322             $done = 1;
2323             last;
2324         }
2325
2326         $config = $found;
2327
2328         doprint "Test with $config disabled\n";
2329
2330         # set in_bisect to keep build and monitor from dieing
2331         $in_bisect = 1;
2332
2333         my $failed = 0;
2334         build "oldconfig";
2335         start_monitor_and_boot or $failed = 1;
2336         end_monitor;
2337
2338         $in_bisect = 0;
2339
2340         if ($failed) {
2341             doprint "$config is needed to boot the box... keeping\n";
2342             # this config is needed, add it to the ignore list.
2343             $keep_configs{$config} = $min_configs{$config};
2344             delete $min_configs{$config};
2345         } else {
2346             # We booted without this config, remove it from the minconfigs.
2347             doprint "$config is not needed, disabling\n";
2348
2349             delete $min_configs{$config};
2350
2351             # Also disable anything that is not enabled in this config
2352             my %configs;
2353             assign_configs \%configs, $output_config;
2354             my @config_keys = keys %min_configs;
2355             foreach my $config (@config_keys) {
2356                 if (!defined($configs{$config})) {
2357                     doprint "$config is not set, disabling\n";
2358                     delete $min_configs{$config};
2359                 }
2360             }
2361
2362             # Save off all the current mandidory configs
2363             open (OUT, ">$output_minconfig")
2364                 or die "Can't write to $output_minconfig";
2365             foreach my $config (keys %keep_configs) {
2366                 print OUT "$keep_configs{$config}\n";
2367             }
2368             foreach my $config (keys %min_configs) {
2369                 print OUT "$min_configs{$config}\n";
2370             }
2371             close OUT;
2372         }
2373
2374         doprint "Reboot and wait $sleep_time seconds\n";
2375         reboot;
2376         start_monitor;
2377         wait_for_monitor $sleep_time;
2378         end_monitor;
2379     }
2380
2381     success $i;
2382     return 1;
2383 }
2384
2385 $#ARGV < 1 or die "ktest.pl version: $VERSION\n   usage: ktest.pl config-file\n";
2386
2387 if ($#ARGV == 0) {
2388     $ktest_config = $ARGV[0];
2389     if (! -f $ktest_config) {
2390         print "$ktest_config does not exist.\n";
2391         my $ans;
2392         for (;;) {
2393             print "Create it? [Y/n] ";
2394             $ans = <STDIN>;
2395             chomp $ans;
2396             if ($ans =~ /^\s*$/) {
2397                 $ans = "y";
2398             }
2399             last if ($ans =~ /^y$/i || $ans =~ /^n$/i);
2400             print "Please answer either 'y' or 'n'.\n";
2401         }
2402         if ($ans !~ /^y$/i) {
2403             exit 0;
2404         }
2405     }
2406 } else {
2407     $ktest_config = "ktest.conf";
2408 }
2409
2410 if (! -f $ktest_config) {
2411     open(OUT, ">$ktest_config") or die "Can not create $ktest_config";
2412     print OUT << "EOF"
2413 # Generated by ktest.pl
2414 #
2415 # Define each test with TEST_START
2416 # The config options below it will override the defaults
2417 TEST_START
2418
2419 DEFAULTS
2420 EOF
2421 ;
2422     close(OUT);
2423 }
2424 read_config $ktest_config;
2425
2426 if (defined($opt{"LOG_FILE"})) {
2427     $opt{"LOG_FILE"} = eval_option($opt{"LOG_FILE"}, -1);
2428 }
2429
2430 # Append any configs entered in manually to the config file.
2431 my @new_configs = keys %entered_configs;
2432 if ($#new_configs >= 0) {
2433     print "\nAppending entered in configs to $ktest_config\n";
2434     open(OUT, ">>$ktest_config") or die "Can not append to $ktest_config";
2435     foreach my $config (@new_configs) {
2436         print OUT "$config = $entered_configs{$config}\n";
2437         $opt{$config} = $entered_configs{$config};
2438     }
2439 }
2440
2441 if ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) {
2442     unlink $opt{"LOG_FILE"};
2443 }
2444
2445 doprint "\n\nSTARTING AUTOMATED TESTS\n\n";
2446
2447 for (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) {
2448
2449     if (!$i) {
2450         doprint "DEFAULT OPTIONS:\n";
2451     } else {
2452         doprint "\nTEST $i OPTIONS";
2453         if (defined($repeat_tests{$i})) {
2454             $repeat = $repeat_tests{$i};
2455             doprint " ITERATE $repeat";
2456         }
2457         doprint "\n";
2458     }
2459
2460     foreach my $option (sort keys %opt) {
2461
2462         if ($option =~ /\[(\d+)\]$/) {
2463             next if ($i != $1);
2464         } else {
2465             next if ($i);
2466         }
2467
2468         doprint "$option = $opt{$option}\n";
2469     }
2470 }
2471
2472 sub __set_test_option {
2473     my ($name, $i) = @_;
2474
2475     my $option = "$name\[$i\]";
2476
2477     if (defined($opt{$option})) {
2478         return $opt{$option};
2479     }
2480
2481     foreach my $test (keys %repeat_tests) {
2482         if ($i >= $test &&
2483             $i < $test + $repeat_tests{$test}) {
2484             $option = "$name\[$test\]";
2485             if (defined($opt{$option})) {
2486                 return $opt{$option};
2487             }
2488         }
2489     }
2490
2491     if (defined($opt{$name})) {
2492         return $opt{$name};
2493     }
2494
2495     return undef;
2496 }
2497
2498 sub set_test_option {
2499     my ($name, $i) = @_;
2500
2501     my $option = __set_test_option($name, $i);
2502     return $option if (!defined($option));
2503
2504     return eval_option($option, $i);
2505 }
2506
2507 # First we need to do is the builds
2508 for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
2509
2510     $iteration = $i;
2511
2512     my $makecmd = set_test_option("MAKE_CMD", $i);
2513
2514     $machine = set_test_option("MACHINE", $i);
2515     $ssh_user = set_test_option("SSH_USER", $i);
2516     $tmpdir = set_test_option("TMP_DIR", $i);
2517     $outputdir = set_test_option("OUTPUT_DIR", $i);
2518     $builddir = set_test_option("BUILD_DIR", $i);
2519     $test_type = set_test_option("TEST_TYPE", $i);
2520     $build_type = set_test_option("BUILD_TYPE", $i);
2521     $build_options = set_test_option("BUILD_OPTIONS", $i);
2522     $pre_build = set_test_option("PRE_BUILD", $i);
2523     $post_build = set_test_option("POST_BUILD", $i);
2524     $pre_build_die = set_test_option("PRE_BUILD_DIE", $i);
2525     $post_build_die = set_test_option("POST_BUILD_DIE", $i);
2526     $power_cycle = set_test_option("POWER_CYCLE", $i);
2527     $reboot = set_test_option("REBOOT", $i);
2528     $noclean = set_test_option("BUILD_NOCLEAN", $i);
2529     $minconfig = set_test_option("MIN_CONFIG", $i);
2530     $output_minconfig = set_test_option("OUTPUT_MIN_CONFIG", $i);
2531     $start_minconfig = set_test_option("START_MIN_CONFIG", $i);
2532     $ignore_config = set_test_option("IGNORE_CONFIG", $i);
2533     $run_test = set_test_option("TEST", $i);
2534     $addconfig = set_test_option("ADD_CONFIG", $i);
2535     $reboot_type = set_test_option("REBOOT_TYPE", $i);
2536     $grub_menu = set_test_option("GRUB_MENU", $i);
2537     $post_install = set_test_option("POST_INSTALL", $i);
2538     $reboot_script = set_test_option("REBOOT_SCRIPT", $i);
2539     $reboot_on_error = set_test_option("REBOOT_ON_ERROR", $i);
2540     $poweroff_on_error = set_test_option("POWEROFF_ON_ERROR", $i);
2541     $die_on_failure = set_test_option("DIE_ON_FAILURE", $i);
2542     $power_off = set_test_option("POWER_OFF", $i);
2543     $powercycle_after_reboot = set_test_option("POWERCYCLE_AFTER_REBOOT", $i);
2544     $poweroff_after_halt = set_test_option("POWEROFF_AFTER_HALT", $i);
2545     $sleep_time = set_test_option("SLEEP_TIME", $i);
2546     $bisect_sleep_time = set_test_option("BISECT_SLEEP_TIME", $i);
2547     $patchcheck_sleep_time = set_test_option("PATCHCHECK_SLEEP_TIME", $i);
2548     $ignore_warnings = set_test_option("IGNORE_WARNINGS", $i);
2549     $bisect_manual = set_test_option("BISECT_MANUAL", $i);
2550     $bisect_skip = set_test_option("BISECT_SKIP", $i);
2551     $config_bisect_good = set_test_option("CONFIG_BISECT_GOOD", $i);
2552     $store_failures = set_test_option("STORE_FAILURES", $i);
2553     $test_name = set_test_option("TEST_NAME", $i);
2554     $timeout = set_test_option("TIMEOUT", $i);
2555     $booted_timeout = set_test_option("BOOTED_TIMEOUT", $i);
2556     $console = set_test_option("CONSOLE", $i);
2557     $detect_triplefault = set_test_option("DETECT_TRIPLE_FAULT", $i);
2558     $success_line = set_test_option("SUCCESS_LINE", $i);
2559     $stop_after_success = set_test_option("STOP_AFTER_SUCCESS", $i);
2560     $stop_after_failure = set_test_option("STOP_AFTER_FAILURE", $i);
2561     $stop_test_after = set_test_option("STOP_TEST_AFTER", $i);
2562     $build_target = set_test_option("BUILD_TARGET", $i);
2563     $ssh_exec = set_test_option("SSH_EXEC", $i);
2564     $scp_to_target = set_test_option("SCP_TO_TARGET", $i);
2565     $target_image = set_test_option("TARGET_IMAGE", $i);
2566     $localversion = set_test_option("LOCALVERSION", $i);
2567
2568     if (!defined($start_minconfig)) {
2569         $start_minconfig = $minconfig;
2570     }
2571
2572     chdir $builddir || die "can't change directory to $builddir";
2573
2574     if (!-d $tmpdir) {
2575         mkpath($tmpdir) or
2576             die "can't create $tmpdir";
2577     }
2578
2579     $ENV{"SSH_USER"} = $ssh_user;
2580     $ENV{"MACHINE"} = $machine;
2581
2582     $target = "$ssh_user\@$machine";
2583
2584     $buildlog = "$tmpdir/buildlog-$machine";
2585     $dmesg = "$tmpdir/dmesg-$machine";
2586     $make = "$makecmd O=$outputdir";
2587     $output_config = "$outputdir/.config";
2588
2589     if ($reboot_type eq "grub") {
2590         dodie "GRUB_MENU not defined" if (!defined($grub_menu));
2591     } elsif (!defined($reboot_script)) {
2592         dodie "REBOOT_SCRIPT not defined"
2593     }
2594
2595     my $run_type = $build_type;
2596     if ($test_type eq "patchcheck") {
2597         $run_type = $opt{"PATCHCHECK_TYPE[$i]"};
2598     } elsif ($test_type eq "bisect") {
2599         $run_type = $opt{"BISECT_TYPE[$i]"};
2600     } elsif ($test_type eq "config_bisect") {
2601         $run_type = $opt{"CONFIG_BISECT_TYPE[$i]"};
2602     }
2603
2604     if ($test_type eq "make_min_config") {
2605         $run_type = "";
2606     }
2607
2608     # mistake in config file?
2609     if (!defined($run_type)) {
2610         $run_type = "ERROR";
2611     }
2612
2613     doprint "\n\n";
2614     doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type\n\n";
2615
2616     unlink $dmesg;
2617     unlink $buildlog;
2618
2619     if (!defined($minconfig)) {
2620         $minconfig = $addconfig;
2621
2622     } elsif (defined($addconfig)) {
2623         run_command "cat $addconfig $minconfig > $tmpdir/add_config" or
2624             dodie "Failed to create temp config";
2625         $minconfig = "$tmpdir/add_config";
2626     }
2627
2628     my $checkout = $opt{"CHECKOUT[$i]"};
2629     if (defined($checkout)) {
2630         run_command "git checkout $checkout" or
2631             die "failed to checkout $checkout";
2632     }
2633
2634     if ($test_type eq "bisect") {
2635         bisect $i;
2636         next;
2637     } elsif ($test_type eq "config_bisect") {
2638         config_bisect $i;
2639         next;
2640     } elsif ($test_type eq "patchcheck") {
2641         patchcheck $i;
2642         next;
2643     } elsif ($test_type eq "make_min_config") {
2644         make_min_config $i;
2645         next;
2646     }
2647
2648     if ($build_type ne "nobuild") {
2649         build $build_type or next;
2650     }
2651
2652     if ($test_type ne "build") {
2653         my $failed = 0;
2654         start_monitor_and_boot or $failed = 1;
2655
2656         if (!$failed && $test_type ne "boot" && defined($run_test)) {
2657             do_run_test or $failed = 1;
2658         }
2659         end_monitor;
2660         next if ($failed);
2661     }
2662
2663     success $i;
2664 }
2665
2666 if ($opt{"POWEROFF_ON_SUCCESS"}) {
2667     halt;
2668 } elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot) {
2669     reboot;
2670 }
2671
2672 doprint "\n    $successes of $opt{NUM_TESTS} tests were successful\n\n";
2673
2674 exit 0;