blob: c95209bac65a741aa08c56417f1c4a1bbb1614ef [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 Rostedt612b9e92011-03-07 13:27:43 -0500933sub make_oldconfig {
934 my ($defconfig) = @_;
935
936 if (!run_command "$defconfig $make oldnoconfig") {
937 # Perhaps oldnoconfig doesn't exist in this version of the kernel
938 # try a yes '' | oldconfig
939 doprint "oldnoconfig failed, trying yes '' | make oldconfig\n";
940 run_command "yes '' | $defconfig $make oldconfig" or
941 dodie "failed make config oldconfig";
942 }
943}
944
Steven Rostedt2545eb62010-11-02 15:01:32 -0400945sub build {
946 my ($type) = @_;
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400947 my $defconfig = "";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400948
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400949 unlink $buildlog;
950
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400951 if ($type =~ /^useconfig:(.*)/) {
Steven Rostedt51ad1dd2010-11-08 16:43:21 -0500952 run_command "cp $1 $output_config" or
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400953 dodie "could not copy $1 to .config";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400954
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400955 $type = "oldconfig";
956 }
957
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400958 # old config can ask questions
959 if ($type eq "oldconfig") {
Steven Rostedt9386c6a2010-11-08 16:35:48 -0500960 $type = "oldnoconfig";
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400961
962 # allow for empty configs
Steven Rostedt51ad1dd2010-11-08 16:43:21 -0500963 run_command "touch $output_config";
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400964
Steven Rostedt51ad1dd2010-11-08 16:43:21 -0500965 run_command "mv $output_config $outputdir/config_temp" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400966 dodie "moving .config";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400967
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400968 if (!$noclean && !run_command "$make mrproper") {
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400969 dodie "make mrproper";
970 }
971
Steven Rostedt51ad1dd2010-11-08 16:43:21 -0500972 run_command "mv $outputdir/config_temp $output_config" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400973 dodie "moving config_temp";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400974
975 } elsif (!$noclean) {
Steven Rostedt51ad1dd2010-11-08 16:43:21 -0500976 unlink "$output_config";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400977 run_command "$make mrproper" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400978 dodie "make mrproper";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400979 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400980
981 # add something to distinguish this build
Steven Rostedta75fece2010-11-02 14:58:27 -0400982 open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file");
983 print OUT "$localversion\n";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400984 close(OUT);
985
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400986 if (defined($minconfig)) {
987 $defconfig = "KCONFIG_ALLCONFIG=$minconfig";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400988 }
989
Steven Rostedt612b9e92011-03-07 13:27:43 -0500990 if ($type eq "oldnoconfig") {
991 make_oldconfig $defconfig;
992 } else {
993 run_command "$defconfig $make $type" or
994 dodie "failed make config";
995 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400996
Steven Rostedta75fece2010-11-02 14:58:27 -0400997 $redirect = "$buildlog";
998 if (!run_command "$make $build_options") {
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400999 undef $redirect;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001000 # bisect may need this to pass
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001001 return 0 if ($in_bisect);
1002 fail "failed build" and return 0;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001003 }
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001004 undef $redirect;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001005
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001006 return 1;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001007}
1008
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001009sub halt {
Steven Rostedte48c5292010-11-02 14:35:37 -04001010 if (!run_ssh "halt" or defined($power_off)) {
Steven Rostedt576f6272010-11-02 14:58:38 -04001011 if (defined($poweroff_after_halt)) {
1012 sleep $poweroff_after_halt;
1013 run_command "$power_off";
1014 }
1015 } else {
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001016 # nope? the zap it!
Steven Rostedta75fece2010-11-02 14:58:27 -04001017 run_command "$power_off";
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001018 }
1019}
1020
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001021sub success {
1022 my ($i) = @_;
1023
Steven Rostedte48c5292010-11-02 14:35:37 -04001024 $successes++;
1025
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001026 doprint "\n\n*******************************************\n";
1027 doprint "*******************************************\n";
Steven Rostedt7a849cd2010-11-08 16:49:25 -05001028 doprint "KTEST RESULT: TEST $i SUCCESS!!!! **\n";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001029 doprint "*******************************************\n";
1030 doprint "*******************************************\n";
1031
Steven Rostedt576f6272010-11-02 14:58:38 -04001032 if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) {
Steven Rostedta75fece2010-11-02 14:58:27 -04001033 doprint "Reboot and wait $sleep_time seconds\n";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001034 reboot;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001035 start_monitor;
Steven Rostedta75fece2010-11-02 14:58:27 -04001036 wait_for_monitor $sleep_time;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001037 end_monitor;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001038 }
1039}
1040
1041sub get_version {
1042 # get the release name
1043 doprint "$make kernelrelease ... ";
1044 $version = `$make kernelrelease | tail -1`;
1045 chomp($version);
1046 doprint "$version\n";
1047}
1048
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001049sub child_run_test {
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001050 my $failed = 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001051
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001052 # child should have no power
Steven Rostedta75fece2010-11-02 14:58:27 -04001053 $reboot_on_error = 0;
1054 $poweroff_on_error = 0;
1055 $die_on_failure = 1;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001056
1057 run_command $run_test or $failed = 1;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001058 exit $failed;
1059}
1060
1061my $child_done;
1062
1063sub child_finished {
1064 $child_done = 1;
1065}
1066
1067sub do_run_test {
1068 my $child_pid;
1069 my $child_exit;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001070 my $line;
1071 my $full_line;
1072 my $bug = 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001073
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001074 wait_for_monitor 1;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001075
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001076 doprint "run test $run_test\n";
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001077
1078 $child_done = 0;
1079
1080 $SIG{CHLD} = qw(child_finished);
1081
1082 $child_pid = fork;
1083
1084 child_run_test if (!$child_pid);
1085
1086 $full_line = "";
1087
1088 do {
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001089 $line = wait_for_input($monitor_fp, 1);
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001090 if (defined($line)) {
1091
1092 # we are not guaranteed to get a full line
1093 $full_line .= $line;
1094
1095 if ($full_line =~ /call trace:/i) {
1096 $bug = 1;
1097 }
1098
1099 if ($full_line =~ /Kernel panic -/) {
1100 $bug = 1;
1101 }
1102
1103 if ($line =~ /\n/) {
1104 $full_line = "";
1105 }
1106 }
1107 } while (!$child_done && !$bug);
1108
1109 if ($bug) {
1110 doprint "Detected kernel crash!\n";
1111 # kill the child with extreme prejudice
1112 kill 9, $child_pid;
1113 }
1114
1115 waitpid $child_pid, 0;
1116 $child_exit = $?;
1117
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001118 if ($bug || $child_exit) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001119 return 0 if $in_bisect;
1120 fail "test failed" and return 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001121 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001122 return 1;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001123}
1124
Steven Rostedta75fece2010-11-02 14:58:27 -04001125sub run_git_bisect {
1126 my ($command) = @_;
1127
1128 doprint "$command ... ";
1129
1130 my $output = `$command 2>&1`;
1131 my $ret = $?;
1132
1133 logit $output;
1134
1135 if ($ret) {
1136 doprint "FAILED\n";
1137 dodie "Failed to git bisect";
1138 }
1139
1140 doprint "SUCCESS\n";
1141 if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) {
1142 doprint "$1 [$2]\n";
1143 } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) {
1144 $bisect_bad = $1;
1145 doprint "Found bad commit... $1\n";
1146 return 0;
1147 } else {
1148 # we already logged it, just print it now.
1149 print $output;
1150 }
1151
1152 return 1;
1153}
1154
Steven Rostedt0a05c762010-11-08 11:14:10 -05001155# returns 1 on success, 0 on failure
1156sub run_bisect_test {
1157 my ($type, $buildtype) = @_;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001158
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001159 my $failed = 0;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001160 my $result;
1161 my $output;
1162 my $ret;
1163
Steven Rostedt0a05c762010-11-08 11:14:10 -05001164 $in_bisect = 1;
1165
1166 build $buildtype or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001167
1168 if ($type ne "build") {
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001169 dodie "Failed on build" if $failed;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001170
1171 # Now boot the box
1172 get_grub_index;
1173 get_version;
1174 install;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001175
1176 start_monitor;
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001177 monitor or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001178
1179 if ($type ne "boot") {
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001180 dodie "Failed on boot" if $failed;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001181
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001182 do_run_test or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001183 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001184 end_monitor;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001185 }
1186
1187 if ($failed) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001188 $result = 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001189
1190 # reboot the box to a good kernel
Steven Rostedta75fece2010-11-02 14:58:27 -04001191 if ($type ne "build") {
1192 doprint "Reboot and sleep $bisect_sleep_time seconds\n";
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001193 reboot;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001194 start_monitor;
Steven Rostedta75fece2010-11-02 14:58:27 -04001195 wait_for_monitor $bisect_sleep_time;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001196 end_monitor;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001197 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001198 } else {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001199 $result = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001200 }
Steven Rostedt0a05c762010-11-08 11:14:10 -05001201 $in_bisect = 0;
1202
1203 return $result;
1204}
1205
1206sub run_bisect {
1207 my ($type) = @_;
1208 my $buildtype = "oldconfig";
1209
1210 # We should have a minconfig to use?
1211 if (defined($minconfig)) {
1212 $buildtype = "useconfig:$minconfig";
1213 }
1214
1215 my $ret = run_bisect_test $type, $buildtype;
1216
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001217
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04001218 # Are we looking for where it worked, not failed?
1219 if ($reverse_bisect) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001220 $ret = !$ret;
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04001221 }
1222
Steven Rostedt0a05c762010-11-08 11:14:10 -05001223 if ($ret) {
1224 return "good";
1225 } else {
1226 return "bad";
1227 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001228}
1229
1230sub bisect {
1231 my ($i) = @_;
1232
1233 my $result;
1234
1235 die "BISECT_GOOD[$i] not defined\n" if (!defined($opt{"BISECT_GOOD[$i]"}));
1236 die "BISECT_BAD[$i] not defined\n" if (!defined($opt{"BISECT_BAD[$i]"}));
1237 die "BISECT_TYPE[$i] not defined\n" if (!defined($opt{"BISECT_TYPE[$i]"}));
1238
1239 my $good = $opt{"BISECT_GOOD[$i]"};
1240 my $bad = $opt{"BISECT_BAD[$i]"};
1241 my $type = $opt{"BISECT_TYPE[$i]"};
Steven Rostedta75fece2010-11-02 14:58:27 -04001242 my $start = $opt{"BISECT_START[$i]"};
1243 my $replay = $opt{"BISECT_REPLAY[$i]"};
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001244
Steven Rostedta57419b2010-11-02 15:13:54 -04001245 # convert to true sha1's
1246 $good = get_sha1($good);
1247 $bad = get_sha1($bad);
1248
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04001249 if (defined($opt{"BISECT_REVERSE[$i]"}) &&
1250 $opt{"BISECT_REVERSE[$i]"} == 1) {
1251 doprint "Performing a reverse bisect (bad is good, good is bad!)\n";
1252 $reverse_bisect = 1;
1253 } else {
1254 $reverse_bisect = 0;
1255 }
1256
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001257 # Can't have a test without having a test to run
1258 if ($type eq "test" && !defined($run_test)) {
1259 $type = "boot";
1260 }
1261
Steven Rostedta75fece2010-11-02 14:58:27 -04001262 my $check = $opt{"BISECT_CHECK[$i]"};
1263 if (defined($check) && $check ne "0") {
1264
1265 # get current HEAD
Steven Rostedta57419b2010-11-02 15:13:54 -04001266 my $head = get_sha1("HEAD");
Steven Rostedta75fece2010-11-02 14:58:27 -04001267
1268 if ($check ne "good") {
1269 doprint "TESTING BISECT BAD [$bad]\n";
1270 run_command "git checkout $bad" or
1271 die "Failed to checkout $bad";
1272
1273 $result = run_bisect $type;
1274
1275 if ($result ne "bad") {
1276 fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0;
1277 }
1278 }
1279
1280 if ($check ne "bad") {
1281 doprint "TESTING BISECT GOOD [$good]\n";
1282 run_command "git checkout $good" or
1283 die "Failed to checkout $good";
1284
1285 $result = run_bisect $type;
1286
1287 if ($result ne "good") {
1288 fail "Tested BISECT_GOOD [$good] and it failed" and return 0;
1289 }
1290 }
1291
1292 # checkout where we started
1293 run_command "git checkout $head" or
1294 die "Failed to checkout $head";
1295 }
1296
1297 run_command "git bisect start" or
1298 dodie "could not start bisect";
1299
1300 run_command "git bisect good $good" or
1301 dodie "could not set bisect good to $good";
1302
1303 run_git_bisect "git bisect bad $bad" or
1304 dodie "could not set bisect bad to $bad";
1305
1306 if (defined($replay)) {
1307 run_command "git bisect replay $replay" or
1308 dodie "failed to run replay";
1309 }
1310
1311 if (defined($start)) {
1312 run_command "git checkout $start" or
1313 dodie "failed to checkout $start";
1314 }
1315
1316 my $test;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001317 do {
1318 $result = run_bisect $type;
Steven Rostedta75fece2010-11-02 14:58:27 -04001319 $test = run_git_bisect "git bisect $result";
1320 } while ($test);
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001321
1322 run_command "git bisect log" or
1323 dodie "could not capture git bisect log";
1324
1325 run_command "git bisect reset" or
1326 dodie "could not reset git bisect";
1327
1328 doprint "Bad commit was [$bisect_bad]\n";
1329
Steven Rostedt0a05c762010-11-08 11:14:10 -05001330 success $i;
1331}
1332
1333my %config_ignore;
1334my %config_set;
1335
1336my %config_list;
1337my %null_config;
1338
1339my %dependency;
1340
1341sub process_config_ignore {
1342 my ($config) = @_;
1343
1344 open (IN, $config)
1345 or dodie "Failed to read $config";
1346
1347 while (<IN>) {
1348 if (/^(.*?(CONFIG\S*)(=.*| is not set))/) {
1349 $config_ignore{$2} = $1;
1350 }
1351 }
1352
1353 close(IN);
1354}
1355
1356sub read_current_config {
1357 my ($config_ref) = @_;
1358
1359 %{$config_ref} = ();
1360 undef %{$config_ref};
1361
1362 my @key = keys %{$config_ref};
1363 if ($#key >= 0) {
1364 print "did not delete!\n";
1365 exit;
1366 }
1367 open (IN, "$output_config");
1368
1369 while (<IN>) {
1370 if (/^(CONFIG\S+)=(.*)/) {
1371 ${$config_ref}{$1} = $2;
1372 }
1373 }
1374 close(IN);
1375}
1376
1377sub get_dependencies {
1378 my ($config) = @_;
1379
1380 my $arr = $dependency{$config};
1381 if (!defined($arr)) {
1382 return ();
1383 }
1384
1385 my @deps = @{$arr};
1386
1387 foreach my $dep (@{$arr}) {
1388 print "ADD DEP $dep\n";
1389 @deps = (@deps, get_dependencies $dep);
1390 }
1391
1392 return @deps;
1393}
1394
1395sub create_config {
1396 my @configs = @_;
1397
1398 open(OUT, ">$output_config") or dodie "Can not write to $output_config";
1399
1400 foreach my $config (@configs) {
1401 print OUT "$config_set{$config}\n";
1402 my @deps = get_dependencies $config;
1403 foreach my $dep (@deps) {
1404 print OUT "$config_set{$dep}\n";
1405 }
1406 }
1407
1408 foreach my $config (keys %config_ignore) {
1409 print OUT "$config_ignore{$config}\n";
1410 }
1411 close(OUT);
1412
1413# exit;
Steven Rostedt612b9e92011-03-07 13:27:43 -05001414 make_oldconfig "";
Steven Rostedt0a05c762010-11-08 11:14:10 -05001415}
1416
1417sub compare_configs {
1418 my (%a, %b) = @_;
1419
1420 foreach my $item (keys %a) {
1421 if (!defined($b{$item})) {
1422 print "diff $item\n";
1423 return 1;
1424 }
1425 delete $b{$item};
1426 }
1427
1428 my @keys = keys %b;
1429 if ($#keys) {
1430 print "diff2 $keys[0]\n";
1431 }
1432 return -1 if ($#keys >= 0);
1433
1434 return 0;
1435}
1436
1437sub run_config_bisect_test {
1438 my ($type) = @_;
1439
1440 return run_bisect_test $type, "oldconfig";
1441}
1442
1443sub process_passed {
1444 my (%configs) = @_;
1445
1446 doprint "These configs had no failure: (Enabling them for further compiles)\n";
1447 # Passed! All these configs are part of a good compile.
1448 # Add them to the min options.
1449 foreach my $config (keys %configs) {
1450 if (defined($config_list{$config})) {
1451 doprint " removing $config\n";
1452 $config_ignore{$config} = $config_list{$config};
1453 delete $config_list{$config};
1454 }
1455 }
Steven Rostedtf1a27852010-11-11 11:34:38 -05001456 doprint "config copied to $outputdir/config_good\n";
1457 run_command "cp -f $output_config $outputdir/config_good";
Steven Rostedt0a05c762010-11-08 11:14:10 -05001458}
1459
1460sub process_failed {
1461 my ($config) = @_;
1462
1463 doprint "\n\n***************************************\n";
1464 doprint "Found bad config: $config\n";
1465 doprint "***************************************\n\n";
1466}
1467
1468sub run_config_bisect {
1469
1470 my @start_list = keys %config_list;
1471
1472 if ($#start_list < 0) {
1473 doprint "No more configs to test!!!\n";
1474 return -1;
1475 }
1476
1477 doprint "***** RUN TEST ***\n";
1478 my $type = $opt{"CONFIG_BISECT_TYPE[$iteration]"};
1479 my $ret;
1480 my %current_config;
1481
1482 my $count = $#start_list + 1;
1483 doprint " $count configs to test\n";
1484
1485 my $half = int($#start_list / 2);
1486
1487 do {
1488 my @tophalf = @start_list[0 .. $half];
1489
1490 create_config @tophalf;
1491 read_current_config \%current_config;
1492
1493 $count = $#tophalf + 1;
1494 doprint "Testing $count configs\n";
1495 my $found = 0;
1496 # make sure we test something
1497 foreach my $config (@tophalf) {
1498 if (defined($current_config{$config})) {
1499 logit " $config\n";
1500 $found = 1;
1501 }
1502 }
1503 if (!$found) {
1504 # try the other half
1505 doprint "Top half produced no set configs, trying bottom half\n";
1506 @tophalf = @start_list[$half .. $#start_list];
1507 create_config @tophalf;
1508 read_current_config \%current_config;
1509 foreach my $config (@tophalf) {
1510 if (defined($current_config{$config})) {
1511 logit " $config\n";
1512 $found = 1;
1513 }
1514 }
1515 if (!$found) {
1516 doprint "Failed: Can't make new config with current configs\n";
1517 foreach my $config (@start_list) {
1518 doprint " CONFIG: $config\n";
1519 }
1520 return -1;
1521 }
1522 $count = $#tophalf + 1;
1523 doprint "Testing $count configs\n";
1524 }
1525
1526 $ret = run_config_bisect_test $type;
1527
1528 if ($ret) {
1529 process_passed %current_config;
1530 return 0;
1531 }
1532
1533 doprint "This config had a failure.\n";
1534 doprint "Removing these configs that were not set in this config:\n";
Steven Rostedtf1a27852010-11-11 11:34:38 -05001535 doprint "config copied to $outputdir/config_bad\n";
1536 run_command "cp -f $output_config $outputdir/config_bad";
Steven Rostedt0a05c762010-11-08 11:14:10 -05001537
1538 # A config exists in this group that was bad.
1539 foreach my $config (keys %config_list) {
1540 if (!defined($current_config{$config})) {
1541 doprint " removing $config\n";
1542 delete $config_list{$config};
1543 }
1544 }
1545
1546 @start_list = @tophalf;
1547
1548 if ($#start_list == 0) {
1549 process_failed $start_list[0];
1550 return 1;
1551 }
1552
1553 # remove half the configs we are looking at and see if
1554 # they are good.
1555 $half = int($#start_list / 2);
1556 } while ($half > 0);
1557
1558 # we found a single config, try it again
1559 my @tophalf = @start_list[0 .. 0];
1560
1561 $ret = run_config_bisect_test $type;
1562 if ($ret) {
1563 process_passed %current_config;
1564 return 0;
1565 }
1566
1567 process_failed $start_list[0];
1568 return 1;
1569}
1570
1571sub config_bisect {
1572 my ($i) = @_;
1573
1574 my $start_config = $opt{"CONFIG_BISECT[$i]"};
1575
1576 my $tmpconfig = "$tmpdir/use_config";
1577
1578 # Make the file with the bad config and the min config
1579 if (defined($minconfig)) {
1580 # read the min config for things to ignore
1581 run_command "cp $minconfig $tmpconfig" or
1582 dodie "failed to copy $minconfig to $tmpconfig";
1583 } else {
1584 unlink $tmpconfig;
1585 }
1586
1587 # Add other configs
1588 if (defined($addconfig)) {
1589 run_command "cat $addconfig >> $tmpconfig" or
1590 dodie "failed to append $addconfig";
1591 }
1592
1593 my $defconfig = "";
1594 if (-f $tmpconfig) {
1595 $defconfig = "KCONFIG_ALLCONFIG=$tmpconfig";
1596 process_config_ignore $tmpconfig;
1597 }
1598
1599 # now process the start config
1600 run_command "cp $start_config $output_config" or
1601 dodie "failed to copy $start_config to $output_config";
1602
1603 # read directly what we want to check
1604 my %config_check;
1605 open (IN, $output_config)
1606 or dodie "faied to open $output_config";
1607
1608 while (<IN>) {
1609 if (/^((CONFIG\S*)=.*)/) {
1610 $config_check{$2} = $1;
1611 }
1612 }
1613 close(IN);
1614
1615 # Now run oldconfig with the minconfig (and addconfigs)
Steven Rostedt612b9e92011-03-07 13:27:43 -05001616 make_oldconfig $defconfig;
Steven Rostedt0a05c762010-11-08 11:14:10 -05001617
1618 # check to see what we lost (or gained)
1619 open (IN, $output_config)
1620 or dodie "Failed to read $start_config";
1621
1622 my %removed_configs;
1623 my %added_configs;
1624
1625 while (<IN>) {
1626 if (/^((CONFIG\S*)=.*)/) {
1627 # save off all options
1628 $config_set{$2} = $1;
1629 if (defined($config_check{$2})) {
1630 if (defined($config_ignore{$2})) {
1631 $removed_configs{$2} = $1;
1632 } else {
1633 $config_list{$2} = $1;
1634 }
1635 } elsif (!defined($config_ignore{$2})) {
1636 $added_configs{$2} = $1;
1637 $config_list{$2} = $1;
1638 }
1639 }
1640 }
1641 close(IN);
1642
1643 my @confs = keys %removed_configs;
1644 if ($#confs >= 0) {
1645 doprint "Configs overridden by default configs and removed from check:\n";
1646 foreach my $config (@confs) {
1647 doprint " $config\n";
1648 }
1649 }
1650 @confs = keys %added_configs;
1651 if ($#confs >= 0) {
1652 doprint "Configs appearing in make oldconfig and added:\n";
1653 foreach my $config (@confs) {
1654 doprint " $config\n";
1655 }
1656 }
1657
1658 my %config_test;
1659 my $once = 0;
1660
1661 # Sometimes kconfig does weird things. We must make sure
1662 # that the config we autocreate has everything we need
1663 # to test, otherwise we may miss testing configs, or
1664 # may not be able to create a new config.
1665 # Here we create a config with everything set.
1666 create_config (keys %config_list);
1667 read_current_config \%config_test;
1668 foreach my $config (keys %config_list) {
1669 if (!defined($config_test{$config})) {
1670 if (!$once) {
1671 $once = 1;
1672 doprint "Configs not produced by kconfig (will not be checked):\n";
1673 }
1674 doprint " $config\n";
1675 delete $config_list{$config};
1676 }
1677 }
1678 my $ret;
1679 do {
1680 $ret = run_config_bisect;
1681 } while (!$ret);
1682
1683 return $ret if ($ret < 0);
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001684
1685 success $i;
1686}
1687
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001688sub patchcheck {
1689 my ($i) = @_;
1690
1691 die "PATCHCHECK_START[$i] not defined\n"
1692 if (!defined($opt{"PATCHCHECK_START[$i]"}));
1693 die "PATCHCHECK_TYPE[$i] not defined\n"
1694 if (!defined($opt{"PATCHCHECK_TYPE[$i]"}));
1695
1696 my $start = $opt{"PATCHCHECK_START[$i]"};
1697
1698 my $end = "HEAD";
1699 if (defined($opt{"PATCHCHECK_END[$i]"})) {
1700 $end = $opt{"PATCHCHECK_END[$i]"};
1701 }
1702
Steven Rostedta57419b2010-11-02 15:13:54 -04001703 # Get the true sha1's since we can use things like HEAD~3
1704 $start = get_sha1($start);
1705 $end = get_sha1($end);
1706
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001707 my $type = $opt{"PATCHCHECK_TYPE[$i]"};
1708
1709 # Can't have a test without having a test to run
1710 if ($type eq "test" && !defined($run_test)) {
1711 $type = "boot";
1712 }
1713
1714 open (IN, "git log --pretty=oneline $end|") or
1715 dodie "could not get git list";
1716
1717 my @list;
1718
1719 while (<IN>) {
1720 chomp;
1721 $list[$#list+1] = $_;
1722 last if (/^$start/);
1723 }
1724 close(IN);
1725
1726 if ($list[$#list] !~ /^$start/) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001727 fail "SHA1 $start not found";
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001728 }
1729
1730 # go backwards in the list
1731 @list = reverse @list;
1732
1733 my $save_clean = $noclean;
1734
1735 $in_patchcheck = 1;
1736 foreach my $item (@list) {
1737 my $sha1 = $item;
1738 $sha1 =~ s/^([[:xdigit:]]+).*/$1/;
1739
1740 doprint "\nProcessing commit $item\n\n";
1741
1742 run_command "git checkout $sha1" or
1743 die "Failed to checkout $sha1";
1744
1745 # only clean on the first and last patch
1746 if ($item eq $list[0] ||
1747 $item eq $list[$#list]) {
1748 $noclean = $save_clean;
1749 } else {
1750 $noclean = 1;
1751 }
1752
1753 if (defined($minconfig)) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001754 build "useconfig:$minconfig" or return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001755 } else {
1756 # ?? no config to use?
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001757 build "oldconfig" or return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001758 }
1759
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001760 check_buildlog $sha1 or return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001761
1762 next if ($type eq "build");
1763
1764 get_grub_index;
1765 get_version;
1766 install;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001767
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001768 my $failed = 0;
1769
1770 start_monitor;
1771 monitor or $failed = 1;
1772
1773 if (!$failed && $type ne "boot"){
1774 do_run_test or $failed = 1;
1775 }
1776 end_monitor;
1777 return 0 if ($failed);
1778
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001779 }
1780 $in_patchcheck = 0;
1781 success $i;
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001782
1783 return 1;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001784}
1785
Steven Rostedt8d1491b2010-11-18 15:39:48 -05001786$#ARGV < 1 or die "ktest.pl version: $VERSION\n usage: ktest.pl config-file\n";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001787
Steven Rostedt8d1491b2010-11-18 15:39:48 -05001788if ($#ARGV == 0) {
1789 $ktest_config = $ARGV[0];
1790 if (! -f $ktest_config) {
1791 print "$ktest_config does not exist.\n";
1792 my $ans;
1793 for (;;) {
1794 print "Create it? [Y/n] ";
1795 $ans = <STDIN>;
1796 chomp $ans;
1797 if ($ans =~ /^\s*$/) {
1798 $ans = "y";
1799 }
1800 last if ($ans =~ /^y$/i || $ans =~ /^n$/i);
1801 print "Please answer either 'y' or 'n'.\n";
1802 }
1803 if ($ans !~ /^y$/i) {
1804 exit 0;
1805 }
1806 }
1807} else {
1808 $ktest_config = "ktest.conf";
1809}
1810
1811if (! -f $ktest_config) {
1812 open(OUT, ">$ktest_config") or die "Can not create $ktest_config";
1813 print OUT << "EOF"
1814# Generated by ktest.pl
1815#
1816# Define each test with TEST_START
1817# The config options below it will override the defaults
1818TEST_START
1819
1820DEFAULTS
1821EOF
1822;
1823 close(OUT);
1824}
1825read_config $ktest_config;
1826
1827# Append any configs entered in manually to the config file.
1828my @new_configs = keys %entered_configs;
1829if ($#new_configs >= 0) {
1830 print "\nAppending entered in configs to $ktest_config\n";
1831 open(OUT, ">>$ktest_config") or die "Can not append to $ktest_config";
1832 foreach my $config (@new_configs) {
1833 print OUT "$config = $entered_configs{$config}\n";
1834 $opt{$config} = $entered_configs{$config};
1835 }
1836}
Steven Rostedt2545eb62010-11-02 15:01:32 -04001837
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001838if ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) {
1839 unlink $opt{"LOG_FILE"};
1840}
Steven Rostedt2545eb62010-11-02 15:01:32 -04001841
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001842doprint "\n\nSTARTING AUTOMATED TESTS\n\n";
1843
Steven Rostedta57419b2010-11-02 15:13:54 -04001844for (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) {
1845
1846 if (!$i) {
1847 doprint "DEFAULT OPTIONS:\n";
1848 } else {
1849 doprint "\nTEST $i OPTIONS";
1850 if (defined($repeat_tests{$i})) {
1851 $repeat = $repeat_tests{$i};
1852 doprint " ITERATE $repeat";
1853 }
1854 doprint "\n";
1855 }
1856
1857 foreach my $option (sort keys %opt) {
1858
1859 if ($option =~ /\[(\d+)\]$/) {
1860 next if ($i != $1);
1861 } else {
1862 next if ($i);
1863 }
1864
1865 doprint "$option = $opt{$option}\n";
1866 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001867}
Steven Rostedt2545eb62010-11-02 15:01:32 -04001868
Steven Rostedta75fece2010-11-02 14:58:27 -04001869sub set_test_option {
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001870 my ($name, $i) = @_;
1871
1872 my $option = "$name\[$i\]";
1873
1874 if (defined($opt{$option})) {
1875 return $opt{$option};
1876 }
1877
Steven Rostedta57419b2010-11-02 15:13:54 -04001878 foreach my $test (keys %repeat_tests) {
1879 if ($i >= $test &&
1880 $i < $test + $repeat_tests{$test}) {
1881 $option = "$name\[$test\]";
1882 if (defined($opt{$option})) {
1883 return $opt{$option};
1884 }
1885 }
1886 }
1887
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001888 if (defined($opt{$name})) {
1889 return $opt{$name};
1890 }
1891
1892 return undef;
1893}
1894
Steven Rostedt2545eb62010-11-02 15:01:32 -04001895# First we need to do is the builds
Steven Rostedta75fece2010-11-02 14:58:27 -04001896for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
Steven Rostedt2545eb62010-11-02 15:01:32 -04001897
Steven Rostedt576f6272010-11-02 14:58:38 -04001898 $iteration = $i;
1899
Steven Rostedta75fece2010-11-02 14:58:27 -04001900 my $makecmd = set_test_option("MAKE_CMD", $i);
1901
1902 $machine = set_test_option("MACHINE", $i);
Steven Rostedte48c5292010-11-02 14:35:37 -04001903 $ssh_user = set_test_option("SSH_USER", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04001904 $tmpdir = set_test_option("TMP_DIR", $i);
1905 $outputdir = set_test_option("OUTPUT_DIR", $i);
1906 $builddir = set_test_option("BUILD_DIR", $i);
1907 $test_type = set_test_option("TEST_TYPE", $i);
1908 $build_type = set_test_option("BUILD_TYPE", $i);
1909 $build_options = set_test_option("BUILD_OPTIONS", $i);
1910 $power_cycle = set_test_option("POWER_CYCLE", $i);
Steven Rostedte48c5292010-11-02 14:35:37 -04001911 $reboot = set_test_option("REBOOT", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04001912 $noclean = set_test_option("BUILD_NOCLEAN", $i);
1913 $minconfig = set_test_option("MIN_CONFIG", $i);
1914 $run_test = set_test_option("TEST", $i);
1915 $addconfig = set_test_option("ADD_CONFIG", $i);
1916 $reboot_type = set_test_option("REBOOT_TYPE", $i);
1917 $grub_menu = set_test_option("GRUB_MENU", $i);
Steven Rostedt8b37ca82010-11-02 14:58:33 -04001918 $post_install = set_test_option("POST_INSTALL", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04001919 $reboot_script = set_test_option("REBOOT_SCRIPT", $i);
1920 $reboot_on_error = set_test_option("REBOOT_ON_ERROR", $i);
1921 $poweroff_on_error = set_test_option("POWEROFF_ON_ERROR", $i);
1922 $die_on_failure = set_test_option("DIE_ON_FAILURE", $i);
1923 $power_off = set_test_option("POWER_OFF", $i);
Steven Rostedt576f6272010-11-02 14:58:38 -04001924 $powercycle_after_reboot = set_test_option("POWERCYCLE_AFTER_REBOOT", $i);
1925 $poweroff_after_halt = set_test_option("POWEROFF_AFTER_HALT", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04001926 $sleep_time = set_test_option("SLEEP_TIME", $i);
1927 $bisect_sleep_time = set_test_option("BISECT_SLEEP_TIME", $i);
1928 $store_failures = set_test_option("STORE_FAILURES", $i);
1929 $timeout = set_test_option("TIMEOUT", $i);
1930 $booted_timeout = set_test_option("BOOTED_TIMEOUT", $i);
1931 $console = set_test_option("CONSOLE", $i);
1932 $success_line = set_test_option("SUCCESS_LINE", $i);
Steven Rostedt1c8a6172010-11-09 12:55:40 -05001933 $stop_after_success = set_test_option("STOP_AFTER_SUCCESS", $i);
1934 $stop_after_failure = set_test_option("STOP_AFTER_FAILURE", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04001935 $build_target = set_test_option("BUILD_TARGET", $i);
Steven Rostedte48c5292010-11-02 14:35:37 -04001936 $ssh_exec = set_test_option("SSH_EXEC", $i);
1937 $scp_to_target = set_test_option("SCP_TO_TARGET", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04001938 $target_image = set_test_option("TARGET_IMAGE", $i);
1939 $localversion = set_test_option("LOCALVERSION", $i);
1940
1941 chdir $builddir || die "can't change directory to $builddir";
1942
1943 if (!-d $tmpdir) {
1944 mkpath($tmpdir) or
1945 die "can't create $tmpdir";
1946 }
1947
Steven Rostedte48c5292010-11-02 14:35:37 -04001948 $ENV{"SSH_USER"} = $ssh_user;
1949 $ENV{"MACHINE"} = $machine;
1950
Steven Rostedta75fece2010-11-02 14:58:27 -04001951 $target = "$ssh_user\@$machine";
1952
1953 $buildlog = "$tmpdir/buildlog-$machine";
1954 $dmesg = "$tmpdir/dmesg-$machine";
1955 $make = "$makecmd O=$outputdir";
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05001956 $output_config = "$outputdir/.config";
Steven Rostedta75fece2010-11-02 14:58:27 -04001957
1958 if ($reboot_type eq "grub") {
Steven Rostedt576f6272010-11-02 14:58:38 -04001959 dodie "GRUB_MENU not defined" if (!defined($grub_menu));
Steven Rostedta75fece2010-11-02 14:58:27 -04001960 } elsif (!defined($reboot_script)) {
Steven Rostedt576f6272010-11-02 14:58:38 -04001961 dodie "REBOOT_SCRIPT not defined"
Steven Rostedta75fece2010-11-02 14:58:27 -04001962 }
1963
1964 my $run_type = $build_type;
1965 if ($test_type eq "patchcheck") {
1966 $run_type = $opt{"PATCHCHECK_TYPE[$i]"};
1967 } elsif ($test_type eq "bisect") {
1968 $run_type = $opt{"BISECT_TYPE[$i]"};
Steven Rostedt0a05c762010-11-08 11:14:10 -05001969 } elsif ($test_type eq "config_bisect") {
1970 $run_type = $opt{"CONFIG_BISECT_TYPE[$i]"};
Steven Rostedta75fece2010-11-02 14:58:27 -04001971 }
1972
1973 # mistake in config file?
1974 if (!defined($run_type)) {
1975 $run_type = "ERROR";
1976 }
Steven Rostedt2545eb62010-11-02 15:01:32 -04001977
1978 doprint "\n\n";
Steven Rostedta75fece2010-11-02 14:58:27 -04001979 doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type\n\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001980
1981 unlink $dmesg;
1982 unlink $buildlog;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001983
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001984 if (!defined($minconfig)) {
1985 $minconfig = $addconfig;
1986
1987 } elsif (defined($addconfig)) {
Steven Rostedt9be2e6b2010-11-09 12:20:21 -05001988 run_command "cat $addconfig $minconfig > $tmpdir/add_config" or
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001989 dodie "Failed to create temp config";
Steven Rostedt9be2e6b2010-11-09 12:20:21 -05001990 $minconfig = "$tmpdir/add_config";
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001991 }
1992
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001993 my $checkout = $opt{"CHECKOUT[$i]"};
1994 if (defined($checkout)) {
1995 run_command "git checkout $checkout" or
1996 die "failed to checkout $checkout";
1997 }
1998
Steven Rostedta75fece2010-11-02 14:58:27 -04001999 if ($test_type eq "bisect") {
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04002000 bisect $i;
2001 next;
Steven Rostedt0a05c762010-11-08 11:14:10 -05002002 } elsif ($test_type eq "config_bisect") {
2003 config_bisect $i;
2004 next;
Steven Rostedta75fece2010-11-02 14:58:27 -04002005 } elsif ($test_type eq "patchcheck") {
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002006 patchcheck $i;
2007 next;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04002008 }
2009
Steven Rostedt7faafbd2010-11-02 14:58:22 -04002010 if ($build_type ne "nobuild") {
2011 build $build_type or next;
Steven Rostedt2545eb62010-11-02 15:01:32 -04002012 }
2013
Steven Rostedta75fece2010-11-02 14:58:27 -04002014 if ($test_type ne "build") {
2015 get_grub_index;
2016 get_version;
2017 install;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04002018
Steven Rostedta75fece2010-11-02 14:58:27 -04002019 my $failed = 0;
2020 start_monitor;
2021 monitor or $failed = 1;;
2022
2023 if (!$failed && $test_type ne "boot" && defined($run_test)) {
2024 do_run_test or $failed = 1;
2025 }
2026 end_monitor;
2027 next if ($failed);
Steven Rostedt5a391fb2010-11-02 14:57:43 -04002028 }
2029
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04002030 success $i;
Steven Rostedt2545eb62010-11-02 15:01:32 -04002031}
2032
Steven Rostedt5c42fc52010-11-02 14:57:01 -04002033if ($opt{"POWEROFF_ON_SUCCESS"}) {
Steven Rostedt75c3fda72010-11-02 14:57:21 -04002034 halt;
Steven Rostedt576f6272010-11-02 14:58:38 -04002035} elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot) {
Steven Rostedt75c3fda72010-11-02 14:57:21 -04002036 reboot;
Steven Rostedt5c42fc52010-11-02 14:57:01 -04002037}
Steven Rostedt75c3fda72010-11-02 14:57:21 -04002038
Steven Rostedte48c5292010-11-02 14:35:37 -04002039doprint "\n $successes of $opt{NUM_TESTS} tests were successful\n\n";
2040
Steven Rostedt2545eb62010-11-02 15:01:32 -04002041exit 0;