ktest: Added force stop after success and failure
[pandora-kernel.git] / tools / testing / ktest / ktest.pl
1 #!/usr/bin/perl -w
2 #
3 # Copywrite 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 $#ARGV >= 0 || die "ktest.pl version: $VERSION\n   usage: ktest.pl config-file\n";
17
18 $| = 1;
19
20 my %opt;
21 my %repeat_tests;
22 my %repeats;
23 my %default;
24
25 #default opts
26 $default{"NUM_TESTS"}           = 1;
27 $default{"REBOOT_TYPE"}         = "grub";
28 $default{"TEST_TYPE"}           = "test";
29 $default{"BUILD_TYPE"}          = "randconfig";
30 $default{"MAKE_CMD"}            = "make";
31 $default{"TIMEOUT"}             = 120;
32 $default{"TMP_DIR"}             = "/tmp/ktest";
33 $default{"SLEEP_TIME"}          = 60;   # sleep time between tests
34 $default{"BUILD_NOCLEAN"}       = 0;
35 $default{"REBOOT_ON_ERROR"}     = 0;
36 $default{"POWEROFF_ON_ERROR"}   = 0;
37 $default{"REBOOT_ON_SUCCESS"}   = 1;
38 $default{"POWEROFF_ON_SUCCESS"} = 0;
39 $default{"BUILD_OPTIONS"}       = "";
40 $default{"BISECT_SLEEP_TIME"}   = 60;   # sleep time between bisects
41 $default{"CLEAR_LOG"}           = 0;
42 $default{"SUCCESS_LINE"}        = "login:";
43 $default{"BOOTED_TIMEOUT"}      = 1;
44 $default{"DIE_ON_FAILURE"}      = 1;
45 $default{"SSH_EXEC"}            = "ssh \$SSH_USER\@\$MACHINE \$SSH_COMMAND";
46 $default{"SCP_TO_TARGET"}       = "scp \$SRC_FILE \$SSH_USER\@\$MACHINE:\$DST_FILE";
47 $default{"REBOOT"}              = "ssh \$SSH_USER\@\$MACHINE reboot";
48 $default{"STOP_AFTER_SUCCESS"}  = 10;
49 $default{"STOP_AFTER_FAILURE"}  = 60;
50
51 my $version;
52 my $machine;
53 my $ssh_user;
54 my $tmpdir;
55 my $builddir;
56 my $outputdir;
57 my $output_config;
58 my $test_type;
59 my $build_type;
60 my $build_options;
61 my $reboot_type;
62 my $reboot_script;
63 my $power_cycle;
64 my $reboot;
65 my $reboot_on_error;
66 my $poweroff_on_error;
67 my $die_on_failure;
68 my $powercycle_after_reboot;
69 my $poweroff_after_halt;
70 my $ssh_exec;
71 my $scp_to_target;
72 my $power_off;
73 my $grub_menu;
74 my $grub_number;
75 my $target;
76 my $make;
77 my $post_install;
78 my $noclean;
79 my $minconfig;
80 my $addconfig;
81 my $in_bisect = 0;
82 my $bisect_bad = "";
83 my $reverse_bisect;
84 my $in_patchcheck = 0;
85 my $run_test;
86 my $redirect;
87 my $buildlog;
88 my $dmesg;
89 my $monitor_fp;
90 my $monitor_pid;
91 my $monitor_cnt = 0;
92 my $sleep_time;
93 my $bisect_sleep_time;
94 my $store_failures;
95 my $timeout;
96 my $booted_timeout;
97 my $console;
98 my $success_line;
99 my $stop_after_success;
100 my $stop_after_failure;
101 my $build_target;
102 my $target_image;
103 my $localversion;
104 my $iteration = 0;
105 my $successes = 0;
106
107 sub set_value {
108     my ($lvalue, $rvalue) = @_;
109
110     if (defined($opt{$lvalue})) {
111         die "Error: Option $lvalue defined more than once!\n";
112     }
113     if ($rvalue =~ /^\s*$/) {
114         delete $opt{$lvalue};
115     } else {
116         $opt{$lvalue} = $rvalue;
117     }
118 }
119
120 sub read_config {
121     my ($config) = @_;
122
123     open(IN, $config) || die "can't read file $config";
124
125     my $name = $config;
126     $name =~ s,.*/(.*),$1,;
127
128     my $test_num = 0;
129     my $default = 1;
130     my $repeat = 1;
131     my $num_tests_set = 0;
132     my $skip = 0;
133     my $rest;
134
135     while (<IN>) {
136
137         # ignore blank lines and comments
138         next if (/^\s*$/ || /\s*\#/);
139
140         if (/^\s*TEST_START(.*)/) {
141
142             $rest = $1;
143
144             if ($num_tests_set) {
145                 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
146             }
147
148             my $old_test_num = $test_num;
149             my $old_repeat = $repeat;
150
151             $test_num += $repeat;
152             $default = 0;
153             $repeat = 1;
154
155             if ($rest =~ /\s+SKIP(.*)/) {
156                 $rest = $1;
157                 $skip = 1;
158             } else {
159                 $skip = 0;
160             }
161
162             if ($rest =~ /\s+ITERATE\s+(\d+)(.*)$/) {
163                 $repeat = $1;
164                 $rest = $2;
165                 $repeat_tests{"$test_num"} = $repeat;
166             }
167
168             if ($rest =~ /\s+SKIP(.*)/) {
169                 $rest = $1;
170                 $skip = 1;
171             }
172
173             if ($rest !~ /^\s*$/) {
174                 die "$name: $.: Gargbage found after TEST_START\n$_";
175             }
176
177             if ($skip) {
178                 $test_num = $old_test_num;
179                 $repeat = $old_repeat;
180             }
181
182         } elsif (/^\s*DEFAULTS(.*)$/) {
183             $default = 1;
184
185             $rest = $1;
186
187             if ($rest =~ /\s+SKIP(.*)/) {
188                 $rest = $1;
189                 $skip = 1;
190             } else {
191                 $skip = 0;
192             }
193
194             if ($rest !~ /^\s*$/) {
195                 die "$name: $.: Gargbage found after DEFAULTS\n$_";
196             }
197
198         } elsif (/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) {
199
200             next if ($skip);
201
202             my $lvalue = $1;
203             my $rvalue = $2;
204
205             if (!$default &&
206                 ($lvalue eq "NUM_TESTS" ||
207                  $lvalue eq "LOG_FILE" ||
208                  $lvalue eq "CLEAR_LOG")) {
209                 die "$name: $.: $lvalue must be set in DEFAULTS section\n";
210             }
211
212             if ($lvalue eq "NUM_TESTS") {
213                 if ($test_num) {
214                     die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
215                 }
216                 if (!$default) {
217                     die "$name: $.: NUM_TESTS must be set in default section\n";
218                 }
219                 $num_tests_set = 1;
220             }
221
222             if ($default || $lvalue =~ /\[\d+\]$/) {
223                 set_value($lvalue, $rvalue);
224             } else {
225                 my $val = "$lvalue\[$test_num\]";
226                 set_value($val, $rvalue);
227
228                 if ($repeat > 1) {
229                     $repeats{$val} = $repeat;
230                 }
231             }
232         } else {
233             die "$name: $.: Garbage found in config\n$_";
234         }
235     }
236
237     close(IN);
238
239     if ($test_num) {
240         $test_num += $repeat - 1;
241         $opt{"NUM_TESTS"} = $test_num;
242     }
243
244     # set any defaults
245
246     foreach my $default (keys %default) {
247         if (!defined($opt{$default})) {
248             $opt{$default} = $default{$default};
249         }
250     }
251 }
252
253 sub _logit {
254     if (defined($opt{"LOG_FILE"})) {
255         open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}";
256         print OUT @_;
257         close(OUT);
258     }
259 }
260
261 sub logit {
262     if (defined($opt{"LOG_FILE"})) {
263         _logit @_;
264     } else {
265         print @_;
266     }
267 }
268
269 sub doprint {
270     print @_;
271     _logit @_;
272 }
273
274 sub run_command;
275
276 sub reboot {
277     # try to reboot normally
278     if (run_command $reboot) {
279         if (defined($powercycle_after_reboot)) {
280             sleep $powercycle_after_reboot;
281             run_command "$power_cycle";
282         }
283     } else {
284         # nope? power cycle it.
285         run_command "$power_cycle";
286     }
287 }
288
289 sub do_not_reboot {
290     my $i = $iteration;
291
292     return $test_type eq "build" ||
293         ($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") ||
294         ($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build");
295 }
296
297 sub dodie {
298     doprint "CRITICAL FAILURE... ", @_, "\n";
299
300     my $i = $iteration;
301
302     if ($reboot_on_error && !do_not_reboot) {
303
304         doprint "REBOOTING\n";
305         reboot;
306
307     } elsif ($poweroff_on_error && defined($power_off)) {
308         doprint "POWERING OFF\n";
309         `$power_off`;
310     }
311
312     die @_, "\n";
313 }
314
315 sub open_console {
316     my ($fp) = @_;
317
318     my $flags;
319
320     my $pid = open($fp, "$console|") or
321         dodie "Can't open console $console";
322
323     $flags = fcntl($fp, F_GETFL, 0) or
324         dodie "Can't get flags for the socket: $!";
325     $flags = fcntl($fp, F_SETFL, $flags | O_NONBLOCK) or
326         dodie "Can't set flags for the socket: $!";
327
328     return $pid;
329 }
330
331 sub close_console {
332     my ($fp, $pid) = @_;
333
334     doprint "kill child process $pid\n";
335     kill 2, $pid;
336
337     print "closing!\n";
338     close($fp);
339 }
340
341 sub start_monitor {
342     if ($monitor_cnt++) {
343         return;
344     }
345     $monitor_fp = \*MONFD;
346     $monitor_pid = open_console $monitor_fp;
347
348     return;
349
350     open(MONFD, "Stop perl from warning about single use of MONFD");
351 }
352
353 sub end_monitor {
354     if (--$monitor_cnt) {
355         return;
356     }
357     close_console($monitor_fp, $monitor_pid);
358 }
359
360 sub wait_for_monitor {
361     my ($time) = @_;
362     my $line;
363
364     doprint "** Wait for monitor to settle down **\n";
365
366     # read the monitor and wait for the system to calm down
367     do {
368         $line = wait_for_input($monitor_fp, $time);
369         print "$line" if (defined($line));
370     } while (defined($line));
371     print "** Monitor flushed **\n";
372 }
373
374 sub fail {
375
376         if ($die_on_failure) {
377                 dodie @_;
378         }
379
380         doprint "FAILED\n";
381
382         my $i = $iteration;
383
384         # no need to reboot for just building.
385         if (!do_not_reboot) {
386             doprint "REBOOTING\n";
387             reboot;
388             start_monitor;
389             wait_for_monitor $sleep_time;
390             end_monitor;
391         }
392
393         doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
394         doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
395         doprint "KTEST RESULT: TEST $i Failed: ", @_, "\n";
396         doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
397         doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
398
399         return 1 if (!defined($store_failures));
400
401         my @t = localtime;
402         my $date = sprintf "%04d%02d%02d%02d%02d%02d",
403                 1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0];
404
405         my $type = $build_type;
406         if ($type =~ /useconfig/) {
407             $type = "useconfig";
408         }
409
410         my $dir = "$machine-$test_type-$type-fail-$date";
411         my $faildir = "$store_failures/$dir";
412
413         if (!-d $faildir) {
414             mkpath($faildir) or
415                 die "can't create $faildir";
416         }
417         if (-f "$output_config") {
418             cp "$output_config", "$faildir/config" or
419                 die "failed to copy .config";
420         }
421         if (-f $buildlog) {
422             cp $buildlog, "$faildir/buildlog" or
423                 die "failed to move $buildlog";
424         }
425         if (-f $dmesg) {
426             cp $dmesg, "$faildir/dmesg" or
427                 die "failed to move $dmesg";
428         }
429
430         doprint "*** Saved info to $faildir ***\n";
431
432         return 1;
433 }
434
435 sub run_command {
436     my ($command) = @_;
437     my $dolog = 0;
438     my $dord = 0;
439     my $pid;
440
441     $command =~ s/\$SSH_USER/$ssh_user/g;
442     $command =~ s/\$MACHINE/$machine/g;
443
444     doprint("$command ... ");
445
446     $pid = open(CMD, "$command 2>&1 |") or
447         (fail "unable to exec $command" and return 0);
448
449     if (defined($opt{"LOG_FILE"})) {
450         open(LOG, ">>$opt{LOG_FILE}") or
451             dodie "failed to write to log";
452         $dolog = 1;
453     }
454
455     if (defined($redirect)) {
456         open (RD, ">$redirect") or
457             dodie "failed to write to redirect $redirect";
458         $dord = 1;
459     }
460
461     while (<CMD>) {
462         print LOG if ($dolog);
463         print RD  if ($dord);
464     }
465
466     waitpid($pid, 0);
467     my $failed = $?;
468
469     close(CMD);
470     close(LOG) if ($dolog);
471     close(RD)  if ($dord);
472
473     if ($failed) {
474         doprint "FAILED!\n";
475     } else {
476         doprint "SUCCESS\n";
477     }
478
479     return !$failed;
480 }
481
482 sub run_ssh {
483     my ($cmd) = @_;
484     my $cp_exec = $ssh_exec;
485
486     $cp_exec =~ s/\$SSH_COMMAND/$cmd/g;
487     return run_command "$cp_exec";
488 }
489
490 sub run_scp {
491     my ($src, $dst) = @_;
492     my $cp_scp = $scp_to_target;
493
494     $cp_scp =~ s/\$SRC_FILE/$src/g;
495     $cp_scp =~ s/\$DST_FILE/$dst/g;
496
497     return run_command "$cp_scp";
498 }
499
500 sub get_grub_index {
501
502     if ($reboot_type ne "grub") {
503         return;
504     }
505     return if (defined($grub_number));
506
507     doprint "Find grub menu ... ";
508     $grub_number = -1;
509
510     my $ssh_grub = $ssh_exec;
511     $ssh_grub =~ s,\$SSH_COMMAND,cat /boot/grub/menu.lst,g;
512
513     open(IN, "$ssh_grub |")
514         or die "unable to get menu.lst";
515
516     while (<IN>) {
517         if (/^\s*title\s+$grub_menu\s*$/) {
518             $grub_number++;
519             last;
520         } elsif (/^\s*title\s/) {
521             $grub_number++;
522         }
523     }
524     close(IN);
525
526     die "Could not find '$grub_menu' in /boot/grub/menu on $machine"
527         if ($grub_number < 0);
528     doprint "$grub_number\n";
529 }
530
531 sub wait_for_input
532 {
533     my ($fp, $time) = @_;
534     my $rin;
535     my $ready;
536     my $line;
537     my $ch;
538
539     if (!defined($time)) {
540         $time = $timeout;
541     }
542
543     $rin = '';
544     vec($rin, fileno($fp), 1) = 1;
545     $ready = select($rin, undef, undef, $time);
546
547     $line = "";
548
549     # try to read one char at a time
550     while (sysread $fp, $ch, 1) {
551         $line .= $ch;
552         last if ($ch eq "\n");
553     }
554
555     if (!length($line)) {
556         return undef;
557     }
558
559     return $line;
560 }
561
562 sub reboot_to {
563     if ($reboot_type eq "grub") {
564         run_command "$ssh_exec '(echo \"savedefault --default=$grub_number --once\" | grub --batch; reboot)'";
565         return;
566     }
567
568     run_command "$reboot_script";
569 }
570
571 sub get_sha1 {
572     my ($commit) = @_;
573
574     doprint "git rev-list --max-count=1 $commit ... ";
575     my $sha1 = `git rev-list --max-count=1 $commit`;
576     my $ret = $?;
577
578     logit $sha1;
579
580     if ($ret) {
581         doprint "FAILED\n";
582         dodie "Failed to get git $commit";
583     }
584
585     print "SUCCESS\n";
586
587     chomp $sha1;
588
589     return $sha1;
590 }
591
592 sub monitor {
593     my $booted = 0;
594     my $bug = 0;
595     my $skip_call_trace = 0;
596     my $loops;
597
598     wait_for_monitor 5;
599
600     my $line;
601     my $full_line = "";
602
603     open(DMESG, "> $dmesg") or
604         die "unable to write to $dmesg";
605
606     reboot_to;
607
608     my $success_start;
609     my $failure_start;
610
611     for (;;) {
612
613         if ($booted) {
614             $line = wait_for_input($monitor_fp, $booted_timeout);
615         } else {
616             $line = wait_for_input($monitor_fp);
617         }
618
619         last if (!defined($line));
620
621         doprint $line;
622         print DMESG $line;
623
624         # we are not guaranteed to get a full line
625         $full_line .= $line;
626
627         if ($full_line =~ /$success_line/) {
628             $booted = 1;
629             $success_start = time;
630         }
631
632         if ($booted && defined($stop_after_success) &&
633             $stop_after_success >= 0) {
634             my $now = time;
635             if ($now - $success_start >= $stop_after_success) {
636                 doprint "Test forced to stop after $stop_after_success seconds after success\n";
637                 last;
638             }
639         }
640
641         if ($full_line =~ /\[ backtrace testing \]/) {
642             $skip_call_trace = 1;
643         }
644
645         if ($full_line =~ /call trace:/i) {
646             if (!$skip_call_trace) {
647                 $bug = 1;
648                 $failure_start = time;
649             }
650         }
651
652         if ($bug && defined($stop_after_failure) &&
653             $stop_after_failure >= 0) {
654             my $now = time;
655             if ($now - $failure_start >= $stop_after_failure) {
656                 doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
657                 last;
658             }
659         }
660
661         if ($full_line =~ /\[ end of backtrace testing \]/) {
662             $skip_call_trace = 0;
663         }
664
665         if ($full_line =~ /Kernel panic -/) {
666             $bug = 1;
667         }
668
669         if ($line =~ /\n/) {
670             $full_line = "";
671         }
672     }
673
674     close(DMESG);
675
676     if ($bug) {
677         return 0 if ($in_bisect);
678         fail "failed - got a bug report" and return 0;
679     }
680
681     if (!$booted) {
682         return 0 if ($in_bisect);
683         fail "failed - never got a boot prompt." and return 0;
684     }
685
686     return 1;
687 }
688
689 sub install {
690
691     run_scp "$outputdir/$build_target", "$target_image" or
692         dodie "failed to copy image";
693
694     my $install_mods = 0;
695
696     # should we process modules?
697     $install_mods = 0;
698     open(IN, "$output_config") or dodie("Can't read config file");
699     while (<IN>) {
700         if (/CONFIG_MODULES(=y)?/) {
701             $install_mods = 1 if (defined($1));
702             last;
703         }
704     }
705     close(IN);
706
707     if (!$install_mods) {
708         doprint "No modules needed\n";
709         return;
710     }
711
712     run_command "$make INSTALL_MOD_PATH=$tmpdir modules_install" or
713         dodie "Failed to install modules";
714
715     my $modlib = "/lib/modules/$version";
716     my $modtar = "ktest-mods.tar.bz2";
717
718     run_ssh "rm -rf $modlib" or
719         dodie "failed to remove old mods: $modlib";
720
721     # would be nice if scp -r did not follow symbolic links
722     run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or
723         dodie "making tarball";
724
725     run_scp "$tmpdir/$modtar", "/tmp" or
726         dodie "failed to copy modules";
727
728     unlink "$tmpdir/$modtar";
729
730     run_ssh "'(cd / && tar xf /tmp/$modtar)'" or
731         dodie "failed to tar modules";
732
733     run_ssh "rm -f /tmp/$modtar";
734
735     return if (!defined($post_install));
736
737     my $cp_post_install = $post_install;
738     $cp_post_install = s/\$KERNEL_VERSION/$version/g;
739     run_command "$cp_post_install" or
740         dodie "Failed to run post install";
741 }
742
743 sub check_buildlog {
744     my ($patch) = @_;
745
746     my @files = `git show $patch | diffstat -l`;
747
748     open(IN, "git show $patch |") or
749         dodie "failed to show $patch";
750     while (<IN>) {
751         if (m,^--- a/(.*),) {
752             chomp $1;
753             $files[$#files] = $1;
754         }
755     }
756     close(IN);
757
758     open(IN, $buildlog) or dodie "Can't open $buildlog";
759     while (<IN>) {
760         if (/^\s*(.*?):.*(warning|error)/) {
761             my $err = $1;
762             foreach my $file (@files) {
763                 my $fullpath = "$builddir/$file";
764                 if ($file eq $err || $fullpath eq $err) {
765                     fail "$file built with warnings" and return 0;
766                 }
767             }
768         }
769     }
770     close(IN);
771
772     return 1;
773 }
774
775 sub build {
776     my ($type) = @_;
777     my $defconfig = "";
778
779     unlink $buildlog;
780
781     if ($type =~ /^useconfig:(.*)/) {
782         run_command "cp $1 $output_config" or
783             dodie "could not copy $1 to .config";
784
785         $type = "oldconfig";
786     }
787
788     # old config can ask questions
789     if ($type eq "oldconfig") {
790         $type = "oldnoconfig";
791
792         # allow for empty configs
793         run_command "touch $output_config";
794
795         run_command "mv $output_config $outputdir/config_temp" or
796             dodie "moving .config";
797
798         if (!$noclean && !run_command "$make mrproper") {
799             dodie "make mrproper";
800         }
801
802         run_command "mv $outputdir/config_temp $output_config" or
803             dodie "moving config_temp";
804
805     } elsif (!$noclean) {
806         unlink "$output_config";
807         run_command "$make mrproper" or
808             dodie "make mrproper";
809     }
810
811     # add something to distinguish this build
812     open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file");
813     print OUT "$localversion\n";
814     close(OUT);
815
816     if (defined($minconfig)) {
817         $defconfig = "KCONFIG_ALLCONFIG=$minconfig";
818     }
819
820     run_command "$defconfig $make $type" or
821         dodie "failed make config";
822
823     $redirect = "$buildlog";
824     if (!run_command "$make $build_options") {
825         undef $redirect;
826         # bisect may need this to pass
827         return 0 if ($in_bisect);
828         fail "failed build" and return 0;
829     }
830     undef $redirect;
831
832     return 1;
833 }
834
835 sub halt {
836     if (!run_ssh "halt" or defined($power_off)) {
837         if (defined($poweroff_after_halt)) {
838             sleep $poweroff_after_halt;
839             run_command "$power_off";
840         }
841     } else {
842         # nope? the zap it!
843         run_command "$power_off";
844     }
845 }
846
847 sub success {
848     my ($i) = @_;
849
850     $successes++;
851
852     doprint "\n\n*******************************************\n";
853     doprint     "*******************************************\n";
854     doprint     "KTEST RESULT: TEST $i SUCCESS!!!!         **\n";
855     doprint     "*******************************************\n";
856     doprint     "*******************************************\n";
857
858     if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) {
859         doprint "Reboot and wait $sleep_time seconds\n";
860         reboot;
861         start_monitor;
862         wait_for_monitor $sleep_time;
863         end_monitor;
864     }
865 }
866
867 sub get_version {
868     # get the release name
869     doprint "$make kernelrelease ... ";
870     $version = `$make kernelrelease | tail -1`;
871     chomp($version);
872     doprint "$version\n";
873 }
874
875 sub child_run_test {
876     my $failed = 0;
877
878     # child should have no power
879     $reboot_on_error = 0;
880     $poweroff_on_error = 0;
881     $die_on_failure = 1;
882
883     run_command $run_test or $failed = 1;
884     exit $failed;
885 }
886
887 my $child_done;
888
889 sub child_finished {
890     $child_done = 1;
891 }
892
893 sub do_run_test {
894     my $child_pid;
895     my $child_exit;
896     my $line;
897     my $full_line;
898     my $bug = 0;
899
900     wait_for_monitor 1;
901
902     doprint "run test $run_test\n";
903
904     $child_done = 0;
905
906     $SIG{CHLD} = qw(child_finished);
907
908     $child_pid = fork;
909
910     child_run_test if (!$child_pid);
911
912     $full_line = "";
913
914     do {
915         $line = wait_for_input($monitor_fp, 1);
916         if (defined($line)) {
917
918             # we are not guaranteed to get a full line
919             $full_line .= $line;
920
921             if ($full_line =~ /call trace:/i) {
922                 $bug = 1;
923             }
924
925             if ($full_line =~ /Kernel panic -/) {
926                 $bug = 1;
927             }
928
929             if ($line =~ /\n/) {
930                 $full_line = "";
931             }
932         }
933     } while (!$child_done && !$bug);
934
935     if ($bug) {
936         doprint "Detected kernel crash!\n";
937         # kill the child with extreme prejudice
938         kill 9, $child_pid;
939     }
940
941     waitpid $child_pid, 0;
942     $child_exit = $?;
943
944     if ($bug || $child_exit) {
945         return 0 if $in_bisect;
946         fail "test failed" and return 0;
947     }
948     return 1;
949 }
950
951 sub run_git_bisect {
952     my ($command) = @_;
953
954     doprint "$command ... ";
955
956     my $output = `$command 2>&1`;
957     my $ret = $?;
958
959     logit $output;
960
961     if ($ret) {
962         doprint "FAILED\n";
963         dodie "Failed to git bisect";
964     }
965
966     doprint "SUCCESS\n";
967     if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) {
968         doprint "$1 [$2]\n";
969     } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) {
970         $bisect_bad = $1;
971         doprint "Found bad commit... $1\n";
972         return 0;
973     } else {
974         # we already logged it, just print it now.
975         print $output;
976     }
977
978     return 1;
979 }
980
981 # returns 1 on success, 0 on failure
982 sub run_bisect_test {
983     my ($type, $buildtype) = @_;
984
985     my $failed = 0;
986     my $result;
987     my $output;
988     my $ret;
989
990     $in_bisect = 1;
991
992     build $buildtype or $failed = 1;
993
994     if ($type ne "build") {
995         dodie "Failed on build" if $failed;
996
997         # Now boot the box
998         get_grub_index;
999         get_version;
1000         install;
1001
1002         start_monitor;
1003         monitor or $failed = 1;
1004
1005         if ($type ne "boot") {
1006             dodie "Failed on boot" if $failed;
1007
1008             do_run_test or $failed = 1;
1009         }
1010         end_monitor;
1011     }
1012
1013     if ($failed) {
1014         $result = 0;
1015
1016         # reboot the box to a good kernel
1017         if ($type ne "build") {
1018             doprint "Reboot and sleep $bisect_sleep_time seconds\n";
1019             reboot;
1020             start_monitor;
1021             wait_for_monitor $bisect_sleep_time;
1022             end_monitor;
1023         }
1024     } else {
1025         $result = 1;
1026     }
1027     $in_bisect = 0;
1028
1029     return $result;
1030 }
1031
1032 sub run_bisect {
1033     my ($type) = @_;
1034     my $buildtype = "oldconfig";
1035
1036     # We should have a minconfig to use?
1037     if (defined($minconfig)) {
1038         $buildtype = "useconfig:$minconfig";
1039     }
1040
1041     my $ret = run_bisect_test $type, $buildtype;
1042
1043
1044     # Are we looking for where it worked, not failed?
1045     if ($reverse_bisect) {
1046         $ret = !$ret;
1047     }
1048
1049     if ($ret) {
1050         return "good";
1051     } else {
1052         return  "bad";
1053     }
1054 }
1055
1056 sub bisect {
1057     my ($i) = @_;
1058
1059     my $result;
1060
1061     die "BISECT_GOOD[$i] not defined\n" if (!defined($opt{"BISECT_GOOD[$i]"}));
1062     die "BISECT_BAD[$i] not defined\n"  if (!defined($opt{"BISECT_BAD[$i]"}));
1063     die "BISECT_TYPE[$i] not defined\n" if (!defined($opt{"BISECT_TYPE[$i]"}));
1064
1065     my $good = $opt{"BISECT_GOOD[$i]"};
1066     my $bad = $opt{"BISECT_BAD[$i]"};
1067     my $type = $opt{"BISECT_TYPE[$i]"};
1068     my $start = $opt{"BISECT_START[$i]"};
1069     my $replay = $opt{"BISECT_REPLAY[$i]"};
1070
1071     # convert to true sha1's
1072     $good = get_sha1($good);
1073     $bad = get_sha1($bad);
1074
1075     if (defined($opt{"BISECT_REVERSE[$i]"}) &&
1076         $opt{"BISECT_REVERSE[$i]"} == 1) {
1077         doprint "Performing a reverse bisect (bad is good, good is bad!)\n";
1078         $reverse_bisect = 1;
1079     } else {
1080         $reverse_bisect = 0;
1081     }
1082
1083     # Can't have a test without having a test to run
1084     if ($type eq "test" && !defined($run_test)) {
1085         $type = "boot";
1086     }
1087
1088     my $check = $opt{"BISECT_CHECK[$i]"};
1089     if (defined($check) && $check ne "0") {
1090
1091         # get current HEAD
1092         my $head = get_sha1("HEAD");
1093
1094         if ($check ne "good") {
1095             doprint "TESTING BISECT BAD [$bad]\n";
1096             run_command "git checkout $bad" or
1097                 die "Failed to checkout $bad";
1098
1099             $result = run_bisect $type;
1100
1101             if ($result ne "bad") {
1102                 fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0;
1103             }
1104         }
1105
1106         if ($check ne "bad") {
1107             doprint "TESTING BISECT GOOD [$good]\n";
1108             run_command "git checkout $good" or
1109                 die "Failed to checkout $good";
1110
1111             $result = run_bisect $type;
1112
1113             if ($result ne "good") {
1114                 fail "Tested BISECT_GOOD [$good] and it failed" and return 0;
1115             }
1116         }
1117
1118         # checkout where we started
1119         run_command "git checkout $head" or
1120             die "Failed to checkout $head";
1121     }
1122
1123     run_command "git bisect start" or
1124         dodie "could not start bisect";
1125
1126     run_command "git bisect good $good" or
1127         dodie "could not set bisect good to $good";
1128
1129     run_git_bisect "git bisect bad $bad" or
1130         dodie "could not set bisect bad to $bad";
1131
1132     if (defined($replay)) {
1133         run_command "git bisect replay $replay" or
1134             dodie "failed to run replay";
1135     }
1136
1137     if (defined($start)) {
1138         run_command "git checkout $start" or
1139             dodie "failed to checkout $start";
1140     }
1141
1142     my $test;
1143     do {
1144         $result = run_bisect $type;
1145         $test = run_git_bisect "git bisect $result";
1146     } while ($test);
1147
1148     run_command "git bisect log" or
1149         dodie "could not capture git bisect log";
1150
1151     run_command "git bisect reset" or
1152         dodie "could not reset git bisect";
1153
1154     doprint "Bad commit was [$bisect_bad]\n";
1155
1156     success $i;
1157 }
1158
1159 my %config_ignore;
1160 my %config_set;
1161
1162 my %config_list;
1163 my %null_config;
1164
1165 my %dependency;
1166
1167 sub process_config_ignore {
1168     my ($config) = @_;
1169
1170     open (IN, $config)
1171         or dodie "Failed to read $config";
1172
1173     while (<IN>) {
1174         if (/^(.*?(CONFIG\S*)(=.*| is not set))/) {
1175             $config_ignore{$2} = $1;
1176         }
1177     }
1178
1179     close(IN);
1180 }
1181
1182 sub read_current_config {
1183     my ($config_ref) = @_;
1184
1185     %{$config_ref} = ();
1186     undef %{$config_ref};
1187
1188     my @key = keys %{$config_ref};
1189     if ($#key >= 0) {
1190         print "did not delete!\n";
1191         exit;
1192     }
1193     open (IN, "$output_config");
1194
1195     while (<IN>) {
1196         if (/^(CONFIG\S+)=(.*)/) {
1197             ${$config_ref}{$1} = $2;
1198         }
1199     }
1200     close(IN);
1201 }
1202
1203 sub get_dependencies {
1204     my ($config) = @_;
1205
1206     my $arr = $dependency{$config};
1207     if (!defined($arr)) {
1208         return ();
1209     }
1210
1211     my @deps = @{$arr};
1212
1213     foreach my $dep (@{$arr}) {
1214         print "ADD DEP $dep\n";
1215         @deps = (@deps, get_dependencies $dep);
1216     }
1217
1218     return @deps;
1219 }
1220
1221 sub create_config {
1222     my @configs = @_;
1223
1224     open(OUT, ">$output_config") or dodie "Can not write to $output_config";
1225
1226     foreach my $config (@configs) {
1227         print OUT "$config_set{$config}\n";
1228         my @deps = get_dependencies $config;
1229         foreach my $dep (@deps) {
1230             print OUT "$config_set{$dep}\n";
1231         }
1232     }
1233
1234     foreach my $config (keys %config_ignore) {
1235         print OUT "$config_ignore{$config}\n";
1236     }
1237     close(OUT);
1238
1239 #    exit;
1240     run_command "$make oldnoconfig" or
1241         dodie "failed make config oldconfig";
1242
1243 }
1244
1245 sub compare_configs {
1246     my (%a, %b) = @_;
1247
1248     foreach my $item (keys %a) {
1249         if (!defined($b{$item})) {
1250             print "diff $item\n";
1251             return 1;
1252         }
1253         delete $b{$item};
1254     }
1255
1256     my @keys = keys %b;
1257     if ($#keys) {
1258         print "diff2 $keys[0]\n";
1259     }
1260     return -1 if ($#keys >= 0);
1261
1262     return 0;
1263 }
1264
1265 sub run_config_bisect_test {
1266     my ($type) = @_;
1267
1268     return run_bisect_test $type, "oldconfig";
1269 }
1270
1271 sub process_passed {
1272     my (%configs) = @_;
1273
1274     doprint "These configs had no failure: (Enabling them for further compiles)\n";
1275     # Passed! All these configs are part of a good compile.
1276     # Add them to the min options.
1277     foreach my $config (keys %configs) {
1278         if (defined($config_list{$config})) {
1279             doprint " removing $config\n";
1280             $config_ignore{$config} = $config_list{$config};
1281             delete $config_list{$config};
1282         }
1283     }
1284 }
1285
1286 sub process_failed {
1287     my ($config) = @_;
1288
1289     doprint "\n\n***************************************\n";
1290     doprint "Found bad config: $config\n";
1291     doprint "***************************************\n\n";
1292 }
1293
1294 sub run_config_bisect {
1295
1296     my @start_list = keys %config_list;
1297
1298     if ($#start_list < 0) {
1299         doprint "No more configs to test!!!\n";
1300         return -1;
1301     }
1302
1303     doprint "***** RUN TEST ***\n";
1304     my $type = $opt{"CONFIG_BISECT_TYPE[$iteration]"};
1305     my $ret;
1306     my %current_config;
1307
1308     my $count = $#start_list + 1;
1309     doprint "  $count configs to test\n";
1310
1311     my $half = int($#start_list / 2);
1312
1313     do {
1314         my @tophalf = @start_list[0 .. $half];
1315
1316         create_config @tophalf;
1317         read_current_config \%current_config;
1318
1319         $count = $#tophalf + 1;
1320         doprint "Testing $count configs\n";
1321         my $found = 0;
1322         # make sure we test something
1323         foreach my $config (@tophalf) {
1324             if (defined($current_config{$config})) {
1325                 logit " $config\n";
1326                 $found = 1;
1327             }
1328         }
1329         if (!$found) {
1330             # try the other half
1331             doprint "Top half produced no set configs, trying bottom half\n";
1332             @tophalf = @start_list[$half .. $#start_list];
1333             create_config @tophalf;
1334             read_current_config \%current_config;
1335             foreach my $config (@tophalf) {
1336                 if (defined($current_config{$config})) {
1337                     logit " $config\n";
1338                     $found = 1;
1339                 }
1340             }
1341             if (!$found) {
1342                 doprint "Failed: Can't make new config with current configs\n";
1343                 foreach my $config (@start_list) {
1344                     doprint "  CONFIG: $config\n";
1345                 }
1346                 return -1;
1347             }
1348             $count = $#tophalf + 1;
1349             doprint "Testing $count configs\n";
1350         }
1351
1352         $ret = run_config_bisect_test $type;
1353
1354         if ($ret) {
1355             process_passed %current_config;
1356             return 0;
1357         }
1358
1359         doprint "This config had a failure.\n";
1360         doprint "Removing these configs that were not set in this config:\n";
1361
1362         # A config exists in this group that was bad.
1363         foreach my $config (keys %config_list) {
1364             if (!defined($current_config{$config})) {
1365                 doprint " removing $config\n";
1366                 delete $config_list{$config};
1367             }
1368         }
1369
1370         @start_list = @tophalf;
1371
1372         if ($#start_list == 0) {
1373             process_failed $start_list[0];
1374             return 1;
1375         }
1376
1377         # remove half the configs we are looking at and see if
1378         # they are good.
1379         $half = int($#start_list / 2);
1380     } while ($half > 0);
1381
1382     # we found a single config, try it again
1383     my @tophalf = @start_list[0 .. 0];
1384
1385     $ret = run_config_bisect_test $type;
1386     if ($ret) {
1387         process_passed %current_config;
1388         return 0;
1389     }
1390
1391     process_failed $start_list[0];
1392     return 1;
1393 }
1394
1395 sub config_bisect {
1396     my ($i) = @_;
1397
1398     my $start_config = $opt{"CONFIG_BISECT[$i]"};
1399
1400     my $tmpconfig = "$tmpdir/use_config";
1401
1402     # Make the file with the bad config and the min config
1403     if (defined($minconfig)) {
1404         # read the min config for things to ignore
1405         run_command "cp $minconfig $tmpconfig" or
1406             dodie "failed to copy $minconfig to $tmpconfig";
1407     } else {
1408         unlink $tmpconfig;
1409     }
1410
1411     # Add other configs
1412     if (defined($addconfig)) {
1413         run_command "cat $addconfig >> $tmpconfig" or
1414             dodie "failed to append $addconfig";
1415     }
1416
1417     my $defconfig = "";
1418     if (-f $tmpconfig) {
1419         $defconfig = "KCONFIG_ALLCONFIG=$tmpconfig";
1420         process_config_ignore $tmpconfig;
1421     }
1422
1423     # now process the start config
1424     run_command "cp $start_config $output_config" or
1425         dodie "failed to copy $start_config to $output_config";
1426
1427     # read directly what we want to check
1428     my %config_check;
1429     open (IN, $output_config)
1430         or dodie "faied to open $output_config";
1431
1432     while (<IN>) {
1433         if (/^((CONFIG\S*)=.*)/) {
1434             $config_check{$2} = $1;
1435         }
1436     }
1437     close(IN);
1438
1439     # Now run oldconfig with the minconfig (and addconfigs)
1440     run_command "$defconfig $make oldnoconfig" or
1441         dodie "failed make config oldconfig";
1442
1443     # check to see what we lost (or gained)
1444     open (IN, $output_config)
1445         or dodie "Failed to read $start_config";
1446
1447     my %removed_configs;
1448     my %added_configs;
1449
1450     while (<IN>) {
1451         if (/^((CONFIG\S*)=.*)/) {
1452             # save off all options
1453             $config_set{$2} = $1;
1454             if (defined($config_check{$2})) {
1455                 if (defined($config_ignore{$2})) {
1456                     $removed_configs{$2} = $1;
1457                 } else {
1458                     $config_list{$2} = $1;
1459                 }
1460             } elsif (!defined($config_ignore{$2})) {
1461                 $added_configs{$2} = $1;
1462                 $config_list{$2} = $1;
1463             }
1464         }
1465     }
1466     close(IN);
1467
1468     my @confs = keys %removed_configs;
1469     if ($#confs >= 0) {
1470         doprint "Configs overridden by default configs and removed from check:\n";
1471         foreach my $config (@confs) {
1472             doprint " $config\n";
1473         }
1474     }
1475     @confs = keys %added_configs;
1476     if ($#confs >= 0) {
1477         doprint "Configs appearing in make oldconfig and added:\n";
1478         foreach my $config (@confs) {
1479             doprint " $config\n";
1480         }
1481     }
1482
1483     my %config_test;
1484     my $once = 0;
1485
1486     # Sometimes kconfig does weird things. We must make sure
1487     # that the config we autocreate has everything we need
1488     # to test, otherwise we may miss testing configs, or
1489     # may not be able to create a new config.
1490     # Here we create a config with everything set.
1491     create_config (keys %config_list);
1492     read_current_config \%config_test;
1493     foreach my $config (keys %config_list) {
1494         if (!defined($config_test{$config})) {
1495             if (!$once) {
1496                 $once = 1;
1497                 doprint "Configs not produced by kconfig (will not be checked):\n";
1498             }
1499             doprint "  $config\n";
1500             delete $config_list{$config};
1501         }
1502     }
1503     my $ret;
1504     do {
1505         $ret = run_config_bisect;
1506     } while (!$ret);
1507
1508     return $ret if ($ret < 0);
1509
1510     success $i;
1511 }
1512
1513 sub patchcheck {
1514     my ($i) = @_;
1515
1516     die "PATCHCHECK_START[$i] not defined\n"
1517         if (!defined($opt{"PATCHCHECK_START[$i]"}));
1518     die "PATCHCHECK_TYPE[$i] not defined\n"
1519         if (!defined($opt{"PATCHCHECK_TYPE[$i]"}));
1520
1521     my $start = $opt{"PATCHCHECK_START[$i]"};
1522
1523     my $end = "HEAD";
1524     if (defined($opt{"PATCHCHECK_END[$i]"})) {
1525         $end = $opt{"PATCHCHECK_END[$i]"};
1526     }
1527
1528     # Get the true sha1's since we can use things like HEAD~3
1529     $start = get_sha1($start);
1530     $end = get_sha1($end);
1531
1532     my $type = $opt{"PATCHCHECK_TYPE[$i]"};
1533
1534     # Can't have a test without having a test to run
1535     if ($type eq "test" && !defined($run_test)) {
1536         $type = "boot";
1537     }
1538
1539     open (IN, "git log --pretty=oneline $end|") or
1540         dodie "could not get git list";
1541
1542     my @list;
1543
1544     while (<IN>) {
1545         chomp;
1546         $list[$#list+1] = $_;
1547         last if (/^$start/);
1548     }
1549     close(IN);
1550
1551     if ($list[$#list] !~ /^$start/) {
1552         fail "SHA1 $start not found";
1553     }
1554
1555     # go backwards in the list
1556     @list = reverse @list;
1557
1558     my $save_clean = $noclean;
1559
1560     $in_patchcheck = 1;
1561     foreach my $item (@list) {
1562         my $sha1 = $item;
1563         $sha1 =~ s/^([[:xdigit:]]+).*/$1/;
1564
1565         doprint "\nProcessing commit $item\n\n";
1566
1567         run_command "git checkout $sha1" or
1568             die "Failed to checkout $sha1";
1569
1570         # only clean on the first and last patch
1571         if ($item eq $list[0] ||
1572             $item eq $list[$#list]) {
1573             $noclean = $save_clean;
1574         } else {
1575             $noclean = 1;
1576         }
1577
1578         if (defined($minconfig)) {
1579             build "useconfig:$minconfig" or return 0;
1580         } else {
1581             # ?? no config to use?
1582             build "oldconfig" or return 0;
1583         }
1584
1585         check_buildlog $sha1 or return 0;
1586
1587         next if ($type eq "build");
1588
1589         get_grub_index;
1590         get_version;
1591         install;
1592
1593         my $failed = 0;
1594
1595         start_monitor;
1596         monitor or $failed = 1;
1597
1598         if (!$failed && $type ne "boot"){
1599             do_run_test or $failed = 1;
1600         }
1601         end_monitor;
1602         return 0 if ($failed);
1603
1604     }
1605     $in_patchcheck = 0;
1606     success $i;
1607
1608     return 1;
1609 }
1610
1611 read_config $ARGV[0];
1612
1613 # mandatory configs
1614 die "MACHINE not defined\n"             if (!defined($opt{"MACHINE"}));
1615 die "SSH_USER not defined\n"            if (!defined($opt{"SSH_USER"}));
1616 die "BUILD_DIR not defined\n"           if (!defined($opt{"BUILD_DIR"}));
1617 die "OUTPUT_DIR not defined\n"          if (!defined($opt{"OUTPUT_DIR"}));
1618 die "BUILD_TARGET not defined\n"        if (!defined($opt{"BUILD_TARGET"}));
1619 die "TARGET_IMAGE not defined\n"        if (!defined($opt{"TARGET_IMAGE"}));
1620 die "POWER_CYCLE not defined\n"         if (!defined($opt{"POWER_CYCLE"}));
1621 die "CONSOLE not defined\n"             if (!defined($opt{"CONSOLE"}));
1622 die "LOCALVERSION not defined\n"        if (!defined($opt{"LOCALVERSION"}));
1623
1624 if ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) {
1625     unlink $opt{"LOG_FILE"};
1626 }
1627
1628 doprint "\n\nSTARTING AUTOMATED TESTS\n\n";
1629
1630 for (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) {
1631
1632     if (!$i) {
1633         doprint "DEFAULT OPTIONS:\n";
1634     } else {
1635         doprint "\nTEST $i OPTIONS";
1636         if (defined($repeat_tests{$i})) {
1637             $repeat = $repeat_tests{$i};
1638             doprint " ITERATE $repeat";
1639         }
1640         doprint "\n";
1641     }
1642
1643     foreach my $option (sort keys %opt) {
1644
1645         if ($option =~ /\[(\d+)\]$/) {
1646             next if ($i != $1);
1647         } else {
1648             next if ($i);
1649         }
1650
1651         doprint "$option = $opt{$option}\n";
1652     }
1653 }
1654
1655 sub set_test_option {
1656     my ($name, $i) = @_;
1657
1658     my $option = "$name\[$i\]";
1659
1660     if (defined($opt{$option})) {
1661         return $opt{$option};
1662     }
1663
1664     foreach my $test (keys %repeat_tests) {
1665         if ($i >= $test &&
1666             $i < $test + $repeat_tests{$test}) {
1667             $option = "$name\[$test\]";
1668             if (defined($opt{$option})) {
1669                 return $opt{$option};
1670             }
1671         }
1672     }
1673
1674     if (defined($opt{$name})) {
1675         return $opt{$name};
1676     }
1677
1678     return undef;
1679 }
1680
1681 # First we need to do is the builds
1682 for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
1683
1684     $iteration = $i;
1685
1686     my $makecmd = set_test_option("MAKE_CMD", $i);
1687
1688     $machine = set_test_option("MACHINE", $i);
1689     $ssh_user = set_test_option("SSH_USER", $i);
1690     $tmpdir = set_test_option("TMP_DIR", $i);
1691     $outputdir = set_test_option("OUTPUT_DIR", $i);
1692     $builddir = set_test_option("BUILD_DIR", $i);
1693     $test_type = set_test_option("TEST_TYPE", $i);
1694     $build_type = set_test_option("BUILD_TYPE", $i);
1695     $build_options = set_test_option("BUILD_OPTIONS", $i);
1696     $power_cycle = set_test_option("POWER_CYCLE", $i);
1697     $reboot = set_test_option("REBOOT", $i);
1698     $noclean = set_test_option("BUILD_NOCLEAN", $i);
1699     $minconfig = set_test_option("MIN_CONFIG", $i);
1700     $run_test = set_test_option("TEST", $i);
1701     $addconfig = set_test_option("ADD_CONFIG", $i);
1702     $reboot_type = set_test_option("REBOOT_TYPE", $i);
1703     $grub_menu = set_test_option("GRUB_MENU", $i);
1704     $post_install = set_test_option("POST_INSTALL", $i);
1705     $reboot_script = set_test_option("REBOOT_SCRIPT", $i);
1706     $reboot_on_error = set_test_option("REBOOT_ON_ERROR", $i);
1707     $poweroff_on_error = set_test_option("POWEROFF_ON_ERROR", $i);
1708     $die_on_failure = set_test_option("DIE_ON_FAILURE", $i);
1709     $power_off = set_test_option("POWER_OFF", $i);
1710     $powercycle_after_reboot = set_test_option("POWERCYCLE_AFTER_REBOOT", $i);
1711     $poweroff_after_halt = set_test_option("POWEROFF_AFTER_HALT", $i);
1712     $sleep_time = set_test_option("SLEEP_TIME", $i);
1713     $bisect_sleep_time = set_test_option("BISECT_SLEEP_TIME", $i);
1714     $store_failures = set_test_option("STORE_FAILURES", $i);
1715     $timeout = set_test_option("TIMEOUT", $i);
1716     $booted_timeout = set_test_option("BOOTED_TIMEOUT", $i);
1717     $console = set_test_option("CONSOLE", $i);
1718     $success_line = set_test_option("SUCCESS_LINE", $i);
1719     $stop_after_success = set_test_option("STOP_AFTER_SUCCESS", $i);
1720     $stop_after_failure = set_test_option("STOP_AFTER_FAILURE", $i);
1721     $build_target = set_test_option("BUILD_TARGET", $i);
1722     $ssh_exec = set_test_option("SSH_EXEC", $i);
1723     $scp_to_target = set_test_option("SCP_TO_TARGET", $i);
1724     $target_image = set_test_option("TARGET_IMAGE", $i);
1725     $localversion = set_test_option("LOCALVERSION", $i);
1726
1727     chdir $builddir || die "can't change directory to $builddir";
1728
1729     if (!-d $tmpdir) {
1730         mkpath($tmpdir) or
1731             die "can't create $tmpdir";
1732     }
1733
1734     $ENV{"SSH_USER"} = $ssh_user;
1735     $ENV{"MACHINE"} = $machine;
1736
1737     $target = "$ssh_user\@$machine";
1738
1739     $buildlog = "$tmpdir/buildlog-$machine";
1740     $dmesg = "$tmpdir/dmesg-$machine";
1741     $make = "$makecmd O=$outputdir";
1742     $output_config = "$outputdir/.config";
1743
1744     if ($reboot_type eq "grub") {
1745         dodie "GRUB_MENU not defined" if (!defined($grub_menu));
1746     } elsif (!defined($reboot_script)) {
1747         dodie "REBOOT_SCRIPT not defined"
1748     }
1749
1750     my $run_type = $build_type;
1751     if ($test_type eq "patchcheck") {
1752         $run_type = $opt{"PATCHCHECK_TYPE[$i]"};
1753     } elsif ($test_type eq "bisect") {
1754         $run_type = $opt{"BISECT_TYPE[$i]"};
1755     } elsif ($test_type eq "config_bisect") {
1756         $run_type = $opt{"CONFIG_BISECT_TYPE[$i]"};
1757     }
1758
1759     # mistake in config file?
1760     if (!defined($run_type)) {
1761         $run_type = "ERROR";
1762     }
1763
1764     doprint "\n\n";
1765     doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type\n\n";
1766
1767     unlink $dmesg;
1768     unlink $buildlog;
1769
1770     if (!defined($minconfig)) {
1771         $minconfig = $addconfig;
1772
1773     } elsif (defined($addconfig)) {
1774         run_command "cat $addconfig $minconfig > $tmpdir/add_config" or
1775             dodie "Failed to create temp config";
1776         $minconfig = "$tmpdir/add_config";
1777     }
1778
1779     my $checkout = $opt{"CHECKOUT[$i]"};
1780     if (defined($checkout)) {
1781         run_command "git checkout $checkout" or
1782             die "failed to checkout $checkout";
1783     }
1784
1785     if ($test_type eq "bisect") {
1786         bisect $i;
1787         next;
1788     } elsif ($test_type eq "config_bisect") {
1789         config_bisect $i;
1790         next;
1791     } elsif ($test_type eq "patchcheck") {
1792         patchcheck $i;
1793         next;
1794     }
1795
1796     if ($build_type ne "nobuild") {
1797         build $build_type or next;
1798     }
1799
1800     if ($test_type ne "build") {
1801         get_grub_index;
1802         get_version;
1803         install;
1804
1805         my $failed = 0;
1806         start_monitor;
1807         monitor or $failed = 1;;
1808
1809         if (!$failed && $test_type ne "boot" && defined($run_test)) {
1810             do_run_test or $failed = 1;
1811         }
1812         end_monitor;
1813         next if ($failed);
1814     }
1815
1816     success $i;
1817 }
1818
1819 if ($opt{"POWEROFF_ON_SUCCESS"}) {
1820     halt;
1821 } elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot) {
1822     reboot;
1823 }
1824
1825 doprint "\n    $successes of $opt{NUM_TESTS} tests were successful\n\n";
1826
1827 exit 0;