blob: ca6ff99ab1a5b786f3689bb3cec4d7f380e6c0d0 [file] [log] [blame]
Steven Rostedt2545eb62010-11-02 15:01:32 -04001#!/usr/bin/perl -w
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04002#
Uwe Kleine-Königcce1dac2011-01-24 21:12:01 +01003# Copyright 2010 - Steven Rostedt <srostedt@redhat.com>, Red Hat Inc.
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04004# Licensed under the terms of the GNU GPL License version 2
5#
Steven Rostedt2545eb62010-11-02 15:01:32 -04006
7use strict;
8use IPC::Open2;
9use Fcntl qw(F_GETFL F_SETFL O_NONBLOCK);
Steven Rostedt7faafbd2010-11-02 14:58:22 -040010use File::Path qw(mkpath);
11use File::Copy qw(cp);
Steven Rostedt2545eb62010-11-02 15:01:32 -040012use FileHandle;
13
Steven Rostedte48c5292010-11-02 14:35:37 -040014my $VERSION = "0.2";
15
Steven Rostedt2545eb62010-11-02 15:01:32 -040016$| = 1;
17
18my %opt;
Steven Rostedta57419b2010-11-02 15:13:54 -040019my %repeat_tests;
20my %repeats;
Steven Rostedta75fece2010-11-02 14:58:27 -040021my %default;
Steven Rostedt2545eb62010-11-02 15:01:32 -040022
23#default opts
Steven Rostedta57419b2010-11-02 15:13:54 -040024$default{"NUM_TESTS"} = 1;
Steven Rostedta75fece2010-11-02 14:58:27 -040025$default{"REBOOT_TYPE"} = "grub";
26$default{"TEST_TYPE"} = "test";
27$default{"BUILD_TYPE"} = "randconfig";
28$default{"MAKE_CMD"} = "make";
29$default{"TIMEOUT"} = 120;
Steven Rostedt48920632011-06-14 20:42:19 -040030$default{"TMP_DIR"} = "/tmp/ktest/\${MACHINE}";
Steven Rostedta75fece2010-11-02 14:58:27 -040031$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
Steven Rostedt27d934b2011-05-20 09:18:18 -040039$default{"PATCHCHECK_SLEEP_TIME"} = 60; # sleep time between patch checks
Steven Rostedta75fece2010-11-02 14:58:27 -040040$default{"CLEAR_LOG"} = 0;
Steven Rostedtc960bb92011-03-08 09:22:39 -050041$default{"BISECT_MANUAL"} = 0;
Steven Rostedtc23dca72011-03-08 09:26:31 -050042$default{"BISECT_SKIP"} = 1;
Steven Rostedta75fece2010-11-02 14:58:27 -040043$default{"SUCCESS_LINE"} = "login:";
Steven Rostedtf1a5b962011-06-13 10:30:00 -040044$default{"DETECT_TRIPLE_FAULT"} = 1;
Steven Rostedta75fece2010-11-02 14:58:27 -040045$default{"BOOTED_TIMEOUT"} = 1;
46$default{"DIE_ON_FAILURE"} = 1;
Steven Rostedte48c5292010-11-02 14:35:37 -040047$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";
Steven Rostedt1c8a6172010-11-09 12:55:40 -050050$default{"STOP_AFTER_SUCCESS"} = 10;
51$default{"STOP_AFTER_FAILURE"} = 60;
Steven Rostedt2d01b262011-03-08 09:47:54 -050052$default{"STOP_TEST_AFTER"} = 600;
Steven Rostedt8d1491b2010-11-18 15:39:48 -050053$default{"LOCALVERSION"} = "-test";
Steven Rostedt2545eb62010-11-02 15:01:32 -040054
Steven Rostedt8d1491b2010-11-18 15:39:48 -050055my $ktest_config;
Steven Rostedt2545eb62010-11-02 15:01:32 -040056my $version;
Steven Rostedta75fece2010-11-02 14:58:27 -040057my $machine;
Steven Rostedte48c5292010-11-02 14:35:37 -040058my $ssh_user;
Steven Rostedta75fece2010-11-02 14:58:27 -040059my $tmpdir;
60my $builddir;
61my $outputdir;
Steven Rostedt51ad1dd2010-11-08 16:43:21 -050062my $output_config;
Steven Rostedta75fece2010-11-02 14:58:27 -040063my $test_type;
Steven Rostedt7faafbd2010-11-02 14:58:22 -040064my $build_type;
Steven Rostedta75fece2010-11-02 14:58:27 -040065my $build_options;
Steven Rostedt0bd6c1a2011-06-14 20:39:31 -040066my $pre_build;
67my $post_build;
68my $pre_build_die;
69my $post_build_die;
Steven Rostedta75fece2010-11-02 14:58:27 -040070my $reboot_type;
71my $reboot_script;
72my $power_cycle;
Steven Rostedte48c5292010-11-02 14:35:37 -040073my $reboot;
Steven Rostedta75fece2010-11-02 14:58:27 -040074my $reboot_on_error;
75my $poweroff_on_error;
76my $die_on_failure;
Steven Rostedt576f6272010-11-02 14:58:38 -040077my $powercycle_after_reboot;
78my $poweroff_after_halt;
Steven Rostedte48c5292010-11-02 14:35:37 -040079my $ssh_exec;
80my $scp_to_target;
Steven Rostedta75fece2010-11-02 14:58:27 -040081my $power_off;
82my $grub_menu;
Steven Rostedt2545eb62010-11-02 15:01:32 -040083my $grub_number;
84my $target;
85my $make;
Steven Rostedt8b37ca82010-11-02 14:58:33 -040086my $post_install;
Steven Rostedt5c42fc52010-11-02 14:57:01 -040087my $noclean;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -040088my $minconfig;
Steven Rostedt4c4ab122011-07-15 21:16:17 -040089my $start_minconfig;
Steven Rostedt35ce5952011-07-15 21:57:25 -040090my $start_minconfig_defined;
Steven Rostedt4c4ab122011-07-15 21:16:17 -040091my $output_minconfig;
92my $ignore_config;
Steven Rostedt2b7d9b22010-11-02 14:58:15 -040093my $addconfig;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -040094my $in_bisect = 0;
95my $bisect_bad = "";
Steven Rostedtd6ce2a02010-11-02 14:58:05 -040096my $reverse_bisect;
Steven Rostedtc960bb92011-03-08 09:22:39 -050097my $bisect_manual;
Steven Rostedtc23dca72011-03-08 09:26:31 -050098my $bisect_skip;
Steven Rostedt30f75da2011-06-13 10:35:35 -040099my $config_bisect_good;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400100my $in_patchcheck = 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400101my $run_test;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400102my $redirect;
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400103my $buildlog;
104my $dmesg;
105my $monitor_fp;
106my $monitor_pid;
107my $monitor_cnt = 0;
Steven Rostedta75fece2010-11-02 14:58:27 -0400108my $sleep_time;
109my $bisect_sleep_time;
Steven Rostedt27d934b2011-05-20 09:18:18 -0400110my $patchcheck_sleep_time;
Steven Rostedt19902072011-06-14 20:46:25 -0400111my $ignore_warnings;
Steven Rostedta75fece2010-11-02 14:58:27 -0400112my $store_failures;
Steven Rostedt9064af52011-06-13 10:38:48 -0400113my $test_name;
Steven Rostedta75fece2010-11-02 14:58:27 -0400114my $timeout;
115my $booted_timeout;
Steven Rostedtf1a5b962011-06-13 10:30:00 -0400116my $detect_triplefault;
Steven Rostedta75fece2010-11-02 14:58:27 -0400117my $console;
118my $success_line;
Steven Rostedt1c8a6172010-11-09 12:55:40 -0500119my $stop_after_success;
120my $stop_after_failure;
Steven Rostedt2d01b262011-03-08 09:47:54 -0500121my $stop_test_after;
Steven Rostedta75fece2010-11-02 14:58:27 -0400122my $build_target;
123my $target_image;
124my $localversion;
Steven Rostedt576f6272010-11-02 14:58:38 -0400125my $iteration = 0;
Steven Rostedte48c5292010-11-02 14:35:37 -0400126my $successes = 0;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400127
Steven Rostedt8d1491b2010-11-18 15:39:48 -0500128my %entered_configs;
129my %config_help;
Steven Rostedt77d942c2011-05-20 13:36:58 -0400130my %variable;
Steven Rostedtfcb3f162011-06-13 10:40:58 -0400131my %force_config;
Steven Rostedt8d1491b2010-11-18 15:39:48 -0500132
133$config_help{"MACHINE"} = << "EOF"
134 The machine hostname that you will test.
135EOF
136 ;
137$config_help{"SSH_USER"} = << "EOF"
138 The box is expected to have ssh on normal bootup, provide the user
139 (most likely root, since you need privileged operations)
140EOF
141 ;
142$config_help{"BUILD_DIR"} = << "EOF"
143 The directory that contains the Linux source code (full path).
144EOF
145 ;
146$config_help{"OUTPUT_DIR"} = << "EOF"
147 The directory that the objects will be built (full path).
148 (can not be same as BUILD_DIR)
149EOF
150 ;
151$config_help{"BUILD_TARGET"} = << "EOF"
152 The location of the compiled file to copy to the target.
153 (relative to OUTPUT_DIR)
154EOF
155 ;
156$config_help{"TARGET_IMAGE"} = << "EOF"
157 The place to put your image on the test machine.
158EOF
159 ;
160$config_help{"POWER_CYCLE"} = << "EOF"
161 A script or command to reboot the box.
162
163 Here is a digital loggers power switch example
164 POWER_CYCLE = wget --no-proxy -O /dev/null -q --auth-no-challenge 'http://admin:admin\@power/outlet?5=CCL'
165
166 Here is an example to reboot a virtual box on the current host
167 with the name "Guest".
168 POWER_CYCLE = virsh destroy Guest; sleep 5; virsh start Guest
169EOF
170 ;
171$config_help{"CONSOLE"} = << "EOF"
172 The script or command that reads the console
173
174 If you use ttywatch server, something like the following would work.
175CONSOLE = nc -d localhost 3001
176
177 For a virtual machine with guest name "Guest".
178CONSOLE = virsh console Guest
179EOF
180 ;
181$config_help{"LOCALVERSION"} = << "EOF"
182 Required version ending to differentiate the test
183 from other linux builds on the system.
184EOF
185 ;
186$config_help{"REBOOT_TYPE"} = << "EOF"
187 Way to reboot the box to the test kernel.
188 Only valid options so far are "grub" and "script".
189
190 If you specify grub, it will assume grub version 1
191 and will search in /boot/grub/menu.lst for the title \$GRUB_MENU
192 and select that target to reboot to the kernel. If this is not
193 your setup, then specify "script" and have a command or script
194 specified in REBOOT_SCRIPT to boot to the target.
195
196 The entry in /boot/grub/menu.lst must be entered in manually.
197 The test will not modify that file.
198EOF
199 ;
200$config_help{"GRUB_MENU"} = << "EOF"
201 The grub title name for the test kernel to boot
202 (Only mandatory if REBOOT_TYPE = grub)
203
204 Note, ktest.pl will not update the grub menu.lst, you need to
205 manually add an option for the test. ktest.pl will search
206 the grub menu.lst for this option to find what kernel to
207 reboot into.
208
209 For example, if in the /boot/grub/menu.lst the test kernel title has:
210 title Test Kernel
211 kernel vmlinuz-test
212 GRUB_MENU = Test Kernel
213EOF
214 ;
215$config_help{"REBOOT_SCRIPT"} = << "EOF"
216 A script to reboot the target into the test kernel
217 (Only mandatory if REBOOT_TYPE = script)
218EOF
219 ;
220
Steven Rostedt35ce5952011-07-15 21:57:25 -0400221sub read_yn {
222 my ($prompt) = @_;
223
224 my $ans;
225
226 for (;;) {
227 print "$prompt [Y/n] ";
228 $ans = <STDIN>;
229 chomp $ans;
230 if ($ans =~ /^\s*$/) {
231 $ans = "y";
232 }
233 last if ($ans =~ /^y$/i || $ans =~ /^n$/i);
234 print "Please answer either 'y' or 'n'.\n";
235 }
236 if ($ans !~ /^y$/i) {
237 return 0;
238 }
239 return 1;
240}
Steven Rostedt8d1491b2010-11-18 15:39:48 -0500241
242sub get_ktest_config {
243 my ($config) = @_;
244
245 return if (defined($opt{$config}));
246
247 if (defined($config_help{$config})) {
248 print "\n";
249 print $config_help{$config};
250 }
251
252 for (;;) {
253 print "$config = ";
254 if (defined($default{$config})) {
255 print "\[$default{$config}\] ";
256 }
257 $entered_configs{$config} = <STDIN>;
258 $entered_configs{$config} =~ s/^\s*(.*\S)\s*$/$1/;
259 if ($entered_configs{$config} =~ /^\s*$/) {
260 if ($default{$config}) {
261 $entered_configs{$config} = $default{$config};
262 } else {
263 print "Your answer can not be blank\n";
264 next;
265 }
266 }
267 last;
268 }
269}
270
271sub get_ktest_configs {
272 get_ktest_config("MACHINE");
273 get_ktest_config("SSH_USER");
274 get_ktest_config("BUILD_DIR");
275 get_ktest_config("OUTPUT_DIR");
276 get_ktest_config("BUILD_TARGET");
277 get_ktest_config("TARGET_IMAGE");
278 get_ktest_config("POWER_CYCLE");
279 get_ktest_config("CONSOLE");
280 get_ktest_config("LOCALVERSION");
281
282 my $rtype = $opt{"REBOOT_TYPE"};
283
284 if (!defined($rtype)) {
285 if (!defined($opt{"GRUB_MENU"})) {
286 get_ktest_config("REBOOT_TYPE");
287 $rtype = $entered_configs{"REBOOT_TYPE"};
288 } else {
289 $rtype = "grub";
290 }
291 }
292
293 if ($rtype eq "grub") {
294 get_ktest_config("GRUB_MENU");
295 } else {
296 get_ktest_config("REBOOT_SCRIPT");
297 }
298}
299
Steven Rostedt77d942c2011-05-20 13:36:58 -0400300sub process_variables {
301 my ($value) = @_;
302 my $retval = "";
303
304 # We want to check for '\', and it is just easier
305 # to check the previous characet of '$' and not need
306 # to worry if '$' is the first character. By adding
307 # a space to $value, we can just check [^\\]\$ and
308 # it will still work.
309 $value = " $value";
310
311 while ($value =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
312 my $begin = $1;
313 my $var = $2;
314 my $end = $3;
315 # append beginning of value to retval
316 $retval = "$retval$begin";
317 if (defined($variable{$var})) {
318 $retval = "$retval$variable{$var}";
319 } else {
320 # put back the origin piece.
321 $retval = "$retval\$\{$var\}";
322 }
323 $value = $end;
324 }
325 $retval = "$retval$value";
326
327 # remove the space added in the beginning
328 $retval =~ s/ //;
329
330 return "$retval"
331}
332
Steven Rostedta57419b2010-11-02 15:13:54 -0400333sub set_value {
334 my ($lvalue, $rvalue) = @_;
335
336 if (defined($opt{$lvalue})) {
337 die "Error: Option $lvalue defined more than once!\n";
338 }
Steven Rostedt21a96792010-11-08 16:45:50 -0500339 if ($rvalue =~ /^\s*$/) {
340 delete $opt{$lvalue};
341 } else {
Steven Rostedt77d942c2011-05-20 13:36:58 -0400342 $rvalue = process_variables($rvalue);
Steven Rostedt21a96792010-11-08 16:45:50 -0500343 $opt{$lvalue} = $rvalue;
344 }
Steven Rostedta57419b2010-11-02 15:13:54 -0400345}
346
Steven Rostedt77d942c2011-05-20 13:36:58 -0400347sub set_variable {
348 my ($lvalue, $rvalue) = @_;
349
350 if ($rvalue =~ /^\s*$/) {
351 delete $variable{$lvalue};
352 } else {
353 $rvalue = process_variables($rvalue);
354 $variable{$lvalue} = $rvalue;
355 }
356}
357
Steven Rostedt2545eb62010-11-02 15:01:32 -0400358sub read_config {
359 my ($config) = @_;
360
361 open(IN, $config) || die "can't read file $config";
362
Steven Rostedta57419b2010-11-02 15:13:54 -0400363 my $name = $config;
364 $name =~ s,.*/(.*),$1,;
365
366 my $test_num = 0;
367 my $default = 1;
368 my $repeat = 1;
369 my $num_tests_set = 0;
370 my $skip = 0;
371 my $rest;
Steven Rostedt0df213c2011-06-14 20:51:37 -0400372 my $test_case = 0;
Steven Rostedta57419b2010-11-02 15:13:54 -0400373
Steven Rostedt2545eb62010-11-02 15:01:32 -0400374 while (<IN>) {
375
376 # ignore blank lines and comments
377 next if (/^\s*$/ || /\s*\#/);
378
Steven Rostedta57419b2010-11-02 15:13:54 -0400379 if (/^\s*TEST_START(.*)/) {
380
381 $rest = $1;
382
383 if ($num_tests_set) {
384 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
385 }
386
387 my $old_test_num = $test_num;
Steven Rostedte48c5292010-11-02 14:35:37 -0400388 my $old_repeat = $repeat;
Steven Rostedta57419b2010-11-02 15:13:54 -0400389
390 $test_num += $repeat;
391 $default = 0;
392 $repeat = 1;
393
394 if ($rest =~ /\s+SKIP(.*)/) {
395 $rest = $1;
396 $skip = 1;
397 } else {
Steven Rostedt0df213c2011-06-14 20:51:37 -0400398 $test_case = 1;
Steven Rostedta57419b2010-11-02 15:13:54 -0400399 $skip = 0;
400 }
401
402 if ($rest =~ /\s+ITERATE\s+(\d+)(.*)$/) {
403 $repeat = $1;
404 $rest = $2;
405 $repeat_tests{"$test_num"} = $repeat;
406 }
407
408 if ($rest =~ /\s+SKIP(.*)/) {
409 $rest = $1;
410 $skip = 1;
411 }
412
413 if ($rest !~ /^\s*$/) {
414 die "$name: $.: Gargbage found after TEST_START\n$_";
415 }
416
417 if ($skip) {
418 $test_num = $old_test_num;
Steven Rostedte48c5292010-11-02 14:35:37 -0400419 $repeat = $old_repeat;
Steven Rostedta57419b2010-11-02 15:13:54 -0400420 }
421
422 } elsif (/^\s*DEFAULTS(.*)$/) {
423 $default = 1;
424
425 $rest = $1;
426
427 if ($rest =~ /\s+SKIP(.*)/) {
428 $rest = $1;
429 $skip = 1;
430 } else {
431 $skip = 0;
432 }
433
434 if ($rest !~ /^\s*$/) {
435 die "$name: $.: Gargbage found after DEFAULTS\n$_";
436 }
437
438 } elsif (/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) {
439
440 next if ($skip);
441
Steven Rostedt2545eb62010-11-02 15:01:32 -0400442 my $lvalue = $1;
443 my $rvalue = $2;
444
Steven Rostedta57419b2010-11-02 15:13:54 -0400445 if (!$default &&
446 ($lvalue eq "NUM_TESTS" ||
447 $lvalue eq "LOG_FILE" ||
448 $lvalue eq "CLEAR_LOG")) {
449 die "$name: $.: $lvalue must be set in DEFAULTS section\n";
Steven Rostedta75fece2010-11-02 14:58:27 -0400450 }
Steven Rostedta57419b2010-11-02 15:13:54 -0400451
452 if ($lvalue eq "NUM_TESTS") {
453 if ($test_num) {
454 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
455 }
456 if (!$default) {
457 die "$name: $.: NUM_TESTS must be set in default section\n";
458 }
459 $num_tests_set = 1;
460 }
461
462 if ($default || $lvalue =~ /\[\d+\]$/) {
463 set_value($lvalue, $rvalue);
464 } else {
465 my $val = "$lvalue\[$test_num\]";
466 set_value($val, $rvalue);
467
468 if ($repeat > 1) {
469 $repeats{$val} = $repeat;
470 }
471 }
Steven Rostedt77d942c2011-05-20 13:36:58 -0400472 } elsif (/^\s*([A-Z_\[\]\d]+)\s*:=\s*(.*?)\s*$/) {
473 next if ($skip);
474
475 my $lvalue = $1;
476 my $rvalue = $2;
477
478 # process config variables.
479 # Config variables are only active while reading the
480 # config and can be defined anywhere. They also ignore
481 # TEST_START and DEFAULTS, but are skipped if they are in
482 # on of these sections that have SKIP defined.
483 # The save variable can be
484 # defined multiple times and the new one simply overrides
485 # the prevous one.
486 set_variable($lvalue, $rvalue);
487
Steven Rostedta57419b2010-11-02 15:13:54 -0400488 } else {
489 die "$name: $.: Garbage found in config\n$_";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400490 }
491 }
492
493 close(IN);
Steven Rostedta75fece2010-11-02 14:58:27 -0400494
Steven Rostedta57419b2010-11-02 15:13:54 -0400495 if ($test_num) {
496 $test_num += $repeat - 1;
497 $opt{"NUM_TESTS"} = $test_num;
498 }
499
Steven Rostedt8d1491b2010-11-18 15:39:48 -0500500 # make sure we have all mandatory configs
501 get_ktest_configs;
502
Steven Rostedt0df213c2011-06-14 20:51:37 -0400503 # was a test specified?
504 if (!$test_case) {
505 print "No test case specified.\n";
506 print "What test case would you like to run?\n";
507 my $ans = <STDIN>;
508 chomp $ans;
509 $default{"TEST_TYPE"} = $ans;
510 }
511
Steven Rostedta75fece2010-11-02 14:58:27 -0400512 # set any defaults
513
514 foreach my $default (keys %default) {
515 if (!defined($opt{$default})) {
516 $opt{$default} = $default{$default};
517 }
518 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400519}
520
Steven Rostedt23715c3c2011-06-13 11:03:34 -0400521sub __eval_option {
522 my ($option, $i) = @_;
523
524 # Add space to evaluate the character before $
525 $option = " $option";
526 my $retval = "";
527
528 while ($option =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
529 my $start = $1;
530 my $var = $2;
531 my $end = $3;
532
533 # Append beginning of line
534 $retval = "$retval$start";
535
536 # If the iteration option OPT[$i] exists, then use that.
537 # otherwise see if the default OPT (without [$i]) exists.
538
539 my $o = "$var\[$i\]";
540
541 if (defined($opt{$o})) {
542 $o = $opt{$o};
543 $retval = "$retval$o";
544 } elsif (defined($opt{$var})) {
545 $o = $opt{$var};
546 $retval = "$retval$o";
547 } else {
548 $retval = "$retval\$\{$var\}";
549 }
550
551 $option = $end;
552 }
553
554 $retval = "$retval$option";
555
556 $retval =~ s/^ //;
557
558 return $retval;
559}
560
561sub eval_option {
562 my ($option, $i) = @_;
563
564 my $prev = "";
565
566 # Since an option can evaluate to another option,
567 # keep iterating until we do not evaluate any more
568 # options.
569 my $r = 0;
570 while ($prev ne $option) {
571 # Check for recursive evaluations.
572 # 100 deep should be more than enough.
573 if ($r++ > 100) {
574 die "Over 100 evaluations accurred with $option\n" .
575 "Check for recursive variables\n";
576 }
577 $prev = $option;
578 $option = __eval_option($option, $i);
579 }
580
581 return $option;
582}
583
Steven Rostedtd1e2f222010-11-08 16:39:57 -0500584sub _logit {
Steven Rostedt2545eb62010-11-02 15:01:32 -0400585 if (defined($opt{"LOG_FILE"})) {
586 open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}";
587 print OUT @_;
588 close(OUT);
589 }
590}
591
Steven Rostedtd1e2f222010-11-08 16:39:57 -0500592sub logit {
593 if (defined($opt{"LOG_FILE"})) {
594 _logit @_;
595 } else {
596 print @_;
597 }
598}
599
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400600sub doprint {
601 print @_;
Steven Rostedtd1e2f222010-11-08 16:39:57 -0500602 _logit @_;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400603}
604
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400605sub run_command;
Andrew Jones2728be42011-08-12 15:32:05 +0200606sub start_monitor;
607sub end_monitor;
608sub wait_for_monitor;
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400609
610sub reboot {
Andrew Jones2728be42011-08-12 15:32:05 +0200611 my ($time) = @_;
612
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400613 # try to reboot normally
Steven Rostedte48c5292010-11-02 14:35:37 -0400614 if (run_command $reboot) {
Steven Rostedt576f6272010-11-02 14:58:38 -0400615 if (defined($powercycle_after_reboot)) {
616 sleep $powercycle_after_reboot;
617 run_command "$power_cycle";
618 }
619 } else {
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400620 # nope? power cycle it.
Steven Rostedta75fece2010-11-02 14:58:27 -0400621 run_command "$power_cycle";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400622 }
Andrew Jones2728be42011-08-12 15:32:05 +0200623
624 if (defined($time)) {
625 start_monitor;
626 wait_for_monitor $time;
627 end_monitor;
628 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400629}
630
Steven Rostedt576f6272010-11-02 14:58:38 -0400631sub do_not_reboot {
632 my $i = $iteration;
633
634 return $test_type eq "build" ||
635 ($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") ||
636 ($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build");
637}
638
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400639sub dodie {
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400640 doprint "CRITICAL FAILURE... ", @_, "\n";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400641
Steven Rostedt576f6272010-11-02 14:58:38 -0400642 my $i = $iteration;
643
644 if ($reboot_on_error && !do_not_reboot) {
645
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400646 doprint "REBOOTING\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400647 reboot;
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400648
Steven Rostedta75fece2010-11-02 14:58:27 -0400649 } elsif ($poweroff_on_error && defined($power_off)) {
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400650 doprint "POWERING OFF\n";
Steven Rostedta75fece2010-11-02 14:58:27 -0400651 `$power_off`;
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400652 }
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400653
Steven Rostedtf80802c2011-03-07 13:18:47 -0500654 if (defined($opt{"LOG_FILE"})) {
655 print " See $opt{LOG_FILE} for more info.\n";
656 }
657
Steven Rostedt576f6272010-11-02 14:58:38 -0400658 die @_, "\n";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400659}
660
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400661sub open_console {
662 my ($fp) = @_;
663
664 my $flags;
665
Steven Rostedta75fece2010-11-02 14:58:27 -0400666 my $pid = open($fp, "$console|") or
667 dodie "Can't open console $console";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400668
669 $flags = fcntl($fp, F_GETFL, 0) or
Steven Rostedt576f6272010-11-02 14:58:38 -0400670 dodie "Can't get flags for the socket: $!";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400671 $flags = fcntl($fp, F_SETFL, $flags | O_NONBLOCK) or
Steven Rostedt576f6272010-11-02 14:58:38 -0400672 dodie "Can't set flags for the socket: $!";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400673
674 return $pid;
675}
676
677sub close_console {
678 my ($fp, $pid) = @_;
679
680 doprint "kill child process $pid\n";
681 kill 2, $pid;
682
683 print "closing!\n";
684 close($fp);
685}
686
687sub start_monitor {
688 if ($monitor_cnt++) {
689 return;
690 }
691 $monitor_fp = \*MONFD;
692 $monitor_pid = open_console $monitor_fp;
Steven Rostedta75fece2010-11-02 14:58:27 -0400693
694 return;
695
696 open(MONFD, "Stop perl from warning about single use of MONFD");
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400697}
698
699sub end_monitor {
700 if (--$monitor_cnt) {
701 return;
702 }
703 close_console($monitor_fp, $monitor_pid);
704}
705
706sub wait_for_monitor {
707 my ($time) = @_;
708 my $line;
709
Steven Rostedta75fece2010-11-02 14:58:27 -0400710 doprint "** Wait for monitor to settle down **\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400711
712 # read the monitor and wait for the system to calm down
713 do {
714 $line = wait_for_input($monitor_fp, $time);
Steven Rostedta75fece2010-11-02 14:58:27 -0400715 print "$line" if (defined($line));
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400716 } while (defined($line));
Steven Rostedta75fece2010-11-02 14:58:27 -0400717 print "** Monitor flushed **\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400718}
719
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400720sub fail {
721
Steven Rostedta75fece2010-11-02 14:58:27 -0400722 if ($die_on_failure) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400723 dodie @_;
724 }
725
Steven Rostedta75fece2010-11-02 14:58:27 -0400726 doprint "FAILED\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400727
Steven Rostedt576f6272010-11-02 14:58:38 -0400728 my $i = $iteration;
729
Steven Rostedta75fece2010-11-02 14:58:27 -0400730 # no need to reboot for just building.
Steven Rostedt576f6272010-11-02 14:58:38 -0400731 if (!do_not_reboot) {
Steven Rostedta75fece2010-11-02 14:58:27 -0400732 doprint "REBOOTING\n";
Andrew Jones2728be42011-08-12 15:32:05 +0200733 reboot $sleep_time;
Steven Rostedta75fece2010-11-02 14:58:27 -0400734 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400735
Steven Rostedt9064af52011-06-13 10:38:48 -0400736 my $name = "";
737
738 if (defined($test_name)) {
739 $name = " ($test_name)";
740 }
741
Steven Rostedt576f6272010-11-02 14:58:38 -0400742 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
743 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
Steven Rostedt9064af52011-06-13 10:38:48 -0400744 doprint "KTEST RESULT: TEST $i$name Failed: ", @_, "\n";
Steven Rostedt576f6272010-11-02 14:58:38 -0400745 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
746 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
Steven Rostedta75fece2010-11-02 14:58:27 -0400747
748 return 1 if (!defined($store_failures));
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400749
750 my @t = localtime;
751 my $date = sprintf "%04d%02d%02d%02d%02d%02d",
752 1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0];
753
Steven Rostedtcccae1a2010-11-09 12:21:32 -0500754 my $type = $build_type;
755 if ($type =~ /useconfig/) {
756 $type = "useconfig";
757 }
758
759 my $dir = "$machine-$test_type-$type-fail-$date";
Steven Rostedta75fece2010-11-02 14:58:27 -0400760 my $faildir = "$store_failures/$dir";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400761
762 if (!-d $faildir) {
763 mkpath($faildir) or
Steven Rostedta75fece2010-11-02 14:58:27 -0400764 die "can't create $faildir";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400765 }
Steven Rostedt51ad1dd2010-11-08 16:43:21 -0500766 if (-f "$output_config") {
767 cp "$output_config", "$faildir/config" or
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400768 die "failed to copy .config";
769 }
770 if (-f $buildlog) {
771 cp $buildlog, "$faildir/buildlog" or
772 die "failed to move $buildlog";
773 }
774 if (-f $dmesg) {
775 cp $dmesg, "$faildir/dmesg" or
776 die "failed to move $dmesg";
777 }
778
779 doprint "*** Saved info to $faildir ***\n";
780
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400781 return 1;
782}
783
Steven Rostedt2545eb62010-11-02 15:01:32 -0400784sub run_command {
785 my ($command) = @_;
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400786 my $dolog = 0;
787 my $dord = 0;
788 my $pid;
789
Steven Rostedte48c5292010-11-02 14:35:37 -0400790 $command =~ s/\$SSH_USER/$ssh_user/g;
791 $command =~ s/\$MACHINE/$machine/g;
792
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400793 doprint("$command ... ");
794
795 $pid = open(CMD, "$command 2>&1 |") or
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400796 (fail "unable to exec $command" and return 0);
Steven Rostedt2545eb62010-11-02 15:01:32 -0400797
798 if (defined($opt{"LOG_FILE"})) {
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400799 open(LOG, ">>$opt{LOG_FILE}") or
800 dodie "failed to write to log";
801 $dolog = 1;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400802 }
803
804 if (defined($redirect)) {
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400805 open (RD, ">$redirect") or
806 dodie "failed to write to redirect $redirect";
807 $dord = 1;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400808 }
809
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400810 while (<CMD>) {
811 print LOG if ($dolog);
812 print RD if ($dord);
813 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400814
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400815 waitpid($pid, 0);
Steven Rostedt2545eb62010-11-02 15:01:32 -0400816 my $failed = $?;
817
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400818 close(CMD);
819 close(LOG) if ($dolog);
820 close(RD) if ($dord);
821
Steven Rostedt2545eb62010-11-02 15:01:32 -0400822 if ($failed) {
823 doprint "FAILED!\n";
824 } else {
825 doprint "SUCCESS\n";
826 }
827
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400828 return !$failed;
829}
830
Steven Rostedte48c5292010-11-02 14:35:37 -0400831sub run_ssh {
832 my ($cmd) = @_;
833 my $cp_exec = $ssh_exec;
834
835 $cp_exec =~ s/\$SSH_COMMAND/$cmd/g;
836 return run_command "$cp_exec";
837}
838
839sub run_scp {
840 my ($src, $dst) = @_;
841 my $cp_scp = $scp_to_target;
842
843 $cp_scp =~ s/\$SRC_FILE/$src/g;
844 $cp_scp =~ s/\$DST_FILE/$dst/g;
845
846 return run_command "$cp_scp";
847}
848
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400849sub get_grub_index {
850
Steven Rostedta75fece2010-11-02 14:58:27 -0400851 if ($reboot_type ne "grub") {
852 return;
853 }
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400854 return if (defined($grub_number));
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400855
856 doprint "Find grub menu ... ";
857 $grub_number = -1;
Steven Rostedte48c5292010-11-02 14:35:37 -0400858
859 my $ssh_grub = $ssh_exec;
860 $ssh_grub =~ s,\$SSH_COMMAND,cat /boot/grub/menu.lst,g;
861
862 open(IN, "$ssh_grub |")
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400863 or die "unable to get menu.lst";
Steven Rostedte48c5292010-11-02 14:35:37 -0400864
Steven Rostedteaa1fe22011-09-14 17:20:39 -0400865 my $found = 0;
866
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400867 while (<IN>) {
Steven Rostedta75fece2010-11-02 14:58:27 -0400868 if (/^\s*title\s+$grub_menu\s*$/) {
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400869 $grub_number++;
Steven Rostedteaa1fe22011-09-14 17:20:39 -0400870 $found = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400871 last;
872 } elsif (/^\s*title\s/) {
873 $grub_number++;
874 }
875 }
876 close(IN);
877
Steven Rostedta75fece2010-11-02 14:58:27 -0400878 die "Could not find '$grub_menu' in /boot/grub/menu on $machine"
Steven Rostedteaa1fe22011-09-14 17:20:39 -0400879 if (!$found);
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400880 doprint "$grub_number\n";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400881}
882
Steven Rostedt2545eb62010-11-02 15:01:32 -0400883sub wait_for_input
884{
885 my ($fp, $time) = @_;
886 my $rin;
887 my $ready;
888 my $line;
889 my $ch;
890
891 if (!defined($time)) {
892 $time = $timeout;
893 }
894
895 $rin = '';
896 vec($rin, fileno($fp), 1) = 1;
897 $ready = select($rin, undef, undef, $time);
898
899 $line = "";
900
901 # try to read one char at a time
902 while (sysread $fp, $ch, 1) {
903 $line .= $ch;
904 last if ($ch eq "\n");
905 }
906
907 if (!length($line)) {
908 return undef;
909 }
910
911 return $line;
912}
913
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400914sub reboot_to {
Steven Rostedta75fece2010-11-02 14:58:27 -0400915 if ($reboot_type eq "grub") {
Steven Rostedt4da46da2011-06-01 23:25:13 -0400916 run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch && reboot)'";
Steven Rostedta75fece2010-11-02 14:58:27 -0400917 return;
918 }
919
920 run_command "$reboot_script";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400921}
922
Steven Rostedta57419b2010-11-02 15:13:54 -0400923sub get_sha1 {
924 my ($commit) = @_;
925
926 doprint "git rev-list --max-count=1 $commit ... ";
927 my $sha1 = `git rev-list --max-count=1 $commit`;
928 my $ret = $?;
929
930 logit $sha1;
931
932 if ($ret) {
933 doprint "FAILED\n";
934 dodie "Failed to get git $commit";
935 }
936
937 print "SUCCESS\n";
938
939 chomp $sha1;
940
941 return $sha1;
942}
943
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400944sub monitor {
Steven Rostedt2545eb62010-11-02 15:01:32 -0400945 my $booted = 0;
946 my $bug = 0;
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400947 my $skip_call_trace = 0;
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400948 my $loops;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400949
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400950 wait_for_monitor 5;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400951
952 my $line;
953 my $full_line = "";
954
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400955 open(DMESG, "> $dmesg") or
956 die "unable to write to $dmesg";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400957
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400958 reboot_to;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400959
Steven Rostedt1c8a6172010-11-09 12:55:40 -0500960 my $success_start;
961 my $failure_start;
Steven Rostedt2d01b262011-03-08 09:47:54 -0500962 my $monitor_start = time;
963 my $done = 0;
Steven Rostedtf1a5b962011-06-13 10:30:00 -0400964 my $version_found = 0;
Steven Rostedt1c8a6172010-11-09 12:55:40 -0500965
Steven Rostedt2d01b262011-03-08 09:47:54 -0500966 while (!$done) {
Steven Rostedt2545eb62010-11-02 15:01:32 -0400967
Steven Rostedtecaf8e52011-06-13 10:48:10 -0400968 if ($bug && defined($stop_after_failure) &&
969 $stop_after_failure >= 0) {
970 my $time = $stop_after_failure - (time - $failure_start);
971 $line = wait_for_input($monitor_fp, $time);
972 if (!defined($line)) {
973 doprint "bug timed out after $booted_timeout seconds\n";
974 doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
975 last;
976 }
977 } elsif ($booted) {
Steven Rostedta75fece2010-11-02 14:58:27 -0400978 $line = wait_for_input($monitor_fp, $booted_timeout);
Steven Rostedtcd4f1d52011-06-13 10:26:27 -0400979 if (!defined($line)) {
980 my $s = $booted_timeout == 1 ? "" : "s";
981 doprint "Successful boot found: break after $booted_timeout second$s\n";
982 last;
983 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400984 } else {
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400985 $line = wait_for_input($monitor_fp);
Steven Rostedtcd4f1d52011-06-13 10:26:27 -0400986 if (!defined($line)) {
987 my $s = $timeout == 1 ? "" : "s";
988 doprint "Timed out after $timeout second$s\n";
989 last;
990 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400991 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400992
Steven Rostedt2545eb62010-11-02 15:01:32 -0400993 doprint $line;
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400994 print DMESG $line;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400995
996 # we are not guaranteed to get a full line
997 $full_line .= $line;
998
Steven Rostedta75fece2010-11-02 14:58:27 -0400999 if ($full_line =~ /$success_line/) {
Steven Rostedt2545eb62010-11-02 15:01:32 -04001000 $booted = 1;
Steven Rostedt1c8a6172010-11-09 12:55:40 -05001001 $success_start = time;
1002 }
1003
1004 if ($booted && defined($stop_after_success) &&
1005 $stop_after_success >= 0) {
1006 my $now = time;
1007 if ($now - $success_start >= $stop_after_success) {
1008 doprint "Test forced to stop after $stop_after_success seconds after success\n";
1009 last;
1010 }
Steven Rostedt2545eb62010-11-02 15:01:32 -04001011 }
1012
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001013 if ($full_line =~ /\[ backtrace testing \]/) {
1014 $skip_call_trace = 1;
1015 }
1016
Steven Rostedt2545eb62010-11-02 15:01:32 -04001017 if ($full_line =~ /call trace:/i) {
Steven Rostedt46519202011-03-08 09:40:31 -05001018 if (!$bug && !$skip_call_trace) {
Steven Rostedt1c8a6172010-11-09 12:55:40 -05001019 $bug = 1;
1020 $failure_start = time;
1021 }
1022 }
1023
1024 if ($bug && defined($stop_after_failure) &&
1025 $stop_after_failure >= 0) {
1026 my $now = time;
1027 if ($now - $failure_start >= $stop_after_failure) {
1028 doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
1029 last;
1030 }
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001031 }
1032
1033 if ($full_line =~ /\[ end of backtrace testing \]/) {
1034 $skip_call_trace = 0;
1035 }
1036
1037 if ($full_line =~ /Kernel panic -/) {
Steven Rostedt10abf112011-03-07 13:21:00 -05001038 $failure_start = time;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001039 $bug = 1;
1040 }
1041
Steven Rostedtf1a5b962011-06-13 10:30:00 -04001042 # Detect triple faults by testing the banner
1043 if ($full_line =~ /\bLinux version (\S+).*\n/) {
1044 if ($1 eq $version) {
1045 $version_found = 1;
1046 } elsif ($version_found && $detect_triplefault) {
1047 # We already booted into the kernel we are testing,
1048 # but now we booted into another kernel?
1049 # Consider this a triple fault.
1050 doprint "Aleady booted in Linux kernel $version, but now\n";
1051 doprint "we booted into Linux kernel $1.\n";
1052 doprint "Assuming that this is a triple fault.\n";
1053 doprint "To disable this: set DETECT_TRIPLE_FAULT to 0\n";
1054 last;
1055 }
1056 }
1057
Steven Rostedt2545eb62010-11-02 15:01:32 -04001058 if ($line =~ /\n/) {
1059 $full_line = "";
1060 }
Steven Rostedt2d01b262011-03-08 09:47:54 -05001061
1062 if ($stop_test_after > 0 && !$booted && !$bug) {
1063 if (time - $monitor_start > $stop_test_after) {
Steven Rostedt4d62bf52011-05-20 09:14:35 -04001064 doprint "STOP_TEST_AFTER ($stop_test_after seconds) timed out\n";
Steven Rostedt2d01b262011-03-08 09:47:54 -05001065 $done = 1;
1066 }
1067 }
Steven Rostedt2545eb62010-11-02 15:01:32 -04001068 }
1069
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001070 close(DMESG);
Steven Rostedt2545eb62010-11-02 15:01:32 -04001071
Steven Rostedt2545eb62010-11-02 15:01:32 -04001072 if ($bug) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001073 return 0 if ($in_bisect);
Steven Rostedt576f6272010-11-02 14:58:38 -04001074 fail "failed - got a bug report" and return 0;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001075 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001076
Steven Rostedta75fece2010-11-02 14:58:27 -04001077 if (!$booted) {
1078 return 0 if ($in_bisect);
Steven Rostedt576f6272010-11-02 14:58:38 -04001079 fail "failed - never got a boot prompt." and return 0;
Steven Rostedta75fece2010-11-02 14:58:27 -04001080 }
1081
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001082 return 1;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001083}
1084
Steven Rostedtdb05cfe2011-06-13 11:09:22 -04001085sub do_post_install {
1086
1087 return if (!defined($post_install));
1088
1089 my $cp_post_install = $post_install;
1090 $cp_post_install =~ s/\$KERNEL_VERSION/$version/g;
1091 run_command "$cp_post_install" or
1092 dodie "Failed to run post install";
1093}
1094
Steven Rostedt2545eb62010-11-02 15:01:32 -04001095sub install {
1096
Steven Rostedte48c5292010-11-02 14:35:37 -04001097 run_scp "$outputdir/$build_target", "$target_image" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001098 dodie "failed to copy image";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001099
1100 my $install_mods = 0;
1101
1102 # should we process modules?
1103 $install_mods = 0;
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05001104 open(IN, "$output_config") or dodie("Can't read config file");
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001105 while (<IN>) {
1106 if (/CONFIG_MODULES(=y)?/) {
1107 $install_mods = 1 if (defined($1));
1108 last;
1109 }
1110 }
1111 close(IN);
1112
1113 if (!$install_mods) {
Steven Rostedtdb05cfe2011-06-13 11:09:22 -04001114 do_post_install;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001115 doprint "No modules needed\n";
1116 return;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001117 }
1118
Steven Rostedta75fece2010-11-02 14:58:27 -04001119 run_command "$make INSTALL_MOD_PATH=$tmpdir modules_install" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001120 dodie "Failed to install modules";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001121
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001122 my $modlib = "/lib/modules/$version";
Steven Rostedta57419b2010-11-02 15:13:54 -04001123 my $modtar = "ktest-mods.tar.bz2";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001124
Steven Rostedte48c5292010-11-02 14:35:37 -04001125 run_ssh "rm -rf $modlib" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001126 dodie "failed to remove old mods: $modlib";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001127
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001128 # would be nice if scp -r did not follow symbolic links
Steven Rostedta75fece2010-11-02 14:58:27 -04001129 run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001130 dodie "making tarball";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001131
Steven Rostedte48c5292010-11-02 14:35:37 -04001132 run_scp "$tmpdir/$modtar", "/tmp" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001133 dodie "failed to copy modules";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001134
Steven Rostedta75fece2010-11-02 14:58:27 -04001135 unlink "$tmpdir/$modtar";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001136
Steven Rostedte7b13442011-06-14 20:44:36 -04001137 run_ssh "'(cd / && tar xjf /tmp/$modtar)'" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001138 dodie "failed to tar modules";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001139
Steven Rostedte48c5292010-11-02 14:35:37 -04001140 run_ssh "rm -f /tmp/$modtar";
Steven Rostedt8b37ca82010-11-02 14:58:33 -04001141
Steven Rostedtdb05cfe2011-06-13 11:09:22 -04001142 do_post_install;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001143}
1144
Steven Rostedtddf607e2011-06-14 20:49:13 -04001145sub get_version {
1146 # get the release name
1147 doprint "$make kernelrelease ... ";
1148 $version = `$make kernelrelease | tail -1`;
1149 chomp($version);
1150 doprint "$version\n";
1151}
1152
1153sub start_monitor_and_boot {
1154 get_grub_index;
1155 get_version;
1156 install;
1157
1158 start_monitor;
1159 return monitor;
1160}
1161
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001162sub check_buildlog {
1163 my ($patch) = @_;
1164
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001165 my @files = `git show $patch | diffstat -l`;
1166
1167 open(IN, "git show $patch |") or
1168 dodie "failed to show $patch";
1169 while (<IN>) {
1170 if (m,^--- a/(.*),) {
1171 chomp $1;
1172 $files[$#files] = $1;
1173 }
1174 }
1175 close(IN);
1176
1177 open(IN, $buildlog) or dodie "Can't open $buildlog";
1178 while (<IN>) {
1179 if (/^\s*(.*?):.*(warning|error)/) {
1180 my $err = $1;
1181 foreach my $file (@files) {
Steven Rostedta75fece2010-11-02 14:58:27 -04001182 my $fullpath = "$builddir/$file";
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001183 if ($file eq $err || $fullpath eq $err) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001184 fail "$file built with warnings" and return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001185 }
1186 }
1187 }
1188 }
1189 close(IN);
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001190
1191 return 1;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001192}
1193
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001194sub apply_min_config {
1195 my $outconfig = "$output_config.new";
Steven Rostedt612b9e92011-03-07 13:27:43 -05001196
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001197 # Read the config file and remove anything that
1198 # is in the force_config hash (from minconfig and others)
1199 # then add the force config back.
1200
1201 doprint "Applying minimum configurations into $output_config.new\n";
1202
1203 open (OUT, ">$outconfig") or
1204 dodie "Can't create $outconfig";
1205
1206 if (-f $output_config) {
1207 open (IN, $output_config) or
1208 dodie "Failed to open $output_config";
1209 while (<IN>) {
1210 if (/^(# )?(CONFIG_[^\s=]*)/) {
1211 next if (defined($force_config{$2}));
1212 }
1213 print OUT;
1214 }
1215 close IN;
1216 }
1217 foreach my $config (keys %force_config) {
1218 print OUT "$force_config{$config}\n";
1219 }
1220 close OUT;
1221
1222 run_command "mv $outconfig $output_config";
1223}
1224
1225sub make_oldconfig {
1226
Steven Rostedt4c4ab122011-07-15 21:16:17 -04001227 my @force_list = keys %force_config;
1228
1229 if ($#force_list >= 0) {
1230 apply_min_config;
1231 }
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001232
1233 if (!run_command "$make oldnoconfig") {
Steven Rostedt612b9e92011-03-07 13:27:43 -05001234 # Perhaps oldnoconfig doesn't exist in this version of the kernel
1235 # try a yes '' | oldconfig
1236 doprint "oldnoconfig failed, trying yes '' | make oldconfig\n";
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001237 run_command "yes '' | $make oldconfig" or
Steven Rostedt612b9e92011-03-07 13:27:43 -05001238 dodie "failed make config oldconfig";
1239 }
1240}
1241
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001242# read a config file and use this to force new configs.
1243sub load_force_config {
1244 my ($config) = @_;
1245
1246 open(IN, $config) or
1247 dodie "failed to read $config";
1248 while (<IN>) {
1249 chomp;
1250 if (/^(CONFIG[^\s=]*)(\s*=.*)/) {
1251 $force_config{$1} = $_;
1252 } elsif (/^# (CONFIG_\S*) is not set/) {
1253 $force_config{$1} = $_;
1254 }
1255 }
1256 close IN;
1257}
1258
Steven Rostedt2545eb62010-11-02 15:01:32 -04001259sub build {
1260 my ($type) = @_;
1261
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001262 unlink $buildlog;
1263
Steven Rostedt0bd6c1a2011-06-14 20:39:31 -04001264 if (defined($pre_build)) {
1265 my $ret = run_command $pre_build;
1266 if (!$ret && defined($pre_build_die) &&
1267 $pre_build_die) {
1268 dodie "failed to pre_build\n";
1269 }
1270 }
1271
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001272 if ($type =~ /^useconfig:(.*)/) {
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05001273 run_command "cp $1 $output_config" or
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001274 dodie "could not copy $1 to .config";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001275
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001276 $type = "oldconfig";
1277 }
1278
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001279 # old config can ask questions
1280 if ($type eq "oldconfig") {
Steven Rostedt9386c6a2010-11-08 16:35:48 -05001281 $type = "oldnoconfig";
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001282
1283 # allow for empty configs
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05001284 run_command "touch $output_config";
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001285
Andrew Jones13488232011-08-12 15:32:04 +02001286 if (!$noclean) {
1287 run_command "mv $output_config $outputdir/config_temp" or
1288 dodie "moving .config";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001289
Andrew Jones13488232011-08-12 15:32:04 +02001290 run_command "$make mrproper" or dodie "make mrproper";
1291
1292 run_command "mv $outputdir/config_temp $output_config" or
1293 dodie "moving config_temp";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001294 }
1295
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001296 } elsif (!$noclean) {
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05001297 unlink "$output_config";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001298 run_command "$make mrproper" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001299 dodie "make mrproper";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001300 }
Steven Rostedt2545eb62010-11-02 15:01:32 -04001301
1302 # add something to distinguish this build
Steven Rostedta75fece2010-11-02 14:58:27 -04001303 open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file");
1304 print OUT "$localversion\n";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001305 close(OUT);
1306
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001307 if (defined($minconfig)) {
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001308 load_force_config($minconfig);
Steven Rostedt2545eb62010-11-02 15:01:32 -04001309 }
1310
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001311 if ($type ne "oldnoconfig") {
1312 run_command "$make $type" or
Steven Rostedt612b9e92011-03-07 13:27:43 -05001313 dodie "failed make config";
1314 }
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001315 # Run old config regardless, to enforce min configurations
1316 make_oldconfig;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001317
Steven Rostedta75fece2010-11-02 14:58:27 -04001318 $redirect = "$buildlog";
Steven Rostedt0bd6c1a2011-06-14 20:39:31 -04001319 my $build_ret = run_command "$make $build_options";
1320 undef $redirect;
1321
1322 if (defined($post_build)) {
1323 my $ret = run_command $post_build;
1324 if (!$ret && defined($post_build_die) &&
1325 $post_build_die) {
1326 dodie "failed to post_build\n";
1327 }
1328 }
1329
1330 if (!$build_ret) {
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001331 # bisect may need this to pass
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001332 return 0 if ($in_bisect);
1333 fail "failed build" and return 0;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001334 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001335
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001336 return 1;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001337}
1338
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001339sub halt {
Steven Rostedte48c5292010-11-02 14:35:37 -04001340 if (!run_ssh "halt" or defined($power_off)) {
Steven Rostedt576f6272010-11-02 14:58:38 -04001341 if (defined($poweroff_after_halt)) {
1342 sleep $poweroff_after_halt;
1343 run_command "$power_off";
1344 }
1345 } else {
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001346 # nope? the zap it!
Steven Rostedta75fece2010-11-02 14:58:27 -04001347 run_command "$power_off";
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001348 }
1349}
1350
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001351sub success {
1352 my ($i) = @_;
1353
Steven Rostedte48c5292010-11-02 14:35:37 -04001354 $successes++;
1355
Steven Rostedt9064af52011-06-13 10:38:48 -04001356 my $name = "";
1357
1358 if (defined($test_name)) {
1359 $name = " ($test_name)";
1360 }
1361
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001362 doprint "\n\n*******************************************\n";
1363 doprint "*******************************************\n";
Steven Rostedt9064af52011-06-13 10:38:48 -04001364 doprint "KTEST RESULT: TEST $i$name SUCCESS!!!! **\n";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001365 doprint "*******************************************\n";
1366 doprint "*******************************************\n";
1367
Steven Rostedt576f6272010-11-02 14:58:38 -04001368 if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) {
Steven Rostedta75fece2010-11-02 14:58:27 -04001369 doprint "Reboot and wait $sleep_time seconds\n";
Andrew Jones2728be42011-08-12 15:32:05 +02001370 reboot $sleep_time;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001371 }
1372}
1373
Steven Rostedtc960bb92011-03-08 09:22:39 -05001374sub answer_bisect {
1375 for (;;) {
1376 doprint "Pass or fail? [p/f]";
1377 my $ans = <STDIN>;
1378 chomp $ans;
1379 if ($ans eq "p" || $ans eq "P") {
1380 return 1;
1381 } elsif ($ans eq "f" || $ans eq "F") {
1382 return 0;
1383 } else {
1384 print "Please answer 'P' or 'F'\n";
1385 }
1386 }
1387}
1388
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001389sub child_run_test {
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001390 my $failed = 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001391
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001392 # child should have no power
Steven Rostedta75fece2010-11-02 14:58:27 -04001393 $reboot_on_error = 0;
1394 $poweroff_on_error = 0;
1395 $die_on_failure = 1;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001396
1397 run_command $run_test or $failed = 1;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001398 exit $failed;
1399}
1400
1401my $child_done;
1402
1403sub child_finished {
1404 $child_done = 1;
1405}
1406
1407sub do_run_test {
1408 my $child_pid;
1409 my $child_exit;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001410 my $line;
1411 my $full_line;
1412 my $bug = 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001413
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001414 wait_for_monitor 1;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001415
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001416 doprint "run test $run_test\n";
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001417
1418 $child_done = 0;
1419
1420 $SIG{CHLD} = qw(child_finished);
1421
1422 $child_pid = fork;
1423
1424 child_run_test if (!$child_pid);
1425
1426 $full_line = "";
1427
1428 do {
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001429 $line = wait_for_input($monitor_fp, 1);
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001430 if (defined($line)) {
1431
1432 # we are not guaranteed to get a full line
1433 $full_line .= $line;
Steven Rostedt8ea0e062011-03-08 09:44:35 -05001434 doprint $line;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001435
1436 if ($full_line =~ /call trace:/i) {
1437 $bug = 1;
1438 }
1439
1440 if ($full_line =~ /Kernel panic -/) {
1441 $bug = 1;
1442 }
1443
1444 if ($line =~ /\n/) {
1445 $full_line = "";
1446 }
1447 }
1448 } while (!$child_done && !$bug);
1449
1450 if ($bug) {
Steven Rostedt8ea0e062011-03-08 09:44:35 -05001451 my $failure_start = time;
1452 my $now;
1453 do {
1454 $line = wait_for_input($monitor_fp, 1);
1455 if (defined($line)) {
1456 doprint $line;
1457 }
1458 $now = time;
1459 if ($now - $failure_start >= $stop_after_failure) {
1460 last;
1461 }
1462 } while (defined($line));
1463
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001464 doprint "Detected kernel crash!\n";
1465 # kill the child with extreme prejudice
1466 kill 9, $child_pid;
1467 }
1468
1469 waitpid $child_pid, 0;
1470 $child_exit = $?;
1471
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001472 if ($bug || $child_exit) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001473 return 0 if $in_bisect;
1474 fail "test failed" and return 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001475 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001476 return 1;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001477}
1478
Steven Rostedta75fece2010-11-02 14:58:27 -04001479sub run_git_bisect {
1480 my ($command) = @_;
1481
1482 doprint "$command ... ";
1483
1484 my $output = `$command 2>&1`;
1485 my $ret = $?;
1486
1487 logit $output;
1488
1489 if ($ret) {
1490 doprint "FAILED\n";
1491 dodie "Failed to git bisect";
1492 }
1493
1494 doprint "SUCCESS\n";
1495 if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) {
1496 doprint "$1 [$2]\n";
1497 } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) {
1498 $bisect_bad = $1;
1499 doprint "Found bad commit... $1\n";
1500 return 0;
1501 } else {
1502 # we already logged it, just print it now.
1503 print $output;
1504 }
1505
1506 return 1;
1507}
1508
Steven Rostedtc23dca72011-03-08 09:26:31 -05001509sub bisect_reboot {
1510 doprint "Reboot and sleep $bisect_sleep_time seconds\n";
Andrew Jones2728be42011-08-12 15:32:05 +02001511 reboot $bisect_sleep_time;
Steven Rostedtc23dca72011-03-08 09:26:31 -05001512}
1513
1514# returns 1 on success, 0 on failure, -1 on skip
Steven Rostedt0a05c762010-11-08 11:14:10 -05001515sub run_bisect_test {
1516 my ($type, $buildtype) = @_;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001517
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001518 my $failed = 0;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001519 my $result;
1520 my $output;
1521 my $ret;
1522
Steven Rostedt0a05c762010-11-08 11:14:10 -05001523 $in_bisect = 1;
1524
1525 build $buildtype or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001526
1527 if ($type ne "build") {
Steven Rostedtc23dca72011-03-08 09:26:31 -05001528 if ($failed && $bisect_skip) {
1529 $in_bisect = 0;
1530 return -1;
1531 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001532 dodie "Failed on build" if $failed;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001533
1534 # Now boot the box
Steven Rostedtddf607e2011-06-14 20:49:13 -04001535 start_monitor_and_boot or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001536
1537 if ($type ne "boot") {
Steven Rostedtc23dca72011-03-08 09:26:31 -05001538 if ($failed && $bisect_skip) {
1539 end_monitor;
1540 bisect_reboot;
1541 $in_bisect = 0;
1542 return -1;
1543 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001544 dodie "Failed on boot" if $failed;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001545
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001546 do_run_test or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001547 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001548 end_monitor;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001549 }
1550
1551 if ($failed) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001552 $result = 0;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001553 } else {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001554 $result = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001555 }
Steven Rostedt4025bc62011-05-20 09:16:29 -04001556
1557 # reboot the box to a kernel we can ssh to
1558 if ($type ne "build") {
1559 bisect_reboot;
1560 }
Steven Rostedt0a05c762010-11-08 11:14:10 -05001561 $in_bisect = 0;
1562
1563 return $result;
1564}
1565
1566sub run_bisect {
1567 my ($type) = @_;
1568 my $buildtype = "oldconfig";
1569
1570 # We should have a minconfig to use?
1571 if (defined($minconfig)) {
1572 $buildtype = "useconfig:$minconfig";
1573 }
1574
1575 my $ret = run_bisect_test $type, $buildtype;
1576
Steven Rostedtc960bb92011-03-08 09:22:39 -05001577 if ($bisect_manual) {
1578 $ret = answer_bisect;
1579 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001580
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04001581 # Are we looking for where it worked, not failed?
1582 if ($reverse_bisect) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001583 $ret = !$ret;
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04001584 }
1585
Steven Rostedtc23dca72011-03-08 09:26:31 -05001586 if ($ret > 0) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001587 return "good";
Steven Rostedtc23dca72011-03-08 09:26:31 -05001588 } elsif ($ret == 0) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001589 return "bad";
Steven Rostedtc23dca72011-03-08 09:26:31 -05001590 } elsif ($bisect_skip) {
1591 doprint "HIT A BAD COMMIT ... SKIPPING\n";
1592 return "skip";
Steven Rostedt0a05c762010-11-08 11:14:10 -05001593 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001594}
1595
1596sub bisect {
1597 my ($i) = @_;
1598
1599 my $result;
1600
1601 die "BISECT_GOOD[$i] not defined\n" if (!defined($opt{"BISECT_GOOD[$i]"}));
1602 die "BISECT_BAD[$i] not defined\n" if (!defined($opt{"BISECT_BAD[$i]"}));
1603 die "BISECT_TYPE[$i] not defined\n" if (!defined($opt{"BISECT_TYPE[$i]"}));
1604
1605 my $good = $opt{"BISECT_GOOD[$i]"};
1606 my $bad = $opt{"BISECT_BAD[$i]"};
1607 my $type = $opt{"BISECT_TYPE[$i]"};
Steven Rostedta75fece2010-11-02 14:58:27 -04001608 my $start = $opt{"BISECT_START[$i]"};
1609 my $replay = $opt{"BISECT_REPLAY[$i]"};
Steven Rostedt3410f6f2011-03-08 09:38:12 -05001610 my $start_files = $opt{"BISECT_FILES[$i]"};
1611
1612 if (defined($start_files)) {
1613 $start_files = " -- " . $start_files;
1614 } else {
1615 $start_files = "";
1616 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001617
Steven Rostedta57419b2010-11-02 15:13:54 -04001618 # convert to true sha1's
1619 $good = get_sha1($good);
1620 $bad = get_sha1($bad);
1621
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04001622 if (defined($opt{"BISECT_REVERSE[$i]"}) &&
1623 $opt{"BISECT_REVERSE[$i]"} == 1) {
1624 doprint "Performing a reverse bisect (bad is good, good is bad!)\n";
1625 $reverse_bisect = 1;
1626 } else {
1627 $reverse_bisect = 0;
1628 }
1629
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001630 # Can't have a test without having a test to run
1631 if ($type eq "test" && !defined($run_test)) {
1632 $type = "boot";
1633 }
1634
Steven Rostedta75fece2010-11-02 14:58:27 -04001635 my $check = $opt{"BISECT_CHECK[$i]"};
1636 if (defined($check) && $check ne "0") {
1637
1638 # get current HEAD
Steven Rostedta57419b2010-11-02 15:13:54 -04001639 my $head = get_sha1("HEAD");
Steven Rostedta75fece2010-11-02 14:58:27 -04001640
1641 if ($check ne "good") {
1642 doprint "TESTING BISECT BAD [$bad]\n";
1643 run_command "git checkout $bad" or
1644 die "Failed to checkout $bad";
1645
1646 $result = run_bisect $type;
1647
1648 if ($result ne "bad") {
1649 fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0;
1650 }
1651 }
1652
1653 if ($check ne "bad") {
1654 doprint "TESTING BISECT GOOD [$good]\n";
1655 run_command "git checkout $good" or
1656 die "Failed to checkout $good";
1657
1658 $result = run_bisect $type;
1659
1660 if ($result ne "good") {
1661 fail "Tested BISECT_GOOD [$good] and it failed" and return 0;
1662 }
1663 }
1664
1665 # checkout where we started
1666 run_command "git checkout $head" or
1667 die "Failed to checkout $head";
1668 }
1669
Steven Rostedt3410f6f2011-03-08 09:38:12 -05001670 run_command "git bisect start$start_files" or
Steven Rostedta75fece2010-11-02 14:58:27 -04001671 dodie "could not start bisect";
1672
1673 run_command "git bisect good $good" or
1674 dodie "could not set bisect good to $good";
1675
1676 run_git_bisect "git bisect bad $bad" or
1677 dodie "could not set bisect bad to $bad";
1678
1679 if (defined($replay)) {
1680 run_command "git bisect replay $replay" or
1681 dodie "failed to run replay";
1682 }
1683
1684 if (defined($start)) {
1685 run_command "git checkout $start" or
1686 dodie "failed to checkout $start";
1687 }
1688
1689 my $test;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001690 do {
1691 $result = run_bisect $type;
Steven Rostedta75fece2010-11-02 14:58:27 -04001692 $test = run_git_bisect "git bisect $result";
1693 } while ($test);
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001694
1695 run_command "git bisect log" or
1696 dodie "could not capture git bisect log";
1697
1698 run_command "git bisect reset" or
1699 dodie "could not reset git bisect";
1700
1701 doprint "Bad commit was [$bisect_bad]\n";
1702
Steven Rostedt0a05c762010-11-08 11:14:10 -05001703 success $i;
1704}
1705
1706my %config_ignore;
1707my %config_set;
1708
1709my %config_list;
1710my %null_config;
1711
1712my %dependency;
1713
Steven Rostedt4c4ab122011-07-15 21:16:17 -04001714sub assign_configs {
1715 my ($hash, $config) = @_;
Steven Rostedt0a05c762010-11-08 11:14:10 -05001716
1717 open (IN, $config)
1718 or dodie "Failed to read $config";
1719
1720 while (<IN>) {
Steven Rostedt9bf71742011-06-01 23:27:19 -04001721 if (/^((CONFIG\S*)=.*)/) {
Steven Rostedt4c4ab122011-07-15 21:16:17 -04001722 ${$hash}{$2} = $1;
Steven Rostedt0a05c762010-11-08 11:14:10 -05001723 }
1724 }
1725
1726 close(IN);
1727}
1728
Steven Rostedt4c4ab122011-07-15 21:16:17 -04001729sub process_config_ignore {
1730 my ($config) = @_;
1731
1732 assign_configs \%config_ignore, $config;
1733}
1734
Steven Rostedt0a05c762010-11-08 11:14:10 -05001735sub read_current_config {
1736 my ($config_ref) = @_;
1737
1738 %{$config_ref} = ();
1739 undef %{$config_ref};
1740
1741 my @key = keys %{$config_ref};
1742 if ($#key >= 0) {
1743 print "did not delete!\n";
1744 exit;
1745 }
1746 open (IN, "$output_config");
1747
1748 while (<IN>) {
1749 if (/^(CONFIG\S+)=(.*)/) {
1750 ${$config_ref}{$1} = $2;
1751 }
1752 }
1753 close(IN);
1754}
1755
1756sub get_dependencies {
1757 my ($config) = @_;
1758
1759 my $arr = $dependency{$config};
1760 if (!defined($arr)) {
1761 return ();
1762 }
1763
1764 my @deps = @{$arr};
1765
1766 foreach my $dep (@{$arr}) {
1767 print "ADD DEP $dep\n";
1768 @deps = (@deps, get_dependencies $dep);
1769 }
1770
1771 return @deps;
1772}
1773
1774sub create_config {
1775 my @configs = @_;
1776
1777 open(OUT, ">$output_config") or dodie "Can not write to $output_config";
1778
1779 foreach my $config (@configs) {
1780 print OUT "$config_set{$config}\n";
1781 my @deps = get_dependencies $config;
1782 foreach my $dep (@deps) {
1783 print OUT "$config_set{$dep}\n";
1784 }
1785 }
1786
1787 foreach my $config (keys %config_ignore) {
1788 print OUT "$config_ignore{$config}\n";
1789 }
1790 close(OUT);
1791
1792# exit;
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001793 make_oldconfig;
Steven Rostedt0a05c762010-11-08 11:14:10 -05001794}
1795
1796sub compare_configs {
1797 my (%a, %b) = @_;
1798
1799 foreach my $item (keys %a) {
1800 if (!defined($b{$item})) {
1801 print "diff $item\n";
1802 return 1;
1803 }
1804 delete $b{$item};
1805 }
1806
1807 my @keys = keys %b;
1808 if ($#keys) {
1809 print "diff2 $keys[0]\n";
1810 }
1811 return -1 if ($#keys >= 0);
1812
1813 return 0;
1814}
1815
1816sub run_config_bisect_test {
1817 my ($type) = @_;
1818
1819 return run_bisect_test $type, "oldconfig";
1820}
1821
1822sub process_passed {
1823 my (%configs) = @_;
1824
1825 doprint "These configs had no failure: (Enabling them for further compiles)\n";
1826 # Passed! All these configs are part of a good compile.
1827 # Add them to the min options.
1828 foreach my $config (keys %configs) {
1829 if (defined($config_list{$config})) {
1830 doprint " removing $config\n";
1831 $config_ignore{$config} = $config_list{$config};
1832 delete $config_list{$config};
1833 }
1834 }
Steven Rostedtf1a27852010-11-11 11:34:38 -05001835 doprint "config copied to $outputdir/config_good\n";
1836 run_command "cp -f $output_config $outputdir/config_good";
Steven Rostedt0a05c762010-11-08 11:14:10 -05001837}
1838
1839sub process_failed {
1840 my ($config) = @_;
1841
1842 doprint "\n\n***************************************\n";
1843 doprint "Found bad config: $config\n";
1844 doprint "***************************************\n\n";
1845}
1846
1847sub run_config_bisect {
1848
1849 my @start_list = keys %config_list;
1850
1851 if ($#start_list < 0) {
1852 doprint "No more configs to test!!!\n";
1853 return -1;
1854 }
1855
1856 doprint "***** RUN TEST ***\n";
1857 my $type = $opt{"CONFIG_BISECT_TYPE[$iteration]"};
1858 my $ret;
1859 my %current_config;
1860
1861 my $count = $#start_list + 1;
1862 doprint " $count configs to test\n";
1863
1864 my $half = int($#start_list / 2);
1865
1866 do {
1867 my @tophalf = @start_list[0 .. $half];
1868
1869 create_config @tophalf;
1870 read_current_config \%current_config;
1871
1872 $count = $#tophalf + 1;
1873 doprint "Testing $count configs\n";
1874 my $found = 0;
1875 # make sure we test something
1876 foreach my $config (@tophalf) {
1877 if (defined($current_config{$config})) {
1878 logit " $config\n";
1879 $found = 1;
1880 }
1881 }
1882 if (!$found) {
1883 # try the other half
1884 doprint "Top half produced no set configs, trying bottom half\n";
Steven Rostedt4c8cc552011-06-01 23:22:30 -04001885 @tophalf = @start_list[$half + 1 .. $#start_list];
Steven Rostedt0a05c762010-11-08 11:14:10 -05001886 create_config @tophalf;
1887 read_current_config \%current_config;
1888 foreach my $config (@tophalf) {
1889 if (defined($current_config{$config})) {
1890 logit " $config\n";
1891 $found = 1;
1892 }
1893 }
1894 if (!$found) {
1895 doprint "Failed: Can't make new config with current configs\n";
1896 foreach my $config (@start_list) {
1897 doprint " CONFIG: $config\n";
1898 }
1899 return -1;
1900 }
1901 $count = $#tophalf + 1;
1902 doprint "Testing $count configs\n";
1903 }
1904
1905 $ret = run_config_bisect_test $type;
Steven Rostedtc960bb92011-03-08 09:22:39 -05001906 if ($bisect_manual) {
1907 $ret = answer_bisect;
1908 }
Steven Rostedt0a05c762010-11-08 11:14:10 -05001909 if ($ret) {
1910 process_passed %current_config;
1911 return 0;
1912 }
1913
1914 doprint "This config had a failure.\n";
1915 doprint "Removing these configs that were not set in this config:\n";
Steven Rostedtf1a27852010-11-11 11:34:38 -05001916 doprint "config copied to $outputdir/config_bad\n";
1917 run_command "cp -f $output_config $outputdir/config_bad";
Steven Rostedt0a05c762010-11-08 11:14:10 -05001918
1919 # A config exists in this group that was bad.
1920 foreach my $config (keys %config_list) {
1921 if (!defined($current_config{$config})) {
1922 doprint " removing $config\n";
1923 delete $config_list{$config};
1924 }
1925 }
1926
1927 @start_list = @tophalf;
1928
1929 if ($#start_list == 0) {
1930 process_failed $start_list[0];
1931 return 1;
1932 }
1933
1934 # remove half the configs we are looking at and see if
1935 # they are good.
1936 $half = int($#start_list / 2);
Steven Rostedt4c8cc552011-06-01 23:22:30 -04001937 } while ($#start_list > 0);
Steven Rostedt0a05c762010-11-08 11:14:10 -05001938
Steven Rostedtc960bb92011-03-08 09:22:39 -05001939 # we found a single config, try it again unless we are running manually
1940
1941 if ($bisect_manual) {
1942 process_failed $start_list[0];
1943 return 1;
1944 }
1945
Steven Rostedt0a05c762010-11-08 11:14:10 -05001946 my @tophalf = @start_list[0 .. 0];
1947
1948 $ret = run_config_bisect_test $type;
1949 if ($ret) {
1950 process_passed %current_config;
1951 return 0;
1952 }
1953
1954 process_failed $start_list[0];
1955 return 1;
1956}
1957
1958sub config_bisect {
1959 my ($i) = @_;
1960
1961 my $start_config = $opt{"CONFIG_BISECT[$i]"};
1962
1963 my $tmpconfig = "$tmpdir/use_config";
1964
Steven Rostedt30f75da2011-06-13 10:35:35 -04001965 if (defined($config_bisect_good)) {
1966 process_config_ignore $config_bisect_good;
1967 }
1968
Steven Rostedt0a05c762010-11-08 11:14:10 -05001969 # Make the file with the bad config and the min config
1970 if (defined($minconfig)) {
1971 # read the min config for things to ignore
1972 run_command "cp $minconfig $tmpconfig" or
1973 dodie "failed to copy $minconfig to $tmpconfig";
1974 } else {
1975 unlink $tmpconfig;
1976 }
1977
Steven Rostedt0a05c762010-11-08 11:14:10 -05001978 if (-f $tmpconfig) {
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001979 load_force_config($tmpconfig);
Steven Rostedt0a05c762010-11-08 11:14:10 -05001980 process_config_ignore $tmpconfig;
1981 }
1982
1983 # now process the start config
1984 run_command "cp $start_config $output_config" or
1985 dodie "failed to copy $start_config to $output_config";
1986
1987 # read directly what we want to check
1988 my %config_check;
1989 open (IN, $output_config)
1990 or dodie "faied to open $output_config";
1991
1992 while (<IN>) {
1993 if (/^((CONFIG\S*)=.*)/) {
1994 $config_check{$2} = $1;
1995 }
1996 }
1997 close(IN);
1998
Steven Rostedt250bae82011-07-15 22:05:59 -04001999 # Now run oldconfig with the minconfig
Steven Rostedtfcb3f162011-06-13 10:40:58 -04002000 make_oldconfig;
Steven Rostedt0a05c762010-11-08 11:14:10 -05002001
2002 # check to see what we lost (or gained)
2003 open (IN, $output_config)
2004 or dodie "Failed to read $start_config";
2005
2006 my %removed_configs;
2007 my %added_configs;
2008
2009 while (<IN>) {
2010 if (/^((CONFIG\S*)=.*)/) {
2011 # save off all options
2012 $config_set{$2} = $1;
2013 if (defined($config_check{$2})) {
2014 if (defined($config_ignore{$2})) {
2015 $removed_configs{$2} = $1;
2016 } else {
2017 $config_list{$2} = $1;
2018 }
2019 } elsif (!defined($config_ignore{$2})) {
2020 $added_configs{$2} = $1;
2021 $config_list{$2} = $1;
2022 }
2023 }
2024 }
2025 close(IN);
2026
2027 my @confs = keys %removed_configs;
2028 if ($#confs >= 0) {
2029 doprint "Configs overridden by default configs and removed from check:\n";
2030 foreach my $config (@confs) {
2031 doprint " $config\n";
2032 }
2033 }
2034 @confs = keys %added_configs;
2035 if ($#confs >= 0) {
2036 doprint "Configs appearing in make oldconfig and added:\n";
2037 foreach my $config (@confs) {
2038 doprint " $config\n";
2039 }
2040 }
2041
2042 my %config_test;
2043 my $once = 0;
2044
2045 # Sometimes kconfig does weird things. We must make sure
2046 # that the config we autocreate has everything we need
2047 # to test, otherwise we may miss testing configs, or
2048 # may not be able to create a new config.
2049 # Here we create a config with everything set.
2050 create_config (keys %config_list);
2051 read_current_config \%config_test;
2052 foreach my $config (keys %config_list) {
2053 if (!defined($config_test{$config})) {
2054 if (!$once) {
2055 $once = 1;
2056 doprint "Configs not produced by kconfig (will not be checked):\n";
2057 }
2058 doprint " $config\n";
2059 delete $config_list{$config};
2060 }
2061 }
2062 my $ret;
2063 do {
2064 $ret = run_config_bisect;
2065 } while (!$ret);
2066
2067 return $ret if ($ret < 0);
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04002068
2069 success $i;
2070}
2071
Steven Rostedt27d934b2011-05-20 09:18:18 -04002072sub patchcheck_reboot {
2073 doprint "Reboot and sleep $patchcheck_sleep_time seconds\n";
Andrew Jones2728be42011-08-12 15:32:05 +02002074 reboot $patchcheck_sleep_time;
Steven Rostedt27d934b2011-05-20 09:18:18 -04002075}
2076
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002077sub patchcheck {
2078 my ($i) = @_;
2079
2080 die "PATCHCHECK_START[$i] not defined\n"
2081 if (!defined($opt{"PATCHCHECK_START[$i]"}));
2082 die "PATCHCHECK_TYPE[$i] not defined\n"
2083 if (!defined($opt{"PATCHCHECK_TYPE[$i]"}));
2084
2085 my $start = $opt{"PATCHCHECK_START[$i]"};
2086
2087 my $end = "HEAD";
2088 if (defined($opt{"PATCHCHECK_END[$i]"})) {
2089 $end = $opt{"PATCHCHECK_END[$i]"};
2090 }
2091
Steven Rostedta57419b2010-11-02 15:13:54 -04002092 # Get the true sha1's since we can use things like HEAD~3
2093 $start = get_sha1($start);
2094 $end = get_sha1($end);
2095
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002096 my $type = $opt{"PATCHCHECK_TYPE[$i]"};
2097
2098 # Can't have a test without having a test to run
2099 if ($type eq "test" && !defined($run_test)) {
2100 $type = "boot";
2101 }
2102
2103 open (IN, "git log --pretty=oneline $end|") or
2104 dodie "could not get git list";
2105
2106 my @list;
2107
2108 while (<IN>) {
2109 chomp;
2110 $list[$#list+1] = $_;
2111 last if (/^$start/);
2112 }
2113 close(IN);
2114
2115 if ($list[$#list] !~ /^$start/) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002116 fail "SHA1 $start not found";
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002117 }
2118
2119 # go backwards in the list
2120 @list = reverse @list;
2121
2122 my $save_clean = $noclean;
Steven Rostedt19902072011-06-14 20:46:25 -04002123 my %ignored_warnings;
2124
2125 if (defined($ignore_warnings)) {
2126 foreach my $sha1 (split /\s+/, $ignore_warnings) {
2127 $ignored_warnings{$sha1} = 1;
2128 }
2129 }
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002130
2131 $in_patchcheck = 1;
2132 foreach my $item (@list) {
2133 my $sha1 = $item;
2134 $sha1 =~ s/^([[:xdigit:]]+).*/$1/;
2135
2136 doprint "\nProcessing commit $item\n\n";
2137
2138 run_command "git checkout $sha1" or
2139 die "Failed to checkout $sha1";
2140
2141 # only clean on the first and last patch
2142 if ($item eq $list[0] ||
2143 $item eq $list[$#list]) {
2144 $noclean = $save_clean;
2145 } else {
2146 $noclean = 1;
2147 }
2148
2149 if (defined($minconfig)) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002150 build "useconfig:$minconfig" or return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002151 } else {
2152 # ?? no config to use?
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002153 build "oldconfig" or return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002154 }
2155
Steven Rostedt19902072011-06-14 20:46:25 -04002156
2157 if (!defined($ignored_warnings{$sha1})) {
2158 check_buildlog $sha1 or return 0;
2159 }
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002160
2161 next if ($type eq "build");
2162
Steven Rostedt7faafbd2010-11-02 14:58:22 -04002163 my $failed = 0;
2164
Steven Rostedtddf607e2011-06-14 20:49:13 -04002165 start_monitor_and_boot or $failed = 1;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04002166
2167 if (!$failed && $type ne "boot"){
2168 do_run_test or $failed = 1;
2169 }
2170 end_monitor;
2171 return 0 if ($failed);
2172
Steven Rostedt27d934b2011-05-20 09:18:18 -04002173 patchcheck_reboot;
2174
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002175 }
2176 $in_patchcheck = 0;
2177 success $i;
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002178
2179 return 1;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002180}
2181
Steven Rostedtb9066f62011-07-15 21:25:24 -04002182my %depends;
2183my $iflevel = 0;
2184my @ifdeps;
2185
2186# prevent recursion
2187my %read_kconfigs;
2188
2189# taken from streamline_config.pl
2190sub read_kconfig {
2191 my ($kconfig) = @_;
2192
2193 my $state = "NONE";
2194 my $config;
2195 my @kconfigs;
2196
2197 my $cont = 0;
2198 my $line;
2199
2200
2201 if (! -f $kconfig) {
2202 doprint "file $kconfig does not exist, skipping\n";
2203 return;
2204 }
2205
2206 open(KIN, "$kconfig")
2207 or die "Can't open $kconfig";
2208 while (<KIN>) {
2209 chomp;
2210
2211 # Make sure that lines ending with \ continue
2212 if ($cont) {
2213 $_ = $line . " " . $_;
2214 }
2215
2216 if (s/\\$//) {
2217 $cont = 1;
2218 $line = $_;
2219 next;
2220 }
2221
2222 $cont = 0;
2223
2224 # collect any Kconfig sources
2225 if (/^source\s*"(.*)"/) {
2226 $kconfigs[$#kconfigs+1] = $1;
2227 }
2228
2229 # configs found
2230 if (/^\s*(menu)?config\s+(\S+)\s*$/) {
2231 $state = "NEW";
2232 $config = $2;
2233
2234 for (my $i = 0; $i < $iflevel; $i++) {
2235 if ($i) {
2236 $depends{$config} .= " " . $ifdeps[$i];
2237 } else {
2238 $depends{$config} = $ifdeps[$i];
2239 }
2240 $state = "DEP";
2241 }
2242
2243 # collect the depends for the config
2244 } elsif ($state eq "NEW" && /^\s*depends\s+on\s+(.*)$/) {
2245
2246 if (defined($depends{$1})) {
2247 $depends{$config} .= " " . $1;
2248 } else {
2249 $depends{$config} = $1;
2250 }
2251
2252 # Get the configs that select this config
2253 } elsif ($state ne "NONE" && /^\s*select\s+(\S+)/) {
2254 if (defined($depends{$1})) {
2255 $depends{$1} .= " " . $config;
2256 } else {
2257 $depends{$1} = $config;
2258 }
2259
2260 # Check for if statements
2261 } elsif (/^if\s+(.*\S)\s*$/) {
2262 my $deps = $1;
2263 # remove beginning and ending non text
2264 $deps =~ s/^[^a-zA-Z0-9_]*//;
2265 $deps =~ s/[^a-zA-Z0-9_]*$//;
2266
2267 my @deps = split /[^a-zA-Z0-9_]+/, $deps;
2268
2269 $ifdeps[$iflevel++] = join ':', @deps;
2270
2271 } elsif (/^endif/) {
2272
2273 $iflevel-- if ($iflevel);
2274
2275 # stop on "help"
2276 } elsif (/^\s*help\s*$/) {
2277 $state = "NONE";
2278 }
2279 }
2280 close(KIN);
2281
2282 # read in any configs that were found.
2283 foreach $kconfig (@kconfigs) {
2284 if (!defined($read_kconfigs{$kconfig})) {
2285 $read_kconfigs{$kconfig} = 1;
2286 read_kconfig("$builddir/$kconfig");
2287 }
2288 }
2289}
2290
2291sub read_depends {
2292 # find out which arch this is by the kconfig file
2293 open (IN, $output_config)
2294 or dodie "Failed to read $output_config";
2295 my $arch;
2296 while (<IN>) {
2297 if (m,Linux/(\S+)\s+\S+\s+Kernel Configuration,) {
2298 $arch = $1;
2299 last;
2300 }
2301 }
2302 close IN;
2303
2304 if (!defined($arch)) {
2305 doprint "Could not find arch from config file\n";
2306 doprint "no dependencies used\n";
2307 return;
2308 }
2309
2310 # arch is really the subarch, we need to know
2311 # what directory to look at.
2312 if ($arch eq "i386" || $arch eq "x86_64") {
2313 $arch = "x86";
2314 } elsif ($arch =~ /^tile/) {
2315 $arch = "tile";
2316 }
2317
2318 my $kconfig = "$builddir/arch/$arch/Kconfig";
2319
2320 if (! -f $kconfig && $arch =~ /\d$/) {
2321 my $orig = $arch;
2322 # some subarchs have numbers, truncate them
2323 $arch =~ s/\d*$//;
2324 $kconfig = "$builddir/arch/$arch/Kconfig";
2325 if (! -f $kconfig) {
2326 doprint "No idea what arch dir $orig is for\n";
2327 doprint "no dependencies used\n";
2328 return;
2329 }
2330 }
2331
2332 read_kconfig($kconfig);
2333}
2334
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002335sub read_config_list {
2336 my ($config) = @_;
2337
2338 open (IN, $config)
2339 or dodie "Failed to read $config";
2340
2341 while (<IN>) {
2342 if (/^((CONFIG\S*)=.*)/) {
2343 if (!defined($config_ignore{$2})) {
2344 $config_list{$2} = $1;
2345 }
2346 }
2347 }
2348
2349 close(IN);
2350}
2351
2352sub read_output_config {
2353 my ($config) = @_;
2354
2355 assign_configs \%config_ignore, $config;
2356}
2357
2358sub make_new_config {
2359 my @configs = @_;
2360
2361 open (OUT, ">$output_config")
2362 or dodie "Failed to write $output_config";
2363
2364 foreach my $config (@configs) {
2365 print OUT "$config\n";
2366 }
2367 close OUT;
2368}
2369
Steven Rostedtb9066f62011-07-15 21:25:24 -04002370sub get_depends {
2371 my ($dep) = @_;
2372
2373 my $kconfig = $dep;
2374 $kconfig =~ s/CONFIG_//;
2375
2376 $dep = $depends{"$kconfig"};
2377
2378 # the dep string we have saves the dependencies as they
2379 # were found, including expressions like ! && ||. We
2380 # want to split this out into just an array of configs.
2381
2382 my $valid = "A-Za-z_0-9";
2383
2384 my @configs;
2385
2386 while ($dep =~ /[$valid]/) {
2387
2388 if ($dep =~ /^[^$valid]*([$valid]+)/) {
2389 my $conf = "CONFIG_" . $1;
2390
2391 $configs[$#configs + 1] = $conf;
2392
2393 $dep =~ s/^[^$valid]*[$valid]+//;
2394 } else {
2395 die "this should never happen";
2396 }
2397 }
2398
2399 return @configs;
2400}
2401
2402my %min_configs;
2403my %keep_configs;
Steven Rostedt43d1b652011-07-15 22:01:56 -04002404my %save_configs;
Steven Rostedtb9066f62011-07-15 21:25:24 -04002405my %processed_configs;
2406my %nochange_config;
2407
2408sub test_this_config {
2409 my ($config) = @_;
2410
2411 my $found;
2412
2413 # if we already processed this config, skip it
2414 if (defined($processed_configs{$config})) {
2415 return undef;
2416 }
2417 $processed_configs{$config} = 1;
2418
2419 # if this config failed during this round, skip it
2420 if (defined($nochange_config{$config})) {
2421 return undef;
2422 }
2423
2424 my $kconfig = $config;
2425 $kconfig =~ s/CONFIG_//;
2426
2427 # Test dependencies first
2428 if (defined($depends{"$kconfig"})) {
2429 my @parents = get_depends $config;
2430 foreach my $parent (@parents) {
2431 # if the parent is in the min config, check it first
2432 next if (!defined($min_configs{$parent}));
2433 $found = test_this_config($parent);
2434 if (defined($found)) {
2435 return $found;
2436 }
2437 }
2438 }
2439
2440 # Remove this config from the list of configs
2441 # do a make oldnoconfig and then read the resulting
2442 # .config to make sure it is missing the config that
2443 # we had before
2444 my %configs = %min_configs;
2445 delete $configs{$config};
2446 make_new_config ((values %configs), (values %keep_configs));
2447 make_oldconfig;
2448 undef %configs;
2449 assign_configs \%configs, $output_config;
2450
2451 return $config if (!defined($configs{$config}));
2452
2453 doprint "disabling config $config did not change .config\n";
2454
2455 $nochange_config{$config} = 1;
2456
2457 return undef;
2458}
2459
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002460sub make_min_config {
2461 my ($i) = @_;
2462
2463 if (!defined($output_minconfig)) {
2464 fail "OUTPUT_MIN_CONFIG not defined" and return;
2465 }
Steven Rostedt35ce5952011-07-15 21:57:25 -04002466
2467 # If output_minconfig exists, and the start_minconfig
2468 # came from min_config, than ask if we should use
2469 # that instead.
2470 if (-f $output_minconfig && !$start_minconfig_defined) {
2471 print "$output_minconfig exists\n";
2472 if (read_yn " Use it as minconfig?") {
2473 $start_minconfig = $output_minconfig;
2474 }
2475 }
2476
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002477 if (!defined($start_minconfig)) {
2478 fail "START_MIN_CONFIG or MIN_CONFIG not defined" and return;
2479 }
2480
Steven Rostedt35ce5952011-07-15 21:57:25 -04002481 my $temp_config = "$tmpdir/temp_config";
2482
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002483 # First things first. We build an allnoconfig to find
2484 # out what the defaults are that we can't touch.
2485 # Some are selections, but we really can't handle selections.
2486
2487 my $save_minconfig = $minconfig;
2488 undef $minconfig;
2489
2490 run_command "$make allnoconfig" or return 0;
2491
Steven Rostedtb9066f62011-07-15 21:25:24 -04002492 read_depends;
2493
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002494 process_config_ignore $output_config;
Steven Rostedtb9066f62011-07-15 21:25:24 -04002495
Steven Rostedt43d1b652011-07-15 22:01:56 -04002496 undef %save_configs;
Steven Rostedtb9066f62011-07-15 21:25:24 -04002497 undef %min_configs;
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002498
2499 if (defined($ignore_config)) {
2500 # make sure the file exists
2501 `touch $ignore_config`;
Steven Rostedt43d1b652011-07-15 22:01:56 -04002502 assign_configs \%save_configs, $ignore_config;
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002503 }
2504
Steven Rostedt43d1b652011-07-15 22:01:56 -04002505 %keep_configs = %save_configs;
2506
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002507 doprint "Load initial configs from $start_minconfig\n";
2508
2509 # Look at the current min configs, and save off all the
2510 # ones that were set via the allnoconfig
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002511 assign_configs \%min_configs, $start_minconfig;
2512
2513 my @config_keys = keys %min_configs;
2514
2515 # Remove anything that was set by the make allnoconfig
2516 # we shouldn't need them as they get set for us anyway.
2517 foreach my $config (@config_keys) {
2518 # Remove anything in the ignore_config
2519 if (defined($keep_configs{$config})) {
2520 my $file = $ignore_config;
2521 $file =~ s,.*/(.*?)$,$1,;
2522 doprint "$config set by $file ... ignored\n";
2523 delete $min_configs{$config};
2524 next;
2525 }
2526 # But make sure the settings are the same. If a min config
2527 # sets a selection, we do not want to get rid of it if
2528 # it is not the same as what we have. Just move it into
2529 # the keep configs.
2530 if (defined($config_ignore{$config})) {
2531 if ($config_ignore{$config} ne $min_configs{$config}) {
2532 doprint "$config is in allnoconfig as '$config_ignore{$config}'";
2533 doprint " but it is '$min_configs{$config}' in minconfig .. keeping\n";
2534 $keep_configs{$config} = $min_configs{$config};
2535 } else {
2536 doprint "$config set by allnoconfig ... ignored\n";
2537 }
2538 delete $min_configs{$config};
2539 }
2540 }
2541
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002542 my $done = 0;
Steven Rostedtb9066f62011-07-15 21:25:24 -04002543 my $take_two = 0;
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002544
2545 while (!$done) {
2546
2547 my $config;
2548 my $found;
2549
2550 # Now disable each config one by one and do a make oldconfig
2551 # till we find a config that changes our list.
2552
2553 # Put configs that did not modify the config at the end.
2554 my @test_configs = keys %min_configs;
2555 my $reset = 1;
2556 for (my $i = 0; $i < $#test_configs; $i++) {
2557 if (!defined($nochange_config{$test_configs[0]})) {
2558 $reset = 0;
2559 last;
2560 }
2561 # This config didn't change the .config last time.
2562 # Place it at the end
2563 my $config = shift @test_configs;
2564 push @test_configs, $config;
2565 }
2566
2567 # if every test config has failed to modify the .config file
2568 # in the past, then reset and start over.
2569 if ($reset) {
2570 undef %nochange_config;
2571 }
2572
Steven Rostedtb9066f62011-07-15 21:25:24 -04002573 undef %processed_configs;
2574
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002575 foreach my $config (@test_configs) {
2576
Steven Rostedtb9066f62011-07-15 21:25:24 -04002577 $found = test_this_config $config;
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002578
Steven Rostedtb9066f62011-07-15 21:25:24 -04002579 last if (defined($found));
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002580
2581 # oh well, try another config
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002582 }
2583
2584 if (!defined($found)) {
Steven Rostedtb9066f62011-07-15 21:25:24 -04002585 # we could have failed due to the nochange_config hash
2586 # reset and try again
2587 if (!$take_two) {
2588 undef %nochange_config;
2589 $take_two = 1;
2590 next;
2591 }
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002592 doprint "No more configs found that we can disable\n";
2593 $done = 1;
2594 last;
2595 }
Steven Rostedtb9066f62011-07-15 21:25:24 -04002596 $take_two = 0;
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002597
2598 $config = $found;
2599
2600 doprint "Test with $config disabled\n";
2601
2602 # set in_bisect to keep build and monitor from dieing
2603 $in_bisect = 1;
2604
2605 my $failed = 0;
2606 build "oldconfig";
2607 start_monitor_and_boot or $failed = 1;
2608 end_monitor;
2609
2610 $in_bisect = 0;
2611
2612 if ($failed) {
Steven Rostedtb9066f62011-07-15 21:25:24 -04002613 doprint "$min_configs{$config} is needed to boot the box... keeping\n";
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002614 # this config is needed, add it to the ignore list.
2615 $keep_configs{$config} = $min_configs{$config};
Steven Rostedt43d1b652011-07-15 22:01:56 -04002616 $save_configs{$config} = $min_configs{$config};
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002617 delete $min_configs{$config};
Steven Rostedt35ce5952011-07-15 21:57:25 -04002618
2619 # update new ignore configs
2620 if (defined($ignore_config)) {
2621 open (OUT, ">$temp_config")
2622 or die "Can't write to $temp_config";
Steven Rostedt43d1b652011-07-15 22:01:56 -04002623 foreach my $config (keys %save_configs) {
2624 print OUT "$save_configs{$config}\n";
Steven Rostedt35ce5952011-07-15 21:57:25 -04002625 }
2626 close OUT;
2627 run_command "mv $temp_config $ignore_config" or
2628 dodie "failed to copy update to $ignore_config";
2629 }
2630
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002631 } else {
2632 # We booted without this config, remove it from the minconfigs.
2633 doprint "$config is not needed, disabling\n";
2634
2635 delete $min_configs{$config};
2636
2637 # Also disable anything that is not enabled in this config
2638 my %configs;
2639 assign_configs \%configs, $output_config;
2640 my @config_keys = keys %min_configs;
2641 foreach my $config (@config_keys) {
2642 if (!defined($configs{$config})) {
2643 doprint "$config is not set, disabling\n";
2644 delete $min_configs{$config};
2645 }
2646 }
2647
2648 # Save off all the current mandidory configs
Steven Rostedt35ce5952011-07-15 21:57:25 -04002649 open (OUT, ">$temp_config")
2650 or die "Can't write to $temp_config";
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002651 foreach my $config (keys %keep_configs) {
2652 print OUT "$keep_configs{$config}\n";
2653 }
2654 foreach my $config (keys %min_configs) {
2655 print OUT "$min_configs{$config}\n";
2656 }
2657 close OUT;
Steven Rostedt35ce5952011-07-15 21:57:25 -04002658
2659 run_command "mv $temp_config $output_minconfig" or
2660 dodie "failed to copy update to $output_minconfig";
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002661 }
2662
2663 doprint "Reboot and wait $sleep_time seconds\n";
Andrew Jones2728be42011-08-12 15:32:05 +02002664 reboot $sleep_time;
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002665 }
2666
2667 success $i;
2668 return 1;
2669}
2670
Steven Rostedt8d1491b2010-11-18 15:39:48 -05002671$#ARGV < 1 or die "ktest.pl version: $VERSION\n usage: ktest.pl config-file\n";
Steven Rostedt2545eb62010-11-02 15:01:32 -04002672
Steven Rostedt8d1491b2010-11-18 15:39:48 -05002673if ($#ARGV == 0) {
2674 $ktest_config = $ARGV[0];
2675 if (! -f $ktest_config) {
2676 print "$ktest_config does not exist.\n";
Steven Rostedt35ce5952011-07-15 21:57:25 -04002677 if (!read_yn "Create it?") {
Steven Rostedt8d1491b2010-11-18 15:39:48 -05002678 exit 0;
2679 }
2680 }
2681} else {
2682 $ktest_config = "ktest.conf";
2683}
2684
2685if (! -f $ktest_config) {
2686 open(OUT, ">$ktest_config") or die "Can not create $ktest_config";
2687 print OUT << "EOF"
2688# Generated by ktest.pl
2689#
2690# Define each test with TEST_START
2691# The config options below it will override the defaults
2692TEST_START
2693
2694DEFAULTS
2695EOF
2696;
2697 close(OUT);
2698}
2699read_config $ktest_config;
2700
Steven Rostedt23715c3c2011-06-13 11:03:34 -04002701if (defined($opt{"LOG_FILE"})) {
2702 $opt{"LOG_FILE"} = eval_option($opt{"LOG_FILE"}, -1);
2703}
2704
Steven Rostedt8d1491b2010-11-18 15:39:48 -05002705# Append any configs entered in manually to the config file.
2706my @new_configs = keys %entered_configs;
2707if ($#new_configs >= 0) {
2708 print "\nAppending entered in configs to $ktest_config\n";
2709 open(OUT, ">>$ktest_config") or die "Can not append to $ktest_config";
2710 foreach my $config (@new_configs) {
2711 print OUT "$config = $entered_configs{$config}\n";
2712 $opt{$config} = $entered_configs{$config};
2713 }
2714}
Steven Rostedt2545eb62010-11-02 15:01:32 -04002715
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002716if ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) {
2717 unlink $opt{"LOG_FILE"};
2718}
Steven Rostedt2545eb62010-11-02 15:01:32 -04002719
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002720doprint "\n\nSTARTING AUTOMATED TESTS\n\n";
2721
Steven Rostedta57419b2010-11-02 15:13:54 -04002722for (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) {
2723
2724 if (!$i) {
2725 doprint "DEFAULT OPTIONS:\n";
2726 } else {
2727 doprint "\nTEST $i OPTIONS";
2728 if (defined($repeat_tests{$i})) {
2729 $repeat = $repeat_tests{$i};
2730 doprint " ITERATE $repeat";
2731 }
2732 doprint "\n";
2733 }
2734
2735 foreach my $option (sort keys %opt) {
2736
2737 if ($option =~ /\[(\d+)\]$/) {
2738 next if ($i != $1);
2739 } else {
2740 next if ($i);
2741 }
2742
2743 doprint "$option = $opt{$option}\n";
2744 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002745}
Steven Rostedt2545eb62010-11-02 15:01:32 -04002746
Steven Rostedt2a625122011-05-20 15:48:59 -04002747sub __set_test_option {
Steven Rostedt5a391fb2010-11-02 14:57:43 -04002748 my ($name, $i) = @_;
2749
2750 my $option = "$name\[$i\]";
2751
2752 if (defined($opt{$option})) {
2753 return $opt{$option};
2754 }
2755
Steven Rostedta57419b2010-11-02 15:13:54 -04002756 foreach my $test (keys %repeat_tests) {
2757 if ($i >= $test &&
2758 $i < $test + $repeat_tests{$test}) {
2759 $option = "$name\[$test\]";
2760 if (defined($opt{$option})) {
2761 return $opt{$option};
2762 }
2763 }
2764 }
2765
Steven Rostedt5a391fb2010-11-02 14:57:43 -04002766 if (defined($opt{$name})) {
2767 return $opt{$name};
2768 }
2769
2770 return undef;
2771}
2772
Steven Rostedt2a625122011-05-20 15:48:59 -04002773sub set_test_option {
2774 my ($name, $i) = @_;
2775
2776 my $option = __set_test_option($name, $i);
2777 return $option if (!defined($option));
2778
Steven Rostedt23715c3c2011-06-13 11:03:34 -04002779 return eval_option($option, $i);
Steven Rostedt2a625122011-05-20 15:48:59 -04002780}
2781
Steven Rostedt2545eb62010-11-02 15:01:32 -04002782# First we need to do is the builds
Steven Rostedta75fece2010-11-02 14:58:27 -04002783for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
Steven Rostedt2545eb62010-11-02 15:01:32 -04002784
Steven Rostedt576f6272010-11-02 14:58:38 -04002785 $iteration = $i;
2786
Steven Rostedta75fece2010-11-02 14:58:27 -04002787 my $makecmd = set_test_option("MAKE_CMD", $i);
2788
2789 $machine = set_test_option("MACHINE", $i);
Steven Rostedte48c5292010-11-02 14:35:37 -04002790 $ssh_user = set_test_option("SSH_USER", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002791 $tmpdir = set_test_option("TMP_DIR", $i);
2792 $outputdir = set_test_option("OUTPUT_DIR", $i);
2793 $builddir = set_test_option("BUILD_DIR", $i);
2794 $test_type = set_test_option("TEST_TYPE", $i);
2795 $build_type = set_test_option("BUILD_TYPE", $i);
2796 $build_options = set_test_option("BUILD_OPTIONS", $i);
Steven Rostedt0bd6c1a2011-06-14 20:39:31 -04002797 $pre_build = set_test_option("PRE_BUILD", $i);
2798 $post_build = set_test_option("POST_BUILD", $i);
2799 $pre_build_die = set_test_option("PRE_BUILD_DIE", $i);
2800 $post_build_die = set_test_option("POST_BUILD_DIE", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002801 $power_cycle = set_test_option("POWER_CYCLE", $i);
Steven Rostedte48c5292010-11-02 14:35:37 -04002802 $reboot = set_test_option("REBOOT", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002803 $noclean = set_test_option("BUILD_NOCLEAN", $i);
2804 $minconfig = set_test_option("MIN_CONFIG", $i);
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002805 $output_minconfig = set_test_option("OUTPUT_MIN_CONFIG", $i);
2806 $start_minconfig = set_test_option("START_MIN_CONFIG", $i);
2807 $ignore_config = set_test_option("IGNORE_CONFIG", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002808 $run_test = set_test_option("TEST", $i);
2809 $addconfig = set_test_option("ADD_CONFIG", $i);
2810 $reboot_type = set_test_option("REBOOT_TYPE", $i);
2811 $grub_menu = set_test_option("GRUB_MENU", $i);
Steven Rostedt8b37ca82010-11-02 14:58:33 -04002812 $post_install = set_test_option("POST_INSTALL", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002813 $reboot_script = set_test_option("REBOOT_SCRIPT", $i);
2814 $reboot_on_error = set_test_option("REBOOT_ON_ERROR", $i);
2815 $poweroff_on_error = set_test_option("POWEROFF_ON_ERROR", $i);
2816 $die_on_failure = set_test_option("DIE_ON_FAILURE", $i);
2817 $power_off = set_test_option("POWER_OFF", $i);
Steven Rostedt576f6272010-11-02 14:58:38 -04002818 $powercycle_after_reboot = set_test_option("POWERCYCLE_AFTER_REBOOT", $i);
2819 $poweroff_after_halt = set_test_option("POWEROFF_AFTER_HALT", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002820 $sleep_time = set_test_option("SLEEP_TIME", $i);
2821 $bisect_sleep_time = set_test_option("BISECT_SLEEP_TIME", $i);
Steven Rostedt27d934b2011-05-20 09:18:18 -04002822 $patchcheck_sleep_time = set_test_option("PATCHCHECK_SLEEP_TIME", $i);
Steven Rostedt19902072011-06-14 20:46:25 -04002823 $ignore_warnings = set_test_option("IGNORE_WARNINGS", $i);
Steven Rostedtc960bb92011-03-08 09:22:39 -05002824 $bisect_manual = set_test_option("BISECT_MANUAL", $i);
Steven Rostedtc23dca72011-03-08 09:26:31 -05002825 $bisect_skip = set_test_option("BISECT_SKIP", $i);
Steven Rostedt30f75da2011-06-13 10:35:35 -04002826 $config_bisect_good = set_test_option("CONFIG_BISECT_GOOD", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002827 $store_failures = set_test_option("STORE_FAILURES", $i);
Steven Rostedt9064af52011-06-13 10:38:48 -04002828 $test_name = set_test_option("TEST_NAME", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002829 $timeout = set_test_option("TIMEOUT", $i);
2830 $booted_timeout = set_test_option("BOOTED_TIMEOUT", $i);
2831 $console = set_test_option("CONSOLE", $i);
Steven Rostedtf1a5b962011-06-13 10:30:00 -04002832 $detect_triplefault = set_test_option("DETECT_TRIPLE_FAULT", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002833 $success_line = set_test_option("SUCCESS_LINE", $i);
Steven Rostedt1c8a6172010-11-09 12:55:40 -05002834 $stop_after_success = set_test_option("STOP_AFTER_SUCCESS", $i);
2835 $stop_after_failure = set_test_option("STOP_AFTER_FAILURE", $i);
Steven Rostedt2d01b262011-03-08 09:47:54 -05002836 $stop_test_after = set_test_option("STOP_TEST_AFTER", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002837 $build_target = set_test_option("BUILD_TARGET", $i);
Steven Rostedte48c5292010-11-02 14:35:37 -04002838 $ssh_exec = set_test_option("SSH_EXEC", $i);
2839 $scp_to_target = set_test_option("SCP_TO_TARGET", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002840 $target_image = set_test_option("TARGET_IMAGE", $i);
2841 $localversion = set_test_option("LOCALVERSION", $i);
2842
Steven Rostedt35ce5952011-07-15 21:57:25 -04002843 $start_minconfig_defined = 1;
2844
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002845 if (!defined($start_minconfig)) {
Steven Rostedt35ce5952011-07-15 21:57:25 -04002846 $start_minconfig_defined = 0;
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002847 $start_minconfig = $minconfig;
2848 }
2849
Steven Rostedta75fece2010-11-02 14:58:27 -04002850 chdir $builddir || die "can't change directory to $builddir";
2851
Andrew Jonesa908a662011-08-12 15:32:03 +02002852 foreach my $dir ($tmpdir, $outputdir) {
2853 if (!-d $dir) {
2854 mkpath($dir) or
2855 die "can't create $dir";
2856 }
Steven Rostedta75fece2010-11-02 14:58:27 -04002857 }
2858
Steven Rostedte48c5292010-11-02 14:35:37 -04002859 $ENV{"SSH_USER"} = $ssh_user;
2860 $ENV{"MACHINE"} = $machine;
2861
Steven Rostedta75fece2010-11-02 14:58:27 -04002862 $target = "$ssh_user\@$machine";
2863
2864 $buildlog = "$tmpdir/buildlog-$machine";
2865 $dmesg = "$tmpdir/dmesg-$machine";
2866 $make = "$makecmd O=$outputdir";
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05002867 $output_config = "$outputdir/.config";
Steven Rostedta75fece2010-11-02 14:58:27 -04002868
2869 if ($reboot_type eq "grub") {
Steven Rostedt576f6272010-11-02 14:58:38 -04002870 dodie "GRUB_MENU not defined" if (!defined($grub_menu));
Steven Rostedta75fece2010-11-02 14:58:27 -04002871 } elsif (!defined($reboot_script)) {
Steven Rostedt576f6272010-11-02 14:58:38 -04002872 dodie "REBOOT_SCRIPT not defined"
Steven Rostedta75fece2010-11-02 14:58:27 -04002873 }
2874
2875 my $run_type = $build_type;
2876 if ($test_type eq "patchcheck") {
2877 $run_type = $opt{"PATCHCHECK_TYPE[$i]"};
2878 } elsif ($test_type eq "bisect") {
2879 $run_type = $opt{"BISECT_TYPE[$i]"};
Steven Rostedt0a05c762010-11-08 11:14:10 -05002880 } elsif ($test_type eq "config_bisect") {
2881 $run_type = $opt{"CONFIG_BISECT_TYPE[$i]"};
Steven Rostedta75fece2010-11-02 14:58:27 -04002882 }
2883
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002884 if ($test_type eq "make_min_config") {
2885 $run_type = "";
2886 }
2887
Steven Rostedta75fece2010-11-02 14:58:27 -04002888 # mistake in config file?
2889 if (!defined($run_type)) {
2890 $run_type = "ERROR";
2891 }
Steven Rostedt2545eb62010-11-02 15:01:32 -04002892
2893 doprint "\n\n";
Steven Rostedta75fece2010-11-02 14:58:27 -04002894 doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type\n\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -04002895
2896 unlink $dmesg;
2897 unlink $buildlog;
Steven Rostedt2545eb62010-11-02 15:01:32 -04002898
Steven Rostedt250bae82011-07-15 22:05:59 -04002899 if (defined($addconfig)) {
2900 my $min = $minconfig;
2901 if (!defined($minconfig)) {
2902 $min = "";
2903 }
2904 run_command "cat $addconfig $min > $tmpdir/add_config" or
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002905 dodie "Failed to create temp config";
Steven Rostedt9be2e6b2010-11-09 12:20:21 -05002906 $minconfig = "$tmpdir/add_config";
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002907 }
2908
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002909 my $checkout = $opt{"CHECKOUT[$i]"};
2910 if (defined($checkout)) {
2911 run_command "git checkout $checkout" or
2912 die "failed to checkout $checkout";
2913 }
2914
Steven Rostedta75fece2010-11-02 14:58:27 -04002915 if ($test_type eq "bisect") {
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04002916 bisect $i;
2917 next;
Steven Rostedt0a05c762010-11-08 11:14:10 -05002918 } elsif ($test_type eq "config_bisect") {
2919 config_bisect $i;
2920 next;
Steven Rostedta75fece2010-11-02 14:58:27 -04002921 } elsif ($test_type eq "patchcheck") {
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002922 patchcheck $i;
2923 next;
Steven Rostedt4c4ab122011-07-15 21:16:17 -04002924 } elsif ($test_type eq "make_min_config") {
2925 make_min_config $i;
2926 next;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04002927 }
2928
Steven Rostedt7faafbd2010-11-02 14:58:22 -04002929 if ($build_type ne "nobuild") {
2930 build $build_type or next;
Steven Rostedt2545eb62010-11-02 15:01:32 -04002931 }
2932
Steven Rostedtcd8e3682011-08-18 16:35:44 -04002933 if ($test_type eq "install") {
2934 get_version;
2935 install;
2936 success $i;
2937 next;
2938 }
2939
Steven Rostedta75fece2010-11-02 14:58:27 -04002940 if ($test_type ne "build") {
Steven Rostedta75fece2010-11-02 14:58:27 -04002941 my $failed = 0;
Steven Rostedtddf607e2011-06-14 20:49:13 -04002942 start_monitor_and_boot or $failed = 1;
Steven Rostedta75fece2010-11-02 14:58:27 -04002943
2944 if (!$failed && $test_type ne "boot" && defined($run_test)) {
2945 do_run_test or $failed = 1;
2946 }
2947 end_monitor;
2948 next if ($failed);
Steven Rostedt5a391fb2010-11-02 14:57:43 -04002949 }
2950
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04002951 success $i;
Steven Rostedt2545eb62010-11-02 15:01:32 -04002952}
2953
Steven Rostedt5c42fc52010-11-02 14:57:01 -04002954if ($opt{"POWEROFF_ON_SUCCESS"}) {
Steven Rostedt75c3fda72010-11-02 14:57:21 -04002955 halt;
Steven Rostedt576f6272010-11-02 14:58:38 -04002956} elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot) {
Steven Rostedt75c3fda72010-11-02 14:57:21 -04002957 reboot;
Steven Rostedt5c42fc52010-11-02 14:57:01 -04002958}
Steven Rostedt75c3fda72010-11-02 14:57:21 -04002959
Steven Rostedte48c5292010-11-02 14:35:37 -04002960doprint "\n $successes of $opt{NUM_TESTS} tests were successful\n\n";
2961
Steven Rostedt2545eb62010-11-02 15:01:32 -04002962exit 0;