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