blob: 83dcfaf0cac4b0a9a5ec2a29fe581c0662d6e840 [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
1034sub install {
1035
Steven Rostedte48c5292010-11-02 14:35:37 -04001036 run_scp "$outputdir/$build_target", "$target_image" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001037 dodie "failed to copy image";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001038
1039 my $install_mods = 0;
1040
1041 # should we process modules?
1042 $install_mods = 0;
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05001043 open(IN, "$output_config") or dodie("Can't read config file");
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001044 while (<IN>) {
1045 if (/CONFIG_MODULES(=y)?/) {
1046 $install_mods = 1 if (defined($1));
1047 last;
1048 }
1049 }
1050 close(IN);
1051
1052 if (!$install_mods) {
1053 doprint "No modules needed\n";
1054 return;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001055 }
1056
Steven Rostedta75fece2010-11-02 14:58:27 -04001057 run_command "$make INSTALL_MOD_PATH=$tmpdir modules_install" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001058 dodie "Failed to install modules";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001059
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001060 my $modlib = "/lib/modules/$version";
Steven Rostedta57419b2010-11-02 15:13:54 -04001061 my $modtar = "ktest-mods.tar.bz2";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001062
Steven Rostedte48c5292010-11-02 14:35:37 -04001063 run_ssh "rm -rf $modlib" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001064 dodie "failed to remove old mods: $modlib";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001065
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001066 # would be nice if scp -r did not follow symbolic links
Steven Rostedta75fece2010-11-02 14:58:27 -04001067 run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001068 dodie "making tarball";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001069
Steven Rostedte48c5292010-11-02 14:35:37 -04001070 run_scp "$tmpdir/$modtar", "/tmp" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001071 dodie "failed to copy modules";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001072
Steven Rostedta75fece2010-11-02 14:58:27 -04001073 unlink "$tmpdir/$modtar";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001074
Steven Rostedte48c5292010-11-02 14:35:37 -04001075 run_ssh "'(cd / && tar xf /tmp/$modtar)'" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001076 dodie "failed to tar modules";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001077
Steven Rostedte48c5292010-11-02 14:35:37 -04001078 run_ssh "rm -f /tmp/$modtar";
Steven Rostedt8b37ca82010-11-02 14:58:33 -04001079
1080 return if (!defined($post_install));
1081
Steven Rostedte48c5292010-11-02 14:35:37 -04001082 my $cp_post_install = $post_install;
Steven Rostedtca6a21f2011-03-25 22:42:53 -04001083 $cp_post_install =~ s/\$KERNEL_VERSION/$version/g;
Steven Rostedte48c5292010-11-02 14:35:37 -04001084 run_command "$cp_post_install" or
Steven Rostedt576f6272010-11-02 14:58:38 -04001085 dodie "Failed to run post install";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001086}
1087
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001088sub check_buildlog {
1089 my ($patch) = @_;
1090
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001091 my @files = `git show $patch | diffstat -l`;
1092
1093 open(IN, "git show $patch |") or
1094 dodie "failed to show $patch";
1095 while (<IN>) {
1096 if (m,^--- a/(.*),) {
1097 chomp $1;
1098 $files[$#files] = $1;
1099 }
1100 }
1101 close(IN);
1102
1103 open(IN, $buildlog) or dodie "Can't open $buildlog";
1104 while (<IN>) {
1105 if (/^\s*(.*?):.*(warning|error)/) {
1106 my $err = $1;
1107 foreach my $file (@files) {
Steven Rostedta75fece2010-11-02 14:58:27 -04001108 my $fullpath = "$builddir/$file";
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001109 if ($file eq $err || $fullpath eq $err) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001110 fail "$file built with warnings" and return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001111 }
1112 }
1113 }
1114 }
1115 close(IN);
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001116
1117 return 1;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001118}
1119
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001120sub apply_min_config {
1121 my $outconfig = "$output_config.new";
Steven Rostedt612b9e92011-03-07 13:27:43 -05001122
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001123 # Read the config file and remove anything that
1124 # is in the force_config hash (from minconfig and others)
1125 # then add the force config back.
1126
1127 doprint "Applying minimum configurations into $output_config.new\n";
1128
1129 open (OUT, ">$outconfig") or
1130 dodie "Can't create $outconfig";
1131
1132 if (-f $output_config) {
1133 open (IN, $output_config) or
1134 dodie "Failed to open $output_config";
1135 while (<IN>) {
1136 if (/^(# )?(CONFIG_[^\s=]*)/) {
1137 next if (defined($force_config{$2}));
1138 }
1139 print OUT;
1140 }
1141 close IN;
1142 }
1143 foreach my $config (keys %force_config) {
1144 print OUT "$force_config{$config}\n";
1145 }
1146 close OUT;
1147
1148 run_command "mv $outconfig $output_config";
1149}
1150
1151sub make_oldconfig {
1152
1153 apply_min_config;
1154
1155 if (!run_command "$make oldnoconfig") {
Steven Rostedt612b9e92011-03-07 13:27:43 -05001156 # Perhaps oldnoconfig doesn't exist in this version of the kernel
1157 # try a yes '' | oldconfig
1158 doprint "oldnoconfig failed, trying yes '' | make oldconfig\n";
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001159 run_command "yes '' | $make oldconfig" or
Steven Rostedt612b9e92011-03-07 13:27:43 -05001160 dodie "failed make config oldconfig";
1161 }
1162}
1163
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001164# read a config file and use this to force new configs.
1165sub load_force_config {
1166 my ($config) = @_;
1167
1168 open(IN, $config) or
1169 dodie "failed to read $config";
1170 while (<IN>) {
1171 chomp;
1172 if (/^(CONFIG[^\s=]*)(\s*=.*)/) {
1173 $force_config{$1} = $_;
1174 } elsif (/^# (CONFIG_\S*) is not set/) {
1175 $force_config{$1} = $_;
1176 }
1177 }
1178 close IN;
1179}
1180
Steven Rostedt2545eb62010-11-02 15:01:32 -04001181sub build {
1182 my ($type) = @_;
1183
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001184 unlink $buildlog;
1185
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001186 if ($type =~ /^useconfig:(.*)/) {
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05001187 run_command "cp $1 $output_config" or
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001188 dodie "could not copy $1 to .config";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001189
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001190 $type = "oldconfig";
1191 }
1192
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001193 # old config can ask questions
1194 if ($type eq "oldconfig") {
Steven Rostedt9386c6a2010-11-08 16:35:48 -05001195 $type = "oldnoconfig";
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001196
1197 # allow for empty configs
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05001198 run_command "touch $output_config";
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001199
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05001200 run_command "mv $output_config $outputdir/config_temp" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001201 dodie "moving .config";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001202
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001203 if (!$noclean && !run_command "$make mrproper") {
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001204 dodie "make mrproper";
1205 }
1206
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05001207 run_command "mv $outputdir/config_temp $output_config" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001208 dodie "moving config_temp";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001209
1210 } elsif (!$noclean) {
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05001211 unlink "$output_config";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001212 run_command "$make mrproper" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001213 dodie "make mrproper";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001214 }
Steven Rostedt2545eb62010-11-02 15:01:32 -04001215
1216 # add something to distinguish this build
Steven Rostedta75fece2010-11-02 14:58:27 -04001217 open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file");
1218 print OUT "$localversion\n";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001219 close(OUT);
1220
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001221 if (defined($minconfig)) {
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001222 load_force_config($minconfig);
Steven Rostedt2545eb62010-11-02 15:01:32 -04001223 }
1224
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001225 if ($type ne "oldnoconfig") {
1226 run_command "$make $type" or
Steven Rostedt612b9e92011-03-07 13:27:43 -05001227 dodie "failed make config";
1228 }
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001229 # Run old config regardless, to enforce min configurations
1230 make_oldconfig;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001231
Steven Rostedta75fece2010-11-02 14:58:27 -04001232 $redirect = "$buildlog";
1233 if (!run_command "$make $build_options") {
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001234 undef $redirect;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001235 # bisect may need this to pass
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001236 return 0 if ($in_bisect);
1237 fail "failed build" and return 0;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001238 }
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001239 undef $redirect;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001240
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001241 return 1;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001242}
1243
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001244sub halt {
Steven Rostedte48c5292010-11-02 14:35:37 -04001245 if (!run_ssh "halt" or defined($power_off)) {
Steven Rostedt576f6272010-11-02 14:58:38 -04001246 if (defined($poweroff_after_halt)) {
1247 sleep $poweroff_after_halt;
1248 run_command "$power_off";
1249 }
1250 } else {
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001251 # nope? the zap it!
Steven Rostedta75fece2010-11-02 14:58:27 -04001252 run_command "$power_off";
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001253 }
1254}
1255
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001256sub success {
1257 my ($i) = @_;
1258
Steven Rostedte48c5292010-11-02 14:35:37 -04001259 $successes++;
1260
Steven Rostedt9064af52011-06-13 10:38:48 -04001261 my $name = "";
1262
1263 if (defined($test_name)) {
1264 $name = " ($test_name)";
1265 }
1266
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001267 doprint "\n\n*******************************************\n";
1268 doprint "*******************************************\n";
Steven Rostedt9064af52011-06-13 10:38:48 -04001269 doprint "KTEST RESULT: TEST $i$name SUCCESS!!!! **\n";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001270 doprint "*******************************************\n";
1271 doprint "*******************************************\n";
1272
Steven Rostedt576f6272010-11-02 14:58:38 -04001273 if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) {
Steven Rostedta75fece2010-11-02 14:58:27 -04001274 doprint "Reboot and wait $sleep_time seconds\n";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001275 reboot;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001276 start_monitor;
Steven Rostedta75fece2010-11-02 14:58:27 -04001277 wait_for_monitor $sleep_time;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001278 end_monitor;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001279 }
1280}
1281
1282sub get_version {
1283 # get the release name
1284 doprint "$make kernelrelease ... ";
1285 $version = `$make kernelrelease | tail -1`;
1286 chomp($version);
1287 doprint "$version\n";
1288}
1289
Steven Rostedtc960bb92011-03-08 09:22:39 -05001290sub answer_bisect {
1291 for (;;) {
1292 doprint "Pass or fail? [p/f]";
1293 my $ans = <STDIN>;
1294 chomp $ans;
1295 if ($ans eq "p" || $ans eq "P") {
1296 return 1;
1297 } elsif ($ans eq "f" || $ans eq "F") {
1298 return 0;
1299 } else {
1300 print "Please answer 'P' or 'F'\n";
1301 }
1302 }
1303}
1304
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001305sub child_run_test {
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001306 my $failed = 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001307
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001308 # child should have no power
Steven Rostedta75fece2010-11-02 14:58:27 -04001309 $reboot_on_error = 0;
1310 $poweroff_on_error = 0;
1311 $die_on_failure = 1;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001312
1313 run_command $run_test or $failed = 1;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001314 exit $failed;
1315}
1316
1317my $child_done;
1318
1319sub child_finished {
1320 $child_done = 1;
1321}
1322
1323sub do_run_test {
1324 my $child_pid;
1325 my $child_exit;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001326 my $line;
1327 my $full_line;
1328 my $bug = 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001329
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001330 wait_for_monitor 1;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001331
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001332 doprint "run test $run_test\n";
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001333
1334 $child_done = 0;
1335
1336 $SIG{CHLD} = qw(child_finished);
1337
1338 $child_pid = fork;
1339
1340 child_run_test if (!$child_pid);
1341
1342 $full_line = "";
1343
1344 do {
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001345 $line = wait_for_input($monitor_fp, 1);
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001346 if (defined($line)) {
1347
1348 # we are not guaranteed to get a full line
1349 $full_line .= $line;
Steven Rostedt8ea0e062011-03-08 09:44:35 -05001350 doprint $line;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001351
1352 if ($full_line =~ /call trace:/i) {
1353 $bug = 1;
1354 }
1355
1356 if ($full_line =~ /Kernel panic -/) {
1357 $bug = 1;
1358 }
1359
1360 if ($line =~ /\n/) {
1361 $full_line = "";
1362 }
1363 }
1364 } while (!$child_done && !$bug);
1365
1366 if ($bug) {
Steven Rostedt8ea0e062011-03-08 09:44:35 -05001367 my $failure_start = time;
1368 my $now;
1369 do {
1370 $line = wait_for_input($monitor_fp, 1);
1371 if (defined($line)) {
1372 doprint $line;
1373 }
1374 $now = time;
1375 if ($now - $failure_start >= $stop_after_failure) {
1376 last;
1377 }
1378 } while (defined($line));
1379
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001380 doprint "Detected kernel crash!\n";
1381 # kill the child with extreme prejudice
1382 kill 9, $child_pid;
1383 }
1384
1385 waitpid $child_pid, 0;
1386 $child_exit = $?;
1387
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001388 if ($bug || $child_exit) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001389 return 0 if $in_bisect;
1390 fail "test failed" and return 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001391 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001392 return 1;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001393}
1394
Steven Rostedta75fece2010-11-02 14:58:27 -04001395sub run_git_bisect {
1396 my ($command) = @_;
1397
1398 doprint "$command ... ";
1399
1400 my $output = `$command 2>&1`;
1401 my $ret = $?;
1402
1403 logit $output;
1404
1405 if ($ret) {
1406 doprint "FAILED\n";
1407 dodie "Failed to git bisect";
1408 }
1409
1410 doprint "SUCCESS\n";
1411 if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) {
1412 doprint "$1 [$2]\n";
1413 } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) {
1414 $bisect_bad = $1;
1415 doprint "Found bad commit... $1\n";
1416 return 0;
1417 } else {
1418 # we already logged it, just print it now.
1419 print $output;
1420 }
1421
1422 return 1;
1423}
1424
Steven Rostedtc23dca72011-03-08 09:26:31 -05001425sub bisect_reboot {
1426 doprint "Reboot and sleep $bisect_sleep_time seconds\n";
1427 reboot;
1428 start_monitor;
1429 wait_for_monitor $bisect_sleep_time;
1430 end_monitor;
1431}
1432
1433# returns 1 on success, 0 on failure, -1 on skip
Steven Rostedt0a05c762010-11-08 11:14:10 -05001434sub run_bisect_test {
1435 my ($type, $buildtype) = @_;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001436
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001437 my $failed = 0;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001438 my $result;
1439 my $output;
1440 my $ret;
1441
Steven Rostedt0a05c762010-11-08 11:14:10 -05001442 $in_bisect = 1;
1443
1444 build $buildtype or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001445
1446 if ($type ne "build") {
Steven Rostedtc23dca72011-03-08 09:26:31 -05001447 if ($failed && $bisect_skip) {
1448 $in_bisect = 0;
1449 return -1;
1450 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001451 dodie "Failed on build" if $failed;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001452
1453 # Now boot the box
1454 get_grub_index;
1455 get_version;
1456 install;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001457
1458 start_monitor;
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001459 monitor or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001460
1461 if ($type ne "boot") {
Steven Rostedtc23dca72011-03-08 09:26:31 -05001462 if ($failed && $bisect_skip) {
1463 end_monitor;
1464 bisect_reboot;
1465 $in_bisect = 0;
1466 return -1;
1467 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001468 dodie "Failed on boot" if $failed;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001469
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001470 do_run_test or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001471 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001472 end_monitor;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001473 }
1474
1475 if ($failed) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001476 $result = 0;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001477 } else {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001478 $result = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001479 }
Steven Rostedt4025bc62011-05-20 09:16:29 -04001480
1481 # reboot the box to a kernel we can ssh to
1482 if ($type ne "build") {
1483 bisect_reboot;
1484 }
Steven Rostedt0a05c762010-11-08 11:14:10 -05001485 $in_bisect = 0;
1486
1487 return $result;
1488}
1489
1490sub run_bisect {
1491 my ($type) = @_;
1492 my $buildtype = "oldconfig";
1493
1494 # We should have a minconfig to use?
1495 if (defined($minconfig)) {
1496 $buildtype = "useconfig:$minconfig";
1497 }
1498
1499 my $ret = run_bisect_test $type, $buildtype;
1500
Steven Rostedtc960bb92011-03-08 09:22:39 -05001501 if ($bisect_manual) {
1502 $ret = answer_bisect;
1503 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001504
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04001505 # Are we looking for where it worked, not failed?
1506 if ($reverse_bisect) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001507 $ret = !$ret;
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04001508 }
1509
Steven Rostedtc23dca72011-03-08 09:26:31 -05001510 if ($ret > 0) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001511 return "good";
Steven Rostedtc23dca72011-03-08 09:26:31 -05001512 } elsif ($ret == 0) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001513 return "bad";
Steven Rostedtc23dca72011-03-08 09:26:31 -05001514 } elsif ($bisect_skip) {
1515 doprint "HIT A BAD COMMIT ... SKIPPING\n";
1516 return "skip";
Steven Rostedt0a05c762010-11-08 11:14:10 -05001517 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001518}
1519
1520sub bisect {
1521 my ($i) = @_;
1522
1523 my $result;
1524
1525 die "BISECT_GOOD[$i] not defined\n" if (!defined($opt{"BISECT_GOOD[$i]"}));
1526 die "BISECT_BAD[$i] not defined\n" if (!defined($opt{"BISECT_BAD[$i]"}));
1527 die "BISECT_TYPE[$i] not defined\n" if (!defined($opt{"BISECT_TYPE[$i]"}));
1528
1529 my $good = $opt{"BISECT_GOOD[$i]"};
1530 my $bad = $opt{"BISECT_BAD[$i]"};
1531 my $type = $opt{"BISECT_TYPE[$i]"};
Steven Rostedta75fece2010-11-02 14:58:27 -04001532 my $start = $opt{"BISECT_START[$i]"};
1533 my $replay = $opt{"BISECT_REPLAY[$i]"};
Steven Rostedt3410f6f2011-03-08 09:38:12 -05001534 my $start_files = $opt{"BISECT_FILES[$i]"};
1535
1536 if (defined($start_files)) {
1537 $start_files = " -- " . $start_files;
1538 } else {
1539 $start_files = "";
1540 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001541
Steven Rostedta57419b2010-11-02 15:13:54 -04001542 # convert to true sha1's
1543 $good = get_sha1($good);
1544 $bad = get_sha1($bad);
1545
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04001546 if (defined($opt{"BISECT_REVERSE[$i]"}) &&
1547 $opt{"BISECT_REVERSE[$i]"} == 1) {
1548 doprint "Performing a reverse bisect (bad is good, good is bad!)\n";
1549 $reverse_bisect = 1;
1550 } else {
1551 $reverse_bisect = 0;
1552 }
1553
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001554 # Can't have a test without having a test to run
1555 if ($type eq "test" && !defined($run_test)) {
1556 $type = "boot";
1557 }
1558
Steven Rostedta75fece2010-11-02 14:58:27 -04001559 my $check = $opt{"BISECT_CHECK[$i]"};
1560 if (defined($check) && $check ne "0") {
1561
1562 # get current HEAD
Steven Rostedta57419b2010-11-02 15:13:54 -04001563 my $head = get_sha1("HEAD");
Steven Rostedta75fece2010-11-02 14:58:27 -04001564
1565 if ($check ne "good") {
1566 doprint "TESTING BISECT BAD [$bad]\n";
1567 run_command "git checkout $bad" or
1568 die "Failed to checkout $bad";
1569
1570 $result = run_bisect $type;
1571
1572 if ($result ne "bad") {
1573 fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0;
1574 }
1575 }
1576
1577 if ($check ne "bad") {
1578 doprint "TESTING BISECT GOOD [$good]\n";
1579 run_command "git checkout $good" or
1580 die "Failed to checkout $good";
1581
1582 $result = run_bisect $type;
1583
1584 if ($result ne "good") {
1585 fail "Tested BISECT_GOOD [$good] and it failed" and return 0;
1586 }
1587 }
1588
1589 # checkout where we started
1590 run_command "git checkout $head" or
1591 die "Failed to checkout $head";
1592 }
1593
Steven Rostedt3410f6f2011-03-08 09:38:12 -05001594 run_command "git bisect start$start_files" or
Steven Rostedta75fece2010-11-02 14:58:27 -04001595 dodie "could not start bisect";
1596
1597 run_command "git bisect good $good" or
1598 dodie "could not set bisect good to $good";
1599
1600 run_git_bisect "git bisect bad $bad" or
1601 dodie "could not set bisect bad to $bad";
1602
1603 if (defined($replay)) {
1604 run_command "git bisect replay $replay" or
1605 dodie "failed to run replay";
1606 }
1607
1608 if (defined($start)) {
1609 run_command "git checkout $start" or
1610 dodie "failed to checkout $start";
1611 }
1612
1613 my $test;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001614 do {
1615 $result = run_bisect $type;
Steven Rostedta75fece2010-11-02 14:58:27 -04001616 $test = run_git_bisect "git bisect $result";
1617 } while ($test);
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001618
1619 run_command "git bisect log" or
1620 dodie "could not capture git bisect log";
1621
1622 run_command "git bisect reset" or
1623 dodie "could not reset git bisect";
1624
1625 doprint "Bad commit was [$bisect_bad]\n";
1626
Steven Rostedt0a05c762010-11-08 11:14:10 -05001627 success $i;
1628}
1629
1630my %config_ignore;
1631my %config_set;
1632
1633my %config_list;
1634my %null_config;
1635
1636my %dependency;
1637
1638sub process_config_ignore {
1639 my ($config) = @_;
1640
1641 open (IN, $config)
1642 or dodie "Failed to read $config";
1643
1644 while (<IN>) {
Steven Rostedt9bf71742011-06-01 23:27:19 -04001645 if (/^((CONFIG\S*)=.*)/) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001646 $config_ignore{$2} = $1;
1647 }
1648 }
1649
1650 close(IN);
1651}
1652
1653sub read_current_config {
1654 my ($config_ref) = @_;
1655
1656 %{$config_ref} = ();
1657 undef %{$config_ref};
1658
1659 my @key = keys %{$config_ref};
1660 if ($#key >= 0) {
1661 print "did not delete!\n";
1662 exit;
1663 }
1664 open (IN, "$output_config");
1665
1666 while (<IN>) {
1667 if (/^(CONFIG\S+)=(.*)/) {
1668 ${$config_ref}{$1} = $2;
1669 }
1670 }
1671 close(IN);
1672}
1673
1674sub get_dependencies {
1675 my ($config) = @_;
1676
1677 my $arr = $dependency{$config};
1678 if (!defined($arr)) {
1679 return ();
1680 }
1681
1682 my @deps = @{$arr};
1683
1684 foreach my $dep (@{$arr}) {
1685 print "ADD DEP $dep\n";
1686 @deps = (@deps, get_dependencies $dep);
1687 }
1688
1689 return @deps;
1690}
1691
1692sub create_config {
1693 my @configs = @_;
1694
1695 open(OUT, ">$output_config") or dodie "Can not write to $output_config";
1696
1697 foreach my $config (@configs) {
1698 print OUT "$config_set{$config}\n";
1699 my @deps = get_dependencies $config;
1700 foreach my $dep (@deps) {
1701 print OUT "$config_set{$dep}\n";
1702 }
1703 }
1704
1705 foreach my $config (keys %config_ignore) {
1706 print OUT "$config_ignore{$config}\n";
1707 }
1708 close(OUT);
1709
1710# exit;
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001711 make_oldconfig;
Steven Rostedt0a05c762010-11-08 11:14:10 -05001712}
1713
1714sub compare_configs {
1715 my (%a, %b) = @_;
1716
1717 foreach my $item (keys %a) {
1718 if (!defined($b{$item})) {
1719 print "diff $item\n";
1720 return 1;
1721 }
1722 delete $b{$item};
1723 }
1724
1725 my @keys = keys %b;
1726 if ($#keys) {
1727 print "diff2 $keys[0]\n";
1728 }
1729 return -1 if ($#keys >= 0);
1730
1731 return 0;
1732}
1733
1734sub run_config_bisect_test {
1735 my ($type) = @_;
1736
1737 return run_bisect_test $type, "oldconfig";
1738}
1739
1740sub process_passed {
1741 my (%configs) = @_;
1742
1743 doprint "These configs had no failure: (Enabling them for further compiles)\n";
1744 # Passed! All these configs are part of a good compile.
1745 # Add them to the min options.
1746 foreach my $config (keys %configs) {
1747 if (defined($config_list{$config})) {
1748 doprint " removing $config\n";
1749 $config_ignore{$config} = $config_list{$config};
1750 delete $config_list{$config};
1751 }
1752 }
Steven Rostedtf1a27852010-11-11 11:34:38 -05001753 doprint "config copied to $outputdir/config_good\n";
1754 run_command "cp -f $output_config $outputdir/config_good";
Steven Rostedt0a05c762010-11-08 11:14:10 -05001755}
1756
1757sub process_failed {
1758 my ($config) = @_;
1759
1760 doprint "\n\n***************************************\n";
1761 doprint "Found bad config: $config\n";
1762 doprint "***************************************\n\n";
1763}
1764
1765sub run_config_bisect {
1766
1767 my @start_list = keys %config_list;
1768
1769 if ($#start_list < 0) {
1770 doprint "No more configs to test!!!\n";
1771 return -1;
1772 }
1773
1774 doprint "***** RUN TEST ***\n";
1775 my $type = $opt{"CONFIG_BISECT_TYPE[$iteration]"};
1776 my $ret;
1777 my %current_config;
1778
1779 my $count = $#start_list + 1;
1780 doprint " $count configs to test\n";
1781
1782 my $half = int($#start_list / 2);
1783
1784 do {
1785 my @tophalf = @start_list[0 .. $half];
1786
1787 create_config @tophalf;
1788 read_current_config \%current_config;
1789
1790 $count = $#tophalf + 1;
1791 doprint "Testing $count configs\n";
1792 my $found = 0;
1793 # make sure we test something
1794 foreach my $config (@tophalf) {
1795 if (defined($current_config{$config})) {
1796 logit " $config\n";
1797 $found = 1;
1798 }
1799 }
1800 if (!$found) {
1801 # try the other half
1802 doprint "Top half produced no set configs, trying bottom half\n";
Steven Rostedt4c8cc552011-06-01 23:22:30 -04001803 @tophalf = @start_list[$half + 1 .. $#start_list];
Steven Rostedt0a05c762010-11-08 11:14:10 -05001804 create_config @tophalf;
1805 read_current_config \%current_config;
1806 foreach my $config (@tophalf) {
1807 if (defined($current_config{$config})) {
1808 logit " $config\n";
1809 $found = 1;
1810 }
1811 }
1812 if (!$found) {
1813 doprint "Failed: Can't make new config with current configs\n";
1814 foreach my $config (@start_list) {
1815 doprint " CONFIG: $config\n";
1816 }
1817 return -1;
1818 }
1819 $count = $#tophalf + 1;
1820 doprint "Testing $count configs\n";
1821 }
1822
1823 $ret = run_config_bisect_test $type;
Steven Rostedtc960bb92011-03-08 09:22:39 -05001824 if ($bisect_manual) {
1825 $ret = answer_bisect;
1826 }
Steven Rostedt0a05c762010-11-08 11:14:10 -05001827 if ($ret) {
1828 process_passed %current_config;
1829 return 0;
1830 }
1831
1832 doprint "This config had a failure.\n";
1833 doprint "Removing these configs that were not set in this config:\n";
Steven Rostedtf1a27852010-11-11 11:34:38 -05001834 doprint "config copied to $outputdir/config_bad\n";
1835 run_command "cp -f $output_config $outputdir/config_bad";
Steven Rostedt0a05c762010-11-08 11:14:10 -05001836
1837 # A config exists in this group that was bad.
1838 foreach my $config (keys %config_list) {
1839 if (!defined($current_config{$config})) {
1840 doprint " removing $config\n";
1841 delete $config_list{$config};
1842 }
1843 }
1844
1845 @start_list = @tophalf;
1846
1847 if ($#start_list == 0) {
1848 process_failed $start_list[0];
1849 return 1;
1850 }
1851
1852 # remove half the configs we are looking at and see if
1853 # they are good.
1854 $half = int($#start_list / 2);
Steven Rostedt4c8cc552011-06-01 23:22:30 -04001855 } while ($#start_list > 0);
Steven Rostedt0a05c762010-11-08 11:14:10 -05001856
Steven Rostedtc960bb92011-03-08 09:22:39 -05001857 # we found a single config, try it again unless we are running manually
1858
1859 if ($bisect_manual) {
1860 process_failed $start_list[0];
1861 return 1;
1862 }
1863
Steven Rostedt0a05c762010-11-08 11:14:10 -05001864 my @tophalf = @start_list[0 .. 0];
1865
1866 $ret = run_config_bisect_test $type;
1867 if ($ret) {
1868 process_passed %current_config;
1869 return 0;
1870 }
1871
1872 process_failed $start_list[0];
1873 return 1;
1874}
1875
1876sub config_bisect {
1877 my ($i) = @_;
1878
1879 my $start_config = $opt{"CONFIG_BISECT[$i]"};
1880
1881 my $tmpconfig = "$tmpdir/use_config";
1882
Steven Rostedt30f75da2011-06-13 10:35:35 -04001883 if (defined($config_bisect_good)) {
1884 process_config_ignore $config_bisect_good;
1885 }
1886
Steven Rostedt0a05c762010-11-08 11:14:10 -05001887 # Make the file with the bad config and the min config
1888 if (defined($minconfig)) {
1889 # read the min config for things to ignore
1890 run_command "cp $minconfig $tmpconfig" or
1891 dodie "failed to copy $minconfig to $tmpconfig";
1892 } else {
1893 unlink $tmpconfig;
1894 }
1895
1896 # Add other configs
1897 if (defined($addconfig)) {
1898 run_command "cat $addconfig >> $tmpconfig" or
1899 dodie "failed to append $addconfig";
1900 }
1901
Steven Rostedt0a05c762010-11-08 11:14:10 -05001902 if (-f $tmpconfig) {
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001903 load_force_config($tmpconfig);
Steven Rostedt0a05c762010-11-08 11:14:10 -05001904 process_config_ignore $tmpconfig;
1905 }
1906
1907 # now process the start config
1908 run_command "cp $start_config $output_config" or
1909 dodie "failed to copy $start_config to $output_config";
1910
1911 # read directly what we want to check
1912 my %config_check;
1913 open (IN, $output_config)
1914 or dodie "faied to open $output_config";
1915
1916 while (<IN>) {
1917 if (/^((CONFIG\S*)=.*)/) {
1918 $config_check{$2} = $1;
1919 }
1920 }
1921 close(IN);
1922
1923 # Now run oldconfig with the minconfig (and addconfigs)
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001924 make_oldconfig;
Steven Rostedt0a05c762010-11-08 11:14:10 -05001925
1926 # check to see what we lost (or gained)
1927 open (IN, $output_config)
1928 or dodie "Failed to read $start_config";
1929
1930 my %removed_configs;
1931 my %added_configs;
1932
1933 while (<IN>) {
1934 if (/^((CONFIG\S*)=.*)/) {
1935 # save off all options
1936 $config_set{$2} = $1;
1937 if (defined($config_check{$2})) {
1938 if (defined($config_ignore{$2})) {
1939 $removed_configs{$2} = $1;
1940 } else {
1941 $config_list{$2} = $1;
1942 }
1943 } elsif (!defined($config_ignore{$2})) {
1944 $added_configs{$2} = $1;
1945 $config_list{$2} = $1;
1946 }
1947 }
1948 }
1949 close(IN);
1950
1951 my @confs = keys %removed_configs;
1952 if ($#confs >= 0) {
1953 doprint "Configs overridden by default configs and removed from check:\n";
1954 foreach my $config (@confs) {
1955 doprint " $config\n";
1956 }
1957 }
1958 @confs = keys %added_configs;
1959 if ($#confs >= 0) {
1960 doprint "Configs appearing in make oldconfig and added:\n";
1961 foreach my $config (@confs) {
1962 doprint " $config\n";
1963 }
1964 }
1965
1966 my %config_test;
1967 my $once = 0;
1968
1969 # Sometimes kconfig does weird things. We must make sure
1970 # that the config we autocreate has everything we need
1971 # to test, otherwise we may miss testing configs, or
1972 # may not be able to create a new config.
1973 # Here we create a config with everything set.
1974 create_config (keys %config_list);
1975 read_current_config \%config_test;
1976 foreach my $config (keys %config_list) {
1977 if (!defined($config_test{$config})) {
1978 if (!$once) {
1979 $once = 1;
1980 doprint "Configs not produced by kconfig (will not be checked):\n";
1981 }
1982 doprint " $config\n";
1983 delete $config_list{$config};
1984 }
1985 }
1986 my $ret;
1987 do {
1988 $ret = run_config_bisect;
1989 } while (!$ret);
1990
1991 return $ret if ($ret < 0);
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001992
1993 success $i;
1994}
1995
Steven Rostedt27d934b2011-05-20 09:18:18 -04001996sub patchcheck_reboot {
1997 doprint "Reboot and sleep $patchcheck_sleep_time seconds\n";
1998 reboot;
1999 start_monitor;
2000 wait_for_monitor $patchcheck_sleep_time;
2001 end_monitor;
2002}
2003
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002004sub patchcheck {
2005 my ($i) = @_;
2006
2007 die "PATCHCHECK_START[$i] not defined\n"
2008 if (!defined($opt{"PATCHCHECK_START[$i]"}));
2009 die "PATCHCHECK_TYPE[$i] not defined\n"
2010 if (!defined($opt{"PATCHCHECK_TYPE[$i]"}));
2011
2012 my $start = $opt{"PATCHCHECK_START[$i]"};
2013
2014 my $end = "HEAD";
2015 if (defined($opt{"PATCHCHECK_END[$i]"})) {
2016 $end = $opt{"PATCHCHECK_END[$i]"};
2017 }
2018
Steven Rostedta57419b2010-11-02 15:13:54 -04002019 # Get the true sha1's since we can use things like HEAD~3
2020 $start = get_sha1($start);
2021 $end = get_sha1($end);
2022
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002023 my $type = $opt{"PATCHCHECK_TYPE[$i]"};
2024
2025 # Can't have a test without having a test to run
2026 if ($type eq "test" && !defined($run_test)) {
2027 $type = "boot";
2028 }
2029
2030 open (IN, "git log --pretty=oneline $end|") or
2031 dodie "could not get git list";
2032
2033 my @list;
2034
2035 while (<IN>) {
2036 chomp;
2037 $list[$#list+1] = $_;
2038 last if (/^$start/);
2039 }
2040 close(IN);
2041
2042 if ($list[$#list] !~ /^$start/) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002043 fail "SHA1 $start not found";
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002044 }
2045
2046 # go backwards in the list
2047 @list = reverse @list;
2048
2049 my $save_clean = $noclean;
2050
2051 $in_patchcheck = 1;
2052 foreach my $item (@list) {
2053 my $sha1 = $item;
2054 $sha1 =~ s/^([[:xdigit:]]+).*/$1/;
2055
2056 doprint "\nProcessing commit $item\n\n";
2057
2058 run_command "git checkout $sha1" or
2059 die "Failed to checkout $sha1";
2060
2061 # only clean on the first and last patch
2062 if ($item eq $list[0] ||
2063 $item eq $list[$#list]) {
2064 $noclean = $save_clean;
2065 } else {
2066 $noclean = 1;
2067 }
2068
2069 if (defined($minconfig)) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002070 build "useconfig:$minconfig" or return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002071 } else {
2072 # ?? no config to use?
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002073 build "oldconfig" or return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002074 }
2075
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002076 check_buildlog $sha1 or return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002077
2078 next if ($type eq "build");
2079
2080 get_grub_index;
2081 get_version;
2082 install;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002083
Steven Rostedt7faafbd2010-11-02 14:58:22 -04002084 my $failed = 0;
2085
2086 start_monitor;
2087 monitor or $failed = 1;
2088
2089 if (!$failed && $type ne "boot"){
2090 do_run_test or $failed = 1;
2091 }
2092 end_monitor;
2093 return 0 if ($failed);
2094
Steven Rostedt27d934b2011-05-20 09:18:18 -04002095 patchcheck_reboot;
2096
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002097 }
2098 $in_patchcheck = 0;
2099 success $i;
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002100
2101 return 1;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002102}
2103
Steven Rostedt8d1491b2010-11-18 15:39:48 -05002104$#ARGV < 1 or die "ktest.pl version: $VERSION\n usage: ktest.pl config-file\n";
Steven Rostedt2545eb62010-11-02 15:01:32 -04002105
Steven Rostedt8d1491b2010-11-18 15:39:48 -05002106if ($#ARGV == 0) {
2107 $ktest_config = $ARGV[0];
2108 if (! -f $ktest_config) {
2109 print "$ktest_config does not exist.\n";
2110 my $ans;
2111 for (;;) {
2112 print "Create it? [Y/n] ";
2113 $ans = <STDIN>;
2114 chomp $ans;
2115 if ($ans =~ /^\s*$/) {
2116 $ans = "y";
2117 }
2118 last if ($ans =~ /^y$/i || $ans =~ /^n$/i);
2119 print "Please answer either 'y' or 'n'.\n";
2120 }
2121 if ($ans !~ /^y$/i) {
2122 exit 0;
2123 }
2124 }
2125} else {
2126 $ktest_config = "ktest.conf";
2127}
2128
2129if (! -f $ktest_config) {
2130 open(OUT, ">$ktest_config") or die "Can not create $ktest_config";
2131 print OUT << "EOF"
2132# Generated by ktest.pl
2133#
2134# Define each test with TEST_START
2135# The config options below it will override the defaults
2136TEST_START
2137
2138DEFAULTS
2139EOF
2140;
2141 close(OUT);
2142}
2143read_config $ktest_config;
2144
Steven Rostedt23715c3c2011-06-13 11:03:34 -04002145if (defined($opt{"LOG_FILE"})) {
2146 $opt{"LOG_FILE"} = eval_option($opt{"LOG_FILE"}, -1);
2147}
2148
Steven Rostedt8d1491b2010-11-18 15:39:48 -05002149# Append any configs entered in manually to the config file.
2150my @new_configs = keys %entered_configs;
2151if ($#new_configs >= 0) {
2152 print "\nAppending entered in configs to $ktest_config\n";
2153 open(OUT, ">>$ktest_config") or die "Can not append to $ktest_config";
2154 foreach my $config (@new_configs) {
2155 print OUT "$config = $entered_configs{$config}\n";
2156 $opt{$config} = $entered_configs{$config};
2157 }
2158}
Steven Rostedt2545eb62010-11-02 15:01:32 -04002159
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002160if ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) {
2161 unlink $opt{"LOG_FILE"};
2162}
Steven Rostedt2545eb62010-11-02 15:01:32 -04002163
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002164doprint "\n\nSTARTING AUTOMATED TESTS\n\n";
2165
Steven Rostedta57419b2010-11-02 15:13:54 -04002166for (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) {
2167
2168 if (!$i) {
2169 doprint "DEFAULT OPTIONS:\n";
2170 } else {
2171 doprint "\nTEST $i OPTIONS";
2172 if (defined($repeat_tests{$i})) {
2173 $repeat = $repeat_tests{$i};
2174 doprint " ITERATE $repeat";
2175 }
2176 doprint "\n";
2177 }
2178
2179 foreach my $option (sort keys %opt) {
2180
2181 if ($option =~ /\[(\d+)\]$/) {
2182 next if ($i != $1);
2183 } else {
2184 next if ($i);
2185 }
2186
2187 doprint "$option = $opt{$option}\n";
2188 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002189}
Steven Rostedt2545eb62010-11-02 15:01:32 -04002190
Steven Rostedt2a625122011-05-20 15:48:59 -04002191sub __set_test_option {
Steven Rostedt5a391fb2010-11-02 14:57:43 -04002192 my ($name, $i) = @_;
2193
2194 my $option = "$name\[$i\]";
2195
2196 if (defined($opt{$option})) {
2197 return $opt{$option};
2198 }
2199
Steven Rostedta57419b2010-11-02 15:13:54 -04002200 foreach my $test (keys %repeat_tests) {
2201 if ($i >= $test &&
2202 $i < $test + $repeat_tests{$test}) {
2203 $option = "$name\[$test\]";
2204 if (defined($opt{$option})) {
2205 return $opt{$option};
2206 }
2207 }
2208 }
2209
Steven Rostedt5a391fb2010-11-02 14:57:43 -04002210 if (defined($opt{$name})) {
2211 return $opt{$name};
2212 }
2213
2214 return undef;
2215}
2216
Steven Rostedt2a625122011-05-20 15:48:59 -04002217sub set_test_option {
2218 my ($name, $i) = @_;
2219
2220 my $option = __set_test_option($name, $i);
2221 return $option if (!defined($option));
2222
Steven Rostedt23715c3c2011-06-13 11:03:34 -04002223 return eval_option($option, $i);
Steven Rostedt2a625122011-05-20 15:48:59 -04002224}
2225
Steven Rostedt2545eb62010-11-02 15:01:32 -04002226# First we need to do is the builds
Steven Rostedta75fece2010-11-02 14:58:27 -04002227for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
Steven Rostedt2545eb62010-11-02 15:01:32 -04002228
Steven Rostedt576f6272010-11-02 14:58:38 -04002229 $iteration = $i;
2230
Steven Rostedta75fece2010-11-02 14:58:27 -04002231 my $makecmd = set_test_option("MAKE_CMD", $i);
2232
2233 $machine = set_test_option("MACHINE", $i);
Steven Rostedte48c5292010-11-02 14:35:37 -04002234 $ssh_user = set_test_option("SSH_USER", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002235 $tmpdir = set_test_option("TMP_DIR", $i);
2236 $outputdir = set_test_option("OUTPUT_DIR", $i);
2237 $builddir = set_test_option("BUILD_DIR", $i);
2238 $test_type = set_test_option("TEST_TYPE", $i);
2239 $build_type = set_test_option("BUILD_TYPE", $i);
2240 $build_options = set_test_option("BUILD_OPTIONS", $i);
2241 $power_cycle = set_test_option("POWER_CYCLE", $i);
Steven Rostedte48c5292010-11-02 14:35:37 -04002242 $reboot = set_test_option("REBOOT", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002243 $noclean = set_test_option("BUILD_NOCLEAN", $i);
2244 $minconfig = set_test_option("MIN_CONFIG", $i);
2245 $run_test = set_test_option("TEST", $i);
2246 $addconfig = set_test_option("ADD_CONFIG", $i);
2247 $reboot_type = set_test_option("REBOOT_TYPE", $i);
2248 $grub_menu = set_test_option("GRUB_MENU", $i);
Steven Rostedt8b37ca82010-11-02 14:58:33 -04002249 $post_install = set_test_option("POST_INSTALL", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002250 $reboot_script = set_test_option("REBOOT_SCRIPT", $i);
2251 $reboot_on_error = set_test_option("REBOOT_ON_ERROR", $i);
2252 $poweroff_on_error = set_test_option("POWEROFF_ON_ERROR", $i);
2253 $die_on_failure = set_test_option("DIE_ON_FAILURE", $i);
2254 $power_off = set_test_option("POWER_OFF", $i);
Steven Rostedt576f6272010-11-02 14:58:38 -04002255 $powercycle_after_reboot = set_test_option("POWERCYCLE_AFTER_REBOOT", $i);
2256 $poweroff_after_halt = set_test_option("POWEROFF_AFTER_HALT", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002257 $sleep_time = set_test_option("SLEEP_TIME", $i);
2258 $bisect_sleep_time = set_test_option("BISECT_SLEEP_TIME", $i);
Steven Rostedt27d934b2011-05-20 09:18:18 -04002259 $patchcheck_sleep_time = set_test_option("PATCHCHECK_SLEEP_TIME", $i);
Steven Rostedtc960bb92011-03-08 09:22:39 -05002260 $bisect_manual = set_test_option("BISECT_MANUAL", $i);
Steven Rostedtc23dca72011-03-08 09:26:31 -05002261 $bisect_skip = set_test_option("BISECT_SKIP", $i);
Steven Rostedt30f75da2011-06-13 10:35:35 -04002262 $config_bisect_good = set_test_option("CONFIG_BISECT_GOOD", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002263 $store_failures = set_test_option("STORE_FAILURES", $i);
Steven Rostedt9064af52011-06-13 10:38:48 -04002264 $test_name = set_test_option("TEST_NAME", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002265 $timeout = set_test_option("TIMEOUT", $i);
2266 $booted_timeout = set_test_option("BOOTED_TIMEOUT", $i);
2267 $console = set_test_option("CONSOLE", $i);
Steven Rostedtf1a5b962011-06-13 10:30:00 -04002268 $detect_triplefault = set_test_option("DETECT_TRIPLE_FAULT", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002269 $success_line = set_test_option("SUCCESS_LINE", $i);
Steven Rostedt1c8a6172010-11-09 12:55:40 -05002270 $stop_after_success = set_test_option("STOP_AFTER_SUCCESS", $i);
2271 $stop_after_failure = set_test_option("STOP_AFTER_FAILURE", $i);
Steven Rostedt2d01b262011-03-08 09:47:54 -05002272 $stop_test_after = set_test_option("STOP_TEST_AFTER", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002273 $build_target = set_test_option("BUILD_TARGET", $i);
Steven Rostedte48c5292010-11-02 14:35:37 -04002274 $ssh_exec = set_test_option("SSH_EXEC", $i);
2275 $scp_to_target = set_test_option("SCP_TO_TARGET", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002276 $target_image = set_test_option("TARGET_IMAGE", $i);
2277 $localversion = set_test_option("LOCALVERSION", $i);
2278
2279 chdir $builddir || die "can't change directory to $builddir";
2280
2281 if (!-d $tmpdir) {
2282 mkpath($tmpdir) or
2283 die "can't create $tmpdir";
2284 }
2285
Steven Rostedte48c5292010-11-02 14:35:37 -04002286 $ENV{"SSH_USER"} = $ssh_user;
2287 $ENV{"MACHINE"} = $machine;
2288
Steven Rostedta75fece2010-11-02 14:58:27 -04002289 $target = "$ssh_user\@$machine";
2290
2291 $buildlog = "$tmpdir/buildlog-$machine";
2292 $dmesg = "$tmpdir/dmesg-$machine";
2293 $make = "$makecmd O=$outputdir";
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05002294 $output_config = "$outputdir/.config";
Steven Rostedta75fece2010-11-02 14:58:27 -04002295
2296 if ($reboot_type eq "grub") {
Steven Rostedt576f6272010-11-02 14:58:38 -04002297 dodie "GRUB_MENU not defined" if (!defined($grub_menu));
Steven Rostedta75fece2010-11-02 14:58:27 -04002298 } elsif (!defined($reboot_script)) {
Steven Rostedt576f6272010-11-02 14:58:38 -04002299 dodie "REBOOT_SCRIPT not defined"
Steven Rostedta75fece2010-11-02 14:58:27 -04002300 }
2301
2302 my $run_type = $build_type;
2303 if ($test_type eq "patchcheck") {
2304 $run_type = $opt{"PATCHCHECK_TYPE[$i]"};
2305 } elsif ($test_type eq "bisect") {
2306 $run_type = $opt{"BISECT_TYPE[$i]"};
Steven Rostedt0a05c762010-11-08 11:14:10 -05002307 } elsif ($test_type eq "config_bisect") {
2308 $run_type = $opt{"CONFIG_BISECT_TYPE[$i]"};
Steven Rostedta75fece2010-11-02 14:58:27 -04002309 }
2310
2311 # mistake in config file?
2312 if (!defined($run_type)) {
2313 $run_type = "ERROR";
2314 }
Steven Rostedt2545eb62010-11-02 15:01:32 -04002315
2316 doprint "\n\n";
Steven Rostedta75fece2010-11-02 14:58:27 -04002317 doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type\n\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -04002318
2319 unlink $dmesg;
2320 unlink $buildlog;
Steven Rostedt2545eb62010-11-02 15:01:32 -04002321
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002322 if (!defined($minconfig)) {
2323 $minconfig = $addconfig;
2324
2325 } elsif (defined($addconfig)) {
Steven Rostedt9be2e6b2010-11-09 12:20:21 -05002326 run_command "cat $addconfig $minconfig > $tmpdir/add_config" or
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002327 dodie "Failed to create temp config";
Steven Rostedt9be2e6b2010-11-09 12:20:21 -05002328 $minconfig = "$tmpdir/add_config";
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002329 }
2330
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002331 my $checkout = $opt{"CHECKOUT[$i]"};
2332 if (defined($checkout)) {
2333 run_command "git checkout $checkout" or
2334 die "failed to checkout $checkout";
2335 }
2336
Steven Rostedta75fece2010-11-02 14:58:27 -04002337 if ($test_type eq "bisect") {
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04002338 bisect $i;
2339 next;
Steven Rostedt0a05c762010-11-08 11:14:10 -05002340 } elsif ($test_type eq "config_bisect") {
2341 config_bisect $i;
2342 next;
Steven Rostedta75fece2010-11-02 14:58:27 -04002343 } elsif ($test_type eq "patchcheck") {
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002344 patchcheck $i;
2345 next;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04002346 }
2347
Steven Rostedt7faafbd2010-11-02 14:58:22 -04002348 if ($build_type ne "nobuild") {
2349 build $build_type or next;
Steven Rostedt2545eb62010-11-02 15:01:32 -04002350 }
2351
Steven Rostedta75fece2010-11-02 14:58:27 -04002352 if ($test_type ne "build") {
2353 get_grub_index;
2354 get_version;
2355 install;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04002356
Steven Rostedta75fece2010-11-02 14:58:27 -04002357 my $failed = 0;
2358 start_monitor;
2359 monitor or $failed = 1;;
2360
2361 if (!$failed && $test_type ne "boot" && defined($run_test)) {
2362 do_run_test or $failed = 1;
2363 }
2364 end_monitor;
2365 next if ($failed);
Steven Rostedt5a391fb2010-11-02 14:57:43 -04002366 }
2367
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04002368 success $i;
Steven Rostedt2545eb62010-11-02 15:01:32 -04002369}
2370
Steven Rostedt5c42fc52010-11-02 14:57:01 -04002371if ($opt{"POWEROFF_ON_SUCCESS"}) {
Steven Rostedt75c3fda72010-11-02 14:57:21 -04002372 halt;
Steven Rostedt576f6272010-11-02 14:58:38 -04002373} elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot) {
Steven Rostedt75c3fda72010-11-02 14:57:21 -04002374 reboot;
Steven Rostedt5c42fc52010-11-02 14:57:01 -04002375}
Steven Rostedt75c3fda72010-11-02 14:57:21 -04002376
Steven Rostedte48c5292010-11-02 14:35:37 -04002377doprint "\n $successes of $opt{NUM_TESTS} tests were successful\n\n";
2378
Steven Rostedt2545eb62010-11-02 15:01:32 -04002379exit 0;