blob: fb46e12eb1d7d6fa5399f99eaac5e647f36c758c [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 Rostedta57419b2010-11-02 15:13:54 -040030$default{"TMP_DIR"} = "/tmp/ktest";
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;
66my $reboot_type;
67my $reboot_script;
68my $power_cycle;
Steven Rostedte48c5292010-11-02 14:35:37 -040069my $reboot;
Steven Rostedta75fece2010-11-02 14:58:27 -040070my $reboot_on_error;
71my $poweroff_on_error;
72my $die_on_failure;
Steven Rostedt576f6272010-11-02 14:58:38 -040073my $powercycle_after_reboot;
74my $poweroff_after_halt;
Steven Rostedte48c5292010-11-02 14:35:37 -040075my $ssh_exec;
76my $scp_to_target;
Steven Rostedta75fece2010-11-02 14:58:27 -040077my $power_off;
78my $grub_menu;
Steven Rostedt2545eb62010-11-02 15:01:32 -040079my $grub_number;
80my $target;
81my $make;
Steven Rostedt8b37ca82010-11-02 14:58:33 -040082my $post_install;
Steven Rostedt5c42fc52010-11-02 14:57:01 -040083my $noclean;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -040084my $minconfig;
Steven Rostedt2b7d9b22010-11-02 14:58:15 -040085my $addconfig;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -040086my $in_bisect = 0;
87my $bisect_bad = "";
Steven Rostedtd6ce2a02010-11-02 14:58:05 -040088my $reverse_bisect;
Steven Rostedtc960bb92011-03-08 09:22:39 -050089my $bisect_manual;
Steven Rostedtc23dca72011-03-08 09:26:31 -050090my $bisect_skip;
Steven Rostedt30f75da2011-06-13 10:35:35 -040091my $config_bisect_good;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -040092my $in_patchcheck = 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -040093my $run_test;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -040094my $redirect;
Steven Rostedt7faafbd2010-11-02 14:58:22 -040095my $buildlog;
96my $dmesg;
97my $monitor_fp;
98my $monitor_pid;
99my $monitor_cnt = 0;
Steven Rostedta75fece2010-11-02 14:58:27 -0400100my $sleep_time;
101my $bisect_sleep_time;
Steven Rostedt27d934b2011-05-20 09:18:18 -0400102my $patchcheck_sleep_time;
Steven Rostedta75fece2010-11-02 14:58:27 -0400103my $store_failures;
Steven Rostedt9064af52011-06-13 10:38:48 -0400104my $test_name;
Steven Rostedta75fece2010-11-02 14:58:27 -0400105my $timeout;
106my $booted_timeout;
Steven Rostedtf1a5b962011-06-13 10:30:00 -0400107my $detect_triplefault;
Steven Rostedta75fece2010-11-02 14:58:27 -0400108my $console;
109my $success_line;
Steven Rostedt1c8a6172010-11-09 12:55:40 -0500110my $stop_after_success;
111my $stop_after_failure;
Steven Rostedt2d01b262011-03-08 09:47:54 -0500112my $stop_test_after;
Steven Rostedta75fece2010-11-02 14:58:27 -0400113my $build_target;
114my $target_image;
115my $localversion;
Steven Rostedt576f6272010-11-02 14:58:38 -0400116my $iteration = 0;
Steven Rostedte48c5292010-11-02 14:35:37 -0400117my $successes = 0;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400118
Steven Rostedt8d1491b2010-11-18 15:39:48 -0500119my %entered_configs;
120my %config_help;
Steven Rostedt77d942c2011-05-20 13:36:58 -0400121my %variable;
Steven Rostedtfcb3f162011-06-13 10:40:58 -0400122my %force_config;
Steven Rostedt8d1491b2010-11-18 15:39:48 -0500123
124$config_help{"MACHINE"} = << "EOF"
125 The machine hostname that you will test.
126EOF
127 ;
128$config_help{"SSH_USER"} = << "EOF"
129 The box is expected to have ssh on normal bootup, provide the user
130 (most likely root, since you need privileged operations)
131EOF
132 ;
133$config_help{"BUILD_DIR"} = << "EOF"
134 The directory that contains the Linux source code (full path).
135EOF
136 ;
137$config_help{"OUTPUT_DIR"} = << "EOF"
138 The directory that the objects will be built (full path).
139 (can not be same as BUILD_DIR)
140EOF
141 ;
142$config_help{"BUILD_TARGET"} = << "EOF"
143 The location of the compiled file to copy to the target.
144 (relative to OUTPUT_DIR)
145EOF
146 ;
147$config_help{"TARGET_IMAGE"} = << "EOF"
148 The place to put your image on the test machine.
149EOF
150 ;
151$config_help{"POWER_CYCLE"} = << "EOF"
152 A script or command to reboot the box.
153
154 Here is a digital loggers power switch example
155 POWER_CYCLE = wget --no-proxy -O /dev/null -q --auth-no-challenge 'http://admin:admin\@power/outlet?5=CCL'
156
157 Here is an example to reboot a virtual box on the current host
158 with the name "Guest".
159 POWER_CYCLE = virsh destroy Guest; sleep 5; virsh start Guest
160EOF
161 ;
162$config_help{"CONSOLE"} = << "EOF"
163 The script or command that reads the console
164
165 If you use ttywatch server, something like the following would work.
166CONSOLE = nc -d localhost 3001
167
168 For a virtual machine with guest name "Guest".
169CONSOLE = virsh console Guest
170EOF
171 ;
172$config_help{"LOCALVERSION"} = << "EOF"
173 Required version ending to differentiate the test
174 from other linux builds on the system.
175EOF
176 ;
177$config_help{"REBOOT_TYPE"} = << "EOF"
178 Way to reboot the box to the test kernel.
179 Only valid options so far are "grub" and "script".
180
181 If you specify grub, it will assume grub version 1
182 and will search in /boot/grub/menu.lst for the title \$GRUB_MENU
183 and select that target to reboot to the kernel. If this is not
184 your setup, then specify "script" and have a command or script
185 specified in REBOOT_SCRIPT to boot to the target.
186
187 The entry in /boot/grub/menu.lst must be entered in manually.
188 The test will not modify that file.
189EOF
190 ;
191$config_help{"GRUB_MENU"} = << "EOF"
192 The grub title name for the test kernel to boot
193 (Only mandatory if REBOOT_TYPE = grub)
194
195 Note, ktest.pl will not update the grub menu.lst, you need to
196 manually add an option for the test. ktest.pl will search
197 the grub menu.lst for this option to find what kernel to
198 reboot into.
199
200 For example, if in the /boot/grub/menu.lst the test kernel title has:
201 title Test Kernel
202 kernel vmlinuz-test
203 GRUB_MENU = Test Kernel
204EOF
205 ;
206$config_help{"REBOOT_SCRIPT"} = << "EOF"
207 A script to reboot the target into the test kernel
208 (Only mandatory if REBOOT_TYPE = script)
209EOF
210 ;
211
212
213sub get_ktest_config {
214 my ($config) = @_;
215
216 return if (defined($opt{$config}));
217
218 if (defined($config_help{$config})) {
219 print "\n";
220 print $config_help{$config};
221 }
222
223 for (;;) {
224 print "$config = ";
225 if (defined($default{$config})) {
226 print "\[$default{$config}\] ";
227 }
228 $entered_configs{$config} = <STDIN>;
229 $entered_configs{$config} =~ s/^\s*(.*\S)\s*$/$1/;
230 if ($entered_configs{$config} =~ /^\s*$/) {
231 if ($default{$config}) {
232 $entered_configs{$config} = $default{$config};
233 } else {
234 print "Your answer can not be blank\n";
235 next;
236 }
237 }
238 last;
239 }
240}
241
242sub get_ktest_configs {
243 get_ktest_config("MACHINE");
244 get_ktest_config("SSH_USER");
245 get_ktest_config("BUILD_DIR");
246 get_ktest_config("OUTPUT_DIR");
247 get_ktest_config("BUILD_TARGET");
248 get_ktest_config("TARGET_IMAGE");
249 get_ktest_config("POWER_CYCLE");
250 get_ktest_config("CONSOLE");
251 get_ktest_config("LOCALVERSION");
252
253 my $rtype = $opt{"REBOOT_TYPE"};
254
255 if (!defined($rtype)) {
256 if (!defined($opt{"GRUB_MENU"})) {
257 get_ktest_config("REBOOT_TYPE");
258 $rtype = $entered_configs{"REBOOT_TYPE"};
259 } else {
260 $rtype = "grub";
261 }
262 }
263
264 if ($rtype eq "grub") {
265 get_ktest_config("GRUB_MENU");
266 } else {
267 get_ktest_config("REBOOT_SCRIPT");
268 }
269}
270
Steven Rostedt77d942c2011-05-20 13:36:58 -0400271sub process_variables {
272 my ($value) = @_;
273 my $retval = "";
274
275 # We want to check for '\', and it is just easier
276 # to check the previous characet of '$' and not need
277 # to worry if '$' is the first character. By adding
278 # a space to $value, we can just check [^\\]\$ and
279 # it will still work.
280 $value = " $value";
281
282 while ($value =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
283 my $begin = $1;
284 my $var = $2;
285 my $end = $3;
286 # append beginning of value to retval
287 $retval = "$retval$begin";
288 if (defined($variable{$var})) {
289 $retval = "$retval$variable{$var}";
290 } else {
291 # put back the origin piece.
292 $retval = "$retval\$\{$var\}";
293 }
294 $value = $end;
295 }
296 $retval = "$retval$value";
297
298 # remove the space added in the beginning
299 $retval =~ s/ //;
300
301 return "$retval"
302}
303
Steven Rostedta57419b2010-11-02 15:13:54 -0400304sub set_value {
305 my ($lvalue, $rvalue) = @_;
306
307 if (defined($opt{$lvalue})) {
308 die "Error: Option $lvalue defined more than once!\n";
309 }
Steven Rostedt21a96792010-11-08 16:45:50 -0500310 if ($rvalue =~ /^\s*$/) {
311 delete $opt{$lvalue};
312 } else {
Steven Rostedt77d942c2011-05-20 13:36:58 -0400313 $rvalue = process_variables($rvalue);
Steven Rostedt21a96792010-11-08 16:45:50 -0500314 $opt{$lvalue} = $rvalue;
315 }
Steven Rostedta57419b2010-11-02 15:13:54 -0400316}
317
Steven Rostedt77d942c2011-05-20 13:36:58 -0400318sub set_variable {
319 my ($lvalue, $rvalue) = @_;
320
321 if ($rvalue =~ /^\s*$/) {
322 delete $variable{$lvalue};
323 } else {
324 $rvalue = process_variables($rvalue);
325 $variable{$lvalue} = $rvalue;
326 }
327}
328
Steven Rostedt2545eb62010-11-02 15:01:32 -0400329sub read_config {
330 my ($config) = @_;
331
332 open(IN, $config) || die "can't read file $config";
333
Steven Rostedta57419b2010-11-02 15:13:54 -0400334 my $name = $config;
335 $name =~ s,.*/(.*),$1,;
336
337 my $test_num = 0;
338 my $default = 1;
339 my $repeat = 1;
340 my $num_tests_set = 0;
341 my $skip = 0;
342 my $rest;
343
Steven Rostedt2545eb62010-11-02 15:01:32 -0400344 while (<IN>) {
345
346 # ignore blank lines and comments
347 next if (/^\s*$/ || /\s*\#/);
348
Steven Rostedta57419b2010-11-02 15:13:54 -0400349 if (/^\s*TEST_START(.*)/) {
350
351 $rest = $1;
352
353 if ($num_tests_set) {
354 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
355 }
356
357 my $old_test_num = $test_num;
Steven Rostedte48c5292010-11-02 14:35:37 -0400358 my $old_repeat = $repeat;
Steven Rostedta57419b2010-11-02 15:13:54 -0400359
360 $test_num += $repeat;
361 $default = 0;
362 $repeat = 1;
363
364 if ($rest =~ /\s+SKIP(.*)/) {
365 $rest = $1;
366 $skip = 1;
367 } else {
368 $skip = 0;
369 }
370
371 if ($rest =~ /\s+ITERATE\s+(\d+)(.*)$/) {
372 $repeat = $1;
373 $rest = $2;
374 $repeat_tests{"$test_num"} = $repeat;
375 }
376
377 if ($rest =~ /\s+SKIP(.*)/) {
378 $rest = $1;
379 $skip = 1;
380 }
381
382 if ($rest !~ /^\s*$/) {
383 die "$name: $.: Gargbage found after TEST_START\n$_";
384 }
385
386 if ($skip) {
387 $test_num = $old_test_num;
Steven Rostedte48c5292010-11-02 14:35:37 -0400388 $repeat = $old_repeat;
Steven Rostedta57419b2010-11-02 15:13:54 -0400389 }
390
391 } elsif (/^\s*DEFAULTS(.*)$/) {
392 $default = 1;
393
394 $rest = $1;
395
396 if ($rest =~ /\s+SKIP(.*)/) {
397 $rest = $1;
398 $skip = 1;
399 } else {
400 $skip = 0;
401 }
402
403 if ($rest !~ /^\s*$/) {
404 die "$name: $.: Gargbage found after DEFAULTS\n$_";
405 }
406
407 } elsif (/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) {
408
409 next if ($skip);
410
Steven Rostedt2545eb62010-11-02 15:01:32 -0400411 my $lvalue = $1;
412 my $rvalue = $2;
413
Steven Rostedta57419b2010-11-02 15:13:54 -0400414 if (!$default &&
415 ($lvalue eq "NUM_TESTS" ||
416 $lvalue eq "LOG_FILE" ||
417 $lvalue eq "CLEAR_LOG")) {
418 die "$name: $.: $lvalue must be set in DEFAULTS section\n";
Steven Rostedta75fece2010-11-02 14:58:27 -0400419 }
Steven Rostedta57419b2010-11-02 15:13:54 -0400420
421 if ($lvalue eq "NUM_TESTS") {
422 if ($test_num) {
423 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
424 }
425 if (!$default) {
426 die "$name: $.: NUM_TESTS must be set in default section\n";
427 }
428 $num_tests_set = 1;
429 }
430
431 if ($default || $lvalue =~ /\[\d+\]$/) {
432 set_value($lvalue, $rvalue);
433 } else {
434 my $val = "$lvalue\[$test_num\]";
435 set_value($val, $rvalue);
436
437 if ($repeat > 1) {
438 $repeats{$val} = $repeat;
439 }
440 }
Steven Rostedt77d942c2011-05-20 13:36:58 -0400441 } elsif (/^\s*([A-Z_\[\]\d]+)\s*:=\s*(.*?)\s*$/) {
442 next if ($skip);
443
444 my $lvalue = $1;
445 my $rvalue = $2;
446
447 # process config variables.
448 # Config variables are only active while reading the
449 # config and can be defined anywhere. They also ignore
450 # TEST_START and DEFAULTS, but are skipped if they are in
451 # on of these sections that have SKIP defined.
452 # The save variable can be
453 # defined multiple times and the new one simply overrides
454 # the prevous one.
455 set_variable($lvalue, $rvalue);
456
Steven Rostedta57419b2010-11-02 15:13:54 -0400457 } else {
458 die "$name: $.: Garbage found in config\n$_";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400459 }
460 }
461
462 close(IN);
Steven Rostedta75fece2010-11-02 14:58:27 -0400463
Steven Rostedta57419b2010-11-02 15:13:54 -0400464 if ($test_num) {
465 $test_num += $repeat - 1;
466 $opt{"NUM_TESTS"} = $test_num;
467 }
468
Steven Rostedt8d1491b2010-11-18 15:39:48 -0500469 # make sure we have all mandatory configs
470 get_ktest_configs;
471
Steven Rostedta75fece2010-11-02 14:58:27 -0400472 # set any defaults
473
474 foreach my $default (keys %default) {
475 if (!defined($opt{$default})) {
476 $opt{$default} = $default{$default};
477 }
478 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400479}
480
Steven Rostedt23715c3c2011-06-13 11:03:34 -0400481sub __eval_option {
482 my ($option, $i) = @_;
483
484 # Add space to evaluate the character before $
485 $option = " $option";
486 my $retval = "";
487
488 while ($option =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
489 my $start = $1;
490 my $var = $2;
491 my $end = $3;
492
493 # Append beginning of line
494 $retval = "$retval$start";
495
496 # If the iteration option OPT[$i] exists, then use that.
497 # otherwise see if the default OPT (without [$i]) exists.
498
499 my $o = "$var\[$i\]";
500
501 if (defined($opt{$o})) {
502 $o = $opt{$o};
503 $retval = "$retval$o";
504 } elsif (defined($opt{$var})) {
505 $o = $opt{$var};
506 $retval = "$retval$o";
507 } else {
508 $retval = "$retval\$\{$var\}";
509 }
510
511 $option = $end;
512 }
513
514 $retval = "$retval$option";
515
516 $retval =~ s/^ //;
517
518 return $retval;
519}
520
521sub eval_option {
522 my ($option, $i) = @_;
523
524 my $prev = "";
525
526 # Since an option can evaluate to another option,
527 # keep iterating until we do not evaluate any more
528 # options.
529 my $r = 0;
530 while ($prev ne $option) {
531 # Check for recursive evaluations.
532 # 100 deep should be more than enough.
533 if ($r++ > 100) {
534 die "Over 100 evaluations accurred with $option\n" .
535 "Check for recursive variables\n";
536 }
537 $prev = $option;
538 $option = __eval_option($option, $i);
539 }
540
541 return $option;
542}
543
Steven Rostedtd1e2f222010-11-08 16:39:57 -0500544sub _logit {
Steven Rostedt2545eb62010-11-02 15:01:32 -0400545 if (defined($opt{"LOG_FILE"})) {
546 open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}";
547 print OUT @_;
548 close(OUT);
549 }
550}
551
Steven Rostedtd1e2f222010-11-08 16:39:57 -0500552sub logit {
553 if (defined($opt{"LOG_FILE"})) {
554 _logit @_;
555 } else {
556 print @_;
557 }
558}
559
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400560sub doprint {
561 print @_;
Steven Rostedtd1e2f222010-11-08 16:39:57 -0500562 _logit @_;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400563}
564
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400565sub run_command;
566
567sub reboot {
568 # try to reboot normally
Steven Rostedte48c5292010-11-02 14:35:37 -0400569 if (run_command $reboot) {
Steven Rostedt576f6272010-11-02 14:58:38 -0400570 if (defined($powercycle_after_reboot)) {
571 sleep $powercycle_after_reboot;
572 run_command "$power_cycle";
573 }
574 } else {
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400575 # nope? power cycle it.
Steven Rostedta75fece2010-11-02 14:58:27 -0400576 run_command "$power_cycle";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400577 }
578}
579
Steven Rostedt576f6272010-11-02 14:58:38 -0400580sub do_not_reboot {
581 my $i = $iteration;
582
583 return $test_type eq "build" ||
584 ($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") ||
585 ($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build");
586}
587
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400588sub dodie {
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400589 doprint "CRITICAL FAILURE... ", @_, "\n";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400590
Steven Rostedt576f6272010-11-02 14:58:38 -0400591 my $i = $iteration;
592
593 if ($reboot_on_error && !do_not_reboot) {
594
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400595 doprint "REBOOTING\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400596 reboot;
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400597
Steven Rostedta75fece2010-11-02 14:58:27 -0400598 } elsif ($poweroff_on_error && defined($power_off)) {
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400599 doprint "POWERING OFF\n";
Steven Rostedta75fece2010-11-02 14:58:27 -0400600 `$power_off`;
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400601 }
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400602
Steven Rostedtf80802c2011-03-07 13:18:47 -0500603 if (defined($opt{"LOG_FILE"})) {
604 print " See $opt{LOG_FILE} for more info.\n";
605 }
606
Steven Rostedt576f6272010-11-02 14:58:38 -0400607 die @_, "\n";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400608}
609
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400610sub open_console {
611 my ($fp) = @_;
612
613 my $flags;
614
Steven Rostedta75fece2010-11-02 14:58:27 -0400615 my $pid = open($fp, "$console|") or
616 dodie "Can't open console $console";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400617
618 $flags = fcntl($fp, F_GETFL, 0) or
Steven Rostedt576f6272010-11-02 14:58:38 -0400619 dodie "Can't get flags for the socket: $!";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400620 $flags = fcntl($fp, F_SETFL, $flags | O_NONBLOCK) or
Steven Rostedt576f6272010-11-02 14:58:38 -0400621 dodie "Can't set flags for the socket: $!";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400622
623 return $pid;
624}
625
626sub close_console {
627 my ($fp, $pid) = @_;
628
629 doprint "kill child process $pid\n";
630 kill 2, $pid;
631
632 print "closing!\n";
633 close($fp);
634}
635
636sub start_monitor {
637 if ($monitor_cnt++) {
638 return;
639 }
640 $monitor_fp = \*MONFD;
641 $monitor_pid = open_console $monitor_fp;
Steven Rostedta75fece2010-11-02 14:58:27 -0400642
643 return;
644
645 open(MONFD, "Stop perl from warning about single use of MONFD");
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400646}
647
648sub end_monitor {
649 if (--$monitor_cnt) {
650 return;
651 }
652 close_console($monitor_fp, $monitor_pid);
653}
654
655sub wait_for_monitor {
656 my ($time) = @_;
657 my $line;
658
Steven Rostedta75fece2010-11-02 14:58:27 -0400659 doprint "** Wait for monitor to settle down **\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400660
661 # read the monitor and wait for the system to calm down
662 do {
663 $line = wait_for_input($monitor_fp, $time);
Steven Rostedta75fece2010-11-02 14:58:27 -0400664 print "$line" if (defined($line));
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400665 } while (defined($line));
Steven Rostedta75fece2010-11-02 14:58:27 -0400666 print "** Monitor flushed **\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400667}
668
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400669sub fail {
670
Steven Rostedta75fece2010-11-02 14:58:27 -0400671 if ($die_on_failure) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400672 dodie @_;
673 }
674
Steven Rostedta75fece2010-11-02 14:58:27 -0400675 doprint "FAILED\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400676
Steven Rostedt576f6272010-11-02 14:58:38 -0400677 my $i = $iteration;
678
Steven Rostedta75fece2010-11-02 14:58:27 -0400679 # no need to reboot for just building.
Steven Rostedt576f6272010-11-02 14:58:38 -0400680 if (!do_not_reboot) {
Steven Rostedta75fece2010-11-02 14:58:27 -0400681 doprint "REBOOTING\n";
682 reboot;
683 start_monitor;
684 wait_for_monitor $sleep_time;
685 end_monitor;
686 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400687
Steven Rostedt9064af52011-06-13 10:38:48 -0400688 my $name = "";
689
690 if (defined($test_name)) {
691 $name = " ($test_name)";
692 }
693
Steven Rostedt576f6272010-11-02 14:58:38 -0400694 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
695 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
Steven Rostedt9064af52011-06-13 10:38:48 -0400696 doprint "KTEST RESULT: TEST $i$name Failed: ", @_, "\n";
Steven Rostedt576f6272010-11-02 14:58:38 -0400697 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
698 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
Steven Rostedta75fece2010-11-02 14:58:27 -0400699
700 return 1 if (!defined($store_failures));
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400701
702 my @t = localtime;
703 my $date = sprintf "%04d%02d%02d%02d%02d%02d",
704 1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0];
705
Steven Rostedtcccae1a2010-11-09 12:21:32 -0500706 my $type = $build_type;
707 if ($type =~ /useconfig/) {
708 $type = "useconfig";
709 }
710
711 my $dir = "$machine-$test_type-$type-fail-$date";
Steven Rostedta75fece2010-11-02 14:58:27 -0400712 my $faildir = "$store_failures/$dir";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400713
714 if (!-d $faildir) {
715 mkpath($faildir) or
Steven Rostedta75fece2010-11-02 14:58:27 -0400716 die "can't create $faildir";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400717 }
Steven Rostedt51ad1dd2010-11-08 16:43:21 -0500718 if (-f "$output_config") {
719 cp "$output_config", "$faildir/config" or
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400720 die "failed to copy .config";
721 }
722 if (-f $buildlog) {
723 cp $buildlog, "$faildir/buildlog" or
724 die "failed to move $buildlog";
725 }
726 if (-f $dmesg) {
727 cp $dmesg, "$faildir/dmesg" or
728 die "failed to move $dmesg";
729 }
730
731 doprint "*** Saved info to $faildir ***\n";
732
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400733 return 1;
734}
735
Steven Rostedt2545eb62010-11-02 15:01:32 -0400736sub run_command {
737 my ($command) = @_;
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400738 my $dolog = 0;
739 my $dord = 0;
740 my $pid;
741
Steven Rostedte48c5292010-11-02 14:35:37 -0400742 $command =~ s/\$SSH_USER/$ssh_user/g;
743 $command =~ s/\$MACHINE/$machine/g;
744
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400745 doprint("$command ... ");
746
747 $pid = open(CMD, "$command 2>&1 |") or
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400748 (fail "unable to exec $command" and return 0);
Steven Rostedt2545eb62010-11-02 15:01:32 -0400749
750 if (defined($opt{"LOG_FILE"})) {
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400751 open(LOG, ">>$opt{LOG_FILE}") or
752 dodie "failed to write to log";
753 $dolog = 1;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400754 }
755
756 if (defined($redirect)) {
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400757 open (RD, ">$redirect") or
758 dodie "failed to write to redirect $redirect";
759 $dord = 1;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400760 }
761
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400762 while (<CMD>) {
763 print LOG if ($dolog);
764 print RD if ($dord);
765 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400766
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400767 waitpid($pid, 0);
Steven Rostedt2545eb62010-11-02 15:01:32 -0400768 my $failed = $?;
769
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400770 close(CMD);
771 close(LOG) if ($dolog);
772 close(RD) if ($dord);
773
Steven Rostedt2545eb62010-11-02 15:01:32 -0400774 if ($failed) {
775 doprint "FAILED!\n";
776 } else {
777 doprint "SUCCESS\n";
778 }
779
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400780 return !$failed;
781}
782
Steven Rostedte48c5292010-11-02 14:35:37 -0400783sub run_ssh {
784 my ($cmd) = @_;
785 my $cp_exec = $ssh_exec;
786
787 $cp_exec =~ s/\$SSH_COMMAND/$cmd/g;
788 return run_command "$cp_exec";
789}
790
791sub run_scp {
792 my ($src, $dst) = @_;
793 my $cp_scp = $scp_to_target;
794
795 $cp_scp =~ s/\$SRC_FILE/$src/g;
796 $cp_scp =~ s/\$DST_FILE/$dst/g;
797
798 return run_command "$cp_scp";
799}
800
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400801sub get_grub_index {
802
Steven Rostedta75fece2010-11-02 14:58:27 -0400803 if ($reboot_type ne "grub") {
804 return;
805 }
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400806 return if (defined($grub_number));
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400807
808 doprint "Find grub menu ... ";
809 $grub_number = -1;
Steven Rostedte48c5292010-11-02 14:35:37 -0400810
811 my $ssh_grub = $ssh_exec;
812 $ssh_grub =~ s,\$SSH_COMMAND,cat /boot/grub/menu.lst,g;
813
814 open(IN, "$ssh_grub |")
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400815 or die "unable to get menu.lst";
Steven Rostedte48c5292010-11-02 14:35:37 -0400816
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400817 while (<IN>) {
Steven Rostedta75fece2010-11-02 14:58:27 -0400818 if (/^\s*title\s+$grub_menu\s*$/) {
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400819 $grub_number++;
820 last;
821 } elsif (/^\s*title\s/) {
822 $grub_number++;
823 }
824 }
825 close(IN);
826
Steven Rostedta75fece2010-11-02 14:58:27 -0400827 die "Could not find '$grub_menu' in /boot/grub/menu on $machine"
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400828 if ($grub_number < 0);
829 doprint "$grub_number\n";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400830}
831
Steven Rostedt2545eb62010-11-02 15:01:32 -0400832sub wait_for_input
833{
834 my ($fp, $time) = @_;
835 my $rin;
836 my $ready;
837 my $line;
838 my $ch;
839
840 if (!defined($time)) {
841 $time = $timeout;
842 }
843
844 $rin = '';
845 vec($rin, fileno($fp), 1) = 1;
846 $ready = select($rin, undef, undef, $time);
847
848 $line = "";
849
850 # try to read one char at a time
851 while (sysread $fp, $ch, 1) {
852 $line .= $ch;
853 last if ($ch eq "\n");
854 }
855
856 if (!length($line)) {
857 return undef;
858 }
859
860 return $line;
861}
862
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400863sub reboot_to {
Steven Rostedta75fece2010-11-02 14:58:27 -0400864 if ($reboot_type eq "grub") {
Steven Rostedt4da46da2011-06-01 23:25:13 -0400865 run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch && reboot)'";
Steven Rostedta75fece2010-11-02 14:58:27 -0400866 return;
867 }
868
869 run_command "$reboot_script";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400870}
871
Steven Rostedta57419b2010-11-02 15:13:54 -0400872sub get_sha1 {
873 my ($commit) = @_;
874
875 doprint "git rev-list --max-count=1 $commit ... ";
876 my $sha1 = `git rev-list --max-count=1 $commit`;
877 my $ret = $?;
878
879 logit $sha1;
880
881 if ($ret) {
882 doprint "FAILED\n";
883 dodie "Failed to get git $commit";
884 }
885
886 print "SUCCESS\n";
887
888 chomp $sha1;
889
890 return $sha1;
891}
892
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400893sub monitor {
Steven Rostedt2545eb62010-11-02 15:01:32 -0400894 my $booted = 0;
895 my $bug = 0;
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400896 my $skip_call_trace = 0;
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400897 my $loops;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400898
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400899 wait_for_monitor 5;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400900
901 my $line;
902 my $full_line = "";
903
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400904 open(DMESG, "> $dmesg") or
905 die "unable to write to $dmesg";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400906
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400907 reboot_to;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400908
Steven Rostedt1c8a6172010-11-09 12:55:40 -0500909 my $success_start;
910 my $failure_start;
Steven Rostedt2d01b262011-03-08 09:47:54 -0500911 my $monitor_start = time;
912 my $done = 0;
Steven Rostedtf1a5b962011-06-13 10:30:00 -0400913 my $version_found = 0;
Steven Rostedt1c8a6172010-11-09 12:55:40 -0500914
Steven Rostedt2d01b262011-03-08 09:47:54 -0500915 while (!$done) {
Steven Rostedt2545eb62010-11-02 15:01:32 -0400916
Steven Rostedtecaf8e52011-06-13 10:48:10 -0400917 if ($bug && defined($stop_after_failure) &&
918 $stop_after_failure >= 0) {
919 my $time = $stop_after_failure - (time - $failure_start);
920 $line = wait_for_input($monitor_fp, $time);
921 if (!defined($line)) {
922 doprint "bug timed out after $booted_timeout seconds\n";
923 doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
924 last;
925 }
926 } elsif ($booted) {
Steven Rostedta75fece2010-11-02 14:58:27 -0400927 $line = wait_for_input($monitor_fp, $booted_timeout);
Steven Rostedtcd4f1d52011-06-13 10:26:27 -0400928 if (!defined($line)) {
929 my $s = $booted_timeout == 1 ? "" : "s";
930 doprint "Successful boot found: break after $booted_timeout second$s\n";
931 last;
932 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400933 } else {
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400934 $line = wait_for_input($monitor_fp);
Steven Rostedtcd4f1d52011-06-13 10:26:27 -0400935 if (!defined($line)) {
936 my $s = $timeout == 1 ? "" : "s";
937 doprint "Timed out after $timeout second$s\n";
938 last;
939 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400940 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400941
Steven Rostedt2545eb62010-11-02 15:01:32 -0400942 doprint $line;
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400943 print DMESG $line;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400944
945 # we are not guaranteed to get a full line
946 $full_line .= $line;
947
Steven Rostedta75fece2010-11-02 14:58:27 -0400948 if ($full_line =~ /$success_line/) {
Steven Rostedt2545eb62010-11-02 15:01:32 -0400949 $booted = 1;
Steven Rostedt1c8a6172010-11-09 12:55:40 -0500950 $success_start = time;
951 }
952
953 if ($booted && defined($stop_after_success) &&
954 $stop_after_success >= 0) {
955 my $now = time;
956 if ($now - $success_start >= $stop_after_success) {
957 doprint "Test forced to stop after $stop_after_success seconds after success\n";
958 last;
959 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400960 }
961
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400962 if ($full_line =~ /\[ backtrace testing \]/) {
963 $skip_call_trace = 1;
964 }
965
Steven Rostedt2545eb62010-11-02 15:01:32 -0400966 if ($full_line =~ /call trace:/i) {
Steven Rostedt46519202011-03-08 09:40:31 -0500967 if (!$bug && !$skip_call_trace) {
Steven Rostedt1c8a6172010-11-09 12:55:40 -0500968 $bug = 1;
969 $failure_start = time;
970 }
971 }
972
973 if ($bug && defined($stop_after_failure) &&
974 $stop_after_failure >= 0) {
975 my $now = time;
976 if ($now - $failure_start >= $stop_after_failure) {
977 doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
978 last;
979 }
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400980 }
981
982 if ($full_line =~ /\[ end of backtrace testing \]/) {
983 $skip_call_trace = 0;
984 }
985
986 if ($full_line =~ /Kernel panic -/) {
Steven Rostedt10abf112011-03-07 13:21:00 -0500987 $failure_start = time;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400988 $bug = 1;
989 }
990
Steven Rostedtf1a5b962011-06-13 10:30:00 -0400991 # Detect triple faults by testing the banner
992 if ($full_line =~ /\bLinux version (\S+).*\n/) {
993 if ($1 eq $version) {
994 $version_found = 1;
995 } elsif ($version_found && $detect_triplefault) {
996 # We already booted into the kernel we are testing,
997 # but now we booted into another kernel?
998 # Consider this a triple fault.
999 doprint "Aleady booted in Linux kernel $version, but now\n";
1000 doprint "we booted into Linux kernel $1.\n";
1001 doprint "Assuming that this is a triple fault.\n";
1002 doprint "To disable this: set DETECT_TRIPLE_FAULT to 0\n";
1003 last;
1004 }
1005 }
1006
Steven Rostedt2545eb62010-11-02 15:01:32 -04001007 if ($line =~ /\n/) {
1008 $full_line = "";
1009 }
Steven Rostedt2d01b262011-03-08 09:47:54 -05001010
1011 if ($stop_test_after > 0 && !$booted && !$bug) {
1012 if (time - $monitor_start > $stop_test_after) {
Steven Rostedt4d62bf52011-05-20 09:14:35 -04001013 doprint "STOP_TEST_AFTER ($stop_test_after seconds) timed out\n";
Steven Rostedt2d01b262011-03-08 09:47:54 -05001014 $done = 1;
1015 }
1016 }
Steven Rostedt2545eb62010-11-02 15:01:32 -04001017 }
1018
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001019 close(DMESG);
Steven Rostedt2545eb62010-11-02 15:01:32 -04001020
Steven Rostedt2545eb62010-11-02 15:01:32 -04001021 if ($bug) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001022 return 0 if ($in_bisect);
Steven Rostedt576f6272010-11-02 14:58:38 -04001023 fail "failed - got a bug report" and return 0;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001024 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001025
Steven Rostedta75fece2010-11-02 14:58:27 -04001026 if (!$booted) {
1027 return 0 if ($in_bisect);
Steven Rostedt576f6272010-11-02 14:58:38 -04001028 fail "failed - never got a boot prompt." and return 0;
Steven Rostedta75fece2010-11-02 14:58:27 -04001029 }
1030
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001031 return 1;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001032}
1033
Steven Rostedtdb05cfe2011-06-13 11:09:22 -04001034sub do_post_install {
1035
1036 return if (!defined($post_install));
1037
1038 my $cp_post_install = $post_install;
1039 $cp_post_install =~ s/\$KERNEL_VERSION/$version/g;
1040 run_command "$cp_post_install" or
1041 dodie "Failed to run post install";
1042}
1043
Steven Rostedt2545eb62010-11-02 15:01:32 -04001044sub install {
1045
Steven Rostedte48c5292010-11-02 14:35:37 -04001046 run_scp "$outputdir/$build_target", "$target_image" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001047 dodie "failed to copy image";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001048
1049 my $install_mods = 0;
1050
1051 # should we process modules?
1052 $install_mods = 0;
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05001053 open(IN, "$output_config") or dodie("Can't read config file");
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001054 while (<IN>) {
1055 if (/CONFIG_MODULES(=y)?/) {
1056 $install_mods = 1 if (defined($1));
1057 last;
1058 }
1059 }
1060 close(IN);
1061
1062 if (!$install_mods) {
Steven Rostedtdb05cfe2011-06-13 11:09:22 -04001063 do_post_install;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001064 doprint "No modules needed\n";
1065 return;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001066 }
1067
Steven Rostedta75fece2010-11-02 14:58:27 -04001068 run_command "$make INSTALL_MOD_PATH=$tmpdir modules_install" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001069 dodie "Failed to install modules";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001070
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001071 my $modlib = "/lib/modules/$version";
Steven Rostedta57419b2010-11-02 15:13:54 -04001072 my $modtar = "ktest-mods.tar.bz2";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001073
Steven Rostedte48c5292010-11-02 14:35:37 -04001074 run_ssh "rm -rf $modlib" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001075 dodie "failed to remove old mods: $modlib";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001076
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001077 # would be nice if scp -r did not follow symbolic links
Steven Rostedta75fece2010-11-02 14:58:27 -04001078 run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001079 dodie "making tarball";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001080
Steven Rostedte48c5292010-11-02 14:35:37 -04001081 run_scp "$tmpdir/$modtar", "/tmp" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001082 dodie "failed to copy modules";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001083
Steven Rostedta75fece2010-11-02 14:58:27 -04001084 unlink "$tmpdir/$modtar";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001085
Steven Rostedte48c5292010-11-02 14:35:37 -04001086 run_ssh "'(cd / && tar xf /tmp/$modtar)'" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001087 dodie "failed to tar modules";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001088
Steven Rostedte48c5292010-11-02 14:35:37 -04001089 run_ssh "rm -f /tmp/$modtar";
Steven Rostedt8b37ca82010-11-02 14:58:33 -04001090
Steven Rostedtdb05cfe2011-06-13 11:09:22 -04001091 do_post_install;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001092}
1093
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001094sub check_buildlog {
1095 my ($patch) = @_;
1096
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001097 my @files = `git show $patch | diffstat -l`;
1098
1099 open(IN, "git show $patch |") or
1100 dodie "failed to show $patch";
1101 while (<IN>) {
1102 if (m,^--- a/(.*),) {
1103 chomp $1;
1104 $files[$#files] = $1;
1105 }
1106 }
1107 close(IN);
1108
1109 open(IN, $buildlog) or dodie "Can't open $buildlog";
1110 while (<IN>) {
1111 if (/^\s*(.*?):.*(warning|error)/) {
1112 my $err = $1;
1113 foreach my $file (@files) {
Steven Rostedta75fece2010-11-02 14:58:27 -04001114 my $fullpath = "$builddir/$file";
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001115 if ($file eq $err || $fullpath eq $err) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001116 fail "$file built with warnings" and return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001117 }
1118 }
1119 }
1120 }
1121 close(IN);
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001122
1123 return 1;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001124}
1125
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001126sub apply_min_config {
1127 my $outconfig = "$output_config.new";
Steven Rostedt612b9e92011-03-07 13:27:43 -05001128
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001129 # Read the config file and remove anything that
1130 # is in the force_config hash (from minconfig and others)
1131 # then add the force config back.
1132
1133 doprint "Applying minimum configurations into $output_config.new\n";
1134
1135 open (OUT, ">$outconfig") or
1136 dodie "Can't create $outconfig";
1137
1138 if (-f $output_config) {
1139 open (IN, $output_config) or
1140 dodie "Failed to open $output_config";
1141 while (<IN>) {
1142 if (/^(# )?(CONFIG_[^\s=]*)/) {
1143 next if (defined($force_config{$2}));
1144 }
1145 print OUT;
1146 }
1147 close IN;
1148 }
1149 foreach my $config (keys %force_config) {
1150 print OUT "$force_config{$config}\n";
1151 }
1152 close OUT;
1153
1154 run_command "mv $outconfig $output_config";
1155}
1156
1157sub make_oldconfig {
1158
1159 apply_min_config;
1160
1161 if (!run_command "$make oldnoconfig") {
Steven Rostedt612b9e92011-03-07 13:27:43 -05001162 # Perhaps oldnoconfig doesn't exist in this version of the kernel
1163 # try a yes '' | oldconfig
1164 doprint "oldnoconfig failed, trying yes '' | make oldconfig\n";
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001165 run_command "yes '' | $make oldconfig" or
Steven Rostedt612b9e92011-03-07 13:27:43 -05001166 dodie "failed make config oldconfig";
1167 }
1168}
1169
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001170# read a config file and use this to force new configs.
1171sub load_force_config {
1172 my ($config) = @_;
1173
1174 open(IN, $config) or
1175 dodie "failed to read $config";
1176 while (<IN>) {
1177 chomp;
1178 if (/^(CONFIG[^\s=]*)(\s*=.*)/) {
1179 $force_config{$1} = $_;
1180 } elsif (/^# (CONFIG_\S*) is not set/) {
1181 $force_config{$1} = $_;
1182 }
1183 }
1184 close IN;
1185}
1186
Steven Rostedt2545eb62010-11-02 15:01:32 -04001187sub build {
1188 my ($type) = @_;
1189
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001190 unlink $buildlog;
1191
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001192 if ($type =~ /^useconfig:(.*)/) {
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05001193 run_command "cp $1 $output_config" or
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001194 dodie "could not copy $1 to .config";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001195
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001196 $type = "oldconfig";
1197 }
1198
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001199 # old config can ask questions
1200 if ($type eq "oldconfig") {
Steven Rostedt9386c6a2010-11-08 16:35:48 -05001201 $type = "oldnoconfig";
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001202
1203 # allow for empty configs
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05001204 run_command "touch $output_config";
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001205
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05001206 run_command "mv $output_config $outputdir/config_temp" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001207 dodie "moving .config";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001208
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001209 if (!$noclean && !run_command "$make mrproper") {
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001210 dodie "make mrproper";
1211 }
1212
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05001213 run_command "mv $outputdir/config_temp $output_config" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001214 dodie "moving config_temp";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001215
1216 } elsif (!$noclean) {
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05001217 unlink "$output_config";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001218 run_command "$make mrproper" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001219 dodie "make mrproper";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001220 }
Steven Rostedt2545eb62010-11-02 15:01:32 -04001221
1222 # add something to distinguish this build
Steven Rostedta75fece2010-11-02 14:58:27 -04001223 open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file");
1224 print OUT "$localversion\n";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001225 close(OUT);
1226
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001227 if (defined($minconfig)) {
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001228 load_force_config($minconfig);
Steven Rostedt2545eb62010-11-02 15:01:32 -04001229 }
1230
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001231 if ($type ne "oldnoconfig") {
1232 run_command "$make $type" or
Steven Rostedt612b9e92011-03-07 13:27:43 -05001233 dodie "failed make config";
1234 }
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001235 # Run old config regardless, to enforce min configurations
1236 make_oldconfig;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001237
Steven Rostedta75fece2010-11-02 14:58:27 -04001238 $redirect = "$buildlog";
1239 if (!run_command "$make $build_options") {
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001240 undef $redirect;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001241 # bisect may need this to pass
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001242 return 0 if ($in_bisect);
1243 fail "failed build" and return 0;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001244 }
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001245 undef $redirect;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001246
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001247 return 1;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001248}
1249
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001250sub halt {
Steven Rostedte48c5292010-11-02 14:35:37 -04001251 if (!run_ssh "halt" or defined($power_off)) {
Steven Rostedt576f6272010-11-02 14:58:38 -04001252 if (defined($poweroff_after_halt)) {
1253 sleep $poweroff_after_halt;
1254 run_command "$power_off";
1255 }
1256 } else {
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001257 # nope? the zap it!
Steven Rostedta75fece2010-11-02 14:58:27 -04001258 run_command "$power_off";
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001259 }
1260}
1261
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001262sub success {
1263 my ($i) = @_;
1264
Steven Rostedte48c5292010-11-02 14:35:37 -04001265 $successes++;
1266
Steven Rostedt9064af52011-06-13 10:38:48 -04001267 my $name = "";
1268
1269 if (defined($test_name)) {
1270 $name = " ($test_name)";
1271 }
1272
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001273 doprint "\n\n*******************************************\n";
1274 doprint "*******************************************\n";
Steven Rostedt9064af52011-06-13 10:38:48 -04001275 doprint "KTEST RESULT: TEST $i$name SUCCESS!!!! **\n";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001276 doprint "*******************************************\n";
1277 doprint "*******************************************\n";
1278
Steven Rostedt576f6272010-11-02 14:58:38 -04001279 if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) {
Steven Rostedta75fece2010-11-02 14:58:27 -04001280 doprint "Reboot and wait $sleep_time seconds\n";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001281 reboot;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001282 start_monitor;
Steven Rostedta75fece2010-11-02 14:58:27 -04001283 wait_for_monitor $sleep_time;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001284 end_monitor;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001285 }
1286}
1287
1288sub get_version {
1289 # get the release name
1290 doprint "$make kernelrelease ... ";
1291 $version = `$make kernelrelease | tail -1`;
1292 chomp($version);
1293 doprint "$version\n";
1294}
1295
Steven Rostedtc960bb92011-03-08 09:22:39 -05001296sub answer_bisect {
1297 for (;;) {
1298 doprint "Pass or fail? [p/f]";
1299 my $ans = <STDIN>;
1300 chomp $ans;
1301 if ($ans eq "p" || $ans eq "P") {
1302 return 1;
1303 } elsif ($ans eq "f" || $ans eq "F") {
1304 return 0;
1305 } else {
1306 print "Please answer 'P' or 'F'\n";
1307 }
1308 }
1309}
1310
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001311sub child_run_test {
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001312 my $failed = 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001313
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001314 # child should have no power
Steven Rostedta75fece2010-11-02 14:58:27 -04001315 $reboot_on_error = 0;
1316 $poweroff_on_error = 0;
1317 $die_on_failure = 1;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001318
1319 run_command $run_test or $failed = 1;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001320 exit $failed;
1321}
1322
1323my $child_done;
1324
1325sub child_finished {
1326 $child_done = 1;
1327}
1328
1329sub do_run_test {
1330 my $child_pid;
1331 my $child_exit;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001332 my $line;
1333 my $full_line;
1334 my $bug = 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001335
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001336 wait_for_monitor 1;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001337
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001338 doprint "run test $run_test\n";
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001339
1340 $child_done = 0;
1341
1342 $SIG{CHLD} = qw(child_finished);
1343
1344 $child_pid = fork;
1345
1346 child_run_test if (!$child_pid);
1347
1348 $full_line = "";
1349
1350 do {
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001351 $line = wait_for_input($monitor_fp, 1);
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001352 if (defined($line)) {
1353
1354 # we are not guaranteed to get a full line
1355 $full_line .= $line;
Steven Rostedt8ea0e062011-03-08 09:44:35 -05001356 doprint $line;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001357
1358 if ($full_line =~ /call trace:/i) {
1359 $bug = 1;
1360 }
1361
1362 if ($full_line =~ /Kernel panic -/) {
1363 $bug = 1;
1364 }
1365
1366 if ($line =~ /\n/) {
1367 $full_line = "";
1368 }
1369 }
1370 } while (!$child_done && !$bug);
1371
1372 if ($bug) {
Steven Rostedt8ea0e062011-03-08 09:44:35 -05001373 my $failure_start = time;
1374 my $now;
1375 do {
1376 $line = wait_for_input($monitor_fp, 1);
1377 if (defined($line)) {
1378 doprint $line;
1379 }
1380 $now = time;
1381 if ($now - $failure_start >= $stop_after_failure) {
1382 last;
1383 }
1384 } while (defined($line));
1385
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001386 doprint "Detected kernel crash!\n";
1387 # kill the child with extreme prejudice
1388 kill 9, $child_pid;
1389 }
1390
1391 waitpid $child_pid, 0;
1392 $child_exit = $?;
1393
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001394 if ($bug || $child_exit) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001395 return 0 if $in_bisect;
1396 fail "test failed" and return 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001397 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001398 return 1;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001399}
1400
Steven Rostedta75fece2010-11-02 14:58:27 -04001401sub run_git_bisect {
1402 my ($command) = @_;
1403
1404 doprint "$command ... ";
1405
1406 my $output = `$command 2>&1`;
1407 my $ret = $?;
1408
1409 logit $output;
1410
1411 if ($ret) {
1412 doprint "FAILED\n";
1413 dodie "Failed to git bisect";
1414 }
1415
1416 doprint "SUCCESS\n";
1417 if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) {
1418 doprint "$1 [$2]\n";
1419 } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) {
1420 $bisect_bad = $1;
1421 doprint "Found bad commit... $1\n";
1422 return 0;
1423 } else {
1424 # we already logged it, just print it now.
1425 print $output;
1426 }
1427
1428 return 1;
1429}
1430
Steven Rostedtc23dca72011-03-08 09:26:31 -05001431sub bisect_reboot {
1432 doprint "Reboot and sleep $bisect_sleep_time seconds\n";
1433 reboot;
1434 start_monitor;
1435 wait_for_monitor $bisect_sleep_time;
1436 end_monitor;
1437}
1438
1439# returns 1 on success, 0 on failure, -1 on skip
Steven Rostedt0a05c762010-11-08 11:14:10 -05001440sub run_bisect_test {
1441 my ($type, $buildtype) = @_;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001442
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001443 my $failed = 0;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001444 my $result;
1445 my $output;
1446 my $ret;
1447
Steven Rostedt0a05c762010-11-08 11:14:10 -05001448 $in_bisect = 1;
1449
1450 build $buildtype or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001451
1452 if ($type ne "build") {
Steven Rostedtc23dca72011-03-08 09:26:31 -05001453 if ($failed && $bisect_skip) {
1454 $in_bisect = 0;
1455 return -1;
1456 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001457 dodie "Failed on build" if $failed;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001458
1459 # Now boot the box
1460 get_grub_index;
1461 get_version;
1462 install;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001463
1464 start_monitor;
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001465 monitor or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001466
1467 if ($type ne "boot") {
Steven Rostedtc23dca72011-03-08 09:26:31 -05001468 if ($failed && $bisect_skip) {
1469 end_monitor;
1470 bisect_reboot;
1471 $in_bisect = 0;
1472 return -1;
1473 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001474 dodie "Failed on boot" if $failed;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001475
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001476 do_run_test or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001477 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001478 end_monitor;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001479 }
1480
1481 if ($failed) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001482 $result = 0;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001483 } else {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001484 $result = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001485 }
Steven Rostedt4025bc62011-05-20 09:16:29 -04001486
1487 # reboot the box to a kernel we can ssh to
1488 if ($type ne "build") {
1489 bisect_reboot;
1490 }
Steven Rostedt0a05c762010-11-08 11:14:10 -05001491 $in_bisect = 0;
1492
1493 return $result;
1494}
1495
1496sub run_bisect {
1497 my ($type) = @_;
1498 my $buildtype = "oldconfig";
1499
1500 # We should have a minconfig to use?
1501 if (defined($minconfig)) {
1502 $buildtype = "useconfig:$minconfig";
1503 }
1504
1505 my $ret = run_bisect_test $type, $buildtype;
1506
Steven Rostedtc960bb92011-03-08 09:22:39 -05001507 if ($bisect_manual) {
1508 $ret = answer_bisect;
1509 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001510
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04001511 # Are we looking for where it worked, not failed?
1512 if ($reverse_bisect) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001513 $ret = !$ret;
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04001514 }
1515
Steven Rostedtc23dca72011-03-08 09:26:31 -05001516 if ($ret > 0) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001517 return "good";
Steven Rostedtc23dca72011-03-08 09:26:31 -05001518 } elsif ($ret == 0) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001519 return "bad";
Steven Rostedtc23dca72011-03-08 09:26:31 -05001520 } elsif ($bisect_skip) {
1521 doprint "HIT A BAD COMMIT ... SKIPPING\n";
1522 return "skip";
Steven Rostedt0a05c762010-11-08 11:14:10 -05001523 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001524}
1525
1526sub bisect {
1527 my ($i) = @_;
1528
1529 my $result;
1530
1531 die "BISECT_GOOD[$i] not defined\n" if (!defined($opt{"BISECT_GOOD[$i]"}));
1532 die "BISECT_BAD[$i] not defined\n" if (!defined($opt{"BISECT_BAD[$i]"}));
1533 die "BISECT_TYPE[$i] not defined\n" if (!defined($opt{"BISECT_TYPE[$i]"}));
1534
1535 my $good = $opt{"BISECT_GOOD[$i]"};
1536 my $bad = $opt{"BISECT_BAD[$i]"};
1537 my $type = $opt{"BISECT_TYPE[$i]"};
Steven Rostedta75fece2010-11-02 14:58:27 -04001538 my $start = $opt{"BISECT_START[$i]"};
1539 my $replay = $opt{"BISECT_REPLAY[$i]"};
Steven Rostedt3410f6f2011-03-08 09:38:12 -05001540 my $start_files = $opt{"BISECT_FILES[$i]"};
1541
1542 if (defined($start_files)) {
1543 $start_files = " -- " . $start_files;
1544 } else {
1545 $start_files = "";
1546 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001547
Steven Rostedta57419b2010-11-02 15:13:54 -04001548 # convert to true sha1's
1549 $good = get_sha1($good);
1550 $bad = get_sha1($bad);
1551
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04001552 if (defined($opt{"BISECT_REVERSE[$i]"}) &&
1553 $opt{"BISECT_REVERSE[$i]"} == 1) {
1554 doprint "Performing a reverse bisect (bad is good, good is bad!)\n";
1555 $reverse_bisect = 1;
1556 } else {
1557 $reverse_bisect = 0;
1558 }
1559
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001560 # Can't have a test without having a test to run
1561 if ($type eq "test" && !defined($run_test)) {
1562 $type = "boot";
1563 }
1564
Steven Rostedta75fece2010-11-02 14:58:27 -04001565 my $check = $opt{"BISECT_CHECK[$i]"};
1566 if (defined($check) && $check ne "0") {
1567
1568 # get current HEAD
Steven Rostedta57419b2010-11-02 15:13:54 -04001569 my $head = get_sha1("HEAD");
Steven Rostedta75fece2010-11-02 14:58:27 -04001570
1571 if ($check ne "good") {
1572 doprint "TESTING BISECT BAD [$bad]\n";
1573 run_command "git checkout $bad" or
1574 die "Failed to checkout $bad";
1575
1576 $result = run_bisect $type;
1577
1578 if ($result ne "bad") {
1579 fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0;
1580 }
1581 }
1582
1583 if ($check ne "bad") {
1584 doprint "TESTING BISECT GOOD [$good]\n";
1585 run_command "git checkout $good" or
1586 die "Failed to checkout $good";
1587
1588 $result = run_bisect $type;
1589
1590 if ($result ne "good") {
1591 fail "Tested BISECT_GOOD [$good] and it failed" and return 0;
1592 }
1593 }
1594
1595 # checkout where we started
1596 run_command "git checkout $head" or
1597 die "Failed to checkout $head";
1598 }
1599
Steven Rostedt3410f6f2011-03-08 09:38:12 -05001600 run_command "git bisect start$start_files" or
Steven Rostedta75fece2010-11-02 14:58:27 -04001601 dodie "could not start bisect";
1602
1603 run_command "git bisect good $good" or
1604 dodie "could not set bisect good to $good";
1605
1606 run_git_bisect "git bisect bad $bad" or
1607 dodie "could not set bisect bad to $bad";
1608
1609 if (defined($replay)) {
1610 run_command "git bisect replay $replay" or
1611 dodie "failed to run replay";
1612 }
1613
1614 if (defined($start)) {
1615 run_command "git checkout $start" or
1616 dodie "failed to checkout $start";
1617 }
1618
1619 my $test;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001620 do {
1621 $result = run_bisect $type;
Steven Rostedta75fece2010-11-02 14:58:27 -04001622 $test = run_git_bisect "git bisect $result";
1623 } while ($test);
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001624
1625 run_command "git bisect log" or
1626 dodie "could not capture git bisect log";
1627
1628 run_command "git bisect reset" or
1629 dodie "could not reset git bisect";
1630
1631 doprint "Bad commit was [$bisect_bad]\n";
1632
Steven Rostedt0a05c762010-11-08 11:14:10 -05001633 success $i;
1634}
1635
1636my %config_ignore;
1637my %config_set;
1638
1639my %config_list;
1640my %null_config;
1641
1642my %dependency;
1643
1644sub process_config_ignore {
1645 my ($config) = @_;
1646
1647 open (IN, $config)
1648 or dodie "Failed to read $config";
1649
1650 while (<IN>) {
Steven Rostedt9bf71742011-06-01 23:27:19 -04001651 if (/^((CONFIG\S*)=.*)/) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001652 $config_ignore{$2} = $1;
1653 }
1654 }
1655
1656 close(IN);
1657}
1658
1659sub read_current_config {
1660 my ($config_ref) = @_;
1661
1662 %{$config_ref} = ();
1663 undef %{$config_ref};
1664
1665 my @key = keys %{$config_ref};
1666 if ($#key >= 0) {
1667 print "did not delete!\n";
1668 exit;
1669 }
1670 open (IN, "$output_config");
1671
1672 while (<IN>) {
1673 if (/^(CONFIG\S+)=(.*)/) {
1674 ${$config_ref}{$1} = $2;
1675 }
1676 }
1677 close(IN);
1678}
1679
1680sub get_dependencies {
1681 my ($config) = @_;
1682
1683 my $arr = $dependency{$config};
1684 if (!defined($arr)) {
1685 return ();
1686 }
1687
1688 my @deps = @{$arr};
1689
1690 foreach my $dep (@{$arr}) {
1691 print "ADD DEP $dep\n";
1692 @deps = (@deps, get_dependencies $dep);
1693 }
1694
1695 return @deps;
1696}
1697
1698sub create_config {
1699 my @configs = @_;
1700
1701 open(OUT, ">$output_config") or dodie "Can not write to $output_config";
1702
1703 foreach my $config (@configs) {
1704 print OUT "$config_set{$config}\n";
1705 my @deps = get_dependencies $config;
1706 foreach my $dep (@deps) {
1707 print OUT "$config_set{$dep}\n";
1708 }
1709 }
1710
1711 foreach my $config (keys %config_ignore) {
1712 print OUT "$config_ignore{$config}\n";
1713 }
1714 close(OUT);
1715
1716# exit;
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001717 make_oldconfig;
Steven Rostedt0a05c762010-11-08 11:14:10 -05001718}
1719
1720sub compare_configs {
1721 my (%a, %b) = @_;
1722
1723 foreach my $item (keys %a) {
1724 if (!defined($b{$item})) {
1725 print "diff $item\n";
1726 return 1;
1727 }
1728 delete $b{$item};
1729 }
1730
1731 my @keys = keys %b;
1732 if ($#keys) {
1733 print "diff2 $keys[0]\n";
1734 }
1735 return -1 if ($#keys >= 0);
1736
1737 return 0;
1738}
1739
1740sub run_config_bisect_test {
1741 my ($type) = @_;
1742
1743 return run_bisect_test $type, "oldconfig";
1744}
1745
1746sub process_passed {
1747 my (%configs) = @_;
1748
1749 doprint "These configs had no failure: (Enabling them for further compiles)\n";
1750 # Passed! All these configs are part of a good compile.
1751 # Add them to the min options.
1752 foreach my $config (keys %configs) {
1753 if (defined($config_list{$config})) {
1754 doprint " removing $config\n";
1755 $config_ignore{$config} = $config_list{$config};
1756 delete $config_list{$config};
1757 }
1758 }
Steven Rostedtf1a27852010-11-11 11:34:38 -05001759 doprint "config copied to $outputdir/config_good\n";
1760 run_command "cp -f $output_config $outputdir/config_good";
Steven Rostedt0a05c762010-11-08 11:14:10 -05001761}
1762
1763sub process_failed {
1764 my ($config) = @_;
1765
1766 doprint "\n\n***************************************\n";
1767 doprint "Found bad config: $config\n";
1768 doprint "***************************************\n\n";
1769}
1770
1771sub run_config_bisect {
1772
1773 my @start_list = keys %config_list;
1774
1775 if ($#start_list < 0) {
1776 doprint "No more configs to test!!!\n";
1777 return -1;
1778 }
1779
1780 doprint "***** RUN TEST ***\n";
1781 my $type = $opt{"CONFIG_BISECT_TYPE[$iteration]"};
1782 my $ret;
1783 my %current_config;
1784
1785 my $count = $#start_list + 1;
1786 doprint " $count configs to test\n";
1787
1788 my $half = int($#start_list / 2);
1789
1790 do {
1791 my @tophalf = @start_list[0 .. $half];
1792
1793 create_config @tophalf;
1794 read_current_config \%current_config;
1795
1796 $count = $#tophalf + 1;
1797 doprint "Testing $count configs\n";
1798 my $found = 0;
1799 # make sure we test something
1800 foreach my $config (@tophalf) {
1801 if (defined($current_config{$config})) {
1802 logit " $config\n";
1803 $found = 1;
1804 }
1805 }
1806 if (!$found) {
1807 # try the other half
1808 doprint "Top half produced no set configs, trying bottom half\n";
Steven Rostedt4c8cc552011-06-01 23:22:30 -04001809 @tophalf = @start_list[$half + 1 .. $#start_list];
Steven Rostedt0a05c762010-11-08 11:14:10 -05001810 create_config @tophalf;
1811 read_current_config \%current_config;
1812 foreach my $config (@tophalf) {
1813 if (defined($current_config{$config})) {
1814 logit " $config\n";
1815 $found = 1;
1816 }
1817 }
1818 if (!$found) {
1819 doprint "Failed: Can't make new config with current configs\n";
1820 foreach my $config (@start_list) {
1821 doprint " CONFIG: $config\n";
1822 }
1823 return -1;
1824 }
1825 $count = $#tophalf + 1;
1826 doprint "Testing $count configs\n";
1827 }
1828
1829 $ret = run_config_bisect_test $type;
Steven Rostedtc960bb92011-03-08 09:22:39 -05001830 if ($bisect_manual) {
1831 $ret = answer_bisect;
1832 }
Steven Rostedt0a05c762010-11-08 11:14:10 -05001833 if ($ret) {
1834 process_passed %current_config;
1835 return 0;
1836 }
1837
1838 doprint "This config had a failure.\n";
1839 doprint "Removing these configs that were not set in this config:\n";
Steven Rostedtf1a27852010-11-11 11:34:38 -05001840 doprint "config copied to $outputdir/config_bad\n";
1841 run_command "cp -f $output_config $outputdir/config_bad";
Steven Rostedt0a05c762010-11-08 11:14:10 -05001842
1843 # A config exists in this group that was bad.
1844 foreach my $config (keys %config_list) {
1845 if (!defined($current_config{$config})) {
1846 doprint " removing $config\n";
1847 delete $config_list{$config};
1848 }
1849 }
1850
1851 @start_list = @tophalf;
1852
1853 if ($#start_list == 0) {
1854 process_failed $start_list[0];
1855 return 1;
1856 }
1857
1858 # remove half the configs we are looking at and see if
1859 # they are good.
1860 $half = int($#start_list / 2);
Steven Rostedt4c8cc552011-06-01 23:22:30 -04001861 } while ($#start_list > 0);
Steven Rostedt0a05c762010-11-08 11:14:10 -05001862
Steven Rostedtc960bb92011-03-08 09:22:39 -05001863 # we found a single config, try it again unless we are running manually
1864
1865 if ($bisect_manual) {
1866 process_failed $start_list[0];
1867 return 1;
1868 }
1869
Steven Rostedt0a05c762010-11-08 11:14:10 -05001870 my @tophalf = @start_list[0 .. 0];
1871
1872 $ret = run_config_bisect_test $type;
1873 if ($ret) {
1874 process_passed %current_config;
1875 return 0;
1876 }
1877
1878 process_failed $start_list[0];
1879 return 1;
1880}
1881
1882sub config_bisect {
1883 my ($i) = @_;
1884
1885 my $start_config = $opt{"CONFIG_BISECT[$i]"};
1886
1887 my $tmpconfig = "$tmpdir/use_config";
1888
Steven Rostedt30f75da2011-06-13 10:35:35 -04001889 if (defined($config_bisect_good)) {
1890 process_config_ignore $config_bisect_good;
1891 }
1892
Steven Rostedt0a05c762010-11-08 11:14:10 -05001893 # Make the file with the bad config and the min config
1894 if (defined($minconfig)) {
1895 # read the min config for things to ignore
1896 run_command "cp $minconfig $tmpconfig" or
1897 dodie "failed to copy $minconfig to $tmpconfig";
1898 } else {
1899 unlink $tmpconfig;
1900 }
1901
1902 # Add other configs
1903 if (defined($addconfig)) {
1904 run_command "cat $addconfig >> $tmpconfig" or
1905 dodie "failed to append $addconfig";
1906 }
1907
Steven Rostedt0a05c762010-11-08 11:14:10 -05001908 if (-f $tmpconfig) {
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001909 load_force_config($tmpconfig);
Steven Rostedt0a05c762010-11-08 11:14:10 -05001910 process_config_ignore $tmpconfig;
1911 }
1912
1913 # now process the start config
1914 run_command "cp $start_config $output_config" or
1915 dodie "failed to copy $start_config to $output_config";
1916
1917 # read directly what we want to check
1918 my %config_check;
1919 open (IN, $output_config)
1920 or dodie "faied to open $output_config";
1921
1922 while (<IN>) {
1923 if (/^((CONFIG\S*)=.*)/) {
1924 $config_check{$2} = $1;
1925 }
1926 }
1927 close(IN);
1928
1929 # Now run oldconfig with the minconfig (and addconfigs)
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001930 make_oldconfig;
Steven Rostedt0a05c762010-11-08 11:14:10 -05001931
1932 # check to see what we lost (or gained)
1933 open (IN, $output_config)
1934 or dodie "Failed to read $start_config";
1935
1936 my %removed_configs;
1937 my %added_configs;
1938
1939 while (<IN>) {
1940 if (/^((CONFIG\S*)=.*)/) {
1941 # save off all options
1942 $config_set{$2} = $1;
1943 if (defined($config_check{$2})) {
1944 if (defined($config_ignore{$2})) {
1945 $removed_configs{$2} = $1;
1946 } else {
1947 $config_list{$2} = $1;
1948 }
1949 } elsif (!defined($config_ignore{$2})) {
1950 $added_configs{$2} = $1;
1951 $config_list{$2} = $1;
1952 }
1953 }
1954 }
1955 close(IN);
1956
1957 my @confs = keys %removed_configs;
1958 if ($#confs >= 0) {
1959 doprint "Configs overridden by default configs and removed from check:\n";
1960 foreach my $config (@confs) {
1961 doprint " $config\n";
1962 }
1963 }
1964 @confs = keys %added_configs;
1965 if ($#confs >= 0) {
1966 doprint "Configs appearing in make oldconfig and added:\n";
1967 foreach my $config (@confs) {
1968 doprint " $config\n";
1969 }
1970 }
1971
1972 my %config_test;
1973 my $once = 0;
1974
1975 # Sometimes kconfig does weird things. We must make sure
1976 # that the config we autocreate has everything we need
1977 # to test, otherwise we may miss testing configs, or
1978 # may not be able to create a new config.
1979 # Here we create a config with everything set.
1980 create_config (keys %config_list);
1981 read_current_config \%config_test;
1982 foreach my $config (keys %config_list) {
1983 if (!defined($config_test{$config})) {
1984 if (!$once) {
1985 $once = 1;
1986 doprint "Configs not produced by kconfig (will not be checked):\n";
1987 }
1988 doprint " $config\n";
1989 delete $config_list{$config};
1990 }
1991 }
1992 my $ret;
1993 do {
1994 $ret = run_config_bisect;
1995 } while (!$ret);
1996
1997 return $ret if ($ret < 0);
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001998
1999 success $i;
2000}
2001
Steven Rostedt27d934b2011-05-20 09:18:18 -04002002sub patchcheck_reboot {
2003 doprint "Reboot and sleep $patchcheck_sleep_time seconds\n";
2004 reboot;
2005 start_monitor;
2006 wait_for_monitor $patchcheck_sleep_time;
2007 end_monitor;
2008}
2009
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002010sub patchcheck {
2011 my ($i) = @_;
2012
2013 die "PATCHCHECK_START[$i] not defined\n"
2014 if (!defined($opt{"PATCHCHECK_START[$i]"}));
2015 die "PATCHCHECK_TYPE[$i] not defined\n"
2016 if (!defined($opt{"PATCHCHECK_TYPE[$i]"}));
2017
2018 my $start = $opt{"PATCHCHECK_START[$i]"};
2019
2020 my $end = "HEAD";
2021 if (defined($opt{"PATCHCHECK_END[$i]"})) {
2022 $end = $opt{"PATCHCHECK_END[$i]"};
2023 }
2024
Steven Rostedta57419b2010-11-02 15:13:54 -04002025 # Get the true sha1's since we can use things like HEAD~3
2026 $start = get_sha1($start);
2027 $end = get_sha1($end);
2028
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002029 my $type = $opt{"PATCHCHECK_TYPE[$i]"};
2030
2031 # Can't have a test without having a test to run
2032 if ($type eq "test" && !defined($run_test)) {
2033 $type = "boot";
2034 }
2035
2036 open (IN, "git log --pretty=oneline $end|") or
2037 dodie "could not get git list";
2038
2039 my @list;
2040
2041 while (<IN>) {
2042 chomp;
2043 $list[$#list+1] = $_;
2044 last if (/^$start/);
2045 }
2046 close(IN);
2047
2048 if ($list[$#list] !~ /^$start/) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002049 fail "SHA1 $start not found";
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002050 }
2051
2052 # go backwards in the list
2053 @list = reverse @list;
2054
2055 my $save_clean = $noclean;
2056
2057 $in_patchcheck = 1;
2058 foreach my $item (@list) {
2059 my $sha1 = $item;
2060 $sha1 =~ s/^([[:xdigit:]]+).*/$1/;
2061
2062 doprint "\nProcessing commit $item\n\n";
2063
2064 run_command "git checkout $sha1" or
2065 die "Failed to checkout $sha1";
2066
2067 # only clean on the first and last patch
2068 if ($item eq $list[0] ||
2069 $item eq $list[$#list]) {
2070 $noclean = $save_clean;
2071 } else {
2072 $noclean = 1;
2073 }
2074
2075 if (defined($minconfig)) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002076 build "useconfig:$minconfig" or return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002077 } else {
2078 # ?? no config to use?
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002079 build "oldconfig" or return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002080 }
2081
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002082 check_buildlog $sha1 or return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002083
2084 next if ($type eq "build");
2085
2086 get_grub_index;
2087 get_version;
2088 install;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002089
Steven Rostedt7faafbd2010-11-02 14:58:22 -04002090 my $failed = 0;
2091
2092 start_monitor;
2093 monitor or $failed = 1;
2094
2095 if (!$failed && $type ne "boot"){
2096 do_run_test or $failed = 1;
2097 }
2098 end_monitor;
2099 return 0 if ($failed);
2100
Steven Rostedt27d934b2011-05-20 09:18:18 -04002101 patchcheck_reboot;
2102
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002103 }
2104 $in_patchcheck = 0;
2105 success $i;
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002106
2107 return 1;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002108}
2109
Steven Rostedt8d1491b2010-11-18 15:39:48 -05002110$#ARGV < 1 or die "ktest.pl version: $VERSION\n usage: ktest.pl config-file\n";
Steven Rostedt2545eb62010-11-02 15:01:32 -04002111
Steven Rostedt8d1491b2010-11-18 15:39:48 -05002112if ($#ARGV == 0) {
2113 $ktest_config = $ARGV[0];
2114 if (! -f $ktest_config) {
2115 print "$ktest_config does not exist.\n";
2116 my $ans;
2117 for (;;) {
2118 print "Create it? [Y/n] ";
2119 $ans = <STDIN>;
2120 chomp $ans;
2121 if ($ans =~ /^\s*$/) {
2122 $ans = "y";
2123 }
2124 last if ($ans =~ /^y$/i || $ans =~ /^n$/i);
2125 print "Please answer either 'y' or 'n'.\n";
2126 }
2127 if ($ans !~ /^y$/i) {
2128 exit 0;
2129 }
2130 }
2131} else {
2132 $ktest_config = "ktest.conf";
2133}
2134
2135if (! -f $ktest_config) {
2136 open(OUT, ">$ktest_config") or die "Can not create $ktest_config";
2137 print OUT << "EOF"
2138# Generated by ktest.pl
2139#
2140# Define each test with TEST_START
2141# The config options below it will override the defaults
2142TEST_START
2143
2144DEFAULTS
2145EOF
2146;
2147 close(OUT);
2148}
2149read_config $ktest_config;
2150
Steven Rostedt23715c3c2011-06-13 11:03:34 -04002151if (defined($opt{"LOG_FILE"})) {
2152 $opt{"LOG_FILE"} = eval_option($opt{"LOG_FILE"}, -1);
2153}
2154
Steven Rostedt8d1491b2010-11-18 15:39:48 -05002155# Append any configs entered in manually to the config file.
2156my @new_configs = keys %entered_configs;
2157if ($#new_configs >= 0) {
2158 print "\nAppending entered in configs to $ktest_config\n";
2159 open(OUT, ">>$ktest_config") or die "Can not append to $ktest_config";
2160 foreach my $config (@new_configs) {
2161 print OUT "$config = $entered_configs{$config}\n";
2162 $opt{$config} = $entered_configs{$config};
2163 }
2164}
Steven Rostedt2545eb62010-11-02 15:01:32 -04002165
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002166if ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) {
2167 unlink $opt{"LOG_FILE"};
2168}
Steven Rostedt2545eb62010-11-02 15:01:32 -04002169
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002170doprint "\n\nSTARTING AUTOMATED TESTS\n\n";
2171
Steven Rostedta57419b2010-11-02 15:13:54 -04002172for (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) {
2173
2174 if (!$i) {
2175 doprint "DEFAULT OPTIONS:\n";
2176 } else {
2177 doprint "\nTEST $i OPTIONS";
2178 if (defined($repeat_tests{$i})) {
2179 $repeat = $repeat_tests{$i};
2180 doprint " ITERATE $repeat";
2181 }
2182 doprint "\n";
2183 }
2184
2185 foreach my $option (sort keys %opt) {
2186
2187 if ($option =~ /\[(\d+)\]$/) {
2188 next if ($i != $1);
2189 } else {
2190 next if ($i);
2191 }
2192
2193 doprint "$option = $opt{$option}\n";
2194 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002195}
Steven Rostedt2545eb62010-11-02 15:01:32 -04002196
Steven Rostedt2a625122011-05-20 15:48:59 -04002197sub __set_test_option {
Steven Rostedt5a391fb2010-11-02 14:57:43 -04002198 my ($name, $i) = @_;
2199
2200 my $option = "$name\[$i\]";
2201
2202 if (defined($opt{$option})) {
2203 return $opt{$option};
2204 }
2205
Steven Rostedta57419b2010-11-02 15:13:54 -04002206 foreach my $test (keys %repeat_tests) {
2207 if ($i >= $test &&
2208 $i < $test + $repeat_tests{$test}) {
2209 $option = "$name\[$test\]";
2210 if (defined($opt{$option})) {
2211 return $opt{$option};
2212 }
2213 }
2214 }
2215
Steven Rostedt5a391fb2010-11-02 14:57:43 -04002216 if (defined($opt{$name})) {
2217 return $opt{$name};
2218 }
2219
2220 return undef;
2221}
2222
Steven Rostedt2a625122011-05-20 15:48:59 -04002223sub set_test_option {
2224 my ($name, $i) = @_;
2225
2226 my $option = __set_test_option($name, $i);
2227 return $option if (!defined($option));
2228
Steven Rostedt23715c3c2011-06-13 11:03:34 -04002229 return eval_option($option, $i);
Steven Rostedt2a625122011-05-20 15:48:59 -04002230}
2231
Steven Rostedt2545eb62010-11-02 15:01:32 -04002232# First we need to do is the builds
Steven Rostedta75fece2010-11-02 14:58:27 -04002233for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
Steven Rostedt2545eb62010-11-02 15:01:32 -04002234
Steven Rostedt576f6272010-11-02 14:58:38 -04002235 $iteration = $i;
2236
Steven Rostedta75fece2010-11-02 14:58:27 -04002237 my $makecmd = set_test_option("MAKE_CMD", $i);
2238
2239 $machine = set_test_option("MACHINE", $i);
Steven Rostedte48c5292010-11-02 14:35:37 -04002240 $ssh_user = set_test_option("SSH_USER", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002241 $tmpdir = set_test_option("TMP_DIR", $i);
2242 $outputdir = set_test_option("OUTPUT_DIR", $i);
2243 $builddir = set_test_option("BUILD_DIR", $i);
2244 $test_type = set_test_option("TEST_TYPE", $i);
2245 $build_type = set_test_option("BUILD_TYPE", $i);
2246 $build_options = set_test_option("BUILD_OPTIONS", $i);
2247 $power_cycle = set_test_option("POWER_CYCLE", $i);
Steven Rostedte48c5292010-11-02 14:35:37 -04002248 $reboot = set_test_option("REBOOT", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002249 $noclean = set_test_option("BUILD_NOCLEAN", $i);
2250 $minconfig = set_test_option("MIN_CONFIG", $i);
2251 $run_test = set_test_option("TEST", $i);
2252 $addconfig = set_test_option("ADD_CONFIG", $i);
2253 $reboot_type = set_test_option("REBOOT_TYPE", $i);
2254 $grub_menu = set_test_option("GRUB_MENU", $i);
Steven Rostedt8b37ca82010-11-02 14:58:33 -04002255 $post_install = set_test_option("POST_INSTALL", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002256 $reboot_script = set_test_option("REBOOT_SCRIPT", $i);
2257 $reboot_on_error = set_test_option("REBOOT_ON_ERROR", $i);
2258 $poweroff_on_error = set_test_option("POWEROFF_ON_ERROR", $i);
2259 $die_on_failure = set_test_option("DIE_ON_FAILURE", $i);
2260 $power_off = set_test_option("POWER_OFF", $i);
Steven Rostedt576f6272010-11-02 14:58:38 -04002261 $powercycle_after_reboot = set_test_option("POWERCYCLE_AFTER_REBOOT", $i);
2262 $poweroff_after_halt = set_test_option("POWEROFF_AFTER_HALT", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002263 $sleep_time = set_test_option("SLEEP_TIME", $i);
2264 $bisect_sleep_time = set_test_option("BISECT_SLEEP_TIME", $i);
Steven Rostedt27d934b2011-05-20 09:18:18 -04002265 $patchcheck_sleep_time = set_test_option("PATCHCHECK_SLEEP_TIME", $i);
Steven Rostedtc960bb92011-03-08 09:22:39 -05002266 $bisect_manual = set_test_option("BISECT_MANUAL", $i);
Steven Rostedtc23dca72011-03-08 09:26:31 -05002267 $bisect_skip = set_test_option("BISECT_SKIP", $i);
Steven Rostedt30f75da2011-06-13 10:35:35 -04002268 $config_bisect_good = set_test_option("CONFIG_BISECT_GOOD", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002269 $store_failures = set_test_option("STORE_FAILURES", $i);
Steven Rostedt9064af52011-06-13 10:38:48 -04002270 $test_name = set_test_option("TEST_NAME", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002271 $timeout = set_test_option("TIMEOUT", $i);
2272 $booted_timeout = set_test_option("BOOTED_TIMEOUT", $i);
2273 $console = set_test_option("CONSOLE", $i);
Steven Rostedtf1a5b962011-06-13 10:30:00 -04002274 $detect_triplefault = set_test_option("DETECT_TRIPLE_FAULT", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002275 $success_line = set_test_option("SUCCESS_LINE", $i);
Steven Rostedt1c8a6172010-11-09 12:55:40 -05002276 $stop_after_success = set_test_option("STOP_AFTER_SUCCESS", $i);
2277 $stop_after_failure = set_test_option("STOP_AFTER_FAILURE", $i);
Steven Rostedt2d01b262011-03-08 09:47:54 -05002278 $stop_test_after = set_test_option("STOP_TEST_AFTER", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002279 $build_target = set_test_option("BUILD_TARGET", $i);
Steven Rostedte48c5292010-11-02 14:35:37 -04002280 $ssh_exec = set_test_option("SSH_EXEC", $i);
2281 $scp_to_target = set_test_option("SCP_TO_TARGET", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002282 $target_image = set_test_option("TARGET_IMAGE", $i);
2283 $localversion = set_test_option("LOCALVERSION", $i);
2284
2285 chdir $builddir || die "can't change directory to $builddir";
2286
2287 if (!-d $tmpdir) {
2288 mkpath($tmpdir) or
2289 die "can't create $tmpdir";
2290 }
2291
Steven Rostedte48c5292010-11-02 14:35:37 -04002292 $ENV{"SSH_USER"} = $ssh_user;
2293 $ENV{"MACHINE"} = $machine;
2294
Steven Rostedta75fece2010-11-02 14:58:27 -04002295 $target = "$ssh_user\@$machine";
2296
2297 $buildlog = "$tmpdir/buildlog-$machine";
2298 $dmesg = "$tmpdir/dmesg-$machine";
2299 $make = "$makecmd O=$outputdir";
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05002300 $output_config = "$outputdir/.config";
Steven Rostedta75fece2010-11-02 14:58:27 -04002301
2302 if ($reboot_type eq "grub") {
Steven Rostedt576f6272010-11-02 14:58:38 -04002303 dodie "GRUB_MENU not defined" if (!defined($grub_menu));
Steven Rostedta75fece2010-11-02 14:58:27 -04002304 } elsif (!defined($reboot_script)) {
Steven Rostedt576f6272010-11-02 14:58:38 -04002305 dodie "REBOOT_SCRIPT not defined"
Steven Rostedta75fece2010-11-02 14:58:27 -04002306 }
2307
2308 my $run_type = $build_type;
2309 if ($test_type eq "patchcheck") {
2310 $run_type = $opt{"PATCHCHECK_TYPE[$i]"};
2311 } elsif ($test_type eq "bisect") {
2312 $run_type = $opt{"BISECT_TYPE[$i]"};
Steven Rostedt0a05c762010-11-08 11:14:10 -05002313 } elsif ($test_type eq "config_bisect") {
2314 $run_type = $opt{"CONFIG_BISECT_TYPE[$i]"};
Steven Rostedta75fece2010-11-02 14:58:27 -04002315 }
2316
2317 # mistake in config file?
2318 if (!defined($run_type)) {
2319 $run_type = "ERROR";
2320 }
Steven Rostedt2545eb62010-11-02 15:01:32 -04002321
2322 doprint "\n\n";
Steven Rostedta75fece2010-11-02 14:58:27 -04002323 doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type\n\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -04002324
2325 unlink $dmesg;
2326 unlink $buildlog;
Steven Rostedt2545eb62010-11-02 15:01:32 -04002327
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002328 if (!defined($minconfig)) {
2329 $minconfig = $addconfig;
2330
2331 } elsif (defined($addconfig)) {
Steven Rostedt9be2e6b2010-11-09 12:20:21 -05002332 run_command "cat $addconfig $minconfig > $tmpdir/add_config" or
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002333 dodie "Failed to create temp config";
Steven Rostedt9be2e6b2010-11-09 12:20:21 -05002334 $minconfig = "$tmpdir/add_config";
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002335 }
2336
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002337 my $checkout = $opt{"CHECKOUT[$i]"};
2338 if (defined($checkout)) {
2339 run_command "git checkout $checkout" or
2340 die "failed to checkout $checkout";
2341 }
2342
Steven Rostedta75fece2010-11-02 14:58:27 -04002343 if ($test_type eq "bisect") {
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04002344 bisect $i;
2345 next;
Steven Rostedt0a05c762010-11-08 11:14:10 -05002346 } elsif ($test_type eq "config_bisect") {
2347 config_bisect $i;
2348 next;
Steven Rostedta75fece2010-11-02 14:58:27 -04002349 } elsif ($test_type eq "patchcheck") {
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002350 patchcheck $i;
2351 next;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04002352 }
2353
Steven Rostedt7faafbd2010-11-02 14:58:22 -04002354 if ($build_type ne "nobuild") {
2355 build $build_type or next;
Steven Rostedt2545eb62010-11-02 15:01:32 -04002356 }
2357
Steven Rostedta75fece2010-11-02 14:58:27 -04002358 if ($test_type ne "build") {
2359 get_grub_index;
2360 get_version;
2361 install;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04002362
Steven Rostedta75fece2010-11-02 14:58:27 -04002363 my $failed = 0;
2364 start_monitor;
2365 monitor or $failed = 1;;
2366
2367 if (!$failed && $test_type ne "boot" && defined($run_test)) {
2368 do_run_test or $failed = 1;
2369 }
2370 end_monitor;
2371 next if ($failed);
Steven Rostedt5a391fb2010-11-02 14:57:43 -04002372 }
2373
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04002374 success $i;
Steven Rostedt2545eb62010-11-02 15:01:32 -04002375}
2376
Steven Rostedt5c42fc52010-11-02 14:57:01 -04002377if ($opt{"POWEROFF_ON_SUCCESS"}) {
Steven Rostedt75c3fda72010-11-02 14:57:21 -04002378 halt;
Steven Rostedt576f6272010-11-02 14:58:38 -04002379} elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot) {
Steven Rostedt75c3fda72010-11-02 14:57:21 -04002380 reboot;
Steven Rostedt5c42fc52010-11-02 14:57:01 -04002381}
Steven Rostedt75c3fda72010-11-02 14:57:21 -04002382
Steven Rostedte48c5292010-11-02 14:35:37 -04002383doprint "\n $successes of $opt{NUM_TESTS} tests were successful\n\n";
2384
Steven Rostedt2545eb62010-11-02 15:01:32 -04002385exit 0;