blob: 6166f3a0f2ea53e40df99eeb800f4592a9bb4026 [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 Rostedt2b7d9b22010-11-02 14:58:15 -040089my $addconfig;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -040090my $in_bisect = 0;
91my $bisect_bad = "";
Steven Rostedtd6ce2a02010-11-02 14:58:05 -040092my $reverse_bisect;
Steven Rostedtc960bb92011-03-08 09:22:39 -050093my $bisect_manual;
Steven Rostedtc23dca72011-03-08 09:26:31 -050094my $bisect_skip;
Steven Rostedt30f75da2011-06-13 10:35:35 -040095my $config_bisect_good;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -040096my $in_patchcheck = 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -040097my $run_test;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -040098my $redirect;
Steven Rostedt7faafbd2010-11-02 14:58:22 -040099my $buildlog;
100my $dmesg;
101my $monitor_fp;
102my $monitor_pid;
103my $monitor_cnt = 0;
Steven Rostedta75fece2010-11-02 14:58:27 -0400104my $sleep_time;
105my $bisect_sleep_time;
Steven Rostedt27d934b2011-05-20 09:18:18 -0400106my $patchcheck_sleep_time;
Steven Rostedt19902072011-06-14 20:46:25 -0400107my $ignore_warnings;
Steven Rostedta75fece2010-11-02 14:58:27 -0400108my $store_failures;
Steven Rostedt9064af52011-06-13 10:38:48 -0400109my $test_name;
Steven Rostedta75fece2010-11-02 14:58:27 -0400110my $timeout;
111my $booted_timeout;
Steven Rostedtf1a5b962011-06-13 10:30:00 -0400112my $detect_triplefault;
Steven Rostedta75fece2010-11-02 14:58:27 -0400113my $console;
114my $success_line;
Steven Rostedt1c8a6172010-11-09 12:55:40 -0500115my $stop_after_success;
116my $stop_after_failure;
Steven Rostedt2d01b262011-03-08 09:47:54 -0500117my $stop_test_after;
Steven Rostedta75fece2010-11-02 14:58:27 -0400118my $build_target;
119my $target_image;
120my $localversion;
Steven Rostedt576f6272010-11-02 14:58:38 -0400121my $iteration = 0;
Steven Rostedte48c5292010-11-02 14:35:37 -0400122my $successes = 0;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400123
Steven Rostedt8d1491b2010-11-18 15:39:48 -0500124my %entered_configs;
125my %config_help;
Steven Rostedt77d942c2011-05-20 13:36:58 -0400126my %variable;
Steven Rostedtfcb3f162011-06-13 10:40:58 -0400127my %force_config;
Steven Rostedt8d1491b2010-11-18 15:39:48 -0500128
129$config_help{"MACHINE"} = << "EOF"
130 The machine hostname that you will test.
131EOF
132 ;
133$config_help{"SSH_USER"} = << "EOF"
134 The box is expected to have ssh on normal bootup, provide the user
135 (most likely root, since you need privileged operations)
136EOF
137 ;
138$config_help{"BUILD_DIR"} = << "EOF"
139 The directory that contains the Linux source code (full path).
140EOF
141 ;
142$config_help{"OUTPUT_DIR"} = << "EOF"
143 The directory that the objects will be built (full path).
144 (can not be same as BUILD_DIR)
145EOF
146 ;
147$config_help{"BUILD_TARGET"} = << "EOF"
148 The location of the compiled file to copy to the target.
149 (relative to OUTPUT_DIR)
150EOF
151 ;
152$config_help{"TARGET_IMAGE"} = << "EOF"
153 The place to put your image on the test machine.
154EOF
155 ;
156$config_help{"POWER_CYCLE"} = << "EOF"
157 A script or command to reboot the box.
158
159 Here is a digital loggers power switch example
160 POWER_CYCLE = wget --no-proxy -O /dev/null -q --auth-no-challenge 'http://admin:admin\@power/outlet?5=CCL'
161
162 Here is an example to reboot a virtual box on the current host
163 with the name "Guest".
164 POWER_CYCLE = virsh destroy Guest; sleep 5; virsh start Guest
165EOF
166 ;
167$config_help{"CONSOLE"} = << "EOF"
168 The script or command that reads the console
169
170 If you use ttywatch server, something like the following would work.
171CONSOLE = nc -d localhost 3001
172
173 For a virtual machine with guest name "Guest".
174CONSOLE = virsh console Guest
175EOF
176 ;
177$config_help{"LOCALVERSION"} = << "EOF"
178 Required version ending to differentiate the test
179 from other linux builds on the system.
180EOF
181 ;
182$config_help{"REBOOT_TYPE"} = << "EOF"
183 Way to reboot the box to the test kernel.
184 Only valid options so far are "grub" and "script".
185
186 If you specify grub, it will assume grub version 1
187 and will search in /boot/grub/menu.lst for the title \$GRUB_MENU
188 and select that target to reboot to the kernel. If this is not
189 your setup, then specify "script" and have a command or script
190 specified in REBOOT_SCRIPT to boot to the target.
191
192 The entry in /boot/grub/menu.lst must be entered in manually.
193 The test will not modify that file.
194EOF
195 ;
196$config_help{"GRUB_MENU"} = << "EOF"
197 The grub title name for the test kernel to boot
198 (Only mandatory if REBOOT_TYPE = grub)
199
200 Note, ktest.pl will not update the grub menu.lst, you need to
201 manually add an option for the test. ktest.pl will search
202 the grub menu.lst for this option to find what kernel to
203 reboot into.
204
205 For example, if in the /boot/grub/menu.lst the test kernel title has:
206 title Test Kernel
207 kernel vmlinuz-test
208 GRUB_MENU = Test Kernel
209EOF
210 ;
211$config_help{"REBOOT_SCRIPT"} = << "EOF"
212 A script to reboot the target into the test kernel
213 (Only mandatory if REBOOT_TYPE = script)
214EOF
215 ;
216
217
218sub get_ktest_config {
219 my ($config) = @_;
220
221 return if (defined($opt{$config}));
222
223 if (defined($config_help{$config})) {
224 print "\n";
225 print $config_help{$config};
226 }
227
228 for (;;) {
229 print "$config = ";
230 if (defined($default{$config})) {
231 print "\[$default{$config}\] ";
232 }
233 $entered_configs{$config} = <STDIN>;
234 $entered_configs{$config} =~ s/^\s*(.*\S)\s*$/$1/;
235 if ($entered_configs{$config} =~ /^\s*$/) {
236 if ($default{$config}) {
237 $entered_configs{$config} = $default{$config};
238 } else {
239 print "Your answer can not be blank\n";
240 next;
241 }
242 }
243 last;
244 }
245}
246
247sub get_ktest_configs {
248 get_ktest_config("MACHINE");
249 get_ktest_config("SSH_USER");
250 get_ktest_config("BUILD_DIR");
251 get_ktest_config("OUTPUT_DIR");
252 get_ktest_config("BUILD_TARGET");
253 get_ktest_config("TARGET_IMAGE");
254 get_ktest_config("POWER_CYCLE");
255 get_ktest_config("CONSOLE");
256 get_ktest_config("LOCALVERSION");
257
258 my $rtype = $opt{"REBOOT_TYPE"};
259
260 if (!defined($rtype)) {
261 if (!defined($opt{"GRUB_MENU"})) {
262 get_ktest_config("REBOOT_TYPE");
263 $rtype = $entered_configs{"REBOOT_TYPE"};
264 } else {
265 $rtype = "grub";
266 }
267 }
268
269 if ($rtype eq "grub") {
270 get_ktest_config("GRUB_MENU");
271 } else {
272 get_ktest_config("REBOOT_SCRIPT");
273 }
274}
275
Steven Rostedt77d942c2011-05-20 13:36:58 -0400276sub process_variables {
277 my ($value) = @_;
278 my $retval = "";
279
280 # We want to check for '\', and it is just easier
281 # to check the previous characet of '$' and not need
282 # to worry if '$' is the first character. By adding
283 # a space to $value, we can just check [^\\]\$ and
284 # it will still work.
285 $value = " $value";
286
287 while ($value =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
288 my $begin = $1;
289 my $var = $2;
290 my $end = $3;
291 # append beginning of value to retval
292 $retval = "$retval$begin";
293 if (defined($variable{$var})) {
294 $retval = "$retval$variable{$var}";
295 } else {
296 # put back the origin piece.
297 $retval = "$retval\$\{$var\}";
298 }
299 $value = $end;
300 }
301 $retval = "$retval$value";
302
303 # remove the space added in the beginning
304 $retval =~ s/ //;
305
306 return "$retval"
307}
308
Steven Rostedta57419b2010-11-02 15:13:54 -0400309sub set_value {
310 my ($lvalue, $rvalue) = @_;
311
312 if (defined($opt{$lvalue})) {
313 die "Error: Option $lvalue defined more than once!\n";
314 }
Steven Rostedt21a96792010-11-08 16:45:50 -0500315 if ($rvalue =~ /^\s*$/) {
316 delete $opt{$lvalue};
317 } else {
Steven Rostedt77d942c2011-05-20 13:36:58 -0400318 $rvalue = process_variables($rvalue);
Steven Rostedt21a96792010-11-08 16:45:50 -0500319 $opt{$lvalue} = $rvalue;
320 }
Steven Rostedta57419b2010-11-02 15:13:54 -0400321}
322
Steven Rostedt77d942c2011-05-20 13:36:58 -0400323sub set_variable {
324 my ($lvalue, $rvalue) = @_;
325
326 if ($rvalue =~ /^\s*$/) {
327 delete $variable{$lvalue};
328 } else {
329 $rvalue = process_variables($rvalue);
330 $variable{$lvalue} = $rvalue;
331 }
332}
333
Steven Rostedt2545eb62010-11-02 15:01:32 -0400334sub read_config {
335 my ($config) = @_;
336
337 open(IN, $config) || die "can't read file $config";
338
Steven Rostedta57419b2010-11-02 15:13:54 -0400339 my $name = $config;
340 $name =~ s,.*/(.*),$1,;
341
342 my $test_num = 0;
343 my $default = 1;
344 my $repeat = 1;
345 my $num_tests_set = 0;
346 my $skip = 0;
347 my $rest;
Steven Rostedt0df213c2011-06-14 20:51:37 -0400348 my $test_case = 0;
Steven Rostedta57419b2010-11-02 15:13:54 -0400349
Steven Rostedt2545eb62010-11-02 15:01:32 -0400350 while (<IN>) {
351
352 # ignore blank lines and comments
353 next if (/^\s*$/ || /\s*\#/);
354
Steven Rostedta57419b2010-11-02 15:13:54 -0400355 if (/^\s*TEST_START(.*)/) {
356
357 $rest = $1;
358
359 if ($num_tests_set) {
360 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
361 }
362
363 my $old_test_num = $test_num;
Steven Rostedte48c5292010-11-02 14:35:37 -0400364 my $old_repeat = $repeat;
Steven Rostedta57419b2010-11-02 15:13:54 -0400365
366 $test_num += $repeat;
367 $default = 0;
368 $repeat = 1;
369
370 if ($rest =~ /\s+SKIP(.*)/) {
371 $rest = $1;
372 $skip = 1;
373 } else {
Steven Rostedt0df213c2011-06-14 20:51:37 -0400374 $test_case = 1;
Steven Rostedta57419b2010-11-02 15:13:54 -0400375 $skip = 0;
376 }
377
378 if ($rest =~ /\s+ITERATE\s+(\d+)(.*)$/) {
379 $repeat = $1;
380 $rest = $2;
381 $repeat_tests{"$test_num"} = $repeat;
382 }
383
384 if ($rest =~ /\s+SKIP(.*)/) {
385 $rest = $1;
386 $skip = 1;
387 }
388
389 if ($rest !~ /^\s*$/) {
390 die "$name: $.: Gargbage found after TEST_START\n$_";
391 }
392
393 if ($skip) {
394 $test_num = $old_test_num;
Steven Rostedte48c5292010-11-02 14:35:37 -0400395 $repeat = $old_repeat;
Steven Rostedta57419b2010-11-02 15:13:54 -0400396 }
397
398 } elsif (/^\s*DEFAULTS(.*)$/) {
399 $default = 1;
400
401 $rest = $1;
402
403 if ($rest =~ /\s+SKIP(.*)/) {
404 $rest = $1;
405 $skip = 1;
406 } else {
407 $skip = 0;
408 }
409
410 if ($rest !~ /^\s*$/) {
411 die "$name: $.: Gargbage found after DEFAULTS\n$_";
412 }
413
414 } elsif (/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) {
415
416 next if ($skip);
417
Steven Rostedt2545eb62010-11-02 15:01:32 -0400418 my $lvalue = $1;
419 my $rvalue = $2;
420
Steven Rostedta57419b2010-11-02 15:13:54 -0400421 if (!$default &&
422 ($lvalue eq "NUM_TESTS" ||
423 $lvalue eq "LOG_FILE" ||
424 $lvalue eq "CLEAR_LOG")) {
425 die "$name: $.: $lvalue must be set in DEFAULTS section\n";
Steven Rostedta75fece2010-11-02 14:58:27 -0400426 }
Steven Rostedta57419b2010-11-02 15:13:54 -0400427
428 if ($lvalue eq "NUM_TESTS") {
429 if ($test_num) {
430 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
431 }
432 if (!$default) {
433 die "$name: $.: NUM_TESTS must be set in default section\n";
434 }
435 $num_tests_set = 1;
436 }
437
438 if ($default || $lvalue =~ /\[\d+\]$/) {
439 set_value($lvalue, $rvalue);
440 } else {
441 my $val = "$lvalue\[$test_num\]";
442 set_value($val, $rvalue);
443
444 if ($repeat > 1) {
445 $repeats{$val} = $repeat;
446 }
447 }
Steven Rostedt77d942c2011-05-20 13:36:58 -0400448 } elsif (/^\s*([A-Z_\[\]\d]+)\s*:=\s*(.*?)\s*$/) {
449 next if ($skip);
450
451 my $lvalue = $1;
452 my $rvalue = $2;
453
454 # process config variables.
455 # Config variables are only active while reading the
456 # config and can be defined anywhere. They also ignore
457 # TEST_START and DEFAULTS, but are skipped if they are in
458 # on of these sections that have SKIP defined.
459 # The save variable can be
460 # defined multiple times and the new one simply overrides
461 # the prevous one.
462 set_variable($lvalue, $rvalue);
463
Steven Rostedta57419b2010-11-02 15:13:54 -0400464 } else {
465 die "$name: $.: Garbage found in config\n$_";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400466 }
467 }
468
469 close(IN);
Steven Rostedta75fece2010-11-02 14:58:27 -0400470
Steven Rostedta57419b2010-11-02 15:13:54 -0400471 if ($test_num) {
472 $test_num += $repeat - 1;
473 $opt{"NUM_TESTS"} = $test_num;
474 }
475
Steven Rostedt8d1491b2010-11-18 15:39:48 -0500476 # make sure we have all mandatory configs
477 get_ktest_configs;
478
Steven Rostedt0df213c2011-06-14 20:51:37 -0400479 # was a test specified?
480 if (!$test_case) {
481 print "No test case specified.\n";
482 print "What test case would you like to run?\n";
483 my $ans = <STDIN>;
484 chomp $ans;
485 $default{"TEST_TYPE"} = $ans;
486 }
487
Steven Rostedta75fece2010-11-02 14:58:27 -0400488 # set any defaults
489
490 foreach my $default (keys %default) {
491 if (!defined($opt{$default})) {
492 $opt{$default} = $default{$default};
493 }
494 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400495}
496
Steven Rostedt23715c3c2011-06-13 11:03:34 -0400497sub __eval_option {
498 my ($option, $i) = @_;
499
500 # Add space to evaluate the character before $
501 $option = " $option";
502 my $retval = "";
503
504 while ($option =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
505 my $start = $1;
506 my $var = $2;
507 my $end = $3;
508
509 # Append beginning of line
510 $retval = "$retval$start";
511
512 # If the iteration option OPT[$i] exists, then use that.
513 # otherwise see if the default OPT (without [$i]) exists.
514
515 my $o = "$var\[$i\]";
516
517 if (defined($opt{$o})) {
518 $o = $opt{$o};
519 $retval = "$retval$o";
520 } elsif (defined($opt{$var})) {
521 $o = $opt{$var};
522 $retval = "$retval$o";
523 } else {
524 $retval = "$retval\$\{$var\}";
525 }
526
527 $option = $end;
528 }
529
530 $retval = "$retval$option";
531
532 $retval =~ s/^ //;
533
534 return $retval;
535}
536
537sub eval_option {
538 my ($option, $i) = @_;
539
540 my $prev = "";
541
542 # Since an option can evaluate to another option,
543 # keep iterating until we do not evaluate any more
544 # options.
545 my $r = 0;
546 while ($prev ne $option) {
547 # Check for recursive evaluations.
548 # 100 deep should be more than enough.
549 if ($r++ > 100) {
550 die "Over 100 evaluations accurred with $option\n" .
551 "Check for recursive variables\n";
552 }
553 $prev = $option;
554 $option = __eval_option($option, $i);
555 }
556
557 return $option;
558}
559
Steven Rostedtd1e2f222010-11-08 16:39:57 -0500560sub _logit {
Steven Rostedt2545eb62010-11-02 15:01:32 -0400561 if (defined($opt{"LOG_FILE"})) {
562 open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}";
563 print OUT @_;
564 close(OUT);
565 }
566}
567
Steven Rostedtd1e2f222010-11-08 16:39:57 -0500568sub logit {
569 if (defined($opt{"LOG_FILE"})) {
570 _logit @_;
571 } else {
572 print @_;
573 }
574}
575
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400576sub doprint {
577 print @_;
Steven Rostedtd1e2f222010-11-08 16:39:57 -0500578 _logit @_;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400579}
580
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400581sub run_command;
582
583sub reboot {
584 # try to reboot normally
Steven Rostedte48c5292010-11-02 14:35:37 -0400585 if (run_command $reboot) {
Steven Rostedt576f6272010-11-02 14:58:38 -0400586 if (defined($powercycle_after_reboot)) {
587 sleep $powercycle_after_reboot;
588 run_command "$power_cycle";
589 }
590 } else {
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400591 # nope? power cycle it.
Steven Rostedta75fece2010-11-02 14:58:27 -0400592 run_command "$power_cycle";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400593 }
594}
595
Steven Rostedt576f6272010-11-02 14:58:38 -0400596sub do_not_reboot {
597 my $i = $iteration;
598
599 return $test_type eq "build" ||
600 ($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") ||
601 ($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build");
602}
603
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400604sub dodie {
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400605 doprint "CRITICAL FAILURE... ", @_, "\n";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400606
Steven Rostedt576f6272010-11-02 14:58:38 -0400607 my $i = $iteration;
608
609 if ($reboot_on_error && !do_not_reboot) {
610
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400611 doprint "REBOOTING\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400612 reboot;
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400613
Steven Rostedta75fece2010-11-02 14:58:27 -0400614 } elsif ($poweroff_on_error && defined($power_off)) {
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400615 doprint "POWERING OFF\n";
Steven Rostedta75fece2010-11-02 14:58:27 -0400616 `$power_off`;
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400617 }
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400618
Steven Rostedtf80802c2011-03-07 13:18:47 -0500619 if (defined($opt{"LOG_FILE"})) {
620 print " See $opt{LOG_FILE} for more info.\n";
621 }
622
Steven Rostedt576f6272010-11-02 14:58:38 -0400623 die @_, "\n";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400624}
625
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400626sub open_console {
627 my ($fp) = @_;
628
629 my $flags;
630
Steven Rostedta75fece2010-11-02 14:58:27 -0400631 my $pid = open($fp, "$console|") or
632 dodie "Can't open console $console";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400633
634 $flags = fcntl($fp, F_GETFL, 0) or
Steven Rostedt576f6272010-11-02 14:58:38 -0400635 dodie "Can't get flags for the socket: $!";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400636 $flags = fcntl($fp, F_SETFL, $flags | O_NONBLOCK) or
Steven Rostedt576f6272010-11-02 14:58:38 -0400637 dodie "Can't set flags for the socket: $!";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400638
639 return $pid;
640}
641
642sub close_console {
643 my ($fp, $pid) = @_;
644
645 doprint "kill child process $pid\n";
646 kill 2, $pid;
647
648 print "closing!\n";
649 close($fp);
650}
651
652sub start_monitor {
653 if ($monitor_cnt++) {
654 return;
655 }
656 $monitor_fp = \*MONFD;
657 $monitor_pid = open_console $monitor_fp;
Steven Rostedta75fece2010-11-02 14:58:27 -0400658
659 return;
660
661 open(MONFD, "Stop perl from warning about single use of MONFD");
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400662}
663
664sub end_monitor {
665 if (--$monitor_cnt) {
666 return;
667 }
668 close_console($monitor_fp, $monitor_pid);
669}
670
671sub wait_for_monitor {
672 my ($time) = @_;
673 my $line;
674
Steven Rostedta75fece2010-11-02 14:58:27 -0400675 doprint "** Wait for monitor to settle down **\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400676
677 # read the monitor and wait for the system to calm down
678 do {
679 $line = wait_for_input($monitor_fp, $time);
Steven Rostedta75fece2010-11-02 14:58:27 -0400680 print "$line" if (defined($line));
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400681 } while (defined($line));
Steven Rostedta75fece2010-11-02 14:58:27 -0400682 print "** Monitor flushed **\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400683}
684
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400685sub fail {
686
Steven Rostedta75fece2010-11-02 14:58:27 -0400687 if ($die_on_failure) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400688 dodie @_;
689 }
690
Steven Rostedta75fece2010-11-02 14:58:27 -0400691 doprint "FAILED\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400692
Steven Rostedt576f6272010-11-02 14:58:38 -0400693 my $i = $iteration;
694
Steven Rostedta75fece2010-11-02 14:58:27 -0400695 # no need to reboot for just building.
Steven Rostedt576f6272010-11-02 14:58:38 -0400696 if (!do_not_reboot) {
Steven Rostedta75fece2010-11-02 14:58:27 -0400697 doprint "REBOOTING\n";
698 reboot;
699 start_monitor;
700 wait_for_monitor $sleep_time;
701 end_monitor;
702 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400703
Steven Rostedt9064af52011-06-13 10:38:48 -0400704 my $name = "";
705
706 if (defined($test_name)) {
707 $name = " ($test_name)";
708 }
709
Steven Rostedt576f6272010-11-02 14:58:38 -0400710 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
711 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
Steven Rostedt9064af52011-06-13 10:38:48 -0400712 doprint "KTEST RESULT: TEST $i$name Failed: ", @_, "\n";
Steven Rostedt576f6272010-11-02 14:58:38 -0400713 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
714 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
Steven Rostedta75fece2010-11-02 14:58:27 -0400715
716 return 1 if (!defined($store_failures));
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400717
718 my @t = localtime;
719 my $date = sprintf "%04d%02d%02d%02d%02d%02d",
720 1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0];
721
Steven Rostedtcccae1a2010-11-09 12:21:32 -0500722 my $type = $build_type;
723 if ($type =~ /useconfig/) {
724 $type = "useconfig";
725 }
726
727 my $dir = "$machine-$test_type-$type-fail-$date";
Steven Rostedta75fece2010-11-02 14:58:27 -0400728 my $faildir = "$store_failures/$dir";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400729
730 if (!-d $faildir) {
731 mkpath($faildir) or
Steven Rostedta75fece2010-11-02 14:58:27 -0400732 die "can't create $faildir";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400733 }
Steven Rostedt51ad1dd2010-11-08 16:43:21 -0500734 if (-f "$output_config") {
735 cp "$output_config", "$faildir/config" or
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400736 die "failed to copy .config";
737 }
738 if (-f $buildlog) {
739 cp $buildlog, "$faildir/buildlog" or
740 die "failed to move $buildlog";
741 }
742 if (-f $dmesg) {
743 cp $dmesg, "$faildir/dmesg" or
744 die "failed to move $dmesg";
745 }
746
747 doprint "*** Saved info to $faildir ***\n";
748
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400749 return 1;
750}
751
Steven Rostedt2545eb62010-11-02 15:01:32 -0400752sub run_command {
753 my ($command) = @_;
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400754 my $dolog = 0;
755 my $dord = 0;
756 my $pid;
757
Steven Rostedte48c5292010-11-02 14:35:37 -0400758 $command =~ s/\$SSH_USER/$ssh_user/g;
759 $command =~ s/\$MACHINE/$machine/g;
760
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400761 doprint("$command ... ");
762
763 $pid = open(CMD, "$command 2>&1 |") or
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400764 (fail "unable to exec $command" and return 0);
Steven Rostedt2545eb62010-11-02 15:01:32 -0400765
766 if (defined($opt{"LOG_FILE"})) {
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400767 open(LOG, ">>$opt{LOG_FILE}") or
768 dodie "failed to write to log";
769 $dolog = 1;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400770 }
771
772 if (defined($redirect)) {
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400773 open (RD, ">$redirect") or
774 dodie "failed to write to redirect $redirect";
775 $dord = 1;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400776 }
777
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400778 while (<CMD>) {
779 print LOG if ($dolog);
780 print RD if ($dord);
781 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400782
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400783 waitpid($pid, 0);
Steven Rostedt2545eb62010-11-02 15:01:32 -0400784 my $failed = $?;
785
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400786 close(CMD);
787 close(LOG) if ($dolog);
788 close(RD) if ($dord);
789
Steven Rostedt2545eb62010-11-02 15:01:32 -0400790 if ($failed) {
791 doprint "FAILED!\n";
792 } else {
793 doprint "SUCCESS\n";
794 }
795
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400796 return !$failed;
797}
798
Steven Rostedte48c5292010-11-02 14:35:37 -0400799sub run_ssh {
800 my ($cmd) = @_;
801 my $cp_exec = $ssh_exec;
802
803 $cp_exec =~ s/\$SSH_COMMAND/$cmd/g;
804 return run_command "$cp_exec";
805}
806
807sub run_scp {
808 my ($src, $dst) = @_;
809 my $cp_scp = $scp_to_target;
810
811 $cp_scp =~ s/\$SRC_FILE/$src/g;
812 $cp_scp =~ s/\$DST_FILE/$dst/g;
813
814 return run_command "$cp_scp";
815}
816
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400817sub get_grub_index {
818
Steven Rostedta75fece2010-11-02 14:58:27 -0400819 if ($reboot_type ne "grub") {
820 return;
821 }
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400822 return if (defined($grub_number));
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400823
824 doprint "Find grub menu ... ";
825 $grub_number = -1;
Steven Rostedte48c5292010-11-02 14:35:37 -0400826
827 my $ssh_grub = $ssh_exec;
828 $ssh_grub =~ s,\$SSH_COMMAND,cat /boot/grub/menu.lst,g;
829
830 open(IN, "$ssh_grub |")
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400831 or die "unable to get menu.lst";
Steven Rostedte48c5292010-11-02 14:35:37 -0400832
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400833 while (<IN>) {
Steven Rostedta75fece2010-11-02 14:58:27 -0400834 if (/^\s*title\s+$grub_menu\s*$/) {
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400835 $grub_number++;
836 last;
837 } elsif (/^\s*title\s/) {
838 $grub_number++;
839 }
840 }
841 close(IN);
842
Steven Rostedta75fece2010-11-02 14:58:27 -0400843 die "Could not find '$grub_menu' in /boot/grub/menu on $machine"
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400844 if ($grub_number < 0);
845 doprint "$grub_number\n";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400846}
847
Steven Rostedt2545eb62010-11-02 15:01:32 -0400848sub wait_for_input
849{
850 my ($fp, $time) = @_;
851 my $rin;
852 my $ready;
853 my $line;
854 my $ch;
855
856 if (!defined($time)) {
857 $time = $timeout;
858 }
859
860 $rin = '';
861 vec($rin, fileno($fp), 1) = 1;
862 $ready = select($rin, undef, undef, $time);
863
864 $line = "";
865
866 # try to read one char at a time
867 while (sysread $fp, $ch, 1) {
868 $line .= $ch;
869 last if ($ch eq "\n");
870 }
871
872 if (!length($line)) {
873 return undef;
874 }
875
876 return $line;
877}
878
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400879sub reboot_to {
Steven Rostedta75fece2010-11-02 14:58:27 -0400880 if ($reboot_type eq "grub") {
Steven Rostedt4da46da2011-06-01 23:25:13 -0400881 run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch && reboot)'";
Steven Rostedta75fece2010-11-02 14:58:27 -0400882 return;
883 }
884
885 run_command "$reboot_script";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400886}
887
Steven Rostedta57419b2010-11-02 15:13:54 -0400888sub get_sha1 {
889 my ($commit) = @_;
890
891 doprint "git rev-list --max-count=1 $commit ... ";
892 my $sha1 = `git rev-list --max-count=1 $commit`;
893 my $ret = $?;
894
895 logit $sha1;
896
897 if ($ret) {
898 doprint "FAILED\n";
899 dodie "Failed to get git $commit";
900 }
901
902 print "SUCCESS\n";
903
904 chomp $sha1;
905
906 return $sha1;
907}
908
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400909sub monitor {
Steven Rostedt2545eb62010-11-02 15:01:32 -0400910 my $booted = 0;
911 my $bug = 0;
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400912 my $skip_call_trace = 0;
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400913 my $loops;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400914
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400915 wait_for_monitor 5;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400916
917 my $line;
918 my $full_line = "";
919
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400920 open(DMESG, "> $dmesg") or
921 die "unable to write to $dmesg";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400922
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400923 reboot_to;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400924
Steven Rostedt1c8a6172010-11-09 12:55:40 -0500925 my $success_start;
926 my $failure_start;
Steven Rostedt2d01b262011-03-08 09:47:54 -0500927 my $monitor_start = time;
928 my $done = 0;
Steven Rostedtf1a5b962011-06-13 10:30:00 -0400929 my $version_found = 0;
Steven Rostedt1c8a6172010-11-09 12:55:40 -0500930
Steven Rostedt2d01b262011-03-08 09:47:54 -0500931 while (!$done) {
Steven Rostedt2545eb62010-11-02 15:01:32 -0400932
Steven Rostedtecaf8e52011-06-13 10:48:10 -0400933 if ($bug && defined($stop_after_failure) &&
934 $stop_after_failure >= 0) {
935 my $time = $stop_after_failure - (time - $failure_start);
936 $line = wait_for_input($monitor_fp, $time);
937 if (!defined($line)) {
938 doprint "bug timed out after $booted_timeout seconds\n";
939 doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
940 last;
941 }
942 } elsif ($booted) {
Steven Rostedta75fece2010-11-02 14:58:27 -0400943 $line = wait_for_input($monitor_fp, $booted_timeout);
Steven Rostedtcd4f1d52011-06-13 10:26:27 -0400944 if (!defined($line)) {
945 my $s = $booted_timeout == 1 ? "" : "s";
946 doprint "Successful boot found: break after $booted_timeout second$s\n";
947 last;
948 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400949 } else {
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400950 $line = wait_for_input($monitor_fp);
Steven Rostedtcd4f1d52011-06-13 10:26:27 -0400951 if (!defined($line)) {
952 my $s = $timeout == 1 ? "" : "s";
953 doprint "Timed out after $timeout second$s\n";
954 last;
955 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400956 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400957
Steven Rostedt2545eb62010-11-02 15:01:32 -0400958 doprint $line;
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400959 print DMESG $line;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400960
961 # we are not guaranteed to get a full line
962 $full_line .= $line;
963
Steven Rostedta75fece2010-11-02 14:58:27 -0400964 if ($full_line =~ /$success_line/) {
Steven Rostedt2545eb62010-11-02 15:01:32 -0400965 $booted = 1;
Steven Rostedt1c8a6172010-11-09 12:55:40 -0500966 $success_start = time;
967 }
968
969 if ($booted && defined($stop_after_success) &&
970 $stop_after_success >= 0) {
971 my $now = time;
972 if ($now - $success_start >= $stop_after_success) {
973 doprint "Test forced to stop after $stop_after_success seconds after success\n";
974 last;
975 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400976 }
977
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400978 if ($full_line =~ /\[ backtrace testing \]/) {
979 $skip_call_trace = 1;
980 }
981
Steven Rostedt2545eb62010-11-02 15:01:32 -0400982 if ($full_line =~ /call trace:/i) {
Steven Rostedt46519202011-03-08 09:40:31 -0500983 if (!$bug && !$skip_call_trace) {
Steven Rostedt1c8a6172010-11-09 12:55:40 -0500984 $bug = 1;
985 $failure_start = time;
986 }
987 }
988
989 if ($bug && defined($stop_after_failure) &&
990 $stop_after_failure >= 0) {
991 my $now = time;
992 if ($now - $failure_start >= $stop_after_failure) {
993 doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
994 last;
995 }
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400996 }
997
998 if ($full_line =~ /\[ end of backtrace testing \]/) {
999 $skip_call_trace = 0;
1000 }
1001
1002 if ($full_line =~ /Kernel panic -/) {
Steven Rostedt10abf112011-03-07 13:21:00 -05001003 $failure_start = time;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001004 $bug = 1;
1005 }
1006
Steven Rostedtf1a5b962011-06-13 10:30:00 -04001007 # Detect triple faults by testing the banner
1008 if ($full_line =~ /\bLinux version (\S+).*\n/) {
1009 if ($1 eq $version) {
1010 $version_found = 1;
1011 } elsif ($version_found && $detect_triplefault) {
1012 # We already booted into the kernel we are testing,
1013 # but now we booted into another kernel?
1014 # Consider this a triple fault.
1015 doprint "Aleady booted in Linux kernel $version, but now\n";
1016 doprint "we booted into Linux kernel $1.\n";
1017 doprint "Assuming that this is a triple fault.\n";
1018 doprint "To disable this: set DETECT_TRIPLE_FAULT to 0\n";
1019 last;
1020 }
1021 }
1022
Steven Rostedt2545eb62010-11-02 15:01:32 -04001023 if ($line =~ /\n/) {
1024 $full_line = "";
1025 }
Steven Rostedt2d01b262011-03-08 09:47:54 -05001026
1027 if ($stop_test_after > 0 && !$booted && !$bug) {
1028 if (time - $monitor_start > $stop_test_after) {
Steven Rostedt4d62bf52011-05-20 09:14:35 -04001029 doprint "STOP_TEST_AFTER ($stop_test_after seconds) timed out\n";
Steven Rostedt2d01b262011-03-08 09:47:54 -05001030 $done = 1;
1031 }
1032 }
Steven Rostedt2545eb62010-11-02 15:01:32 -04001033 }
1034
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001035 close(DMESG);
Steven Rostedt2545eb62010-11-02 15:01:32 -04001036
Steven Rostedt2545eb62010-11-02 15:01:32 -04001037 if ($bug) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001038 return 0 if ($in_bisect);
Steven Rostedt576f6272010-11-02 14:58:38 -04001039 fail "failed - got a bug report" and return 0;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001040 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001041
Steven Rostedta75fece2010-11-02 14:58:27 -04001042 if (!$booted) {
1043 return 0 if ($in_bisect);
Steven Rostedt576f6272010-11-02 14:58:38 -04001044 fail "failed - never got a boot prompt." and return 0;
Steven Rostedta75fece2010-11-02 14:58:27 -04001045 }
1046
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001047 return 1;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001048}
1049
Steven Rostedtdb05cfe2011-06-13 11:09:22 -04001050sub do_post_install {
1051
1052 return if (!defined($post_install));
1053
1054 my $cp_post_install = $post_install;
1055 $cp_post_install =~ s/\$KERNEL_VERSION/$version/g;
1056 run_command "$cp_post_install" or
1057 dodie "Failed to run post install";
1058}
1059
Steven Rostedt2545eb62010-11-02 15:01:32 -04001060sub install {
1061
Steven Rostedte48c5292010-11-02 14:35:37 -04001062 run_scp "$outputdir/$build_target", "$target_image" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001063 dodie "failed to copy image";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001064
1065 my $install_mods = 0;
1066
1067 # should we process modules?
1068 $install_mods = 0;
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05001069 open(IN, "$output_config") or dodie("Can't read config file");
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001070 while (<IN>) {
1071 if (/CONFIG_MODULES(=y)?/) {
1072 $install_mods = 1 if (defined($1));
1073 last;
1074 }
1075 }
1076 close(IN);
1077
1078 if (!$install_mods) {
Steven Rostedtdb05cfe2011-06-13 11:09:22 -04001079 do_post_install;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001080 doprint "No modules needed\n";
1081 return;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001082 }
1083
Steven Rostedta75fece2010-11-02 14:58:27 -04001084 run_command "$make INSTALL_MOD_PATH=$tmpdir modules_install" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001085 dodie "Failed to install modules";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001086
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001087 my $modlib = "/lib/modules/$version";
Steven Rostedta57419b2010-11-02 15:13:54 -04001088 my $modtar = "ktest-mods.tar.bz2";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001089
Steven Rostedte48c5292010-11-02 14:35:37 -04001090 run_ssh "rm -rf $modlib" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001091 dodie "failed to remove old mods: $modlib";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001092
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001093 # would be nice if scp -r did not follow symbolic links
Steven Rostedta75fece2010-11-02 14:58:27 -04001094 run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001095 dodie "making tarball";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001096
Steven Rostedte48c5292010-11-02 14:35:37 -04001097 run_scp "$tmpdir/$modtar", "/tmp" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001098 dodie "failed to copy modules";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001099
Steven Rostedta75fece2010-11-02 14:58:27 -04001100 unlink "$tmpdir/$modtar";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001101
Steven Rostedte7b13442011-06-14 20:44:36 -04001102 run_ssh "'(cd / && tar xjf /tmp/$modtar)'" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001103 dodie "failed to tar modules";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001104
Steven Rostedte48c5292010-11-02 14:35:37 -04001105 run_ssh "rm -f /tmp/$modtar";
Steven Rostedt8b37ca82010-11-02 14:58:33 -04001106
Steven Rostedtdb05cfe2011-06-13 11:09:22 -04001107 do_post_install;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001108}
1109
Steven Rostedtddf607e2011-06-14 20:49:13 -04001110sub get_version {
1111 # get the release name
1112 doprint "$make kernelrelease ... ";
1113 $version = `$make kernelrelease | tail -1`;
1114 chomp($version);
1115 doprint "$version\n";
1116}
1117
1118sub start_monitor_and_boot {
1119 get_grub_index;
1120 get_version;
1121 install;
1122
1123 start_monitor;
1124 return monitor;
1125}
1126
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001127sub check_buildlog {
1128 my ($patch) = @_;
1129
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001130 my @files = `git show $patch | diffstat -l`;
1131
1132 open(IN, "git show $patch |") or
1133 dodie "failed to show $patch";
1134 while (<IN>) {
1135 if (m,^--- a/(.*),) {
1136 chomp $1;
1137 $files[$#files] = $1;
1138 }
1139 }
1140 close(IN);
1141
1142 open(IN, $buildlog) or dodie "Can't open $buildlog";
1143 while (<IN>) {
1144 if (/^\s*(.*?):.*(warning|error)/) {
1145 my $err = $1;
1146 foreach my $file (@files) {
Steven Rostedta75fece2010-11-02 14:58:27 -04001147 my $fullpath = "$builddir/$file";
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001148 if ($file eq $err || $fullpath eq $err) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001149 fail "$file built with warnings" and return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001150 }
1151 }
1152 }
1153 }
1154 close(IN);
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001155
1156 return 1;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001157}
1158
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001159sub apply_min_config {
1160 my $outconfig = "$output_config.new";
Steven Rostedt612b9e92011-03-07 13:27:43 -05001161
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001162 # Read the config file and remove anything that
1163 # is in the force_config hash (from minconfig and others)
1164 # then add the force config back.
1165
1166 doprint "Applying minimum configurations into $output_config.new\n";
1167
1168 open (OUT, ">$outconfig") or
1169 dodie "Can't create $outconfig";
1170
1171 if (-f $output_config) {
1172 open (IN, $output_config) or
1173 dodie "Failed to open $output_config";
1174 while (<IN>) {
1175 if (/^(# )?(CONFIG_[^\s=]*)/) {
1176 next if (defined($force_config{$2}));
1177 }
1178 print OUT;
1179 }
1180 close IN;
1181 }
1182 foreach my $config (keys %force_config) {
1183 print OUT "$force_config{$config}\n";
1184 }
1185 close OUT;
1186
1187 run_command "mv $outconfig $output_config";
1188}
1189
1190sub make_oldconfig {
1191
1192 apply_min_config;
1193
1194 if (!run_command "$make oldnoconfig") {
Steven Rostedt612b9e92011-03-07 13:27:43 -05001195 # Perhaps oldnoconfig doesn't exist in this version of the kernel
1196 # try a yes '' | oldconfig
1197 doprint "oldnoconfig failed, trying yes '' | make oldconfig\n";
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001198 run_command "yes '' | $make oldconfig" or
Steven Rostedt612b9e92011-03-07 13:27:43 -05001199 dodie "failed make config oldconfig";
1200 }
1201}
1202
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001203# read a config file and use this to force new configs.
1204sub load_force_config {
1205 my ($config) = @_;
1206
1207 open(IN, $config) or
1208 dodie "failed to read $config";
1209 while (<IN>) {
1210 chomp;
1211 if (/^(CONFIG[^\s=]*)(\s*=.*)/) {
1212 $force_config{$1} = $_;
1213 } elsif (/^# (CONFIG_\S*) is not set/) {
1214 $force_config{$1} = $_;
1215 }
1216 }
1217 close IN;
1218}
1219
Steven Rostedt2545eb62010-11-02 15:01:32 -04001220sub build {
1221 my ($type) = @_;
1222
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001223 unlink $buildlog;
1224
Steven Rostedt0bd6c1a2011-06-14 20:39:31 -04001225 if (defined($pre_build)) {
1226 my $ret = run_command $pre_build;
1227 if (!$ret && defined($pre_build_die) &&
1228 $pre_build_die) {
1229 dodie "failed to pre_build\n";
1230 }
1231 }
1232
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001233 if ($type =~ /^useconfig:(.*)/) {
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05001234 run_command "cp $1 $output_config" or
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001235 dodie "could not copy $1 to .config";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001236
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001237 $type = "oldconfig";
1238 }
1239
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001240 # old config can ask questions
1241 if ($type eq "oldconfig") {
Steven Rostedt9386c6a2010-11-08 16:35:48 -05001242 $type = "oldnoconfig";
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001243
1244 # allow for empty configs
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05001245 run_command "touch $output_config";
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001246
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05001247 run_command "mv $output_config $outputdir/config_temp" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001248 dodie "moving .config";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001249
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001250 if (!$noclean && !run_command "$make mrproper") {
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001251 dodie "make mrproper";
1252 }
1253
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05001254 run_command "mv $outputdir/config_temp $output_config" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001255 dodie "moving config_temp";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001256
1257 } elsif (!$noclean) {
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05001258 unlink "$output_config";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001259 run_command "$make mrproper" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001260 dodie "make mrproper";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001261 }
Steven Rostedt2545eb62010-11-02 15:01:32 -04001262
1263 # add something to distinguish this build
Steven Rostedta75fece2010-11-02 14:58:27 -04001264 open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file");
1265 print OUT "$localversion\n";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001266 close(OUT);
1267
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001268 if (defined($minconfig)) {
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001269 load_force_config($minconfig);
Steven Rostedt2545eb62010-11-02 15:01:32 -04001270 }
1271
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001272 if ($type ne "oldnoconfig") {
1273 run_command "$make $type" or
Steven Rostedt612b9e92011-03-07 13:27:43 -05001274 dodie "failed make config";
1275 }
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001276 # Run old config regardless, to enforce min configurations
1277 make_oldconfig;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001278
Steven Rostedta75fece2010-11-02 14:58:27 -04001279 $redirect = "$buildlog";
Steven Rostedt0bd6c1a2011-06-14 20:39:31 -04001280 my $build_ret = run_command "$make $build_options";
1281 undef $redirect;
1282
1283 if (defined($post_build)) {
1284 my $ret = run_command $post_build;
1285 if (!$ret && defined($post_build_die) &&
1286 $post_build_die) {
1287 dodie "failed to post_build\n";
1288 }
1289 }
1290
1291 if (!$build_ret) {
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001292 # bisect may need this to pass
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001293 return 0 if ($in_bisect);
1294 fail "failed build" and return 0;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001295 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001296
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001297 return 1;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001298}
1299
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001300sub halt {
Steven Rostedte48c5292010-11-02 14:35:37 -04001301 if (!run_ssh "halt" or defined($power_off)) {
Steven Rostedt576f6272010-11-02 14:58:38 -04001302 if (defined($poweroff_after_halt)) {
1303 sleep $poweroff_after_halt;
1304 run_command "$power_off";
1305 }
1306 } else {
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001307 # nope? the zap it!
Steven Rostedta75fece2010-11-02 14:58:27 -04001308 run_command "$power_off";
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001309 }
1310}
1311
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001312sub success {
1313 my ($i) = @_;
1314
Steven Rostedte48c5292010-11-02 14:35:37 -04001315 $successes++;
1316
Steven Rostedt9064af52011-06-13 10:38:48 -04001317 my $name = "";
1318
1319 if (defined($test_name)) {
1320 $name = " ($test_name)";
1321 }
1322
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001323 doprint "\n\n*******************************************\n";
1324 doprint "*******************************************\n";
Steven Rostedt9064af52011-06-13 10:38:48 -04001325 doprint "KTEST RESULT: TEST $i$name SUCCESS!!!! **\n";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001326 doprint "*******************************************\n";
1327 doprint "*******************************************\n";
1328
Steven Rostedt576f6272010-11-02 14:58:38 -04001329 if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) {
Steven Rostedta75fece2010-11-02 14:58:27 -04001330 doprint "Reboot and wait $sleep_time seconds\n";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001331 reboot;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001332 start_monitor;
Steven Rostedta75fece2010-11-02 14:58:27 -04001333 wait_for_monitor $sleep_time;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001334 end_monitor;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001335 }
1336}
1337
Steven Rostedtc960bb92011-03-08 09:22:39 -05001338sub answer_bisect {
1339 for (;;) {
1340 doprint "Pass or fail? [p/f]";
1341 my $ans = <STDIN>;
1342 chomp $ans;
1343 if ($ans eq "p" || $ans eq "P") {
1344 return 1;
1345 } elsif ($ans eq "f" || $ans eq "F") {
1346 return 0;
1347 } else {
1348 print "Please answer 'P' or 'F'\n";
1349 }
1350 }
1351}
1352
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001353sub child_run_test {
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001354 my $failed = 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001355
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001356 # child should have no power
Steven Rostedta75fece2010-11-02 14:58:27 -04001357 $reboot_on_error = 0;
1358 $poweroff_on_error = 0;
1359 $die_on_failure = 1;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001360
1361 run_command $run_test or $failed = 1;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001362 exit $failed;
1363}
1364
1365my $child_done;
1366
1367sub child_finished {
1368 $child_done = 1;
1369}
1370
1371sub do_run_test {
1372 my $child_pid;
1373 my $child_exit;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001374 my $line;
1375 my $full_line;
1376 my $bug = 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001377
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001378 wait_for_monitor 1;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001379
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001380 doprint "run test $run_test\n";
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001381
1382 $child_done = 0;
1383
1384 $SIG{CHLD} = qw(child_finished);
1385
1386 $child_pid = fork;
1387
1388 child_run_test if (!$child_pid);
1389
1390 $full_line = "";
1391
1392 do {
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001393 $line = wait_for_input($monitor_fp, 1);
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001394 if (defined($line)) {
1395
1396 # we are not guaranteed to get a full line
1397 $full_line .= $line;
Steven Rostedt8ea0e062011-03-08 09:44:35 -05001398 doprint $line;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001399
1400 if ($full_line =~ /call trace:/i) {
1401 $bug = 1;
1402 }
1403
1404 if ($full_line =~ /Kernel panic -/) {
1405 $bug = 1;
1406 }
1407
1408 if ($line =~ /\n/) {
1409 $full_line = "";
1410 }
1411 }
1412 } while (!$child_done && !$bug);
1413
1414 if ($bug) {
Steven Rostedt8ea0e062011-03-08 09:44:35 -05001415 my $failure_start = time;
1416 my $now;
1417 do {
1418 $line = wait_for_input($monitor_fp, 1);
1419 if (defined($line)) {
1420 doprint $line;
1421 }
1422 $now = time;
1423 if ($now - $failure_start >= $stop_after_failure) {
1424 last;
1425 }
1426 } while (defined($line));
1427
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001428 doprint "Detected kernel crash!\n";
1429 # kill the child with extreme prejudice
1430 kill 9, $child_pid;
1431 }
1432
1433 waitpid $child_pid, 0;
1434 $child_exit = $?;
1435
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001436 if ($bug || $child_exit) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001437 return 0 if $in_bisect;
1438 fail "test failed" and return 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001439 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001440 return 1;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001441}
1442
Steven Rostedta75fece2010-11-02 14:58:27 -04001443sub run_git_bisect {
1444 my ($command) = @_;
1445
1446 doprint "$command ... ";
1447
1448 my $output = `$command 2>&1`;
1449 my $ret = $?;
1450
1451 logit $output;
1452
1453 if ($ret) {
1454 doprint "FAILED\n";
1455 dodie "Failed to git bisect";
1456 }
1457
1458 doprint "SUCCESS\n";
1459 if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) {
1460 doprint "$1 [$2]\n";
1461 } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) {
1462 $bisect_bad = $1;
1463 doprint "Found bad commit... $1\n";
1464 return 0;
1465 } else {
1466 # we already logged it, just print it now.
1467 print $output;
1468 }
1469
1470 return 1;
1471}
1472
Steven Rostedtc23dca72011-03-08 09:26:31 -05001473sub bisect_reboot {
1474 doprint "Reboot and sleep $bisect_sleep_time seconds\n";
1475 reboot;
1476 start_monitor;
1477 wait_for_monitor $bisect_sleep_time;
1478 end_monitor;
1479}
1480
1481# returns 1 on success, 0 on failure, -1 on skip
Steven Rostedt0a05c762010-11-08 11:14:10 -05001482sub run_bisect_test {
1483 my ($type, $buildtype) = @_;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001484
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001485 my $failed = 0;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001486 my $result;
1487 my $output;
1488 my $ret;
1489
Steven Rostedt0a05c762010-11-08 11:14:10 -05001490 $in_bisect = 1;
1491
1492 build $buildtype or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001493
1494 if ($type ne "build") {
Steven Rostedtc23dca72011-03-08 09:26:31 -05001495 if ($failed && $bisect_skip) {
1496 $in_bisect = 0;
1497 return -1;
1498 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001499 dodie "Failed on build" if $failed;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001500
1501 # Now boot the box
Steven Rostedtddf607e2011-06-14 20:49:13 -04001502 start_monitor_and_boot or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001503
1504 if ($type ne "boot") {
Steven Rostedtc23dca72011-03-08 09:26:31 -05001505 if ($failed && $bisect_skip) {
1506 end_monitor;
1507 bisect_reboot;
1508 $in_bisect = 0;
1509 return -1;
1510 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001511 dodie "Failed on boot" if $failed;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001512
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001513 do_run_test or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001514 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001515 end_monitor;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001516 }
1517
1518 if ($failed) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001519 $result = 0;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001520 } else {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001521 $result = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001522 }
Steven Rostedt4025bc62011-05-20 09:16:29 -04001523
1524 # reboot the box to a kernel we can ssh to
1525 if ($type ne "build") {
1526 bisect_reboot;
1527 }
Steven Rostedt0a05c762010-11-08 11:14:10 -05001528 $in_bisect = 0;
1529
1530 return $result;
1531}
1532
1533sub run_bisect {
1534 my ($type) = @_;
1535 my $buildtype = "oldconfig";
1536
1537 # We should have a minconfig to use?
1538 if (defined($minconfig)) {
1539 $buildtype = "useconfig:$minconfig";
1540 }
1541
1542 my $ret = run_bisect_test $type, $buildtype;
1543
Steven Rostedtc960bb92011-03-08 09:22:39 -05001544 if ($bisect_manual) {
1545 $ret = answer_bisect;
1546 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001547
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04001548 # Are we looking for where it worked, not failed?
1549 if ($reverse_bisect) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001550 $ret = !$ret;
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04001551 }
1552
Steven Rostedtc23dca72011-03-08 09:26:31 -05001553 if ($ret > 0) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001554 return "good";
Steven Rostedtc23dca72011-03-08 09:26:31 -05001555 } elsif ($ret == 0) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001556 return "bad";
Steven Rostedtc23dca72011-03-08 09:26:31 -05001557 } elsif ($bisect_skip) {
1558 doprint "HIT A BAD COMMIT ... SKIPPING\n";
1559 return "skip";
Steven Rostedt0a05c762010-11-08 11:14:10 -05001560 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001561}
1562
1563sub bisect {
1564 my ($i) = @_;
1565
1566 my $result;
1567
1568 die "BISECT_GOOD[$i] not defined\n" if (!defined($opt{"BISECT_GOOD[$i]"}));
1569 die "BISECT_BAD[$i] not defined\n" if (!defined($opt{"BISECT_BAD[$i]"}));
1570 die "BISECT_TYPE[$i] not defined\n" if (!defined($opt{"BISECT_TYPE[$i]"}));
1571
1572 my $good = $opt{"BISECT_GOOD[$i]"};
1573 my $bad = $opt{"BISECT_BAD[$i]"};
1574 my $type = $opt{"BISECT_TYPE[$i]"};
Steven Rostedta75fece2010-11-02 14:58:27 -04001575 my $start = $opt{"BISECT_START[$i]"};
1576 my $replay = $opt{"BISECT_REPLAY[$i]"};
Steven Rostedt3410f6f2011-03-08 09:38:12 -05001577 my $start_files = $opt{"BISECT_FILES[$i]"};
1578
1579 if (defined($start_files)) {
1580 $start_files = " -- " . $start_files;
1581 } else {
1582 $start_files = "";
1583 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001584
Steven Rostedta57419b2010-11-02 15:13:54 -04001585 # convert to true sha1's
1586 $good = get_sha1($good);
1587 $bad = get_sha1($bad);
1588
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04001589 if (defined($opt{"BISECT_REVERSE[$i]"}) &&
1590 $opt{"BISECT_REVERSE[$i]"} == 1) {
1591 doprint "Performing a reverse bisect (bad is good, good is bad!)\n";
1592 $reverse_bisect = 1;
1593 } else {
1594 $reverse_bisect = 0;
1595 }
1596
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001597 # Can't have a test without having a test to run
1598 if ($type eq "test" && !defined($run_test)) {
1599 $type = "boot";
1600 }
1601
Steven Rostedta75fece2010-11-02 14:58:27 -04001602 my $check = $opt{"BISECT_CHECK[$i]"};
1603 if (defined($check) && $check ne "0") {
1604
1605 # get current HEAD
Steven Rostedta57419b2010-11-02 15:13:54 -04001606 my $head = get_sha1("HEAD");
Steven Rostedta75fece2010-11-02 14:58:27 -04001607
1608 if ($check ne "good") {
1609 doprint "TESTING BISECT BAD [$bad]\n";
1610 run_command "git checkout $bad" or
1611 die "Failed to checkout $bad";
1612
1613 $result = run_bisect $type;
1614
1615 if ($result ne "bad") {
1616 fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0;
1617 }
1618 }
1619
1620 if ($check ne "bad") {
1621 doprint "TESTING BISECT GOOD [$good]\n";
1622 run_command "git checkout $good" or
1623 die "Failed to checkout $good";
1624
1625 $result = run_bisect $type;
1626
1627 if ($result ne "good") {
1628 fail "Tested BISECT_GOOD [$good] and it failed" and return 0;
1629 }
1630 }
1631
1632 # checkout where we started
1633 run_command "git checkout $head" or
1634 die "Failed to checkout $head";
1635 }
1636
Steven Rostedt3410f6f2011-03-08 09:38:12 -05001637 run_command "git bisect start$start_files" or
Steven Rostedta75fece2010-11-02 14:58:27 -04001638 dodie "could not start bisect";
1639
1640 run_command "git bisect good $good" or
1641 dodie "could not set bisect good to $good";
1642
1643 run_git_bisect "git bisect bad $bad" or
1644 dodie "could not set bisect bad to $bad";
1645
1646 if (defined($replay)) {
1647 run_command "git bisect replay $replay" or
1648 dodie "failed to run replay";
1649 }
1650
1651 if (defined($start)) {
1652 run_command "git checkout $start" or
1653 dodie "failed to checkout $start";
1654 }
1655
1656 my $test;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001657 do {
1658 $result = run_bisect $type;
Steven Rostedta75fece2010-11-02 14:58:27 -04001659 $test = run_git_bisect "git bisect $result";
1660 } while ($test);
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001661
1662 run_command "git bisect log" or
1663 dodie "could not capture git bisect log";
1664
1665 run_command "git bisect reset" or
1666 dodie "could not reset git bisect";
1667
1668 doprint "Bad commit was [$bisect_bad]\n";
1669
Steven Rostedt0a05c762010-11-08 11:14:10 -05001670 success $i;
1671}
1672
1673my %config_ignore;
1674my %config_set;
1675
1676my %config_list;
1677my %null_config;
1678
1679my %dependency;
1680
1681sub process_config_ignore {
1682 my ($config) = @_;
1683
1684 open (IN, $config)
1685 or dodie "Failed to read $config";
1686
1687 while (<IN>) {
Steven Rostedt9bf71742011-06-01 23:27:19 -04001688 if (/^((CONFIG\S*)=.*)/) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001689 $config_ignore{$2} = $1;
1690 }
1691 }
1692
1693 close(IN);
1694}
1695
1696sub read_current_config {
1697 my ($config_ref) = @_;
1698
1699 %{$config_ref} = ();
1700 undef %{$config_ref};
1701
1702 my @key = keys %{$config_ref};
1703 if ($#key >= 0) {
1704 print "did not delete!\n";
1705 exit;
1706 }
1707 open (IN, "$output_config");
1708
1709 while (<IN>) {
1710 if (/^(CONFIG\S+)=(.*)/) {
1711 ${$config_ref}{$1} = $2;
1712 }
1713 }
1714 close(IN);
1715}
1716
1717sub get_dependencies {
1718 my ($config) = @_;
1719
1720 my $arr = $dependency{$config};
1721 if (!defined($arr)) {
1722 return ();
1723 }
1724
1725 my @deps = @{$arr};
1726
1727 foreach my $dep (@{$arr}) {
1728 print "ADD DEP $dep\n";
1729 @deps = (@deps, get_dependencies $dep);
1730 }
1731
1732 return @deps;
1733}
1734
1735sub create_config {
1736 my @configs = @_;
1737
1738 open(OUT, ">$output_config") or dodie "Can not write to $output_config";
1739
1740 foreach my $config (@configs) {
1741 print OUT "$config_set{$config}\n";
1742 my @deps = get_dependencies $config;
1743 foreach my $dep (@deps) {
1744 print OUT "$config_set{$dep}\n";
1745 }
1746 }
1747
1748 foreach my $config (keys %config_ignore) {
1749 print OUT "$config_ignore{$config}\n";
1750 }
1751 close(OUT);
1752
1753# exit;
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001754 make_oldconfig;
Steven Rostedt0a05c762010-11-08 11:14:10 -05001755}
1756
1757sub compare_configs {
1758 my (%a, %b) = @_;
1759
1760 foreach my $item (keys %a) {
1761 if (!defined($b{$item})) {
1762 print "diff $item\n";
1763 return 1;
1764 }
1765 delete $b{$item};
1766 }
1767
1768 my @keys = keys %b;
1769 if ($#keys) {
1770 print "diff2 $keys[0]\n";
1771 }
1772 return -1 if ($#keys >= 0);
1773
1774 return 0;
1775}
1776
1777sub run_config_bisect_test {
1778 my ($type) = @_;
1779
1780 return run_bisect_test $type, "oldconfig";
1781}
1782
1783sub process_passed {
1784 my (%configs) = @_;
1785
1786 doprint "These configs had no failure: (Enabling them for further compiles)\n";
1787 # Passed! All these configs are part of a good compile.
1788 # Add them to the min options.
1789 foreach my $config (keys %configs) {
1790 if (defined($config_list{$config})) {
1791 doprint " removing $config\n";
1792 $config_ignore{$config} = $config_list{$config};
1793 delete $config_list{$config};
1794 }
1795 }
Steven Rostedtf1a27852010-11-11 11:34:38 -05001796 doprint "config copied to $outputdir/config_good\n";
1797 run_command "cp -f $output_config $outputdir/config_good";
Steven Rostedt0a05c762010-11-08 11:14:10 -05001798}
1799
1800sub process_failed {
1801 my ($config) = @_;
1802
1803 doprint "\n\n***************************************\n";
1804 doprint "Found bad config: $config\n";
1805 doprint "***************************************\n\n";
1806}
1807
1808sub run_config_bisect {
1809
1810 my @start_list = keys %config_list;
1811
1812 if ($#start_list < 0) {
1813 doprint "No more configs to test!!!\n";
1814 return -1;
1815 }
1816
1817 doprint "***** RUN TEST ***\n";
1818 my $type = $opt{"CONFIG_BISECT_TYPE[$iteration]"};
1819 my $ret;
1820 my %current_config;
1821
1822 my $count = $#start_list + 1;
1823 doprint " $count configs to test\n";
1824
1825 my $half = int($#start_list / 2);
1826
1827 do {
1828 my @tophalf = @start_list[0 .. $half];
1829
1830 create_config @tophalf;
1831 read_current_config \%current_config;
1832
1833 $count = $#tophalf + 1;
1834 doprint "Testing $count configs\n";
1835 my $found = 0;
1836 # make sure we test something
1837 foreach my $config (@tophalf) {
1838 if (defined($current_config{$config})) {
1839 logit " $config\n";
1840 $found = 1;
1841 }
1842 }
1843 if (!$found) {
1844 # try the other half
1845 doprint "Top half produced no set configs, trying bottom half\n";
Steven Rostedt4c8cc552011-06-01 23:22:30 -04001846 @tophalf = @start_list[$half + 1 .. $#start_list];
Steven Rostedt0a05c762010-11-08 11:14:10 -05001847 create_config @tophalf;
1848 read_current_config \%current_config;
1849 foreach my $config (@tophalf) {
1850 if (defined($current_config{$config})) {
1851 logit " $config\n";
1852 $found = 1;
1853 }
1854 }
1855 if (!$found) {
1856 doprint "Failed: Can't make new config with current configs\n";
1857 foreach my $config (@start_list) {
1858 doprint " CONFIG: $config\n";
1859 }
1860 return -1;
1861 }
1862 $count = $#tophalf + 1;
1863 doprint "Testing $count configs\n";
1864 }
1865
1866 $ret = run_config_bisect_test $type;
Steven Rostedtc960bb92011-03-08 09:22:39 -05001867 if ($bisect_manual) {
1868 $ret = answer_bisect;
1869 }
Steven Rostedt0a05c762010-11-08 11:14:10 -05001870 if ($ret) {
1871 process_passed %current_config;
1872 return 0;
1873 }
1874
1875 doprint "This config had a failure.\n";
1876 doprint "Removing these configs that were not set in this config:\n";
Steven Rostedtf1a27852010-11-11 11:34:38 -05001877 doprint "config copied to $outputdir/config_bad\n";
1878 run_command "cp -f $output_config $outputdir/config_bad";
Steven Rostedt0a05c762010-11-08 11:14:10 -05001879
1880 # A config exists in this group that was bad.
1881 foreach my $config (keys %config_list) {
1882 if (!defined($current_config{$config})) {
1883 doprint " removing $config\n";
1884 delete $config_list{$config};
1885 }
1886 }
1887
1888 @start_list = @tophalf;
1889
1890 if ($#start_list == 0) {
1891 process_failed $start_list[0];
1892 return 1;
1893 }
1894
1895 # remove half the configs we are looking at and see if
1896 # they are good.
1897 $half = int($#start_list / 2);
Steven Rostedt4c8cc552011-06-01 23:22:30 -04001898 } while ($#start_list > 0);
Steven Rostedt0a05c762010-11-08 11:14:10 -05001899
Steven Rostedtc960bb92011-03-08 09:22:39 -05001900 # we found a single config, try it again unless we are running manually
1901
1902 if ($bisect_manual) {
1903 process_failed $start_list[0];
1904 return 1;
1905 }
1906
Steven Rostedt0a05c762010-11-08 11:14:10 -05001907 my @tophalf = @start_list[0 .. 0];
1908
1909 $ret = run_config_bisect_test $type;
1910 if ($ret) {
1911 process_passed %current_config;
1912 return 0;
1913 }
1914
1915 process_failed $start_list[0];
1916 return 1;
1917}
1918
1919sub config_bisect {
1920 my ($i) = @_;
1921
1922 my $start_config = $opt{"CONFIG_BISECT[$i]"};
1923
1924 my $tmpconfig = "$tmpdir/use_config";
1925
Steven Rostedt30f75da2011-06-13 10:35:35 -04001926 if (defined($config_bisect_good)) {
1927 process_config_ignore $config_bisect_good;
1928 }
1929
Steven Rostedt0a05c762010-11-08 11:14:10 -05001930 # Make the file with the bad config and the min config
1931 if (defined($minconfig)) {
1932 # read the min config for things to ignore
1933 run_command "cp $minconfig $tmpconfig" or
1934 dodie "failed to copy $minconfig to $tmpconfig";
1935 } else {
1936 unlink $tmpconfig;
1937 }
1938
1939 # Add other configs
1940 if (defined($addconfig)) {
1941 run_command "cat $addconfig >> $tmpconfig" or
1942 dodie "failed to append $addconfig";
1943 }
1944
Steven Rostedt0a05c762010-11-08 11:14:10 -05001945 if (-f $tmpconfig) {
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001946 load_force_config($tmpconfig);
Steven Rostedt0a05c762010-11-08 11:14:10 -05001947 process_config_ignore $tmpconfig;
1948 }
1949
1950 # now process the start config
1951 run_command "cp $start_config $output_config" or
1952 dodie "failed to copy $start_config to $output_config";
1953
1954 # read directly what we want to check
1955 my %config_check;
1956 open (IN, $output_config)
1957 or dodie "faied to open $output_config";
1958
1959 while (<IN>) {
1960 if (/^((CONFIG\S*)=.*)/) {
1961 $config_check{$2} = $1;
1962 }
1963 }
1964 close(IN);
1965
1966 # Now run oldconfig with the minconfig (and addconfigs)
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001967 make_oldconfig;
Steven Rostedt0a05c762010-11-08 11:14:10 -05001968
1969 # check to see what we lost (or gained)
1970 open (IN, $output_config)
1971 or dodie "Failed to read $start_config";
1972
1973 my %removed_configs;
1974 my %added_configs;
1975
1976 while (<IN>) {
1977 if (/^((CONFIG\S*)=.*)/) {
1978 # save off all options
1979 $config_set{$2} = $1;
1980 if (defined($config_check{$2})) {
1981 if (defined($config_ignore{$2})) {
1982 $removed_configs{$2} = $1;
1983 } else {
1984 $config_list{$2} = $1;
1985 }
1986 } elsif (!defined($config_ignore{$2})) {
1987 $added_configs{$2} = $1;
1988 $config_list{$2} = $1;
1989 }
1990 }
1991 }
1992 close(IN);
1993
1994 my @confs = keys %removed_configs;
1995 if ($#confs >= 0) {
1996 doprint "Configs overridden by default configs and removed from check:\n";
1997 foreach my $config (@confs) {
1998 doprint " $config\n";
1999 }
2000 }
2001 @confs = keys %added_configs;
2002 if ($#confs >= 0) {
2003 doprint "Configs appearing in make oldconfig and added:\n";
2004 foreach my $config (@confs) {
2005 doprint " $config\n";
2006 }
2007 }
2008
2009 my %config_test;
2010 my $once = 0;
2011
2012 # Sometimes kconfig does weird things. We must make sure
2013 # that the config we autocreate has everything we need
2014 # to test, otherwise we may miss testing configs, or
2015 # may not be able to create a new config.
2016 # Here we create a config with everything set.
2017 create_config (keys %config_list);
2018 read_current_config \%config_test;
2019 foreach my $config (keys %config_list) {
2020 if (!defined($config_test{$config})) {
2021 if (!$once) {
2022 $once = 1;
2023 doprint "Configs not produced by kconfig (will not be checked):\n";
2024 }
2025 doprint " $config\n";
2026 delete $config_list{$config};
2027 }
2028 }
2029 my $ret;
2030 do {
2031 $ret = run_config_bisect;
2032 } while (!$ret);
2033
2034 return $ret if ($ret < 0);
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04002035
2036 success $i;
2037}
2038
Steven Rostedt27d934b2011-05-20 09:18:18 -04002039sub patchcheck_reboot {
2040 doprint "Reboot and sleep $patchcheck_sleep_time seconds\n";
2041 reboot;
2042 start_monitor;
2043 wait_for_monitor $patchcheck_sleep_time;
2044 end_monitor;
2045}
2046
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002047sub patchcheck {
2048 my ($i) = @_;
2049
2050 die "PATCHCHECK_START[$i] not defined\n"
2051 if (!defined($opt{"PATCHCHECK_START[$i]"}));
2052 die "PATCHCHECK_TYPE[$i] not defined\n"
2053 if (!defined($opt{"PATCHCHECK_TYPE[$i]"}));
2054
2055 my $start = $opt{"PATCHCHECK_START[$i]"};
2056
2057 my $end = "HEAD";
2058 if (defined($opt{"PATCHCHECK_END[$i]"})) {
2059 $end = $opt{"PATCHCHECK_END[$i]"};
2060 }
2061
Steven Rostedta57419b2010-11-02 15:13:54 -04002062 # Get the true sha1's since we can use things like HEAD~3
2063 $start = get_sha1($start);
2064 $end = get_sha1($end);
2065
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002066 my $type = $opt{"PATCHCHECK_TYPE[$i]"};
2067
2068 # Can't have a test without having a test to run
2069 if ($type eq "test" && !defined($run_test)) {
2070 $type = "boot";
2071 }
2072
2073 open (IN, "git log --pretty=oneline $end|") or
2074 dodie "could not get git list";
2075
2076 my @list;
2077
2078 while (<IN>) {
2079 chomp;
2080 $list[$#list+1] = $_;
2081 last if (/^$start/);
2082 }
2083 close(IN);
2084
2085 if ($list[$#list] !~ /^$start/) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002086 fail "SHA1 $start not found";
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002087 }
2088
2089 # go backwards in the list
2090 @list = reverse @list;
2091
2092 my $save_clean = $noclean;
Steven Rostedt19902072011-06-14 20:46:25 -04002093 my %ignored_warnings;
2094
2095 if (defined($ignore_warnings)) {
2096 foreach my $sha1 (split /\s+/, $ignore_warnings) {
2097 $ignored_warnings{$sha1} = 1;
2098 }
2099 }
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002100
2101 $in_patchcheck = 1;
2102 foreach my $item (@list) {
2103 my $sha1 = $item;
2104 $sha1 =~ s/^([[:xdigit:]]+).*/$1/;
2105
2106 doprint "\nProcessing commit $item\n\n";
2107
2108 run_command "git checkout $sha1" or
2109 die "Failed to checkout $sha1";
2110
2111 # only clean on the first and last patch
2112 if ($item eq $list[0] ||
2113 $item eq $list[$#list]) {
2114 $noclean = $save_clean;
2115 } else {
2116 $noclean = 1;
2117 }
2118
2119 if (defined($minconfig)) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002120 build "useconfig:$minconfig" or return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002121 } else {
2122 # ?? no config to use?
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002123 build "oldconfig" or return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002124 }
2125
Steven Rostedt19902072011-06-14 20:46:25 -04002126
2127 if (!defined($ignored_warnings{$sha1})) {
2128 check_buildlog $sha1 or return 0;
2129 }
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002130
2131 next if ($type eq "build");
2132
Steven Rostedt7faafbd2010-11-02 14:58:22 -04002133 my $failed = 0;
2134
Steven Rostedtddf607e2011-06-14 20:49:13 -04002135 start_monitor_and_boot or $failed = 1;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04002136
2137 if (!$failed && $type ne "boot"){
2138 do_run_test or $failed = 1;
2139 }
2140 end_monitor;
2141 return 0 if ($failed);
2142
Steven Rostedt27d934b2011-05-20 09:18:18 -04002143 patchcheck_reboot;
2144
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002145 }
2146 $in_patchcheck = 0;
2147 success $i;
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002148
2149 return 1;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002150}
2151
Steven Rostedt8d1491b2010-11-18 15:39:48 -05002152$#ARGV < 1 or die "ktest.pl version: $VERSION\n usage: ktest.pl config-file\n";
Steven Rostedt2545eb62010-11-02 15:01:32 -04002153
Steven Rostedt8d1491b2010-11-18 15:39:48 -05002154if ($#ARGV == 0) {
2155 $ktest_config = $ARGV[0];
2156 if (! -f $ktest_config) {
2157 print "$ktest_config does not exist.\n";
2158 my $ans;
2159 for (;;) {
2160 print "Create it? [Y/n] ";
2161 $ans = <STDIN>;
2162 chomp $ans;
2163 if ($ans =~ /^\s*$/) {
2164 $ans = "y";
2165 }
2166 last if ($ans =~ /^y$/i || $ans =~ /^n$/i);
2167 print "Please answer either 'y' or 'n'.\n";
2168 }
2169 if ($ans !~ /^y$/i) {
2170 exit 0;
2171 }
2172 }
2173} else {
2174 $ktest_config = "ktest.conf";
2175}
2176
2177if (! -f $ktest_config) {
2178 open(OUT, ">$ktest_config") or die "Can not create $ktest_config";
2179 print OUT << "EOF"
2180# Generated by ktest.pl
2181#
2182# Define each test with TEST_START
2183# The config options below it will override the defaults
2184TEST_START
2185
2186DEFAULTS
2187EOF
2188;
2189 close(OUT);
2190}
2191read_config $ktest_config;
2192
Steven Rostedt23715c3c2011-06-13 11:03:34 -04002193if (defined($opt{"LOG_FILE"})) {
2194 $opt{"LOG_FILE"} = eval_option($opt{"LOG_FILE"}, -1);
2195}
2196
Steven Rostedt8d1491b2010-11-18 15:39:48 -05002197# Append any configs entered in manually to the config file.
2198my @new_configs = keys %entered_configs;
2199if ($#new_configs >= 0) {
2200 print "\nAppending entered in configs to $ktest_config\n";
2201 open(OUT, ">>$ktest_config") or die "Can not append to $ktest_config";
2202 foreach my $config (@new_configs) {
2203 print OUT "$config = $entered_configs{$config}\n";
2204 $opt{$config} = $entered_configs{$config};
2205 }
2206}
Steven Rostedt2545eb62010-11-02 15:01:32 -04002207
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002208if ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) {
2209 unlink $opt{"LOG_FILE"};
2210}
Steven Rostedt2545eb62010-11-02 15:01:32 -04002211
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002212doprint "\n\nSTARTING AUTOMATED TESTS\n\n";
2213
Steven Rostedta57419b2010-11-02 15:13:54 -04002214for (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) {
2215
2216 if (!$i) {
2217 doprint "DEFAULT OPTIONS:\n";
2218 } else {
2219 doprint "\nTEST $i OPTIONS";
2220 if (defined($repeat_tests{$i})) {
2221 $repeat = $repeat_tests{$i};
2222 doprint " ITERATE $repeat";
2223 }
2224 doprint "\n";
2225 }
2226
2227 foreach my $option (sort keys %opt) {
2228
2229 if ($option =~ /\[(\d+)\]$/) {
2230 next if ($i != $1);
2231 } else {
2232 next if ($i);
2233 }
2234
2235 doprint "$option = $opt{$option}\n";
2236 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002237}
Steven Rostedt2545eb62010-11-02 15:01:32 -04002238
Steven Rostedt2a625122011-05-20 15:48:59 -04002239sub __set_test_option {
Steven Rostedt5a391fb2010-11-02 14:57:43 -04002240 my ($name, $i) = @_;
2241
2242 my $option = "$name\[$i\]";
2243
2244 if (defined($opt{$option})) {
2245 return $opt{$option};
2246 }
2247
Steven Rostedta57419b2010-11-02 15:13:54 -04002248 foreach my $test (keys %repeat_tests) {
2249 if ($i >= $test &&
2250 $i < $test + $repeat_tests{$test}) {
2251 $option = "$name\[$test\]";
2252 if (defined($opt{$option})) {
2253 return $opt{$option};
2254 }
2255 }
2256 }
2257
Steven Rostedt5a391fb2010-11-02 14:57:43 -04002258 if (defined($opt{$name})) {
2259 return $opt{$name};
2260 }
2261
2262 return undef;
2263}
2264
Steven Rostedt2a625122011-05-20 15:48:59 -04002265sub set_test_option {
2266 my ($name, $i) = @_;
2267
2268 my $option = __set_test_option($name, $i);
2269 return $option if (!defined($option));
2270
Steven Rostedt23715c3c2011-06-13 11:03:34 -04002271 return eval_option($option, $i);
Steven Rostedt2a625122011-05-20 15:48:59 -04002272}
2273
Steven Rostedt2545eb62010-11-02 15:01:32 -04002274# First we need to do is the builds
Steven Rostedta75fece2010-11-02 14:58:27 -04002275for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
Steven Rostedt2545eb62010-11-02 15:01:32 -04002276
Steven Rostedt576f6272010-11-02 14:58:38 -04002277 $iteration = $i;
2278
Steven Rostedta75fece2010-11-02 14:58:27 -04002279 my $makecmd = set_test_option("MAKE_CMD", $i);
2280
2281 $machine = set_test_option("MACHINE", $i);
Steven Rostedte48c5292010-11-02 14:35:37 -04002282 $ssh_user = set_test_option("SSH_USER", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002283 $tmpdir = set_test_option("TMP_DIR", $i);
2284 $outputdir = set_test_option("OUTPUT_DIR", $i);
2285 $builddir = set_test_option("BUILD_DIR", $i);
2286 $test_type = set_test_option("TEST_TYPE", $i);
2287 $build_type = set_test_option("BUILD_TYPE", $i);
2288 $build_options = set_test_option("BUILD_OPTIONS", $i);
Steven Rostedt0bd6c1a2011-06-14 20:39:31 -04002289 $pre_build = set_test_option("PRE_BUILD", $i);
2290 $post_build = set_test_option("POST_BUILD", $i);
2291 $pre_build_die = set_test_option("PRE_BUILD_DIE", $i);
2292 $post_build_die = set_test_option("POST_BUILD_DIE", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002293 $power_cycle = set_test_option("POWER_CYCLE", $i);
Steven Rostedte48c5292010-11-02 14:35:37 -04002294 $reboot = set_test_option("REBOOT", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002295 $noclean = set_test_option("BUILD_NOCLEAN", $i);
2296 $minconfig = set_test_option("MIN_CONFIG", $i);
2297 $run_test = set_test_option("TEST", $i);
2298 $addconfig = set_test_option("ADD_CONFIG", $i);
2299 $reboot_type = set_test_option("REBOOT_TYPE", $i);
2300 $grub_menu = set_test_option("GRUB_MENU", $i);
Steven Rostedt8b37ca82010-11-02 14:58:33 -04002301 $post_install = set_test_option("POST_INSTALL", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002302 $reboot_script = set_test_option("REBOOT_SCRIPT", $i);
2303 $reboot_on_error = set_test_option("REBOOT_ON_ERROR", $i);
2304 $poweroff_on_error = set_test_option("POWEROFF_ON_ERROR", $i);
2305 $die_on_failure = set_test_option("DIE_ON_FAILURE", $i);
2306 $power_off = set_test_option("POWER_OFF", $i);
Steven Rostedt576f6272010-11-02 14:58:38 -04002307 $powercycle_after_reboot = set_test_option("POWERCYCLE_AFTER_REBOOT", $i);
2308 $poweroff_after_halt = set_test_option("POWEROFF_AFTER_HALT", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002309 $sleep_time = set_test_option("SLEEP_TIME", $i);
2310 $bisect_sleep_time = set_test_option("BISECT_SLEEP_TIME", $i);
Steven Rostedt27d934b2011-05-20 09:18:18 -04002311 $patchcheck_sleep_time = set_test_option("PATCHCHECK_SLEEP_TIME", $i);
Steven Rostedt19902072011-06-14 20:46:25 -04002312 $ignore_warnings = set_test_option("IGNORE_WARNINGS", $i);
Steven Rostedtc960bb92011-03-08 09:22:39 -05002313 $bisect_manual = set_test_option("BISECT_MANUAL", $i);
Steven Rostedtc23dca72011-03-08 09:26:31 -05002314 $bisect_skip = set_test_option("BISECT_SKIP", $i);
Steven Rostedt30f75da2011-06-13 10:35:35 -04002315 $config_bisect_good = set_test_option("CONFIG_BISECT_GOOD", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002316 $store_failures = set_test_option("STORE_FAILURES", $i);
Steven Rostedt9064af52011-06-13 10:38:48 -04002317 $test_name = set_test_option("TEST_NAME", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002318 $timeout = set_test_option("TIMEOUT", $i);
2319 $booted_timeout = set_test_option("BOOTED_TIMEOUT", $i);
2320 $console = set_test_option("CONSOLE", $i);
Steven Rostedtf1a5b962011-06-13 10:30:00 -04002321 $detect_triplefault = set_test_option("DETECT_TRIPLE_FAULT", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002322 $success_line = set_test_option("SUCCESS_LINE", $i);
Steven Rostedt1c8a6172010-11-09 12:55:40 -05002323 $stop_after_success = set_test_option("STOP_AFTER_SUCCESS", $i);
2324 $stop_after_failure = set_test_option("STOP_AFTER_FAILURE", $i);
Steven Rostedt2d01b262011-03-08 09:47:54 -05002325 $stop_test_after = set_test_option("STOP_TEST_AFTER", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002326 $build_target = set_test_option("BUILD_TARGET", $i);
Steven Rostedte48c5292010-11-02 14:35:37 -04002327 $ssh_exec = set_test_option("SSH_EXEC", $i);
2328 $scp_to_target = set_test_option("SCP_TO_TARGET", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002329 $target_image = set_test_option("TARGET_IMAGE", $i);
2330 $localversion = set_test_option("LOCALVERSION", $i);
2331
2332 chdir $builddir || die "can't change directory to $builddir";
2333
2334 if (!-d $tmpdir) {
2335 mkpath($tmpdir) or
2336 die "can't create $tmpdir";
2337 }
2338
Steven Rostedte48c5292010-11-02 14:35:37 -04002339 $ENV{"SSH_USER"} = $ssh_user;
2340 $ENV{"MACHINE"} = $machine;
2341
Steven Rostedta75fece2010-11-02 14:58:27 -04002342 $target = "$ssh_user\@$machine";
2343
2344 $buildlog = "$tmpdir/buildlog-$machine";
2345 $dmesg = "$tmpdir/dmesg-$machine";
2346 $make = "$makecmd O=$outputdir";
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05002347 $output_config = "$outputdir/.config";
Steven Rostedta75fece2010-11-02 14:58:27 -04002348
2349 if ($reboot_type eq "grub") {
Steven Rostedt576f6272010-11-02 14:58:38 -04002350 dodie "GRUB_MENU not defined" if (!defined($grub_menu));
Steven Rostedta75fece2010-11-02 14:58:27 -04002351 } elsif (!defined($reboot_script)) {
Steven Rostedt576f6272010-11-02 14:58:38 -04002352 dodie "REBOOT_SCRIPT not defined"
Steven Rostedta75fece2010-11-02 14:58:27 -04002353 }
2354
2355 my $run_type = $build_type;
2356 if ($test_type eq "patchcheck") {
2357 $run_type = $opt{"PATCHCHECK_TYPE[$i]"};
2358 } elsif ($test_type eq "bisect") {
2359 $run_type = $opt{"BISECT_TYPE[$i]"};
Steven Rostedt0a05c762010-11-08 11:14:10 -05002360 } elsif ($test_type eq "config_bisect") {
2361 $run_type = $opt{"CONFIG_BISECT_TYPE[$i]"};
Steven Rostedta75fece2010-11-02 14:58:27 -04002362 }
2363
2364 # mistake in config file?
2365 if (!defined($run_type)) {
2366 $run_type = "ERROR";
2367 }
Steven Rostedt2545eb62010-11-02 15:01:32 -04002368
2369 doprint "\n\n";
Steven Rostedta75fece2010-11-02 14:58:27 -04002370 doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type\n\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -04002371
2372 unlink $dmesg;
2373 unlink $buildlog;
Steven Rostedt2545eb62010-11-02 15:01:32 -04002374
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002375 if (!defined($minconfig)) {
2376 $minconfig = $addconfig;
2377
2378 } elsif (defined($addconfig)) {
Steven Rostedt9be2e6b2010-11-09 12:20:21 -05002379 run_command "cat $addconfig $minconfig > $tmpdir/add_config" or
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002380 dodie "Failed to create temp config";
Steven Rostedt9be2e6b2010-11-09 12:20:21 -05002381 $minconfig = "$tmpdir/add_config";
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002382 }
2383
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002384 my $checkout = $opt{"CHECKOUT[$i]"};
2385 if (defined($checkout)) {
2386 run_command "git checkout $checkout" or
2387 die "failed to checkout $checkout";
2388 }
2389
Steven Rostedta75fece2010-11-02 14:58:27 -04002390 if ($test_type eq "bisect") {
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04002391 bisect $i;
2392 next;
Steven Rostedt0a05c762010-11-08 11:14:10 -05002393 } elsif ($test_type eq "config_bisect") {
2394 config_bisect $i;
2395 next;
Steven Rostedta75fece2010-11-02 14:58:27 -04002396 } elsif ($test_type eq "patchcheck") {
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002397 patchcheck $i;
2398 next;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04002399 }
2400
Steven Rostedt7faafbd2010-11-02 14:58:22 -04002401 if ($build_type ne "nobuild") {
2402 build $build_type or next;
Steven Rostedt2545eb62010-11-02 15:01:32 -04002403 }
2404
Steven Rostedta75fece2010-11-02 14:58:27 -04002405 if ($test_type ne "build") {
Steven Rostedta75fece2010-11-02 14:58:27 -04002406 my $failed = 0;
Steven Rostedtddf607e2011-06-14 20:49:13 -04002407 start_monitor_and_boot or $failed = 1;
Steven Rostedta75fece2010-11-02 14:58:27 -04002408
2409 if (!$failed && $test_type ne "boot" && defined($run_test)) {
2410 do_run_test or $failed = 1;
2411 }
2412 end_monitor;
2413 next if ($failed);
Steven Rostedt5a391fb2010-11-02 14:57:43 -04002414 }
2415
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04002416 success $i;
Steven Rostedt2545eb62010-11-02 15:01:32 -04002417}
2418
Steven Rostedt5c42fc52010-11-02 14:57:01 -04002419if ($opt{"POWEROFF_ON_SUCCESS"}) {
Steven Rostedt75c3fda72010-11-02 14:57:21 -04002420 halt;
Steven Rostedt576f6272010-11-02 14:58:38 -04002421} elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot) {
Steven Rostedt75c3fda72010-11-02 14:57:21 -04002422 reboot;
Steven Rostedt5c42fc52010-11-02 14:57:01 -04002423}
Steven Rostedt75c3fda72010-11-02 14:57:21 -04002424
Steven Rostedte48c5292010-11-02 14:35:37 -04002425doprint "\n $successes of $opt{NUM_TESTS} tests were successful\n\n";
2426
Steven Rostedt2545eb62010-11-02 15:01:32 -04002427exit 0;