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