blob: 1fd29b2daa9204fff6e345c8871799dcb0e04e5e [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:";
44$default{"BOOTED_TIMEOUT"} = 1;
45$default{"DIE_ON_FAILURE"} = 1;
Steven Rostedte48c5292010-11-02 14:35:37 -040046$default{"SSH_EXEC"} = "ssh \$SSH_USER\@\$MACHINE \$SSH_COMMAND";
47$default{"SCP_TO_TARGET"} = "scp \$SRC_FILE \$SSH_USER\@\$MACHINE:\$DST_FILE";
48$default{"REBOOT"} = "ssh \$SSH_USER\@\$MACHINE reboot";
Steven Rostedt1c8a6172010-11-09 12:55:40 -050049$default{"STOP_AFTER_SUCCESS"} = 10;
50$default{"STOP_AFTER_FAILURE"} = 60;
Steven Rostedt2d01b262011-03-08 09:47:54 -050051$default{"STOP_TEST_AFTER"} = 600;
Steven Rostedt8d1491b2010-11-18 15:39:48 -050052$default{"LOCALVERSION"} = "-test";
Steven Rostedt2545eb62010-11-02 15:01:32 -040053
Steven Rostedt8d1491b2010-11-18 15:39:48 -050054my $ktest_config;
Steven Rostedt2545eb62010-11-02 15:01:32 -040055my $version;
Steven Rostedta75fece2010-11-02 14:58:27 -040056my $machine;
Steven Rostedte48c5292010-11-02 14:35:37 -040057my $ssh_user;
Steven Rostedta75fece2010-11-02 14:58:27 -040058my $tmpdir;
59my $builddir;
60my $outputdir;
Steven Rostedt51ad1dd2010-11-08 16:43:21 -050061my $output_config;
Steven Rostedta75fece2010-11-02 14:58:27 -040062my $test_type;
Steven Rostedt7faafbd2010-11-02 14:58:22 -040063my $build_type;
Steven Rostedta75fece2010-11-02 14:58:27 -040064my $build_options;
65my $reboot_type;
66my $reboot_script;
67my $power_cycle;
Steven Rostedte48c5292010-11-02 14:35:37 -040068my $reboot;
Steven Rostedta75fece2010-11-02 14:58:27 -040069my $reboot_on_error;
70my $poweroff_on_error;
71my $die_on_failure;
Steven Rostedt576f6272010-11-02 14:58:38 -040072my $powercycle_after_reboot;
73my $poweroff_after_halt;
Steven Rostedte48c5292010-11-02 14:35:37 -040074my $ssh_exec;
75my $scp_to_target;
Steven Rostedta75fece2010-11-02 14:58:27 -040076my $power_off;
77my $grub_menu;
Steven Rostedt2545eb62010-11-02 15:01:32 -040078my $grub_number;
79my $target;
80my $make;
Steven Rostedt8b37ca82010-11-02 14:58:33 -040081my $post_install;
Steven Rostedt5c42fc52010-11-02 14:57:01 -040082my $noclean;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -040083my $minconfig;
Steven Rostedt2b7d9b22010-11-02 14:58:15 -040084my $addconfig;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -040085my $in_bisect = 0;
86my $bisect_bad = "";
Steven Rostedtd6ce2a02010-11-02 14:58:05 -040087my $reverse_bisect;
Steven Rostedtc960bb92011-03-08 09:22:39 -050088my $bisect_manual;
Steven Rostedtc23dca72011-03-08 09:26:31 -050089my $bisect_skip;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -040090my $in_patchcheck = 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -040091my $run_test;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -040092my $redirect;
Steven Rostedt7faafbd2010-11-02 14:58:22 -040093my $buildlog;
94my $dmesg;
95my $monitor_fp;
96my $monitor_pid;
97my $monitor_cnt = 0;
Steven Rostedta75fece2010-11-02 14:58:27 -040098my $sleep_time;
99my $bisect_sleep_time;
Steven Rostedt27d934b2011-05-20 09:18:18 -0400100my $patchcheck_sleep_time;
Steven Rostedta75fece2010-11-02 14:58:27 -0400101my $store_failures;
102my $timeout;
103my $booted_timeout;
104my $console;
105my $success_line;
Steven Rostedt1c8a6172010-11-09 12:55:40 -0500106my $stop_after_success;
107my $stop_after_failure;
Steven Rostedt2d01b262011-03-08 09:47:54 -0500108my $stop_test_after;
Steven Rostedta75fece2010-11-02 14:58:27 -0400109my $build_target;
110my $target_image;
111my $localversion;
Steven Rostedt576f6272010-11-02 14:58:38 -0400112my $iteration = 0;
Steven Rostedte48c5292010-11-02 14:35:37 -0400113my $successes = 0;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400114
Steven Rostedt8d1491b2010-11-18 15:39:48 -0500115my %entered_configs;
116my %config_help;
Steven Rostedt77d942c2011-05-20 13:36:58 -0400117my %variable;
Steven Rostedt8d1491b2010-11-18 15:39:48 -0500118
119$config_help{"MACHINE"} = << "EOF"
120 The machine hostname that you will test.
121EOF
122 ;
123$config_help{"SSH_USER"} = << "EOF"
124 The box is expected to have ssh on normal bootup, provide the user
125 (most likely root, since you need privileged operations)
126EOF
127 ;
128$config_help{"BUILD_DIR"} = << "EOF"
129 The directory that contains the Linux source code (full path).
130EOF
131 ;
132$config_help{"OUTPUT_DIR"} = << "EOF"
133 The directory that the objects will be built (full path).
134 (can not be same as BUILD_DIR)
135EOF
136 ;
137$config_help{"BUILD_TARGET"} = << "EOF"
138 The location of the compiled file to copy to the target.
139 (relative to OUTPUT_DIR)
140EOF
141 ;
142$config_help{"TARGET_IMAGE"} = << "EOF"
143 The place to put your image on the test machine.
144EOF
145 ;
146$config_help{"POWER_CYCLE"} = << "EOF"
147 A script or command to reboot the box.
148
149 Here is a digital loggers power switch example
150 POWER_CYCLE = wget --no-proxy -O /dev/null -q --auth-no-challenge 'http://admin:admin\@power/outlet?5=CCL'
151
152 Here is an example to reboot a virtual box on the current host
153 with the name "Guest".
154 POWER_CYCLE = virsh destroy Guest; sleep 5; virsh start Guest
155EOF
156 ;
157$config_help{"CONSOLE"} = << "EOF"
158 The script or command that reads the console
159
160 If you use ttywatch server, something like the following would work.
161CONSOLE = nc -d localhost 3001
162
163 For a virtual machine with guest name "Guest".
164CONSOLE = virsh console Guest
165EOF
166 ;
167$config_help{"LOCALVERSION"} = << "EOF"
168 Required version ending to differentiate the test
169 from other linux builds on the system.
170EOF
171 ;
172$config_help{"REBOOT_TYPE"} = << "EOF"
173 Way to reboot the box to the test kernel.
174 Only valid options so far are "grub" and "script".
175
176 If you specify grub, it will assume grub version 1
177 and will search in /boot/grub/menu.lst for the title \$GRUB_MENU
178 and select that target to reboot to the kernel. If this is not
179 your setup, then specify "script" and have a command or script
180 specified in REBOOT_SCRIPT to boot to the target.
181
182 The entry in /boot/grub/menu.lst must be entered in manually.
183 The test will not modify that file.
184EOF
185 ;
186$config_help{"GRUB_MENU"} = << "EOF"
187 The grub title name for the test kernel to boot
188 (Only mandatory if REBOOT_TYPE = grub)
189
190 Note, ktest.pl will not update the grub menu.lst, you need to
191 manually add an option for the test. ktest.pl will search
192 the grub menu.lst for this option to find what kernel to
193 reboot into.
194
195 For example, if in the /boot/grub/menu.lst the test kernel title has:
196 title Test Kernel
197 kernel vmlinuz-test
198 GRUB_MENU = Test Kernel
199EOF
200 ;
201$config_help{"REBOOT_SCRIPT"} = << "EOF"
202 A script to reboot the target into the test kernel
203 (Only mandatory if REBOOT_TYPE = script)
204EOF
205 ;
206
207
208sub get_ktest_config {
209 my ($config) = @_;
210
211 return if (defined($opt{$config}));
212
213 if (defined($config_help{$config})) {
214 print "\n";
215 print $config_help{$config};
216 }
217
218 for (;;) {
219 print "$config = ";
220 if (defined($default{$config})) {
221 print "\[$default{$config}\] ";
222 }
223 $entered_configs{$config} = <STDIN>;
224 $entered_configs{$config} =~ s/^\s*(.*\S)\s*$/$1/;
225 if ($entered_configs{$config} =~ /^\s*$/) {
226 if ($default{$config}) {
227 $entered_configs{$config} = $default{$config};
228 } else {
229 print "Your answer can not be blank\n";
230 next;
231 }
232 }
233 last;
234 }
235}
236
237sub get_ktest_configs {
238 get_ktest_config("MACHINE");
239 get_ktest_config("SSH_USER");
240 get_ktest_config("BUILD_DIR");
241 get_ktest_config("OUTPUT_DIR");
242 get_ktest_config("BUILD_TARGET");
243 get_ktest_config("TARGET_IMAGE");
244 get_ktest_config("POWER_CYCLE");
245 get_ktest_config("CONSOLE");
246 get_ktest_config("LOCALVERSION");
247
248 my $rtype = $opt{"REBOOT_TYPE"};
249
250 if (!defined($rtype)) {
251 if (!defined($opt{"GRUB_MENU"})) {
252 get_ktest_config("REBOOT_TYPE");
253 $rtype = $entered_configs{"REBOOT_TYPE"};
254 } else {
255 $rtype = "grub";
256 }
257 }
258
259 if ($rtype eq "grub") {
260 get_ktest_config("GRUB_MENU");
261 } else {
262 get_ktest_config("REBOOT_SCRIPT");
263 }
264}
265
Steven Rostedt77d942c2011-05-20 13:36:58 -0400266sub process_variables {
267 my ($value) = @_;
268 my $retval = "";
269
270 # We want to check for '\', and it is just easier
271 # to check the previous characet of '$' and not need
272 # to worry if '$' is the first character. By adding
273 # a space to $value, we can just check [^\\]\$ and
274 # it will still work.
275 $value = " $value";
276
277 while ($value =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
278 my $begin = $1;
279 my $var = $2;
280 my $end = $3;
281 # append beginning of value to retval
282 $retval = "$retval$begin";
283 if (defined($variable{$var})) {
284 $retval = "$retval$variable{$var}";
285 } else {
286 # put back the origin piece.
287 $retval = "$retval\$\{$var\}";
288 }
289 $value = $end;
290 }
291 $retval = "$retval$value";
292
293 # remove the space added in the beginning
294 $retval =~ s/ //;
295
296 return "$retval"
297}
298
Steven Rostedta57419b2010-11-02 15:13:54 -0400299sub set_value {
300 my ($lvalue, $rvalue) = @_;
301
302 if (defined($opt{$lvalue})) {
303 die "Error: Option $lvalue defined more than once!\n";
304 }
Steven Rostedt21a96792010-11-08 16:45:50 -0500305 if ($rvalue =~ /^\s*$/) {
306 delete $opt{$lvalue};
307 } else {
Steven Rostedt77d942c2011-05-20 13:36:58 -0400308 $rvalue = process_variables($rvalue);
Steven Rostedt21a96792010-11-08 16:45:50 -0500309 $opt{$lvalue} = $rvalue;
310 }
Steven Rostedta57419b2010-11-02 15:13:54 -0400311}
312
Steven Rostedt77d942c2011-05-20 13:36:58 -0400313sub set_variable {
314 my ($lvalue, $rvalue) = @_;
315
316 if ($rvalue =~ /^\s*$/) {
317 delete $variable{$lvalue};
318 } else {
319 $rvalue = process_variables($rvalue);
320 $variable{$lvalue} = $rvalue;
321 }
322}
323
Steven Rostedt2545eb62010-11-02 15:01:32 -0400324sub read_config {
325 my ($config) = @_;
326
327 open(IN, $config) || die "can't read file $config";
328
Steven Rostedta57419b2010-11-02 15:13:54 -0400329 my $name = $config;
330 $name =~ s,.*/(.*),$1,;
331
332 my $test_num = 0;
333 my $default = 1;
334 my $repeat = 1;
335 my $num_tests_set = 0;
336 my $skip = 0;
337 my $rest;
338
Steven Rostedt2545eb62010-11-02 15:01:32 -0400339 while (<IN>) {
340
341 # ignore blank lines and comments
342 next if (/^\s*$/ || /\s*\#/);
343
Steven Rostedta57419b2010-11-02 15:13:54 -0400344 if (/^\s*TEST_START(.*)/) {
345
346 $rest = $1;
347
348 if ($num_tests_set) {
349 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
350 }
351
352 my $old_test_num = $test_num;
Steven Rostedte48c5292010-11-02 14:35:37 -0400353 my $old_repeat = $repeat;
Steven Rostedta57419b2010-11-02 15:13:54 -0400354
355 $test_num += $repeat;
356 $default = 0;
357 $repeat = 1;
358
359 if ($rest =~ /\s+SKIP(.*)/) {
360 $rest = $1;
361 $skip = 1;
362 } else {
363 $skip = 0;
364 }
365
366 if ($rest =~ /\s+ITERATE\s+(\d+)(.*)$/) {
367 $repeat = $1;
368 $rest = $2;
369 $repeat_tests{"$test_num"} = $repeat;
370 }
371
372 if ($rest =~ /\s+SKIP(.*)/) {
373 $rest = $1;
374 $skip = 1;
375 }
376
377 if ($rest !~ /^\s*$/) {
378 die "$name: $.: Gargbage found after TEST_START\n$_";
379 }
380
381 if ($skip) {
382 $test_num = $old_test_num;
Steven Rostedte48c5292010-11-02 14:35:37 -0400383 $repeat = $old_repeat;
Steven Rostedta57419b2010-11-02 15:13:54 -0400384 }
385
386 } elsif (/^\s*DEFAULTS(.*)$/) {
387 $default = 1;
388
389 $rest = $1;
390
391 if ($rest =~ /\s+SKIP(.*)/) {
392 $rest = $1;
393 $skip = 1;
394 } else {
395 $skip = 0;
396 }
397
398 if ($rest !~ /^\s*$/) {
399 die "$name: $.: Gargbage found after DEFAULTS\n$_";
400 }
401
402 } elsif (/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) {
403
404 next if ($skip);
405
Steven Rostedt2545eb62010-11-02 15:01:32 -0400406 my $lvalue = $1;
407 my $rvalue = $2;
408
Steven Rostedta57419b2010-11-02 15:13:54 -0400409 if (!$default &&
410 ($lvalue eq "NUM_TESTS" ||
411 $lvalue eq "LOG_FILE" ||
412 $lvalue eq "CLEAR_LOG")) {
413 die "$name: $.: $lvalue must be set in DEFAULTS section\n";
Steven Rostedta75fece2010-11-02 14:58:27 -0400414 }
Steven Rostedta57419b2010-11-02 15:13:54 -0400415
416 if ($lvalue eq "NUM_TESTS") {
417 if ($test_num) {
418 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
419 }
420 if (!$default) {
421 die "$name: $.: NUM_TESTS must be set in default section\n";
422 }
423 $num_tests_set = 1;
424 }
425
426 if ($default || $lvalue =~ /\[\d+\]$/) {
427 set_value($lvalue, $rvalue);
428 } else {
429 my $val = "$lvalue\[$test_num\]";
430 set_value($val, $rvalue);
431
432 if ($repeat > 1) {
433 $repeats{$val} = $repeat;
434 }
435 }
Steven Rostedt77d942c2011-05-20 13:36:58 -0400436 } elsif (/^\s*([A-Z_\[\]\d]+)\s*:=\s*(.*?)\s*$/) {
437 next if ($skip);
438
439 my $lvalue = $1;
440 my $rvalue = $2;
441
442 # process config variables.
443 # Config variables are only active while reading the
444 # config and can be defined anywhere. They also ignore
445 # TEST_START and DEFAULTS, but are skipped if they are in
446 # on of these sections that have SKIP defined.
447 # The save variable can be
448 # defined multiple times and the new one simply overrides
449 # the prevous one.
450 set_variable($lvalue, $rvalue);
451
Steven Rostedta57419b2010-11-02 15:13:54 -0400452 } else {
453 die "$name: $.: Garbage found in config\n$_";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400454 }
455 }
456
457 close(IN);
Steven Rostedta75fece2010-11-02 14:58:27 -0400458
Steven Rostedta57419b2010-11-02 15:13:54 -0400459 if ($test_num) {
460 $test_num += $repeat - 1;
461 $opt{"NUM_TESTS"} = $test_num;
462 }
463
Steven Rostedt8d1491b2010-11-18 15:39:48 -0500464 # make sure we have all mandatory configs
465 get_ktest_configs;
466
Steven Rostedta75fece2010-11-02 14:58:27 -0400467 # set any defaults
468
469 foreach my $default (keys %default) {
470 if (!defined($opt{$default})) {
471 $opt{$default} = $default{$default};
472 }
473 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400474}
475
Steven Rostedtd1e2f222010-11-08 16:39:57 -0500476sub _logit {
Steven Rostedt2545eb62010-11-02 15:01:32 -0400477 if (defined($opt{"LOG_FILE"})) {
478 open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}";
479 print OUT @_;
480 close(OUT);
481 }
482}
483
Steven Rostedtd1e2f222010-11-08 16:39:57 -0500484sub logit {
485 if (defined($opt{"LOG_FILE"})) {
486 _logit @_;
487 } else {
488 print @_;
489 }
490}
491
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400492sub doprint {
493 print @_;
Steven Rostedtd1e2f222010-11-08 16:39:57 -0500494 _logit @_;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400495}
496
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400497sub run_command;
498
499sub reboot {
500 # try to reboot normally
Steven Rostedte48c5292010-11-02 14:35:37 -0400501 if (run_command $reboot) {
Steven Rostedt576f6272010-11-02 14:58:38 -0400502 if (defined($powercycle_after_reboot)) {
503 sleep $powercycle_after_reboot;
504 run_command "$power_cycle";
505 }
506 } else {
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400507 # nope? power cycle it.
Steven Rostedta75fece2010-11-02 14:58:27 -0400508 run_command "$power_cycle";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400509 }
510}
511
Steven Rostedt576f6272010-11-02 14:58:38 -0400512sub do_not_reboot {
513 my $i = $iteration;
514
515 return $test_type eq "build" ||
516 ($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") ||
517 ($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build");
518}
519
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400520sub dodie {
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400521 doprint "CRITICAL FAILURE... ", @_, "\n";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400522
Steven Rostedt576f6272010-11-02 14:58:38 -0400523 my $i = $iteration;
524
525 if ($reboot_on_error && !do_not_reboot) {
526
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400527 doprint "REBOOTING\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400528 reboot;
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400529
Steven Rostedta75fece2010-11-02 14:58:27 -0400530 } elsif ($poweroff_on_error && defined($power_off)) {
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400531 doprint "POWERING OFF\n";
Steven Rostedta75fece2010-11-02 14:58:27 -0400532 `$power_off`;
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400533 }
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400534
Steven Rostedtf80802c2011-03-07 13:18:47 -0500535 if (defined($opt{"LOG_FILE"})) {
536 print " See $opt{LOG_FILE} for more info.\n";
537 }
538
Steven Rostedt576f6272010-11-02 14:58:38 -0400539 die @_, "\n";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400540}
541
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400542sub open_console {
543 my ($fp) = @_;
544
545 my $flags;
546
Steven Rostedta75fece2010-11-02 14:58:27 -0400547 my $pid = open($fp, "$console|") or
548 dodie "Can't open console $console";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400549
550 $flags = fcntl($fp, F_GETFL, 0) or
Steven Rostedt576f6272010-11-02 14:58:38 -0400551 dodie "Can't get flags for the socket: $!";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400552 $flags = fcntl($fp, F_SETFL, $flags | O_NONBLOCK) or
Steven Rostedt576f6272010-11-02 14:58:38 -0400553 dodie "Can't set flags for the socket: $!";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400554
555 return $pid;
556}
557
558sub close_console {
559 my ($fp, $pid) = @_;
560
561 doprint "kill child process $pid\n";
562 kill 2, $pid;
563
564 print "closing!\n";
565 close($fp);
566}
567
568sub start_monitor {
569 if ($monitor_cnt++) {
570 return;
571 }
572 $monitor_fp = \*MONFD;
573 $monitor_pid = open_console $monitor_fp;
Steven Rostedta75fece2010-11-02 14:58:27 -0400574
575 return;
576
577 open(MONFD, "Stop perl from warning about single use of MONFD");
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400578}
579
580sub end_monitor {
581 if (--$monitor_cnt) {
582 return;
583 }
584 close_console($monitor_fp, $monitor_pid);
585}
586
587sub wait_for_monitor {
588 my ($time) = @_;
589 my $line;
590
Steven Rostedta75fece2010-11-02 14:58:27 -0400591 doprint "** Wait for monitor to settle down **\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400592
593 # read the monitor and wait for the system to calm down
594 do {
595 $line = wait_for_input($monitor_fp, $time);
Steven Rostedta75fece2010-11-02 14:58:27 -0400596 print "$line" if (defined($line));
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400597 } while (defined($line));
Steven Rostedta75fece2010-11-02 14:58:27 -0400598 print "** Monitor flushed **\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400599}
600
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400601sub fail {
602
Steven Rostedta75fece2010-11-02 14:58:27 -0400603 if ($die_on_failure) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400604 dodie @_;
605 }
606
Steven Rostedta75fece2010-11-02 14:58:27 -0400607 doprint "FAILED\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400608
Steven Rostedt576f6272010-11-02 14:58:38 -0400609 my $i = $iteration;
610
Steven Rostedta75fece2010-11-02 14:58:27 -0400611 # no need to reboot for just building.
Steven Rostedt576f6272010-11-02 14:58:38 -0400612 if (!do_not_reboot) {
Steven Rostedta75fece2010-11-02 14:58:27 -0400613 doprint "REBOOTING\n";
614 reboot;
615 start_monitor;
616 wait_for_monitor $sleep_time;
617 end_monitor;
618 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400619
Steven Rostedt576f6272010-11-02 14:58:38 -0400620 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
621 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
Steven Rostedt7a849cd2010-11-08 16:49:25 -0500622 doprint "KTEST RESULT: TEST $i Failed: ", @_, "\n";
Steven Rostedt576f6272010-11-02 14:58:38 -0400623 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
624 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
Steven Rostedta75fece2010-11-02 14:58:27 -0400625
626 return 1 if (!defined($store_failures));
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400627
628 my @t = localtime;
629 my $date = sprintf "%04d%02d%02d%02d%02d%02d",
630 1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0];
631
Steven Rostedtcccae1a2010-11-09 12:21:32 -0500632 my $type = $build_type;
633 if ($type =~ /useconfig/) {
634 $type = "useconfig";
635 }
636
637 my $dir = "$machine-$test_type-$type-fail-$date";
Steven Rostedta75fece2010-11-02 14:58:27 -0400638 my $faildir = "$store_failures/$dir";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400639
640 if (!-d $faildir) {
641 mkpath($faildir) or
Steven Rostedta75fece2010-11-02 14:58:27 -0400642 die "can't create $faildir";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400643 }
Steven Rostedt51ad1dd2010-11-08 16:43:21 -0500644 if (-f "$output_config") {
645 cp "$output_config", "$faildir/config" or
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400646 die "failed to copy .config";
647 }
648 if (-f $buildlog) {
649 cp $buildlog, "$faildir/buildlog" or
650 die "failed to move $buildlog";
651 }
652 if (-f $dmesg) {
653 cp $dmesg, "$faildir/dmesg" or
654 die "failed to move $dmesg";
655 }
656
657 doprint "*** Saved info to $faildir ***\n";
658
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400659 return 1;
660}
661
Steven Rostedt2545eb62010-11-02 15:01:32 -0400662sub run_command {
663 my ($command) = @_;
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400664 my $dolog = 0;
665 my $dord = 0;
666 my $pid;
667
Steven Rostedte48c5292010-11-02 14:35:37 -0400668 $command =~ s/\$SSH_USER/$ssh_user/g;
669 $command =~ s/\$MACHINE/$machine/g;
670
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400671 doprint("$command ... ");
672
673 $pid = open(CMD, "$command 2>&1 |") or
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400674 (fail "unable to exec $command" and return 0);
Steven Rostedt2545eb62010-11-02 15:01:32 -0400675
676 if (defined($opt{"LOG_FILE"})) {
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400677 open(LOG, ">>$opt{LOG_FILE}") or
678 dodie "failed to write to log";
679 $dolog = 1;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400680 }
681
682 if (defined($redirect)) {
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400683 open (RD, ">$redirect") or
684 dodie "failed to write to redirect $redirect";
685 $dord = 1;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400686 }
687
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400688 while (<CMD>) {
689 print LOG if ($dolog);
690 print RD if ($dord);
691 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400692
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400693 waitpid($pid, 0);
Steven Rostedt2545eb62010-11-02 15:01:32 -0400694 my $failed = $?;
695
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400696 close(CMD);
697 close(LOG) if ($dolog);
698 close(RD) if ($dord);
699
Steven Rostedt2545eb62010-11-02 15:01:32 -0400700 if ($failed) {
701 doprint "FAILED!\n";
702 } else {
703 doprint "SUCCESS\n";
704 }
705
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400706 return !$failed;
707}
708
Steven Rostedte48c5292010-11-02 14:35:37 -0400709sub run_ssh {
710 my ($cmd) = @_;
711 my $cp_exec = $ssh_exec;
712
713 $cp_exec =~ s/\$SSH_COMMAND/$cmd/g;
714 return run_command "$cp_exec";
715}
716
717sub run_scp {
718 my ($src, $dst) = @_;
719 my $cp_scp = $scp_to_target;
720
721 $cp_scp =~ s/\$SRC_FILE/$src/g;
722 $cp_scp =~ s/\$DST_FILE/$dst/g;
723
724 return run_command "$cp_scp";
725}
726
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400727sub get_grub_index {
728
Steven Rostedta75fece2010-11-02 14:58:27 -0400729 if ($reboot_type ne "grub") {
730 return;
731 }
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400732 return if (defined($grub_number));
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400733
734 doprint "Find grub menu ... ";
735 $grub_number = -1;
Steven Rostedte48c5292010-11-02 14:35:37 -0400736
737 my $ssh_grub = $ssh_exec;
738 $ssh_grub =~ s,\$SSH_COMMAND,cat /boot/grub/menu.lst,g;
739
740 open(IN, "$ssh_grub |")
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400741 or die "unable to get menu.lst";
Steven Rostedte48c5292010-11-02 14:35:37 -0400742
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400743 while (<IN>) {
Steven Rostedta75fece2010-11-02 14:58:27 -0400744 if (/^\s*title\s+$grub_menu\s*$/) {
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400745 $grub_number++;
746 last;
747 } elsif (/^\s*title\s/) {
748 $grub_number++;
749 }
750 }
751 close(IN);
752
Steven Rostedta75fece2010-11-02 14:58:27 -0400753 die "Could not find '$grub_menu' in /boot/grub/menu on $machine"
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400754 if ($grub_number < 0);
755 doprint "$grub_number\n";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400756}
757
Steven Rostedt2545eb62010-11-02 15:01:32 -0400758sub wait_for_input
759{
760 my ($fp, $time) = @_;
761 my $rin;
762 my $ready;
763 my $line;
764 my $ch;
765
766 if (!defined($time)) {
767 $time = $timeout;
768 }
769
770 $rin = '';
771 vec($rin, fileno($fp), 1) = 1;
772 $ready = select($rin, undef, undef, $time);
773
774 $line = "";
775
776 # try to read one char at a time
777 while (sysread $fp, $ch, 1) {
778 $line .= $ch;
779 last if ($ch eq "\n");
780 }
781
782 if (!length($line)) {
783 return undef;
784 }
785
786 return $line;
787}
788
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400789sub reboot_to {
Steven Rostedta75fece2010-11-02 14:58:27 -0400790 if ($reboot_type eq "grub") {
Steven Rostedteec56462010-11-10 09:08:20 -0500791 run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch; reboot)'";
Steven Rostedta75fece2010-11-02 14:58:27 -0400792 return;
793 }
794
795 run_command "$reboot_script";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400796}
797
Steven Rostedta57419b2010-11-02 15:13:54 -0400798sub get_sha1 {
799 my ($commit) = @_;
800
801 doprint "git rev-list --max-count=1 $commit ... ";
802 my $sha1 = `git rev-list --max-count=1 $commit`;
803 my $ret = $?;
804
805 logit $sha1;
806
807 if ($ret) {
808 doprint "FAILED\n";
809 dodie "Failed to get git $commit";
810 }
811
812 print "SUCCESS\n";
813
814 chomp $sha1;
815
816 return $sha1;
817}
818
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400819sub monitor {
Steven Rostedt2545eb62010-11-02 15:01:32 -0400820 my $booted = 0;
821 my $bug = 0;
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400822 my $skip_call_trace = 0;
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400823 my $loops;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400824
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400825 wait_for_monitor 5;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400826
827 my $line;
828 my $full_line = "";
829
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400830 open(DMESG, "> $dmesg") or
831 die "unable to write to $dmesg";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400832
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400833 reboot_to;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400834
Steven Rostedt1c8a6172010-11-09 12:55:40 -0500835 my $success_start;
836 my $failure_start;
Steven Rostedt2d01b262011-03-08 09:47:54 -0500837 my $monitor_start = time;
838 my $done = 0;
Steven Rostedt1c8a6172010-11-09 12:55:40 -0500839
Steven Rostedt2d01b262011-03-08 09:47:54 -0500840 while (!$done) {
Steven Rostedt2545eb62010-11-02 15:01:32 -0400841
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400842 if ($booted) {
Steven Rostedta75fece2010-11-02 14:58:27 -0400843 $line = wait_for_input($monitor_fp, $booted_timeout);
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400844 } else {
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400845 $line = wait_for_input($monitor_fp);
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400846 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400847
848 last if (!defined($line));
849
850 doprint $line;
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400851 print DMESG $line;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400852
853 # we are not guaranteed to get a full line
854 $full_line .= $line;
855
Steven Rostedta75fece2010-11-02 14:58:27 -0400856 if ($full_line =~ /$success_line/) {
Steven Rostedt2545eb62010-11-02 15:01:32 -0400857 $booted = 1;
Steven Rostedt1c8a6172010-11-09 12:55:40 -0500858 $success_start = time;
859 }
860
861 if ($booted && defined($stop_after_success) &&
862 $stop_after_success >= 0) {
863 my $now = time;
864 if ($now - $success_start >= $stop_after_success) {
865 doprint "Test forced to stop after $stop_after_success seconds after success\n";
866 last;
867 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400868 }
869
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400870 if ($full_line =~ /\[ backtrace testing \]/) {
871 $skip_call_trace = 1;
872 }
873
Steven Rostedt2545eb62010-11-02 15:01:32 -0400874 if ($full_line =~ /call trace:/i) {
Steven Rostedt46519202011-03-08 09:40:31 -0500875 if (!$bug && !$skip_call_trace) {
Steven Rostedt1c8a6172010-11-09 12:55:40 -0500876 $bug = 1;
877 $failure_start = time;
878 }
879 }
880
881 if ($bug && defined($stop_after_failure) &&
882 $stop_after_failure >= 0) {
883 my $now = time;
884 if ($now - $failure_start >= $stop_after_failure) {
885 doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
886 last;
887 }
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400888 }
889
890 if ($full_line =~ /\[ end of backtrace testing \]/) {
891 $skip_call_trace = 0;
892 }
893
894 if ($full_line =~ /Kernel panic -/) {
Steven Rostedt10abf112011-03-07 13:21:00 -0500895 $failure_start = time;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400896 $bug = 1;
897 }
898
899 if ($line =~ /\n/) {
900 $full_line = "";
901 }
Steven Rostedt2d01b262011-03-08 09:47:54 -0500902
903 if ($stop_test_after > 0 && !$booted && !$bug) {
904 if (time - $monitor_start > $stop_test_after) {
Steven Rostedt4d62bf52011-05-20 09:14:35 -0400905 doprint "STOP_TEST_AFTER ($stop_test_after seconds) timed out\n";
Steven Rostedt2d01b262011-03-08 09:47:54 -0500906 $done = 1;
907 }
908 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400909 }
910
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400911 close(DMESG);
Steven Rostedt2545eb62010-11-02 15:01:32 -0400912
Steven Rostedt2545eb62010-11-02 15:01:32 -0400913 if ($bug) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400914 return 0 if ($in_bisect);
Steven Rostedt576f6272010-11-02 14:58:38 -0400915 fail "failed - got a bug report" and return 0;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400916 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400917
Steven Rostedta75fece2010-11-02 14:58:27 -0400918 if (!$booted) {
919 return 0 if ($in_bisect);
Steven Rostedt576f6272010-11-02 14:58:38 -0400920 fail "failed - never got a boot prompt." and return 0;
Steven Rostedta75fece2010-11-02 14:58:27 -0400921 }
922
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400923 return 1;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400924}
925
926sub install {
927
Steven Rostedte48c5292010-11-02 14:35:37 -0400928 run_scp "$outputdir/$build_target", "$target_image" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400929 dodie "failed to copy image";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400930
931 my $install_mods = 0;
932
933 # should we process modules?
934 $install_mods = 0;
Steven Rostedt51ad1dd2010-11-08 16:43:21 -0500935 open(IN, "$output_config") or dodie("Can't read config file");
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400936 while (<IN>) {
937 if (/CONFIG_MODULES(=y)?/) {
938 $install_mods = 1 if (defined($1));
939 last;
940 }
941 }
942 close(IN);
943
944 if (!$install_mods) {
945 doprint "No modules needed\n";
946 return;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400947 }
948
Steven Rostedta75fece2010-11-02 14:58:27 -0400949 run_command "$make INSTALL_MOD_PATH=$tmpdir modules_install" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400950 dodie "Failed to install modules";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400951
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400952 my $modlib = "/lib/modules/$version";
Steven Rostedta57419b2010-11-02 15:13:54 -0400953 my $modtar = "ktest-mods.tar.bz2";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400954
Steven Rostedte48c5292010-11-02 14:35:37 -0400955 run_ssh "rm -rf $modlib" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400956 dodie "failed to remove old mods: $modlib";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400957
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400958 # would be nice if scp -r did not follow symbolic links
Steven Rostedta75fece2010-11-02 14:58:27 -0400959 run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400960 dodie "making tarball";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400961
Steven Rostedte48c5292010-11-02 14:35:37 -0400962 run_scp "$tmpdir/$modtar", "/tmp" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400963 dodie "failed to copy modules";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400964
Steven Rostedta75fece2010-11-02 14:58:27 -0400965 unlink "$tmpdir/$modtar";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400966
Steven Rostedte48c5292010-11-02 14:35:37 -0400967 run_ssh "'(cd / && tar xf /tmp/$modtar)'" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400968 dodie "failed to tar modules";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400969
Steven Rostedte48c5292010-11-02 14:35:37 -0400970 run_ssh "rm -f /tmp/$modtar";
Steven Rostedt8b37ca82010-11-02 14:58:33 -0400971
972 return if (!defined($post_install));
973
Steven Rostedte48c5292010-11-02 14:35:37 -0400974 my $cp_post_install = $post_install;
Steven Rostedtca6a21f2011-03-25 22:42:53 -0400975 $cp_post_install =~ s/\$KERNEL_VERSION/$version/g;
Steven Rostedte48c5292010-11-02 14:35:37 -0400976 run_command "$cp_post_install" or
Steven Rostedt576f6272010-11-02 14:58:38 -0400977 dodie "Failed to run post install";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400978}
979
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400980sub check_buildlog {
981 my ($patch) = @_;
982
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400983 my @files = `git show $patch | diffstat -l`;
984
985 open(IN, "git show $patch |") or
986 dodie "failed to show $patch";
987 while (<IN>) {
988 if (m,^--- a/(.*),) {
989 chomp $1;
990 $files[$#files] = $1;
991 }
992 }
993 close(IN);
994
995 open(IN, $buildlog) or dodie "Can't open $buildlog";
996 while (<IN>) {
997 if (/^\s*(.*?):.*(warning|error)/) {
998 my $err = $1;
999 foreach my $file (@files) {
Steven Rostedta75fece2010-11-02 14:58:27 -04001000 my $fullpath = "$builddir/$file";
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001001 if ($file eq $err || $fullpath eq $err) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001002 fail "$file built with warnings" and return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001003 }
1004 }
1005 }
1006 }
1007 close(IN);
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001008
1009 return 1;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001010}
1011
Steven Rostedt612b9e92011-03-07 13:27:43 -05001012sub make_oldconfig {
1013 my ($defconfig) = @_;
1014
1015 if (!run_command "$defconfig $make oldnoconfig") {
1016 # Perhaps oldnoconfig doesn't exist in this version of the kernel
1017 # try a yes '' | oldconfig
1018 doprint "oldnoconfig failed, trying yes '' | make oldconfig\n";
1019 run_command "yes '' | $defconfig $make oldconfig" or
1020 dodie "failed make config oldconfig";
1021 }
1022}
1023
Steven Rostedt2545eb62010-11-02 15:01:32 -04001024sub build {
1025 my ($type) = @_;
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001026 my $defconfig = "";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001027
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001028 unlink $buildlog;
1029
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001030 if ($type =~ /^useconfig:(.*)/) {
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05001031 run_command "cp $1 $output_config" or
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001032 dodie "could not copy $1 to .config";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001033
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001034 $type = "oldconfig";
1035 }
1036
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001037 # old config can ask questions
1038 if ($type eq "oldconfig") {
Steven Rostedt9386c6a2010-11-08 16:35:48 -05001039 $type = "oldnoconfig";
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001040
1041 # allow for empty configs
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05001042 run_command "touch $output_config";
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001043
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05001044 run_command "mv $output_config $outputdir/config_temp" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001045 dodie "moving .config";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001046
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001047 if (!$noclean && !run_command "$make mrproper") {
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001048 dodie "make mrproper";
1049 }
1050
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05001051 run_command "mv $outputdir/config_temp $output_config" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001052 dodie "moving config_temp";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001053
1054 } elsif (!$noclean) {
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05001055 unlink "$output_config";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001056 run_command "$make mrproper" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001057 dodie "make mrproper";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001058 }
Steven Rostedt2545eb62010-11-02 15:01:32 -04001059
1060 # add something to distinguish this build
Steven Rostedta75fece2010-11-02 14:58:27 -04001061 open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file");
1062 print OUT "$localversion\n";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001063 close(OUT);
1064
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001065 if (defined($minconfig)) {
1066 $defconfig = "KCONFIG_ALLCONFIG=$minconfig";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001067 }
1068
Steven Rostedt612b9e92011-03-07 13:27:43 -05001069 if ($type eq "oldnoconfig") {
1070 make_oldconfig $defconfig;
1071 } else {
1072 run_command "$defconfig $make $type" or
1073 dodie "failed make config";
1074 }
Steven Rostedt2545eb62010-11-02 15:01:32 -04001075
Steven Rostedta75fece2010-11-02 14:58:27 -04001076 $redirect = "$buildlog";
1077 if (!run_command "$make $build_options") {
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001078 undef $redirect;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001079 # bisect may need this to pass
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001080 return 0 if ($in_bisect);
1081 fail "failed build" and return 0;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001082 }
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001083 undef $redirect;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001084
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001085 return 1;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001086}
1087
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001088sub halt {
Steven Rostedte48c5292010-11-02 14:35:37 -04001089 if (!run_ssh "halt" or defined($power_off)) {
Steven Rostedt576f6272010-11-02 14:58:38 -04001090 if (defined($poweroff_after_halt)) {
1091 sleep $poweroff_after_halt;
1092 run_command "$power_off";
1093 }
1094 } else {
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001095 # nope? the zap it!
Steven Rostedta75fece2010-11-02 14:58:27 -04001096 run_command "$power_off";
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001097 }
1098}
1099
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001100sub success {
1101 my ($i) = @_;
1102
Steven Rostedte48c5292010-11-02 14:35:37 -04001103 $successes++;
1104
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001105 doprint "\n\n*******************************************\n";
1106 doprint "*******************************************\n";
Steven Rostedt7a849cd2010-11-08 16:49:25 -05001107 doprint "KTEST RESULT: TEST $i SUCCESS!!!! **\n";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001108 doprint "*******************************************\n";
1109 doprint "*******************************************\n";
1110
Steven Rostedt576f6272010-11-02 14:58:38 -04001111 if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) {
Steven Rostedta75fece2010-11-02 14:58:27 -04001112 doprint "Reboot and wait $sleep_time seconds\n";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001113 reboot;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001114 start_monitor;
Steven Rostedta75fece2010-11-02 14:58:27 -04001115 wait_for_monitor $sleep_time;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001116 end_monitor;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001117 }
1118}
1119
1120sub get_version {
1121 # get the release name
1122 doprint "$make kernelrelease ... ";
1123 $version = `$make kernelrelease | tail -1`;
1124 chomp($version);
1125 doprint "$version\n";
1126}
1127
Steven Rostedtc960bb92011-03-08 09:22:39 -05001128sub answer_bisect {
1129 for (;;) {
1130 doprint "Pass or fail? [p/f]";
1131 my $ans = <STDIN>;
1132 chomp $ans;
1133 if ($ans eq "p" || $ans eq "P") {
1134 return 1;
1135 } elsif ($ans eq "f" || $ans eq "F") {
1136 return 0;
1137 } else {
1138 print "Please answer 'P' or 'F'\n";
1139 }
1140 }
1141}
1142
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001143sub child_run_test {
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001144 my $failed = 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001145
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001146 # child should have no power
Steven Rostedta75fece2010-11-02 14:58:27 -04001147 $reboot_on_error = 0;
1148 $poweroff_on_error = 0;
1149 $die_on_failure = 1;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001150
1151 run_command $run_test or $failed = 1;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001152 exit $failed;
1153}
1154
1155my $child_done;
1156
1157sub child_finished {
1158 $child_done = 1;
1159}
1160
1161sub do_run_test {
1162 my $child_pid;
1163 my $child_exit;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001164 my $line;
1165 my $full_line;
1166 my $bug = 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001167
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001168 wait_for_monitor 1;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001169
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001170 doprint "run test $run_test\n";
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001171
1172 $child_done = 0;
1173
1174 $SIG{CHLD} = qw(child_finished);
1175
1176 $child_pid = fork;
1177
1178 child_run_test if (!$child_pid);
1179
1180 $full_line = "";
1181
1182 do {
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001183 $line = wait_for_input($monitor_fp, 1);
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001184 if (defined($line)) {
1185
1186 # we are not guaranteed to get a full line
1187 $full_line .= $line;
Steven Rostedt8ea0e062011-03-08 09:44:35 -05001188 doprint $line;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001189
1190 if ($full_line =~ /call trace:/i) {
1191 $bug = 1;
1192 }
1193
1194 if ($full_line =~ /Kernel panic -/) {
1195 $bug = 1;
1196 }
1197
1198 if ($line =~ /\n/) {
1199 $full_line = "";
1200 }
1201 }
1202 } while (!$child_done && !$bug);
1203
1204 if ($bug) {
Steven Rostedt8ea0e062011-03-08 09:44:35 -05001205 my $failure_start = time;
1206 my $now;
1207 do {
1208 $line = wait_for_input($monitor_fp, 1);
1209 if (defined($line)) {
1210 doprint $line;
1211 }
1212 $now = time;
1213 if ($now - $failure_start >= $stop_after_failure) {
1214 last;
1215 }
1216 } while (defined($line));
1217
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001218 doprint "Detected kernel crash!\n";
1219 # kill the child with extreme prejudice
1220 kill 9, $child_pid;
1221 }
1222
1223 waitpid $child_pid, 0;
1224 $child_exit = $?;
1225
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001226 if ($bug || $child_exit) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001227 return 0 if $in_bisect;
1228 fail "test failed" and return 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001229 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001230 return 1;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001231}
1232
Steven Rostedta75fece2010-11-02 14:58:27 -04001233sub run_git_bisect {
1234 my ($command) = @_;
1235
1236 doprint "$command ... ";
1237
1238 my $output = `$command 2>&1`;
1239 my $ret = $?;
1240
1241 logit $output;
1242
1243 if ($ret) {
1244 doprint "FAILED\n";
1245 dodie "Failed to git bisect";
1246 }
1247
1248 doprint "SUCCESS\n";
1249 if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) {
1250 doprint "$1 [$2]\n";
1251 } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) {
1252 $bisect_bad = $1;
1253 doprint "Found bad commit... $1\n";
1254 return 0;
1255 } else {
1256 # we already logged it, just print it now.
1257 print $output;
1258 }
1259
1260 return 1;
1261}
1262
Steven Rostedtc23dca72011-03-08 09:26:31 -05001263sub bisect_reboot {
1264 doprint "Reboot and sleep $bisect_sleep_time seconds\n";
1265 reboot;
1266 start_monitor;
1267 wait_for_monitor $bisect_sleep_time;
1268 end_monitor;
1269}
1270
1271# returns 1 on success, 0 on failure, -1 on skip
Steven Rostedt0a05c762010-11-08 11:14:10 -05001272sub run_bisect_test {
1273 my ($type, $buildtype) = @_;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001274
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001275 my $failed = 0;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001276 my $result;
1277 my $output;
1278 my $ret;
1279
Steven Rostedt0a05c762010-11-08 11:14:10 -05001280 $in_bisect = 1;
1281
1282 build $buildtype or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001283
1284 if ($type ne "build") {
Steven Rostedtc23dca72011-03-08 09:26:31 -05001285 if ($failed && $bisect_skip) {
1286 $in_bisect = 0;
1287 return -1;
1288 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001289 dodie "Failed on build" if $failed;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001290
1291 # Now boot the box
1292 get_grub_index;
1293 get_version;
1294 install;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001295
1296 start_monitor;
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001297 monitor or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001298
1299 if ($type ne "boot") {
Steven Rostedtc23dca72011-03-08 09:26:31 -05001300 if ($failed && $bisect_skip) {
1301 end_monitor;
1302 bisect_reboot;
1303 $in_bisect = 0;
1304 return -1;
1305 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001306 dodie "Failed on boot" if $failed;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001307
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001308 do_run_test or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001309 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001310 end_monitor;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001311 }
1312
1313 if ($failed) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001314 $result = 0;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001315 } else {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001316 $result = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001317 }
Steven Rostedt4025bc62011-05-20 09:16:29 -04001318
1319 # reboot the box to a kernel we can ssh to
1320 if ($type ne "build") {
1321 bisect_reboot;
1322 }
Steven Rostedt0a05c762010-11-08 11:14:10 -05001323 $in_bisect = 0;
1324
1325 return $result;
1326}
1327
1328sub run_bisect {
1329 my ($type) = @_;
1330 my $buildtype = "oldconfig";
1331
1332 # We should have a minconfig to use?
1333 if (defined($minconfig)) {
1334 $buildtype = "useconfig:$minconfig";
1335 }
1336
1337 my $ret = run_bisect_test $type, $buildtype;
1338
Steven Rostedtc960bb92011-03-08 09:22:39 -05001339 if ($bisect_manual) {
1340 $ret = answer_bisect;
1341 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001342
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04001343 # Are we looking for where it worked, not failed?
1344 if ($reverse_bisect) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001345 $ret = !$ret;
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04001346 }
1347
Steven Rostedtc23dca72011-03-08 09:26:31 -05001348 if ($ret > 0) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001349 return "good";
Steven Rostedtc23dca72011-03-08 09:26:31 -05001350 } elsif ($ret == 0) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001351 return "bad";
Steven Rostedtc23dca72011-03-08 09:26:31 -05001352 } elsif ($bisect_skip) {
1353 doprint "HIT A BAD COMMIT ... SKIPPING\n";
1354 return "skip";
Steven Rostedt0a05c762010-11-08 11:14:10 -05001355 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001356}
1357
1358sub bisect {
1359 my ($i) = @_;
1360
1361 my $result;
1362
1363 die "BISECT_GOOD[$i] not defined\n" if (!defined($opt{"BISECT_GOOD[$i]"}));
1364 die "BISECT_BAD[$i] not defined\n" if (!defined($opt{"BISECT_BAD[$i]"}));
1365 die "BISECT_TYPE[$i] not defined\n" if (!defined($opt{"BISECT_TYPE[$i]"}));
1366
1367 my $good = $opt{"BISECT_GOOD[$i]"};
1368 my $bad = $opt{"BISECT_BAD[$i]"};
1369 my $type = $opt{"BISECT_TYPE[$i]"};
Steven Rostedta75fece2010-11-02 14:58:27 -04001370 my $start = $opt{"BISECT_START[$i]"};
1371 my $replay = $opt{"BISECT_REPLAY[$i]"};
Steven Rostedt3410f6f2011-03-08 09:38:12 -05001372 my $start_files = $opt{"BISECT_FILES[$i]"};
1373
1374 if (defined($start_files)) {
1375 $start_files = " -- " . $start_files;
1376 } else {
1377 $start_files = "";
1378 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001379
Steven Rostedta57419b2010-11-02 15:13:54 -04001380 # convert to true sha1's
1381 $good = get_sha1($good);
1382 $bad = get_sha1($bad);
1383
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04001384 if (defined($opt{"BISECT_REVERSE[$i]"}) &&
1385 $opt{"BISECT_REVERSE[$i]"} == 1) {
1386 doprint "Performing a reverse bisect (bad is good, good is bad!)\n";
1387 $reverse_bisect = 1;
1388 } else {
1389 $reverse_bisect = 0;
1390 }
1391
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001392 # Can't have a test without having a test to run
1393 if ($type eq "test" && !defined($run_test)) {
1394 $type = "boot";
1395 }
1396
Steven Rostedta75fece2010-11-02 14:58:27 -04001397 my $check = $opt{"BISECT_CHECK[$i]"};
1398 if (defined($check) && $check ne "0") {
1399
1400 # get current HEAD
Steven Rostedta57419b2010-11-02 15:13:54 -04001401 my $head = get_sha1("HEAD");
Steven Rostedta75fece2010-11-02 14:58:27 -04001402
1403 if ($check ne "good") {
1404 doprint "TESTING BISECT BAD [$bad]\n";
1405 run_command "git checkout $bad" or
1406 die "Failed to checkout $bad";
1407
1408 $result = run_bisect $type;
1409
1410 if ($result ne "bad") {
1411 fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0;
1412 }
1413 }
1414
1415 if ($check ne "bad") {
1416 doprint "TESTING BISECT GOOD [$good]\n";
1417 run_command "git checkout $good" or
1418 die "Failed to checkout $good";
1419
1420 $result = run_bisect $type;
1421
1422 if ($result ne "good") {
1423 fail "Tested BISECT_GOOD [$good] and it failed" and return 0;
1424 }
1425 }
1426
1427 # checkout where we started
1428 run_command "git checkout $head" or
1429 die "Failed to checkout $head";
1430 }
1431
Steven Rostedt3410f6f2011-03-08 09:38:12 -05001432 run_command "git bisect start$start_files" or
Steven Rostedta75fece2010-11-02 14:58:27 -04001433 dodie "could not start bisect";
1434
1435 run_command "git bisect good $good" or
1436 dodie "could not set bisect good to $good";
1437
1438 run_git_bisect "git bisect bad $bad" or
1439 dodie "could not set bisect bad to $bad";
1440
1441 if (defined($replay)) {
1442 run_command "git bisect replay $replay" or
1443 dodie "failed to run replay";
1444 }
1445
1446 if (defined($start)) {
1447 run_command "git checkout $start" or
1448 dodie "failed to checkout $start";
1449 }
1450
1451 my $test;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001452 do {
1453 $result = run_bisect $type;
Steven Rostedta75fece2010-11-02 14:58:27 -04001454 $test = run_git_bisect "git bisect $result";
1455 } while ($test);
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001456
1457 run_command "git bisect log" or
1458 dodie "could not capture git bisect log";
1459
1460 run_command "git bisect reset" or
1461 dodie "could not reset git bisect";
1462
1463 doprint "Bad commit was [$bisect_bad]\n";
1464
Steven Rostedt0a05c762010-11-08 11:14:10 -05001465 success $i;
1466}
1467
1468my %config_ignore;
1469my %config_set;
1470
1471my %config_list;
1472my %null_config;
1473
1474my %dependency;
1475
1476sub process_config_ignore {
1477 my ($config) = @_;
1478
1479 open (IN, $config)
1480 or dodie "Failed to read $config";
1481
1482 while (<IN>) {
1483 if (/^(.*?(CONFIG\S*)(=.*| is not set))/) {
1484 $config_ignore{$2} = $1;
1485 }
1486 }
1487
1488 close(IN);
1489}
1490
1491sub read_current_config {
1492 my ($config_ref) = @_;
1493
1494 %{$config_ref} = ();
1495 undef %{$config_ref};
1496
1497 my @key = keys %{$config_ref};
1498 if ($#key >= 0) {
1499 print "did not delete!\n";
1500 exit;
1501 }
1502 open (IN, "$output_config");
1503
1504 while (<IN>) {
1505 if (/^(CONFIG\S+)=(.*)/) {
1506 ${$config_ref}{$1} = $2;
1507 }
1508 }
1509 close(IN);
1510}
1511
1512sub get_dependencies {
1513 my ($config) = @_;
1514
1515 my $arr = $dependency{$config};
1516 if (!defined($arr)) {
1517 return ();
1518 }
1519
1520 my @deps = @{$arr};
1521
1522 foreach my $dep (@{$arr}) {
1523 print "ADD DEP $dep\n";
1524 @deps = (@deps, get_dependencies $dep);
1525 }
1526
1527 return @deps;
1528}
1529
1530sub create_config {
1531 my @configs = @_;
1532
1533 open(OUT, ">$output_config") or dodie "Can not write to $output_config";
1534
1535 foreach my $config (@configs) {
1536 print OUT "$config_set{$config}\n";
1537 my @deps = get_dependencies $config;
1538 foreach my $dep (@deps) {
1539 print OUT "$config_set{$dep}\n";
1540 }
1541 }
1542
1543 foreach my $config (keys %config_ignore) {
1544 print OUT "$config_ignore{$config}\n";
1545 }
1546 close(OUT);
1547
1548# exit;
Steven Rostedt612b9e92011-03-07 13:27:43 -05001549 make_oldconfig "";
Steven Rostedt0a05c762010-11-08 11:14:10 -05001550}
1551
1552sub compare_configs {
1553 my (%a, %b) = @_;
1554
1555 foreach my $item (keys %a) {
1556 if (!defined($b{$item})) {
1557 print "diff $item\n";
1558 return 1;
1559 }
1560 delete $b{$item};
1561 }
1562
1563 my @keys = keys %b;
1564 if ($#keys) {
1565 print "diff2 $keys[0]\n";
1566 }
1567 return -1 if ($#keys >= 0);
1568
1569 return 0;
1570}
1571
1572sub run_config_bisect_test {
1573 my ($type) = @_;
1574
1575 return run_bisect_test $type, "oldconfig";
1576}
1577
1578sub process_passed {
1579 my (%configs) = @_;
1580
1581 doprint "These configs had no failure: (Enabling them for further compiles)\n";
1582 # Passed! All these configs are part of a good compile.
1583 # Add them to the min options.
1584 foreach my $config (keys %configs) {
1585 if (defined($config_list{$config})) {
1586 doprint " removing $config\n";
1587 $config_ignore{$config} = $config_list{$config};
1588 delete $config_list{$config};
1589 }
1590 }
Steven Rostedtf1a27852010-11-11 11:34:38 -05001591 doprint "config copied to $outputdir/config_good\n";
1592 run_command "cp -f $output_config $outputdir/config_good";
Steven Rostedt0a05c762010-11-08 11:14:10 -05001593}
1594
1595sub process_failed {
1596 my ($config) = @_;
1597
1598 doprint "\n\n***************************************\n";
1599 doprint "Found bad config: $config\n";
1600 doprint "***************************************\n\n";
1601}
1602
1603sub run_config_bisect {
1604
1605 my @start_list = keys %config_list;
1606
1607 if ($#start_list < 0) {
1608 doprint "No more configs to test!!!\n";
1609 return -1;
1610 }
1611
1612 doprint "***** RUN TEST ***\n";
1613 my $type = $opt{"CONFIG_BISECT_TYPE[$iteration]"};
1614 my $ret;
1615 my %current_config;
1616
1617 my $count = $#start_list + 1;
1618 doprint " $count configs to test\n";
1619
1620 my $half = int($#start_list / 2);
1621
1622 do {
1623 my @tophalf = @start_list[0 .. $half];
1624
1625 create_config @tophalf;
1626 read_current_config \%current_config;
1627
1628 $count = $#tophalf + 1;
1629 doprint "Testing $count configs\n";
1630 my $found = 0;
1631 # make sure we test something
1632 foreach my $config (@tophalf) {
1633 if (defined($current_config{$config})) {
1634 logit " $config\n";
1635 $found = 1;
1636 }
1637 }
1638 if (!$found) {
1639 # try the other half
1640 doprint "Top half produced no set configs, trying bottom half\n";
1641 @tophalf = @start_list[$half .. $#start_list];
1642 create_config @tophalf;
1643 read_current_config \%current_config;
1644 foreach my $config (@tophalf) {
1645 if (defined($current_config{$config})) {
1646 logit " $config\n";
1647 $found = 1;
1648 }
1649 }
1650 if (!$found) {
1651 doprint "Failed: Can't make new config with current configs\n";
1652 foreach my $config (@start_list) {
1653 doprint " CONFIG: $config\n";
1654 }
1655 return -1;
1656 }
1657 $count = $#tophalf + 1;
1658 doprint "Testing $count configs\n";
1659 }
1660
1661 $ret = run_config_bisect_test $type;
Steven Rostedtc960bb92011-03-08 09:22:39 -05001662 if ($bisect_manual) {
1663 $ret = answer_bisect;
1664 }
Steven Rostedt0a05c762010-11-08 11:14:10 -05001665 if ($ret) {
1666 process_passed %current_config;
1667 return 0;
1668 }
1669
1670 doprint "This config had a failure.\n";
1671 doprint "Removing these configs that were not set in this config:\n";
Steven Rostedtf1a27852010-11-11 11:34:38 -05001672 doprint "config copied to $outputdir/config_bad\n";
1673 run_command "cp -f $output_config $outputdir/config_bad";
Steven Rostedt0a05c762010-11-08 11:14:10 -05001674
1675 # A config exists in this group that was bad.
1676 foreach my $config (keys %config_list) {
1677 if (!defined($current_config{$config})) {
1678 doprint " removing $config\n";
1679 delete $config_list{$config};
1680 }
1681 }
1682
1683 @start_list = @tophalf;
1684
1685 if ($#start_list == 0) {
1686 process_failed $start_list[0];
1687 return 1;
1688 }
1689
1690 # remove half the configs we are looking at and see if
1691 # they are good.
1692 $half = int($#start_list / 2);
1693 } while ($half > 0);
1694
Steven Rostedtc960bb92011-03-08 09:22:39 -05001695 # we found a single config, try it again unless we are running manually
1696
1697 if ($bisect_manual) {
1698 process_failed $start_list[0];
1699 return 1;
1700 }
1701
Steven Rostedt0a05c762010-11-08 11:14:10 -05001702 my @tophalf = @start_list[0 .. 0];
1703
1704 $ret = run_config_bisect_test $type;
1705 if ($ret) {
1706 process_passed %current_config;
1707 return 0;
1708 }
1709
1710 process_failed $start_list[0];
1711 return 1;
1712}
1713
1714sub config_bisect {
1715 my ($i) = @_;
1716
1717 my $start_config = $opt{"CONFIG_BISECT[$i]"};
1718
1719 my $tmpconfig = "$tmpdir/use_config";
1720
1721 # Make the file with the bad config and the min config
1722 if (defined($minconfig)) {
1723 # read the min config for things to ignore
1724 run_command "cp $minconfig $tmpconfig" or
1725 dodie "failed to copy $minconfig to $tmpconfig";
1726 } else {
1727 unlink $tmpconfig;
1728 }
1729
1730 # Add other configs
1731 if (defined($addconfig)) {
1732 run_command "cat $addconfig >> $tmpconfig" or
1733 dodie "failed to append $addconfig";
1734 }
1735
1736 my $defconfig = "";
1737 if (-f $tmpconfig) {
1738 $defconfig = "KCONFIG_ALLCONFIG=$tmpconfig";
1739 process_config_ignore $tmpconfig;
1740 }
1741
1742 # now process the start config
1743 run_command "cp $start_config $output_config" or
1744 dodie "failed to copy $start_config to $output_config";
1745
1746 # read directly what we want to check
1747 my %config_check;
1748 open (IN, $output_config)
1749 or dodie "faied to open $output_config";
1750
1751 while (<IN>) {
1752 if (/^((CONFIG\S*)=.*)/) {
1753 $config_check{$2} = $1;
1754 }
1755 }
1756 close(IN);
1757
1758 # Now run oldconfig with the minconfig (and addconfigs)
Steven Rostedt612b9e92011-03-07 13:27:43 -05001759 make_oldconfig $defconfig;
Steven Rostedt0a05c762010-11-08 11:14:10 -05001760
1761 # check to see what we lost (or gained)
1762 open (IN, $output_config)
1763 or dodie "Failed to read $start_config";
1764
1765 my %removed_configs;
1766 my %added_configs;
1767
1768 while (<IN>) {
1769 if (/^((CONFIG\S*)=.*)/) {
1770 # save off all options
1771 $config_set{$2} = $1;
1772 if (defined($config_check{$2})) {
1773 if (defined($config_ignore{$2})) {
1774 $removed_configs{$2} = $1;
1775 } else {
1776 $config_list{$2} = $1;
1777 }
1778 } elsif (!defined($config_ignore{$2})) {
1779 $added_configs{$2} = $1;
1780 $config_list{$2} = $1;
1781 }
1782 }
1783 }
1784 close(IN);
1785
1786 my @confs = keys %removed_configs;
1787 if ($#confs >= 0) {
1788 doprint "Configs overridden by default configs and removed from check:\n";
1789 foreach my $config (@confs) {
1790 doprint " $config\n";
1791 }
1792 }
1793 @confs = keys %added_configs;
1794 if ($#confs >= 0) {
1795 doprint "Configs appearing in make oldconfig and added:\n";
1796 foreach my $config (@confs) {
1797 doprint " $config\n";
1798 }
1799 }
1800
1801 my %config_test;
1802 my $once = 0;
1803
1804 # Sometimes kconfig does weird things. We must make sure
1805 # that the config we autocreate has everything we need
1806 # to test, otherwise we may miss testing configs, or
1807 # may not be able to create a new config.
1808 # Here we create a config with everything set.
1809 create_config (keys %config_list);
1810 read_current_config \%config_test;
1811 foreach my $config (keys %config_list) {
1812 if (!defined($config_test{$config})) {
1813 if (!$once) {
1814 $once = 1;
1815 doprint "Configs not produced by kconfig (will not be checked):\n";
1816 }
1817 doprint " $config\n";
1818 delete $config_list{$config};
1819 }
1820 }
1821 my $ret;
1822 do {
1823 $ret = run_config_bisect;
1824 } while (!$ret);
1825
1826 return $ret if ($ret < 0);
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001827
1828 success $i;
1829}
1830
Steven Rostedt27d934b2011-05-20 09:18:18 -04001831sub patchcheck_reboot {
1832 doprint "Reboot and sleep $patchcheck_sleep_time seconds\n";
1833 reboot;
1834 start_monitor;
1835 wait_for_monitor $patchcheck_sleep_time;
1836 end_monitor;
1837}
1838
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001839sub patchcheck {
1840 my ($i) = @_;
1841
1842 die "PATCHCHECK_START[$i] not defined\n"
1843 if (!defined($opt{"PATCHCHECK_START[$i]"}));
1844 die "PATCHCHECK_TYPE[$i] not defined\n"
1845 if (!defined($opt{"PATCHCHECK_TYPE[$i]"}));
1846
1847 my $start = $opt{"PATCHCHECK_START[$i]"};
1848
1849 my $end = "HEAD";
1850 if (defined($opt{"PATCHCHECK_END[$i]"})) {
1851 $end = $opt{"PATCHCHECK_END[$i]"};
1852 }
1853
Steven Rostedta57419b2010-11-02 15:13:54 -04001854 # Get the true sha1's since we can use things like HEAD~3
1855 $start = get_sha1($start);
1856 $end = get_sha1($end);
1857
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001858 my $type = $opt{"PATCHCHECK_TYPE[$i]"};
1859
1860 # Can't have a test without having a test to run
1861 if ($type eq "test" && !defined($run_test)) {
1862 $type = "boot";
1863 }
1864
1865 open (IN, "git log --pretty=oneline $end|") or
1866 dodie "could not get git list";
1867
1868 my @list;
1869
1870 while (<IN>) {
1871 chomp;
1872 $list[$#list+1] = $_;
1873 last if (/^$start/);
1874 }
1875 close(IN);
1876
1877 if ($list[$#list] !~ /^$start/) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001878 fail "SHA1 $start not found";
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001879 }
1880
1881 # go backwards in the list
1882 @list = reverse @list;
1883
1884 my $save_clean = $noclean;
1885
1886 $in_patchcheck = 1;
1887 foreach my $item (@list) {
1888 my $sha1 = $item;
1889 $sha1 =~ s/^([[:xdigit:]]+).*/$1/;
1890
1891 doprint "\nProcessing commit $item\n\n";
1892
1893 run_command "git checkout $sha1" or
1894 die "Failed to checkout $sha1";
1895
1896 # only clean on the first and last patch
1897 if ($item eq $list[0] ||
1898 $item eq $list[$#list]) {
1899 $noclean = $save_clean;
1900 } else {
1901 $noclean = 1;
1902 }
1903
1904 if (defined($minconfig)) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001905 build "useconfig:$minconfig" or return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001906 } else {
1907 # ?? no config to use?
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001908 build "oldconfig" or return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001909 }
1910
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001911 check_buildlog $sha1 or return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001912
1913 next if ($type eq "build");
1914
1915 get_grub_index;
1916 get_version;
1917 install;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001918
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001919 my $failed = 0;
1920
1921 start_monitor;
1922 monitor or $failed = 1;
1923
1924 if (!$failed && $type ne "boot"){
1925 do_run_test or $failed = 1;
1926 }
1927 end_monitor;
1928 return 0 if ($failed);
1929
Steven Rostedt27d934b2011-05-20 09:18:18 -04001930 patchcheck_reboot;
1931
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001932 }
1933 $in_patchcheck = 0;
1934 success $i;
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001935
1936 return 1;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001937}
1938
Steven Rostedt8d1491b2010-11-18 15:39:48 -05001939$#ARGV < 1 or die "ktest.pl version: $VERSION\n usage: ktest.pl config-file\n";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001940
Steven Rostedt8d1491b2010-11-18 15:39:48 -05001941if ($#ARGV == 0) {
1942 $ktest_config = $ARGV[0];
1943 if (! -f $ktest_config) {
1944 print "$ktest_config does not exist.\n";
1945 my $ans;
1946 for (;;) {
1947 print "Create it? [Y/n] ";
1948 $ans = <STDIN>;
1949 chomp $ans;
1950 if ($ans =~ /^\s*$/) {
1951 $ans = "y";
1952 }
1953 last if ($ans =~ /^y$/i || $ans =~ /^n$/i);
1954 print "Please answer either 'y' or 'n'.\n";
1955 }
1956 if ($ans !~ /^y$/i) {
1957 exit 0;
1958 }
1959 }
1960} else {
1961 $ktest_config = "ktest.conf";
1962}
1963
1964if (! -f $ktest_config) {
1965 open(OUT, ">$ktest_config") or die "Can not create $ktest_config";
1966 print OUT << "EOF"
1967# Generated by ktest.pl
1968#
1969# Define each test with TEST_START
1970# The config options below it will override the defaults
1971TEST_START
1972
1973DEFAULTS
1974EOF
1975;
1976 close(OUT);
1977}
1978read_config $ktest_config;
1979
1980# Append any configs entered in manually to the config file.
1981my @new_configs = keys %entered_configs;
1982if ($#new_configs >= 0) {
1983 print "\nAppending entered in configs to $ktest_config\n";
1984 open(OUT, ">>$ktest_config") or die "Can not append to $ktest_config";
1985 foreach my $config (@new_configs) {
1986 print OUT "$config = $entered_configs{$config}\n";
1987 $opt{$config} = $entered_configs{$config};
1988 }
1989}
Steven Rostedt2545eb62010-11-02 15:01:32 -04001990
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001991if ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) {
1992 unlink $opt{"LOG_FILE"};
1993}
Steven Rostedt2545eb62010-11-02 15:01:32 -04001994
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001995doprint "\n\nSTARTING AUTOMATED TESTS\n\n";
1996
Steven Rostedta57419b2010-11-02 15:13:54 -04001997for (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) {
1998
1999 if (!$i) {
2000 doprint "DEFAULT OPTIONS:\n";
2001 } else {
2002 doprint "\nTEST $i OPTIONS";
2003 if (defined($repeat_tests{$i})) {
2004 $repeat = $repeat_tests{$i};
2005 doprint " ITERATE $repeat";
2006 }
2007 doprint "\n";
2008 }
2009
2010 foreach my $option (sort keys %opt) {
2011
2012 if ($option =~ /\[(\d+)\]$/) {
2013 next if ($i != $1);
2014 } else {
2015 next if ($i);
2016 }
2017
2018 doprint "$option = $opt{$option}\n";
2019 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002020}
Steven Rostedt2545eb62010-11-02 15:01:32 -04002021
Steven Rostedt2a625122011-05-20 15:48:59 -04002022sub __set_test_option {
Steven Rostedt5a391fb2010-11-02 14:57:43 -04002023 my ($name, $i) = @_;
2024
2025 my $option = "$name\[$i\]";
2026
2027 if (defined($opt{$option})) {
2028 return $opt{$option};
2029 }
2030
Steven Rostedta57419b2010-11-02 15:13:54 -04002031 foreach my $test (keys %repeat_tests) {
2032 if ($i >= $test &&
2033 $i < $test + $repeat_tests{$test}) {
2034 $option = "$name\[$test\]";
2035 if (defined($opt{$option})) {
2036 return $opt{$option};
2037 }
2038 }
2039 }
2040
Steven Rostedt5a391fb2010-11-02 14:57:43 -04002041 if (defined($opt{$name})) {
2042 return $opt{$name};
2043 }
2044
2045 return undef;
2046}
2047
Steven Rostedt2a625122011-05-20 15:48:59 -04002048sub eval_option {
2049 my ($option, $i) = @_;
2050
2051 # Add space to evaluate the character before $
2052 $option = " $option";
2053 my $retval = "";
2054
2055 while ($option =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
2056 my $start = $1;
2057 my $var = $2;
2058 my $end = $3;
2059
2060 # Append beginning of line
2061 $retval = "$retval$start";
2062
2063 # If the iteration option OPT[$i] exists, then use that.
2064 # otherwise see if the default OPT (without [$i]) exists.
2065
2066 my $o = "$var\[$i\]";
2067
2068 if (defined($opt{$o})) {
2069 $o = $opt{$o};
2070 $retval = "$retval$o";
2071 } elsif (defined($opt{$var})) {
2072 $o = $opt{$var};
2073 $retval = "$retval$o";
2074 } else {
2075 $retval = "$retval\$\{$var\}";
2076 }
2077
2078 $option = $end;
2079 }
2080
2081 $retval = "$retval$option";
2082
2083 $retval =~ s/^ //;
2084
2085 return $retval;
2086}
2087
2088sub set_test_option {
2089 my ($name, $i) = @_;
2090
2091 my $option = __set_test_option($name, $i);
2092 return $option if (!defined($option));
2093
2094 my $prev = "";
2095
2096 # Since an option can evaluate to another option,
2097 # keep iterating until we do not evaluate any more
2098 # options.
2099 my $r = 0;
2100 while ($prev ne $option) {
2101 # Check for recursive evaluations.
2102 # 100 deep should be more than enough.
2103 if ($r++ > 100) {
2104 die "Over 100 evaluations accurred with $name\n" .
2105 "Check for recursive variables\n";
2106 }
2107 $prev = $option;
2108 $option = eval_option($option, $i);
2109 }
2110
2111 return $option;
2112}
2113
Steven Rostedt2545eb62010-11-02 15:01:32 -04002114# First we need to do is the builds
Steven Rostedta75fece2010-11-02 14:58:27 -04002115for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
Steven Rostedt2545eb62010-11-02 15:01:32 -04002116
Steven Rostedt576f6272010-11-02 14:58:38 -04002117 $iteration = $i;
2118
Steven Rostedta75fece2010-11-02 14:58:27 -04002119 my $makecmd = set_test_option("MAKE_CMD", $i);
2120
2121 $machine = set_test_option("MACHINE", $i);
Steven Rostedte48c5292010-11-02 14:35:37 -04002122 $ssh_user = set_test_option("SSH_USER", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002123 $tmpdir = set_test_option("TMP_DIR", $i);
2124 $outputdir = set_test_option("OUTPUT_DIR", $i);
2125 $builddir = set_test_option("BUILD_DIR", $i);
2126 $test_type = set_test_option("TEST_TYPE", $i);
2127 $build_type = set_test_option("BUILD_TYPE", $i);
2128 $build_options = set_test_option("BUILD_OPTIONS", $i);
2129 $power_cycle = set_test_option("POWER_CYCLE", $i);
Steven Rostedte48c5292010-11-02 14:35:37 -04002130 $reboot = set_test_option("REBOOT", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002131 $noclean = set_test_option("BUILD_NOCLEAN", $i);
2132 $minconfig = set_test_option("MIN_CONFIG", $i);
2133 $run_test = set_test_option("TEST", $i);
2134 $addconfig = set_test_option("ADD_CONFIG", $i);
2135 $reboot_type = set_test_option("REBOOT_TYPE", $i);
2136 $grub_menu = set_test_option("GRUB_MENU", $i);
Steven Rostedt8b37ca82010-11-02 14:58:33 -04002137 $post_install = set_test_option("POST_INSTALL", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002138 $reboot_script = set_test_option("REBOOT_SCRIPT", $i);
2139 $reboot_on_error = set_test_option("REBOOT_ON_ERROR", $i);
2140 $poweroff_on_error = set_test_option("POWEROFF_ON_ERROR", $i);
2141 $die_on_failure = set_test_option("DIE_ON_FAILURE", $i);
2142 $power_off = set_test_option("POWER_OFF", $i);
Steven Rostedt576f6272010-11-02 14:58:38 -04002143 $powercycle_after_reboot = set_test_option("POWERCYCLE_AFTER_REBOOT", $i);
2144 $poweroff_after_halt = set_test_option("POWEROFF_AFTER_HALT", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002145 $sleep_time = set_test_option("SLEEP_TIME", $i);
2146 $bisect_sleep_time = set_test_option("BISECT_SLEEP_TIME", $i);
Steven Rostedt27d934b2011-05-20 09:18:18 -04002147 $patchcheck_sleep_time = set_test_option("PATCHCHECK_SLEEP_TIME", $i);
Steven Rostedtc960bb92011-03-08 09:22:39 -05002148 $bisect_manual = set_test_option("BISECT_MANUAL", $i);
Steven Rostedtc23dca72011-03-08 09:26:31 -05002149 $bisect_skip = set_test_option("BISECT_SKIP", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002150 $store_failures = set_test_option("STORE_FAILURES", $i);
2151 $timeout = set_test_option("TIMEOUT", $i);
2152 $booted_timeout = set_test_option("BOOTED_TIMEOUT", $i);
2153 $console = set_test_option("CONSOLE", $i);
2154 $success_line = set_test_option("SUCCESS_LINE", $i);
Steven Rostedt1c8a6172010-11-09 12:55:40 -05002155 $stop_after_success = set_test_option("STOP_AFTER_SUCCESS", $i);
2156 $stop_after_failure = set_test_option("STOP_AFTER_FAILURE", $i);
Steven Rostedt2d01b262011-03-08 09:47:54 -05002157 $stop_test_after = set_test_option("STOP_TEST_AFTER", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002158 $build_target = set_test_option("BUILD_TARGET", $i);
Steven Rostedte48c5292010-11-02 14:35:37 -04002159 $ssh_exec = set_test_option("SSH_EXEC", $i);
2160 $scp_to_target = set_test_option("SCP_TO_TARGET", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002161 $target_image = set_test_option("TARGET_IMAGE", $i);
2162 $localversion = set_test_option("LOCALVERSION", $i);
2163
2164 chdir $builddir || die "can't change directory to $builddir";
2165
2166 if (!-d $tmpdir) {
2167 mkpath($tmpdir) or
2168 die "can't create $tmpdir";
2169 }
2170
Steven Rostedte48c5292010-11-02 14:35:37 -04002171 $ENV{"SSH_USER"} = $ssh_user;
2172 $ENV{"MACHINE"} = $machine;
2173
Steven Rostedta75fece2010-11-02 14:58:27 -04002174 $target = "$ssh_user\@$machine";
2175
2176 $buildlog = "$tmpdir/buildlog-$machine";
2177 $dmesg = "$tmpdir/dmesg-$machine";
2178 $make = "$makecmd O=$outputdir";
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05002179 $output_config = "$outputdir/.config";
Steven Rostedta75fece2010-11-02 14:58:27 -04002180
2181 if ($reboot_type eq "grub") {
Steven Rostedt576f6272010-11-02 14:58:38 -04002182 dodie "GRUB_MENU not defined" if (!defined($grub_menu));
Steven Rostedta75fece2010-11-02 14:58:27 -04002183 } elsif (!defined($reboot_script)) {
Steven Rostedt576f6272010-11-02 14:58:38 -04002184 dodie "REBOOT_SCRIPT not defined"
Steven Rostedta75fece2010-11-02 14:58:27 -04002185 }
2186
2187 my $run_type = $build_type;
2188 if ($test_type eq "patchcheck") {
2189 $run_type = $opt{"PATCHCHECK_TYPE[$i]"};
2190 } elsif ($test_type eq "bisect") {
2191 $run_type = $opt{"BISECT_TYPE[$i]"};
Steven Rostedt0a05c762010-11-08 11:14:10 -05002192 } elsif ($test_type eq "config_bisect") {
2193 $run_type = $opt{"CONFIG_BISECT_TYPE[$i]"};
Steven Rostedta75fece2010-11-02 14:58:27 -04002194 }
2195
2196 # mistake in config file?
2197 if (!defined($run_type)) {
2198 $run_type = "ERROR";
2199 }
Steven Rostedt2545eb62010-11-02 15:01:32 -04002200
2201 doprint "\n\n";
Steven Rostedta75fece2010-11-02 14:58:27 -04002202 doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type\n\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -04002203
2204 unlink $dmesg;
2205 unlink $buildlog;
Steven Rostedt2545eb62010-11-02 15:01:32 -04002206
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002207 if (!defined($minconfig)) {
2208 $minconfig = $addconfig;
2209
2210 } elsif (defined($addconfig)) {
Steven Rostedt9be2e6b2010-11-09 12:20:21 -05002211 run_command "cat $addconfig $minconfig > $tmpdir/add_config" or
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002212 dodie "Failed to create temp config";
Steven Rostedt9be2e6b2010-11-09 12:20:21 -05002213 $minconfig = "$tmpdir/add_config";
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002214 }
2215
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002216 my $checkout = $opt{"CHECKOUT[$i]"};
2217 if (defined($checkout)) {
2218 run_command "git checkout $checkout" or
2219 die "failed to checkout $checkout";
2220 }
2221
Steven Rostedta75fece2010-11-02 14:58:27 -04002222 if ($test_type eq "bisect") {
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04002223 bisect $i;
2224 next;
Steven Rostedt0a05c762010-11-08 11:14:10 -05002225 } elsif ($test_type eq "config_bisect") {
2226 config_bisect $i;
2227 next;
Steven Rostedta75fece2010-11-02 14:58:27 -04002228 } elsif ($test_type eq "patchcheck") {
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002229 patchcheck $i;
2230 next;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04002231 }
2232
Steven Rostedt7faafbd2010-11-02 14:58:22 -04002233 if ($build_type ne "nobuild") {
2234 build $build_type or next;
Steven Rostedt2545eb62010-11-02 15:01:32 -04002235 }
2236
Steven Rostedta75fece2010-11-02 14:58:27 -04002237 if ($test_type ne "build") {
2238 get_grub_index;
2239 get_version;
2240 install;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04002241
Steven Rostedta75fece2010-11-02 14:58:27 -04002242 my $failed = 0;
2243 start_monitor;
2244 monitor or $failed = 1;;
2245
2246 if (!$failed && $test_type ne "boot" && defined($run_test)) {
2247 do_run_test or $failed = 1;
2248 }
2249 end_monitor;
2250 next if ($failed);
Steven Rostedt5a391fb2010-11-02 14:57:43 -04002251 }
2252
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04002253 success $i;
Steven Rostedt2545eb62010-11-02 15:01:32 -04002254}
2255
Steven Rostedt5c42fc52010-11-02 14:57:01 -04002256if ($opt{"POWEROFF_ON_SUCCESS"}) {
Steven Rostedt75c3fda72010-11-02 14:57:21 -04002257 halt;
Steven Rostedt576f6272010-11-02 14:58:38 -04002258} elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot) {
Steven Rostedt75c3fda72010-11-02 14:57:21 -04002259 reboot;
Steven Rostedt5c42fc52010-11-02 14:57:01 -04002260}
Steven Rostedt75c3fda72010-11-02 14:57:21 -04002261
Steven Rostedte48c5292010-11-02 14:35:37 -04002262doprint "\n $successes of $opt{NUM_TESTS} tests were successful\n\n";
2263
Steven Rostedt2545eb62010-11-02 15:01:32 -04002264exit 0;