blob: 5924f14ba4188cc0fd06249a86fcf6094da47477 [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 Rostedt6c5ee0b2010-11-02 14:57:58 -04001099sub check_buildlog {
1100 my ($patch) = @_;
1101
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001102 my @files = `git show $patch | diffstat -l`;
1103
1104 open(IN, "git show $patch |") or
1105 dodie "failed to show $patch";
1106 while (<IN>) {
1107 if (m,^--- a/(.*),) {
1108 chomp $1;
1109 $files[$#files] = $1;
1110 }
1111 }
1112 close(IN);
1113
1114 open(IN, $buildlog) or dodie "Can't open $buildlog";
1115 while (<IN>) {
1116 if (/^\s*(.*?):.*(warning|error)/) {
1117 my $err = $1;
1118 foreach my $file (@files) {
Steven Rostedta75fece2010-11-02 14:58:27 -04001119 my $fullpath = "$builddir/$file";
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001120 if ($file eq $err || $fullpath eq $err) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001121 fail "$file built with warnings" and return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001122 }
1123 }
1124 }
1125 }
1126 close(IN);
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001127
1128 return 1;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001129}
1130
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001131sub apply_min_config {
1132 my $outconfig = "$output_config.new";
Steven Rostedt612b9e92011-03-07 13:27:43 -05001133
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001134 # Read the config file and remove anything that
1135 # is in the force_config hash (from minconfig and others)
1136 # then add the force config back.
1137
1138 doprint "Applying minimum configurations into $output_config.new\n";
1139
1140 open (OUT, ">$outconfig") or
1141 dodie "Can't create $outconfig";
1142
1143 if (-f $output_config) {
1144 open (IN, $output_config) or
1145 dodie "Failed to open $output_config";
1146 while (<IN>) {
1147 if (/^(# )?(CONFIG_[^\s=]*)/) {
1148 next if (defined($force_config{$2}));
1149 }
1150 print OUT;
1151 }
1152 close IN;
1153 }
1154 foreach my $config (keys %force_config) {
1155 print OUT "$force_config{$config}\n";
1156 }
1157 close OUT;
1158
1159 run_command "mv $outconfig $output_config";
1160}
1161
1162sub make_oldconfig {
1163
1164 apply_min_config;
1165
1166 if (!run_command "$make oldnoconfig") {
Steven Rostedt612b9e92011-03-07 13:27:43 -05001167 # Perhaps oldnoconfig doesn't exist in this version of the kernel
1168 # try a yes '' | oldconfig
1169 doprint "oldnoconfig failed, trying yes '' | make oldconfig\n";
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001170 run_command "yes '' | $make oldconfig" or
Steven Rostedt612b9e92011-03-07 13:27:43 -05001171 dodie "failed make config oldconfig";
1172 }
1173}
1174
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001175# read a config file and use this to force new configs.
1176sub load_force_config {
1177 my ($config) = @_;
1178
1179 open(IN, $config) or
1180 dodie "failed to read $config";
1181 while (<IN>) {
1182 chomp;
1183 if (/^(CONFIG[^\s=]*)(\s*=.*)/) {
1184 $force_config{$1} = $_;
1185 } elsif (/^# (CONFIG_\S*) is not set/) {
1186 $force_config{$1} = $_;
1187 }
1188 }
1189 close IN;
1190}
1191
Steven Rostedt2545eb62010-11-02 15:01:32 -04001192sub build {
1193 my ($type) = @_;
1194
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001195 unlink $buildlog;
1196
Steven Rostedt0bd6c1a2011-06-14 20:39:31 -04001197 if (defined($pre_build)) {
1198 my $ret = run_command $pre_build;
1199 if (!$ret && defined($pre_build_die) &&
1200 $pre_build_die) {
1201 dodie "failed to pre_build\n";
1202 }
1203 }
1204
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001205 if ($type =~ /^useconfig:(.*)/) {
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05001206 run_command "cp $1 $output_config" or
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001207 dodie "could not copy $1 to .config";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001208
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001209 $type = "oldconfig";
1210 }
1211
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001212 # old config can ask questions
1213 if ($type eq "oldconfig") {
Steven Rostedt9386c6a2010-11-08 16:35:48 -05001214 $type = "oldnoconfig";
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001215
1216 # allow for empty configs
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05001217 run_command "touch $output_config";
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001218
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05001219 run_command "mv $output_config $outputdir/config_temp" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001220 dodie "moving .config";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001221
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001222 if (!$noclean && !run_command "$make mrproper") {
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001223 dodie "make mrproper";
1224 }
1225
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05001226 run_command "mv $outputdir/config_temp $output_config" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001227 dodie "moving config_temp";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001228
1229 } elsif (!$noclean) {
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05001230 unlink "$output_config";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001231 run_command "$make mrproper" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001232 dodie "make mrproper";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001233 }
Steven Rostedt2545eb62010-11-02 15:01:32 -04001234
1235 # add something to distinguish this build
Steven Rostedta75fece2010-11-02 14:58:27 -04001236 open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file");
1237 print OUT "$localversion\n";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001238 close(OUT);
1239
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001240 if (defined($minconfig)) {
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001241 load_force_config($minconfig);
Steven Rostedt2545eb62010-11-02 15:01:32 -04001242 }
1243
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001244 if ($type ne "oldnoconfig") {
1245 run_command "$make $type" or
Steven Rostedt612b9e92011-03-07 13:27:43 -05001246 dodie "failed make config";
1247 }
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001248 # Run old config regardless, to enforce min configurations
1249 make_oldconfig;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001250
Steven Rostedta75fece2010-11-02 14:58:27 -04001251 $redirect = "$buildlog";
Steven Rostedt0bd6c1a2011-06-14 20:39:31 -04001252 my $build_ret = run_command "$make $build_options";
1253 undef $redirect;
1254
1255 if (defined($post_build)) {
1256 my $ret = run_command $post_build;
1257 if (!$ret && defined($post_build_die) &&
1258 $post_build_die) {
1259 dodie "failed to post_build\n";
1260 }
1261 }
1262
1263 if (!$build_ret) {
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001264 # bisect may need this to pass
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001265 return 0 if ($in_bisect);
1266 fail "failed build" and return 0;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001267 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001268
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001269 return 1;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001270}
1271
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001272sub halt {
Steven Rostedte48c5292010-11-02 14:35:37 -04001273 if (!run_ssh "halt" or defined($power_off)) {
Steven Rostedt576f6272010-11-02 14:58:38 -04001274 if (defined($poweroff_after_halt)) {
1275 sleep $poweroff_after_halt;
1276 run_command "$power_off";
1277 }
1278 } else {
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001279 # nope? the zap it!
Steven Rostedta75fece2010-11-02 14:58:27 -04001280 run_command "$power_off";
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001281 }
1282}
1283
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001284sub success {
1285 my ($i) = @_;
1286
Steven Rostedte48c5292010-11-02 14:35:37 -04001287 $successes++;
1288
Steven Rostedt9064af52011-06-13 10:38:48 -04001289 my $name = "";
1290
1291 if (defined($test_name)) {
1292 $name = " ($test_name)";
1293 }
1294
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001295 doprint "\n\n*******************************************\n";
1296 doprint "*******************************************\n";
Steven Rostedt9064af52011-06-13 10:38:48 -04001297 doprint "KTEST RESULT: TEST $i$name SUCCESS!!!! **\n";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001298 doprint "*******************************************\n";
1299 doprint "*******************************************\n";
1300
Steven Rostedt576f6272010-11-02 14:58:38 -04001301 if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) {
Steven Rostedta75fece2010-11-02 14:58:27 -04001302 doprint "Reboot and wait $sleep_time seconds\n";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001303 reboot;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001304 start_monitor;
Steven Rostedta75fece2010-11-02 14:58:27 -04001305 wait_for_monitor $sleep_time;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001306 end_monitor;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001307 }
1308}
1309
1310sub get_version {
1311 # get the release name
1312 doprint "$make kernelrelease ... ";
1313 $version = `$make kernelrelease | tail -1`;
1314 chomp($version);
1315 doprint "$version\n";
1316}
1317
Steven Rostedtc960bb92011-03-08 09:22:39 -05001318sub answer_bisect {
1319 for (;;) {
1320 doprint "Pass or fail? [p/f]";
1321 my $ans = <STDIN>;
1322 chomp $ans;
1323 if ($ans eq "p" || $ans eq "P") {
1324 return 1;
1325 } elsif ($ans eq "f" || $ans eq "F") {
1326 return 0;
1327 } else {
1328 print "Please answer 'P' or 'F'\n";
1329 }
1330 }
1331}
1332
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001333sub child_run_test {
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001334 my $failed = 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001335
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001336 # child should have no power
Steven Rostedta75fece2010-11-02 14:58:27 -04001337 $reboot_on_error = 0;
1338 $poweroff_on_error = 0;
1339 $die_on_failure = 1;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001340
1341 run_command $run_test or $failed = 1;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001342 exit $failed;
1343}
1344
1345my $child_done;
1346
1347sub child_finished {
1348 $child_done = 1;
1349}
1350
1351sub do_run_test {
1352 my $child_pid;
1353 my $child_exit;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001354 my $line;
1355 my $full_line;
1356 my $bug = 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001357
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001358 wait_for_monitor 1;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001359
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001360 doprint "run test $run_test\n";
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001361
1362 $child_done = 0;
1363
1364 $SIG{CHLD} = qw(child_finished);
1365
1366 $child_pid = fork;
1367
1368 child_run_test if (!$child_pid);
1369
1370 $full_line = "";
1371
1372 do {
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001373 $line = wait_for_input($monitor_fp, 1);
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001374 if (defined($line)) {
1375
1376 # we are not guaranteed to get a full line
1377 $full_line .= $line;
Steven Rostedt8ea0e062011-03-08 09:44:35 -05001378 doprint $line;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001379
1380 if ($full_line =~ /call trace:/i) {
1381 $bug = 1;
1382 }
1383
1384 if ($full_line =~ /Kernel panic -/) {
1385 $bug = 1;
1386 }
1387
1388 if ($line =~ /\n/) {
1389 $full_line = "";
1390 }
1391 }
1392 } while (!$child_done && !$bug);
1393
1394 if ($bug) {
Steven Rostedt8ea0e062011-03-08 09:44:35 -05001395 my $failure_start = time;
1396 my $now;
1397 do {
1398 $line = wait_for_input($monitor_fp, 1);
1399 if (defined($line)) {
1400 doprint $line;
1401 }
1402 $now = time;
1403 if ($now - $failure_start >= $stop_after_failure) {
1404 last;
1405 }
1406 } while (defined($line));
1407
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001408 doprint "Detected kernel crash!\n";
1409 # kill the child with extreme prejudice
1410 kill 9, $child_pid;
1411 }
1412
1413 waitpid $child_pid, 0;
1414 $child_exit = $?;
1415
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001416 if ($bug || $child_exit) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001417 return 0 if $in_bisect;
1418 fail "test failed" and return 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001419 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001420 return 1;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001421}
1422
Steven Rostedta75fece2010-11-02 14:58:27 -04001423sub run_git_bisect {
1424 my ($command) = @_;
1425
1426 doprint "$command ... ";
1427
1428 my $output = `$command 2>&1`;
1429 my $ret = $?;
1430
1431 logit $output;
1432
1433 if ($ret) {
1434 doprint "FAILED\n";
1435 dodie "Failed to git bisect";
1436 }
1437
1438 doprint "SUCCESS\n";
1439 if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) {
1440 doprint "$1 [$2]\n";
1441 } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) {
1442 $bisect_bad = $1;
1443 doprint "Found bad commit... $1\n";
1444 return 0;
1445 } else {
1446 # we already logged it, just print it now.
1447 print $output;
1448 }
1449
1450 return 1;
1451}
1452
Steven Rostedtc23dca72011-03-08 09:26:31 -05001453sub bisect_reboot {
1454 doprint "Reboot and sleep $bisect_sleep_time seconds\n";
1455 reboot;
1456 start_monitor;
1457 wait_for_monitor $bisect_sleep_time;
1458 end_monitor;
1459}
1460
1461# returns 1 on success, 0 on failure, -1 on skip
Steven Rostedt0a05c762010-11-08 11:14:10 -05001462sub run_bisect_test {
1463 my ($type, $buildtype) = @_;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001464
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001465 my $failed = 0;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001466 my $result;
1467 my $output;
1468 my $ret;
1469
Steven Rostedt0a05c762010-11-08 11:14:10 -05001470 $in_bisect = 1;
1471
1472 build $buildtype or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001473
1474 if ($type ne "build") {
Steven Rostedtc23dca72011-03-08 09:26:31 -05001475 if ($failed && $bisect_skip) {
1476 $in_bisect = 0;
1477 return -1;
1478 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001479 dodie "Failed on build" if $failed;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001480
1481 # Now boot the box
1482 get_grub_index;
1483 get_version;
1484 install;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001485
1486 start_monitor;
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001487 monitor or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001488
1489 if ($type ne "boot") {
Steven Rostedtc23dca72011-03-08 09:26:31 -05001490 if ($failed && $bisect_skip) {
1491 end_monitor;
1492 bisect_reboot;
1493 $in_bisect = 0;
1494 return -1;
1495 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001496 dodie "Failed on boot" if $failed;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001497
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001498 do_run_test or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001499 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001500 end_monitor;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001501 }
1502
1503 if ($failed) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001504 $result = 0;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001505 } else {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001506 $result = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001507 }
Steven Rostedt4025bc62011-05-20 09:16:29 -04001508
1509 # reboot the box to a kernel we can ssh to
1510 if ($type ne "build") {
1511 bisect_reboot;
1512 }
Steven Rostedt0a05c762010-11-08 11:14:10 -05001513 $in_bisect = 0;
1514
1515 return $result;
1516}
1517
1518sub run_bisect {
1519 my ($type) = @_;
1520 my $buildtype = "oldconfig";
1521
1522 # We should have a minconfig to use?
1523 if (defined($minconfig)) {
1524 $buildtype = "useconfig:$minconfig";
1525 }
1526
1527 my $ret = run_bisect_test $type, $buildtype;
1528
Steven Rostedtc960bb92011-03-08 09:22:39 -05001529 if ($bisect_manual) {
1530 $ret = answer_bisect;
1531 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001532
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04001533 # Are we looking for where it worked, not failed?
1534 if ($reverse_bisect) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001535 $ret = !$ret;
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04001536 }
1537
Steven Rostedtc23dca72011-03-08 09:26:31 -05001538 if ($ret > 0) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001539 return "good";
Steven Rostedtc23dca72011-03-08 09:26:31 -05001540 } elsif ($ret == 0) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001541 return "bad";
Steven Rostedtc23dca72011-03-08 09:26:31 -05001542 } elsif ($bisect_skip) {
1543 doprint "HIT A BAD COMMIT ... SKIPPING\n";
1544 return "skip";
Steven Rostedt0a05c762010-11-08 11:14:10 -05001545 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001546}
1547
1548sub bisect {
1549 my ($i) = @_;
1550
1551 my $result;
1552
1553 die "BISECT_GOOD[$i] not defined\n" if (!defined($opt{"BISECT_GOOD[$i]"}));
1554 die "BISECT_BAD[$i] not defined\n" if (!defined($opt{"BISECT_BAD[$i]"}));
1555 die "BISECT_TYPE[$i] not defined\n" if (!defined($opt{"BISECT_TYPE[$i]"}));
1556
1557 my $good = $opt{"BISECT_GOOD[$i]"};
1558 my $bad = $opt{"BISECT_BAD[$i]"};
1559 my $type = $opt{"BISECT_TYPE[$i]"};
Steven Rostedta75fece2010-11-02 14:58:27 -04001560 my $start = $opt{"BISECT_START[$i]"};
1561 my $replay = $opt{"BISECT_REPLAY[$i]"};
Steven Rostedt3410f6f2011-03-08 09:38:12 -05001562 my $start_files = $opt{"BISECT_FILES[$i]"};
1563
1564 if (defined($start_files)) {
1565 $start_files = " -- " . $start_files;
1566 } else {
1567 $start_files = "";
1568 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001569
Steven Rostedta57419b2010-11-02 15:13:54 -04001570 # convert to true sha1's
1571 $good = get_sha1($good);
1572 $bad = get_sha1($bad);
1573
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04001574 if (defined($opt{"BISECT_REVERSE[$i]"}) &&
1575 $opt{"BISECT_REVERSE[$i]"} == 1) {
1576 doprint "Performing a reverse bisect (bad is good, good is bad!)\n";
1577 $reverse_bisect = 1;
1578 } else {
1579 $reverse_bisect = 0;
1580 }
1581
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001582 # Can't have a test without having a test to run
1583 if ($type eq "test" && !defined($run_test)) {
1584 $type = "boot";
1585 }
1586
Steven Rostedta75fece2010-11-02 14:58:27 -04001587 my $check = $opt{"BISECT_CHECK[$i]"};
1588 if (defined($check) && $check ne "0") {
1589
1590 # get current HEAD
Steven Rostedta57419b2010-11-02 15:13:54 -04001591 my $head = get_sha1("HEAD");
Steven Rostedta75fece2010-11-02 14:58:27 -04001592
1593 if ($check ne "good") {
1594 doprint "TESTING BISECT BAD [$bad]\n";
1595 run_command "git checkout $bad" or
1596 die "Failed to checkout $bad";
1597
1598 $result = run_bisect $type;
1599
1600 if ($result ne "bad") {
1601 fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0;
1602 }
1603 }
1604
1605 if ($check ne "bad") {
1606 doprint "TESTING BISECT GOOD [$good]\n";
1607 run_command "git checkout $good" or
1608 die "Failed to checkout $good";
1609
1610 $result = run_bisect $type;
1611
1612 if ($result ne "good") {
1613 fail "Tested BISECT_GOOD [$good] and it failed" and return 0;
1614 }
1615 }
1616
1617 # checkout where we started
1618 run_command "git checkout $head" or
1619 die "Failed to checkout $head";
1620 }
1621
Steven Rostedt3410f6f2011-03-08 09:38:12 -05001622 run_command "git bisect start$start_files" or
Steven Rostedta75fece2010-11-02 14:58:27 -04001623 dodie "could not start bisect";
1624
1625 run_command "git bisect good $good" or
1626 dodie "could not set bisect good to $good";
1627
1628 run_git_bisect "git bisect bad $bad" or
1629 dodie "could not set bisect bad to $bad";
1630
1631 if (defined($replay)) {
1632 run_command "git bisect replay $replay" or
1633 dodie "failed to run replay";
1634 }
1635
1636 if (defined($start)) {
1637 run_command "git checkout $start" or
1638 dodie "failed to checkout $start";
1639 }
1640
1641 my $test;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001642 do {
1643 $result = run_bisect $type;
Steven Rostedta75fece2010-11-02 14:58:27 -04001644 $test = run_git_bisect "git bisect $result";
1645 } while ($test);
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001646
1647 run_command "git bisect log" or
1648 dodie "could not capture git bisect log";
1649
1650 run_command "git bisect reset" or
1651 dodie "could not reset git bisect";
1652
1653 doprint "Bad commit was [$bisect_bad]\n";
1654
Steven Rostedt0a05c762010-11-08 11:14:10 -05001655 success $i;
1656}
1657
1658my %config_ignore;
1659my %config_set;
1660
1661my %config_list;
1662my %null_config;
1663
1664my %dependency;
1665
1666sub process_config_ignore {
1667 my ($config) = @_;
1668
1669 open (IN, $config)
1670 or dodie "Failed to read $config";
1671
1672 while (<IN>) {
Steven Rostedt9bf71742011-06-01 23:27:19 -04001673 if (/^((CONFIG\S*)=.*)/) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001674 $config_ignore{$2} = $1;
1675 }
1676 }
1677
1678 close(IN);
1679}
1680
1681sub read_current_config {
1682 my ($config_ref) = @_;
1683
1684 %{$config_ref} = ();
1685 undef %{$config_ref};
1686
1687 my @key = keys %{$config_ref};
1688 if ($#key >= 0) {
1689 print "did not delete!\n";
1690 exit;
1691 }
1692 open (IN, "$output_config");
1693
1694 while (<IN>) {
1695 if (/^(CONFIG\S+)=(.*)/) {
1696 ${$config_ref}{$1} = $2;
1697 }
1698 }
1699 close(IN);
1700}
1701
1702sub get_dependencies {
1703 my ($config) = @_;
1704
1705 my $arr = $dependency{$config};
1706 if (!defined($arr)) {
1707 return ();
1708 }
1709
1710 my @deps = @{$arr};
1711
1712 foreach my $dep (@{$arr}) {
1713 print "ADD DEP $dep\n";
1714 @deps = (@deps, get_dependencies $dep);
1715 }
1716
1717 return @deps;
1718}
1719
1720sub create_config {
1721 my @configs = @_;
1722
1723 open(OUT, ">$output_config") or dodie "Can not write to $output_config";
1724
1725 foreach my $config (@configs) {
1726 print OUT "$config_set{$config}\n";
1727 my @deps = get_dependencies $config;
1728 foreach my $dep (@deps) {
1729 print OUT "$config_set{$dep}\n";
1730 }
1731 }
1732
1733 foreach my $config (keys %config_ignore) {
1734 print OUT "$config_ignore{$config}\n";
1735 }
1736 close(OUT);
1737
1738# exit;
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001739 make_oldconfig;
Steven Rostedt0a05c762010-11-08 11:14:10 -05001740}
1741
1742sub compare_configs {
1743 my (%a, %b) = @_;
1744
1745 foreach my $item (keys %a) {
1746 if (!defined($b{$item})) {
1747 print "diff $item\n";
1748 return 1;
1749 }
1750 delete $b{$item};
1751 }
1752
1753 my @keys = keys %b;
1754 if ($#keys) {
1755 print "diff2 $keys[0]\n";
1756 }
1757 return -1 if ($#keys >= 0);
1758
1759 return 0;
1760}
1761
1762sub run_config_bisect_test {
1763 my ($type) = @_;
1764
1765 return run_bisect_test $type, "oldconfig";
1766}
1767
1768sub process_passed {
1769 my (%configs) = @_;
1770
1771 doprint "These configs had no failure: (Enabling them for further compiles)\n";
1772 # Passed! All these configs are part of a good compile.
1773 # Add them to the min options.
1774 foreach my $config (keys %configs) {
1775 if (defined($config_list{$config})) {
1776 doprint " removing $config\n";
1777 $config_ignore{$config} = $config_list{$config};
1778 delete $config_list{$config};
1779 }
1780 }
Steven Rostedtf1a27852010-11-11 11:34:38 -05001781 doprint "config copied to $outputdir/config_good\n";
1782 run_command "cp -f $output_config $outputdir/config_good";
Steven Rostedt0a05c762010-11-08 11:14:10 -05001783}
1784
1785sub process_failed {
1786 my ($config) = @_;
1787
1788 doprint "\n\n***************************************\n";
1789 doprint "Found bad config: $config\n";
1790 doprint "***************************************\n\n";
1791}
1792
1793sub run_config_bisect {
1794
1795 my @start_list = keys %config_list;
1796
1797 if ($#start_list < 0) {
1798 doprint "No more configs to test!!!\n";
1799 return -1;
1800 }
1801
1802 doprint "***** RUN TEST ***\n";
1803 my $type = $opt{"CONFIG_BISECT_TYPE[$iteration]"};
1804 my $ret;
1805 my %current_config;
1806
1807 my $count = $#start_list + 1;
1808 doprint " $count configs to test\n";
1809
1810 my $half = int($#start_list / 2);
1811
1812 do {
1813 my @tophalf = @start_list[0 .. $half];
1814
1815 create_config @tophalf;
1816 read_current_config \%current_config;
1817
1818 $count = $#tophalf + 1;
1819 doprint "Testing $count configs\n";
1820 my $found = 0;
1821 # make sure we test something
1822 foreach my $config (@tophalf) {
1823 if (defined($current_config{$config})) {
1824 logit " $config\n";
1825 $found = 1;
1826 }
1827 }
1828 if (!$found) {
1829 # try the other half
1830 doprint "Top half produced no set configs, trying bottom half\n";
Steven Rostedt4c8cc552011-06-01 23:22:30 -04001831 @tophalf = @start_list[$half + 1 .. $#start_list];
Steven Rostedt0a05c762010-11-08 11:14:10 -05001832 create_config @tophalf;
1833 read_current_config \%current_config;
1834 foreach my $config (@tophalf) {
1835 if (defined($current_config{$config})) {
1836 logit " $config\n";
1837 $found = 1;
1838 }
1839 }
1840 if (!$found) {
1841 doprint "Failed: Can't make new config with current configs\n";
1842 foreach my $config (@start_list) {
1843 doprint " CONFIG: $config\n";
1844 }
1845 return -1;
1846 }
1847 $count = $#tophalf + 1;
1848 doprint "Testing $count configs\n";
1849 }
1850
1851 $ret = run_config_bisect_test $type;
Steven Rostedtc960bb92011-03-08 09:22:39 -05001852 if ($bisect_manual) {
1853 $ret = answer_bisect;
1854 }
Steven Rostedt0a05c762010-11-08 11:14:10 -05001855 if ($ret) {
1856 process_passed %current_config;
1857 return 0;
1858 }
1859
1860 doprint "This config had a failure.\n";
1861 doprint "Removing these configs that were not set in this config:\n";
Steven Rostedtf1a27852010-11-11 11:34:38 -05001862 doprint "config copied to $outputdir/config_bad\n";
1863 run_command "cp -f $output_config $outputdir/config_bad";
Steven Rostedt0a05c762010-11-08 11:14:10 -05001864
1865 # A config exists in this group that was bad.
1866 foreach my $config (keys %config_list) {
1867 if (!defined($current_config{$config})) {
1868 doprint " removing $config\n";
1869 delete $config_list{$config};
1870 }
1871 }
1872
1873 @start_list = @tophalf;
1874
1875 if ($#start_list == 0) {
1876 process_failed $start_list[0];
1877 return 1;
1878 }
1879
1880 # remove half the configs we are looking at and see if
1881 # they are good.
1882 $half = int($#start_list / 2);
Steven Rostedt4c8cc552011-06-01 23:22:30 -04001883 } while ($#start_list > 0);
Steven Rostedt0a05c762010-11-08 11:14:10 -05001884
Steven Rostedtc960bb92011-03-08 09:22:39 -05001885 # we found a single config, try it again unless we are running manually
1886
1887 if ($bisect_manual) {
1888 process_failed $start_list[0];
1889 return 1;
1890 }
1891
Steven Rostedt0a05c762010-11-08 11:14:10 -05001892 my @tophalf = @start_list[0 .. 0];
1893
1894 $ret = run_config_bisect_test $type;
1895 if ($ret) {
1896 process_passed %current_config;
1897 return 0;
1898 }
1899
1900 process_failed $start_list[0];
1901 return 1;
1902}
1903
1904sub config_bisect {
1905 my ($i) = @_;
1906
1907 my $start_config = $opt{"CONFIG_BISECT[$i]"};
1908
1909 my $tmpconfig = "$tmpdir/use_config";
1910
Steven Rostedt30f75da2011-06-13 10:35:35 -04001911 if (defined($config_bisect_good)) {
1912 process_config_ignore $config_bisect_good;
1913 }
1914
Steven Rostedt0a05c762010-11-08 11:14:10 -05001915 # Make the file with the bad config and the min config
1916 if (defined($minconfig)) {
1917 # read the min config for things to ignore
1918 run_command "cp $minconfig $tmpconfig" or
1919 dodie "failed to copy $minconfig to $tmpconfig";
1920 } else {
1921 unlink $tmpconfig;
1922 }
1923
1924 # Add other configs
1925 if (defined($addconfig)) {
1926 run_command "cat $addconfig >> $tmpconfig" or
1927 dodie "failed to append $addconfig";
1928 }
1929
Steven Rostedt0a05c762010-11-08 11:14:10 -05001930 if (-f $tmpconfig) {
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001931 load_force_config($tmpconfig);
Steven Rostedt0a05c762010-11-08 11:14:10 -05001932 process_config_ignore $tmpconfig;
1933 }
1934
1935 # now process the start config
1936 run_command "cp $start_config $output_config" or
1937 dodie "failed to copy $start_config to $output_config";
1938
1939 # read directly what we want to check
1940 my %config_check;
1941 open (IN, $output_config)
1942 or dodie "faied to open $output_config";
1943
1944 while (<IN>) {
1945 if (/^((CONFIG\S*)=.*)/) {
1946 $config_check{$2} = $1;
1947 }
1948 }
1949 close(IN);
1950
1951 # Now run oldconfig with the minconfig (and addconfigs)
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001952 make_oldconfig;
Steven Rostedt0a05c762010-11-08 11:14:10 -05001953
1954 # check to see what we lost (or gained)
1955 open (IN, $output_config)
1956 or dodie "Failed to read $start_config";
1957
1958 my %removed_configs;
1959 my %added_configs;
1960
1961 while (<IN>) {
1962 if (/^((CONFIG\S*)=.*)/) {
1963 # save off all options
1964 $config_set{$2} = $1;
1965 if (defined($config_check{$2})) {
1966 if (defined($config_ignore{$2})) {
1967 $removed_configs{$2} = $1;
1968 } else {
1969 $config_list{$2} = $1;
1970 }
1971 } elsif (!defined($config_ignore{$2})) {
1972 $added_configs{$2} = $1;
1973 $config_list{$2} = $1;
1974 }
1975 }
1976 }
1977 close(IN);
1978
1979 my @confs = keys %removed_configs;
1980 if ($#confs >= 0) {
1981 doprint "Configs overridden by default configs and removed from check:\n";
1982 foreach my $config (@confs) {
1983 doprint " $config\n";
1984 }
1985 }
1986 @confs = keys %added_configs;
1987 if ($#confs >= 0) {
1988 doprint "Configs appearing in make oldconfig and added:\n";
1989 foreach my $config (@confs) {
1990 doprint " $config\n";
1991 }
1992 }
1993
1994 my %config_test;
1995 my $once = 0;
1996
1997 # Sometimes kconfig does weird things. We must make sure
1998 # that the config we autocreate has everything we need
1999 # to test, otherwise we may miss testing configs, or
2000 # may not be able to create a new config.
2001 # Here we create a config with everything set.
2002 create_config (keys %config_list);
2003 read_current_config \%config_test;
2004 foreach my $config (keys %config_list) {
2005 if (!defined($config_test{$config})) {
2006 if (!$once) {
2007 $once = 1;
2008 doprint "Configs not produced by kconfig (will not be checked):\n";
2009 }
2010 doprint " $config\n";
2011 delete $config_list{$config};
2012 }
2013 }
2014 my $ret;
2015 do {
2016 $ret = run_config_bisect;
2017 } while (!$ret);
2018
2019 return $ret if ($ret < 0);
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04002020
2021 success $i;
2022}
2023
Steven Rostedt27d934b2011-05-20 09:18:18 -04002024sub patchcheck_reboot {
2025 doprint "Reboot and sleep $patchcheck_sleep_time seconds\n";
2026 reboot;
2027 start_monitor;
2028 wait_for_monitor $patchcheck_sleep_time;
2029 end_monitor;
2030}
2031
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002032sub patchcheck {
2033 my ($i) = @_;
2034
2035 die "PATCHCHECK_START[$i] not defined\n"
2036 if (!defined($opt{"PATCHCHECK_START[$i]"}));
2037 die "PATCHCHECK_TYPE[$i] not defined\n"
2038 if (!defined($opt{"PATCHCHECK_TYPE[$i]"}));
2039
2040 my $start = $opt{"PATCHCHECK_START[$i]"};
2041
2042 my $end = "HEAD";
2043 if (defined($opt{"PATCHCHECK_END[$i]"})) {
2044 $end = $opt{"PATCHCHECK_END[$i]"};
2045 }
2046
Steven Rostedta57419b2010-11-02 15:13:54 -04002047 # Get the true sha1's since we can use things like HEAD~3
2048 $start = get_sha1($start);
2049 $end = get_sha1($end);
2050
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002051 my $type = $opt{"PATCHCHECK_TYPE[$i]"};
2052
2053 # Can't have a test without having a test to run
2054 if ($type eq "test" && !defined($run_test)) {
2055 $type = "boot";
2056 }
2057
2058 open (IN, "git log --pretty=oneline $end|") or
2059 dodie "could not get git list";
2060
2061 my @list;
2062
2063 while (<IN>) {
2064 chomp;
2065 $list[$#list+1] = $_;
2066 last if (/^$start/);
2067 }
2068 close(IN);
2069
2070 if ($list[$#list] !~ /^$start/) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002071 fail "SHA1 $start not found";
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002072 }
2073
2074 # go backwards in the list
2075 @list = reverse @list;
2076
2077 my $save_clean = $noclean;
Steven Rostedt19902072011-06-14 20:46:25 -04002078 my %ignored_warnings;
2079
2080 if (defined($ignore_warnings)) {
2081 foreach my $sha1 (split /\s+/, $ignore_warnings) {
2082 $ignored_warnings{$sha1} = 1;
2083 }
2084 }
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002085
2086 $in_patchcheck = 1;
2087 foreach my $item (@list) {
2088 my $sha1 = $item;
2089 $sha1 =~ s/^([[:xdigit:]]+).*/$1/;
2090
2091 doprint "\nProcessing commit $item\n\n";
2092
2093 run_command "git checkout $sha1" or
2094 die "Failed to checkout $sha1";
2095
2096 # only clean on the first and last patch
2097 if ($item eq $list[0] ||
2098 $item eq $list[$#list]) {
2099 $noclean = $save_clean;
2100 } else {
2101 $noclean = 1;
2102 }
2103
2104 if (defined($minconfig)) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002105 build "useconfig:$minconfig" or return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002106 } else {
2107 # ?? no config to use?
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002108 build "oldconfig" or return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002109 }
2110
Steven Rostedt19902072011-06-14 20:46:25 -04002111
2112 if (!defined($ignored_warnings{$sha1})) {
2113 check_buildlog $sha1 or return 0;
2114 }
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002115
2116 next if ($type eq "build");
2117
2118 get_grub_index;
2119 get_version;
2120 install;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002121
Steven Rostedt7faafbd2010-11-02 14:58:22 -04002122 my $failed = 0;
2123
2124 start_monitor;
2125 monitor or $failed = 1;
2126
2127 if (!$failed && $type ne "boot"){
2128 do_run_test or $failed = 1;
2129 }
2130 end_monitor;
2131 return 0 if ($failed);
2132
Steven Rostedt27d934b2011-05-20 09:18:18 -04002133 patchcheck_reboot;
2134
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002135 }
2136 $in_patchcheck = 0;
2137 success $i;
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002138
2139 return 1;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002140}
2141
Steven Rostedt8d1491b2010-11-18 15:39:48 -05002142$#ARGV < 1 or die "ktest.pl version: $VERSION\n usage: ktest.pl config-file\n";
Steven Rostedt2545eb62010-11-02 15:01:32 -04002143
Steven Rostedt8d1491b2010-11-18 15:39:48 -05002144if ($#ARGV == 0) {
2145 $ktest_config = $ARGV[0];
2146 if (! -f $ktest_config) {
2147 print "$ktest_config does not exist.\n";
2148 my $ans;
2149 for (;;) {
2150 print "Create it? [Y/n] ";
2151 $ans = <STDIN>;
2152 chomp $ans;
2153 if ($ans =~ /^\s*$/) {
2154 $ans = "y";
2155 }
2156 last if ($ans =~ /^y$/i || $ans =~ /^n$/i);
2157 print "Please answer either 'y' or 'n'.\n";
2158 }
2159 if ($ans !~ /^y$/i) {
2160 exit 0;
2161 }
2162 }
2163} else {
2164 $ktest_config = "ktest.conf";
2165}
2166
2167if (! -f $ktest_config) {
2168 open(OUT, ">$ktest_config") or die "Can not create $ktest_config";
2169 print OUT << "EOF"
2170# Generated by ktest.pl
2171#
2172# Define each test with TEST_START
2173# The config options below it will override the defaults
2174TEST_START
2175
2176DEFAULTS
2177EOF
2178;
2179 close(OUT);
2180}
2181read_config $ktest_config;
2182
Steven Rostedt23715c3c2011-06-13 11:03:34 -04002183if (defined($opt{"LOG_FILE"})) {
2184 $opt{"LOG_FILE"} = eval_option($opt{"LOG_FILE"}, -1);
2185}
2186
Steven Rostedt8d1491b2010-11-18 15:39:48 -05002187# Append any configs entered in manually to the config file.
2188my @new_configs = keys %entered_configs;
2189if ($#new_configs >= 0) {
2190 print "\nAppending entered in configs to $ktest_config\n";
2191 open(OUT, ">>$ktest_config") or die "Can not append to $ktest_config";
2192 foreach my $config (@new_configs) {
2193 print OUT "$config = $entered_configs{$config}\n";
2194 $opt{$config} = $entered_configs{$config};
2195 }
2196}
Steven Rostedt2545eb62010-11-02 15:01:32 -04002197
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002198if ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) {
2199 unlink $opt{"LOG_FILE"};
2200}
Steven Rostedt2545eb62010-11-02 15:01:32 -04002201
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002202doprint "\n\nSTARTING AUTOMATED TESTS\n\n";
2203
Steven Rostedta57419b2010-11-02 15:13:54 -04002204for (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) {
2205
2206 if (!$i) {
2207 doprint "DEFAULT OPTIONS:\n";
2208 } else {
2209 doprint "\nTEST $i OPTIONS";
2210 if (defined($repeat_tests{$i})) {
2211 $repeat = $repeat_tests{$i};
2212 doprint " ITERATE $repeat";
2213 }
2214 doprint "\n";
2215 }
2216
2217 foreach my $option (sort keys %opt) {
2218
2219 if ($option =~ /\[(\d+)\]$/) {
2220 next if ($i != $1);
2221 } else {
2222 next if ($i);
2223 }
2224
2225 doprint "$option = $opt{$option}\n";
2226 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002227}
Steven Rostedt2545eb62010-11-02 15:01:32 -04002228
Steven Rostedt2a625122011-05-20 15:48:59 -04002229sub __set_test_option {
Steven Rostedt5a391fb2010-11-02 14:57:43 -04002230 my ($name, $i) = @_;
2231
2232 my $option = "$name\[$i\]";
2233
2234 if (defined($opt{$option})) {
2235 return $opt{$option};
2236 }
2237
Steven Rostedta57419b2010-11-02 15:13:54 -04002238 foreach my $test (keys %repeat_tests) {
2239 if ($i >= $test &&
2240 $i < $test + $repeat_tests{$test}) {
2241 $option = "$name\[$test\]";
2242 if (defined($opt{$option})) {
2243 return $opt{$option};
2244 }
2245 }
2246 }
2247
Steven Rostedt5a391fb2010-11-02 14:57:43 -04002248 if (defined($opt{$name})) {
2249 return $opt{$name};
2250 }
2251
2252 return undef;
2253}
2254
Steven Rostedt2a625122011-05-20 15:48:59 -04002255sub set_test_option {
2256 my ($name, $i) = @_;
2257
2258 my $option = __set_test_option($name, $i);
2259 return $option if (!defined($option));
2260
Steven Rostedt23715c3c2011-06-13 11:03:34 -04002261 return eval_option($option, $i);
Steven Rostedt2a625122011-05-20 15:48:59 -04002262}
2263
Steven Rostedt2545eb62010-11-02 15:01:32 -04002264# First we need to do is the builds
Steven Rostedta75fece2010-11-02 14:58:27 -04002265for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
Steven Rostedt2545eb62010-11-02 15:01:32 -04002266
Steven Rostedt576f6272010-11-02 14:58:38 -04002267 $iteration = $i;
2268
Steven Rostedta75fece2010-11-02 14:58:27 -04002269 my $makecmd = set_test_option("MAKE_CMD", $i);
2270
2271 $machine = set_test_option("MACHINE", $i);
Steven Rostedte48c5292010-11-02 14:35:37 -04002272 $ssh_user = set_test_option("SSH_USER", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002273 $tmpdir = set_test_option("TMP_DIR", $i);
2274 $outputdir = set_test_option("OUTPUT_DIR", $i);
2275 $builddir = set_test_option("BUILD_DIR", $i);
2276 $test_type = set_test_option("TEST_TYPE", $i);
2277 $build_type = set_test_option("BUILD_TYPE", $i);
2278 $build_options = set_test_option("BUILD_OPTIONS", $i);
Steven Rostedt0bd6c1a2011-06-14 20:39:31 -04002279 $pre_build = set_test_option("PRE_BUILD", $i);
2280 $post_build = set_test_option("POST_BUILD", $i);
2281 $pre_build_die = set_test_option("PRE_BUILD_DIE", $i);
2282 $post_build_die = set_test_option("POST_BUILD_DIE", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002283 $power_cycle = set_test_option("POWER_CYCLE", $i);
Steven Rostedte48c5292010-11-02 14:35:37 -04002284 $reboot = set_test_option("REBOOT", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002285 $noclean = set_test_option("BUILD_NOCLEAN", $i);
2286 $minconfig = set_test_option("MIN_CONFIG", $i);
2287 $run_test = set_test_option("TEST", $i);
2288 $addconfig = set_test_option("ADD_CONFIG", $i);
2289 $reboot_type = set_test_option("REBOOT_TYPE", $i);
2290 $grub_menu = set_test_option("GRUB_MENU", $i);
Steven Rostedt8b37ca82010-11-02 14:58:33 -04002291 $post_install = set_test_option("POST_INSTALL", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002292 $reboot_script = set_test_option("REBOOT_SCRIPT", $i);
2293 $reboot_on_error = set_test_option("REBOOT_ON_ERROR", $i);
2294 $poweroff_on_error = set_test_option("POWEROFF_ON_ERROR", $i);
2295 $die_on_failure = set_test_option("DIE_ON_FAILURE", $i);
2296 $power_off = set_test_option("POWER_OFF", $i);
Steven Rostedt576f6272010-11-02 14:58:38 -04002297 $powercycle_after_reboot = set_test_option("POWERCYCLE_AFTER_REBOOT", $i);
2298 $poweroff_after_halt = set_test_option("POWEROFF_AFTER_HALT", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002299 $sleep_time = set_test_option("SLEEP_TIME", $i);
2300 $bisect_sleep_time = set_test_option("BISECT_SLEEP_TIME", $i);
Steven Rostedt27d934b2011-05-20 09:18:18 -04002301 $patchcheck_sleep_time = set_test_option("PATCHCHECK_SLEEP_TIME", $i);
Steven Rostedt19902072011-06-14 20:46:25 -04002302 $ignore_warnings = set_test_option("IGNORE_WARNINGS", $i);
Steven Rostedtc960bb92011-03-08 09:22:39 -05002303 $bisect_manual = set_test_option("BISECT_MANUAL", $i);
Steven Rostedtc23dca72011-03-08 09:26:31 -05002304 $bisect_skip = set_test_option("BISECT_SKIP", $i);
Steven Rostedt30f75da2011-06-13 10:35:35 -04002305 $config_bisect_good = set_test_option("CONFIG_BISECT_GOOD", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002306 $store_failures = set_test_option("STORE_FAILURES", $i);
Steven Rostedt9064af52011-06-13 10:38:48 -04002307 $test_name = set_test_option("TEST_NAME", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002308 $timeout = set_test_option("TIMEOUT", $i);
2309 $booted_timeout = set_test_option("BOOTED_TIMEOUT", $i);
2310 $console = set_test_option("CONSOLE", $i);
Steven Rostedtf1a5b962011-06-13 10:30:00 -04002311 $detect_triplefault = set_test_option("DETECT_TRIPLE_FAULT", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002312 $success_line = set_test_option("SUCCESS_LINE", $i);
Steven Rostedt1c8a6172010-11-09 12:55:40 -05002313 $stop_after_success = set_test_option("STOP_AFTER_SUCCESS", $i);
2314 $stop_after_failure = set_test_option("STOP_AFTER_FAILURE", $i);
Steven Rostedt2d01b262011-03-08 09:47:54 -05002315 $stop_test_after = set_test_option("STOP_TEST_AFTER", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002316 $build_target = set_test_option("BUILD_TARGET", $i);
Steven Rostedte48c5292010-11-02 14:35:37 -04002317 $ssh_exec = set_test_option("SSH_EXEC", $i);
2318 $scp_to_target = set_test_option("SCP_TO_TARGET", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002319 $target_image = set_test_option("TARGET_IMAGE", $i);
2320 $localversion = set_test_option("LOCALVERSION", $i);
2321
2322 chdir $builddir || die "can't change directory to $builddir";
2323
2324 if (!-d $tmpdir) {
2325 mkpath($tmpdir) or
2326 die "can't create $tmpdir";
2327 }
2328
Steven Rostedte48c5292010-11-02 14:35:37 -04002329 $ENV{"SSH_USER"} = $ssh_user;
2330 $ENV{"MACHINE"} = $machine;
2331
Steven Rostedta75fece2010-11-02 14:58:27 -04002332 $target = "$ssh_user\@$machine";
2333
2334 $buildlog = "$tmpdir/buildlog-$machine";
2335 $dmesg = "$tmpdir/dmesg-$machine";
2336 $make = "$makecmd O=$outputdir";
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05002337 $output_config = "$outputdir/.config";
Steven Rostedta75fece2010-11-02 14:58:27 -04002338
2339 if ($reboot_type eq "grub") {
Steven Rostedt576f6272010-11-02 14:58:38 -04002340 dodie "GRUB_MENU not defined" if (!defined($grub_menu));
Steven Rostedta75fece2010-11-02 14:58:27 -04002341 } elsif (!defined($reboot_script)) {
Steven Rostedt576f6272010-11-02 14:58:38 -04002342 dodie "REBOOT_SCRIPT not defined"
Steven Rostedta75fece2010-11-02 14:58:27 -04002343 }
2344
2345 my $run_type = $build_type;
2346 if ($test_type eq "patchcheck") {
2347 $run_type = $opt{"PATCHCHECK_TYPE[$i]"};
2348 } elsif ($test_type eq "bisect") {
2349 $run_type = $opt{"BISECT_TYPE[$i]"};
Steven Rostedt0a05c762010-11-08 11:14:10 -05002350 } elsif ($test_type eq "config_bisect") {
2351 $run_type = $opt{"CONFIG_BISECT_TYPE[$i]"};
Steven Rostedta75fece2010-11-02 14:58:27 -04002352 }
2353
2354 # mistake in config file?
2355 if (!defined($run_type)) {
2356 $run_type = "ERROR";
2357 }
Steven Rostedt2545eb62010-11-02 15:01:32 -04002358
2359 doprint "\n\n";
Steven Rostedta75fece2010-11-02 14:58:27 -04002360 doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type\n\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -04002361
2362 unlink $dmesg;
2363 unlink $buildlog;
Steven Rostedt2545eb62010-11-02 15:01:32 -04002364
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002365 if (!defined($minconfig)) {
2366 $minconfig = $addconfig;
2367
2368 } elsif (defined($addconfig)) {
Steven Rostedt9be2e6b2010-11-09 12:20:21 -05002369 run_command "cat $addconfig $minconfig > $tmpdir/add_config" or
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002370 dodie "Failed to create temp config";
Steven Rostedt9be2e6b2010-11-09 12:20:21 -05002371 $minconfig = "$tmpdir/add_config";
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002372 }
2373
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002374 my $checkout = $opt{"CHECKOUT[$i]"};
2375 if (defined($checkout)) {
2376 run_command "git checkout $checkout" or
2377 die "failed to checkout $checkout";
2378 }
2379
Steven Rostedta75fece2010-11-02 14:58:27 -04002380 if ($test_type eq "bisect") {
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04002381 bisect $i;
2382 next;
Steven Rostedt0a05c762010-11-08 11:14:10 -05002383 } elsif ($test_type eq "config_bisect") {
2384 config_bisect $i;
2385 next;
Steven Rostedta75fece2010-11-02 14:58:27 -04002386 } elsif ($test_type eq "patchcheck") {
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002387 patchcheck $i;
2388 next;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04002389 }
2390
Steven Rostedt7faafbd2010-11-02 14:58:22 -04002391 if ($build_type ne "nobuild") {
2392 build $build_type or next;
Steven Rostedt2545eb62010-11-02 15:01:32 -04002393 }
2394
Steven Rostedta75fece2010-11-02 14:58:27 -04002395 if ($test_type ne "build") {
2396 get_grub_index;
2397 get_version;
2398 install;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04002399
Steven Rostedta75fece2010-11-02 14:58:27 -04002400 my $failed = 0;
2401 start_monitor;
2402 monitor or $failed = 1;;
2403
2404 if (!$failed && $test_type ne "boot" && defined($run_test)) {
2405 do_run_test or $failed = 1;
2406 }
2407 end_monitor;
2408 next if ($failed);
Steven Rostedt5a391fb2010-11-02 14:57:43 -04002409 }
2410
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04002411 success $i;
Steven Rostedt2545eb62010-11-02 15:01:32 -04002412}
2413
Steven Rostedt5c42fc52010-11-02 14:57:01 -04002414if ($opt{"POWEROFF_ON_SUCCESS"}) {
Steven Rostedt75c3fda72010-11-02 14:57:21 -04002415 halt;
Steven Rostedt576f6272010-11-02 14:58:38 -04002416} elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot) {
Steven Rostedt75c3fda72010-11-02 14:57:21 -04002417 reboot;
Steven Rostedt5c42fc52010-11-02 14:57:01 -04002418}
Steven Rostedt75c3fda72010-11-02 14:57:21 -04002419
Steven Rostedte48c5292010-11-02 14:35:37 -04002420doprint "\n $successes of $opt{NUM_TESTS} tests were successful\n\n";
2421
Steven Rostedt2545eb62010-11-02 15:01:32 -04002422exit 0;