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