blob: ef978171ecb72f5d217ae9eadc6628b676dfbef7 [file] [log] [blame]
Steven Rostedt2545eb62010-11-02 15:01:32 -04001#!/usr/bin/perl -w
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04002#
3# Copywrite 2010 - Steven Rostedt <srostedt@redhat.com>, Red Hat Inc.
4# 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
14$#ARGV >= 0 || die "usage: autotest.pl config-file\n";
15
16$| = 1;
17
18my %opt;
Steven Rostedta75fece2010-11-02 14:58:27 -040019my %default;
Steven Rostedt2545eb62010-11-02 15:01:32 -040020
21#default opts
Steven Rostedta75fece2010-11-02 14:58:27 -040022$default{"NUM_TESTS"} = 5;
23$default{"REBOOT_TYPE"} = "grub";
24$default{"TEST_TYPE"} = "test";
25$default{"BUILD_TYPE"} = "randconfig";
26$default{"MAKE_CMD"} = "make";
27$default{"TIMEOUT"} = 120;
28$default{"TMP_DIR"} = "/tmp/autotest";
29$default{"SLEEP_TIME"} = 60; # sleep time between tests
30$default{"BUILD_NOCLEAN"} = 0;
31$default{"REBOOT_ON_ERROR"} = 0;
32$default{"POWEROFF_ON_ERROR"} = 0;
33$default{"REBOOT_ON_SUCCESS"} = 1;
34$default{"POWEROFF_ON_SUCCESS"} = 0;
35$default{"BUILD_OPTIONS"} = "";
36$default{"BISECT_SLEEP_TIME"} = 60; # sleep time between bisects
37$default{"CLEAR_LOG"} = 0;
38$default{"SUCCESS_LINE"} = "login:";
39$default{"BOOTED_TIMEOUT"} = 1;
40$default{"DIE_ON_FAILURE"} = 1;
Steven Rostedt2545eb62010-11-02 15:01:32 -040041
42my $version;
Steven Rostedta75fece2010-11-02 14:58:27 -040043my $machine;
44my $tmpdir;
45my $builddir;
46my $outputdir;
47my $test_type;
Steven Rostedt7faafbd2010-11-02 14:58:22 -040048my $build_type;
Steven Rostedta75fece2010-11-02 14:58:27 -040049my $build_options;
50my $reboot_type;
51my $reboot_script;
52my $power_cycle;
53my $reboot_on_error;
54my $poweroff_on_error;
55my $die_on_failure;
Steven Rostedt576f6272010-11-02 14:58:38 -040056my $powercycle_after_reboot;
57my $poweroff_after_halt;
Steven Rostedta75fece2010-11-02 14:58:27 -040058my $power_off;
59my $grub_menu;
Steven Rostedt2545eb62010-11-02 15:01:32 -040060my $grub_number;
61my $target;
62my $make;
Steven Rostedt8b37ca82010-11-02 14:58:33 -040063my $post_install;
Steven Rostedt5c42fc52010-11-02 14:57:01 -040064my $noclean;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -040065my $minconfig;
Steven Rostedt2b7d9b22010-11-02 14:58:15 -040066my $addconfig;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -040067my $in_bisect = 0;
68my $bisect_bad = "";
Steven Rostedtd6ce2a02010-11-02 14:58:05 -040069my $reverse_bisect;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -040070my $in_patchcheck = 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -040071my $run_test;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -040072my $redirect;
Steven Rostedt7faafbd2010-11-02 14:58:22 -040073my $buildlog;
74my $dmesg;
75my $monitor_fp;
76my $monitor_pid;
77my $monitor_cnt = 0;
Steven Rostedta75fece2010-11-02 14:58:27 -040078my $sleep_time;
79my $bisect_sleep_time;
80my $store_failures;
81my $timeout;
82my $booted_timeout;
83my $console;
84my $success_line;
85my $build_target;
86my $target_image;
87my $localversion;
Steven Rostedt576f6272010-11-02 14:58:38 -040088my $iteration = 0;
Steven Rostedt2545eb62010-11-02 15:01:32 -040089
90sub read_config {
91 my ($config) = @_;
92
93 open(IN, $config) || die "can't read file $config";
94
95 while (<IN>) {
96
97 # ignore blank lines and comments
98 next if (/^\s*$/ || /\s*\#/);
99
100 if (/^\s*(\S+)\s*=\s*(.*?)\s*$/) {
101 my $lvalue = $1;
102 my $rvalue = $2;
103
Steven Rostedta75fece2010-11-02 14:58:27 -0400104 if (defined($opt{$lvalue})) {
105 die "Error: Option $lvalue defined more than once!\n";
106 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400107 $opt{$lvalue} = $rvalue;
108 }
109 }
110
111 close(IN);
Steven Rostedta75fece2010-11-02 14:58:27 -0400112
113 # set any defaults
114
115 foreach my $default (keys %default) {
116 if (!defined($opt{$default})) {
117 $opt{$default} = $default{$default};
118 }
119 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400120}
121
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400122sub logit {
Steven Rostedt2545eb62010-11-02 15:01:32 -0400123 if (defined($opt{"LOG_FILE"})) {
124 open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}";
125 print OUT @_;
126 close(OUT);
127 }
128}
129
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400130sub doprint {
131 print @_;
132 logit @_;
133}
134
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400135sub run_command;
136
137sub reboot {
138 # try to reboot normally
Steven Rostedt576f6272010-11-02 14:58:38 -0400139 if (run_command "ssh $target reboot") {
140 if (defined($powercycle_after_reboot)) {
141 sleep $powercycle_after_reboot;
142 run_command "$power_cycle";
143 }
144 } else {
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400145 # nope? power cycle it.
Steven Rostedta75fece2010-11-02 14:58:27 -0400146 run_command "$power_cycle";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400147 }
148}
149
Steven Rostedt576f6272010-11-02 14:58:38 -0400150sub do_not_reboot {
151 my $i = $iteration;
152
153 return $test_type eq "build" ||
154 ($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") ||
155 ($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build");
156}
157
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400158sub dodie {
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400159 doprint "CRITICAL FAILURE... ", @_, "\n";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400160
Steven Rostedt576f6272010-11-02 14:58:38 -0400161 my $i = $iteration;
162
163 if ($reboot_on_error && !do_not_reboot) {
164
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400165 doprint "REBOOTING\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400166 reboot;
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400167
Steven Rostedta75fece2010-11-02 14:58:27 -0400168 } elsif ($poweroff_on_error && defined($power_off)) {
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400169 doprint "POWERING OFF\n";
Steven Rostedta75fece2010-11-02 14:58:27 -0400170 `$power_off`;
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400171 }
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400172
Steven Rostedt576f6272010-11-02 14:58:38 -0400173 die @_, "\n";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400174}
175
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400176sub open_console {
177 my ($fp) = @_;
178
179 my $flags;
180
Steven Rostedta75fece2010-11-02 14:58:27 -0400181 my $pid = open($fp, "$console|") or
182 dodie "Can't open console $console";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400183
184 $flags = fcntl($fp, F_GETFL, 0) or
Steven Rostedt576f6272010-11-02 14:58:38 -0400185 dodie "Can't get flags for the socket: $!";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400186 $flags = fcntl($fp, F_SETFL, $flags | O_NONBLOCK) or
Steven Rostedt576f6272010-11-02 14:58:38 -0400187 dodie "Can't set flags for the socket: $!";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400188
189 return $pid;
190}
191
192sub close_console {
193 my ($fp, $pid) = @_;
194
195 doprint "kill child process $pid\n";
196 kill 2, $pid;
197
198 print "closing!\n";
199 close($fp);
200}
201
202sub start_monitor {
203 if ($monitor_cnt++) {
204 return;
205 }
206 $monitor_fp = \*MONFD;
207 $monitor_pid = open_console $monitor_fp;
Steven Rostedta75fece2010-11-02 14:58:27 -0400208
209 return;
210
211 open(MONFD, "Stop perl from warning about single use of MONFD");
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400212}
213
214sub end_monitor {
215 if (--$monitor_cnt) {
216 return;
217 }
218 close_console($monitor_fp, $monitor_pid);
219}
220
221sub wait_for_monitor {
222 my ($time) = @_;
223 my $line;
224
Steven Rostedta75fece2010-11-02 14:58:27 -0400225 doprint "** Wait for monitor to settle down **\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400226
227 # read the monitor and wait for the system to calm down
228 do {
229 $line = wait_for_input($monitor_fp, $time);
Steven Rostedta75fece2010-11-02 14:58:27 -0400230 print "$line" if (defined($line));
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400231 } while (defined($line));
Steven Rostedta75fece2010-11-02 14:58:27 -0400232 print "** Monitor flushed **\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400233}
234
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400235sub fail {
236
Steven Rostedta75fece2010-11-02 14:58:27 -0400237 if ($die_on_failure) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400238 dodie @_;
239 }
240
Steven Rostedta75fece2010-11-02 14:58:27 -0400241 doprint "FAILED\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400242
Steven Rostedt576f6272010-11-02 14:58:38 -0400243 my $i = $iteration;
244
Steven Rostedta75fece2010-11-02 14:58:27 -0400245 # no need to reboot for just building.
Steven Rostedt576f6272010-11-02 14:58:38 -0400246 if (!do_not_reboot) {
Steven Rostedta75fece2010-11-02 14:58:27 -0400247 doprint "REBOOTING\n";
248 reboot;
249 start_monitor;
250 wait_for_monitor $sleep_time;
251 end_monitor;
252 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400253
Steven Rostedt576f6272010-11-02 14:58:38 -0400254 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
255 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
Steven Rostedta75fece2010-11-02 14:58:27 -0400256 doprint "**** Failed: ", @_, " ****\n";
Steven Rostedt576f6272010-11-02 14:58:38 -0400257 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
258 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
Steven Rostedta75fece2010-11-02 14:58:27 -0400259
260 return 1 if (!defined($store_failures));
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400261
262 my @t = localtime;
263 my $date = sprintf "%04d%02d%02d%02d%02d%02d",
264 1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0];
265
Steven Rostedta75fece2010-11-02 14:58:27 -0400266 my $dir = "$machine-$test_type-$build_type-fail-$date";
267 my $faildir = "$store_failures/$dir";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400268
269 if (!-d $faildir) {
270 mkpath($faildir) or
Steven Rostedta75fece2010-11-02 14:58:27 -0400271 die "can't create $faildir";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400272 }
Steven Rostedta75fece2010-11-02 14:58:27 -0400273 if (-f "$outputdir/.config") {
274 cp "$outputdir/.config", "$faildir/config" or
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400275 die "failed to copy .config";
276 }
277 if (-f $buildlog) {
278 cp $buildlog, "$faildir/buildlog" or
279 die "failed to move $buildlog";
280 }
281 if (-f $dmesg) {
282 cp $dmesg, "$faildir/dmesg" or
283 die "failed to move $dmesg";
284 }
285
286 doprint "*** Saved info to $faildir ***\n";
287
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400288 return 1;
289}
290
Steven Rostedt2545eb62010-11-02 15:01:32 -0400291sub run_command {
292 my ($command) = @_;
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400293 my $dolog = 0;
294 my $dord = 0;
295 my $pid;
296
297 doprint("$command ... ");
298
299 $pid = open(CMD, "$command 2>&1 |") or
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400300 (fail "unable to exec $command" and return 0);
Steven Rostedt2545eb62010-11-02 15:01:32 -0400301
302 if (defined($opt{"LOG_FILE"})) {
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400303 open(LOG, ">>$opt{LOG_FILE}") or
304 dodie "failed to write to log";
305 $dolog = 1;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400306 }
307
308 if (defined($redirect)) {
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400309 open (RD, ">$redirect") or
310 dodie "failed to write to redirect $redirect";
311 $dord = 1;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400312 }
313
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400314 while (<CMD>) {
315 print LOG if ($dolog);
316 print RD if ($dord);
317 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400318
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400319 waitpid($pid, 0);
Steven Rostedt2545eb62010-11-02 15:01:32 -0400320 my $failed = $?;
321
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400322 close(CMD);
323 close(LOG) if ($dolog);
324 close(RD) if ($dord);
325
Steven Rostedt2545eb62010-11-02 15:01:32 -0400326 if ($failed) {
327 doprint "FAILED!\n";
328 } else {
329 doprint "SUCCESS\n";
330 }
331
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400332 return !$failed;
333}
334
335sub get_grub_index {
336
Steven Rostedta75fece2010-11-02 14:58:27 -0400337 if ($reboot_type ne "grub") {
338 return;
339 }
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400340 return if (defined($grub_number));
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400341
342 doprint "Find grub menu ... ";
343 $grub_number = -1;
344 open(IN, "ssh $target cat /boot/grub/menu.lst |")
345 or die "unable to get menu.lst";
346 while (<IN>) {
Steven Rostedta75fece2010-11-02 14:58:27 -0400347 if (/^\s*title\s+$grub_menu\s*$/) {
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400348 $grub_number++;
349 last;
350 } elsif (/^\s*title\s/) {
351 $grub_number++;
352 }
353 }
354 close(IN);
355
Steven Rostedta75fece2010-11-02 14:58:27 -0400356 die "Could not find '$grub_menu' in /boot/grub/menu on $machine"
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400357 if ($grub_number < 0);
358 doprint "$grub_number\n";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400359}
360
Steven Rostedt2545eb62010-11-02 15:01:32 -0400361sub wait_for_input
362{
363 my ($fp, $time) = @_;
364 my $rin;
365 my $ready;
366 my $line;
367 my $ch;
368
369 if (!defined($time)) {
370 $time = $timeout;
371 }
372
373 $rin = '';
374 vec($rin, fileno($fp), 1) = 1;
375 $ready = select($rin, undef, undef, $time);
376
377 $line = "";
378
379 # try to read one char at a time
380 while (sysread $fp, $ch, 1) {
381 $line .= $ch;
382 last if ($ch eq "\n");
383 }
384
385 if (!length($line)) {
386 return undef;
387 }
388
389 return $line;
390}
391
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400392sub reboot_to {
Steven Rostedta75fece2010-11-02 14:58:27 -0400393 if ($reboot_type eq "grub") {
394 run_command "ssh $target '(echo \"savedefault --default=$grub_number --once\" | grub --batch; reboot)'";
395 return;
396 }
397
398 run_command "$reboot_script";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400399}
400
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400401sub monitor {
Steven Rostedt2545eb62010-11-02 15:01:32 -0400402 my $booted = 0;
403 my $bug = 0;
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400404 my $skip_call_trace = 0;
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400405 my $loops;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400406
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400407 wait_for_monitor 5;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400408
409 my $line;
410 my $full_line = "";
411
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400412 open(DMESG, "> $dmesg") or
413 die "unable to write to $dmesg";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400414
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400415 reboot_to;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400416
417 for (;;) {
418
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400419 if ($booted) {
Steven Rostedta75fece2010-11-02 14:58:27 -0400420 $line = wait_for_input($monitor_fp, $booted_timeout);
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400421 } else {
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400422 $line = wait_for_input($monitor_fp);
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400423 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400424
425 last if (!defined($line));
426
427 doprint $line;
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400428 print DMESG $line;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400429
430 # we are not guaranteed to get a full line
431 $full_line .= $line;
432
Steven Rostedta75fece2010-11-02 14:58:27 -0400433 if ($full_line =~ /$success_line/) {
Steven Rostedt2545eb62010-11-02 15:01:32 -0400434 $booted = 1;
435 }
436
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400437 if ($full_line =~ /\[ backtrace testing \]/) {
438 $skip_call_trace = 1;
439 }
440
Steven Rostedt2545eb62010-11-02 15:01:32 -0400441 if ($full_line =~ /call trace:/i) {
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400442 $bug = 1 if (!$skip_call_trace);
443 }
444
445 if ($full_line =~ /\[ end of backtrace testing \]/) {
446 $skip_call_trace = 0;
447 }
448
449 if ($full_line =~ /Kernel panic -/) {
Steven Rostedt2545eb62010-11-02 15:01:32 -0400450 $bug = 1;
451 }
452
453 if ($line =~ /\n/) {
454 $full_line = "";
455 }
456 }
457
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400458 close(DMESG);
Steven Rostedt2545eb62010-11-02 15:01:32 -0400459
Steven Rostedt2545eb62010-11-02 15:01:32 -0400460 if ($bug) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400461 return 0 if ($in_bisect);
Steven Rostedt576f6272010-11-02 14:58:38 -0400462 fail "failed - got a bug report" and return 0;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400463 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400464
Steven Rostedta75fece2010-11-02 14:58:27 -0400465 if (!$booted) {
466 return 0 if ($in_bisect);
Steven Rostedt576f6272010-11-02 14:58:38 -0400467 fail "failed - never got a boot prompt." and return 0;
Steven Rostedta75fece2010-11-02 14:58:27 -0400468 }
469
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400470 return 1;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400471}
472
473sub install {
474
Steven Rostedta75fece2010-11-02 14:58:27 -0400475 run_command "scp $outputdir/$build_target $target:$target_image" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400476 dodie "failed to copy image";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400477
478 my $install_mods = 0;
479
480 # should we process modules?
481 $install_mods = 0;
Steven Rostedta75fece2010-11-02 14:58:27 -0400482 open(IN, "$outputdir/.config") or dodie("Can't read config file");
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400483 while (<IN>) {
484 if (/CONFIG_MODULES(=y)?/) {
485 $install_mods = 1 if (defined($1));
486 last;
487 }
488 }
489 close(IN);
490
491 if (!$install_mods) {
492 doprint "No modules needed\n";
493 return;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400494 }
495
Steven Rostedta75fece2010-11-02 14:58:27 -0400496 run_command "$make INSTALL_MOD_PATH=$tmpdir modules_install" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400497 dodie "Failed to install modules";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400498
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400499 my $modlib = "/lib/modules/$version";
500 my $modtar = "autotest-mods.tar.bz2";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400501
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400502 run_command "ssh $target rm -rf $modlib" or
503 dodie "failed to remove old mods: $modlib";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400504
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400505 # would be nice if scp -r did not follow symbolic links
Steven Rostedta75fece2010-11-02 14:58:27 -0400506 run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400507 dodie "making tarball";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400508
Steven Rostedta75fece2010-11-02 14:58:27 -0400509 run_command "scp $tmpdir/$modtar $target:/tmp" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400510 dodie "failed to copy modules";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400511
Steven Rostedta75fece2010-11-02 14:58:27 -0400512 unlink "$tmpdir/$modtar";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400513
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400514 run_command "ssh $target '(cd / && tar xf /tmp/$modtar)'" or
515 dodie "failed to tar modules";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400516
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400517 run_command "ssh $target rm -f /tmp/$modtar";
Steven Rostedt8b37ca82010-11-02 14:58:33 -0400518
519 return if (!defined($post_install));
520
521 my $save_env = $ENV{KERNEL_VERSION};
522
523 $ENV{KERNEL_VERSION} = $version;
Steven Rostedt576f6272010-11-02 14:58:38 -0400524 run_command "$post_install" or
525 dodie "Failed to run post install";
Steven Rostedt8b37ca82010-11-02 14:58:33 -0400526
527 $ENV{KERNEL_VERSION} = $save_env;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400528}
529
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400530sub check_buildlog {
531 my ($patch) = @_;
532
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400533 my @files = `git show $patch | diffstat -l`;
534
535 open(IN, "git show $patch |") or
536 dodie "failed to show $patch";
537 while (<IN>) {
538 if (m,^--- a/(.*),) {
539 chomp $1;
540 $files[$#files] = $1;
541 }
542 }
543 close(IN);
544
545 open(IN, $buildlog) or dodie "Can't open $buildlog";
546 while (<IN>) {
547 if (/^\s*(.*?):.*(warning|error)/) {
548 my $err = $1;
549 foreach my $file (@files) {
Steven Rostedta75fece2010-11-02 14:58:27 -0400550 my $fullpath = "$builddir/$file";
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400551 if ($file eq $err || $fullpath eq $err) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400552 fail "$file built with warnings" and return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400553 }
554 }
555 }
556 }
557 close(IN);
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400558
559 return 1;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400560}
561
Steven Rostedt2545eb62010-11-02 15:01:32 -0400562sub build {
563 my ($type) = @_;
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400564 my $defconfig = "";
565 my $append = "";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400566
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400567 unlink $buildlog;
568
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400569 if ($type =~ /^useconfig:(.*)/) {
Steven Rostedta75fece2010-11-02 14:58:27 -0400570 run_command "cp $1 $outputdir/.config" or
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400571 dodie "could not copy $1 to .config";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400572
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400573 $type = "oldconfig";
574 }
575
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400576 # old config can ask questions
577 if ($type eq "oldconfig") {
578 $append = "yes ''|";
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400579
580 # allow for empty configs
Steven Rostedta75fece2010-11-02 14:58:27 -0400581 run_command "touch $outputdir/.config";
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400582
Steven Rostedta75fece2010-11-02 14:58:27 -0400583 run_command "mv $outputdir/.config $outputdir/config_temp" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400584 dodie "moving .config";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400585
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400586 if (!$noclean && !run_command "$make mrproper") {
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400587 dodie "make mrproper";
588 }
589
Steven Rostedta75fece2010-11-02 14:58:27 -0400590 run_command "mv $outputdir/config_temp $outputdir/.config" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400591 dodie "moving config_temp";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400592
593 } elsif (!$noclean) {
Steven Rostedta75fece2010-11-02 14:58:27 -0400594 unlink "$outputdir/.config";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400595 run_command "$make mrproper" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400596 dodie "make mrproper";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400597 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400598
599 # add something to distinguish this build
Steven Rostedta75fece2010-11-02 14:58:27 -0400600 open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file");
601 print OUT "$localversion\n";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400602 close(OUT);
603
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400604 if (defined($minconfig)) {
605 $defconfig = "KCONFIG_ALLCONFIG=$minconfig";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400606 }
607
Steven Rostedta75fece2010-11-02 14:58:27 -0400608 run_command "$append $defconfig $make $type" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400609 dodie "failed make config";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400610
Steven Rostedta75fece2010-11-02 14:58:27 -0400611 $redirect = "$buildlog";
612 if (!run_command "$make $build_options") {
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400613 undef $redirect;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400614 # bisect may need this to pass
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400615 return 0 if ($in_bisect);
616 fail "failed build" and return 0;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400617 }
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400618 undef $redirect;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400619
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400620 return 1;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400621}
622
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400623sub halt {
Steven Rostedta75fece2010-11-02 14:58:27 -0400624 if (!run_command "ssh $target halt" or defined($power_off)) {
Steven Rostedt576f6272010-11-02 14:58:38 -0400625 if (defined($poweroff_after_halt)) {
626 sleep $poweroff_after_halt;
627 run_command "$power_off";
628 }
629 } else {
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400630 # nope? the zap it!
Steven Rostedta75fece2010-11-02 14:58:27 -0400631 run_command "$power_off";
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400632 }
633}
634
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400635sub success {
636 my ($i) = @_;
637
638 doprint "\n\n*******************************************\n";
639 doprint "*******************************************\n";
Steven Rostedta75fece2010-11-02 14:58:27 -0400640 doprint "** TEST $i SUCCESS!!!! **\n";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400641 doprint "*******************************************\n";
642 doprint "*******************************************\n";
643
Steven Rostedt576f6272010-11-02 14:58:38 -0400644 if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) {
Steven Rostedta75fece2010-11-02 14:58:27 -0400645 doprint "Reboot and wait $sleep_time seconds\n";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400646 reboot;
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400647 start_monitor;
Steven Rostedta75fece2010-11-02 14:58:27 -0400648 wait_for_monitor $sleep_time;
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400649 end_monitor;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400650 }
651}
652
653sub get_version {
654 # get the release name
655 doprint "$make kernelrelease ... ";
656 $version = `$make kernelrelease | tail -1`;
657 chomp($version);
658 doprint "$version\n";
659}
660
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400661sub child_run_test {
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400662 my $failed = 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400663
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400664 # child should have no power
Steven Rostedta75fece2010-11-02 14:58:27 -0400665 $reboot_on_error = 0;
666 $poweroff_on_error = 0;
667 $die_on_failure = 1;
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400668
669 run_command $run_test or $failed = 1;
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400670 exit $failed;
671}
672
673my $child_done;
674
675sub child_finished {
676 $child_done = 1;
677}
678
679sub do_run_test {
680 my $child_pid;
681 my $child_exit;
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400682 my $line;
683 my $full_line;
684 my $bug = 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400685
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400686 wait_for_monitor 1;
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400687
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400688 doprint "run test $run_test\n";
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400689
690 $child_done = 0;
691
692 $SIG{CHLD} = qw(child_finished);
693
694 $child_pid = fork;
695
696 child_run_test if (!$child_pid);
697
698 $full_line = "";
699
700 do {
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400701 $line = wait_for_input($monitor_fp, 1);
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400702 if (defined($line)) {
703
704 # we are not guaranteed to get a full line
705 $full_line .= $line;
706
707 if ($full_line =~ /call trace:/i) {
708 $bug = 1;
709 }
710
711 if ($full_line =~ /Kernel panic -/) {
712 $bug = 1;
713 }
714
715 if ($line =~ /\n/) {
716 $full_line = "";
717 }
718 }
719 } while (!$child_done && !$bug);
720
721 if ($bug) {
722 doprint "Detected kernel crash!\n";
723 # kill the child with extreme prejudice
724 kill 9, $child_pid;
725 }
726
727 waitpid $child_pid, 0;
728 $child_exit = $?;
729
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400730 if ($bug || $child_exit) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400731 return 0 if $in_bisect;
732 fail "test failed" and return 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400733 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400734 return 1;
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400735}
736
Steven Rostedta75fece2010-11-02 14:58:27 -0400737sub run_git_bisect {
738 my ($command) = @_;
739
740 doprint "$command ... ";
741
742 my $output = `$command 2>&1`;
743 my $ret = $?;
744
745 logit $output;
746
747 if ($ret) {
748 doprint "FAILED\n";
749 dodie "Failed to git bisect";
750 }
751
752 doprint "SUCCESS\n";
753 if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) {
754 doprint "$1 [$2]\n";
755 } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) {
756 $bisect_bad = $1;
757 doprint "Found bad commit... $1\n";
758 return 0;
759 } else {
760 # we already logged it, just print it now.
761 print $output;
762 }
763
764 return 1;
765}
766
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400767sub run_bisect {
768 my ($type) = @_;
769
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400770 my $failed = 0;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400771 my $result;
772 my $output;
773 my $ret;
774
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400775 if (defined($minconfig)) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400776 build "useconfig:$minconfig" or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400777 } else {
778 # ?? no config to use?
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400779 build "oldconfig" or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400780 }
781
782 if ($type ne "build") {
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400783 dodie "Failed on build" if $failed;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400784
785 # Now boot the box
786 get_grub_index;
787 get_version;
788 install;
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400789
790 start_monitor;
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400791 monitor or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400792
793 if ($type ne "boot") {
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400794 dodie "Failed on boot" if $failed;
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400795
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400796 do_run_test or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400797 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400798 end_monitor;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400799 }
800
801 if ($failed) {
802 $result = "bad";
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400803
804 # reboot the box to a good kernel
Steven Rostedta75fece2010-11-02 14:58:27 -0400805 if ($type ne "build") {
806 doprint "Reboot and sleep $bisect_sleep_time seconds\n";
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400807 reboot;
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400808 start_monitor;
Steven Rostedta75fece2010-11-02 14:58:27 -0400809 wait_for_monitor $bisect_sleep_time;
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400810 end_monitor;
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400811 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400812 } else {
813 $result = "good";
814 }
815
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400816 # Are we looking for where it worked, not failed?
817 if ($reverse_bisect) {
818 if ($failed) {
819 $result = "good";
820 } else {
821 $result = "bad";
822 }
823 }
824
Steven Rostedta75fece2010-11-02 14:58:27 -0400825 return $result;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400826}
827
828sub bisect {
829 my ($i) = @_;
830
831 my $result;
832
833 die "BISECT_GOOD[$i] not defined\n" if (!defined($opt{"BISECT_GOOD[$i]"}));
834 die "BISECT_BAD[$i] not defined\n" if (!defined($opt{"BISECT_BAD[$i]"}));
835 die "BISECT_TYPE[$i] not defined\n" if (!defined($opt{"BISECT_TYPE[$i]"}));
836
837 my $good = $opt{"BISECT_GOOD[$i]"};
838 my $bad = $opt{"BISECT_BAD[$i]"};
839 my $type = $opt{"BISECT_TYPE[$i]"};
Steven Rostedta75fece2010-11-02 14:58:27 -0400840 my $start = $opt{"BISECT_START[$i]"};
841 my $replay = $opt{"BISECT_REPLAY[$i]"};
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400842
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400843 if (defined($opt{"BISECT_REVERSE[$i]"}) &&
844 $opt{"BISECT_REVERSE[$i]"} == 1) {
845 doprint "Performing a reverse bisect (bad is good, good is bad!)\n";
846 $reverse_bisect = 1;
847 } else {
848 $reverse_bisect = 0;
849 }
850
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400851 $in_bisect = 1;
852
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400853 # Can't have a test without having a test to run
854 if ($type eq "test" && !defined($run_test)) {
855 $type = "boot";
856 }
857
Steven Rostedta75fece2010-11-02 14:58:27 -0400858 my $check = $opt{"BISECT_CHECK[$i]"};
859 if (defined($check) && $check ne "0") {
860
861 # get current HEAD
862 doprint "git rev-list HEAD --max-count=1 ... ";
863 my $head = `git rev-list HEAD --max-count=1`;
864 my $ret = $?;
865
866 logit $head;
867
868 if ($ret) {
869 doprint "FAILED\n";
870 dodie "Failed to get git HEAD";
871 }
872
873 print "SUCCESS\n";
874
875 chomp $head;
876
877 if ($check ne "good") {
878 doprint "TESTING BISECT BAD [$bad]\n";
879 run_command "git checkout $bad" or
880 die "Failed to checkout $bad";
881
882 $result = run_bisect $type;
883
884 if ($result ne "bad") {
885 fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0;
886 }
887 }
888
889 if ($check ne "bad") {
890 doprint "TESTING BISECT GOOD [$good]\n";
891 run_command "git checkout $good" or
892 die "Failed to checkout $good";
893
894 $result = run_bisect $type;
895
896 if ($result ne "good") {
897 fail "Tested BISECT_GOOD [$good] and it failed" and return 0;
898 }
899 }
900
901 # checkout where we started
902 run_command "git checkout $head" or
903 die "Failed to checkout $head";
904 }
905
906 run_command "git bisect start" or
907 dodie "could not start bisect";
908
909 run_command "git bisect good $good" or
910 dodie "could not set bisect good to $good";
911
912 run_git_bisect "git bisect bad $bad" or
913 dodie "could not set bisect bad to $bad";
914
915 if (defined($replay)) {
916 run_command "git bisect replay $replay" or
917 dodie "failed to run replay";
918 }
919
920 if (defined($start)) {
921 run_command "git checkout $start" or
922 dodie "failed to checkout $start";
923 }
924
925 my $test;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400926 do {
927 $result = run_bisect $type;
Steven Rostedta75fece2010-11-02 14:58:27 -0400928 $test = run_git_bisect "git bisect $result";
929 } while ($test);
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400930
931 run_command "git bisect log" or
932 dodie "could not capture git bisect log";
933
934 run_command "git bisect reset" or
935 dodie "could not reset git bisect";
936
937 doprint "Bad commit was [$bisect_bad]\n";
938
939 $in_bisect = 0;
940
941 success $i;
942}
943
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400944sub patchcheck {
945 my ($i) = @_;
946
947 die "PATCHCHECK_START[$i] not defined\n"
948 if (!defined($opt{"PATCHCHECK_START[$i]"}));
949 die "PATCHCHECK_TYPE[$i] not defined\n"
950 if (!defined($opt{"PATCHCHECK_TYPE[$i]"}));
951
952 my $start = $opt{"PATCHCHECK_START[$i]"};
953
954 my $end = "HEAD";
955 if (defined($opt{"PATCHCHECK_END[$i]"})) {
956 $end = $opt{"PATCHCHECK_END[$i]"};
957 }
958
959 my $type = $opt{"PATCHCHECK_TYPE[$i]"};
960
961 # Can't have a test without having a test to run
962 if ($type eq "test" && !defined($run_test)) {
963 $type = "boot";
964 }
965
966 open (IN, "git log --pretty=oneline $end|") or
967 dodie "could not get git list";
968
969 my @list;
970
971 while (<IN>) {
972 chomp;
973 $list[$#list+1] = $_;
974 last if (/^$start/);
975 }
976 close(IN);
977
978 if ($list[$#list] !~ /^$start/) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400979 fail "SHA1 $start not found";
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400980 }
981
982 # go backwards in the list
983 @list = reverse @list;
984
985 my $save_clean = $noclean;
986
987 $in_patchcheck = 1;
988 foreach my $item (@list) {
989 my $sha1 = $item;
990 $sha1 =~ s/^([[:xdigit:]]+).*/$1/;
991
992 doprint "\nProcessing commit $item\n\n";
993
994 run_command "git checkout $sha1" or
995 die "Failed to checkout $sha1";
996
997 # only clean on the first and last patch
998 if ($item eq $list[0] ||
999 $item eq $list[$#list]) {
1000 $noclean = $save_clean;
1001 } else {
1002 $noclean = 1;
1003 }
1004
1005 if (defined($minconfig)) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001006 build "useconfig:$minconfig" or return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001007 } else {
1008 # ?? no config to use?
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001009 build "oldconfig" or return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001010 }
1011
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001012 check_buildlog $sha1 or return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001013
1014 next if ($type eq "build");
1015
1016 get_grub_index;
1017 get_version;
1018 install;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001019
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001020 my $failed = 0;
1021
1022 start_monitor;
1023 monitor or $failed = 1;
1024
1025 if (!$failed && $type ne "boot"){
1026 do_run_test or $failed = 1;
1027 }
1028 end_monitor;
1029 return 0 if ($failed);
1030
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001031 }
1032 $in_patchcheck = 0;
1033 success $i;
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001034
1035 return 1;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001036}
1037
Steven Rostedt2545eb62010-11-02 15:01:32 -04001038read_config $ARGV[0];
1039
1040# mandatory configs
1041die "MACHINE not defined\n" if (!defined($opt{"MACHINE"}));
1042die "SSH_USER not defined\n" if (!defined($opt{"SSH_USER"}));
1043die "BUILD_DIR not defined\n" if (!defined($opt{"BUILD_DIR"}));
1044die "OUTPUT_DIR not defined\n" if (!defined($opt{"OUTPUT_DIR"}));
1045die "BUILD_TARGET not defined\n" if (!defined($opt{"BUILD_TARGET"}));
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001046die "TARGET_IMAGE not defined\n" if (!defined($opt{"TARGET_IMAGE"}));
Steven Rostedt2545eb62010-11-02 15:01:32 -04001047die "POWER_CYCLE not defined\n" if (!defined($opt{"POWER_CYCLE"}));
1048die "CONSOLE not defined\n" if (!defined($opt{"CONSOLE"}));
1049die "LOCALVERSION not defined\n" if (!defined($opt{"LOCALVERSION"}));
Steven Rostedt2545eb62010-11-02 15:01:32 -04001050
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001051if ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) {
1052 unlink $opt{"LOG_FILE"};
1053}
Steven Rostedt2545eb62010-11-02 15:01:32 -04001054
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001055doprint "\n\nSTARTING AUTOMATED TESTS\n\n";
1056
1057foreach my $option (sort keys %opt) {
1058 doprint "$option = $opt{$option}\n";
1059}
Steven Rostedt2545eb62010-11-02 15:01:32 -04001060
Steven Rostedta75fece2010-11-02 14:58:27 -04001061sub set_test_option {
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001062 my ($name, $i) = @_;
1063
1064 my $option = "$name\[$i\]";
1065
1066 if (defined($opt{$option})) {
1067 return $opt{$option};
1068 }
1069
1070 if (defined($opt{$name})) {
1071 return $opt{$name};
1072 }
1073
1074 return undef;
1075}
1076
Steven Rostedt2545eb62010-11-02 15:01:32 -04001077# First we need to do is the builds
Steven Rostedta75fece2010-11-02 14:58:27 -04001078for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
Steven Rostedt2545eb62010-11-02 15:01:32 -04001079
Steven Rostedt576f6272010-11-02 14:58:38 -04001080 $iteration = $i;
1081
Steven Rostedta75fece2010-11-02 14:58:27 -04001082 my $ssh_user = set_test_option("SSH_USER", $i);
1083 my $makecmd = set_test_option("MAKE_CMD", $i);
1084
1085 $machine = set_test_option("MACHINE", $i);
1086 $tmpdir = set_test_option("TMP_DIR", $i);
1087 $outputdir = set_test_option("OUTPUT_DIR", $i);
1088 $builddir = set_test_option("BUILD_DIR", $i);
1089 $test_type = set_test_option("TEST_TYPE", $i);
1090 $build_type = set_test_option("BUILD_TYPE", $i);
1091 $build_options = set_test_option("BUILD_OPTIONS", $i);
1092 $power_cycle = set_test_option("POWER_CYCLE", $i);
1093 $noclean = set_test_option("BUILD_NOCLEAN", $i);
1094 $minconfig = set_test_option("MIN_CONFIG", $i);
1095 $run_test = set_test_option("TEST", $i);
1096 $addconfig = set_test_option("ADD_CONFIG", $i);
1097 $reboot_type = set_test_option("REBOOT_TYPE", $i);
1098 $grub_menu = set_test_option("GRUB_MENU", $i);
Steven Rostedt8b37ca82010-11-02 14:58:33 -04001099 $post_install = set_test_option("POST_INSTALL", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04001100 $reboot_script = set_test_option("REBOOT_SCRIPT", $i);
1101 $reboot_on_error = set_test_option("REBOOT_ON_ERROR", $i);
1102 $poweroff_on_error = set_test_option("POWEROFF_ON_ERROR", $i);
1103 $die_on_failure = set_test_option("DIE_ON_FAILURE", $i);
1104 $power_off = set_test_option("POWER_OFF", $i);
Steven Rostedt576f6272010-11-02 14:58:38 -04001105 $powercycle_after_reboot = set_test_option("POWERCYCLE_AFTER_REBOOT", $i);
1106 $poweroff_after_halt = set_test_option("POWEROFF_AFTER_HALT", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04001107 $sleep_time = set_test_option("SLEEP_TIME", $i);
1108 $bisect_sleep_time = set_test_option("BISECT_SLEEP_TIME", $i);
1109 $store_failures = set_test_option("STORE_FAILURES", $i);
1110 $timeout = set_test_option("TIMEOUT", $i);
1111 $booted_timeout = set_test_option("BOOTED_TIMEOUT", $i);
1112 $console = set_test_option("CONSOLE", $i);
1113 $success_line = set_test_option("SUCCESS_LINE", $i);
1114 $build_target = set_test_option("BUILD_TARGET", $i);
1115 $target_image = set_test_option("TARGET_IMAGE", $i);
1116 $localversion = set_test_option("LOCALVERSION", $i);
1117
1118 chdir $builddir || die "can't change directory to $builddir";
1119
1120 if (!-d $tmpdir) {
1121 mkpath($tmpdir) or
1122 die "can't create $tmpdir";
1123 }
1124
1125 $target = "$ssh_user\@$machine";
1126
1127 $buildlog = "$tmpdir/buildlog-$machine";
1128 $dmesg = "$tmpdir/dmesg-$machine";
1129 $make = "$makecmd O=$outputdir";
1130
1131 if ($reboot_type eq "grub") {
Steven Rostedt576f6272010-11-02 14:58:38 -04001132 dodie "GRUB_MENU not defined" if (!defined($grub_menu));
Steven Rostedta75fece2010-11-02 14:58:27 -04001133 } elsif (!defined($reboot_script)) {
Steven Rostedt576f6272010-11-02 14:58:38 -04001134 dodie "REBOOT_SCRIPT not defined"
Steven Rostedta75fece2010-11-02 14:58:27 -04001135 }
1136
1137 my $run_type = $build_type;
1138 if ($test_type eq "patchcheck") {
1139 $run_type = $opt{"PATCHCHECK_TYPE[$i]"};
1140 } elsif ($test_type eq "bisect") {
1141 $run_type = $opt{"BISECT_TYPE[$i]"};
1142 }
1143
1144 # mistake in config file?
1145 if (!defined($run_type)) {
1146 $run_type = "ERROR";
1147 }
Steven Rostedt2545eb62010-11-02 15:01:32 -04001148
1149 doprint "\n\n";
Steven Rostedta75fece2010-11-02 14:58:27 -04001150 doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type\n\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001151
1152 unlink $dmesg;
1153 unlink $buildlog;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001154
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001155 if (!defined($minconfig)) {
1156 $minconfig = $addconfig;
1157
1158 } elsif (defined($addconfig)) {
Steven Rostedta75fece2010-11-02 14:58:27 -04001159 run_command "cat $addconfig $minconfig > $tmpdir/use_config" or
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001160 dodie "Failed to create temp config";
Steven Rostedta75fece2010-11-02 14:58:27 -04001161 $minconfig = "$tmpdir/use_config";
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001162 }
1163
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001164 my $checkout = $opt{"CHECKOUT[$i]"};
1165 if (defined($checkout)) {
1166 run_command "git checkout $checkout" or
1167 die "failed to checkout $checkout";
1168 }
1169
Steven Rostedta75fece2010-11-02 14:58:27 -04001170 if ($test_type eq "bisect") {
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001171 bisect $i;
1172 next;
Steven Rostedta75fece2010-11-02 14:58:27 -04001173 } elsif ($test_type eq "patchcheck") {
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001174 patchcheck $i;
1175 next;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001176 }
1177
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001178 if ($build_type ne "nobuild") {
1179 build $build_type or next;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001180 }
1181
Steven Rostedta75fece2010-11-02 14:58:27 -04001182 if ($test_type ne "build") {
1183 get_grub_index;
1184 get_version;
1185 install;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001186
Steven Rostedta75fece2010-11-02 14:58:27 -04001187 my $failed = 0;
1188 start_monitor;
1189 monitor or $failed = 1;;
1190
1191 if (!$failed && $test_type ne "boot" && defined($run_test)) {
1192 do_run_test or $failed = 1;
1193 }
1194 end_monitor;
1195 next if ($failed);
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001196 }
1197
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001198 success $i;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001199}
1200
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001201if ($opt{"POWEROFF_ON_SUCCESS"}) {
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001202 halt;
Steven Rostedt576f6272010-11-02 14:58:38 -04001203} elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot) {
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001204 reboot;
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001205}
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001206
Steven Rostedt2545eb62010-11-02 15:01:32 -04001207exit 0;