blob: 3e3615a7d968dfc13e1c79f9370883688d929e9b [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 Rostedt2545eb62010-11-02 15:01:32 -0400823 $bug = 1;
824 }
825
826 if ($line =~ /\n/) {
827 $full_line = "";
828 }
829 }
830
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400831 close(DMESG);
Steven Rostedt2545eb62010-11-02 15:01:32 -0400832
Steven Rostedt2545eb62010-11-02 15:01:32 -0400833 if ($bug) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400834 return 0 if ($in_bisect);
Steven Rostedt576f6272010-11-02 14:58:38 -0400835 fail "failed - got a bug report" and return 0;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400836 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400837
Steven Rostedta75fece2010-11-02 14:58:27 -0400838 if (!$booted) {
839 return 0 if ($in_bisect);
Steven Rostedt576f6272010-11-02 14:58:38 -0400840 fail "failed - never got a boot prompt." and return 0;
Steven Rostedta75fece2010-11-02 14:58:27 -0400841 }
842
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400843 return 1;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400844}
845
846sub install {
847
Steven Rostedte48c5292010-11-02 14:35:37 -0400848 run_scp "$outputdir/$build_target", "$target_image" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400849 dodie "failed to copy image";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400850
851 my $install_mods = 0;
852
853 # should we process modules?
854 $install_mods = 0;
Steven Rostedt51ad1dd2010-11-08 16:43:21 -0500855 open(IN, "$output_config") or dodie("Can't read config file");
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400856 while (<IN>) {
857 if (/CONFIG_MODULES(=y)?/) {
858 $install_mods = 1 if (defined($1));
859 last;
860 }
861 }
862 close(IN);
863
864 if (!$install_mods) {
865 doprint "No modules needed\n";
866 return;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400867 }
868
Steven Rostedta75fece2010-11-02 14:58:27 -0400869 run_command "$make INSTALL_MOD_PATH=$tmpdir modules_install" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400870 dodie "Failed to install modules";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400871
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400872 my $modlib = "/lib/modules/$version";
Steven Rostedta57419b2010-11-02 15:13:54 -0400873 my $modtar = "ktest-mods.tar.bz2";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400874
Steven Rostedte48c5292010-11-02 14:35:37 -0400875 run_ssh "rm -rf $modlib" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400876 dodie "failed to remove old mods: $modlib";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400877
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400878 # would be nice if scp -r did not follow symbolic links
Steven Rostedta75fece2010-11-02 14:58:27 -0400879 run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400880 dodie "making tarball";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400881
Steven Rostedte48c5292010-11-02 14:35:37 -0400882 run_scp "$tmpdir/$modtar", "/tmp" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400883 dodie "failed to copy modules";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400884
Steven Rostedta75fece2010-11-02 14:58:27 -0400885 unlink "$tmpdir/$modtar";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400886
Steven Rostedte48c5292010-11-02 14:35:37 -0400887 run_ssh "'(cd / && tar xf /tmp/$modtar)'" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400888 dodie "failed to tar modules";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400889
Steven Rostedte48c5292010-11-02 14:35:37 -0400890 run_ssh "rm -f /tmp/$modtar";
Steven Rostedt8b37ca82010-11-02 14:58:33 -0400891
892 return if (!defined($post_install));
893
Steven Rostedte48c5292010-11-02 14:35:37 -0400894 my $cp_post_install = $post_install;
895 $cp_post_install = s/\$KERNEL_VERSION/$version/g;
896 run_command "$cp_post_install" or
Steven Rostedt576f6272010-11-02 14:58:38 -0400897 dodie "Failed to run post install";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400898}
899
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400900sub check_buildlog {
901 my ($patch) = @_;
902
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400903 my @files = `git show $patch | diffstat -l`;
904
905 open(IN, "git show $patch |") or
906 dodie "failed to show $patch";
907 while (<IN>) {
908 if (m,^--- a/(.*),) {
909 chomp $1;
910 $files[$#files] = $1;
911 }
912 }
913 close(IN);
914
915 open(IN, $buildlog) or dodie "Can't open $buildlog";
916 while (<IN>) {
917 if (/^\s*(.*?):.*(warning|error)/) {
918 my $err = $1;
919 foreach my $file (@files) {
Steven Rostedta75fece2010-11-02 14:58:27 -0400920 my $fullpath = "$builddir/$file";
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400921 if ($file eq $err || $fullpath eq $err) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400922 fail "$file built with warnings" and return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400923 }
924 }
925 }
926 }
927 close(IN);
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400928
929 return 1;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400930}
931
Steven Rostedt2545eb62010-11-02 15:01:32 -0400932sub build {
933 my ($type) = @_;
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400934 my $defconfig = "";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400935
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400936 unlink $buildlog;
937
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400938 if ($type =~ /^useconfig:(.*)/) {
Steven Rostedt51ad1dd2010-11-08 16:43:21 -0500939 run_command "cp $1 $output_config" or
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400940 dodie "could not copy $1 to .config";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400941
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400942 $type = "oldconfig";
943 }
944
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400945 # old config can ask questions
946 if ($type eq "oldconfig") {
Steven Rostedt9386c6a2010-11-08 16:35:48 -0500947 $type = "oldnoconfig";
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400948
949 # allow for empty configs
Steven Rostedt51ad1dd2010-11-08 16:43:21 -0500950 run_command "touch $output_config";
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400951
Steven Rostedt51ad1dd2010-11-08 16:43:21 -0500952 run_command "mv $output_config $outputdir/config_temp" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400953 dodie "moving .config";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400954
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400955 if (!$noclean && !run_command "$make mrproper") {
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400956 dodie "make mrproper";
957 }
958
Steven Rostedt51ad1dd2010-11-08 16:43:21 -0500959 run_command "mv $outputdir/config_temp $output_config" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400960 dodie "moving config_temp";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400961
962 } elsif (!$noclean) {
Steven Rostedt51ad1dd2010-11-08 16:43:21 -0500963 unlink "$output_config";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400964 run_command "$make mrproper" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400965 dodie "make mrproper";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400966 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400967
968 # add something to distinguish this build
Steven Rostedta75fece2010-11-02 14:58:27 -0400969 open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file");
970 print OUT "$localversion\n";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400971 close(OUT);
972
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400973 if (defined($minconfig)) {
974 $defconfig = "KCONFIG_ALLCONFIG=$minconfig";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400975 }
976
Steven Rostedt9386c6a2010-11-08 16:35:48 -0500977 run_command "$defconfig $make $type" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400978 dodie "failed make config";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400979
Steven Rostedta75fece2010-11-02 14:58:27 -0400980 $redirect = "$buildlog";
981 if (!run_command "$make $build_options") {
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400982 undef $redirect;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400983 # bisect may need this to pass
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400984 return 0 if ($in_bisect);
985 fail "failed build" and return 0;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400986 }
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400987 undef $redirect;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400988
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400989 return 1;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400990}
991
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400992sub halt {
Steven Rostedte48c5292010-11-02 14:35:37 -0400993 if (!run_ssh "halt" or defined($power_off)) {
Steven Rostedt576f6272010-11-02 14:58:38 -0400994 if (defined($poweroff_after_halt)) {
995 sleep $poweroff_after_halt;
996 run_command "$power_off";
997 }
998 } else {
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400999 # nope? the zap it!
Steven Rostedta75fece2010-11-02 14:58:27 -04001000 run_command "$power_off";
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001001 }
1002}
1003
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001004sub success {
1005 my ($i) = @_;
1006
Steven Rostedte48c5292010-11-02 14:35:37 -04001007 $successes++;
1008
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001009 doprint "\n\n*******************************************\n";
1010 doprint "*******************************************\n";
Steven Rostedt7a849cd2010-11-08 16:49:25 -05001011 doprint "KTEST RESULT: TEST $i SUCCESS!!!! **\n";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001012 doprint "*******************************************\n";
1013 doprint "*******************************************\n";
1014
Steven Rostedt576f6272010-11-02 14:58:38 -04001015 if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) {
Steven Rostedta75fece2010-11-02 14:58:27 -04001016 doprint "Reboot and wait $sleep_time seconds\n";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001017 reboot;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001018 start_monitor;
Steven Rostedta75fece2010-11-02 14:58:27 -04001019 wait_for_monitor $sleep_time;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001020 end_monitor;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001021 }
1022}
1023
1024sub get_version {
1025 # get the release name
1026 doprint "$make kernelrelease ... ";
1027 $version = `$make kernelrelease | tail -1`;
1028 chomp($version);
1029 doprint "$version\n";
1030}
1031
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001032sub child_run_test {
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001033 my $failed = 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001034
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001035 # child should have no power
Steven Rostedta75fece2010-11-02 14:58:27 -04001036 $reboot_on_error = 0;
1037 $poweroff_on_error = 0;
1038 $die_on_failure = 1;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001039
1040 run_command $run_test or $failed = 1;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001041 exit $failed;
1042}
1043
1044my $child_done;
1045
1046sub child_finished {
1047 $child_done = 1;
1048}
1049
1050sub do_run_test {
1051 my $child_pid;
1052 my $child_exit;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001053 my $line;
1054 my $full_line;
1055 my $bug = 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001056
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001057 wait_for_monitor 1;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001058
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001059 doprint "run test $run_test\n";
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001060
1061 $child_done = 0;
1062
1063 $SIG{CHLD} = qw(child_finished);
1064
1065 $child_pid = fork;
1066
1067 child_run_test if (!$child_pid);
1068
1069 $full_line = "";
1070
1071 do {
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001072 $line = wait_for_input($monitor_fp, 1);
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001073 if (defined($line)) {
1074
1075 # we are not guaranteed to get a full line
1076 $full_line .= $line;
1077
1078 if ($full_line =~ /call trace:/i) {
1079 $bug = 1;
1080 }
1081
1082 if ($full_line =~ /Kernel panic -/) {
1083 $bug = 1;
1084 }
1085
1086 if ($line =~ /\n/) {
1087 $full_line = "";
1088 }
1089 }
1090 } while (!$child_done && !$bug);
1091
1092 if ($bug) {
1093 doprint "Detected kernel crash!\n";
1094 # kill the child with extreme prejudice
1095 kill 9, $child_pid;
1096 }
1097
1098 waitpid $child_pid, 0;
1099 $child_exit = $?;
1100
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001101 if ($bug || $child_exit) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001102 return 0 if $in_bisect;
1103 fail "test failed" and return 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001104 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001105 return 1;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001106}
1107
Steven Rostedta75fece2010-11-02 14:58:27 -04001108sub run_git_bisect {
1109 my ($command) = @_;
1110
1111 doprint "$command ... ";
1112
1113 my $output = `$command 2>&1`;
1114 my $ret = $?;
1115
1116 logit $output;
1117
1118 if ($ret) {
1119 doprint "FAILED\n";
1120 dodie "Failed to git bisect";
1121 }
1122
1123 doprint "SUCCESS\n";
1124 if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) {
1125 doprint "$1 [$2]\n";
1126 } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) {
1127 $bisect_bad = $1;
1128 doprint "Found bad commit... $1\n";
1129 return 0;
1130 } else {
1131 # we already logged it, just print it now.
1132 print $output;
1133 }
1134
1135 return 1;
1136}
1137
Steven Rostedt0a05c762010-11-08 11:14:10 -05001138# returns 1 on success, 0 on failure
1139sub run_bisect_test {
1140 my ($type, $buildtype) = @_;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001141
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001142 my $failed = 0;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001143 my $result;
1144 my $output;
1145 my $ret;
1146
Steven Rostedt0a05c762010-11-08 11:14:10 -05001147 $in_bisect = 1;
1148
1149 build $buildtype or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001150
1151 if ($type ne "build") {
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001152 dodie "Failed on build" if $failed;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001153
1154 # Now boot the box
1155 get_grub_index;
1156 get_version;
1157 install;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001158
1159 start_monitor;
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001160 monitor or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001161
1162 if ($type ne "boot") {
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001163 dodie "Failed on boot" if $failed;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001164
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001165 do_run_test or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001166 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001167 end_monitor;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001168 }
1169
1170 if ($failed) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001171 $result = 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001172
1173 # reboot the box to a good kernel
Steven Rostedta75fece2010-11-02 14:58:27 -04001174 if ($type ne "build") {
1175 doprint "Reboot and sleep $bisect_sleep_time seconds\n";
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001176 reboot;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001177 start_monitor;
Steven Rostedta75fece2010-11-02 14:58:27 -04001178 wait_for_monitor $bisect_sleep_time;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001179 end_monitor;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001180 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001181 } else {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001182 $result = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001183 }
Steven Rostedt0a05c762010-11-08 11:14:10 -05001184 $in_bisect = 0;
1185
1186 return $result;
1187}
1188
1189sub run_bisect {
1190 my ($type) = @_;
1191 my $buildtype = "oldconfig";
1192
1193 # We should have a minconfig to use?
1194 if (defined($minconfig)) {
1195 $buildtype = "useconfig:$minconfig";
1196 }
1197
1198 my $ret = run_bisect_test $type, $buildtype;
1199
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001200
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04001201 # Are we looking for where it worked, not failed?
1202 if ($reverse_bisect) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001203 $ret = !$ret;
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04001204 }
1205
Steven Rostedt0a05c762010-11-08 11:14:10 -05001206 if ($ret) {
1207 return "good";
1208 } else {
1209 return "bad";
1210 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001211}
1212
1213sub bisect {
1214 my ($i) = @_;
1215
1216 my $result;
1217
1218 die "BISECT_GOOD[$i] not defined\n" if (!defined($opt{"BISECT_GOOD[$i]"}));
1219 die "BISECT_BAD[$i] not defined\n" if (!defined($opt{"BISECT_BAD[$i]"}));
1220 die "BISECT_TYPE[$i] not defined\n" if (!defined($opt{"BISECT_TYPE[$i]"}));
1221
1222 my $good = $opt{"BISECT_GOOD[$i]"};
1223 my $bad = $opt{"BISECT_BAD[$i]"};
1224 my $type = $opt{"BISECT_TYPE[$i]"};
Steven Rostedta75fece2010-11-02 14:58:27 -04001225 my $start = $opt{"BISECT_START[$i]"};
1226 my $replay = $opt{"BISECT_REPLAY[$i]"};
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001227
Steven Rostedta57419b2010-11-02 15:13:54 -04001228 # convert to true sha1's
1229 $good = get_sha1($good);
1230 $bad = get_sha1($bad);
1231
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04001232 if (defined($opt{"BISECT_REVERSE[$i]"}) &&
1233 $opt{"BISECT_REVERSE[$i]"} == 1) {
1234 doprint "Performing a reverse bisect (bad is good, good is bad!)\n";
1235 $reverse_bisect = 1;
1236 } else {
1237 $reverse_bisect = 0;
1238 }
1239
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001240 # Can't have a test without having a test to run
1241 if ($type eq "test" && !defined($run_test)) {
1242 $type = "boot";
1243 }
1244
Steven Rostedta75fece2010-11-02 14:58:27 -04001245 my $check = $opt{"BISECT_CHECK[$i]"};
1246 if (defined($check) && $check ne "0") {
1247
1248 # get current HEAD
Steven Rostedta57419b2010-11-02 15:13:54 -04001249 my $head = get_sha1("HEAD");
Steven Rostedta75fece2010-11-02 14:58:27 -04001250
1251 if ($check ne "good") {
1252 doprint "TESTING BISECT BAD [$bad]\n";
1253 run_command "git checkout $bad" or
1254 die "Failed to checkout $bad";
1255
1256 $result = run_bisect $type;
1257
1258 if ($result ne "bad") {
1259 fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0;
1260 }
1261 }
1262
1263 if ($check ne "bad") {
1264 doprint "TESTING BISECT GOOD [$good]\n";
1265 run_command "git checkout $good" or
1266 die "Failed to checkout $good";
1267
1268 $result = run_bisect $type;
1269
1270 if ($result ne "good") {
1271 fail "Tested BISECT_GOOD [$good] and it failed" and return 0;
1272 }
1273 }
1274
1275 # checkout where we started
1276 run_command "git checkout $head" or
1277 die "Failed to checkout $head";
1278 }
1279
1280 run_command "git bisect start" or
1281 dodie "could not start bisect";
1282
1283 run_command "git bisect good $good" or
1284 dodie "could not set bisect good to $good";
1285
1286 run_git_bisect "git bisect bad $bad" or
1287 dodie "could not set bisect bad to $bad";
1288
1289 if (defined($replay)) {
1290 run_command "git bisect replay $replay" or
1291 dodie "failed to run replay";
1292 }
1293
1294 if (defined($start)) {
1295 run_command "git checkout $start" or
1296 dodie "failed to checkout $start";
1297 }
1298
1299 my $test;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001300 do {
1301 $result = run_bisect $type;
Steven Rostedta75fece2010-11-02 14:58:27 -04001302 $test = run_git_bisect "git bisect $result";
1303 } while ($test);
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001304
1305 run_command "git bisect log" or
1306 dodie "could not capture git bisect log";
1307
1308 run_command "git bisect reset" or
1309 dodie "could not reset git bisect";
1310
1311 doprint "Bad commit was [$bisect_bad]\n";
1312
Steven Rostedt0a05c762010-11-08 11:14:10 -05001313 success $i;
1314}
1315
1316my %config_ignore;
1317my %config_set;
1318
1319my %config_list;
1320my %null_config;
1321
1322my %dependency;
1323
1324sub process_config_ignore {
1325 my ($config) = @_;
1326
1327 open (IN, $config)
1328 or dodie "Failed to read $config";
1329
1330 while (<IN>) {
1331 if (/^(.*?(CONFIG\S*)(=.*| is not set))/) {
1332 $config_ignore{$2} = $1;
1333 }
1334 }
1335
1336 close(IN);
1337}
1338
1339sub read_current_config {
1340 my ($config_ref) = @_;
1341
1342 %{$config_ref} = ();
1343 undef %{$config_ref};
1344
1345 my @key = keys %{$config_ref};
1346 if ($#key >= 0) {
1347 print "did not delete!\n";
1348 exit;
1349 }
1350 open (IN, "$output_config");
1351
1352 while (<IN>) {
1353 if (/^(CONFIG\S+)=(.*)/) {
1354 ${$config_ref}{$1} = $2;
1355 }
1356 }
1357 close(IN);
1358}
1359
1360sub get_dependencies {
1361 my ($config) = @_;
1362
1363 my $arr = $dependency{$config};
1364 if (!defined($arr)) {
1365 return ();
1366 }
1367
1368 my @deps = @{$arr};
1369
1370 foreach my $dep (@{$arr}) {
1371 print "ADD DEP $dep\n";
1372 @deps = (@deps, get_dependencies $dep);
1373 }
1374
1375 return @deps;
1376}
1377
1378sub create_config {
1379 my @configs = @_;
1380
1381 open(OUT, ">$output_config") or dodie "Can not write to $output_config";
1382
1383 foreach my $config (@configs) {
1384 print OUT "$config_set{$config}\n";
1385 my @deps = get_dependencies $config;
1386 foreach my $dep (@deps) {
1387 print OUT "$config_set{$dep}\n";
1388 }
1389 }
1390
1391 foreach my $config (keys %config_ignore) {
1392 print OUT "$config_ignore{$config}\n";
1393 }
1394 close(OUT);
1395
1396# exit;
1397 run_command "$make oldnoconfig" or
1398 dodie "failed make config oldconfig";
1399
1400}
1401
1402sub compare_configs {
1403 my (%a, %b) = @_;
1404
1405 foreach my $item (keys %a) {
1406 if (!defined($b{$item})) {
1407 print "diff $item\n";
1408 return 1;
1409 }
1410 delete $b{$item};
1411 }
1412
1413 my @keys = keys %b;
1414 if ($#keys) {
1415 print "diff2 $keys[0]\n";
1416 }
1417 return -1 if ($#keys >= 0);
1418
1419 return 0;
1420}
1421
1422sub run_config_bisect_test {
1423 my ($type) = @_;
1424
1425 return run_bisect_test $type, "oldconfig";
1426}
1427
1428sub process_passed {
1429 my (%configs) = @_;
1430
1431 doprint "These configs had no failure: (Enabling them for further compiles)\n";
1432 # Passed! All these configs are part of a good compile.
1433 # Add them to the min options.
1434 foreach my $config (keys %configs) {
1435 if (defined($config_list{$config})) {
1436 doprint " removing $config\n";
1437 $config_ignore{$config} = $config_list{$config};
1438 delete $config_list{$config};
1439 }
1440 }
Steven Rostedtf1a27852010-11-11 11:34:38 -05001441 doprint "config copied to $outputdir/config_good\n";
1442 run_command "cp -f $output_config $outputdir/config_good";
Steven Rostedt0a05c762010-11-08 11:14:10 -05001443}
1444
1445sub process_failed {
1446 my ($config) = @_;
1447
1448 doprint "\n\n***************************************\n";
1449 doprint "Found bad config: $config\n";
1450 doprint "***************************************\n\n";
1451}
1452
1453sub run_config_bisect {
1454
1455 my @start_list = keys %config_list;
1456
1457 if ($#start_list < 0) {
1458 doprint "No more configs to test!!!\n";
1459 return -1;
1460 }
1461
1462 doprint "***** RUN TEST ***\n";
1463 my $type = $opt{"CONFIG_BISECT_TYPE[$iteration]"};
1464 my $ret;
1465 my %current_config;
1466
1467 my $count = $#start_list + 1;
1468 doprint " $count configs to test\n";
1469
1470 my $half = int($#start_list / 2);
1471
1472 do {
1473 my @tophalf = @start_list[0 .. $half];
1474
1475 create_config @tophalf;
1476 read_current_config \%current_config;
1477
1478 $count = $#tophalf + 1;
1479 doprint "Testing $count configs\n";
1480 my $found = 0;
1481 # make sure we test something
1482 foreach my $config (@tophalf) {
1483 if (defined($current_config{$config})) {
1484 logit " $config\n";
1485 $found = 1;
1486 }
1487 }
1488 if (!$found) {
1489 # try the other half
1490 doprint "Top half produced no set configs, trying bottom half\n";
1491 @tophalf = @start_list[$half .. $#start_list];
1492 create_config @tophalf;
1493 read_current_config \%current_config;
1494 foreach my $config (@tophalf) {
1495 if (defined($current_config{$config})) {
1496 logit " $config\n";
1497 $found = 1;
1498 }
1499 }
1500 if (!$found) {
1501 doprint "Failed: Can't make new config with current configs\n";
1502 foreach my $config (@start_list) {
1503 doprint " CONFIG: $config\n";
1504 }
1505 return -1;
1506 }
1507 $count = $#tophalf + 1;
1508 doprint "Testing $count configs\n";
1509 }
1510
1511 $ret = run_config_bisect_test $type;
1512
1513 if ($ret) {
1514 process_passed %current_config;
1515 return 0;
1516 }
1517
1518 doprint "This config had a failure.\n";
1519 doprint "Removing these configs that were not set in this config:\n";
Steven Rostedtf1a27852010-11-11 11:34:38 -05001520 doprint "config copied to $outputdir/config_bad\n";
1521 run_command "cp -f $output_config $outputdir/config_bad";
Steven Rostedt0a05c762010-11-08 11:14:10 -05001522
1523 # A config exists in this group that was bad.
1524 foreach my $config (keys %config_list) {
1525 if (!defined($current_config{$config})) {
1526 doprint " removing $config\n";
1527 delete $config_list{$config};
1528 }
1529 }
1530
1531 @start_list = @tophalf;
1532
1533 if ($#start_list == 0) {
1534 process_failed $start_list[0];
1535 return 1;
1536 }
1537
1538 # remove half the configs we are looking at and see if
1539 # they are good.
1540 $half = int($#start_list / 2);
1541 } while ($half > 0);
1542
1543 # we found a single config, try it again
1544 my @tophalf = @start_list[0 .. 0];
1545
1546 $ret = run_config_bisect_test $type;
1547 if ($ret) {
1548 process_passed %current_config;
1549 return 0;
1550 }
1551
1552 process_failed $start_list[0];
1553 return 1;
1554}
1555
1556sub config_bisect {
1557 my ($i) = @_;
1558
1559 my $start_config = $opt{"CONFIG_BISECT[$i]"};
1560
1561 my $tmpconfig = "$tmpdir/use_config";
1562
1563 # Make the file with the bad config and the min config
1564 if (defined($minconfig)) {
1565 # read the min config for things to ignore
1566 run_command "cp $minconfig $tmpconfig" or
1567 dodie "failed to copy $minconfig to $tmpconfig";
1568 } else {
1569 unlink $tmpconfig;
1570 }
1571
1572 # Add other configs
1573 if (defined($addconfig)) {
1574 run_command "cat $addconfig >> $tmpconfig" or
1575 dodie "failed to append $addconfig";
1576 }
1577
1578 my $defconfig = "";
1579 if (-f $tmpconfig) {
1580 $defconfig = "KCONFIG_ALLCONFIG=$tmpconfig";
1581 process_config_ignore $tmpconfig;
1582 }
1583
1584 # now process the start config
1585 run_command "cp $start_config $output_config" or
1586 dodie "failed to copy $start_config to $output_config";
1587
1588 # read directly what we want to check
1589 my %config_check;
1590 open (IN, $output_config)
1591 or dodie "faied to open $output_config";
1592
1593 while (<IN>) {
1594 if (/^((CONFIG\S*)=.*)/) {
1595 $config_check{$2} = $1;
1596 }
1597 }
1598 close(IN);
1599
1600 # Now run oldconfig with the minconfig (and addconfigs)
1601 run_command "$defconfig $make oldnoconfig" or
1602 dodie "failed make config oldconfig";
1603
1604 # check to see what we lost (or gained)
1605 open (IN, $output_config)
1606 or dodie "Failed to read $start_config";
1607
1608 my %removed_configs;
1609 my %added_configs;
1610
1611 while (<IN>) {
1612 if (/^((CONFIG\S*)=.*)/) {
1613 # save off all options
1614 $config_set{$2} = $1;
1615 if (defined($config_check{$2})) {
1616 if (defined($config_ignore{$2})) {
1617 $removed_configs{$2} = $1;
1618 } else {
1619 $config_list{$2} = $1;
1620 }
1621 } elsif (!defined($config_ignore{$2})) {
1622 $added_configs{$2} = $1;
1623 $config_list{$2} = $1;
1624 }
1625 }
1626 }
1627 close(IN);
1628
1629 my @confs = keys %removed_configs;
1630 if ($#confs >= 0) {
1631 doprint "Configs overridden by default configs and removed from check:\n";
1632 foreach my $config (@confs) {
1633 doprint " $config\n";
1634 }
1635 }
1636 @confs = keys %added_configs;
1637 if ($#confs >= 0) {
1638 doprint "Configs appearing in make oldconfig and added:\n";
1639 foreach my $config (@confs) {
1640 doprint " $config\n";
1641 }
1642 }
1643
1644 my %config_test;
1645 my $once = 0;
1646
1647 # Sometimes kconfig does weird things. We must make sure
1648 # that the config we autocreate has everything we need
1649 # to test, otherwise we may miss testing configs, or
1650 # may not be able to create a new config.
1651 # Here we create a config with everything set.
1652 create_config (keys %config_list);
1653 read_current_config \%config_test;
1654 foreach my $config (keys %config_list) {
1655 if (!defined($config_test{$config})) {
1656 if (!$once) {
1657 $once = 1;
1658 doprint "Configs not produced by kconfig (will not be checked):\n";
1659 }
1660 doprint " $config\n";
1661 delete $config_list{$config};
1662 }
1663 }
1664 my $ret;
1665 do {
1666 $ret = run_config_bisect;
1667 } while (!$ret);
1668
1669 return $ret if ($ret < 0);
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001670
1671 success $i;
1672}
1673
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001674sub patchcheck {
1675 my ($i) = @_;
1676
1677 die "PATCHCHECK_START[$i] not defined\n"
1678 if (!defined($opt{"PATCHCHECK_START[$i]"}));
1679 die "PATCHCHECK_TYPE[$i] not defined\n"
1680 if (!defined($opt{"PATCHCHECK_TYPE[$i]"}));
1681
1682 my $start = $opt{"PATCHCHECK_START[$i]"};
1683
1684 my $end = "HEAD";
1685 if (defined($opt{"PATCHCHECK_END[$i]"})) {
1686 $end = $opt{"PATCHCHECK_END[$i]"};
1687 }
1688
Steven Rostedta57419b2010-11-02 15:13:54 -04001689 # Get the true sha1's since we can use things like HEAD~3
1690 $start = get_sha1($start);
1691 $end = get_sha1($end);
1692
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001693 my $type = $opt{"PATCHCHECK_TYPE[$i]"};
1694
1695 # Can't have a test without having a test to run
1696 if ($type eq "test" && !defined($run_test)) {
1697 $type = "boot";
1698 }
1699
1700 open (IN, "git log --pretty=oneline $end|") or
1701 dodie "could not get git list";
1702
1703 my @list;
1704
1705 while (<IN>) {
1706 chomp;
1707 $list[$#list+1] = $_;
1708 last if (/^$start/);
1709 }
1710 close(IN);
1711
1712 if ($list[$#list] !~ /^$start/) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001713 fail "SHA1 $start not found";
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001714 }
1715
1716 # go backwards in the list
1717 @list = reverse @list;
1718
1719 my $save_clean = $noclean;
1720
1721 $in_patchcheck = 1;
1722 foreach my $item (@list) {
1723 my $sha1 = $item;
1724 $sha1 =~ s/^([[:xdigit:]]+).*/$1/;
1725
1726 doprint "\nProcessing commit $item\n\n";
1727
1728 run_command "git checkout $sha1" or
1729 die "Failed to checkout $sha1";
1730
1731 # only clean on the first and last patch
1732 if ($item eq $list[0] ||
1733 $item eq $list[$#list]) {
1734 $noclean = $save_clean;
1735 } else {
1736 $noclean = 1;
1737 }
1738
1739 if (defined($minconfig)) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001740 build "useconfig:$minconfig" or return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001741 } else {
1742 # ?? no config to use?
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001743 build "oldconfig" or return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001744 }
1745
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001746 check_buildlog $sha1 or return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001747
1748 next if ($type eq "build");
1749
1750 get_grub_index;
1751 get_version;
1752 install;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001753
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001754 my $failed = 0;
1755
1756 start_monitor;
1757 monitor or $failed = 1;
1758
1759 if (!$failed && $type ne "boot"){
1760 do_run_test or $failed = 1;
1761 }
1762 end_monitor;
1763 return 0 if ($failed);
1764
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001765 }
1766 $in_patchcheck = 0;
1767 success $i;
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001768
1769 return 1;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001770}
1771
Steven Rostedt8d1491b2010-11-18 15:39:48 -05001772$#ARGV < 1 or die "ktest.pl version: $VERSION\n usage: ktest.pl config-file\n";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001773
Steven Rostedt8d1491b2010-11-18 15:39:48 -05001774if ($#ARGV == 0) {
1775 $ktest_config = $ARGV[0];
1776 if (! -f $ktest_config) {
1777 print "$ktest_config does not exist.\n";
1778 my $ans;
1779 for (;;) {
1780 print "Create it? [Y/n] ";
1781 $ans = <STDIN>;
1782 chomp $ans;
1783 if ($ans =~ /^\s*$/) {
1784 $ans = "y";
1785 }
1786 last if ($ans =~ /^y$/i || $ans =~ /^n$/i);
1787 print "Please answer either 'y' or 'n'.\n";
1788 }
1789 if ($ans !~ /^y$/i) {
1790 exit 0;
1791 }
1792 }
1793} else {
1794 $ktest_config = "ktest.conf";
1795}
1796
1797if (! -f $ktest_config) {
1798 open(OUT, ">$ktest_config") or die "Can not create $ktest_config";
1799 print OUT << "EOF"
1800# Generated by ktest.pl
1801#
1802# Define each test with TEST_START
1803# The config options below it will override the defaults
1804TEST_START
1805
1806DEFAULTS
1807EOF
1808;
1809 close(OUT);
1810}
1811read_config $ktest_config;
1812
1813# Append any configs entered in manually to the config file.
1814my @new_configs = keys %entered_configs;
1815if ($#new_configs >= 0) {
1816 print "\nAppending entered in configs to $ktest_config\n";
1817 open(OUT, ">>$ktest_config") or die "Can not append to $ktest_config";
1818 foreach my $config (@new_configs) {
1819 print OUT "$config = $entered_configs{$config}\n";
1820 $opt{$config} = $entered_configs{$config};
1821 }
1822}
Steven Rostedt2545eb62010-11-02 15:01:32 -04001823
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001824if ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) {
1825 unlink $opt{"LOG_FILE"};
1826}
Steven Rostedt2545eb62010-11-02 15:01:32 -04001827
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001828doprint "\n\nSTARTING AUTOMATED TESTS\n\n";
1829
Steven Rostedta57419b2010-11-02 15:13:54 -04001830for (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) {
1831
1832 if (!$i) {
1833 doprint "DEFAULT OPTIONS:\n";
1834 } else {
1835 doprint "\nTEST $i OPTIONS";
1836 if (defined($repeat_tests{$i})) {
1837 $repeat = $repeat_tests{$i};
1838 doprint " ITERATE $repeat";
1839 }
1840 doprint "\n";
1841 }
1842
1843 foreach my $option (sort keys %opt) {
1844
1845 if ($option =~ /\[(\d+)\]$/) {
1846 next if ($i != $1);
1847 } else {
1848 next if ($i);
1849 }
1850
1851 doprint "$option = $opt{$option}\n";
1852 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001853}
Steven Rostedt2545eb62010-11-02 15:01:32 -04001854
Steven Rostedta75fece2010-11-02 14:58:27 -04001855sub set_test_option {
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001856 my ($name, $i) = @_;
1857
1858 my $option = "$name\[$i\]";
1859
1860 if (defined($opt{$option})) {
1861 return $opt{$option};
1862 }
1863
Steven Rostedta57419b2010-11-02 15:13:54 -04001864 foreach my $test (keys %repeat_tests) {
1865 if ($i >= $test &&
1866 $i < $test + $repeat_tests{$test}) {
1867 $option = "$name\[$test\]";
1868 if (defined($opt{$option})) {
1869 return $opt{$option};
1870 }
1871 }
1872 }
1873
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001874 if (defined($opt{$name})) {
1875 return $opt{$name};
1876 }
1877
1878 return undef;
1879}
1880
Steven Rostedt2545eb62010-11-02 15:01:32 -04001881# First we need to do is the builds
Steven Rostedta75fece2010-11-02 14:58:27 -04001882for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
Steven Rostedt2545eb62010-11-02 15:01:32 -04001883
Steven Rostedt576f6272010-11-02 14:58:38 -04001884 $iteration = $i;
1885
Steven Rostedta75fece2010-11-02 14:58:27 -04001886 my $makecmd = set_test_option("MAKE_CMD", $i);
1887
1888 $machine = set_test_option("MACHINE", $i);
Steven Rostedte48c5292010-11-02 14:35:37 -04001889 $ssh_user = set_test_option("SSH_USER", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04001890 $tmpdir = set_test_option("TMP_DIR", $i);
1891 $outputdir = set_test_option("OUTPUT_DIR", $i);
1892 $builddir = set_test_option("BUILD_DIR", $i);
1893 $test_type = set_test_option("TEST_TYPE", $i);
1894 $build_type = set_test_option("BUILD_TYPE", $i);
1895 $build_options = set_test_option("BUILD_OPTIONS", $i);
1896 $power_cycle = set_test_option("POWER_CYCLE", $i);
Steven Rostedte48c5292010-11-02 14:35:37 -04001897 $reboot = set_test_option("REBOOT", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04001898 $noclean = set_test_option("BUILD_NOCLEAN", $i);
1899 $minconfig = set_test_option("MIN_CONFIG", $i);
1900 $run_test = set_test_option("TEST", $i);
1901 $addconfig = set_test_option("ADD_CONFIG", $i);
1902 $reboot_type = set_test_option("REBOOT_TYPE", $i);
1903 $grub_menu = set_test_option("GRUB_MENU", $i);
Steven Rostedt8b37ca82010-11-02 14:58:33 -04001904 $post_install = set_test_option("POST_INSTALL", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04001905 $reboot_script = set_test_option("REBOOT_SCRIPT", $i);
1906 $reboot_on_error = set_test_option("REBOOT_ON_ERROR", $i);
1907 $poweroff_on_error = set_test_option("POWEROFF_ON_ERROR", $i);
1908 $die_on_failure = set_test_option("DIE_ON_FAILURE", $i);
1909 $power_off = set_test_option("POWER_OFF", $i);
Steven Rostedt576f6272010-11-02 14:58:38 -04001910 $powercycle_after_reboot = set_test_option("POWERCYCLE_AFTER_REBOOT", $i);
1911 $poweroff_after_halt = set_test_option("POWEROFF_AFTER_HALT", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04001912 $sleep_time = set_test_option("SLEEP_TIME", $i);
1913 $bisect_sleep_time = set_test_option("BISECT_SLEEP_TIME", $i);
1914 $store_failures = set_test_option("STORE_FAILURES", $i);
1915 $timeout = set_test_option("TIMEOUT", $i);
1916 $booted_timeout = set_test_option("BOOTED_TIMEOUT", $i);
1917 $console = set_test_option("CONSOLE", $i);
1918 $success_line = set_test_option("SUCCESS_LINE", $i);
Steven Rostedt1c8a6172010-11-09 12:55:40 -05001919 $stop_after_success = set_test_option("STOP_AFTER_SUCCESS", $i);
1920 $stop_after_failure = set_test_option("STOP_AFTER_FAILURE", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04001921 $build_target = set_test_option("BUILD_TARGET", $i);
Steven Rostedte48c5292010-11-02 14:35:37 -04001922 $ssh_exec = set_test_option("SSH_EXEC", $i);
1923 $scp_to_target = set_test_option("SCP_TO_TARGET", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04001924 $target_image = set_test_option("TARGET_IMAGE", $i);
1925 $localversion = set_test_option("LOCALVERSION", $i);
1926
1927 chdir $builddir || die "can't change directory to $builddir";
1928
1929 if (!-d $tmpdir) {
1930 mkpath($tmpdir) or
1931 die "can't create $tmpdir";
1932 }
1933
Steven Rostedte48c5292010-11-02 14:35:37 -04001934 $ENV{"SSH_USER"} = $ssh_user;
1935 $ENV{"MACHINE"} = $machine;
1936
Steven Rostedta75fece2010-11-02 14:58:27 -04001937 $target = "$ssh_user\@$machine";
1938
1939 $buildlog = "$tmpdir/buildlog-$machine";
1940 $dmesg = "$tmpdir/dmesg-$machine";
1941 $make = "$makecmd O=$outputdir";
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05001942 $output_config = "$outputdir/.config";
Steven Rostedta75fece2010-11-02 14:58:27 -04001943
1944 if ($reboot_type eq "grub") {
Steven Rostedt576f6272010-11-02 14:58:38 -04001945 dodie "GRUB_MENU not defined" if (!defined($grub_menu));
Steven Rostedta75fece2010-11-02 14:58:27 -04001946 } elsif (!defined($reboot_script)) {
Steven Rostedt576f6272010-11-02 14:58:38 -04001947 dodie "REBOOT_SCRIPT not defined"
Steven Rostedta75fece2010-11-02 14:58:27 -04001948 }
1949
1950 my $run_type = $build_type;
1951 if ($test_type eq "patchcheck") {
1952 $run_type = $opt{"PATCHCHECK_TYPE[$i]"};
1953 } elsif ($test_type eq "bisect") {
1954 $run_type = $opt{"BISECT_TYPE[$i]"};
Steven Rostedt0a05c762010-11-08 11:14:10 -05001955 } elsif ($test_type eq "config_bisect") {
1956 $run_type = $opt{"CONFIG_BISECT_TYPE[$i]"};
Steven Rostedta75fece2010-11-02 14:58:27 -04001957 }
1958
1959 # mistake in config file?
1960 if (!defined($run_type)) {
1961 $run_type = "ERROR";
1962 }
Steven Rostedt2545eb62010-11-02 15:01:32 -04001963
1964 doprint "\n\n";
Steven Rostedta75fece2010-11-02 14:58:27 -04001965 doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type\n\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001966
1967 unlink $dmesg;
1968 unlink $buildlog;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001969
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001970 if (!defined($minconfig)) {
1971 $minconfig = $addconfig;
1972
1973 } elsif (defined($addconfig)) {
Steven Rostedt9be2e6b2010-11-09 12:20:21 -05001974 run_command "cat $addconfig $minconfig > $tmpdir/add_config" or
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001975 dodie "Failed to create temp config";
Steven Rostedt9be2e6b2010-11-09 12:20:21 -05001976 $minconfig = "$tmpdir/add_config";
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001977 }
1978
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001979 my $checkout = $opt{"CHECKOUT[$i]"};
1980 if (defined($checkout)) {
1981 run_command "git checkout $checkout" or
1982 die "failed to checkout $checkout";
1983 }
1984
Steven Rostedta75fece2010-11-02 14:58:27 -04001985 if ($test_type eq "bisect") {
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001986 bisect $i;
1987 next;
Steven Rostedt0a05c762010-11-08 11:14:10 -05001988 } elsif ($test_type eq "config_bisect") {
1989 config_bisect $i;
1990 next;
Steven Rostedta75fece2010-11-02 14:58:27 -04001991 } elsif ($test_type eq "patchcheck") {
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001992 patchcheck $i;
1993 next;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001994 }
1995
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001996 if ($build_type ne "nobuild") {
1997 build $build_type or next;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001998 }
1999
Steven Rostedta75fece2010-11-02 14:58:27 -04002000 if ($test_type ne "build") {
2001 get_grub_index;
2002 get_version;
2003 install;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04002004
Steven Rostedta75fece2010-11-02 14:58:27 -04002005 my $failed = 0;
2006 start_monitor;
2007 monitor or $failed = 1;;
2008
2009 if (!$failed && $test_type ne "boot" && defined($run_test)) {
2010 do_run_test or $failed = 1;
2011 }
2012 end_monitor;
2013 next if ($failed);
Steven Rostedt5a391fb2010-11-02 14:57:43 -04002014 }
2015
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04002016 success $i;
Steven Rostedt2545eb62010-11-02 15:01:32 -04002017}
2018
Steven Rostedt5c42fc52010-11-02 14:57:01 -04002019if ($opt{"POWEROFF_ON_SUCCESS"}) {
Steven Rostedt75c3fda72010-11-02 14:57:21 -04002020 halt;
Steven Rostedt576f6272010-11-02 14:58:38 -04002021} elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot) {
Steven Rostedt75c3fda72010-11-02 14:57:21 -04002022 reboot;
Steven Rostedt5c42fc52010-11-02 14:57:01 -04002023}
Steven Rostedt75c3fda72010-11-02 14:57:21 -04002024
Steven Rostedte48c5292010-11-02 14:35:37 -04002025doprint "\n $successes of $opt{NUM_TESTS} tests were successful\n\n";
2026
Steven Rostedt2545eb62010-11-02 15:01:32 -04002027exit 0;