blob: 6620fe4b364f143dd3a9d602322649c07620ca2d [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 Rostedte48c5292010-11-02 14:35:37 -040014my $VERSION = "0.2";
15
Steven Rostedt2545eb62010-11-02 15:01:32 -040016$| = 1;
17
18my %opt;
Steven Rostedta57419b2010-11-02 15:13:54 -040019my %repeat_tests;
20my %repeats;
Steven Rostedta75fece2010-11-02 14:58:27 -040021my %default;
Steven Rostedt2545eb62010-11-02 15:01:32 -040022
23#default opts
Steven Rostedta57419b2010-11-02 15:13:54 -040024$default{"NUM_TESTS"} = 1;
Steven Rostedta75fece2010-11-02 14:58:27 -040025$default{"REBOOT_TYPE"} = "grub";
26$default{"TEST_TYPE"} = "test";
27$default{"BUILD_TYPE"} = "randconfig";
28$default{"MAKE_CMD"} = "make";
29$default{"TIMEOUT"} = 120;
Steven Rostedta57419b2010-11-02 15:13:54 -040030$default{"TMP_DIR"} = "/tmp/ktest";
Steven Rostedta75fece2010-11-02 14:58:27 -040031$default{"SLEEP_TIME"} = 60; # sleep time between tests
32$default{"BUILD_NOCLEAN"} = 0;
33$default{"REBOOT_ON_ERROR"} = 0;
34$default{"POWEROFF_ON_ERROR"} = 0;
35$default{"REBOOT_ON_SUCCESS"} = 1;
36$default{"POWEROFF_ON_SUCCESS"} = 0;
37$default{"BUILD_OPTIONS"} = "";
38$default{"BISECT_SLEEP_TIME"} = 60; # sleep time between bisects
39$default{"CLEAR_LOG"} = 0;
40$default{"SUCCESS_LINE"} = "login:";
41$default{"BOOTED_TIMEOUT"} = 1;
42$default{"DIE_ON_FAILURE"} = 1;
Steven Rostedte48c5292010-11-02 14:35:37 -040043$default{"SSH_EXEC"} = "ssh \$SSH_USER\@\$MACHINE \$SSH_COMMAND";
44$default{"SCP_TO_TARGET"} = "scp \$SRC_FILE \$SSH_USER\@\$MACHINE:\$DST_FILE";
45$default{"REBOOT"} = "ssh \$SSH_USER\@\$MACHINE reboot";
Steven Rostedt1c8a6172010-11-09 12:55:40 -050046$default{"STOP_AFTER_SUCCESS"} = 10;
47$default{"STOP_AFTER_FAILURE"} = 60;
Steven Rostedt8d1491b2010-11-18 15:39:48 -050048$default{"LOCALVERSION"} = "-test";
Steven Rostedt2545eb62010-11-02 15:01:32 -040049
Steven Rostedt8d1491b2010-11-18 15:39:48 -050050my $ktest_config;
Steven Rostedt2545eb62010-11-02 15:01:32 -040051my $version;
Steven Rostedta75fece2010-11-02 14:58:27 -040052my $machine;
Steven Rostedte48c5292010-11-02 14:35:37 -040053my $ssh_user;
Steven Rostedta75fece2010-11-02 14:58:27 -040054my $tmpdir;
55my $builddir;
56my $outputdir;
Steven Rostedt51ad1dd2010-11-08 16:43:21 -050057my $output_config;
Steven Rostedta75fece2010-11-02 14:58:27 -040058my $test_type;
Steven Rostedt7faafbd2010-11-02 14:58:22 -040059my $build_type;
Steven Rostedta75fece2010-11-02 14:58:27 -040060my $build_options;
61my $reboot_type;
62my $reboot_script;
63my $power_cycle;
Steven Rostedte48c5292010-11-02 14:35:37 -040064my $reboot;
Steven Rostedta75fece2010-11-02 14:58:27 -040065my $reboot_on_error;
66my $poweroff_on_error;
67my $die_on_failure;
Steven Rostedt576f6272010-11-02 14:58:38 -040068my $powercycle_after_reboot;
69my $poweroff_after_halt;
Steven Rostedte48c5292010-11-02 14:35:37 -040070my $ssh_exec;
71my $scp_to_target;
Steven Rostedta75fece2010-11-02 14:58:27 -040072my $power_off;
73my $grub_menu;
Steven Rostedt2545eb62010-11-02 15:01:32 -040074my $grub_number;
75my $target;
76my $make;
Steven Rostedt8b37ca82010-11-02 14:58:33 -040077my $post_install;
Steven Rostedt5c42fc52010-11-02 14:57:01 -040078my $noclean;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -040079my $minconfig;
Steven Rostedt2b7d9b22010-11-02 14:58:15 -040080my $addconfig;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -040081my $in_bisect = 0;
82my $bisect_bad = "";
Steven Rostedtd6ce2a02010-11-02 14:58:05 -040083my $reverse_bisect;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -040084my $in_patchcheck = 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -040085my $run_test;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -040086my $redirect;
Steven Rostedt7faafbd2010-11-02 14:58:22 -040087my $buildlog;
88my $dmesg;
89my $monitor_fp;
90my $monitor_pid;
91my $monitor_cnt = 0;
Steven Rostedta75fece2010-11-02 14:58:27 -040092my $sleep_time;
93my $bisect_sleep_time;
94my $store_failures;
95my $timeout;
96my $booted_timeout;
97my $console;
98my $success_line;
Steven Rostedt1c8a6172010-11-09 12:55:40 -050099my $stop_after_success;
100my $stop_after_failure;
Steven Rostedta75fece2010-11-02 14:58:27 -0400101my $build_target;
102my $target_image;
103my $localversion;
Steven Rostedt576f6272010-11-02 14:58:38 -0400104my $iteration = 0;
Steven Rostedte48c5292010-11-02 14:35:37 -0400105my $successes = 0;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400106
Steven Rostedt8d1491b2010-11-18 15:39:48 -0500107my %entered_configs;
108my %config_help;
109
110$config_help{"MACHINE"} = << "EOF"
111 The machine hostname that you will test.
112EOF
113 ;
114$config_help{"SSH_USER"} = << "EOF"
115 The box is expected to have ssh on normal bootup, provide the user
116 (most likely root, since you need privileged operations)
117EOF
118 ;
119$config_help{"BUILD_DIR"} = << "EOF"
120 The directory that contains the Linux source code (full path).
121EOF
122 ;
123$config_help{"OUTPUT_DIR"} = << "EOF"
124 The directory that the objects will be built (full path).
125 (can not be same as BUILD_DIR)
126EOF
127 ;
128$config_help{"BUILD_TARGET"} = << "EOF"
129 The location of the compiled file to copy to the target.
130 (relative to OUTPUT_DIR)
131EOF
132 ;
133$config_help{"TARGET_IMAGE"} = << "EOF"
134 The place to put your image on the test machine.
135EOF
136 ;
137$config_help{"POWER_CYCLE"} = << "EOF"
138 A script or command to reboot the box.
139
140 Here is a digital loggers power switch example
141 POWER_CYCLE = wget --no-proxy -O /dev/null -q --auth-no-challenge 'http://admin:admin\@power/outlet?5=CCL'
142
143 Here is an example to reboot a virtual box on the current host
144 with the name "Guest".
145 POWER_CYCLE = virsh destroy Guest; sleep 5; virsh start Guest
146EOF
147 ;
148$config_help{"CONSOLE"} = << "EOF"
149 The script or command that reads the console
150
151 If you use ttywatch server, something like the following would work.
152CONSOLE = nc -d localhost 3001
153
154 For a virtual machine with guest name "Guest".
155CONSOLE = virsh console Guest
156EOF
157 ;
158$config_help{"LOCALVERSION"} = << "EOF"
159 Required version ending to differentiate the test
160 from other linux builds on the system.
161EOF
162 ;
163$config_help{"REBOOT_TYPE"} = << "EOF"
164 Way to reboot the box to the test kernel.
165 Only valid options so far are "grub" and "script".
166
167 If you specify grub, it will assume grub version 1
168 and will search in /boot/grub/menu.lst for the title \$GRUB_MENU
169 and select that target to reboot to the kernel. If this is not
170 your setup, then specify "script" and have a command or script
171 specified in REBOOT_SCRIPT to boot to the target.
172
173 The entry in /boot/grub/menu.lst must be entered in manually.
174 The test will not modify that file.
175EOF
176 ;
177$config_help{"GRUB_MENU"} = << "EOF"
178 The grub title name for the test kernel to boot
179 (Only mandatory if REBOOT_TYPE = grub)
180
181 Note, ktest.pl will not update the grub menu.lst, you need to
182 manually add an option for the test. ktest.pl will search
183 the grub menu.lst for this option to find what kernel to
184 reboot into.
185
186 For example, if in the /boot/grub/menu.lst the test kernel title has:
187 title Test Kernel
188 kernel vmlinuz-test
189 GRUB_MENU = Test Kernel
190EOF
191 ;
192$config_help{"REBOOT_SCRIPT"} = << "EOF"
193 A script to reboot the target into the test kernel
194 (Only mandatory if REBOOT_TYPE = script)
195EOF
196 ;
197
198
199sub get_ktest_config {
200 my ($config) = @_;
201
202 return if (defined($opt{$config}));
203
204 if (defined($config_help{$config})) {
205 print "\n";
206 print $config_help{$config};
207 }
208
209 for (;;) {
210 print "$config = ";
211 if (defined($default{$config})) {
212 print "\[$default{$config}\] ";
213 }
214 $entered_configs{$config} = <STDIN>;
215 $entered_configs{$config} =~ s/^\s*(.*\S)\s*$/$1/;
216 if ($entered_configs{$config} =~ /^\s*$/) {
217 if ($default{$config}) {
218 $entered_configs{$config} = $default{$config};
219 } else {
220 print "Your answer can not be blank\n";
221 next;
222 }
223 }
224 last;
225 }
226}
227
228sub get_ktest_configs {
229 get_ktest_config("MACHINE");
230 get_ktest_config("SSH_USER");
231 get_ktest_config("BUILD_DIR");
232 get_ktest_config("OUTPUT_DIR");
233 get_ktest_config("BUILD_TARGET");
234 get_ktest_config("TARGET_IMAGE");
235 get_ktest_config("POWER_CYCLE");
236 get_ktest_config("CONSOLE");
237 get_ktest_config("LOCALVERSION");
238
239 my $rtype = $opt{"REBOOT_TYPE"};
240
241 if (!defined($rtype)) {
242 if (!defined($opt{"GRUB_MENU"})) {
243 get_ktest_config("REBOOT_TYPE");
244 $rtype = $entered_configs{"REBOOT_TYPE"};
245 } else {
246 $rtype = "grub";
247 }
248 }
249
250 if ($rtype eq "grub") {
251 get_ktest_config("GRUB_MENU");
252 } else {
253 get_ktest_config("REBOOT_SCRIPT");
254 }
255}
256
Steven Rostedta57419b2010-11-02 15:13:54 -0400257sub set_value {
258 my ($lvalue, $rvalue) = @_;
259
260 if (defined($opt{$lvalue})) {
261 die "Error: Option $lvalue defined more than once!\n";
262 }
Steven Rostedt21a96792010-11-08 16:45:50 -0500263 if ($rvalue =~ /^\s*$/) {
264 delete $opt{$lvalue};
265 } else {
266 $opt{$lvalue} = $rvalue;
267 }
Steven Rostedta57419b2010-11-02 15:13:54 -0400268}
269
Steven Rostedt2545eb62010-11-02 15:01:32 -0400270sub read_config {
271 my ($config) = @_;
272
273 open(IN, $config) || die "can't read file $config";
274
Steven Rostedta57419b2010-11-02 15:13:54 -0400275 my $name = $config;
276 $name =~ s,.*/(.*),$1,;
277
278 my $test_num = 0;
279 my $default = 1;
280 my $repeat = 1;
281 my $num_tests_set = 0;
282 my $skip = 0;
283 my $rest;
284
Steven Rostedt2545eb62010-11-02 15:01:32 -0400285 while (<IN>) {
286
287 # ignore blank lines and comments
288 next if (/^\s*$/ || /\s*\#/);
289
Steven Rostedta57419b2010-11-02 15:13:54 -0400290 if (/^\s*TEST_START(.*)/) {
291
292 $rest = $1;
293
294 if ($num_tests_set) {
295 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
296 }
297
298 my $old_test_num = $test_num;
Steven Rostedte48c5292010-11-02 14:35:37 -0400299 my $old_repeat = $repeat;
Steven Rostedta57419b2010-11-02 15:13:54 -0400300
301 $test_num += $repeat;
302 $default = 0;
303 $repeat = 1;
304
305 if ($rest =~ /\s+SKIP(.*)/) {
306 $rest = $1;
307 $skip = 1;
308 } else {
309 $skip = 0;
310 }
311
312 if ($rest =~ /\s+ITERATE\s+(\d+)(.*)$/) {
313 $repeat = $1;
314 $rest = $2;
315 $repeat_tests{"$test_num"} = $repeat;
316 }
317
318 if ($rest =~ /\s+SKIP(.*)/) {
319 $rest = $1;
320 $skip = 1;
321 }
322
323 if ($rest !~ /^\s*$/) {
324 die "$name: $.: Gargbage found after TEST_START\n$_";
325 }
326
327 if ($skip) {
328 $test_num = $old_test_num;
Steven Rostedte48c5292010-11-02 14:35:37 -0400329 $repeat = $old_repeat;
Steven Rostedta57419b2010-11-02 15:13:54 -0400330 }
331
332 } elsif (/^\s*DEFAULTS(.*)$/) {
333 $default = 1;
334
335 $rest = $1;
336
337 if ($rest =~ /\s+SKIP(.*)/) {
338 $rest = $1;
339 $skip = 1;
340 } else {
341 $skip = 0;
342 }
343
344 if ($rest !~ /^\s*$/) {
345 die "$name: $.: Gargbage found after DEFAULTS\n$_";
346 }
347
348 } elsif (/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) {
349
350 next if ($skip);
351
Steven Rostedt2545eb62010-11-02 15:01:32 -0400352 my $lvalue = $1;
353 my $rvalue = $2;
354
Steven Rostedta57419b2010-11-02 15:13:54 -0400355 if (!$default &&
356 ($lvalue eq "NUM_TESTS" ||
357 $lvalue eq "LOG_FILE" ||
358 $lvalue eq "CLEAR_LOG")) {
359 die "$name: $.: $lvalue must be set in DEFAULTS section\n";
Steven Rostedta75fece2010-11-02 14:58:27 -0400360 }
Steven Rostedta57419b2010-11-02 15:13:54 -0400361
362 if ($lvalue eq "NUM_TESTS") {
363 if ($test_num) {
364 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
365 }
366 if (!$default) {
367 die "$name: $.: NUM_TESTS must be set in default section\n";
368 }
369 $num_tests_set = 1;
370 }
371
372 if ($default || $lvalue =~ /\[\d+\]$/) {
373 set_value($lvalue, $rvalue);
374 } else {
375 my $val = "$lvalue\[$test_num\]";
376 set_value($val, $rvalue);
377
378 if ($repeat > 1) {
379 $repeats{$val} = $repeat;
380 }
381 }
382 } else {
383 die "$name: $.: Garbage found in config\n$_";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400384 }
385 }
386
387 close(IN);
Steven Rostedta75fece2010-11-02 14:58:27 -0400388
Steven Rostedta57419b2010-11-02 15:13:54 -0400389 if ($test_num) {
390 $test_num += $repeat - 1;
391 $opt{"NUM_TESTS"} = $test_num;
392 }
393
Steven Rostedt8d1491b2010-11-18 15:39:48 -0500394 # make sure we have all mandatory configs
395 get_ktest_configs;
396
Steven Rostedta75fece2010-11-02 14:58:27 -0400397 # set any defaults
398
399 foreach my $default (keys %default) {
400 if (!defined($opt{$default})) {
401 $opt{$default} = $default{$default};
402 }
403 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400404}
405
Steven Rostedtd1e2f222010-11-08 16:39:57 -0500406sub _logit {
Steven Rostedt2545eb62010-11-02 15:01:32 -0400407 if (defined($opt{"LOG_FILE"})) {
408 open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}";
409 print OUT @_;
410 close(OUT);
411 }
412}
413
Steven Rostedtd1e2f222010-11-08 16:39:57 -0500414sub logit {
415 if (defined($opt{"LOG_FILE"})) {
416 _logit @_;
417 } else {
418 print @_;
419 }
420}
421
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400422sub doprint {
423 print @_;
Steven Rostedtd1e2f222010-11-08 16:39:57 -0500424 _logit @_;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400425}
426
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400427sub run_command;
428
429sub reboot {
430 # try to reboot normally
Steven Rostedte48c5292010-11-02 14:35:37 -0400431 if (run_command $reboot) {
Steven Rostedt576f6272010-11-02 14:58:38 -0400432 if (defined($powercycle_after_reboot)) {
433 sleep $powercycle_after_reboot;
434 run_command "$power_cycle";
435 }
436 } else {
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400437 # nope? power cycle it.
Steven Rostedta75fece2010-11-02 14:58:27 -0400438 run_command "$power_cycle";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400439 }
440}
441
Steven Rostedt576f6272010-11-02 14:58:38 -0400442sub do_not_reboot {
443 my $i = $iteration;
444
445 return $test_type eq "build" ||
446 ($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") ||
447 ($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build");
448}
449
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400450sub dodie {
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400451 doprint "CRITICAL FAILURE... ", @_, "\n";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400452
Steven Rostedt576f6272010-11-02 14:58:38 -0400453 my $i = $iteration;
454
455 if ($reboot_on_error && !do_not_reboot) {
456
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400457 doprint "REBOOTING\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400458 reboot;
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400459
Steven Rostedta75fece2010-11-02 14:58:27 -0400460 } elsif ($poweroff_on_error && defined($power_off)) {
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400461 doprint "POWERING OFF\n";
Steven Rostedta75fece2010-11-02 14:58:27 -0400462 `$power_off`;
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400463 }
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400464
Steven Rostedtf80802c2011-03-07 13:18:47 -0500465 if (defined($opt{"LOG_FILE"})) {
466 print " See $opt{LOG_FILE} for more info.\n";
467 }
468
Steven Rostedt576f6272010-11-02 14:58:38 -0400469 die @_, "\n";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400470}
471
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400472sub open_console {
473 my ($fp) = @_;
474
475 my $flags;
476
Steven Rostedta75fece2010-11-02 14:58:27 -0400477 my $pid = open($fp, "$console|") or
478 dodie "Can't open console $console";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400479
480 $flags = fcntl($fp, F_GETFL, 0) or
Steven Rostedt576f6272010-11-02 14:58:38 -0400481 dodie "Can't get flags for the socket: $!";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400482 $flags = fcntl($fp, F_SETFL, $flags | O_NONBLOCK) or
Steven Rostedt576f6272010-11-02 14:58:38 -0400483 dodie "Can't set flags for the socket: $!";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400484
485 return $pid;
486}
487
488sub close_console {
489 my ($fp, $pid) = @_;
490
491 doprint "kill child process $pid\n";
492 kill 2, $pid;
493
494 print "closing!\n";
495 close($fp);
496}
497
498sub start_monitor {
499 if ($monitor_cnt++) {
500 return;
501 }
502 $monitor_fp = \*MONFD;
503 $monitor_pid = open_console $monitor_fp;
Steven Rostedta75fece2010-11-02 14:58:27 -0400504
505 return;
506
507 open(MONFD, "Stop perl from warning about single use of MONFD");
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400508}
509
510sub end_monitor {
511 if (--$monitor_cnt) {
512 return;
513 }
514 close_console($monitor_fp, $monitor_pid);
515}
516
517sub wait_for_monitor {
518 my ($time) = @_;
519 my $line;
520
Steven Rostedta75fece2010-11-02 14:58:27 -0400521 doprint "** Wait for monitor to settle down **\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400522
523 # read the monitor and wait for the system to calm down
524 do {
525 $line = wait_for_input($monitor_fp, $time);
Steven Rostedta75fece2010-11-02 14:58:27 -0400526 print "$line" if (defined($line));
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400527 } while (defined($line));
Steven Rostedta75fece2010-11-02 14:58:27 -0400528 print "** Monitor flushed **\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400529}
530
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400531sub fail {
532
Steven Rostedta75fece2010-11-02 14:58:27 -0400533 if ($die_on_failure) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400534 dodie @_;
535 }
536
Steven Rostedta75fece2010-11-02 14:58:27 -0400537 doprint "FAILED\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400538
Steven Rostedt576f6272010-11-02 14:58:38 -0400539 my $i = $iteration;
540
Steven Rostedta75fece2010-11-02 14:58:27 -0400541 # no need to reboot for just building.
Steven Rostedt576f6272010-11-02 14:58:38 -0400542 if (!do_not_reboot) {
Steven Rostedta75fece2010-11-02 14:58:27 -0400543 doprint "REBOOTING\n";
544 reboot;
545 start_monitor;
546 wait_for_monitor $sleep_time;
547 end_monitor;
548 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400549
Steven Rostedt576f6272010-11-02 14:58:38 -0400550 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
551 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
Steven Rostedt7a849cd2010-11-08 16:49:25 -0500552 doprint "KTEST RESULT: TEST $i Failed: ", @_, "\n";
Steven Rostedt576f6272010-11-02 14:58:38 -0400553 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
554 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
Steven Rostedta75fece2010-11-02 14:58:27 -0400555
556 return 1 if (!defined($store_failures));
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400557
558 my @t = localtime;
559 my $date = sprintf "%04d%02d%02d%02d%02d%02d",
560 1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0];
561
Steven Rostedtcccae1a2010-11-09 12:21:32 -0500562 my $type = $build_type;
563 if ($type =~ /useconfig/) {
564 $type = "useconfig";
565 }
566
567 my $dir = "$machine-$test_type-$type-fail-$date";
Steven Rostedta75fece2010-11-02 14:58:27 -0400568 my $faildir = "$store_failures/$dir";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400569
570 if (!-d $faildir) {
571 mkpath($faildir) or
Steven Rostedta75fece2010-11-02 14:58:27 -0400572 die "can't create $faildir";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400573 }
Steven Rostedt51ad1dd2010-11-08 16:43:21 -0500574 if (-f "$output_config") {
575 cp "$output_config", "$faildir/config" or
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400576 die "failed to copy .config";
577 }
578 if (-f $buildlog) {
579 cp $buildlog, "$faildir/buildlog" or
580 die "failed to move $buildlog";
581 }
582 if (-f $dmesg) {
583 cp $dmesg, "$faildir/dmesg" or
584 die "failed to move $dmesg";
585 }
586
587 doprint "*** Saved info to $faildir ***\n";
588
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400589 return 1;
590}
591
Steven Rostedt2545eb62010-11-02 15:01:32 -0400592sub run_command {
593 my ($command) = @_;
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400594 my $dolog = 0;
595 my $dord = 0;
596 my $pid;
597
Steven Rostedte48c5292010-11-02 14:35:37 -0400598 $command =~ s/\$SSH_USER/$ssh_user/g;
599 $command =~ s/\$MACHINE/$machine/g;
600
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400601 doprint("$command ... ");
602
603 $pid = open(CMD, "$command 2>&1 |") or
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400604 (fail "unable to exec $command" and return 0);
Steven Rostedt2545eb62010-11-02 15:01:32 -0400605
606 if (defined($opt{"LOG_FILE"})) {
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400607 open(LOG, ">>$opt{LOG_FILE}") or
608 dodie "failed to write to log";
609 $dolog = 1;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400610 }
611
612 if (defined($redirect)) {
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400613 open (RD, ">$redirect") or
614 dodie "failed to write to redirect $redirect";
615 $dord = 1;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400616 }
617
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400618 while (<CMD>) {
619 print LOG if ($dolog);
620 print RD if ($dord);
621 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400622
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400623 waitpid($pid, 0);
Steven Rostedt2545eb62010-11-02 15:01:32 -0400624 my $failed = $?;
625
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400626 close(CMD);
627 close(LOG) if ($dolog);
628 close(RD) if ($dord);
629
Steven Rostedt2545eb62010-11-02 15:01:32 -0400630 if ($failed) {
631 doprint "FAILED!\n";
632 } else {
633 doprint "SUCCESS\n";
634 }
635
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400636 return !$failed;
637}
638
Steven Rostedte48c5292010-11-02 14:35:37 -0400639sub run_ssh {
640 my ($cmd) = @_;
641 my $cp_exec = $ssh_exec;
642
643 $cp_exec =~ s/\$SSH_COMMAND/$cmd/g;
644 return run_command "$cp_exec";
645}
646
647sub run_scp {
648 my ($src, $dst) = @_;
649 my $cp_scp = $scp_to_target;
650
651 $cp_scp =~ s/\$SRC_FILE/$src/g;
652 $cp_scp =~ s/\$DST_FILE/$dst/g;
653
654 return run_command "$cp_scp";
655}
656
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400657sub get_grub_index {
658
Steven Rostedta75fece2010-11-02 14:58:27 -0400659 if ($reboot_type ne "grub") {
660 return;
661 }
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400662 return if (defined($grub_number));
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400663
664 doprint "Find grub menu ... ";
665 $grub_number = -1;
Steven Rostedte48c5292010-11-02 14:35:37 -0400666
667 my $ssh_grub = $ssh_exec;
668 $ssh_grub =~ s,\$SSH_COMMAND,cat /boot/grub/menu.lst,g;
669
670 open(IN, "$ssh_grub |")
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400671 or die "unable to get menu.lst";
Steven Rostedte48c5292010-11-02 14:35:37 -0400672
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400673 while (<IN>) {
Steven Rostedta75fece2010-11-02 14:58:27 -0400674 if (/^\s*title\s+$grub_menu\s*$/) {
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400675 $grub_number++;
676 last;
677 } elsif (/^\s*title\s/) {
678 $grub_number++;
679 }
680 }
681 close(IN);
682
Steven Rostedta75fece2010-11-02 14:58:27 -0400683 die "Could not find '$grub_menu' in /boot/grub/menu on $machine"
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400684 if ($grub_number < 0);
685 doprint "$grub_number\n";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400686}
687
Steven Rostedt2545eb62010-11-02 15:01:32 -0400688sub wait_for_input
689{
690 my ($fp, $time) = @_;
691 my $rin;
692 my $ready;
693 my $line;
694 my $ch;
695
696 if (!defined($time)) {
697 $time = $timeout;
698 }
699
700 $rin = '';
701 vec($rin, fileno($fp), 1) = 1;
702 $ready = select($rin, undef, undef, $time);
703
704 $line = "";
705
706 # try to read one char at a time
707 while (sysread $fp, $ch, 1) {
708 $line .= $ch;
709 last if ($ch eq "\n");
710 }
711
712 if (!length($line)) {
713 return undef;
714 }
715
716 return $line;
717}
718
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400719sub reboot_to {
Steven Rostedta75fece2010-11-02 14:58:27 -0400720 if ($reboot_type eq "grub") {
Steven Rostedteec56462010-11-10 09:08:20 -0500721 run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch; reboot)'";
Steven Rostedta75fece2010-11-02 14:58:27 -0400722 return;
723 }
724
725 run_command "$reboot_script";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400726}
727
Steven Rostedta57419b2010-11-02 15:13:54 -0400728sub get_sha1 {
729 my ($commit) = @_;
730
731 doprint "git rev-list --max-count=1 $commit ... ";
732 my $sha1 = `git rev-list --max-count=1 $commit`;
733 my $ret = $?;
734
735 logit $sha1;
736
737 if ($ret) {
738 doprint "FAILED\n";
739 dodie "Failed to get git $commit";
740 }
741
742 print "SUCCESS\n";
743
744 chomp $sha1;
745
746 return $sha1;
747}
748
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400749sub monitor {
Steven Rostedt2545eb62010-11-02 15:01:32 -0400750 my $booted = 0;
751 my $bug = 0;
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400752 my $skip_call_trace = 0;
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400753 my $loops;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400754
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400755 wait_for_monitor 5;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400756
757 my $line;
758 my $full_line = "";
759
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400760 open(DMESG, "> $dmesg") or
761 die "unable to write to $dmesg";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400762
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400763 reboot_to;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400764
Steven Rostedt1c8a6172010-11-09 12:55:40 -0500765 my $success_start;
766 my $failure_start;
767
Steven Rostedt2545eb62010-11-02 15:01:32 -0400768 for (;;) {
769
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400770 if ($booted) {
Steven Rostedta75fece2010-11-02 14:58:27 -0400771 $line = wait_for_input($monitor_fp, $booted_timeout);
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400772 } else {
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400773 $line = wait_for_input($monitor_fp);
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400774 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400775
776 last if (!defined($line));
777
778 doprint $line;
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400779 print DMESG $line;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400780
781 # we are not guaranteed to get a full line
782 $full_line .= $line;
783
Steven Rostedta75fece2010-11-02 14:58:27 -0400784 if ($full_line =~ /$success_line/) {
Steven Rostedt2545eb62010-11-02 15:01:32 -0400785 $booted = 1;
Steven Rostedt1c8a6172010-11-09 12:55:40 -0500786 $success_start = time;
787 }
788
789 if ($booted && defined($stop_after_success) &&
790 $stop_after_success >= 0) {
791 my $now = time;
792 if ($now - $success_start >= $stop_after_success) {
793 doprint "Test forced to stop after $stop_after_success seconds after success\n";
794 last;
795 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400796 }
797
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400798 if ($full_line =~ /\[ backtrace testing \]/) {
799 $skip_call_trace = 1;
800 }
801
Steven Rostedt2545eb62010-11-02 15:01:32 -0400802 if ($full_line =~ /call trace:/i) {
Steven Rostedt1c8a6172010-11-09 12:55:40 -0500803 if (!$skip_call_trace) {
804 $bug = 1;
805 $failure_start = time;
806 }
807 }
808
809 if ($bug && defined($stop_after_failure) &&
810 $stop_after_failure >= 0) {
811 my $now = time;
812 if ($now - $failure_start >= $stop_after_failure) {
813 doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
814 last;
815 }
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400816 }
817
818 if ($full_line =~ /\[ end of backtrace testing \]/) {
819 $skip_call_trace = 0;
820 }
821
822 if ($full_line =~ /Kernel panic -/) {
Steven Rostedt10abf112011-03-07 13:21:00 -0500823 $failure_start = time;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400824 $bug = 1;
825 }
826
827 if ($line =~ /\n/) {
828 $full_line = "";
829 }
830 }
831
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400832 close(DMESG);
Steven Rostedt2545eb62010-11-02 15:01:32 -0400833
Steven Rostedt2545eb62010-11-02 15:01:32 -0400834 if ($bug) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400835 return 0 if ($in_bisect);
Steven Rostedt576f6272010-11-02 14:58:38 -0400836 fail "failed - got a bug report" and return 0;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400837 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400838
Steven Rostedta75fece2010-11-02 14:58:27 -0400839 if (!$booted) {
840 return 0 if ($in_bisect);
Steven Rostedt576f6272010-11-02 14:58:38 -0400841 fail "failed - never got a boot prompt." and return 0;
Steven Rostedta75fece2010-11-02 14:58:27 -0400842 }
843
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400844 return 1;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400845}
846
847sub install {
848
Steven Rostedte48c5292010-11-02 14:35:37 -0400849 run_scp "$outputdir/$build_target", "$target_image" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400850 dodie "failed to copy image";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400851
852 my $install_mods = 0;
853
854 # should we process modules?
855 $install_mods = 0;
Steven Rostedt51ad1dd2010-11-08 16:43:21 -0500856 open(IN, "$output_config") or dodie("Can't read config file");
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400857 while (<IN>) {
858 if (/CONFIG_MODULES(=y)?/) {
859 $install_mods = 1 if (defined($1));
860 last;
861 }
862 }
863 close(IN);
864
865 if (!$install_mods) {
866 doprint "No modules needed\n";
867 return;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400868 }
869
Steven Rostedta75fece2010-11-02 14:58:27 -0400870 run_command "$make INSTALL_MOD_PATH=$tmpdir modules_install" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400871 dodie "Failed to install modules";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400872
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400873 my $modlib = "/lib/modules/$version";
Steven Rostedta57419b2010-11-02 15:13:54 -0400874 my $modtar = "ktest-mods.tar.bz2";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400875
Steven Rostedte48c5292010-11-02 14:35:37 -0400876 run_ssh "rm -rf $modlib" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400877 dodie "failed to remove old mods: $modlib";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400878
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400879 # would be nice if scp -r did not follow symbolic links
Steven Rostedta75fece2010-11-02 14:58:27 -0400880 run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400881 dodie "making tarball";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400882
Steven Rostedte48c5292010-11-02 14:35:37 -0400883 run_scp "$tmpdir/$modtar", "/tmp" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400884 dodie "failed to copy modules";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400885
Steven Rostedta75fece2010-11-02 14:58:27 -0400886 unlink "$tmpdir/$modtar";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400887
Steven Rostedte48c5292010-11-02 14:35:37 -0400888 run_ssh "'(cd / && tar xf /tmp/$modtar)'" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400889 dodie "failed to tar modules";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400890
Steven Rostedte48c5292010-11-02 14:35:37 -0400891 run_ssh "rm -f /tmp/$modtar";
Steven Rostedt8b37ca82010-11-02 14:58:33 -0400892
893 return if (!defined($post_install));
894
Steven Rostedte48c5292010-11-02 14:35:37 -0400895 my $cp_post_install = $post_install;
896 $cp_post_install = s/\$KERNEL_VERSION/$version/g;
897 run_command "$cp_post_install" or
Steven Rostedt576f6272010-11-02 14:58:38 -0400898 dodie "Failed to run post install";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400899}
900
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400901sub check_buildlog {
902 my ($patch) = @_;
903
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400904 my @files = `git show $patch | diffstat -l`;
905
906 open(IN, "git show $patch |") or
907 dodie "failed to show $patch";
908 while (<IN>) {
909 if (m,^--- a/(.*),) {
910 chomp $1;
911 $files[$#files] = $1;
912 }
913 }
914 close(IN);
915
916 open(IN, $buildlog) or dodie "Can't open $buildlog";
917 while (<IN>) {
918 if (/^\s*(.*?):.*(warning|error)/) {
919 my $err = $1;
920 foreach my $file (@files) {
Steven Rostedta75fece2010-11-02 14:58:27 -0400921 my $fullpath = "$builddir/$file";
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400922 if ($file eq $err || $fullpath eq $err) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400923 fail "$file built with warnings" and return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400924 }
925 }
926 }
927 }
928 close(IN);
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400929
930 return 1;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400931}
932
Steven Rostedt2545eb62010-11-02 15:01:32 -0400933sub build {
934 my ($type) = @_;
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400935 my $defconfig = "";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400936
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400937 unlink $buildlog;
938
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400939 if ($type =~ /^useconfig:(.*)/) {
Steven Rostedt51ad1dd2010-11-08 16:43:21 -0500940 run_command "cp $1 $output_config" or
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400941 dodie "could not copy $1 to .config";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400942
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400943 $type = "oldconfig";
944 }
945
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400946 # old config can ask questions
947 if ($type eq "oldconfig") {
Steven Rostedt9386c6a2010-11-08 16:35:48 -0500948 $type = "oldnoconfig";
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400949
950 # allow for empty configs
Steven Rostedt51ad1dd2010-11-08 16:43:21 -0500951 run_command "touch $output_config";
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400952
Steven Rostedt51ad1dd2010-11-08 16:43:21 -0500953 run_command "mv $output_config $outputdir/config_temp" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400954 dodie "moving .config";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400955
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400956 if (!$noclean && !run_command "$make mrproper") {
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400957 dodie "make mrproper";
958 }
959
Steven Rostedt51ad1dd2010-11-08 16:43:21 -0500960 run_command "mv $outputdir/config_temp $output_config" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400961 dodie "moving config_temp";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400962
963 } elsif (!$noclean) {
Steven Rostedt51ad1dd2010-11-08 16:43:21 -0500964 unlink "$output_config";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400965 run_command "$make mrproper" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400966 dodie "make mrproper";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400967 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400968
969 # add something to distinguish this build
Steven Rostedta75fece2010-11-02 14:58:27 -0400970 open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file");
971 print OUT "$localversion\n";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400972 close(OUT);
973
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400974 if (defined($minconfig)) {
975 $defconfig = "KCONFIG_ALLCONFIG=$minconfig";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400976 }
977
Steven Rostedt9386c6a2010-11-08 16:35:48 -0500978 run_command "$defconfig $make $type" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400979 dodie "failed make config";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400980
Steven Rostedta75fece2010-11-02 14:58:27 -0400981 $redirect = "$buildlog";
982 if (!run_command "$make $build_options") {
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400983 undef $redirect;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400984 # bisect may need this to pass
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400985 return 0 if ($in_bisect);
986 fail "failed build" and return 0;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400987 }
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400988 undef $redirect;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400989
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400990 return 1;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400991}
992
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400993sub halt {
Steven Rostedte48c5292010-11-02 14:35:37 -0400994 if (!run_ssh "halt" or defined($power_off)) {
Steven Rostedt576f6272010-11-02 14:58:38 -0400995 if (defined($poweroff_after_halt)) {
996 sleep $poweroff_after_halt;
997 run_command "$power_off";
998 }
999 } else {
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001000 # nope? the zap it!
Steven Rostedta75fece2010-11-02 14:58:27 -04001001 run_command "$power_off";
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001002 }
1003}
1004
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001005sub success {
1006 my ($i) = @_;
1007
Steven Rostedte48c5292010-11-02 14:35:37 -04001008 $successes++;
1009
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001010 doprint "\n\n*******************************************\n";
1011 doprint "*******************************************\n";
Steven Rostedt7a849cd2010-11-08 16:49:25 -05001012 doprint "KTEST RESULT: TEST $i SUCCESS!!!! **\n";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001013 doprint "*******************************************\n";
1014 doprint "*******************************************\n";
1015
Steven Rostedt576f6272010-11-02 14:58:38 -04001016 if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) {
Steven Rostedta75fece2010-11-02 14:58:27 -04001017 doprint "Reboot and wait $sleep_time seconds\n";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001018 reboot;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001019 start_monitor;
Steven Rostedta75fece2010-11-02 14:58:27 -04001020 wait_for_monitor $sleep_time;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001021 end_monitor;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001022 }
1023}
1024
1025sub get_version {
1026 # get the release name
1027 doprint "$make kernelrelease ... ";
1028 $version = `$make kernelrelease | tail -1`;
1029 chomp($version);
1030 doprint "$version\n";
1031}
1032
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001033sub child_run_test {
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001034 my $failed = 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001035
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001036 # child should have no power
Steven Rostedta75fece2010-11-02 14:58:27 -04001037 $reboot_on_error = 0;
1038 $poweroff_on_error = 0;
1039 $die_on_failure = 1;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001040
1041 run_command $run_test or $failed = 1;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001042 exit $failed;
1043}
1044
1045my $child_done;
1046
1047sub child_finished {
1048 $child_done = 1;
1049}
1050
1051sub do_run_test {
1052 my $child_pid;
1053 my $child_exit;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001054 my $line;
1055 my $full_line;
1056 my $bug = 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001057
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001058 wait_for_monitor 1;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001059
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001060 doprint "run test $run_test\n";
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001061
1062 $child_done = 0;
1063
1064 $SIG{CHLD} = qw(child_finished);
1065
1066 $child_pid = fork;
1067
1068 child_run_test if (!$child_pid);
1069
1070 $full_line = "";
1071
1072 do {
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001073 $line = wait_for_input($monitor_fp, 1);
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001074 if (defined($line)) {
1075
1076 # we are not guaranteed to get a full line
1077 $full_line .= $line;
1078
1079 if ($full_line =~ /call trace:/i) {
1080 $bug = 1;
1081 }
1082
1083 if ($full_line =~ /Kernel panic -/) {
1084 $bug = 1;
1085 }
1086
1087 if ($line =~ /\n/) {
1088 $full_line = "";
1089 }
1090 }
1091 } while (!$child_done && !$bug);
1092
1093 if ($bug) {
1094 doprint "Detected kernel crash!\n";
1095 # kill the child with extreme prejudice
1096 kill 9, $child_pid;
1097 }
1098
1099 waitpid $child_pid, 0;
1100 $child_exit = $?;
1101
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001102 if ($bug || $child_exit) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001103 return 0 if $in_bisect;
1104 fail "test failed" and return 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001105 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001106 return 1;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001107}
1108
Steven Rostedta75fece2010-11-02 14:58:27 -04001109sub run_git_bisect {
1110 my ($command) = @_;
1111
1112 doprint "$command ... ";
1113
1114 my $output = `$command 2>&1`;
1115 my $ret = $?;
1116
1117 logit $output;
1118
1119 if ($ret) {
1120 doprint "FAILED\n";
1121 dodie "Failed to git bisect";
1122 }
1123
1124 doprint "SUCCESS\n";
1125 if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) {
1126 doprint "$1 [$2]\n";
1127 } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) {
1128 $bisect_bad = $1;
1129 doprint "Found bad commit... $1\n";
1130 return 0;
1131 } else {
1132 # we already logged it, just print it now.
1133 print $output;
1134 }
1135
1136 return 1;
1137}
1138
Steven Rostedt0a05c762010-11-08 11:14:10 -05001139# returns 1 on success, 0 on failure
1140sub run_bisect_test {
1141 my ($type, $buildtype) = @_;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001142
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001143 my $failed = 0;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001144 my $result;
1145 my $output;
1146 my $ret;
1147
Steven Rostedt0a05c762010-11-08 11:14:10 -05001148 $in_bisect = 1;
1149
1150 build $buildtype or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001151
1152 if ($type ne "build") {
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001153 dodie "Failed on build" if $failed;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001154
1155 # Now boot the box
1156 get_grub_index;
1157 get_version;
1158 install;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001159
1160 start_monitor;
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001161 monitor or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001162
1163 if ($type ne "boot") {
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001164 dodie "Failed on boot" if $failed;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001165
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001166 do_run_test or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001167 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001168 end_monitor;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001169 }
1170
1171 if ($failed) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001172 $result = 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001173
1174 # reboot the box to a good kernel
Steven Rostedta75fece2010-11-02 14:58:27 -04001175 if ($type ne "build") {
1176 doprint "Reboot and sleep $bisect_sleep_time seconds\n";
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001177 reboot;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001178 start_monitor;
Steven Rostedta75fece2010-11-02 14:58:27 -04001179 wait_for_monitor $bisect_sleep_time;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001180 end_monitor;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001181 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001182 } else {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001183 $result = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001184 }
Steven Rostedt0a05c762010-11-08 11:14:10 -05001185 $in_bisect = 0;
1186
1187 return $result;
1188}
1189
1190sub run_bisect {
1191 my ($type) = @_;
1192 my $buildtype = "oldconfig";
1193
1194 # We should have a minconfig to use?
1195 if (defined($minconfig)) {
1196 $buildtype = "useconfig:$minconfig";
1197 }
1198
1199 my $ret = run_bisect_test $type, $buildtype;
1200
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001201
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04001202 # Are we looking for where it worked, not failed?
1203 if ($reverse_bisect) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001204 $ret = !$ret;
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04001205 }
1206
Steven Rostedt0a05c762010-11-08 11:14:10 -05001207 if ($ret) {
1208 return "good";
1209 } else {
1210 return "bad";
1211 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001212}
1213
1214sub bisect {
1215 my ($i) = @_;
1216
1217 my $result;
1218
1219 die "BISECT_GOOD[$i] not defined\n" if (!defined($opt{"BISECT_GOOD[$i]"}));
1220 die "BISECT_BAD[$i] not defined\n" if (!defined($opt{"BISECT_BAD[$i]"}));
1221 die "BISECT_TYPE[$i] not defined\n" if (!defined($opt{"BISECT_TYPE[$i]"}));
1222
1223 my $good = $opt{"BISECT_GOOD[$i]"};
1224 my $bad = $opt{"BISECT_BAD[$i]"};
1225 my $type = $opt{"BISECT_TYPE[$i]"};
Steven Rostedta75fece2010-11-02 14:58:27 -04001226 my $start = $opt{"BISECT_START[$i]"};
1227 my $replay = $opt{"BISECT_REPLAY[$i]"};
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001228
Steven Rostedta57419b2010-11-02 15:13:54 -04001229 # convert to true sha1's
1230 $good = get_sha1($good);
1231 $bad = get_sha1($bad);
1232
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04001233 if (defined($opt{"BISECT_REVERSE[$i]"}) &&
1234 $opt{"BISECT_REVERSE[$i]"} == 1) {
1235 doprint "Performing a reverse bisect (bad is good, good is bad!)\n";
1236 $reverse_bisect = 1;
1237 } else {
1238 $reverse_bisect = 0;
1239 }
1240
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001241 # Can't have a test without having a test to run
1242 if ($type eq "test" && !defined($run_test)) {
1243 $type = "boot";
1244 }
1245
Steven Rostedta75fece2010-11-02 14:58:27 -04001246 my $check = $opt{"BISECT_CHECK[$i]"};
1247 if (defined($check) && $check ne "0") {
1248
1249 # get current HEAD
Steven Rostedta57419b2010-11-02 15:13:54 -04001250 my $head = get_sha1("HEAD");
Steven Rostedta75fece2010-11-02 14:58:27 -04001251
1252 if ($check ne "good") {
1253 doprint "TESTING BISECT BAD [$bad]\n";
1254 run_command "git checkout $bad" or
1255 die "Failed to checkout $bad";
1256
1257 $result = run_bisect $type;
1258
1259 if ($result ne "bad") {
1260 fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0;
1261 }
1262 }
1263
1264 if ($check ne "bad") {
1265 doprint "TESTING BISECT GOOD [$good]\n";
1266 run_command "git checkout $good" or
1267 die "Failed to checkout $good";
1268
1269 $result = run_bisect $type;
1270
1271 if ($result ne "good") {
1272 fail "Tested BISECT_GOOD [$good] and it failed" and return 0;
1273 }
1274 }
1275
1276 # checkout where we started
1277 run_command "git checkout $head" or
1278 die "Failed to checkout $head";
1279 }
1280
1281 run_command "git bisect start" or
1282 dodie "could not start bisect";
1283
1284 run_command "git bisect good $good" or
1285 dodie "could not set bisect good to $good";
1286
1287 run_git_bisect "git bisect bad $bad" or
1288 dodie "could not set bisect bad to $bad";
1289
1290 if (defined($replay)) {
1291 run_command "git bisect replay $replay" or
1292 dodie "failed to run replay";
1293 }
1294
1295 if (defined($start)) {
1296 run_command "git checkout $start" or
1297 dodie "failed to checkout $start";
1298 }
1299
1300 my $test;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001301 do {
1302 $result = run_bisect $type;
Steven Rostedta75fece2010-11-02 14:58:27 -04001303 $test = run_git_bisect "git bisect $result";
1304 } while ($test);
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001305
1306 run_command "git bisect log" or
1307 dodie "could not capture git bisect log";
1308
1309 run_command "git bisect reset" or
1310 dodie "could not reset git bisect";
1311
1312 doprint "Bad commit was [$bisect_bad]\n";
1313
Steven Rostedt0a05c762010-11-08 11:14:10 -05001314 success $i;
1315}
1316
1317my %config_ignore;
1318my %config_set;
1319
1320my %config_list;
1321my %null_config;
1322
1323my %dependency;
1324
1325sub process_config_ignore {
1326 my ($config) = @_;
1327
1328 open (IN, $config)
1329 or dodie "Failed to read $config";
1330
1331 while (<IN>) {
1332 if (/^(.*?(CONFIG\S*)(=.*| is not set))/) {
1333 $config_ignore{$2} = $1;
1334 }
1335 }
1336
1337 close(IN);
1338}
1339
1340sub read_current_config {
1341 my ($config_ref) = @_;
1342
1343 %{$config_ref} = ();
1344 undef %{$config_ref};
1345
1346 my @key = keys %{$config_ref};
1347 if ($#key >= 0) {
1348 print "did not delete!\n";
1349 exit;
1350 }
1351 open (IN, "$output_config");
1352
1353 while (<IN>) {
1354 if (/^(CONFIG\S+)=(.*)/) {
1355 ${$config_ref}{$1} = $2;
1356 }
1357 }
1358 close(IN);
1359}
1360
1361sub get_dependencies {
1362 my ($config) = @_;
1363
1364 my $arr = $dependency{$config};
1365 if (!defined($arr)) {
1366 return ();
1367 }
1368
1369 my @deps = @{$arr};
1370
1371 foreach my $dep (@{$arr}) {
1372 print "ADD DEP $dep\n";
1373 @deps = (@deps, get_dependencies $dep);
1374 }
1375
1376 return @deps;
1377}
1378
1379sub create_config {
1380 my @configs = @_;
1381
1382 open(OUT, ">$output_config") or dodie "Can not write to $output_config";
1383
1384 foreach my $config (@configs) {
1385 print OUT "$config_set{$config}\n";
1386 my @deps = get_dependencies $config;
1387 foreach my $dep (@deps) {
1388 print OUT "$config_set{$dep}\n";
1389 }
1390 }
1391
1392 foreach my $config (keys %config_ignore) {
1393 print OUT "$config_ignore{$config}\n";
1394 }
1395 close(OUT);
1396
1397# exit;
1398 run_command "$make oldnoconfig" or
1399 dodie "failed make config oldconfig";
1400
1401}
1402
1403sub compare_configs {
1404 my (%a, %b) = @_;
1405
1406 foreach my $item (keys %a) {
1407 if (!defined($b{$item})) {
1408 print "diff $item\n";
1409 return 1;
1410 }
1411 delete $b{$item};
1412 }
1413
1414 my @keys = keys %b;
1415 if ($#keys) {
1416 print "diff2 $keys[0]\n";
1417 }
1418 return -1 if ($#keys >= 0);
1419
1420 return 0;
1421}
1422
1423sub run_config_bisect_test {
1424 my ($type) = @_;
1425
1426 return run_bisect_test $type, "oldconfig";
1427}
1428
1429sub process_passed {
1430 my (%configs) = @_;
1431
1432 doprint "These configs had no failure: (Enabling them for further compiles)\n";
1433 # Passed! All these configs are part of a good compile.
1434 # Add them to the min options.
1435 foreach my $config (keys %configs) {
1436 if (defined($config_list{$config})) {
1437 doprint " removing $config\n";
1438 $config_ignore{$config} = $config_list{$config};
1439 delete $config_list{$config};
1440 }
1441 }
Steven Rostedtf1a27852010-11-11 11:34:38 -05001442 doprint "config copied to $outputdir/config_good\n";
1443 run_command "cp -f $output_config $outputdir/config_good";
Steven Rostedt0a05c762010-11-08 11:14:10 -05001444}
1445
1446sub process_failed {
1447 my ($config) = @_;
1448
1449 doprint "\n\n***************************************\n";
1450 doprint "Found bad config: $config\n";
1451 doprint "***************************************\n\n";
1452}
1453
1454sub run_config_bisect {
1455
1456 my @start_list = keys %config_list;
1457
1458 if ($#start_list < 0) {
1459 doprint "No more configs to test!!!\n";
1460 return -1;
1461 }
1462
1463 doprint "***** RUN TEST ***\n";
1464 my $type = $opt{"CONFIG_BISECT_TYPE[$iteration]"};
1465 my $ret;
1466 my %current_config;
1467
1468 my $count = $#start_list + 1;
1469 doprint " $count configs to test\n";
1470
1471 my $half = int($#start_list / 2);
1472
1473 do {
1474 my @tophalf = @start_list[0 .. $half];
1475
1476 create_config @tophalf;
1477 read_current_config \%current_config;
1478
1479 $count = $#tophalf + 1;
1480 doprint "Testing $count configs\n";
1481 my $found = 0;
1482 # make sure we test something
1483 foreach my $config (@tophalf) {
1484 if (defined($current_config{$config})) {
1485 logit " $config\n";
1486 $found = 1;
1487 }
1488 }
1489 if (!$found) {
1490 # try the other half
1491 doprint "Top half produced no set configs, trying bottom half\n";
1492 @tophalf = @start_list[$half .. $#start_list];
1493 create_config @tophalf;
1494 read_current_config \%current_config;
1495 foreach my $config (@tophalf) {
1496 if (defined($current_config{$config})) {
1497 logit " $config\n";
1498 $found = 1;
1499 }
1500 }
1501 if (!$found) {
1502 doprint "Failed: Can't make new config with current configs\n";
1503 foreach my $config (@start_list) {
1504 doprint " CONFIG: $config\n";
1505 }
1506 return -1;
1507 }
1508 $count = $#tophalf + 1;
1509 doprint "Testing $count configs\n";
1510 }
1511
1512 $ret = run_config_bisect_test $type;
1513
1514 if ($ret) {
1515 process_passed %current_config;
1516 return 0;
1517 }
1518
1519 doprint "This config had a failure.\n";
1520 doprint "Removing these configs that were not set in this config:\n";
Steven Rostedtf1a27852010-11-11 11:34:38 -05001521 doprint "config copied to $outputdir/config_bad\n";
1522 run_command "cp -f $output_config $outputdir/config_bad";
Steven Rostedt0a05c762010-11-08 11:14:10 -05001523
1524 # A config exists in this group that was bad.
1525 foreach my $config (keys %config_list) {
1526 if (!defined($current_config{$config})) {
1527 doprint " removing $config\n";
1528 delete $config_list{$config};
1529 }
1530 }
1531
1532 @start_list = @tophalf;
1533
1534 if ($#start_list == 0) {
1535 process_failed $start_list[0];
1536 return 1;
1537 }
1538
1539 # remove half the configs we are looking at and see if
1540 # they are good.
1541 $half = int($#start_list / 2);
1542 } while ($half > 0);
1543
1544 # we found a single config, try it again
1545 my @tophalf = @start_list[0 .. 0];
1546
1547 $ret = run_config_bisect_test $type;
1548 if ($ret) {
1549 process_passed %current_config;
1550 return 0;
1551 }
1552
1553 process_failed $start_list[0];
1554 return 1;
1555}
1556
1557sub config_bisect {
1558 my ($i) = @_;
1559
1560 my $start_config = $opt{"CONFIG_BISECT[$i]"};
1561
1562 my $tmpconfig = "$tmpdir/use_config";
1563
1564 # Make the file with the bad config and the min config
1565 if (defined($minconfig)) {
1566 # read the min config for things to ignore
1567 run_command "cp $minconfig $tmpconfig" or
1568 dodie "failed to copy $minconfig to $tmpconfig";
1569 } else {
1570 unlink $tmpconfig;
1571 }
1572
1573 # Add other configs
1574 if (defined($addconfig)) {
1575 run_command "cat $addconfig >> $tmpconfig" or
1576 dodie "failed to append $addconfig";
1577 }
1578
1579 my $defconfig = "";
1580 if (-f $tmpconfig) {
1581 $defconfig = "KCONFIG_ALLCONFIG=$tmpconfig";
1582 process_config_ignore $tmpconfig;
1583 }
1584
1585 # now process the start config
1586 run_command "cp $start_config $output_config" or
1587 dodie "failed to copy $start_config to $output_config";
1588
1589 # read directly what we want to check
1590 my %config_check;
1591 open (IN, $output_config)
1592 or dodie "faied to open $output_config";
1593
1594 while (<IN>) {
1595 if (/^((CONFIG\S*)=.*)/) {
1596 $config_check{$2} = $1;
1597 }
1598 }
1599 close(IN);
1600
1601 # Now run oldconfig with the minconfig (and addconfigs)
1602 run_command "$defconfig $make oldnoconfig" or
1603 dodie "failed make config oldconfig";
1604
1605 # check to see what we lost (or gained)
1606 open (IN, $output_config)
1607 or dodie "Failed to read $start_config";
1608
1609 my %removed_configs;
1610 my %added_configs;
1611
1612 while (<IN>) {
1613 if (/^((CONFIG\S*)=.*)/) {
1614 # save off all options
1615 $config_set{$2} = $1;
1616 if (defined($config_check{$2})) {
1617 if (defined($config_ignore{$2})) {
1618 $removed_configs{$2} = $1;
1619 } else {
1620 $config_list{$2} = $1;
1621 }
1622 } elsif (!defined($config_ignore{$2})) {
1623 $added_configs{$2} = $1;
1624 $config_list{$2} = $1;
1625 }
1626 }
1627 }
1628 close(IN);
1629
1630 my @confs = keys %removed_configs;
1631 if ($#confs >= 0) {
1632 doprint "Configs overridden by default configs and removed from check:\n";
1633 foreach my $config (@confs) {
1634 doprint " $config\n";
1635 }
1636 }
1637 @confs = keys %added_configs;
1638 if ($#confs >= 0) {
1639 doprint "Configs appearing in make oldconfig and added:\n";
1640 foreach my $config (@confs) {
1641 doprint " $config\n";
1642 }
1643 }
1644
1645 my %config_test;
1646 my $once = 0;
1647
1648 # Sometimes kconfig does weird things. We must make sure
1649 # that the config we autocreate has everything we need
1650 # to test, otherwise we may miss testing configs, or
1651 # may not be able to create a new config.
1652 # Here we create a config with everything set.
1653 create_config (keys %config_list);
1654 read_current_config \%config_test;
1655 foreach my $config (keys %config_list) {
1656 if (!defined($config_test{$config})) {
1657 if (!$once) {
1658 $once = 1;
1659 doprint "Configs not produced by kconfig (will not be checked):\n";
1660 }
1661 doprint " $config\n";
1662 delete $config_list{$config};
1663 }
1664 }
1665 my $ret;
1666 do {
1667 $ret = run_config_bisect;
1668 } while (!$ret);
1669
1670 return $ret if ($ret < 0);
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001671
1672 success $i;
1673}
1674
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001675sub patchcheck {
1676 my ($i) = @_;
1677
1678 die "PATCHCHECK_START[$i] not defined\n"
1679 if (!defined($opt{"PATCHCHECK_START[$i]"}));
1680 die "PATCHCHECK_TYPE[$i] not defined\n"
1681 if (!defined($opt{"PATCHCHECK_TYPE[$i]"}));
1682
1683 my $start = $opt{"PATCHCHECK_START[$i]"};
1684
1685 my $end = "HEAD";
1686 if (defined($opt{"PATCHCHECK_END[$i]"})) {
1687 $end = $opt{"PATCHCHECK_END[$i]"};
1688 }
1689
Steven Rostedta57419b2010-11-02 15:13:54 -04001690 # Get the true sha1's since we can use things like HEAD~3
1691 $start = get_sha1($start);
1692 $end = get_sha1($end);
1693
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001694 my $type = $opt{"PATCHCHECK_TYPE[$i]"};
1695
1696 # Can't have a test without having a test to run
1697 if ($type eq "test" && !defined($run_test)) {
1698 $type = "boot";
1699 }
1700
1701 open (IN, "git log --pretty=oneline $end|") or
1702 dodie "could not get git list";
1703
1704 my @list;
1705
1706 while (<IN>) {
1707 chomp;
1708 $list[$#list+1] = $_;
1709 last if (/^$start/);
1710 }
1711 close(IN);
1712
1713 if ($list[$#list] !~ /^$start/) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001714 fail "SHA1 $start not found";
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001715 }
1716
1717 # go backwards in the list
1718 @list = reverse @list;
1719
1720 my $save_clean = $noclean;
1721
1722 $in_patchcheck = 1;
1723 foreach my $item (@list) {
1724 my $sha1 = $item;
1725 $sha1 =~ s/^([[:xdigit:]]+).*/$1/;
1726
1727 doprint "\nProcessing commit $item\n\n";
1728
1729 run_command "git checkout $sha1" or
1730 die "Failed to checkout $sha1";
1731
1732 # only clean on the first and last patch
1733 if ($item eq $list[0] ||
1734 $item eq $list[$#list]) {
1735 $noclean = $save_clean;
1736 } else {
1737 $noclean = 1;
1738 }
1739
1740 if (defined($minconfig)) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001741 build "useconfig:$minconfig" or return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001742 } else {
1743 # ?? no config to use?
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001744 build "oldconfig" or return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001745 }
1746
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001747 check_buildlog $sha1 or return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001748
1749 next if ($type eq "build");
1750
1751 get_grub_index;
1752 get_version;
1753 install;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001754
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001755 my $failed = 0;
1756
1757 start_monitor;
1758 monitor or $failed = 1;
1759
1760 if (!$failed && $type ne "boot"){
1761 do_run_test or $failed = 1;
1762 }
1763 end_monitor;
1764 return 0 if ($failed);
1765
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001766 }
1767 $in_patchcheck = 0;
1768 success $i;
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001769
1770 return 1;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001771}
1772
Steven Rostedt8d1491b2010-11-18 15:39:48 -05001773$#ARGV < 1 or die "ktest.pl version: $VERSION\n usage: ktest.pl config-file\n";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001774
Steven Rostedt8d1491b2010-11-18 15:39:48 -05001775if ($#ARGV == 0) {
1776 $ktest_config = $ARGV[0];
1777 if (! -f $ktest_config) {
1778 print "$ktest_config does not exist.\n";
1779 my $ans;
1780 for (;;) {
1781 print "Create it? [Y/n] ";
1782 $ans = <STDIN>;
1783 chomp $ans;
1784 if ($ans =~ /^\s*$/) {
1785 $ans = "y";
1786 }
1787 last if ($ans =~ /^y$/i || $ans =~ /^n$/i);
1788 print "Please answer either 'y' or 'n'.\n";
1789 }
1790 if ($ans !~ /^y$/i) {
1791 exit 0;
1792 }
1793 }
1794} else {
1795 $ktest_config = "ktest.conf";
1796}
1797
1798if (! -f $ktest_config) {
1799 open(OUT, ">$ktest_config") or die "Can not create $ktest_config";
1800 print OUT << "EOF"
1801# Generated by ktest.pl
1802#
1803# Define each test with TEST_START
1804# The config options below it will override the defaults
1805TEST_START
1806
1807DEFAULTS
1808EOF
1809;
1810 close(OUT);
1811}
1812read_config $ktest_config;
1813
1814# Append any configs entered in manually to the config file.
1815my @new_configs = keys %entered_configs;
1816if ($#new_configs >= 0) {
1817 print "\nAppending entered in configs to $ktest_config\n";
1818 open(OUT, ">>$ktest_config") or die "Can not append to $ktest_config";
1819 foreach my $config (@new_configs) {
1820 print OUT "$config = $entered_configs{$config}\n";
1821 $opt{$config} = $entered_configs{$config};
1822 }
1823}
Steven Rostedt2545eb62010-11-02 15:01:32 -04001824
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001825if ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) {
1826 unlink $opt{"LOG_FILE"};
1827}
Steven Rostedt2545eb62010-11-02 15:01:32 -04001828
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001829doprint "\n\nSTARTING AUTOMATED TESTS\n\n";
1830
Steven Rostedta57419b2010-11-02 15:13:54 -04001831for (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) {
1832
1833 if (!$i) {
1834 doprint "DEFAULT OPTIONS:\n";
1835 } else {
1836 doprint "\nTEST $i OPTIONS";
1837 if (defined($repeat_tests{$i})) {
1838 $repeat = $repeat_tests{$i};
1839 doprint " ITERATE $repeat";
1840 }
1841 doprint "\n";
1842 }
1843
1844 foreach my $option (sort keys %opt) {
1845
1846 if ($option =~ /\[(\d+)\]$/) {
1847 next if ($i != $1);
1848 } else {
1849 next if ($i);
1850 }
1851
1852 doprint "$option = $opt{$option}\n";
1853 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001854}
Steven Rostedt2545eb62010-11-02 15:01:32 -04001855
Steven Rostedta75fece2010-11-02 14:58:27 -04001856sub set_test_option {
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001857 my ($name, $i) = @_;
1858
1859 my $option = "$name\[$i\]";
1860
1861 if (defined($opt{$option})) {
1862 return $opt{$option};
1863 }
1864
Steven Rostedta57419b2010-11-02 15:13:54 -04001865 foreach my $test (keys %repeat_tests) {
1866 if ($i >= $test &&
1867 $i < $test + $repeat_tests{$test}) {
1868 $option = "$name\[$test\]";
1869 if (defined($opt{$option})) {
1870 return $opt{$option};
1871 }
1872 }
1873 }
1874
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001875 if (defined($opt{$name})) {
1876 return $opt{$name};
1877 }
1878
1879 return undef;
1880}
1881
Steven Rostedt2545eb62010-11-02 15:01:32 -04001882# First we need to do is the builds
Steven Rostedta75fece2010-11-02 14:58:27 -04001883for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
Steven Rostedt2545eb62010-11-02 15:01:32 -04001884
Steven Rostedt576f6272010-11-02 14:58:38 -04001885 $iteration = $i;
1886
Steven Rostedta75fece2010-11-02 14:58:27 -04001887 my $makecmd = set_test_option("MAKE_CMD", $i);
1888
1889 $machine = set_test_option("MACHINE", $i);
Steven Rostedte48c5292010-11-02 14:35:37 -04001890 $ssh_user = set_test_option("SSH_USER", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04001891 $tmpdir = set_test_option("TMP_DIR", $i);
1892 $outputdir = set_test_option("OUTPUT_DIR", $i);
1893 $builddir = set_test_option("BUILD_DIR", $i);
1894 $test_type = set_test_option("TEST_TYPE", $i);
1895 $build_type = set_test_option("BUILD_TYPE", $i);
1896 $build_options = set_test_option("BUILD_OPTIONS", $i);
1897 $power_cycle = set_test_option("POWER_CYCLE", $i);
Steven Rostedte48c5292010-11-02 14:35:37 -04001898 $reboot = set_test_option("REBOOT", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04001899 $noclean = set_test_option("BUILD_NOCLEAN", $i);
1900 $minconfig = set_test_option("MIN_CONFIG", $i);
1901 $run_test = set_test_option("TEST", $i);
1902 $addconfig = set_test_option("ADD_CONFIG", $i);
1903 $reboot_type = set_test_option("REBOOT_TYPE", $i);
1904 $grub_menu = set_test_option("GRUB_MENU", $i);
Steven Rostedt8b37ca82010-11-02 14:58:33 -04001905 $post_install = set_test_option("POST_INSTALL", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04001906 $reboot_script = set_test_option("REBOOT_SCRIPT", $i);
1907 $reboot_on_error = set_test_option("REBOOT_ON_ERROR", $i);
1908 $poweroff_on_error = set_test_option("POWEROFF_ON_ERROR", $i);
1909 $die_on_failure = set_test_option("DIE_ON_FAILURE", $i);
1910 $power_off = set_test_option("POWER_OFF", $i);
Steven Rostedt576f6272010-11-02 14:58:38 -04001911 $powercycle_after_reboot = set_test_option("POWERCYCLE_AFTER_REBOOT", $i);
1912 $poweroff_after_halt = set_test_option("POWEROFF_AFTER_HALT", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04001913 $sleep_time = set_test_option("SLEEP_TIME", $i);
1914 $bisect_sleep_time = set_test_option("BISECT_SLEEP_TIME", $i);
1915 $store_failures = set_test_option("STORE_FAILURES", $i);
1916 $timeout = set_test_option("TIMEOUT", $i);
1917 $booted_timeout = set_test_option("BOOTED_TIMEOUT", $i);
1918 $console = set_test_option("CONSOLE", $i);
1919 $success_line = set_test_option("SUCCESS_LINE", $i);
Steven Rostedt1c8a6172010-11-09 12:55:40 -05001920 $stop_after_success = set_test_option("STOP_AFTER_SUCCESS", $i);
1921 $stop_after_failure = set_test_option("STOP_AFTER_FAILURE", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04001922 $build_target = set_test_option("BUILD_TARGET", $i);
Steven Rostedte48c5292010-11-02 14:35:37 -04001923 $ssh_exec = set_test_option("SSH_EXEC", $i);
1924 $scp_to_target = set_test_option("SCP_TO_TARGET", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04001925 $target_image = set_test_option("TARGET_IMAGE", $i);
1926 $localversion = set_test_option("LOCALVERSION", $i);
1927
1928 chdir $builddir || die "can't change directory to $builddir";
1929
1930 if (!-d $tmpdir) {
1931 mkpath($tmpdir) or
1932 die "can't create $tmpdir";
1933 }
1934
Steven Rostedte48c5292010-11-02 14:35:37 -04001935 $ENV{"SSH_USER"} = $ssh_user;
1936 $ENV{"MACHINE"} = $machine;
1937
Steven Rostedta75fece2010-11-02 14:58:27 -04001938 $target = "$ssh_user\@$machine";
1939
1940 $buildlog = "$tmpdir/buildlog-$machine";
1941 $dmesg = "$tmpdir/dmesg-$machine";
1942 $make = "$makecmd O=$outputdir";
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05001943 $output_config = "$outputdir/.config";
Steven Rostedta75fece2010-11-02 14:58:27 -04001944
1945 if ($reboot_type eq "grub") {
Steven Rostedt576f6272010-11-02 14:58:38 -04001946 dodie "GRUB_MENU not defined" if (!defined($grub_menu));
Steven Rostedta75fece2010-11-02 14:58:27 -04001947 } elsif (!defined($reboot_script)) {
Steven Rostedt576f6272010-11-02 14:58:38 -04001948 dodie "REBOOT_SCRIPT not defined"
Steven Rostedta75fece2010-11-02 14:58:27 -04001949 }
1950
1951 my $run_type = $build_type;
1952 if ($test_type eq "patchcheck") {
1953 $run_type = $opt{"PATCHCHECK_TYPE[$i]"};
1954 } elsif ($test_type eq "bisect") {
1955 $run_type = $opt{"BISECT_TYPE[$i]"};
Steven Rostedt0a05c762010-11-08 11:14:10 -05001956 } elsif ($test_type eq "config_bisect") {
1957 $run_type = $opt{"CONFIG_BISECT_TYPE[$i]"};
Steven Rostedta75fece2010-11-02 14:58:27 -04001958 }
1959
1960 # mistake in config file?
1961 if (!defined($run_type)) {
1962 $run_type = "ERROR";
1963 }
Steven Rostedt2545eb62010-11-02 15:01:32 -04001964
1965 doprint "\n\n";
Steven Rostedta75fece2010-11-02 14:58:27 -04001966 doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type\n\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001967
1968 unlink $dmesg;
1969 unlink $buildlog;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001970
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001971 if (!defined($minconfig)) {
1972 $minconfig = $addconfig;
1973
1974 } elsif (defined($addconfig)) {
Steven Rostedt9be2e6b2010-11-09 12:20:21 -05001975 run_command "cat $addconfig $minconfig > $tmpdir/add_config" or
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001976 dodie "Failed to create temp config";
Steven Rostedt9be2e6b2010-11-09 12:20:21 -05001977 $minconfig = "$tmpdir/add_config";
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001978 }
1979
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001980 my $checkout = $opt{"CHECKOUT[$i]"};
1981 if (defined($checkout)) {
1982 run_command "git checkout $checkout" or
1983 die "failed to checkout $checkout";
1984 }
1985
Steven Rostedta75fece2010-11-02 14:58:27 -04001986 if ($test_type eq "bisect") {
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001987 bisect $i;
1988 next;
Steven Rostedt0a05c762010-11-08 11:14:10 -05001989 } elsif ($test_type eq "config_bisect") {
1990 config_bisect $i;
1991 next;
Steven Rostedta75fece2010-11-02 14:58:27 -04001992 } elsif ($test_type eq "patchcheck") {
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001993 patchcheck $i;
1994 next;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001995 }
1996
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001997 if ($build_type ne "nobuild") {
1998 build $build_type or next;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001999 }
2000
Steven Rostedta75fece2010-11-02 14:58:27 -04002001 if ($test_type ne "build") {
2002 get_grub_index;
2003 get_version;
2004 install;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04002005
Steven Rostedta75fece2010-11-02 14:58:27 -04002006 my $failed = 0;
2007 start_monitor;
2008 monitor or $failed = 1;;
2009
2010 if (!$failed && $test_type ne "boot" && defined($run_test)) {
2011 do_run_test or $failed = 1;
2012 }
2013 end_monitor;
2014 next if ($failed);
Steven Rostedt5a391fb2010-11-02 14:57:43 -04002015 }
2016
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04002017 success $i;
Steven Rostedt2545eb62010-11-02 15:01:32 -04002018}
2019
Steven Rostedt5c42fc52010-11-02 14:57:01 -04002020if ($opt{"POWEROFF_ON_SUCCESS"}) {
Steven Rostedt75c3fda72010-11-02 14:57:21 -04002021 halt;
Steven Rostedt576f6272010-11-02 14:58:38 -04002022} elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot) {
Steven Rostedt75c3fda72010-11-02 14:57:21 -04002023 reboot;
Steven Rostedt5c42fc52010-11-02 14:57:01 -04002024}
Steven Rostedt75c3fda72010-11-02 14:57:21 -04002025
Steven Rostedte48c5292010-11-02 14:35:37 -04002026doprint "\n $successes of $opt{NUM_TESTS} tests were successful\n\n";
2027
Steven Rostedt2545eb62010-11-02 15:01:32 -04002028exit 0;