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