blob: 099ceeed4144109864b90507dc479edbc92e1b3d [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;
348
Steven Rostedt2545eb62010-11-02 15:01:32 -0400349 while (<IN>) {
350
351 # ignore blank lines and comments
352 next if (/^\s*$/ || /\s*\#/);
353
Steven Rostedta57419b2010-11-02 15:13:54 -0400354 if (/^\s*TEST_START(.*)/) {
355
356 $rest = $1;
357
358 if ($num_tests_set) {
359 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
360 }
361
362 my $old_test_num = $test_num;
Steven Rostedte48c5292010-11-02 14:35:37 -0400363 my $old_repeat = $repeat;
Steven Rostedta57419b2010-11-02 15:13:54 -0400364
365 $test_num += $repeat;
366 $default = 0;
367 $repeat = 1;
368
369 if ($rest =~ /\s+SKIP(.*)/) {
370 $rest = $1;
371 $skip = 1;
372 } else {
373 $skip = 0;
374 }
375
376 if ($rest =~ /\s+ITERATE\s+(\d+)(.*)$/) {
377 $repeat = $1;
378 $rest = $2;
379 $repeat_tests{"$test_num"} = $repeat;
380 }
381
382 if ($rest =~ /\s+SKIP(.*)/) {
383 $rest = $1;
384 $skip = 1;
385 }
386
387 if ($rest !~ /^\s*$/) {
388 die "$name: $.: Gargbage found after TEST_START\n$_";
389 }
390
391 if ($skip) {
392 $test_num = $old_test_num;
Steven Rostedte48c5292010-11-02 14:35:37 -0400393 $repeat = $old_repeat;
Steven Rostedta57419b2010-11-02 15:13:54 -0400394 }
395
396 } elsif (/^\s*DEFAULTS(.*)$/) {
397 $default = 1;
398
399 $rest = $1;
400
401 if ($rest =~ /\s+SKIP(.*)/) {
402 $rest = $1;
403 $skip = 1;
404 } else {
405 $skip = 0;
406 }
407
408 if ($rest !~ /^\s*$/) {
409 die "$name: $.: Gargbage found after DEFAULTS\n$_";
410 }
411
412 } elsif (/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) {
413
414 next if ($skip);
415
Steven Rostedt2545eb62010-11-02 15:01:32 -0400416 my $lvalue = $1;
417 my $rvalue = $2;
418
Steven Rostedta57419b2010-11-02 15:13:54 -0400419 if (!$default &&
420 ($lvalue eq "NUM_TESTS" ||
421 $lvalue eq "LOG_FILE" ||
422 $lvalue eq "CLEAR_LOG")) {
423 die "$name: $.: $lvalue must be set in DEFAULTS section\n";
Steven Rostedta75fece2010-11-02 14:58:27 -0400424 }
Steven Rostedta57419b2010-11-02 15:13:54 -0400425
426 if ($lvalue eq "NUM_TESTS") {
427 if ($test_num) {
428 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
429 }
430 if (!$default) {
431 die "$name: $.: NUM_TESTS must be set in default section\n";
432 }
433 $num_tests_set = 1;
434 }
435
436 if ($default || $lvalue =~ /\[\d+\]$/) {
437 set_value($lvalue, $rvalue);
438 } else {
439 my $val = "$lvalue\[$test_num\]";
440 set_value($val, $rvalue);
441
442 if ($repeat > 1) {
443 $repeats{$val} = $repeat;
444 }
445 }
Steven Rostedt77d942c2011-05-20 13:36:58 -0400446 } elsif (/^\s*([A-Z_\[\]\d]+)\s*:=\s*(.*?)\s*$/) {
447 next if ($skip);
448
449 my $lvalue = $1;
450 my $rvalue = $2;
451
452 # process config variables.
453 # Config variables are only active while reading the
454 # config and can be defined anywhere. They also ignore
455 # TEST_START and DEFAULTS, but are skipped if they are in
456 # on of these sections that have SKIP defined.
457 # The save variable can be
458 # defined multiple times and the new one simply overrides
459 # the prevous one.
460 set_variable($lvalue, $rvalue);
461
Steven Rostedta57419b2010-11-02 15:13:54 -0400462 } else {
463 die "$name: $.: Garbage found in config\n$_";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400464 }
465 }
466
467 close(IN);
Steven Rostedta75fece2010-11-02 14:58:27 -0400468
Steven Rostedta57419b2010-11-02 15:13:54 -0400469 if ($test_num) {
470 $test_num += $repeat - 1;
471 $opt{"NUM_TESTS"} = $test_num;
472 }
473
Steven Rostedt8d1491b2010-11-18 15:39:48 -0500474 # make sure we have all mandatory configs
475 get_ktest_configs;
476
Steven Rostedta75fece2010-11-02 14:58:27 -0400477 # set any defaults
478
479 foreach my $default (keys %default) {
480 if (!defined($opt{$default})) {
481 $opt{$default} = $default{$default};
482 }
483 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400484}
485
Steven Rostedt23715c3c2011-06-13 11:03:34 -0400486sub __eval_option {
487 my ($option, $i) = @_;
488
489 # Add space to evaluate the character before $
490 $option = " $option";
491 my $retval = "";
492
493 while ($option =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
494 my $start = $1;
495 my $var = $2;
496 my $end = $3;
497
498 # Append beginning of line
499 $retval = "$retval$start";
500
501 # If the iteration option OPT[$i] exists, then use that.
502 # otherwise see if the default OPT (without [$i]) exists.
503
504 my $o = "$var\[$i\]";
505
506 if (defined($opt{$o})) {
507 $o = $opt{$o};
508 $retval = "$retval$o";
509 } elsif (defined($opt{$var})) {
510 $o = $opt{$var};
511 $retval = "$retval$o";
512 } else {
513 $retval = "$retval\$\{$var\}";
514 }
515
516 $option = $end;
517 }
518
519 $retval = "$retval$option";
520
521 $retval =~ s/^ //;
522
523 return $retval;
524}
525
526sub eval_option {
527 my ($option, $i) = @_;
528
529 my $prev = "";
530
531 # Since an option can evaluate to another option,
532 # keep iterating until we do not evaluate any more
533 # options.
534 my $r = 0;
535 while ($prev ne $option) {
536 # Check for recursive evaluations.
537 # 100 deep should be more than enough.
538 if ($r++ > 100) {
539 die "Over 100 evaluations accurred with $option\n" .
540 "Check for recursive variables\n";
541 }
542 $prev = $option;
543 $option = __eval_option($option, $i);
544 }
545
546 return $option;
547}
548
Steven Rostedtd1e2f222010-11-08 16:39:57 -0500549sub _logit {
Steven Rostedt2545eb62010-11-02 15:01:32 -0400550 if (defined($opt{"LOG_FILE"})) {
551 open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}";
552 print OUT @_;
553 close(OUT);
554 }
555}
556
Steven Rostedtd1e2f222010-11-08 16:39:57 -0500557sub logit {
558 if (defined($opt{"LOG_FILE"})) {
559 _logit @_;
560 } else {
561 print @_;
562 }
563}
564
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400565sub doprint {
566 print @_;
Steven Rostedtd1e2f222010-11-08 16:39:57 -0500567 _logit @_;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400568}
569
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400570sub run_command;
571
572sub reboot {
573 # try to reboot normally
Steven Rostedte48c5292010-11-02 14:35:37 -0400574 if (run_command $reboot) {
Steven Rostedt576f6272010-11-02 14:58:38 -0400575 if (defined($powercycle_after_reboot)) {
576 sleep $powercycle_after_reboot;
577 run_command "$power_cycle";
578 }
579 } else {
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400580 # nope? power cycle it.
Steven Rostedta75fece2010-11-02 14:58:27 -0400581 run_command "$power_cycle";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400582 }
583}
584
Steven Rostedt576f6272010-11-02 14:58:38 -0400585sub do_not_reboot {
586 my $i = $iteration;
587
588 return $test_type eq "build" ||
589 ($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") ||
590 ($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build");
591}
592
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400593sub dodie {
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400594 doprint "CRITICAL FAILURE... ", @_, "\n";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400595
Steven Rostedt576f6272010-11-02 14:58:38 -0400596 my $i = $iteration;
597
598 if ($reboot_on_error && !do_not_reboot) {
599
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400600 doprint "REBOOTING\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400601 reboot;
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400602
Steven Rostedta75fece2010-11-02 14:58:27 -0400603 } elsif ($poweroff_on_error && defined($power_off)) {
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400604 doprint "POWERING OFF\n";
Steven Rostedta75fece2010-11-02 14:58:27 -0400605 `$power_off`;
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400606 }
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400607
Steven Rostedtf80802c2011-03-07 13:18:47 -0500608 if (defined($opt{"LOG_FILE"})) {
609 print " See $opt{LOG_FILE} for more info.\n";
610 }
611
Steven Rostedt576f6272010-11-02 14:58:38 -0400612 die @_, "\n";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400613}
614
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400615sub open_console {
616 my ($fp) = @_;
617
618 my $flags;
619
Steven Rostedta75fece2010-11-02 14:58:27 -0400620 my $pid = open($fp, "$console|") or
621 dodie "Can't open console $console";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400622
623 $flags = fcntl($fp, F_GETFL, 0) or
Steven Rostedt576f6272010-11-02 14:58:38 -0400624 dodie "Can't get flags for the socket: $!";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400625 $flags = fcntl($fp, F_SETFL, $flags | O_NONBLOCK) or
Steven Rostedt576f6272010-11-02 14:58:38 -0400626 dodie "Can't set flags for the socket: $!";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400627
628 return $pid;
629}
630
631sub close_console {
632 my ($fp, $pid) = @_;
633
634 doprint "kill child process $pid\n";
635 kill 2, $pid;
636
637 print "closing!\n";
638 close($fp);
639}
640
641sub start_monitor {
642 if ($monitor_cnt++) {
643 return;
644 }
645 $monitor_fp = \*MONFD;
646 $monitor_pid = open_console $monitor_fp;
Steven Rostedta75fece2010-11-02 14:58:27 -0400647
648 return;
649
650 open(MONFD, "Stop perl from warning about single use of MONFD");
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400651}
652
653sub end_monitor {
654 if (--$monitor_cnt) {
655 return;
656 }
657 close_console($monitor_fp, $monitor_pid);
658}
659
660sub wait_for_monitor {
661 my ($time) = @_;
662 my $line;
663
Steven Rostedta75fece2010-11-02 14:58:27 -0400664 doprint "** Wait for monitor to settle down **\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400665
666 # read the monitor and wait for the system to calm down
667 do {
668 $line = wait_for_input($monitor_fp, $time);
Steven Rostedta75fece2010-11-02 14:58:27 -0400669 print "$line" if (defined($line));
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400670 } while (defined($line));
Steven Rostedta75fece2010-11-02 14:58:27 -0400671 print "** Monitor flushed **\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400672}
673
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400674sub fail {
675
Steven Rostedta75fece2010-11-02 14:58:27 -0400676 if ($die_on_failure) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400677 dodie @_;
678 }
679
Steven Rostedta75fece2010-11-02 14:58:27 -0400680 doprint "FAILED\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400681
Steven Rostedt576f6272010-11-02 14:58:38 -0400682 my $i = $iteration;
683
Steven Rostedta75fece2010-11-02 14:58:27 -0400684 # no need to reboot for just building.
Steven Rostedt576f6272010-11-02 14:58:38 -0400685 if (!do_not_reboot) {
Steven Rostedta75fece2010-11-02 14:58:27 -0400686 doprint "REBOOTING\n";
687 reboot;
688 start_monitor;
689 wait_for_monitor $sleep_time;
690 end_monitor;
691 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400692
Steven Rostedt9064af52011-06-13 10:38:48 -0400693 my $name = "";
694
695 if (defined($test_name)) {
696 $name = " ($test_name)";
697 }
698
Steven Rostedt576f6272010-11-02 14:58:38 -0400699 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
700 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
Steven Rostedt9064af52011-06-13 10:38:48 -0400701 doprint "KTEST RESULT: TEST $i$name Failed: ", @_, "\n";
Steven Rostedt576f6272010-11-02 14:58:38 -0400702 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
703 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
Steven Rostedta75fece2010-11-02 14:58:27 -0400704
705 return 1 if (!defined($store_failures));
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400706
707 my @t = localtime;
708 my $date = sprintf "%04d%02d%02d%02d%02d%02d",
709 1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0];
710
Steven Rostedtcccae1a2010-11-09 12:21:32 -0500711 my $type = $build_type;
712 if ($type =~ /useconfig/) {
713 $type = "useconfig";
714 }
715
716 my $dir = "$machine-$test_type-$type-fail-$date";
Steven Rostedta75fece2010-11-02 14:58:27 -0400717 my $faildir = "$store_failures/$dir";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400718
719 if (!-d $faildir) {
720 mkpath($faildir) or
Steven Rostedta75fece2010-11-02 14:58:27 -0400721 die "can't create $faildir";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400722 }
Steven Rostedt51ad1dd2010-11-08 16:43:21 -0500723 if (-f "$output_config") {
724 cp "$output_config", "$faildir/config" or
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400725 die "failed to copy .config";
726 }
727 if (-f $buildlog) {
728 cp $buildlog, "$faildir/buildlog" or
729 die "failed to move $buildlog";
730 }
731 if (-f $dmesg) {
732 cp $dmesg, "$faildir/dmesg" or
733 die "failed to move $dmesg";
734 }
735
736 doprint "*** Saved info to $faildir ***\n";
737
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400738 return 1;
739}
740
Steven Rostedt2545eb62010-11-02 15:01:32 -0400741sub run_command {
742 my ($command) = @_;
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400743 my $dolog = 0;
744 my $dord = 0;
745 my $pid;
746
Steven Rostedte48c5292010-11-02 14:35:37 -0400747 $command =~ s/\$SSH_USER/$ssh_user/g;
748 $command =~ s/\$MACHINE/$machine/g;
749
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400750 doprint("$command ... ");
751
752 $pid = open(CMD, "$command 2>&1 |") or
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400753 (fail "unable to exec $command" and return 0);
Steven Rostedt2545eb62010-11-02 15:01:32 -0400754
755 if (defined($opt{"LOG_FILE"})) {
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400756 open(LOG, ">>$opt{LOG_FILE}") or
757 dodie "failed to write to log";
758 $dolog = 1;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400759 }
760
761 if (defined($redirect)) {
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400762 open (RD, ">$redirect") or
763 dodie "failed to write to redirect $redirect";
764 $dord = 1;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400765 }
766
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400767 while (<CMD>) {
768 print LOG if ($dolog);
769 print RD if ($dord);
770 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400771
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400772 waitpid($pid, 0);
Steven Rostedt2545eb62010-11-02 15:01:32 -0400773 my $failed = $?;
774
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400775 close(CMD);
776 close(LOG) if ($dolog);
777 close(RD) if ($dord);
778
Steven Rostedt2545eb62010-11-02 15:01:32 -0400779 if ($failed) {
780 doprint "FAILED!\n";
781 } else {
782 doprint "SUCCESS\n";
783 }
784
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400785 return !$failed;
786}
787
Steven Rostedte48c5292010-11-02 14:35:37 -0400788sub run_ssh {
789 my ($cmd) = @_;
790 my $cp_exec = $ssh_exec;
791
792 $cp_exec =~ s/\$SSH_COMMAND/$cmd/g;
793 return run_command "$cp_exec";
794}
795
796sub run_scp {
797 my ($src, $dst) = @_;
798 my $cp_scp = $scp_to_target;
799
800 $cp_scp =~ s/\$SRC_FILE/$src/g;
801 $cp_scp =~ s/\$DST_FILE/$dst/g;
802
803 return run_command "$cp_scp";
804}
805
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400806sub get_grub_index {
807
Steven Rostedta75fece2010-11-02 14:58:27 -0400808 if ($reboot_type ne "grub") {
809 return;
810 }
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400811 return if (defined($grub_number));
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400812
813 doprint "Find grub menu ... ";
814 $grub_number = -1;
Steven Rostedte48c5292010-11-02 14:35:37 -0400815
816 my $ssh_grub = $ssh_exec;
817 $ssh_grub =~ s,\$SSH_COMMAND,cat /boot/grub/menu.lst,g;
818
819 open(IN, "$ssh_grub |")
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400820 or die "unable to get menu.lst";
Steven Rostedte48c5292010-11-02 14:35:37 -0400821
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400822 while (<IN>) {
Steven Rostedta75fece2010-11-02 14:58:27 -0400823 if (/^\s*title\s+$grub_menu\s*$/) {
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400824 $grub_number++;
825 last;
826 } elsif (/^\s*title\s/) {
827 $grub_number++;
828 }
829 }
830 close(IN);
831
Steven Rostedta75fece2010-11-02 14:58:27 -0400832 die "Could not find '$grub_menu' in /boot/grub/menu on $machine"
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400833 if ($grub_number < 0);
834 doprint "$grub_number\n";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400835}
836
Steven Rostedt2545eb62010-11-02 15:01:32 -0400837sub wait_for_input
838{
839 my ($fp, $time) = @_;
840 my $rin;
841 my $ready;
842 my $line;
843 my $ch;
844
845 if (!defined($time)) {
846 $time = $timeout;
847 }
848
849 $rin = '';
850 vec($rin, fileno($fp), 1) = 1;
851 $ready = select($rin, undef, undef, $time);
852
853 $line = "";
854
855 # try to read one char at a time
856 while (sysread $fp, $ch, 1) {
857 $line .= $ch;
858 last if ($ch eq "\n");
859 }
860
861 if (!length($line)) {
862 return undef;
863 }
864
865 return $line;
866}
867
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400868sub reboot_to {
Steven Rostedta75fece2010-11-02 14:58:27 -0400869 if ($reboot_type eq "grub") {
Steven Rostedt4da46da2011-06-01 23:25:13 -0400870 run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch && reboot)'";
Steven Rostedta75fece2010-11-02 14:58:27 -0400871 return;
872 }
873
874 run_command "$reboot_script";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400875}
876
Steven Rostedta57419b2010-11-02 15:13:54 -0400877sub get_sha1 {
878 my ($commit) = @_;
879
880 doprint "git rev-list --max-count=1 $commit ... ";
881 my $sha1 = `git rev-list --max-count=1 $commit`;
882 my $ret = $?;
883
884 logit $sha1;
885
886 if ($ret) {
887 doprint "FAILED\n";
888 dodie "Failed to get git $commit";
889 }
890
891 print "SUCCESS\n";
892
893 chomp $sha1;
894
895 return $sha1;
896}
897
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400898sub monitor {
Steven Rostedt2545eb62010-11-02 15:01:32 -0400899 my $booted = 0;
900 my $bug = 0;
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400901 my $skip_call_trace = 0;
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400902 my $loops;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400903
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400904 wait_for_monitor 5;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400905
906 my $line;
907 my $full_line = "";
908
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400909 open(DMESG, "> $dmesg") or
910 die "unable to write to $dmesg";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400911
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400912 reboot_to;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400913
Steven Rostedt1c8a6172010-11-09 12:55:40 -0500914 my $success_start;
915 my $failure_start;
Steven Rostedt2d01b262011-03-08 09:47:54 -0500916 my $monitor_start = time;
917 my $done = 0;
Steven Rostedtf1a5b962011-06-13 10:30:00 -0400918 my $version_found = 0;
Steven Rostedt1c8a6172010-11-09 12:55:40 -0500919
Steven Rostedt2d01b262011-03-08 09:47:54 -0500920 while (!$done) {
Steven Rostedt2545eb62010-11-02 15:01:32 -0400921
Steven Rostedtecaf8e52011-06-13 10:48:10 -0400922 if ($bug && defined($stop_after_failure) &&
923 $stop_after_failure >= 0) {
924 my $time = $stop_after_failure - (time - $failure_start);
925 $line = wait_for_input($monitor_fp, $time);
926 if (!defined($line)) {
927 doprint "bug timed out after $booted_timeout seconds\n";
928 doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
929 last;
930 }
931 } elsif ($booted) {
Steven Rostedta75fece2010-11-02 14:58:27 -0400932 $line = wait_for_input($monitor_fp, $booted_timeout);
Steven Rostedtcd4f1d52011-06-13 10:26:27 -0400933 if (!defined($line)) {
934 my $s = $booted_timeout == 1 ? "" : "s";
935 doprint "Successful boot found: break after $booted_timeout second$s\n";
936 last;
937 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400938 } else {
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400939 $line = wait_for_input($monitor_fp);
Steven Rostedtcd4f1d52011-06-13 10:26:27 -0400940 if (!defined($line)) {
941 my $s = $timeout == 1 ? "" : "s";
942 doprint "Timed out after $timeout second$s\n";
943 last;
944 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400945 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400946
Steven Rostedt2545eb62010-11-02 15:01:32 -0400947 doprint $line;
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400948 print DMESG $line;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400949
950 # we are not guaranteed to get a full line
951 $full_line .= $line;
952
Steven Rostedta75fece2010-11-02 14:58:27 -0400953 if ($full_line =~ /$success_line/) {
Steven Rostedt2545eb62010-11-02 15:01:32 -0400954 $booted = 1;
Steven Rostedt1c8a6172010-11-09 12:55:40 -0500955 $success_start = time;
956 }
957
958 if ($booted && defined($stop_after_success) &&
959 $stop_after_success >= 0) {
960 my $now = time;
961 if ($now - $success_start >= $stop_after_success) {
962 doprint "Test forced to stop after $stop_after_success seconds after success\n";
963 last;
964 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400965 }
966
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400967 if ($full_line =~ /\[ backtrace testing \]/) {
968 $skip_call_trace = 1;
969 }
970
Steven Rostedt2545eb62010-11-02 15:01:32 -0400971 if ($full_line =~ /call trace:/i) {
Steven Rostedt46519202011-03-08 09:40:31 -0500972 if (!$bug && !$skip_call_trace) {
Steven Rostedt1c8a6172010-11-09 12:55:40 -0500973 $bug = 1;
974 $failure_start = time;
975 }
976 }
977
978 if ($bug && defined($stop_after_failure) &&
979 $stop_after_failure >= 0) {
980 my $now = time;
981 if ($now - $failure_start >= $stop_after_failure) {
982 doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
983 last;
984 }
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400985 }
986
987 if ($full_line =~ /\[ end of backtrace testing \]/) {
988 $skip_call_trace = 0;
989 }
990
991 if ($full_line =~ /Kernel panic -/) {
Steven Rostedt10abf112011-03-07 13:21:00 -0500992 $failure_start = time;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400993 $bug = 1;
994 }
995
Steven Rostedtf1a5b962011-06-13 10:30:00 -0400996 # Detect triple faults by testing the banner
997 if ($full_line =~ /\bLinux version (\S+).*\n/) {
998 if ($1 eq $version) {
999 $version_found = 1;
1000 } elsif ($version_found && $detect_triplefault) {
1001 # We already booted into the kernel we are testing,
1002 # but now we booted into another kernel?
1003 # Consider this a triple fault.
1004 doprint "Aleady booted in Linux kernel $version, but now\n";
1005 doprint "we booted into Linux kernel $1.\n";
1006 doprint "Assuming that this is a triple fault.\n";
1007 doprint "To disable this: set DETECT_TRIPLE_FAULT to 0\n";
1008 last;
1009 }
1010 }
1011
Steven Rostedt2545eb62010-11-02 15:01:32 -04001012 if ($line =~ /\n/) {
1013 $full_line = "";
1014 }
Steven Rostedt2d01b262011-03-08 09:47:54 -05001015
1016 if ($stop_test_after > 0 && !$booted && !$bug) {
1017 if (time - $monitor_start > $stop_test_after) {
Steven Rostedt4d62bf52011-05-20 09:14:35 -04001018 doprint "STOP_TEST_AFTER ($stop_test_after seconds) timed out\n";
Steven Rostedt2d01b262011-03-08 09:47:54 -05001019 $done = 1;
1020 }
1021 }
Steven Rostedt2545eb62010-11-02 15:01:32 -04001022 }
1023
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001024 close(DMESG);
Steven Rostedt2545eb62010-11-02 15:01:32 -04001025
Steven Rostedt2545eb62010-11-02 15:01:32 -04001026 if ($bug) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001027 return 0 if ($in_bisect);
Steven Rostedt576f6272010-11-02 14:58:38 -04001028 fail "failed - got a bug report" and return 0;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001029 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001030
Steven Rostedta75fece2010-11-02 14:58:27 -04001031 if (!$booted) {
1032 return 0 if ($in_bisect);
Steven Rostedt576f6272010-11-02 14:58:38 -04001033 fail "failed - never got a boot prompt." and return 0;
Steven Rostedta75fece2010-11-02 14:58:27 -04001034 }
1035
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001036 return 1;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001037}
1038
Steven Rostedtdb05cfe2011-06-13 11:09:22 -04001039sub do_post_install {
1040
1041 return if (!defined($post_install));
1042
1043 my $cp_post_install = $post_install;
1044 $cp_post_install =~ s/\$KERNEL_VERSION/$version/g;
1045 run_command "$cp_post_install" or
1046 dodie "Failed to run post install";
1047}
1048
Steven Rostedt2545eb62010-11-02 15:01:32 -04001049sub install {
1050
Steven Rostedte48c5292010-11-02 14:35:37 -04001051 run_scp "$outputdir/$build_target", "$target_image" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001052 dodie "failed to copy image";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001053
1054 my $install_mods = 0;
1055
1056 # should we process modules?
1057 $install_mods = 0;
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05001058 open(IN, "$output_config") or dodie("Can't read config file");
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001059 while (<IN>) {
1060 if (/CONFIG_MODULES(=y)?/) {
1061 $install_mods = 1 if (defined($1));
1062 last;
1063 }
1064 }
1065 close(IN);
1066
1067 if (!$install_mods) {
Steven Rostedtdb05cfe2011-06-13 11:09:22 -04001068 do_post_install;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001069 doprint "No modules needed\n";
1070 return;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001071 }
1072
Steven Rostedta75fece2010-11-02 14:58:27 -04001073 run_command "$make INSTALL_MOD_PATH=$tmpdir modules_install" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001074 dodie "Failed to install modules";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001075
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001076 my $modlib = "/lib/modules/$version";
Steven Rostedta57419b2010-11-02 15:13:54 -04001077 my $modtar = "ktest-mods.tar.bz2";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001078
Steven Rostedte48c5292010-11-02 14:35:37 -04001079 run_ssh "rm -rf $modlib" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001080 dodie "failed to remove old mods: $modlib";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001081
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001082 # would be nice if scp -r did not follow symbolic links
Steven Rostedta75fece2010-11-02 14:58:27 -04001083 run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001084 dodie "making tarball";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001085
Steven Rostedte48c5292010-11-02 14:35:37 -04001086 run_scp "$tmpdir/$modtar", "/tmp" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001087 dodie "failed to copy modules";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001088
Steven Rostedta75fece2010-11-02 14:58:27 -04001089 unlink "$tmpdir/$modtar";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001090
Steven Rostedte7b13442011-06-14 20:44:36 -04001091 run_ssh "'(cd / && tar xjf /tmp/$modtar)'" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001092 dodie "failed to tar modules";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001093
Steven Rostedte48c5292010-11-02 14:35:37 -04001094 run_ssh "rm -f /tmp/$modtar";
Steven Rostedt8b37ca82010-11-02 14:58:33 -04001095
Steven Rostedtdb05cfe2011-06-13 11:09:22 -04001096 do_post_install;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001097}
1098
Steven Rostedtddf607e2011-06-14 20:49:13 -04001099sub get_version {
1100 # get the release name
1101 doprint "$make kernelrelease ... ";
1102 $version = `$make kernelrelease | tail -1`;
1103 chomp($version);
1104 doprint "$version\n";
1105}
1106
1107sub start_monitor_and_boot {
1108 get_grub_index;
1109 get_version;
1110 install;
1111
1112 start_monitor;
1113 return monitor;
1114}
1115
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001116sub check_buildlog {
1117 my ($patch) = @_;
1118
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001119 my @files = `git show $patch | diffstat -l`;
1120
1121 open(IN, "git show $patch |") or
1122 dodie "failed to show $patch";
1123 while (<IN>) {
1124 if (m,^--- a/(.*),) {
1125 chomp $1;
1126 $files[$#files] = $1;
1127 }
1128 }
1129 close(IN);
1130
1131 open(IN, $buildlog) or dodie "Can't open $buildlog";
1132 while (<IN>) {
1133 if (/^\s*(.*?):.*(warning|error)/) {
1134 my $err = $1;
1135 foreach my $file (@files) {
Steven Rostedta75fece2010-11-02 14:58:27 -04001136 my $fullpath = "$builddir/$file";
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001137 if ($file eq $err || $fullpath eq $err) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001138 fail "$file built with warnings" and return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001139 }
1140 }
1141 }
1142 }
1143 close(IN);
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001144
1145 return 1;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001146}
1147
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001148sub apply_min_config {
1149 my $outconfig = "$output_config.new";
Steven Rostedt612b9e92011-03-07 13:27:43 -05001150
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001151 # Read the config file and remove anything that
1152 # is in the force_config hash (from minconfig and others)
1153 # then add the force config back.
1154
1155 doprint "Applying minimum configurations into $output_config.new\n";
1156
1157 open (OUT, ">$outconfig") or
1158 dodie "Can't create $outconfig";
1159
1160 if (-f $output_config) {
1161 open (IN, $output_config) or
1162 dodie "Failed to open $output_config";
1163 while (<IN>) {
1164 if (/^(# )?(CONFIG_[^\s=]*)/) {
1165 next if (defined($force_config{$2}));
1166 }
1167 print OUT;
1168 }
1169 close IN;
1170 }
1171 foreach my $config (keys %force_config) {
1172 print OUT "$force_config{$config}\n";
1173 }
1174 close OUT;
1175
1176 run_command "mv $outconfig $output_config";
1177}
1178
1179sub make_oldconfig {
1180
1181 apply_min_config;
1182
1183 if (!run_command "$make oldnoconfig") {
Steven Rostedt612b9e92011-03-07 13:27:43 -05001184 # Perhaps oldnoconfig doesn't exist in this version of the kernel
1185 # try a yes '' | oldconfig
1186 doprint "oldnoconfig failed, trying yes '' | make oldconfig\n";
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001187 run_command "yes '' | $make oldconfig" or
Steven Rostedt612b9e92011-03-07 13:27:43 -05001188 dodie "failed make config oldconfig";
1189 }
1190}
1191
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001192# read a config file and use this to force new configs.
1193sub load_force_config {
1194 my ($config) = @_;
1195
1196 open(IN, $config) or
1197 dodie "failed to read $config";
1198 while (<IN>) {
1199 chomp;
1200 if (/^(CONFIG[^\s=]*)(\s*=.*)/) {
1201 $force_config{$1} = $_;
1202 } elsif (/^# (CONFIG_\S*) is not set/) {
1203 $force_config{$1} = $_;
1204 }
1205 }
1206 close IN;
1207}
1208
Steven Rostedt2545eb62010-11-02 15:01:32 -04001209sub build {
1210 my ($type) = @_;
1211
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001212 unlink $buildlog;
1213
Steven Rostedt0bd6c1a2011-06-14 20:39:31 -04001214 if (defined($pre_build)) {
1215 my $ret = run_command $pre_build;
1216 if (!$ret && defined($pre_build_die) &&
1217 $pre_build_die) {
1218 dodie "failed to pre_build\n";
1219 }
1220 }
1221
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001222 if ($type =~ /^useconfig:(.*)/) {
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05001223 run_command "cp $1 $output_config" or
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001224 dodie "could not copy $1 to .config";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001225
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001226 $type = "oldconfig";
1227 }
1228
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001229 # old config can ask questions
1230 if ($type eq "oldconfig") {
Steven Rostedt9386c6a2010-11-08 16:35:48 -05001231 $type = "oldnoconfig";
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001232
1233 # allow for empty configs
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05001234 run_command "touch $output_config";
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001235
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05001236 run_command "mv $output_config $outputdir/config_temp" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001237 dodie "moving .config";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001238
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001239 if (!$noclean && !run_command "$make mrproper") {
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001240 dodie "make mrproper";
1241 }
1242
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05001243 run_command "mv $outputdir/config_temp $output_config" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001244 dodie "moving config_temp";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001245
1246 } elsif (!$noclean) {
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05001247 unlink "$output_config";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001248 run_command "$make mrproper" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001249 dodie "make mrproper";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001250 }
Steven Rostedt2545eb62010-11-02 15:01:32 -04001251
1252 # add something to distinguish this build
Steven Rostedta75fece2010-11-02 14:58:27 -04001253 open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file");
1254 print OUT "$localversion\n";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001255 close(OUT);
1256
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001257 if (defined($minconfig)) {
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001258 load_force_config($minconfig);
Steven Rostedt2545eb62010-11-02 15:01:32 -04001259 }
1260
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001261 if ($type ne "oldnoconfig") {
1262 run_command "$make $type" or
Steven Rostedt612b9e92011-03-07 13:27:43 -05001263 dodie "failed make config";
1264 }
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001265 # Run old config regardless, to enforce min configurations
1266 make_oldconfig;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001267
Steven Rostedta75fece2010-11-02 14:58:27 -04001268 $redirect = "$buildlog";
Steven Rostedt0bd6c1a2011-06-14 20:39:31 -04001269 my $build_ret = run_command "$make $build_options";
1270 undef $redirect;
1271
1272 if (defined($post_build)) {
1273 my $ret = run_command $post_build;
1274 if (!$ret && defined($post_build_die) &&
1275 $post_build_die) {
1276 dodie "failed to post_build\n";
1277 }
1278 }
1279
1280 if (!$build_ret) {
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001281 # bisect may need this to pass
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001282 return 0 if ($in_bisect);
1283 fail "failed build" and return 0;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001284 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001285
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001286 return 1;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001287}
1288
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001289sub halt {
Steven Rostedte48c5292010-11-02 14:35:37 -04001290 if (!run_ssh "halt" or defined($power_off)) {
Steven Rostedt576f6272010-11-02 14:58:38 -04001291 if (defined($poweroff_after_halt)) {
1292 sleep $poweroff_after_halt;
1293 run_command "$power_off";
1294 }
1295 } else {
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001296 # nope? the zap it!
Steven Rostedta75fece2010-11-02 14:58:27 -04001297 run_command "$power_off";
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001298 }
1299}
1300
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001301sub success {
1302 my ($i) = @_;
1303
Steven Rostedte48c5292010-11-02 14:35:37 -04001304 $successes++;
1305
Steven Rostedt9064af52011-06-13 10:38:48 -04001306 my $name = "";
1307
1308 if (defined($test_name)) {
1309 $name = " ($test_name)";
1310 }
1311
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001312 doprint "\n\n*******************************************\n";
1313 doprint "*******************************************\n";
Steven Rostedt9064af52011-06-13 10:38:48 -04001314 doprint "KTEST RESULT: TEST $i$name SUCCESS!!!! **\n";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001315 doprint "*******************************************\n";
1316 doprint "*******************************************\n";
1317
Steven Rostedt576f6272010-11-02 14:58:38 -04001318 if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) {
Steven Rostedta75fece2010-11-02 14:58:27 -04001319 doprint "Reboot and wait $sleep_time seconds\n";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001320 reboot;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001321 start_monitor;
Steven Rostedta75fece2010-11-02 14:58:27 -04001322 wait_for_monitor $sleep_time;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001323 end_monitor;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001324 }
1325}
1326
Steven Rostedtc960bb92011-03-08 09:22:39 -05001327sub answer_bisect {
1328 for (;;) {
1329 doprint "Pass or fail? [p/f]";
1330 my $ans = <STDIN>;
1331 chomp $ans;
1332 if ($ans eq "p" || $ans eq "P") {
1333 return 1;
1334 } elsif ($ans eq "f" || $ans eq "F") {
1335 return 0;
1336 } else {
1337 print "Please answer 'P' or 'F'\n";
1338 }
1339 }
1340}
1341
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001342sub child_run_test {
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001343 my $failed = 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001344
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001345 # child should have no power
Steven Rostedta75fece2010-11-02 14:58:27 -04001346 $reboot_on_error = 0;
1347 $poweroff_on_error = 0;
1348 $die_on_failure = 1;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001349
1350 run_command $run_test or $failed = 1;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001351 exit $failed;
1352}
1353
1354my $child_done;
1355
1356sub child_finished {
1357 $child_done = 1;
1358}
1359
1360sub do_run_test {
1361 my $child_pid;
1362 my $child_exit;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001363 my $line;
1364 my $full_line;
1365 my $bug = 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001366
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001367 wait_for_monitor 1;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001368
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001369 doprint "run test $run_test\n";
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001370
1371 $child_done = 0;
1372
1373 $SIG{CHLD} = qw(child_finished);
1374
1375 $child_pid = fork;
1376
1377 child_run_test if (!$child_pid);
1378
1379 $full_line = "";
1380
1381 do {
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001382 $line = wait_for_input($monitor_fp, 1);
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001383 if (defined($line)) {
1384
1385 # we are not guaranteed to get a full line
1386 $full_line .= $line;
Steven Rostedt8ea0e062011-03-08 09:44:35 -05001387 doprint $line;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001388
1389 if ($full_line =~ /call trace:/i) {
1390 $bug = 1;
1391 }
1392
1393 if ($full_line =~ /Kernel panic -/) {
1394 $bug = 1;
1395 }
1396
1397 if ($line =~ /\n/) {
1398 $full_line = "";
1399 }
1400 }
1401 } while (!$child_done && !$bug);
1402
1403 if ($bug) {
Steven Rostedt8ea0e062011-03-08 09:44:35 -05001404 my $failure_start = time;
1405 my $now;
1406 do {
1407 $line = wait_for_input($monitor_fp, 1);
1408 if (defined($line)) {
1409 doprint $line;
1410 }
1411 $now = time;
1412 if ($now - $failure_start >= $stop_after_failure) {
1413 last;
1414 }
1415 } while (defined($line));
1416
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001417 doprint "Detected kernel crash!\n";
1418 # kill the child with extreme prejudice
1419 kill 9, $child_pid;
1420 }
1421
1422 waitpid $child_pid, 0;
1423 $child_exit = $?;
1424
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001425 if ($bug || $child_exit) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001426 return 0 if $in_bisect;
1427 fail "test failed" and return 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001428 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001429 return 1;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001430}
1431
Steven Rostedta75fece2010-11-02 14:58:27 -04001432sub run_git_bisect {
1433 my ($command) = @_;
1434
1435 doprint "$command ... ";
1436
1437 my $output = `$command 2>&1`;
1438 my $ret = $?;
1439
1440 logit $output;
1441
1442 if ($ret) {
1443 doprint "FAILED\n";
1444 dodie "Failed to git bisect";
1445 }
1446
1447 doprint "SUCCESS\n";
1448 if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) {
1449 doprint "$1 [$2]\n";
1450 } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) {
1451 $bisect_bad = $1;
1452 doprint "Found bad commit... $1\n";
1453 return 0;
1454 } else {
1455 # we already logged it, just print it now.
1456 print $output;
1457 }
1458
1459 return 1;
1460}
1461
Steven Rostedtc23dca72011-03-08 09:26:31 -05001462sub bisect_reboot {
1463 doprint "Reboot and sleep $bisect_sleep_time seconds\n";
1464 reboot;
1465 start_monitor;
1466 wait_for_monitor $bisect_sleep_time;
1467 end_monitor;
1468}
1469
1470# returns 1 on success, 0 on failure, -1 on skip
Steven Rostedt0a05c762010-11-08 11:14:10 -05001471sub run_bisect_test {
1472 my ($type, $buildtype) = @_;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001473
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001474 my $failed = 0;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001475 my $result;
1476 my $output;
1477 my $ret;
1478
Steven Rostedt0a05c762010-11-08 11:14:10 -05001479 $in_bisect = 1;
1480
1481 build $buildtype or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001482
1483 if ($type ne "build") {
Steven Rostedtc23dca72011-03-08 09:26:31 -05001484 if ($failed && $bisect_skip) {
1485 $in_bisect = 0;
1486 return -1;
1487 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001488 dodie "Failed on build" if $failed;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001489
1490 # Now boot the box
Steven Rostedtddf607e2011-06-14 20:49:13 -04001491 start_monitor_and_boot or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001492
1493 if ($type ne "boot") {
Steven Rostedtc23dca72011-03-08 09:26:31 -05001494 if ($failed && $bisect_skip) {
1495 end_monitor;
1496 bisect_reboot;
1497 $in_bisect = 0;
1498 return -1;
1499 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001500 dodie "Failed on boot" if $failed;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001501
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001502 do_run_test or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001503 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001504 end_monitor;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001505 }
1506
1507 if ($failed) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001508 $result = 0;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001509 } else {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001510 $result = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001511 }
Steven Rostedt4025bc62011-05-20 09:16:29 -04001512
1513 # reboot the box to a kernel we can ssh to
1514 if ($type ne "build") {
1515 bisect_reboot;
1516 }
Steven Rostedt0a05c762010-11-08 11:14:10 -05001517 $in_bisect = 0;
1518
1519 return $result;
1520}
1521
1522sub run_bisect {
1523 my ($type) = @_;
1524 my $buildtype = "oldconfig";
1525
1526 # We should have a minconfig to use?
1527 if (defined($minconfig)) {
1528 $buildtype = "useconfig:$minconfig";
1529 }
1530
1531 my $ret = run_bisect_test $type, $buildtype;
1532
Steven Rostedtc960bb92011-03-08 09:22:39 -05001533 if ($bisect_manual) {
1534 $ret = answer_bisect;
1535 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001536
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04001537 # Are we looking for where it worked, not failed?
1538 if ($reverse_bisect) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001539 $ret = !$ret;
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04001540 }
1541
Steven Rostedtc23dca72011-03-08 09:26:31 -05001542 if ($ret > 0) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001543 return "good";
Steven Rostedtc23dca72011-03-08 09:26:31 -05001544 } elsif ($ret == 0) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001545 return "bad";
Steven Rostedtc23dca72011-03-08 09:26:31 -05001546 } elsif ($bisect_skip) {
1547 doprint "HIT A BAD COMMIT ... SKIPPING\n";
1548 return "skip";
Steven Rostedt0a05c762010-11-08 11:14:10 -05001549 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001550}
1551
1552sub bisect {
1553 my ($i) = @_;
1554
1555 my $result;
1556
1557 die "BISECT_GOOD[$i] not defined\n" if (!defined($opt{"BISECT_GOOD[$i]"}));
1558 die "BISECT_BAD[$i] not defined\n" if (!defined($opt{"BISECT_BAD[$i]"}));
1559 die "BISECT_TYPE[$i] not defined\n" if (!defined($opt{"BISECT_TYPE[$i]"}));
1560
1561 my $good = $opt{"BISECT_GOOD[$i]"};
1562 my $bad = $opt{"BISECT_BAD[$i]"};
1563 my $type = $opt{"BISECT_TYPE[$i]"};
Steven Rostedta75fece2010-11-02 14:58:27 -04001564 my $start = $opt{"BISECT_START[$i]"};
1565 my $replay = $opt{"BISECT_REPLAY[$i]"};
Steven Rostedt3410f6f2011-03-08 09:38:12 -05001566 my $start_files = $opt{"BISECT_FILES[$i]"};
1567
1568 if (defined($start_files)) {
1569 $start_files = " -- " . $start_files;
1570 } else {
1571 $start_files = "";
1572 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001573
Steven Rostedta57419b2010-11-02 15:13:54 -04001574 # convert to true sha1's
1575 $good = get_sha1($good);
1576 $bad = get_sha1($bad);
1577
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04001578 if (defined($opt{"BISECT_REVERSE[$i]"}) &&
1579 $opt{"BISECT_REVERSE[$i]"} == 1) {
1580 doprint "Performing a reverse bisect (bad is good, good is bad!)\n";
1581 $reverse_bisect = 1;
1582 } else {
1583 $reverse_bisect = 0;
1584 }
1585
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001586 # Can't have a test without having a test to run
1587 if ($type eq "test" && !defined($run_test)) {
1588 $type = "boot";
1589 }
1590
Steven Rostedta75fece2010-11-02 14:58:27 -04001591 my $check = $opt{"BISECT_CHECK[$i]"};
1592 if (defined($check) && $check ne "0") {
1593
1594 # get current HEAD
Steven Rostedta57419b2010-11-02 15:13:54 -04001595 my $head = get_sha1("HEAD");
Steven Rostedta75fece2010-11-02 14:58:27 -04001596
1597 if ($check ne "good") {
1598 doprint "TESTING BISECT BAD [$bad]\n";
1599 run_command "git checkout $bad" or
1600 die "Failed to checkout $bad";
1601
1602 $result = run_bisect $type;
1603
1604 if ($result ne "bad") {
1605 fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0;
1606 }
1607 }
1608
1609 if ($check ne "bad") {
1610 doprint "TESTING BISECT GOOD [$good]\n";
1611 run_command "git checkout $good" or
1612 die "Failed to checkout $good";
1613
1614 $result = run_bisect $type;
1615
1616 if ($result ne "good") {
1617 fail "Tested BISECT_GOOD [$good] and it failed" and return 0;
1618 }
1619 }
1620
1621 # checkout where we started
1622 run_command "git checkout $head" or
1623 die "Failed to checkout $head";
1624 }
1625
Steven Rostedt3410f6f2011-03-08 09:38:12 -05001626 run_command "git bisect start$start_files" or
Steven Rostedta75fece2010-11-02 14:58:27 -04001627 dodie "could not start bisect";
1628
1629 run_command "git bisect good $good" or
1630 dodie "could not set bisect good to $good";
1631
1632 run_git_bisect "git bisect bad $bad" or
1633 dodie "could not set bisect bad to $bad";
1634
1635 if (defined($replay)) {
1636 run_command "git bisect replay $replay" or
1637 dodie "failed to run replay";
1638 }
1639
1640 if (defined($start)) {
1641 run_command "git checkout $start" or
1642 dodie "failed to checkout $start";
1643 }
1644
1645 my $test;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001646 do {
1647 $result = run_bisect $type;
Steven Rostedta75fece2010-11-02 14:58:27 -04001648 $test = run_git_bisect "git bisect $result";
1649 } while ($test);
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001650
1651 run_command "git bisect log" or
1652 dodie "could not capture git bisect log";
1653
1654 run_command "git bisect reset" or
1655 dodie "could not reset git bisect";
1656
1657 doprint "Bad commit was [$bisect_bad]\n";
1658
Steven Rostedt0a05c762010-11-08 11:14:10 -05001659 success $i;
1660}
1661
1662my %config_ignore;
1663my %config_set;
1664
1665my %config_list;
1666my %null_config;
1667
1668my %dependency;
1669
1670sub process_config_ignore {
1671 my ($config) = @_;
1672
1673 open (IN, $config)
1674 or dodie "Failed to read $config";
1675
1676 while (<IN>) {
Steven Rostedt9bf71742011-06-01 23:27:19 -04001677 if (/^((CONFIG\S*)=.*)/) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001678 $config_ignore{$2} = $1;
1679 }
1680 }
1681
1682 close(IN);
1683}
1684
1685sub read_current_config {
1686 my ($config_ref) = @_;
1687
1688 %{$config_ref} = ();
1689 undef %{$config_ref};
1690
1691 my @key = keys %{$config_ref};
1692 if ($#key >= 0) {
1693 print "did not delete!\n";
1694 exit;
1695 }
1696 open (IN, "$output_config");
1697
1698 while (<IN>) {
1699 if (/^(CONFIG\S+)=(.*)/) {
1700 ${$config_ref}{$1} = $2;
1701 }
1702 }
1703 close(IN);
1704}
1705
1706sub get_dependencies {
1707 my ($config) = @_;
1708
1709 my $arr = $dependency{$config};
1710 if (!defined($arr)) {
1711 return ();
1712 }
1713
1714 my @deps = @{$arr};
1715
1716 foreach my $dep (@{$arr}) {
1717 print "ADD DEP $dep\n";
1718 @deps = (@deps, get_dependencies $dep);
1719 }
1720
1721 return @deps;
1722}
1723
1724sub create_config {
1725 my @configs = @_;
1726
1727 open(OUT, ">$output_config") or dodie "Can not write to $output_config";
1728
1729 foreach my $config (@configs) {
1730 print OUT "$config_set{$config}\n";
1731 my @deps = get_dependencies $config;
1732 foreach my $dep (@deps) {
1733 print OUT "$config_set{$dep}\n";
1734 }
1735 }
1736
1737 foreach my $config (keys %config_ignore) {
1738 print OUT "$config_ignore{$config}\n";
1739 }
1740 close(OUT);
1741
1742# exit;
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001743 make_oldconfig;
Steven Rostedt0a05c762010-11-08 11:14:10 -05001744}
1745
1746sub compare_configs {
1747 my (%a, %b) = @_;
1748
1749 foreach my $item (keys %a) {
1750 if (!defined($b{$item})) {
1751 print "diff $item\n";
1752 return 1;
1753 }
1754 delete $b{$item};
1755 }
1756
1757 my @keys = keys %b;
1758 if ($#keys) {
1759 print "diff2 $keys[0]\n";
1760 }
1761 return -1 if ($#keys >= 0);
1762
1763 return 0;
1764}
1765
1766sub run_config_bisect_test {
1767 my ($type) = @_;
1768
1769 return run_bisect_test $type, "oldconfig";
1770}
1771
1772sub process_passed {
1773 my (%configs) = @_;
1774
1775 doprint "These configs had no failure: (Enabling them for further compiles)\n";
1776 # Passed! All these configs are part of a good compile.
1777 # Add them to the min options.
1778 foreach my $config (keys %configs) {
1779 if (defined($config_list{$config})) {
1780 doprint " removing $config\n";
1781 $config_ignore{$config} = $config_list{$config};
1782 delete $config_list{$config};
1783 }
1784 }
Steven Rostedtf1a27852010-11-11 11:34:38 -05001785 doprint "config copied to $outputdir/config_good\n";
1786 run_command "cp -f $output_config $outputdir/config_good";
Steven Rostedt0a05c762010-11-08 11:14:10 -05001787}
1788
1789sub process_failed {
1790 my ($config) = @_;
1791
1792 doprint "\n\n***************************************\n";
1793 doprint "Found bad config: $config\n";
1794 doprint "***************************************\n\n";
1795}
1796
1797sub run_config_bisect {
1798
1799 my @start_list = keys %config_list;
1800
1801 if ($#start_list < 0) {
1802 doprint "No more configs to test!!!\n";
1803 return -1;
1804 }
1805
1806 doprint "***** RUN TEST ***\n";
1807 my $type = $opt{"CONFIG_BISECT_TYPE[$iteration]"};
1808 my $ret;
1809 my %current_config;
1810
1811 my $count = $#start_list + 1;
1812 doprint " $count configs to test\n";
1813
1814 my $half = int($#start_list / 2);
1815
1816 do {
1817 my @tophalf = @start_list[0 .. $half];
1818
1819 create_config @tophalf;
1820 read_current_config \%current_config;
1821
1822 $count = $#tophalf + 1;
1823 doprint "Testing $count configs\n";
1824 my $found = 0;
1825 # make sure we test something
1826 foreach my $config (@tophalf) {
1827 if (defined($current_config{$config})) {
1828 logit " $config\n";
1829 $found = 1;
1830 }
1831 }
1832 if (!$found) {
1833 # try the other half
1834 doprint "Top half produced no set configs, trying bottom half\n";
Steven Rostedt4c8cc552011-06-01 23:22:30 -04001835 @tophalf = @start_list[$half + 1 .. $#start_list];
Steven Rostedt0a05c762010-11-08 11:14:10 -05001836 create_config @tophalf;
1837 read_current_config \%current_config;
1838 foreach my $config (@tophalf) {
1839 if (defined($current_config{$config})) {
1840 logit " $config\n";
1841 $found = 1;
1842 }
1843 }
1844 if (!$found) {
1845 doprint "Failed: Can't make new config with current configs\n";
1846 foreach my $config (@start_list) {
1847 doprint " CONFIG: $config\n";
1848 }
1849 return -1;
1850 }
1851 $count = $#tophalf + 1;
1852 doprint "Testing $count configs\n";
1853 }
1854
1855 $ret = run_config_bisect_test $type;
Steven Rostedtc960bb92011-03-08 09:22:39 -05001856 if ($bisect_manual) {
1857 $ret = answer_bisect;
1858 }
Steven Rostedt0a05c762010-11-08 11:14:10 -05001859 if ($ret) {
1860 process_passed %current_config;
1861 return 0;
1862 }
1863
1864 doprint "This config had a failure.\n";
1865 doprint "Removing these configs that were not set in this config:\n";
Steven Rostedtf1a27852010-11-11 11:34:38 -05001866 doprint "config copied to $outputdir/config_bad\n";
1867 run_command "cp -f $output_config $outputdir/config_bad";
Steven Rostedt0a05c762010-11-08 11:14:10 -05001868
1869 # A config exists in this group that was bad.
1870 foreach my $config (keys %config_list) {
1871 if (!defined($current_config{$config})) {
1872 doprint " removing $config\n";
1873 delete $config_list{$config};
1874 }
1875 }
1876
1877 @start_list = @tophalf;
1878
1879 if ($#start_list == 0) {
1880 process_failed $start_list[0];
1881 return 1;
1882 }
1883
1884 # remove half the configs we are looking at and see if
1885 # they are good.
1886 $half = int($#start_list / 2);
Steven Rostedt4c8cc552011-06-01 23:22:30 -04001887 } while ($#start_list > 0);
Steven Rostedt0a05c762010-11-08 11:14:10 -05001888
Steven Rostedtc960bb92011-03-08 09:22:39 -05001889 # we found a single config, try it again unless we are running manually
1890
1891 if ($bisect_manual) {
1892 process_failed $start_list[0];
1893 return 1;
1894 }
1895
Steven Rostedt0a05c762010-11-08 11:14:10 -05001896 my @tophalf = @start_list[0 .. 0];
1897
1898 $ret = run_config_bisect_test $type;
1899 if ($ret) {
1900 process_passed %current_config;
1901 return 0;
1902 }
1903
1904 process_failed $start_list[0];
1905 return 1;
1906}
1907
1908sub config_bisect {
1909 my ($i) = @_;
1910
1911 my $start_config = $opt{"CONFIG_BISECT[$i]"};
1912
1913 my $tmpconfig = "$tmpdir/use_config";
1914
Steven Rostedt30f75da2011-06-13 10:35:35 -04001915 if (defined($config_bisect_good)) {
1916 process_config_ignore $config_bisect_good;
1917 }
1918
Steven Rostedt0a05c762010-11-08 11:14:10 -05001919 # Make the file with the bad config and the min config
1920 if (defined($minconfig)) {
1921 # read the min config for things to ignore
1922 run_command "cp $minconfig $tmpconfig" or
1923 dodie "failed to copy $minconfig to $tmpconfig";
1924 } else {
1925 unlink $tmpconfig;
1926 }
1927
1928 # Add other configs
1929 if (defined($addconfig)) {
1930 run_command "cat $addconfig >> $tmpconfig" or
1931 dodie "failed to append $addconfig";
1932 }
1933
Steven Rostedt0a05c762010-11-08 11:14:10 -05001934 if (-f $tmpconfig) {
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001935 load_force_config($tmpconfig);
Steven Rostedt0a05c762010-11-08 11:14:10 -05001936 process_config_ignore $tmpconfig;
1937 }
1938
1939 # now process the start config
1940 run_command "cp $start_config $output_config" or
1941 dodie "failed to copy $start_config to $output_config";
1942
1943 # read directly what we want to check
1944 my %config_check;
1945 open (IN, $output_config)
1946 or dodie "faied to open $output_config";
1947
1948 while (<IN>) {
1949 if (/^((CONFIG\S*)=.*)/) {
1950 $config_check{$2} = $1;
1951 }
1952 }
1953 close(IN);
1954
1955 # Now run oldconfig with the minconfig (and addconfigs)
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001956 make_oldconfig;
Steven Rostedt0a05c762010-11-08 11:14:10 -05001957
1958 # check to see what we lost (or gained)
1959 open (IN, $output_config)
1960 or dodie "Failed to read $start_config";
1961
1962 my %removed_configs;
1963 my %added_configs;
1964
1965 while (<IN>) {
1966 if (/^((CONFIG\S*)=.*)/) {
1967 # save off all options
1968 $config_set{$2} = $1;
1969 if (defined($config_check{$2})) {
1970 if (defined($config_ignore{$2})) {
1971 $removed_configs{$2} = $1;
1972 } else {
1973 $config_list{$2} = $1;
1974 }
1975 } elsif (!defined($config_ignore{$2})) {
1976 $added_configs{$2} = $1;
1977 $config_list{$2} = $1;
1978 }
1979 }
1980 }
1981 close(IN);
1982
1983 my @confs = keys %removed_configs;
1984 if ($#confs >= 0) {
1985 doprint "Configs overridden by default configs and removed from check:\n";
1986 foreach my $config (@confs) {
1987 doprint " $config\n";
1988 }
1989 }
1990 @confs = keys %added_configs;
1991 if ($#confs >= 0) {
1992 doprint "Configs appearing in make oldconfig and added:\n";
1993 foreach my $config (@confs) {
1994 doprint " $config\n";
1995 }
1996 }
1997
1998 my %config_test;
1999 my $once = 0;
2000
2001 # Sometimes kconfig does weird things. We must make sure
2002 # that the config we autocreate has everything we need
2003 # to test, otherwise we may miss testing configs, or
2004 # may not be able to create a new config.
2005 # Here we create a config with everything set.
2006 create_config (keys %config_list);
2007 read_current_config \%config_test;
2008 foreach my $config (keys %config_list) {
2009 if (!defined($config_test{$config})) {
2010 if (!$once) {
2011 $once = 1;
2012 doprint "Configs not produced by kconfig (will not be checked):\n";
2013 }
2014 doprint " $config\n";
2015 delete $config_list{$config};
2016 }
2017 }
2018 my $ret;
2019 do {
2020 $ret = run_config_bisect;
2021 } while (!$ret);
2022
2023 return $ret if ($ret < 0);
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04002024
2025 success $i;
2026}
2027
Steven Rostedt27d934b2011-05-20 09:18:18 -04002028sub patchcheck_reboot {
2029 doprint "Reboot and sleep $patchcheck_sleep_time seconds\n";
2030 reboot;
2031 start_monitor;
2032 wait_for_monitor $patchcheck_sleep_time;
2033 end_monitor;
2034}
2035
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002036sub patchcheck {
2037 my ($i) = @_;
2038
2039 die "PATCHCHECK_START[$i] not defined\n"
2040 if (!defined($opt{"PATCHCHECK_START[$i]"}));
2041 die "PATCHCHECK_TYPE[$i] not defined\n"
2042 if (!defined($opt{"PATCHCHECK_TYPE[$i]"}));
2043
2044 my $start = $opt{"PATCHCHECK_START[$i]"};
2045
2046 my $end = "HEAD";
2047 if (defined($opt{"PATCHCHECK_END[$i]"})) {
2048 $end = $opt{"PATCHCHECK_END[$i]"};
2049 }
2050
Steven Rostedta57419b2010-11-02 15:13:54 -04002051 # Get the true sha1's since we can use things like HEAD~3
2052 $start = get_sha1($start);
2053 $end = get_sha1($end);
2054
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002055 my $type = $opt{"PATCHCHECK_TYPE[$i]"};
2056
2057 # Can't have a test without having a test to run
2058 if ($type eq "test" && !defined($run_test)) {
2059 $type = "boot";
2060 }
2061
2062 open (IN, "git log --pretty=oneline $end|") or
2063 dodie "could not get git list";
2064
2065 my @list;
2066
2067 while (<IN>) {
2068 chomp;
2069 $list[$#list+1] = $_;
2070 last if (/^$start/);
2071 }
2072 close(IN);
2073
2074 if ($list[$#list] !~ /^$start/) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002075 fail "SHA1 $start not found";
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002076 }
2077
2078 # go backwards in the list
2079 @list = reverse @list;
2080
2081 my $save_clean = $noclean;
Steven Rostedt19902072011-06-14 20:46:25 -04002082 my %ignored_warnings;
2083
2084 if (defined($ignore_warnings)) {
2085 foreach my $sha1 (split /\s+/, $ignore_warnings) {
2086 $ignored_warnings{$sha1} = 1;
2087 }
2088 }
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002089
2090 $in_patchcheck = 1;
2091 foreach my $item (@list) {
2092 my $sha1 = $item;
2093 $sha1 =~ s/^([[:xdigit:]]+).*/$1/;
2094
2095 doprint "\nProcessing commit $item\n\n";
2096
2097 run_command "git checkout $sha1" or
2098 die "Failed to checkout $sha1";
2099
2100 # only clean on the first and last patch
2101 if ($item eq $list[0] ||
2102 $item eq $list[$#list]) {
2103 $noclean = $save_clean;
2104 } else {
2105 $noclean = 1;
2106 }
2107
2108 if (defined($minconfig)) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002109 build "useconfig:$minconfig" or return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002110 } else {
2111 # ?? no config to use?
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002112 build "oldconfig" or return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002113 }
2114
Steven Rostedt19902072011-06-14 20:46:25 -04002115
2116 if (!defined($ignored_warnings{$sha1})) {
2117 check_buildlog $sha1 or return 0;
2118 }
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002119
2120 next if ($type eq "build");
2121
Steven Rostedt7faafbd2010-11-02 14:58:22 -04002122 my $failed = 0;
2123
Steven Rostedtddf607e2011-06-14 20:49:13 -04002124 start_monitor_and_boot or $failed = 1;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04002125
2126 if (!$failed && $type ne "boot"){
2127 do_run_test or $failed = 1;
2128 }
2129 end_monitor;
2130 return 0 if ($failed);
2131
Steven Rostedt27d934b2011-05-20 09:18:18 -04002132 patchcheck_reboot;
2133
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002134 }
2135 $in_patchcheck = 0;
2136 success $i;
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002137
2138 return 1;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002139}
2140
Steven Rostedt8d1491b2010-11-18 15:39:48 -05002141$#ARGV < 1 or die "ktest.pl version: $VERSION\n usage: ktest.pl config-file\n";
Steven Rostedt2545eb62010-11-02 15:01:32 -04002142
Steven Rostedt8d1491b2010-11-18 15:39:48 -05002143if ($#ARGV == 0) {
2144 $ktest_config = $ARGV[0];
2145 if (! -f $ktest_config) {
2146 print "$ktest_config does not exist.\n";
2147 my $ans;
2148 for (;;) {
2149 print "Create it? [Y/n] ";
2150 $ans = <STDIN>;
2151 chomp $ans;
2152 if ($ans =~ /^\s*$/) {
2153 $ans = "y";
2154 }
2155 last if ($ans =~ /^y$/i || $ans =~ /^n$/i);
2156 print "Please answer either 'y' or 'n'.\n";
2157 }
2158 if ($ans !~ /^y$/i) {
2159 exit 0;
2160 }
2161 }
2162} else {
2163 $ktest_config = "ktest.conf";
2164}
2165
2166if (! -f $ktest_config) {
2167 open(OUT, ">$ktest_config") or die "Can not create $ktest_config";
2168 print OUT << "EOF"
2169# Generated by ktest.pl
2170#
2171# Define each test with TEST_START
2172# The config options below it will override the defaults
2173TEST_START
2174
2175DEFAULTS
2176EOF
2177;
2178 close(OUT);
2179}
2180read_config $ktest_config;
2181
Steven Rostedt23715c3c2011-06-13 11:03:34 -04002182if (defined($opt{"LOG_FILE"})) {
2183 $opt{"LOG_FILE"} = eval_option($opt{"LOG_FILE"}, -1);
2184}
2185
Steven Rostedt8d1491b2010-11-18 15:39:48 -05002186# Append any configs entered in manually to the config file.
2187my @new_configs = keys %entered_configs;
2188if ($#new_configs >= 0) {
2189 print "\nAppending entered in configs to $ktest_config\n";
2190 open(OUT, ">>$ktest_config") or die "Can not append to $ktest_config";
2191 foreach my $config (@new_configs) {
2192 print OUT "$config = $entered_configs{$config}\n";
2193 $opt{$config} = $entered_configs{$config};
2194 }
2195}
Steven Rostedt2545eb62010-11-02 15:01:32 -04002196
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002197if ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) {
2198 unlink $opt{"LOG_FILE"};
2199}
Steven Rostedt2545eb62010-11-02 15:01:32 -04002200
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002201doprint "\n\nSTARTING AUTOMATED TESTS\n\n";
2202
Steven Rostedta57419b2010-11-02 15:13:54 -04002203for (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) {
2204
2205 if (!$i) {
2206 doprint "DEFAULT OPTIONS:\n";
2207 } else {
2208 doprint "\nTEST $i OPTIONS";
2209 if (defined($repeat_tests{$i})) {
2210 $repeat = $repeat_tests{$i};
2211 doprint " ITERATE $repeat";
2212 }
2213 doprint "\n";
2214 }
2215
2216 foreach my $option (sort keys %opt) {
2217
2218 if ($option =~ /\[(\d+)\]$/) {
2219 next if ($i != $1);
2220 } else {
2221 next if ($i);
2222 }
2223
2224 doprint "$option = $opt{$option}\n";
2225 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002226}
Steven Rostedt2545eb62010-11-02 15:01:32 -04002227
Steven Rostedt2a625122011-05-20 15:48:59 -04002228sub __set_test_option {
Steven Rostedt5a391fb2010-11-02 14:57:43 -04002229 my ($name, $i) = @_;
2230
2231 my $option = "$name\[$i\]";
2232
2233 if (defined($opt{$option})) {
2234 return $opt{$option};
2235 }
2236
Steven Rostedta57419b2010-11-02 15:13:54 -04002237 foreach my $test (keys %repeat_tests) {
2238 if ($i >= $test &&
2239 $i < $test + $repeat_tests{$test}) {
2240 $option = "$name\[$test\]";
2241 if (defined($opt{$option})) {
2242 return $opt{$option};
2243 }
2244 }
2245 }
2246
Steven Rostedt5a391fb2010-11-02 14:57:43 -04002247 if (defined($opt{$name})) {
2248 return $opt{$name};
2249 }
2250
2251 return undef;
2252}
2253
Steven Rostedt2a625122011-05-20 15:48:59 -04002254sub set_test_option {
2255 my ($name, $i) = @_;
2256
2257 my $option = __set_test_option($name, $i);
2258 return $option if (!defined($option));
2259
Steven Rostedt23715c3c2011-06-13 11:03:34 -04002260 return eval_option($option, $i);
Steven Rostedt2a625122011-05-20 15:48:59 -04002261}
2262
Steven Rostedt2545eb62010-11-02 15:01:32 -04002263# First we need to do is the builds
Steven Rostedta75fece2010-11-02 14:58:27 -04002264for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
Steven Rostedt2545eb62010-11-02 15:01:32 -04002265
Steven Rostedt576f6272010-11-02 14:58:38 -04002266 $iteration = $i;
2267
Steven Rostedta75fece2010-11-02 14:58:27 -04002268 my $makecmd = set_test_option("MAKE_CMD", $i);
2269
2270 $machine = set_test_option("MACHINE", $i);
Steven Rostedte48c5292010-11-02 14:35:37 -04002271 $ssh_user = set_test_option("SSH_USER", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002272 $tmpdir = set_test_option("TMP_DIR", $i);
2273 $outputdir = set_test_option("OUTPUT_DIR", $i);
2274 $builddir = set_test_option("BUILD_DIR", $i);
2275 $test_type = set_test_option("TEST_TYPE", $i);
2276 $build_type = set_test_option("BUILD_TYPE", $i);
2277 $build_options = set_test_option("BUILD_OPTIONS", $i);
Steven Rostedt0bd6c1a2011-06-14 20:39:31 -04002278 $pre_build = set_test_option("PRE_BUILD", $i);
2279 $post_build = set_test_option("POST_BUILD", $i);
2280 $pre_build_die = set_test_option("PRE_BUILD_DIE", $i);
2281 $post_build_die = set_test_option("POST_BUILD_DIE", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002282 $power_cycle = set_test_option("POWER_CYCLE", $i);
Steven Rostedte48c5292010-11-02 14:35:37 -04002283 $reboot = set_test_option("REBOOT", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002284 $noclean = set_test_option("BUILD_NOCLEAN", $i);
2285 $minconfig = set_test_option("MIN_CONFIG", $i);
2286 $run_test = set_test_option("TEST", $i);
2287 $addconfig = set_test_option("ADD_CONFIG", $i);
2288 $reboot_type = set_test_option("REBOOT_TYPE", $i);
2289 $grub_menu = set_test_option("GRUB_MENU", $i);
Steven Rostedt8b37ca82010-11-02 14:58:33 -04002290 $post_install = set_test_option("POST_INSTALL", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002291 $reboot_script = set_test_option("REBOOT_SCRIPT", $i);
2292 $reboot_on_error = set_test_option("REBOOT_ON_ERROR", $i);
2293 $poweroff_on_error = set_test_option("POWEROFF_ON_ERROR", $i);
2294 $die_on_failure = set_test_option("DIE_ON_FAILURE", $i);
2295 $power_off = set_test_option("POWER_OFF", $i);
Steven Rostedt576f6272010-11-02 14:58:38 -04002296 $powercycle_after_reboot = set_test_option("POWERCYCLE_AFTER_REBOOT", $i);
2297 $poweroff_after_halt = set_test_option("POWEROFF_AFTER_HALT", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002298 $sleep_time = set_test_option("SLEEP_TIME", $i);
2299 $bisect_sleep_time = set_test_option("BISECT_SLEEP_TIME", $i);
Steven Rostedt27d934b2011-05-20 09:18:18 -04002300 $patchcheck_sleep_time = set_test_option("PATCHCHECK_SLEEP_TIME", $i);
Steven Rostedt19902072011-06-14 20:46:25 -04002301 $ignore_warnings = set_test_option("IGNORE_WARNINGS", $i);
Steven Rostedtc960bb92011-03-08 09:22:39 -05002302 $bisect_manual = set_test_option("BISECT_MANUAL", $i);
Steven Rostedtc23dca72011-03-08 09:26:31 -05002303 $bisect_skip = set_test_option("BISECT_SKIP", $i);
Steven Rostedt30f75da2011-06-13 10:35:35 -04002304 $config_bisect_good = set_test_option("CONFIG_BISECT_GOOD", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002305 $store_failures = set_test_option("STORE_FAILURES", $i);
Steven Rostedt9064af52011-06-13 10:38:48 -04002306 $test_name = set_test_option("TEST_NAME", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002307 $timeout = set_test_option("TIMEOUT", $i);
2308 $booted_timeout = set_test_option("BOOTED_TIMEOUT", $i);
2309 $console = set_test_option("CONSOLE", $i);
Steven Rostedtf1a5b962011-06-13 10:30:00 -04002310 $detect_triplefault = set_test_option("DETECT_TRIPLE_FAULT", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002311 $success_line = set_test_option("SUCCESS_LINE", $i);
Steven Rostedt1c8a6172010-11-09 12:55:40 -05002312 $stop_after_success = set_test_option("STOP_AFTER_SUCCESS", $i);
2313 $stop_after_failure = set_test_option("STOP_AFTER_FAILURE", $i);
Steven Rostedt2d01b262011-03-08 09:47:54 -05002314 $stop_test_after = set_test_option("STOP_TEST_AFTER", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002315 $build_target = set_test_option("BUILD_TARGET", $i);
Steven Rostedte48c5292010-11-02 14:35:37 -04002316 $ssh_exec = set_test_option("SSH_EXEC", $i);
2317 $scp_to_target = set_test_option("SCP_TO_TARGET", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002318 $target_image = set_test_option("TARGET_IMAGE", $i);
2319 $localversion = set_test_option("LOCALVERSION", $i);
2320
2321 chdir $builddir || die "can't change directory to $builddir";
2322
2323 if (!-d $tmpdir) {
2324 mkpath($tmpdir) or
2325 die "can't create $tmpdir";
2326 }
2327
Steven Rostedte48c5292010-11-02 14:35:37 -04002328 $ENV{"SSH_USER"} = $ssh_user;
2329 $ENV{"MACHINE"} = $machine;
2330
Steven Rostedta75fece2010-11-02 14:58:27 -04002331 $target = "$ssh_user\@$machine";
2332
2333 $buildlog = "$tmpdir/buildlog-$machine";
2334 $dmesg = "$tmpdir/dmesg-$machine";
2335 $make = "$makecmd O=$outputdir";
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05002336 $output_config = "$outputdir/.config";
Steven Rostedta75fece2010-11-02 14:58:27 -04002337
2338 if ($reboot_type eq "grub") {
Steven Rostedt576f6272010-11-02 14:58:38 -04002339 dodie "GRUB_MENU not defined" if (!defined($grub_menu));
Steven Rostedta75fece2010-11-02 14:58:27 -04002340 } elsif (!defined($reboot_script)) {
Steven Rostedt576f6272010-11-02 14:58:38 -04002341 dodie "REBOOT_SCRIPT not defined"
Steven Rostedta75fece2010-11-02 14:58:27 -04002342 }
2343
2344 my $run_type = $build_type;
2345 if ($test_type eq "patchcheck") {
2346 $run_type = $opt{"PATCHCHECK_TYPE[$i]"};
2347 } elsif ($test_type eq "bisect") {
2348 $run_type = $opt{"BISECT_TYPE[$i]"};
Steven Rostedt0a05c762010-11-08 11:14:10 -05002349 } elsif ($test_type eq "config_bisect") {
2350 $run_type = $opt{"CONFIG_BISECT_TYPE[$i]"};
Steven Rostedta75fece2010-11-02 14:58:27 -04002351 }
2352
2353 # mistake in config file?
2354 if (!defined($run_type)) {
2355 $run_type = "ERROR";
2356 }
Steven Rostedt2545eb62010-11-02 15:01:32 -04002357
2358 doprint "\n\n";
Steven Rostedta75fece2010-11-02 14:58:27 -04002359 doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type\n\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -04002360
2361 unlink $dmesg;
2362 unlink $buildlog;
Steven Rostedt2545eb62010-11-02 15:01:32 -04002363
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002364 if (!defined($minconfig)) {
2365 $minconfig = $addconfig;
2366
2367 } elsif (defined($addconfig)) {
Steven Rostedt9be2e6b2010-11-09 12:20:21 -05002368 run_command "cat $addconfig $minconfig > $tmpdir/add_config" or
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002369 dodie "Failed to create temp config";
Steven Rostedt9be2e6b2010-11-09 12:20:21 -05002370 $minconfig = "$tmpdir/add_config";
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002371 }
2372
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002373 my $checkout = $opt{"CHECKOUT[$i]"};
2374 if (defined($checkout)) {
2375 run_command "git checkout $checkout" or
2376 die "failed to checkout $checkout";
2377 }
2378
Steven Rostedta75fece2010-11-02 14:58:27 -04002379 if ($test_type eq "bisect") {
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04002380 bisect $i;
2381 next;
Steven Rostedt0a05c762010-11-08 11:14:10 -05002382 } elsif ($test_type eq "config_bisect") {
2383 config_bisect $i;
2384 next;
Steven Rostedta75fece2010-11-02 14:58:27 -04002385 } elsif ($test_type eq "patchcheck") {
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002386 patchcheck $i;
2387 next;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04002388 }
2389
Steven Rostedt7faafbd2010-11-02 14:58:22 -04002390 if ($build_type ne "nobuild") {
2391 build $build_type or next;
Steven Rostedt2545eb62010-11-02 15:01:32 -04002392 }
2393
Steven Rostedta75fece2010-11-02 14:58:27 -04002394 if ($test_type ne "build") {
Steven Rostedta75fece2010-11-02 14:58:27 -04002395 my $failed = 0;
Steven Rostedtddf607e2011-06-14 20:49:13 -04002396 start_monitor_and_boot or $failed = 1;
Steven Rostedta75fece2010-11-02 14:58:27 -04002397
2398 if (!$failed && $test_type ne "boot" && defined($run_test)) {
2399 do_run_test or $failed = 1;
2400 }
2401 end_monitor;
2402 next if ($failed);
Steven Rostedt5a391fb2010-11-02 14:57:43 -04002403 }
2404
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04002405 success $i;
Steven Rostedt2545eb62010-11-02 15:01:32 -04002406}
2407
Steven Rostedt5c42fc52010-11-02 14:57:01 -04002408if ($opt{"POWEROFF_ON_SUCCESS"}) {
Steven Rostedt75c3fda72010-11-02 14:57:21 -04002409 halt;
Steven Rostedt576f6272010-11-02 14:58:38 -04002410} elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot) {
Steven Rostedt75c3fda72010-11-02 14:57:21 -04002411 reboot;
Steven Rostedt5c42fc52010-11-02 14:57:01 -04002412}
Steven Rostedt75c3fda72010-11-02 14:57:21 -04002413
Steven Rostedte48c5292010-11-02 14:35:37 -04002414doprint "\n $successes of $opt{NUM_TESTS} tests were successful\n\n";
2415
Steven Rostedt2545eb62010-11-02 15:01:32 -04002416exit 0;