blob: 3d88be784df01437bc9f9eb6cdd40df6821f0b83 [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
Steven Rostedta57419b2010-11-02 15:13:54 -040014$#ARGV >= 0 || die "usage: ktest.pl config-file\n";
Steven Rostedt2545eb62010-11-02 15:01:32 -040015
16$| = 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
39$default{"CLEAR_LOG"} = 0;
40$default{"SUCCESS_LINE"} = "login:";
41$default{"BOOTED_TIMEOUT"} = 1;
42$default{"DIE_ON_FAILURE"} = 1;
Steven Rostedt2545eb62010-11-02 15:01:32 -040043
44my $version;
Steven Rostedta75fece2010-11-02 14:58:27 -040045my $machine;
46my $tmpdir;
47my $builddir;
48my $outputdir;
Steven Rostedt51ad1dd2010-11-08 16:43:21 -050049my $output_config;
Steven Rostedta75fece2010-11-02 14:58:27 -040050my $test_type;
Steven Rostedt7faafbd2010-11-02 14:58:22 -040051my $build_type;
Steven Rostedta75fece2010-11-02 14:58:27 -040052my $build_options;
53my $reboot_type;
54my $reboot_script;
55my $power_cycle;
56my $reboot_on_error;
57my $poweroff_on_error;
58my $die_on_failure;
Steven Rostedt576f6272010-11-02 14:58:38 -040059my $powercycle_after_reboot;
60my $poweroff_after_halt;
Steven Rostedta75fece2010-11-02 14:58:27 -040061my $power_off;
62my $grub_menu;
Steven Rostedt2545eb62010-11-02 15:01:32 -040063my $grub_number;
64my $target;
65my $make;
Steven Rostedt8b37ca82010-11-02 14:58:33 -040066my $post_install;
Steven Rostedt5c42fc52010-11-02 14:57:01 -040067my $noclean;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -040068my $minconfig;
Steven Rostedt2b7d9b22010-11-02 14:58:15 -040069my $addconfig;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -040070my $in_bisect = 0;
71my $bisect_bad = "";
Steven Rostedtd6ce2a02010-11-02 14:58:05 -040072my $reverse_bisect;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -040073my $in_patchcheck = 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -040074my $run_test;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -040075my $redirect;
Steven Rostedt7faafbd2010-11-02 14:58:22 -040076my $buildlog;
77my $dmesg;
78my $monitor_fp;
79my $monitor_pid;
80my $monitor_cnt = 0;
Steven Rostedta75fece2010-11-02 14:58:27 -040081my $sleep_time;
82my $bisect_sleep_time;
83my $store_failures;
84my $timeout;
85my $booted_timeout;
86my $console;
87my $success_line;
88my $build_target;
89my $target_image;
90my $localversion;
Steven Rostedt576f6272010-11-02 14:58:38 -040091my $iteration = 0;
Steven Rostedt2545eb62010-11-02 15:01:32 -040092
Steven Rostedta57419b2010-11-02 15:13:54 -040093sub set_value {
94 my ($lvalue, $rvalue) = @_;
95
96 if (defined($opt{$lvalue})) {
97 die "Error: Option $lvalue defined more than once!\n";
98 }
99 $opt{$lvalue} = $rvalue;
100}
101
Steven Rostedt2545eb62010-11-02 15:01:32 -0400102sub read_config {
103 my ($config) = @_;
104
105 open(IN, $config) || die "can't read file $config";
106
Steven Rostedta57419b2010-11-02 15:13:54 -0400107 my $name = $config;
108 $name =~ s,.*/(.*),$1,;
109
110 my $test_num = 0;
111 my $default = 1;
112 my $repeat = 1;
113 my $num_tests_set = 0;
114 my $skip = 0;
115 my $rest;
116
Steven Rostedt2545eb62010-11-02 15:01:32 -0400117 while (<IN>) {
118
119 # ignore blank lines and comments
120 next if (/^\s*$/ || /\s*\#/);
121
Steven Rostedta57419b2010-11-02 15:13:54 -0400122 if (/^\s*TEST_START(.*)/) {
123
124 $rest = $1;
125
126 if ($num_tests_set) {
127 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
128 }
129
130 my $old_test_num = $test_num;
131
132 $test_num += $repeat;
133 $default = 0;
134 $repeat = 1;
135
136 if ($rest =~ /\s+SKIP(.*)/) {
137 $rest = $1;
138 $skip = 1;
139 } else {
140 $skip = 0;
141 }
142
143 if ($rest =~ /\s+ITERATE\s+(\d+)(.*)$/) {
144 $repeat = $1;
145 $rest = $2;
146 $repeat_tests{"$test_num"} = $repeat;
147 }
148
149 if ($rest =~ /\s+SKIP(.*)/) {
150 $rest = $1;
151 $skip = 1;
152 }
153
154 if ($rest !~ /^\s*$/) {
155 die "$name: $.: Gargbage found after TEST_START\n$_";
156 }
157
158 if ($skip) {
159 $test_num = $old_test_num;
160 $repeat = 1;
161 }
162
163 } elsif (/^\s*DEFAULTS(.*)$/) {
164 $default = 1;
165
166 $rest = $1;
167
168 if ($rest =~ /\s+SKIP(.*)/) {
169 $rest = $1;
170 $skip = 1;
171 } else {
172 $skip = 0;
173 }
174
175 if ($rest !~ /^\s*$/) {
176 die "$name: $.: Gargbage found after DEFAULTS\n$_";
177 }
178
179 } elsif (/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) {
180
181 next if ($skip);
182
Steven Rostedt2545eb62010-11-02 15:01:32 -0400183 my $lvalue = $1;
184 my $rvalue = $2;
185
Steven Rostedta57419b2010-11-02 15:13:54 -0400186 if (!$default &&
187 ($lvalue eq "NUM_TESTS" ||
188 $lvalue eq "LOG_FILE" ||
189 $lvalue eq "CLEAR_LOG")) {
190 die "$name: $.: $lvalue must be set in DEFAULTS section\n";
Steven Rostedta75fece2010-11-02 14:58:27 -0400191 }
Steven Rostedta57419b2010-11-02 15:13:54 -0400192
193 if ($lvalue eq "NUM_TESTS") {
194 if ($test_num) {
195 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
196 }
197 if (!$default) {
198 die "$name: $.: NUM_TESTS must be set in default section\n";
199 }
200 $num_tests_set = 1;
201 }
202
203 if ($default || $lvalue =~ /\[\d+\]$/) {
204 set_value($lvalue, $rvalue);
205 } else {
206 my $val = "$lvalue\[$test_num\]";
207 set_value($val, $rvalue);
208
209 if ($repeat > 1) {
210 $repeats{$val} = $repeat;
211 }
212 }
213 } else {
214 die "$name: $.: Garbage found in config\n$_";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400215 }
216 }
217
218 close(IN);
Steven Rostedta75fece2010-11-02 14:58:27 -0400219
Steven Rostedta57419b2010-11-02 15:13:54 -0400220 if ($test_num) {
221 $test_num += $repeat - 1;
222 $opt{"NUM_TESTS"} = $test_num;
223 }
224
Steven Rostedta75fece2010-11-02 14:58:27 -0400225 # set any defaults
226
227 foreach my $default (keys %default) {
228 if (!defined($opt{$default})) {
229 $opt{$default} = $default{$default};
230 }
231 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400232}
233
Steven Rostedtd1e2f222010-11-08 16:39:57 -0500234sub _logit {
Steven Rostedt2545eb62010-11-02 15:01:32 -0400235 if (defined($opt{"LOG_FILE"})) {
236 open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}";
237 print OUT @_;
238 close(OUT);
239 }
240}
241
Steven Rostedtd1e2f222010-11-08 16:39:57 -0500242sub logit {
243 if (defined($opt{"LOG_FILE"})) {
244 _logit @_;
245 } else {
246 print @_;
247 }
248}
249
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400250sub doprint {
251 print @_;
Steven Rostedtd1e2f222010-11-08 16:39:57 -0500252 _logit @_;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400253}
254
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400255sub run_command;
256
257sub reboot {
258 # try to reboot normally
Steven Rostedt576f6272010-11-02 14:58:38 -0400259 if (run_command "ssh $target reboot") {
260 if (defined($powercycle_after_reboot)) {
261 sleep $powercycle_after_reboot;
262 run_command "$power_cycle";
263 }
264 } else {
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400265 # nope? power cycle it.
Steven Rostedta75fece2010-11-02 14:58:27 -0400266 run_command "$power_cycle";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400267 }
268}
269
Steven Rostedt576f6272010-11-02 14:58:38 -0400270sub do_not_reboot {
271 my $i = $iteration;
272
273 return $test_type eq "build" ||
274 ($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") ||
275 ($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build");
276}
277
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400278sub dodie {
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400279 doprint "CRITICAL FAILURE... ", @_, "\n";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400280
Steven Rostedt576f6272010-11-02 14:58:38 -0400281 my $i = $iteration;
282
283 if ($reboot_on_error && !do_not_reboot) {
284
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400285 doprint "REBOOTING\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400286 reboot;
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400287
Steven Rostedta75fece2010-11-02 14:58:27 -0400288 } elsif ($poweroff_on_error && defined($power_off)) {
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400289 doprint "POWERING OFF\n";
Steven Rostedta75fece2010-11-02 14:58:27 -0400290 `$power_off`;
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400291 }
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400292
Steven Rostedt576f6272010-11-02 14:58:38 -0400293 die @_, "\n";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400294}
295
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400296sub open_console {
297 my ($fp) = @_;
298
299 my $flags;
300
Steven Rostedta75fece2010-11-02 14:58:27 -0400301 my $pid = open($fp, "$console|") or
302 dodie "Can't open console $console";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400303
304 $flags = fcntl($fp, F_GETFL, 0) or
Steven Rostedt576f6272010-11-02 14:58:38 -0400305 dodie "Can't get flags for the socket: $!";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400306 $flags = fcntl($fp, F_SETFL, $flags | O_NONBLOCK) or
Steven Rostedt576f6272010-11-02 14:58:38 -0400307 dodie "Can't set flags for the socket: $!";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400308
309 return $pid;
310}
311
312sub close_console {
313 my ($fp, $pid) = @_;
314
315 doprint "kill child process $pid\n";
316 kill 2, $pid;
317
318 print "closing!\n";
319 close($fp);
320}
321
322sub start_monitor {
323 if ($monitor_cnt++) {
324 return;
325 }
326 $monitor_fp = \*MONFD;
327 $monitor_pid = open_console $monitor_fp;
Steven Rostedta75fece2010-11-02 14:58:27 -0400328
329 return;
330
331 open(MONFD, "Stop perl from warning about single use of MONFD");
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400332}
333
334sub end_monitor {
335 if (--$monitor_cnt) {
336 return;
337 }
338 close_console($monitor_fp, $monitor_pid);
339}
340
341sub wait_for_monitor {
342 my ($time) = @_;
343 my $line;
344
Steven Rostedta75fece2010-11-02 14:58:27 -0400345 doprint "** Wait for monitor to settle down **\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400346
347 # read the monitor and wait for the system to calm down
348 do {
349 $line = wait_for_input($monitor_fp, $time);
Steven Rostedta75fece2010-11-02 14:58:27 -0400350 print "$line" if (defined($line));
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400351 } while (defined($line));
Steven Rostedta75fece2010-11-02 14:58:27 -0400352 print "** Monitor flushed **\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400353}
354
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400355sub fail {
356
Steven Rostedta75fece2010-11-02 14:58:27 -0400357 if ($die_on_failure) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400358 dodie @_;
359 }
360
Steven Rostedta75fece2010-11-02 14:58:27 -0400361 doprint "FAILED\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400362
Steven Rostedt576f6272010-11-02 14:58:38 -0400363 my $i = $iteration;
364
Steven Rostedta75fece2010-11-02 14:58:27 -0400365 # no need to reboot for just building.
Steven Rostedt576f6272010-11-02 14:58:38 -0400366 if (!do_not_reboot) {
Steven Rostedta75fece2010-11-02 14:58:27 -0400367 doprint "REBOOTING\n";
368 reboot;
369 start_monitor;
370 wait_for_monitor $sleep_time;
371 end_monitor;
372 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400373
Steven Rostedt576f6272010-11-02 14:58:38 -0400374 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
375 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
Steven Rostedta75fece2010-11-02 14:58:27 -0400376 doprint "**** Failed: ", @_, " ****\n";
Steven Rostedt576f6272010-11-02 14:58:38 -0400377 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
378 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
Steven Rostedta75fece2010-11-02 14:58:27 -0400379
380 return 1 if (!defined($store_failures));
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400381
382 my @t = localtime;
383 my $date = sprintf "%04d%02d%02d%02d%02d%02d",
384 1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0];
385
Steven Rostedta75fece2010-11-02 14:58:27 -0400386 my $dir = "$machine-$test_type-$build_type-fail-$date";
387 my $faildir = "$store_failures/$dir";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400388
389 if (!-d $faildir) {
390 mkpath($faildir) or
Steven Rostedta75fece2010-11-02 14:58:27 -0400391 die "can't create $faildir";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400392 }
Steven Rostedt51ad1dd2010-11-08 16:43:21 -0500393 if (-f "$output_config") {
394 cp "$output_config", "$faildir/config" or
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400395 die "failed to copy .config";
396 }
397 if (-f $buildlog) {
398 cp $buildlog, "$faildir/buildlog" or
399 die "failed to move $buildlog";
400 }
401 if (-f $dmesg) {
402 cp $dmesg, "$faildir/dmesg" or
403 die "failed to move $dmesg";
404 }
405
406 doprint "*** Saved info to $faildir ***\n";
407
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400408 return 1;
409}
410
Steven Rostedt2545eb62010-11-02 15:01:32 -0400411sub run_command {
412 my ($command) = @_;
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400413 my $dolog = 0;
414 my $dord = 0;
415 my $pid;
416
417 doprint("$command ... ");
418
419 $pid = open(CMD, "$command 2>&1 |") or
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400420 (fail "unable to exec $command" and return 0);
Steven Rostedt2545eb62010-11-02 15:01:32 -0400421
422 if (defined($opt{"LOG_FILE"})) {
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400423 open(LOG, ">>$opt{LOG_FILE}") or
424 dodie "failed to write to log";
425 $dolog = 1;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400426 }
427
428 if (defined($redirect)) {
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400429 open (RD, ">$redirect") or
430 dodie "failed to write to redirect $redirect";
431 $dord = 1;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400432 }
433
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400434 while (<CMD>) {
435 print LOG if ($dolog);
436 print RD if ($dord);
437 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400438
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400439 waitpid($pid, 0);
Steven Rostedt2545eb62010-11-02 15:01:32 -0400440 my $failed = $?;
441
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400442 close(CMD);
443 close(LOG) if ($dolog);
444 close(RD) if ($dord);
445
Steven Rostedt2545eb62010-11-02 15:01:32 -0400446 if ($failed) {
447 doprint "FAILED!\n";
448 } else {
449 doprint "SUCCESS\n";
450 }
451
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400452 return !$failed;
453}
454
455sub get_grub_index {
456
Steven Rostedta75fece2010-11-02 14:58:27 -0400457 if ($reboot_type ne "grub") {
458 return;
459 }
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400460 return if (defined($grub_number));
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400461
462 doprint "Find grub menu ... ";
463 $grub_number = -1;
464 open(IN, "ssh $target cat /boot/grub/menu.lst |")
465 or die "unable to get menu.lst";
466 while (<IN>) {
Steven Rostedta75fece2010-11-02 14:58:27 -0400467 if (/^\s*title\s+$grub_menu\s*$/) {
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400468 $grub_number++;
469 last;
470 } elsif (/^\s*title\s/) {
471 $grub_number++;
472 }
473 }
474 close(IN);
475
Steven Rostedta75fece2010-11-02 14:58:27 -0400476 die "Could not find '$grub_menu' in /boot/grub/menu on $machine"
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400477 if ($grub_number < 0);
478 doprint "$grub_number\n";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400479}
480
Steven Rostedt2545eb62010-11-02 15:01:32 -0400481sub wait_for_input
482{
483 my ($fp, $time) = @_;
484 my $rin;
485 my $ready;
486 my $line;
487 my $ch;
488
489 if (!defined($time)) {
490 $time = $timeout;
491 }
492
493 $rin = '';
494 vec($rin, fileno($fp), 1) = 1;
495 $ready = select($rin, undef, undef, $time);
496
497 $line = "";
498
499 # try to read one char at a time
500 while (sysread $fp, $ch, 1) {
501 $line .= $ch;
502 last if ($ch eq "\n");
503 }
504
505 if (!length($line)) {
506 return undef;
507 }
508
509 return $line;
510}
511
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400512sub reboot_to {
Steven Rostedta75fece2010-11-02 14:58:27 -0400513 if ($reboot_type eq "grub") {
514 run_command "ssh $target '(echo \"savedefault --default=$grub_number --once\" | grub --batch; reboot)'";
515 return;
516 }
517
518 run_command "$reboot_script";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400519}
520
Steven Rostedta57419b2010-11-02 15:13:54 -0400521sub get_sha1 {
522 my ($commit) = @_;
523
524 doprint "git rev-list --max-count=1 $commit ... ";
525 my $sha1 = `git rev-list --max-count=1 $commit`;
526 my $ret = $?;
527
528 logit $sha1;
529
530 if ($ret) {
531 doprint "FAILED\n";
532 dodie "Failed to get git $commit";
533 }
534
535 print "SUCCESS\n";
536
537 chomp $sha1;
538
539 return $sha1;
540}
541
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400542sub monitor {
Steven Rostedt2545eb62010-11-02 15:01:32 -0400543 my $booted = 0;
544 my $bug = 0;
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400545 my $skip_call_trace = 0;
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400546 my $loops;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400547
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400548 wait_for_monitor 5;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400549
550 my $line;
551 my $full_line = "";
552
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400553 open(DMESG, "> $dmesg") or
554 die "unable to write to $dmesg";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400555
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400556 reboot_to;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400557
558 for (;;) {
559
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400560 if ($booted) {
Steven Rostedta75fece2010-11-02 14:58:27 -0400561 $line = wait_for_input($monitor_fp, $booted_timeout);
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400562 } else {
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400563 $line = wait_for_input($monitor_fp);
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400564 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400565
566 last if (!defined($line));
567
568 doprint $line;
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400569 print DMESG $line;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400570
571 # we are not guaranteed to get a full line
572 $full_line .= $line;
573
Steven Rostedta75fece2010-11-02 14:58:27 -0400574 if ($full_line =~ /$success_line/) {
Steven Rostedt2545eb62010-11-02 15:01:32 -0400575 $booted = 1;
576 }
577
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400578 if ($full_line =~ /\[ backtrace testing \]/) {
579 $skip_call_trace = 1;
580 }
581
Steven Rostedt2545eb62010-11-02 15:01:32 -0400582 if ($full_line =~ /call trace:/i) {
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400583 $bug = 1 if (!$skip_call_trace);
584 }
585
586 if ($full_line =~ /\[ end of backtrace testing \]/) {
587 $skip_call_trace = 0;
588 }
589
590 if ($full_line =~ /Kernel panic -/) {
Steven Rostedt2545eb62010-11-02 15:01:32 -0400591 $bug = 1;
592 }
593
594 if ($line =~ /\n/) {
595 $full_line = "";
596 }
597 }
598
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400599 close(DMESG);
Steven Rostedt2545eb62010-11-02 15:01:32 -0400600
Steven Rostedt2545eb62010-11-02 15:01:32 -0400601 if ($bug) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400602 return 0 if ($in_bisect);
Steven Rostedt576f6272010-11-02 14:58:38 -0400603 fail "failed - got a bug report" and return 0;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400604 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400605
Steven Rostedta75fece2010-11-02 14:58:27 -0400606 if (!$booted) {
607 return 0 if ($in_bisect);
Steven Rostedt576f6272010-11-02 14:58:38 -0400608 fail "failed - never got a boot prompt." and return 0;
Steven Rostedta75fece2010-11-02 14:58:27 -0400609 }
610
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400611 return 1;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400612}
613
614sub install {
615
Steven Rostedta75fece2010-11-02 14:58:27 -0400616 run_command "scp $outputdir/$build_target $target:$target_image" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400617 dodie "failed to copy image";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400618
619 my $install_mods = 0;
620
621 # should we process modules?
622 $install_mods = 0;
Steven Rostedt51ad1dd2010-11-08 16:43:21 -0500623 open(IN, "$output_config") or dodie("Can't read config file");
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400624 while (<IN>) {
625 if (/CONFIG_MODULES(=y)?/) {
626 $install_mods = 1 if (defined($1));
627 last;
628 }
629 }
630 close(IN);
631
632 if (!$install_mods) {
633 doprint "No modules needed\n";
634 return;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400635 }
636
Steven Rostedta75fece2010-11-02 14:58:27 -0400637 run_command "$make INSTALL_MOD_PATH=$tmpdir modules_install" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400638 dodie "Failed to install modules";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400639
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400640 my $modlib = "/lib/modules/$version";
Steven Rostedta57419b2010-11-02 15:13:54 -0400641 my $modtar = "ktest-mods.tar.bz2";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400642
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400643 run_command "ssh $target rm -rf $modlib" or
644 dodie "failed to remove old mods: $modlib";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400645
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400646 # would be nice if scp -r did not follow symbolic links
Steven Rostedta75fece2010-11-02 14:58:27 -0400647 run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400648 dodie "making tarball";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400649
Steven Rostedta75fece2010-11-02 14:58:27 -0400650 run_command "scp $tmpdir/$modtar $target:/tmp" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400651 dodie "failed to copy modules";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400652
Steven Rostedta75fece2010-11-02 14:58:27 -0400653 unlink "$tmpdir/$modtar";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400654
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400655 run_command "ssh $target '(cd / && tar xf /tmp/$modtar)'" or
656 dodie "failed to tar modules";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400657
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400658 run_command "ssh $target rm -f /tmp/$modtar";
Steven Rostedt8b37ca82010-11-02 14:58:33 -0400659
660 return if (!defined($post_install));
661
662 my $save_env = $ENV{KERNEL_VERSION};
663
664 $ENV{KERNEL_VERSION} = $version;
Steven Rostedt576f6272010-11-02 14:58:38 -0400665 run_command "$post_install" or
666 dodie "Failed to run post install";
Steven Rostedt8b37ca82010-11-02 14:58:33 -0400667
668 $ENV{KERNEL_VERSION} = $save_env;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400669}
670
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400671sub check_buildlog {
672 my ($patch) = @_;
673
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400674 my @files = `git show $patch | diffstat -l`;
675
676 open(IN, "git show $patch |") or
677 dodie "failed to show $patch";
678 while (<IN>) {
679 if (m,^--- a/(.*),) {
680 chomp $1;
681 $files[$#files] = $1;
682 }
683 }
684 close(IN);
685
686 open(IN, $buildlog) or dodie "Can't open $buildlog";
687 while (<IN>) {
688 if (/^\s*(.*?):.*(warning|error)/) {
689 my $err = $1;
690 foreach my $file (@files) {
Steven Rostedta75fece2010-11-02 14:58:27 -0400691 my $fullpath = "$builddir/$file";
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400692 if ($file eq $err || $fullpath eq $err) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400693 fail "$file built with warnings" and return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400694 }
695 }
696 }
697 }
698 close(IN);
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400699
700 return 1;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400701}
702
Steven Rostedt2545eb62010-11-02 15:01:32 -0400703sub build {
704 my ($type) = @_;
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400705 my $defconfig = "";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400706
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400707 unlink $buildlog;
708
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400709 if ($type =~ /^useconfig:(.*)/) {
Steven Rostedt51ad1dd2010-11-08 16:43:21 -0500710 run_command "cp $1 $output_config" or
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400711 dodie "could not copy $1 to .config";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400712
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400713 $type = "oldconfig";
714 }
715
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400716 # old config can ask questions
717 if ($type eq "oldconfig") {
Steven Rostedt9386c6a2010-11-08 16:35:48 -0500718 $type = "oldnoconfig";
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400719
720 # allow for empty configs
Steven Rostedt51ad1dd2010-11-08 16:43:21 -0500721 run_command "touch $output_config";
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400722
Steven Rostedt51ad1dd2010-11-08 16:43:21 -0500723 run_command "mv $output_config $outputdir/config_temp" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400724 dodie "moving .config";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400725
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400726 if (!$noclean && !run_command "$make mrproper") {
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400727 dodie "make mrproper";
728 }
729
Steven Rostedt51ad1dd2010-11-08 16:43:21 -0500730 run_command "mv $outputdir/config_temp $output_config" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400731 dodie "moving config_temp";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400732
733 } elsif (!$noclean) {
Steven Rostedt51ad1dd2010-11-08 16:43:21 -0500734 unlink "$output_config";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400735 run_command "$make mrproper" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400736 dodie "make mrproper";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400737 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400738
739 # add something to distinguish this build
Steven Rostedta75fece2010-11-02 14:58:27 -0400740 open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file");
741 print OUT "$localversion\n";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400742 close(OUT);
743
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400744 if (defined($minconfig)) {
745 $defconfig = "KCONFIG_ALLCONFIG=$minconfig";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400746 }
747
Steven Rostedt9386c6a2010-11-08 16:35:48 -0500748 run_command "$defconfig $make $type" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400749 dodie "failed make config";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400750
Steven Rostedta75fece2010-11-02 14:58:27 -0400751 $redirect = "$buildlog";
752 if (!run_command "$make $build_options") {
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400753 undef $redirect;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400754 # bisect may need this to pass
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400755 return 0 if ($in_bisect);
756 fail "failed build" and return 0;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400757 }
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400758 undef $redirect;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400759
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400760 return 1;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400761}
762
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400763sub halt {
Steven Rostedta75fece2010-11-02 14:58:27 -0400764 if (!run_command "ssh $target halt" or defined($power_off)) {
Steven Rostedt576f6272010-11-02 14:58:38 -0400765 if (defined($poweroff_after_halt)) {
766 sleep $poweroff_after_halt;
767 run_command "$power_off";
768 }
769 } else {
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400770 # nope? the zap it!
Steven Rostedta75fece2010-11-02 14:58:27 -0400771 run_command "$power_off";
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400772 }
773}
774
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400775sub success {
776 my ($i) = @_;
777
778 doprint "\n\n*******************************************\n";
779 doprint "*******************************************\n";
Steven Rostedta75fece2010-11-02 14:58:27 -0400780 doprint "** TEST $i SUCCESS!!!! **\n";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400781 doprint "*******************************************\n";
782 doprint "*******************************************\n";
783
Steven Rostedt576f6272010-11-02 14:58:38 -0400784 if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) {
Steven Rostedta75fece2010-11-02 14:58:27 -0400785 doprint "Reboot and wait $sleep_time seconds\n";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400786 reboot;
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400787 start_monitor;
Steven Rostedta75fece2010-11-02 14:58:27 -0400788 wait_for_monitor $sleep_time;
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400789 end_monitor;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400790 }
791}
792
793sub get_version {
794 # get the release name
795 doprint "$make kernelrelease ... ";
796 $version = `$make kernelrelease | tail -1`;
797 chomp($version);
798 doprint "$version\n";
799}
800
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400801sub child_run_test {
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400802 my $failed = 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400803
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400804 # child should have no power
Steven Rostedta75fece2010-11-02 14:58:27 -0400805 $reboot_on_error = 0;
806 $poweroff_on_error = 0;
807 $die_on_failure = 1;
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400808
809 run_command $run_test or $failed = 1;
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400810 exit $failed;
811}
812
813my $child_done;
814
815sub child_finished {
816 $child_done = 1;
817}
818
819sub do_run_test {
820 my $child_pid;
821 my $child_exit;
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400822 my $line;
823 my $full_line;
824 my $bug = 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400825
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400826 wait_for_monitor 1;
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400827
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400828 doprint "run test $run_test\n";
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400829
830 $child_done = 0;
831
832 $SIG{CHLD} = qw(child_finished);
833
834 $child_pid = fork;
835
836 child_run_test if (!$child_pid);
837
838 $full_line = "";
839
840 do {
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400841 $line = wait_for_input($monitor_fp, 1);
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400842 if (defined($line)) {
843
844 # we are not guaranteed to get a full line
845 $full_line .= $line;
846
847 if ($full_line =~ /call trace:/i) {
848 $bug = 1;
849 }
850
851 if ($full_line =~ /Kernel panic -/) {
852 $bug = 1;
853 }
854
855 if ($line =~ /\n/) {
856 $full_line = "";
857 }
858 }
859 } while (!$child_done && !$bug);
860
861 if ($bug) {
862 doprint "Detected kernel crash!\n";
863 # kill the child with extreme prejudice
864 kill 9, $child_pid;
865 }
866
867 waitpid $child_pid, 0;
868 $child_exit = $?;
869
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400870 if ($bug || $child_exit) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400871 return 0 if $in_bisect;
872 fail "test failed" and return 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400873 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400874 return 1;
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400875}
876
Steven Rostedta75fece2010-11-02 14:58:27 -0400877sub run_git_bisect {
878 my ($command) = @_;
879
880 doprint "$command ... ";
881
882 my $output = `$command 2>&1`;
883 my $ret = $?;
884
885 logit $output;
886
887 if ($ret) {
888 doprint "FAILED\n";
889 dodie "Failed to git bisect";
890 }
891
892 doprint "SUCCESS\n";
893 if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) {
894 doprint "$1 [$2]\n";
895 } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) {
896 $bisect_bad = $1;
897 doprint "Found bad commit... $1\n";
898 return 0;
899 } else {
900 # we already logged it, just print it now.
901 print $output;
902 }
903
904 return 1;
905}
906
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400907sub run_bisect {
908 my ($type) = @_;
909
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400910 my $failed = 0;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400911 my $result;
912 my $output;
913 my $ret;
914
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400915 if (defined($minconfig)) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400916 build "useconfig:$minconfig" or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400917 } else {
918 # ?? no config to use?
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400919 build "oldconfig" or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400920 }
921
922 if ($type ne "build") {
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400923 dodie "Failed on build" if $failed;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400924
925 # Now boot the box
926 get_grub_index;
927 get_version;
928 install;
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400929
930 start_monitor;
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400931 monitor or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400932
933 if ($type ne "boot") {
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400934 dodie "Failed on boot" if $failed;
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400935
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400936 do_run_test or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400937 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400938 end_monitor;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400939 }
940
941 if ($failed) {
942 $result = "bad";
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400943
944 # reboot the box to a good kernel
Steven Rostedta75fece2010-11-02 14:58:27 -0400945 if ($type ne "build") {
946 doprint "Reboot and sleep $bisect_sleep_time seconds\n";
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400947 reboot;
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400948 start_monitor;
Steven Rostedta75fece2010-11-02 14:58:27 -0400949 wait_for_monitor $bisect_sleep_time;
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400950 end_monitor;
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400951 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400952 } else {
953 $result = "good";
954 }
955
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400956 # Are we looking for where it worked, not failed?
957 if ($reverse_bisect) {
958 if ($failed) {
959 $result = "good";
960 } else {
961 $result = "bad";
962 }
963 }
964
Steven Rostedta75fece2010-11-02 14:58:27 -0400965 return $result;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400966}
967
968sub bisect {
969 my ($i) = @_;
970
971 my $result;
972
973 die "BISECT_GOOD[$i] not defined\n" if (!defined($opt{"BISECT_GOOD[$i]"}));
974 die "BISECT_BAD[$i] not defined\n" if (!defined($opt{"BISECT_BAD[$i]"}));
975 die "BISECT_TYPE[$i] not defined\n" if (!defined($opt{"BISECT_TYPE[$i]"}));
976
977 my $good = $opt{"BISECT_GOOD[$i]"};
978 my $bad = $opt{"BISECT_BAD[$i]"};
979 my $type = $opt{"BISECT_TYPE[$i]"};
Steven Rostedta75fece2010-11-02 14:58:27 -0400980 my $start = $opt{"BISECT_START[$i]"};
981 my $replay = $opt{"BISECT_REPLAY[$i]"};
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400982
Steven Rostedta57419b2010-11-02 15:13:54 -0400983 # convert to true sha1's
984 $good = get_sha1($good);
985 $bad = get_sha1($bad);
986
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400987 if (defined($opt{"BISECT_REVERSE[$i]"}) &&
988 $opt{"BISECT_REVERSE[$i]"} == 1) {
989 doprint "Performing a reverse bisect (bad is good, good is bad!)\n";
990 $reverse_bisect = 1;
991 } else {
992 $reverse_bisect = 0;
993 }
994
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400995 $in_bisect = 1;
996
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400997 # Can't have a test without having a test to run
998 if ($type eq "test" && !defined($run_test)) {
999 $type = "boot";
1000 }
1001
Steven Rostedta75fece2010-11-02 14:58:27 -04001002 my $check = $opt{"BISECT_CHECK[$i]"};
1003 if (defined($check) && $check ne "0") {
1004
1005 # get current HEAD
Steven Rostedta57419b2010-11-02 15:13:54 -04001006 my $head = get_sha1("HEAD");
Steven Rostedta75fece2010-11-02 14:58:27 -04001007
1008 if ($check ne "good") {
1009 doprint "TESTING BISECT BAD [$bad]\n";
1010 run_command "git checkout $bad" or
1011 die "Failed to checkout $bad";
1012
1013 $result = run_bisect $type;
1014
1015 if ($result ne "bad") {
1016 fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0;
1017 }
1018 }
1019
1020 if ($check ne "bad") {
1021 doprint "TESTING BISECT GOOD [$good]\n";
1022 run_command "git checkout $good" or
1023 die "Failed to checkout $good";
1024
1025 $result = run_bisect $type;
1026
1027 if ($result ne "good") {
1028 fail "Tested BISECT_GOOD [$good] and it failed" and return 0;
1029 }
1030 }
1031
1032 # checkout where we started
1033 run_command "git checkout $head" or
1034 die "Failed to checkout $head";
1035 }
1036
1037 run_command "git bisect start" or
1038 dodie "could not start bisect";
1039
1040 run_command "git bisect good $good" or
1041 dodie "could not set bisect good to $good";
1042
1043 run_git_bisect "git bisect bad $bad" or
1044 dodie "could not set bisect bad to $bad";
1045
1046 if (defined($replay)) {
1047 run_command "git bisect replay $replay" or
1048 dodie "failed to run replay";
1049 }
1050
1051 if (defined($start)) {
1052 run_command "git checkout $start" or
1053 dodie "failed to checkout $start";
1054 }
1055
1056 my $test;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001057 do {
1058 $result = run_bisect $type;
Steven Rostedta75fece2010-11-02 14:58:27 -04001059 $test = run_git_bisect "git bisect $result";
1060 } while ($test);
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001061
1062 run_command "git bisect log" or
1063 dodie "could not capture git bisect log";
1064
1065 run_command "git bisect reset" or
1066 dodie "could not reset git bisect";
1067
1068 doprint "Bad commit was [$bisect_bad]\n";
1069
1070 $in_bisect = 0;
1071
1072 success $i;
1073}
1074
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001075sub patchcheck {
1076 my ($i) = @_;
1077
1078 die "PATCHCHECK_START[$i] not defined\n"
1079 if (!defined($opt{"PATCHCHECK_START[$i]"}));
1080 die "PATCHCHECK_TYPE[$i] not defined\n"
1081 if (!defined($opt{"PATCHCHECK_TYPE[$i]"}));
1082
1083 my $start = $opt{"PATCHCHECK_START[$i]"};
1084
1085 my $end = "HEAD";
1086 if (defined($opt{"PATCHCHECK_END[$i]"})) {
1087 $end = $opt{"PATCHCHECK_END[$i]"};
1088 }
1089
Steven Rostedta57419b2010-11-02 15:13:54 -04001090 # Get the true sha1's since we can use things like HEAD~3
1091 $start = get_sha1($start);
1092 $end = get_sha1($end);
1093
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001094 my $type = $opt{"PATCHCHECK_TYPE[$i]"};
1095
1096 # Can't have a test without having a test to run
1097 if ($type eq "test" && !defined($run_test)) {
1098 $type = "boot";
1099 }
1100
1101 open (IN, "git log --pretty=oneline $end|") or
1102 dodie "could not get git list";
1103
1104 my @list;
1105
1106 while (<IN>) {
1107 chomp;
1108 $list[$#list+1] = $_;
1109 last if (/^$start/);
1110 }
1111 close(IN);
1112
1113 if ($list[$#list] !~ /^$start/) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001114 fail "SHA1 $start not found";
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001115 }
1116
1117 # go backwards in the list
1118 @list = reverse @list;
1119
1120 my $save_clean = $noclean;
1121
1122 $in_patchcheck = 1;
1123 foreach my $item (@list) {
1124 my $sha1 = $item;
1125 $sha1 =~ s/^([[:xdigit:]]+).*/$1/;
1126
1127 doprint "\nProcessing commit $item\n\n";
1128
1129 run_command "git checkout $sha1" or
1130 die "Failed to checkout $sha1";
1131
1132 # only clean on the first and last patch
1133 if ($item eq $list[0] ||
1134 $item eq $list[$#list]) {
1135 $noclean = $save_clean;
1136 } else {
1137 $noclean = 1;
1138 }
1139
1140 if (defined($minconfig)) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001141 build "useconfig:$minconfig" or return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001142 } else {
1143 # ?? no config to use?
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001144 build "oldconfig" or return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001145 }
1146
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001147 check_buildlog $sha1 or return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001148
1149 next if ($type eq "build");
1150
1151 get_grub_index;
1152 get_version;
1153 install;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001154
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001155 my $failed = 0;
1156
1157 start_monitor;
1158 monitor or $failed = 1;
1159
1160 if (!$failed && $type ne "boot"){
1161 do_run_test or $failed = 1;
1162 }
1163 end_monitor;
1164 return 0 if ($failed);
1165
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001166 }
1167 $in_patchcheck = 0;
1168 success $i;
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001169
1170 return 1;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001171}
1172
Steven Rostedt2545eb62010-11-02 15:01:32 -04001173read_config $ARGV[0];
1174
1175# mandatory configs
1176die "MACHINE not defined\n" if (!defined($opt{"MACHINE"}));
1177die "SSH_USER not defined\n" if (!defined($opt{"SSH_USER"}));
1178die "BUILD_DIR not defined\n" if (!defined($opt{"BUILD_DIR"}));
1179die "OUTPUT_DIR not defined\n" if (!defined($opt{"OUTPUT_DIR"}));
1180die "BUILD_TARGET not defined\n" if (!defined($opt{"BUILD_TARGET"}));
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001181die "TARGET_IMAGE not defined\n" if (!defined($opt{"TARGET_IMAGE"}));
Steven Rostedt2545eb62010-11-02 15:01:32 -04001182die "POWER_CYCLE not defined\n" if (!defined($opt{"POWER_CYCLE"}));
1183die "CONSOLE not defined\n" if (!defined($opt{"CONSOLE"}));
1184die "LOCALVERSION not defined\n" if (!defined($opt{"LOCALVERSION"}));
Steven Rostedt2545eb62010-11-02 15:01:32 -04001185
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001186if ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) {
1187 unlink $opt{"LOG_FILE"};
1188}
Steven Rostedt2545eb62010-11-02 15:01:32 -04001189
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001190doprint "\n\nSTARTING AUTOMATED TESTS\n\n";
1191
Steven Rostedta57419b2010-11-02 15:13:54 -04001192for (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) {
1193
1194 if (!$i) {
1195 doprint "DEFAULT OPTIONS:\n";
1196 } else {
1197 doprint "\nTEST $i OPTIONS";
1198 if (defined($repeat_tests{$i})) {
1199 $repeat = $repeat_tests{$i};
1200 doprint " ITERATE $repeat";
1201 }
1202 doprint "\n";
1203 }
1204
1205 foreach my $option (sort keys %opt) {
1206
1207 if ($option =~ /\[(\d+)\]$/) {
1208 next if ($i != $1);
1209 } else {
1210 next if ($i);
1211 }
1212
1213 doprint "$option = $opt{$option}\n";
1214 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001215}
Steven Rostedt2545eb62010-11-02 15:01:32 -04001216
Steven Rostedta75fece2010-11-02 14:58:27 -04001217sub set_test_option {
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001218 my ($name, $i) = @_;
1219
1220 my $option = "$name\[$i\]";
1221
1222 if (defined($opt{$option})) {
1223 return $opt{$option};
1224 }
1225
Steven Rostedta57419b2010-11-02 15:13:54 -04001226 foreach my $test (keys %repeat_tests) {
1227 if ($i >= $test &&
1228 $i < $test + $repeat_tests{$test}) {
1229 $option = "$name\[$test\]";
1230 if (defined($opt{$option})) {
1231 return $opt{$option};
1232 }
1233 }
1234 }
1235
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001236 if (defined($opt{$name})) {
1237 return $opt{$name};
1238 }
1239
1240 return undef;
1241}
1242
Steven Rostedt2545eb62010-11-02 15:01:32 -04001243# First we need to do is the builds
Steven Rostedta75fece2010-11-02 14:58:27 -04001244for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
Steven Rostedt2545eb62010-11-02 15:01:32 -04001245
Steven Rostedt576f6272010-11-02 14:58:38 -04001246 $iteration = $i;
1247
Steven Rostedta75fece2010-11-02 14:58:27 -04001248 my $ssh_user = set_test_option("SSH_USER", $i);
1249 my $makecmd = set_test_option("MAKE_CMD", $i);
1250
1251 $machine = set_test_option("MACHINE", $i);
1252 $tmpdir = set_test_option("TMP_DIR", $i);
1253 $outputdir = set_test_option("OUTPUT_DIR", $i);
1254 $builddir = set_test_option("BUILD_DIR", $i);
1255 $test_type = set_test_option("TEST_TYPE", $i);
1256 $build_type = set_test_option("BUILD_TYPE", $i);
1257 $build_options = set_test_option("BUILD_OPTIONS", $i);
1258 $power_cycle = set_test_option("POWER_CYCLE", $i);
1259 $noclean = set_test_option("BUILD_NOCLEAN", $i);
1260 $minconfig = set_test_option("MIN_CONFIG", $i);
1261 $run_test = set_test_option("TEST", $i);
1262 $addconfig = set_test_option("ADD_CONFIG", $i);
1263 $reboot_type = set_test_option("REBOOT_TYPE", $i);
1264 $grub_menu = set_test_option("GRUB_MENU", $i);
Steven Rostedt8b37ca82010-11-02 14:58:33 -04001265 $post_install = set_test_option("POST_INSTALL", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04001266 $reboot_script = set_test_option("REBOOT_SCRIPT", $i);
1267 $reboot_on_error = set_test_option("REBOOT_ON_ERROR", $i);
1268 $poweroff_on_error = set_test_option("POWEROFF_ON_ERROR", $i);
1269 $die_on_failure = set_test_option("DIE_ON_FAILURE", $i);
1270 $power_off = set_test_option("POWER_OFF", $i);
Steven Rostedt576f6272010-11-02 14:58:38 -04001271 $powercycle_after_reboot = set_test_option("POWERCYCLE_AFTER_REBOOT", $i);
1272 $poweroff_after_halt = set_test_option("POWEROFF_AFTER_HALT", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04001273 $sleep_time = set_test_option("SLEEP_TIME", $i);
1274 $bisect_sleep_time = set_test_option("BISECT_SLEEP_TIME", $i);
1275 $store_failures = set_test_option("STORE_FAILURES", $i);
1276 $timeout = set_test_option("TIMEOUT", $i);
1277 $booted_timeout = set_test_option("BOOTED_TIMEOUT", $i);
1278 $console = set_test_option("CONSOLE", $i);
1279 $success_line = set_test_option("SUCCESS_LINE", $i);
1280 $build_target = set_test_option("BUILD_TARGET", $i);
1281 $target_image = set_test_option("TARGET_IMAGE", $i);
1282 $localversion = set_test_option("LOCALVERSION", $i);
1283
1284 chdir $builddir || die "can't change directory to $builddir";
1285
1286 if (!-d $tmpdir) {
1287 mkpath($tmpdir) or
1288 die "can't create $tmpdir";
1289 }
1290
1291 $target = "$ssh_user\@$machine";
1292
1293 $buildlog = "$tmpdir/buildlog-$machine";
1294 $dmesg = "$tmpdir/dmesg-$machine";
1295 $make = "$makecmd O=$outputdir";
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05001296 $output_config = "$outputdir/.config";
Steven Rostedta75fece2010-11-02 14:58:27 -04001297
1298 if ($reboot_type eq "grub") {
Steven Rostedt576f6272010-11-02 14:58:38 -04001299 dodie "GRUB_MENU not defined" if (!defined($grub_menu));
Steven Rostedta75fece2010-11-02 14:58:27 -04001300 } elsif (!defined($reboot_script)) {
Steven Rostedt576f6272010-11-02 14:58:38 -04001301 dodie "REBOOT_SCRIPT not defined"
Steven Rostedta75fece2010-11-02 14:58:27 -04001302 }
1303
1304 my $run_type = $build_type;
1305 if ($test_type eq "patchcheck") {
1306 $run_type = $opt{"PATCHCHECK_TYPE[$i]"};
1307 } elsif ($test_type eq "bisect") {
1308 $run_type = $opt{"BISECT_TYPE[$i]"};
1309 }
1310
1311 # mistake in config file?
1312 if (!defined($run_type)) {
1313 $run_type = "ERROR";
1314 }
Steven Rostedt2545eb62010-11-02 15:01:32 -04001315
1316 doprint "\n\n";
Steven Rostedta75fece2010-11-02 14:58:27 -04001317 doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type\n\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001318
1319 unlink $dmesg;
1320 unlink $buildlog;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001321
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001322 if (!defined($minconfig)) {
1323 $minconfig = $addconfig;
1324
1325 } elsif (defined($addconfig)) {
Steven Rostedta75fece2010-11-02 14:58:27 -04001326 run_command "cat $addconfig $minconfig > $tmpdir/use_config" or
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001327 dodie "Failed to create temp config";
Steven Rostedta75fece2010-11-02 14:58:27 -04001328 $minconfig = "$tmpdir/use_config";
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001329 }
1330
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001331 my $checkout = $opt{"CHECKOUT[$i]"};
1332 if (defined($checkout)) {
1333 run_command "git checkout $checkout" or
1334 die "failed to checkout $checkout";
1335 }
1336
Steven Rostedta75fece2010-11-02 14:58:27 -04001337 if ($test_type eq "bisect") {
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001338 bisect $i;
1339 next;
Steven Rostedta75fece2010-11-02 14:58:27 -04001340 } elsif ($test_type eq "patchcheck") {
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001341 patchcheck $i;
1342 next;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001343 }
1344
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001345 if ($build_type ne "nobuild") {
1346 build $build_type or next;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001347 }
1348
Steven Rostedta75fece2010-11-02 14:58:27 -04001349 if ($test_type ne "build") {
1350 get_grub_index;
1351 get_version;
1352 install;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001353
Steven Rostedta75fece2010-11-02 14:58:27 -04001354 my $failed = 0;
1355 start_monitor;
1356 monitor or $failed = 1;;
1357
1358 if (!$failed && $test_type ne "boot" && defined($run_test)) {
1359 do_run_test or $failed = 1;
1360 }
1361 end_monitor;
1362 next if ($failed);
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001363 }
1364
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001365 success $i;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001366}
1367
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001368if ($opt{"POWEROFF_ON_SUCCESS"}) {
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001369 halt;
Steven Rostedt576f6272010-11-02 14:58:38 -04001370} elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot) {
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001371 reboot;
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001372}
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001373
Steven Rostedt2545eb62010-11-02 15:01:32 -04001374exit 0;