blob: 1e1fe835df48e1a7019eea0ea46ff6914396ea5b [file] [log] [blame]
Steven Rostedt2545eb62010-11-02 15:01:32 -04001#!/usr/bin/perl -w
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04002#
Uwe Kleine-Königcce1dac2011-01-24 21:12:01 +01003# Copyright 2010 - Steven Rostedt <srostedt@redhat.com>, Red Hat Inc.
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04004# 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
Steven Rostedt27d934b2011-05-20 09:18:18 -040039$default{"PATCHCHECK_SLEEP_TIME"} = 60; # sleep time between patch checks
Steven Rostedta75fece2010-11-02 14:58:27 -040040$default{"CLEAR_LOG"} = 0;
Steven Rostedtc960bb92011-03-08 09:22:39 -050041$default{"BISECT_MANUAL"} = 0;
Steven Rostedtc23dca72011-03-08 09:26:31 -050042$default{"BISECT_SKIP"} = 1;
Steven Rostedta75fece2010-11-02 14:58:27 -040043$default{"SUCCESS_LINE"} = "login:";
Steven Rostedtf1a5b962011-06-13 10:30:00 -040044$default{"DETECT_TRIPLE_FAULT"} = 1;
Steven Rostedta75fece2010-11-02 14:58:27 -040045$default{"BOOTED_TIMEOUT"} = 1;
46$default{"DIE_ON_FAILURE"} = 1;
Steven Rostedte48c5292010-11-02 14:35:37 -040047$default{"SSH_EXEC"} = "ssh \$SSH_USER\@\$MACHINE \$SSH_COMMAND";
48$default{"SCP_TO_TARGET"} = "scp \$SRC_FILE \$SSH_USER\@\$MACHINE:\$DST_FILE";
49$default{"REBOOT"} = "ssh \$SSH_USER\@\$MACHINE reboot";
Steven Rostedt1c8a6172010-11-09 12:55:40 -050050$default{"STOP_AFTER_SUCCESS"} = 10;
51$default{"STOP_AFTER_FAILURE"} = 60;
Steven Rostedt2d01b262011-03-08 09:47:54 -050052$default{"STOP_TEST_AFTER"} = 600;
Steven Rostedt8d1491b2010-11-18 15:39:48 -050053$default{"LOCALVERSION"} = "-test";
Steven Rostedt2545eb62010-11-02 15:01:32 -040054
Steven Rostedt8d1491b2010-11-18 15:39:48 -050055my $ktest_config;
Steven Rostedt2545eb62010-11-02 15:01:32 -040056my $version;
Steven Rostedta75fece2010-11-02 14:58:27 -040057my $machine;
Steven Rostedte48c5292010-11-02 14:35:37 -040058my $ssh_user;
Steven Rostedta75fece2010-11-02 14:58:27 -040059my $tmpdir;
60my $builddir;
61my $outputdir;
Steven Rostedt51ad1dd2010-11-08 16:43:21 -050062my $output_config;
Steven Rostedta75fece2010-11-02 14:58:27 -040063my $test_type;
Steven Rostedt7faafbd2010-11-02 14:58:22 -040064my $build_type;
Steven Rostedta75fece2010-11-02 14:58:27 -040065my $build_options;
66my $reboot_type;
67my $reboot_script;
68my $power_cycle;
Steven Rostedte48c5292010-11-02 14:35:37 -040069my $reboot;
Steven Rostedta75fece2010-11-02 14:58:27 -040070my $reboot_on_error;
71my $poweroff_on_error;
72my $die_on_failure;
Steven Rostedt576f6272010-11-02 14:58:38 -040073my $powercycle_after_reboot;
74my $poweroff_after_halt;
Steven Rostedte48c5292010-11-02 14:35:37 -040075my $ssh_exec;
76my $scp_to_target;
Steven Rostedta75fece2010-11-02 14:58:27 -040077my $power_off;
78my $grub_menu;
Steven Rostedt2545eb62010-11-02 15:01:32 -040079my $grub_number;
80my $target;
81my $make;
Steven Rostedt8b37ca82010-11-02 14:58:33 -040082my $post_install;
Steven Rostedt5c42fc52010-11-02 14:57:01 -040083my $noclean;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -040084my $minconfig;
Steven Rostedt2b7d9b22010-11-02 14:58:15 -040085my $addconfig;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -040086my $in_bisect = 0;
87my $bisect_bad = "";
Steven Rostedtd6ce2a02010-11-02 14:58:05 -040088my $reverse_bisect;
Steven Rostedtc960bb92011-03-08 09:22:39 -050089my $bisect_manual;
Steven Rostedtc23dca72011-03-08 09:26:31 -050090my $bisect_skip;
Steven Rostedt30f75da2011-06-13 10:35:35 -040091my $config_bisect_good;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -040092my $in_patchcheck = 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -040093my $run_test;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -040094my $redirect;
Steven Rostedt7faafbd2010-11-02 14:58:22 -040095my $buildlog;
96my $dmesg;
97my $monitor_fp;
98my $monitor_pid;
99my $monitor_cnt = 0;
Steven Rostedta75fece2010-11-02 14:58:27 -0400100my $sleep_time;
101my $bisect_sleep_time;
Steven Rostedt27d934b2011-05-20 09:18:18 -0400102my $patchcheck_sleep_time;
Steven Rostedta75fece2010-11-02 14:58:27 -0400103my $store_failures;
Steven Rostedt9064af52011-06-13 10:38:48 -0400104my $test_name;
Steven Rostedta75fece2010-11-02 14:58:27 -0400105my $timeout;
106my $booted_timeout;
Steven Rostedtf1a5b962011-06-13 10:30:00 -0400107my $detect_triplefault;
Steven Rostedta75fece2010-11-02 14:58:27 -0400108my $console;
109my $success_line;
Steven Rostedt1c8a6172010-11-09 12:55:40 -0500110my $stop_after_success;
111my $stop_after_failure;
Steven Rostedt2d01b262011-03-08 09:47:54 -0500112my $stop_test_after;
Steven Rostedta75fece2010-11-02 14:58:27 -0400113my $build_target;
114my $target_image;
115my $localversion;
Steven Rostedt576f6272010-11-02 14:58:38 -0400116my $iteration = 0;
Steven Rostedte48c5292010-11-02 14:35:37 -0400117my $successes = 0;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400118
Steven Rostedt8d1491b2010-11-18 15:39:48 -0500119my %entered_configs;
120my %config_help;
Steven Rostedt77d942c2011-05-20 13:36:58 -0400121my %variable;
Steven Rostedtfcb3f162011-06-13 10:40:58 -0400122my %force_config;
Steven Rostedt8d1491b2010-11-18 15:39:48 -0500123
124$config_help{"MACHINE"} = << "EOF"
125 The machine hostname that you will test.
126EOF
127 ;
128$config_help{"SSH_USER"} = << "EOF"
129 The box is expected to have ssh on normal bootup, provide the user
130 (most likely root, since you need privileged operations)
131EOF
132 ;
133$config_help{"BUILD_DIR"} = << "EOF"
134 The directory that contains the Linux source code (full path).
135EOF
136 ;
137$config_help{"OUTPUT_DIR"} = << "EOF"
138 The directory that the objects will be built (full path).
139 (can not be same as BUILD_DIR)
140EOF
141 ;
142$config_help{"BUILD_TARGET"} = << "EOF"
143 The location of the compiled file to copy to the target.
144 (relative to OUTPUT_DIR)
145EOF
146 ;
147$config_help{"TARGET_IMAGE"} = << "EOF"
148 The place to put your image on the test machine.
149EOF
150 ;
151$config_help{"POWER_CYCLE"} = << "EOF"
152 A script or command to reboot the box.
153
154 Here is a digital loggers power switch example
155 POWER_CYCLE = wget --no-proxy -O /dev/null -q --auth-no-challenge 'http://admin:admin\@power/outlet?5=CCL'
156
157 Here is an example to reboot a virtual box on the current host
158 with the name "Guest".
159 POWER_CYCLE = virsh destroy Guest; sleep 5; virsh start Guest
160EOF
161 ;
162$config_help{"CONSOLE"} = << "EOF"
163 The script or command that reads the console
164
165 If you use ttywatch server, something like the following would work.
166CONSOLE = nc -d localhost 3001
167
168 For a virtual machine with guest name "Guest".
169CONSOLE = virsh console Guest
170EOF
171 ;
172$config_help{"LOCALVERSION"} = << "EOF"
173 Required version ending to differentiate the test
174 from other linux builds on the system.
175EOF
176 ;
177$config_help{"REBOOT_TYPE"} = << "EOF"
178 Way to reboot the box to the test kernel.
179 Only valid options so far are "grub" and "script".
180
181 If you specify grub, it will assume grub version 1
182 and will search in /boot/grub/menu.lst for the title \$GRUB_MENU
183 and select that target to reboot to the kernel. If this is not
184 your setup, then specify "script" and have a command or script
185 specified in REBOOT_SCRIPT to boot to the target.
186
187 The entry in /boot/grub/menu.lst must be entered in manually.
188 The test will not modify that file.
189EOF
190 ;
191$config_help{"GRUB_MENU"} = << "EOF"
192 The grub title name for the test kernel to boot
193 (Only mandatory if REBOOT_TYPE = grub)
194
195 Note, ktest.pl will not update the grub menu.lst, you need to
196 manually add an option for the test. ktest.pl will search
197 the grub menu.lst for this option to find what kernel to
198 reboot into.
199
200 For example, if in the /boot/grub/menu.lst the test kernel title has:
201 title Test Kernel
202 kernel vmlinuz-test
203 GRUB_MENU = Test Kernel
204EOF
205 ;
206$config_help{"REBOOT_SCRIPT"} = << "EOF"
207 A script to reboot the target into the test kernel
208 (Only mandatory if REBOOT_TYPE = script)
209EOF
210 ;
211
212
213sub get_ktest_config {
214 my ($config) = @_;
215
216 return if (defined($opt{$config}));
217
218 if (defined($config_help{$config})) {
219 print "\n";
220 print $config_help{$config};
221 }
222
223 for (;;) {
224 print "$config = ";
225 if (defined($default{$config})) {
226 print "\[$default{$config}\] ";
227 }
228 $entered_configs{$config} = <STDIN>;
229 $entered_configs{$config} =~ s/^\s*(.*\S)\s*$/$1/;
230 if ($entered_configs{$config} =~ /^\s*$/) {
231 if ($default{$config}) {
232 $entered_configs{$config} = $default{$config};
233 } else {
234 print "Your answer can not be blank\n";
235 next;
236 }
237 }
238 last;
239 }
240}
241
242sub get_ktest_configs {
243 get_ktest_config("MACHINE");
244 get_ktest_config("SSH_USER");
245 get_ktest_config("BUILD_DIR");
246 get_ktest_config("OUTPUT_DIR");
247 get_ktest_config("BUILD_TARGET");
248 get_ktest_config("TARGET_IMAGE");
249 get_ktest_config("POWER_CYCLE");
250 get_ktest_config("CONSOLE");
251 get_ktest_config("LOCALVERSION");
252
253 my $rtype = $opt{"REBOOT_TYPE"};
254
255 if (!defined($rtype)) {
256 if (!defined($opt{"GRUB_MENU"})) {
257 get_ktest_config("REBOOT_TYPE");
258 $rtype = $entered_configs{"REBOOT_TYPE"};
259 } else {
260 $rtype = "grub";
261 }
262 }
263
264 if ($rtype eq "grub") {
265 get_ktest_config("GRUB_MENU");
266 } else {
267 get_ktest_config("REBOOT_SCRIPT");
268 }
269}
270
Steven Rostedt77d942c2011-05-20 13:36:58 -0400271sub process_variables {
272 my ($value) = @_;
273 my $retval = "";
274
275 # We want to check for '\', and it is just easier
276 # to check the previous characet of '$' and not need
277 # to worry if '$' is the first character. By adding
278 # a space to $value, we can just check [^\\]\$ and
279 # it will still work.
280 $value = " $value";
281
282 while ($value =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
283 my $begin = $1;
284 my $var = $2;
285 my $end = $3;
286 # append beginning of value to retval
287 $retval = "$retval$begin";
288 if (defined($variable{$var})) {
289 $retval = "$retval$variable{$var}";
290 } else {
291 # put back the origin piece.
292 $retval = "$retval\$\{$var\}";
293 }
294 $value = $end;
295 }
296 $retval = "$retval$value";
297
298 # remove the space added in the beginning
299 $retval =~ s/ //;
300
301 return "$retval"
302}
303
Steven Rostedta57419b2010-11-02 15:13:54 -0400304sub set_value {
305 my ($lvalue, $rvalue) = @_;
306
307 if (defined($opt{$lvalue})) {
308 die "Error: Option $lvalue defined more than once!\n";
309 }
Steven Rostedt21a96792010-11-08 16:45:50 -0500310 if ($rvalue =~ /^\s*$/) {
311 delete $opt{$lvalue};
312 } else {
Steven Rostedt77d942c2011-05-20 13:36:58 -0400313 $rvalue = process_variables($rvalue);
Steven Rostedt21a96792010-11-08 16:45:50 -0500314 $opt{$lvalue} = $rvalue;
315 }
Steven Rostedta57419b2010-11-02 15:13:54 -0400316}
317
Steven Rostedt77d942c2011-05-20 13:36:58 -0400318sub set_variable {
319 my ($lvalue, $rvalue) = @_;
320
321 if ($rvalue =~ /^\s*$/) {
322 delete $variable{$lvalue};
323 } else {
324 $rvalue = process_variables($rvalue);
325 $variable{$lvalue} = $rvalue;
326 }
327}
328
Steven Rostedt2545eb62010-11-02 15:01:32 -0400329sub read_config {
330 my ($config) = @_;
331
332 open(IN, $config) || die "can't read file $config";
333
Steven Rostedta57419b2010-11-02 15:13:54 -0400334 my $name = $config;
335 $name =~ s,.*/(.*),$1,;
336
337 my $test_num = 0;
338 my $default = 1;
339 my $repeat = 1;
340 my $num_tests_set = 0;
341 my $skip = 0;
342 my $rest;
343
Steven Rostedt2545eb62010-11-02 15:01:32 -0400344 while (<IN>) {
345
346 # ignore blank lines and comments
347 next if (/^\s*$/ || /\s*\#/);
348
Steven Rostedta57419b2010-11-02 15:13:54 -0400349 if (/^\s*TEST_START(.*)/) {
350
351 $rest = $1;
352
353 if ($num_tests_set) {
354 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
355 }
356
357 my $old_test_num = $test_num;
Steven Rostedte48c5292010-11-02 14:35:37 -0400358 my $old_repeat = $repeat;
Steven Rostedta57419b2010-11-02 15:13:54 -0400359
360 $test_num += $repeat;
361 $default = 0;
362 $repeat = 1;
363
364 if ($rest =~ /\s+SKIP(.*)/) {
365 $rest = $1;
366 $skip = 1;
367 } else {
368 $skip = 0;
369 }
370
371 if ($rest =~ /\s+ITERATE\s+(\d+)(.*)$/) {
372 $repeat = $1;
373 $rest = $2;
374 $repeat_tests{"$test_num"} = $repeat;
375 }
376
377 if ($rest =~ /\s+SKIP(.*)/) {
378 $rest = $1;
379 $skip = 1;
380 }
381
382 if ($rest !~ /^\s*$/) {
383 die "$name: $.: Gargbage found after TEST_START\n$_";
384 }
385
386 if ($skip) {
387 $test_num = $old_test_num;
Steven Rostedte48c5292010-11-02 14:35:37 -0400388 $repeat = $old_repeat;
Steven Rostedta57419b2010-11-02 15:13:54 -0400389 }
390
391 } elsif (/^\s*DEFAULTS(.*)$/) {
392 $default = 1;
393
394 $rest = $1;
395
396 if ($rest =~ /\s+SKIP(.*)/) {
397 $rest = $1;
398 $skip = 1;
399 } else {
400 $skip = 0;
401 }
402
403 if ($rest !~ /^\s*$/) {
404 die "$name: $.: Gargbage found after DEFAULTS\n$_";
405 }
406
407 } elsif (/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) {
408
409 next if ($skip);
410
Steven Rostedt2545eb62010-11-02 15:01:32 -0400411 my $lvalue = $1;
412 my $rvalue = $2;
413
Steven Rostedta57419b2010-11-02 15:13:54 -0400414 if (!$default &&
415 ($lvalue eq "NUM_TESTS" ||
416 $lvalue eq "LOG_FILE" ||
417 $lvalue eq "CLEAR_LOG")) {
418 die "$name: $.: $lvalue must be set in DEFAULTS section\n";
Steven Rostedta75fece2010-11-02 14:58:27 -0400419 }
Steven Rostedta57419b2010-11-02 15:13:54 -0400420
421 if ($lvalue eq "NUM_TESTS") {
422 if ($test_num) {
423 die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n";
424 }
425 if (!$default) {
426 die "$name: $.: NUM_TESTS must be set in default section\n";
427 }
428 $num_tests_set = 1;
429 }
430
431 if ($default || $lvalue =~ /\[\d+\]$/) {
432 set_value($lvalue, $rvalue);
433 } else {
434 my $val = "$lvalue\[$test_num\]";
435 set_value($val, $rvalue);
436
437 if ($repeat > 1) {
438 $repeats{$val} = $repeat;
439 }
440 }
Steven Rostedt77d942c2011-05-20 13:36:58 -0400441 } elsif (/^\s*([A-Z_\[\]\d]+)\s*:=\s*(.*?)\s*$/) {
442 next if ($skip);
443
444 my $lvalue = $1;
445 my $rvalue = $2;
446
447 # process config variables.
448 # Config variables are only active while reading the
449 # config and can be defined anywhere. They also ignore
450 # TEST_START and DEFAULTS, but are skipped if they are in
451 # on of these sections that have SKIP defined.
452 # The save variable can be
453 # defined multiple times and the new one simply overrides
454 # the prevous one.
455 set_variable($lvalue, $rvalue);
456
Steven Rostedta57419b2010-11-02 15:13:54 -0400457 } else {
458 die "$name: $.: Garbage found in config\n$_";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400459 }
460 }
461
462 close(IN);
Steven Rostedta75fece2010-11-02 14:58:27 -0400463
Steven Rostedta57419b2010-11-02 15:13:54 -0400464 if ($test_num) {
465 $test_num += $repeat - 1;
466 $opt{"NUM_TESTS"} = $test_num;
467 }
468
Steven Rostedt8d1491b2010-11-18 15:39:48 -0500469 # make sure we have all mandatory configs
470 get_ktest_configs;
471
Steven Rostedta75fece2010-11-02 14:58:27 -0400472 # set any defaults
473
474 foreach my $default (keys %default) {
475 if (!defined($opt{$default})) {
476 $opt{$default} = $default{$default};
477 }
478 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400479}
480
Steven Rostedtd1e2f222010-11-08 16:39:57 -0500481sub _logit {
Steven Rostedt2545eb62010-11-02 15:01:32 -0400482 if (defined($opt{"LOG_FILE"})) {
483 open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}";
484 print OUT @_;
485 close(OUT);
486 }
487}
488
Steven Rostedtd1e2f222010-11-08 16:39:57 -0500489sub logit {
490 if (defined($opt{"LOG_FILE"})) {
491 _logit @_;
492 } else {
493 print @_;
494 }
495}
496
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400497sub doprint {
498 print @_;
Steven Rostedtd1e2f222010-11-08 16:39:57 -0500499 _logit @_;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400500}
501
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400502sub run_command;
503
504sub reboot {
505 # try to reboot normally
Steven Rostedte48c5292010-11-02 14:35:37 -0400506 if (run_command $reboot) {
Steven Rostedt576f6272010-11-02 14:58:38 -0400507 if (defined($powercycle_after_reboot)) {
508 sleep $powercycle_after_reboot;
509 run_command "$power_cycle";
510 }
511 } else {
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400512 # nope? power cycle it.
Steven Rostedta75fece2010-11-02 14:58:27 -0400513 run_command "$power_cycle";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400514 }
515}
516
Steven Rostedt576f6272010-11-02 14:58:38 -0400517sub do_not_reboot {
518 my $i = $iteration;
519
520 return $test_type eq "build" ||
521 ($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") ||
522 ($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build");
523}
524
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400525sub dodie {
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400526 doprint "CRITICAL FAILURE... ", @_, "\n";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400527
Steven Rostedt576f6272010-11-02 14:58:38 -0400528 my $i = $iteration;
529
530 if ($reboot_on_error && !do_not_reboot) {
531
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400532 doprint "REBOOTING\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400533 reboot;
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400534
Steven Rostedta75fece2010-11-02 14:58:27 -0400535 } elsif ($poweroff_on_error && defined($power_off)) {
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400536 doprint "POWERING OFF\n";
Steven Rostedta75fece2010-11-02 14:58:27 -0400537 `$power_off`;
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400538 }
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400539
Steven Rostedtf80802c2011-03-07 13:18:47 -0500540 if (defined($opt{"LOG_FILE"})) {
541 print " See $opt{LOG_FILE} for more info.\n";
542 }
543
Steven Rostedt576f6272010-11-02 14:58:38 -0400544 die @_, "\n";
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400545}
546
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400547sub open_console {
548 my ($fp) = @_;
549
550 my $flags;
551
Steven Rostedta75fece2010-11-02 14:58:27 -0400552 my $pid = open($fp, "$console|") or
553 dodie "Can't open console $console";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400554
555 $flags = fcntl($fp, F_GETFL, 0) or
Steven Rostedt576f6272010-11-02 14:58:38 -0400556 dodie "Can't get flags for the socket: $!";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400557 $flags = fcntl($fp, F_SETFL, $flags | O_NONBLOCK) or
Steven Rostedt576f6272010-11-02 14:58:38 -0400558 dodie "Can't set flags for the socket: $!";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400559
560 return $pid;
561}
562
563sub close_console {
564 my ($fp, $pid) = @_;
565
566 doprint "kill child process $pid\n";
567 kill 2, $pid;
568
569 print "closing!\n";
570 close($fp);
571}
572
573sub start_monitor {
574 if ($monitor_cnt++) {
575 return;
576 }
577 $monitor_fp = \*MONFD;
578 $monitor_pid = open_console $monitor_fp;
Steven Rostedta75fece2010-11-02 14:58:27 -0400579
580 return;
581
582 open(MONFD, "Stop perl from warning about single use of MONFD");
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400583}
584
585sub end_monitor {
586 if (--$monitor_cnt) {
587 return;
588 }
589 close_console($monitor_fp, $monitor_pid);
590}
591
592sub wait_for_monitor {
593 my ($time) = @_;
594 my $line;
595
Steven Rostedta75fece2010-11-02 14:58:27 -0400596 doprint "** Wait for monitor to settle down **\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400597
598 # read the monitor and wait for the system to calm down
599 do {
600 $line = wait_for_input($monitor_fp, $time);
Steven Rostedta75fece2010-11-02 14:58:27 -0400601 print "$line" if (defined($line));
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400602 } while (defined($line));
Steven Rostedta75fece2010-11-02 14:58:27 -0400603 print "** Monitor flushed **\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400604}
605
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400606sub fail {
607
Steven Rostedta75fece2010-11-02 14:58:27 -0400608 if ($die_on_failure) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400609 dodie @_;
610 }
611
Steven Rostedta75fece2010-11-02 14:58:27 -0400612 doprint "FAILED\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400613
Steven Rostedt576f6272010-11-02 14:58:38 -0400614 my $i = $iteration;
615
Steven Rostedta75fece2010-11-02 14:58:27 -0400616 # no need to reboot for just building.
Steven Rostedt576f6272010-11-02 14:58:38 -0400617 if (!do_not_reboot) {
Steven Rostedta75fece2010-11-02 14:58:27 -0400618 doprint "REBOOTING\n";
619 reboot;
620 start_monitor;
621 wait_for_monitor $sleep_time;
622 end_monitor;
623 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400624
Steven Rostedt9064af52011-06-13 10:38:48 -0400625 my $name = "";
626
627 if (defined($test_name)) {
628 $name = " ($test_name)";
629 }
630
Steven Rostedt576f6272010-11-02 14:58:38 -0400631 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
632 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
Steven Rostedt9064af52011-06-13 10:38:48 -0400633 doprint "KTEST RESULT: TEST $i$name Failed: ", @_, "\n";
Steven Rostedt576f6272010-11-02 14:58:38 -0400634 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
635 doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
Steven Rostedta75fece2010-11-02 14:58:27 -0400636
637 return 1 if (!defined($store_failures));
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400638
639 my @t = localtime;
640 my $date = sprintf "%04d%02d%02d%02d%02d%02d",
641 1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0];
642
Steven Rostedtcccae1a2010-11-09 12:21:32 -0500643 my $type = $build_type;
644 if ($type =~ /useconfig/) {
645 $type = "useconfig";
646 }
647
648 my $dir = "$machine-$test_type-$type-fail-$date";
Steven Rostedta75fece2010-11-02 14:58:27 -0400649 my $faildir = "$store_failures/$dir";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400650
651 if (!-d $faildir) {
652 mkpath($faildir) or
Steven Rostedta75fece2010-11-02 14:58:27 -0400653 die "can't create $faildir";
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400654 }
Steven Rostedt51ad1dd2010-11-08 16:43:21 -0500655 if (-f "$output_config") {
656 cp "$output_config", "$faildir/config" or
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400657 die "failed to copy .config";
658 }
659 if (-f $buildlog) {
660 cp $buildlog, "$faildir/buildlog" or
661 die "failed to move $buildlog";
662 }
663 if (-f $dmesg) {
664 cp $dmesg, "$faildir/dmesg" or
665 die "failed to move $dmesg";
666 }
667
668 doprint "*** Saved info to $faildir ***\n";
669
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400670 return 1;
671}
672
Steven Rostedt2545eb62010-11-02 15:01:32 -0400673sub run_command {
674 my ($command) = @_;
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400675 my $dolog = 0;
676 my $dord = 0;
677 my $pid;
678
Steven Rostedte48c5292010-11-02 14:35:37 -0400679 $command =~ s/\$SSH_USER/$ssh_user/g;
680 $command =~ s/\$MACHINE/$machine/g;
681
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400682 doprint("$command ... ");
683
684 $pid = open(CMD, "$command 2>&1 |") or
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400685 (fail "unable to exec $command" and return 0);
Steven Rostedt2545eb62010-11-02 15:01:32 -0400686
687 if (defined($opt{"LOG_FILE"})) {
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400688 open(LOG, ">>$opt{LOG_FILE}") or
689 dodie "failed to write to log";
690 $dolog = 1;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -0400691 }
692
693 if (defined($redirect)) {
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400694 open (RD, ">$redirect") or
695 dodie "failed to write to redirect $redirect";
696 $dord = 1;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400697 }
698
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400699 while (<CMD>) {
700 print LOG if ($dolog);
701 print RD if ($dord);
702 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400703
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400704 waitpid($pid, 0);
Steven Rostedt2545eb62010-11-02 15:01:32 -0400705 my $failed = $?;
706
Steven Rostedtd6ce2a02010-11-02 14:58:05 -0400707 close(CMD);
708 close(LOG) if ($dolog);
709 close(RD) if ($dord);
710
Steven Rostedt2545eb62010-11-02 15:01:32 -0400711 if ($failed) {
712 doprint "FAILED!\n";
713 } else {
714 doprint "SUCCESS\n";
715 }
716
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400717 return !$failed;
718}
719
Steven Rostedte48c5292010-11-02 14:35:37 -0400720sub run_ssh {
721 my ($cmd) = @_;
722 my $cp_exec = $ssh_exec;
723
724 $cp_exec =~ s/\$SSH_COMMAND/$cmd/g;
725 return run_command "$cp_exec";
726}
727
728sub run_scp {
729 my ($src, $dst) = @_;
730 my $cp_scp = $scp_to_target;
731
732 $cp_scp =~ s/\$SRC_FILE/$src/g;
733 $cp_scp =~ s/\$DST_FILE/$dst/g;
734
735 return run_command "$cp_scp";
736}
737
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400738sub get_grub_index {
739
Steven Rostedta75fece2010-11-02 14:58:27 -0400740 if ($reboot_type ne "grub") {
741 return;
742 }
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400743 return if (defined($grub_number));
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400744
745 doprint "Find grub menu ... ";
746 $grub_number = -1;
Steven Rostedte48c5292010-11-02 14:35:37 -0400747
748 my $ssh_grub = $ssh_exec;
749 $ssh_grub =~ s,\$SSH_COMMAND,cat /boot/grub/menu.lst,g;
750
751 open(IN, "$ssh_grub |")
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400752 or die "unable to get menu.lst";
Steven Rostedte48c5292010-11-02 14:35:37 -0400753
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400754 while (<IN>) {
Steven Rostedta75fece2010-11-02 14:58:27 -0400755 if (/^\s*title\s+$grub_menu\s*$/) {
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400756 $grub_number++;
757 last;
758 } elsif (/^\s*title\s/) {
759 $grub_number++;
760 }
761 }
762 close(IN);
763
Steven Rostedta75fece2010-11-02 14:58:27 -0400764 die "Could not find '$grub_menu' in /boot/grub/menu on $machine"
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400765 if ($grub_number < 0);
766 doprint "$grub_number\n";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400767}
768
Steven Rostedt2545eb62010-11-02 15:01:32 -0400769sub wait_for_input
770{
771 my ($fp, $time) = @_;
772 my $rin;
773 my $ready;
774 my $line;
775 my $ch;
776
777 if (!defined($time)) {
778 $time = $timeout;
779 }
780
781 $rin = '';
782 vec($rin, fileno($fp), 1) = 1;
783 $ready = select($rin, undef, undef, $time);
784
785 $line = "";
786
787 # try to read one char at a time
788 while (sysread $fp, $ch, 1) {
789 $line .= $ch;
790 last if ($ch eq "\n");
791 }
792
793 if (!length($line)) {
794 return undef;
795 }
796
797 return $line;
798}
799
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400800sub reboot_to {
Steven Rostedta75fece2010-11-02 14:58:27 -0400801 if ($reboot_type eq "grub") {
Steven Rostedt4da46da2011-06-01 23:25:13 -0400802 run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch && reboot)'";
Steven Rostedta75fece2010-11-02 14:58:27 -0400803 return;
804 }
805
806 run_command "$reboot_script";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400807}
808
Steven Rostedta57419b2010-11-02 15:13:54 -0400809sub get_sha1 {
810 my ($commit) = @_;
811
812 doprint "git rev-list --max-count=1 $commit ... ";
813 my $sha1 = `git rev-list --max-count=1 $commit`;
814 my $ret = $?;
815
816 logit $sha1;
817
818 if ($ret) {
819 doprint "FAILED\n";
820 dodie "Failed to get git $commit";
821 }
822
823 print "SUCCESS\n";
824
825 chomp $sha1;
826
827 return $sha1;
828}
829
Steven Rostedt5a391fb2010-11-02 14:57:43 -0400830sub monitor {
Steven Rostedt2545eb62010-11-02 15:01:32 -0400831 my $booted = 0;
832 my $bug = 0;
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400833 my $skip_call_trace = 0;
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400834 my $loops;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400835
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400836 wait_for_monitor 5;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400837
838 my $line;
839 my $full_line = "";
840
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400841 open(DMESG, "> $dmesg") or
842 die "unable to write to $dmesg";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400843
Steven Rostedt75c3fda72010-11-02 14:57:21 -0400844 reboot_to;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400845
Steven Rostedt1c8a6172010-11-09 12:55:40 -0500846 my $success_start;
847 my $failure_start;
Steven Rostedt2d01b262011-03-08 09:47:54 -0500848 my $monitor_start = time;
849 my $done = 0;
Steven Rostedtf1a5b962011-06-13 10:30:00 -0400850 my $version_found = 0;
Steven Rostedt1c8a6172010-11-09 12:55:40 -0500851
Steven Rostedt2d01b262011-03-08 09:47:54 -0500852 while (!$done) {
Steven Rostedt2545eb62010-11-02 15:01:32 -0400853
Steven Rostedtecaf8e52011-06-13 10:48:10 -0400854 if ($bug && defined($stop_after_failure) &&
855 $stop_after_failure >= 0) {
856 my $time = $stop_after_failure - (time - $failure_start);
857 $line = wait_for_input($monitor_fp, $time);
858 if (!defined($line)) {
859 doprint "bug timed out after $booted_timeout seconds\n";
860 doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
861 last;
862 }
863 } elsif ($booted) {
Steven Rostedta75fece2010-11-02 14:58:27 -0400864 $line = wait_for_input($monitor_fp, $booted_timeout);
Steven Rostedtcd4f1d52011-06-13 10:26:27 -0400865 if (!defined($line)) {
866 my $s = $booted_timeout == 1 ? "" : "s";
867 doprint "Successful boot found: break after $booted_timeout second$s\n";
868 last;
869 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400870 } else {
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400871 $line = wait_for_input($monitor_fp);
Steven Rostedtcd4f1d52011-06-13 10:26:27 -0400872 if (!defined($line)) {
873 my $s = $timeout == 1 ? "" : "s";
874 doprint "Timed out after $timeout second$s\n";
875 last;
876 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400877 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400878
Steven Rostedt2545eb62010-11-02 15:01:32 -0400879 doprint $line;
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400880 print DMESG $line;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400881
882 # we are not guaranteed to get a full line
883 $full_line .= $line;
884
Steven Rostedta75fece2010-11-02 14:58:27 -0400885 if ($full_line =~ /$success_line/) {
Steven Rostedt2545eb62010-11-02 15:01:32 -0400886 $booted = 1;
Steven Rostedt1c8a6172010-11-09 12:55:40 -0500887 $success_start = time;
888 }
889
890 if ($booted && defined($stop_after_success) &&
891 $stop_after_success >= 0) {
892 my $now = time;
893 if ($now - $success_start >= $stop_after_success) {
894 doprint "Test forced to stop after $stop_after_success seconds after success\n";
895 last;
896 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400897 }
898
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400899 if ($full_line =~ /\[ backtrace testing \]/) {
900 $skip_call_trace = 1;
901 }
902
Steven Rostedt2545eb62010-11-02 15:01:32 -0400903 if ($full_line =~ /call trace:/i) {
Steven Rostedt46519202011-03-08 09:40:31 -0500904 if (!$bug && !$skip_call_trace) {
Steven Rostedt1c8a6172010-11-09 12:55:40 -0500905 $bug = 1;
906 $failure_start = time;
907 }
908 }
909
910 if ($bug && defined($stop_after_failure) &&
911 $stop_after_failure >= 0) {
912 my $now = time;
913 if ($now - $failure_start >= $stop_after_failure) {
914 doprint "Test forced to stop after $stop_after_failure seconds after failure\n";
915 last;
916 }
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400917 }
918
919 if ($full_line =~ /\[ end of backtrace testing \]/) {
920 $skip_call_trace = 0;
921 }
922
923 if ($full_line =~ /Kernel panic -/) {
Steven Rostedt10abf112011-03-07 13:21:00 -0500924 $failure_start = time;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400925 $bug = 1;
926 }
927
Steven Rostedtf1a5b962011-06-13 10:30:00 -0400928 # Detect triple faults by testing the banner
929 if ($full_line =~ /\bLinux version (\S+).*\n/) {
930 if ($1 eq $version) {
931 $version_found = 1;
932 } elsif ($version_found && $detect_triplefault) {
933 # We already booted into the kernel we are testing,
934 # but now we booted into another kernel?
935 # Consider this a triple fault.
936 doprint "Aleady booted in Linux kernel $version, but now\n";
937 doprint "we booted into Linux kernel $1.\n";
938 doprint "Assuming that this is a triple fault.\n";
939 doprint "To disable this: set DETECT_TRIPLE_FAULT to 0\n";
940 last;
941 }
942 }
943
Steven Rostedt2545eb62010-11-02 15:01:32 -0400944 if ($line =~ /\n/) {
945 $full_line = "";
946 }
Steven Rostedt2d01b262011-03-08 09:47:54 -0500947
948 if ($stop_test_after > 0 && !$booted && !$bug) {
949 if (time - $monitor_start > $stop_test_after) {
Steven Rostedt4d62bf52011-05-20 09:14:35 -0400950 doprint "STOP_TEST_AFTER ($stop_test_after seconds) timed out\n";
Steven Rostedt2d01b262011-03-08 09:47:54 -0500951 $done = 1;
952 }
953 }
Steven Rostedt2545eb62010-11-02 15:01:32 -0400954 }
955
Steven Rostedt7faafbd2010-11-02 14:58:22 -0400956 close(DMESG);
Steven Rostedt2545eb62010-11-02 15:01:32 -0400957
Steven Rostedt2545eb62010-11-02 15:01:32 -0400958 if ($bug) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400959 return 0 if ($in_bisect);
Steven Rostedt576f6272010-11-02 14:58:38 -0400960 fail "failed - got a bug report" and return 0;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400961 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400962
Steven Rostedta75fece2010-11-02 14:58:27 -0400963 if (!$booted) {
964 return 0 if ($in_bisect);
Steven Rostedt576f6272010-11-02 14:58:38 -0400965 fail "failed - never got a boot prompt." and return 0;
Steven Rostedta75fece2010-11-02 14:58:27 -0400966 }
967
Steven Rostedt2b7d9b22010-11-02 14:58:15 -0400968 return 1;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400969}
970
971sub install {
972
Steven Rostedte48c5292010-11-02 14:35:37 -0400973 run_scp "$outputdir/$build_target", "$target_image" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -0400974 dodie "failed to copy image";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400975
976 my $install_mods = 0;
977
978 # should we process modules?
979 $install_mods = 0;
Steven Rostedt51ad1dd2010-11-08 16:43:21 -0500980 open(IN, "$output_config") or dodie("Can't read config file");
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400981 while (<IN>) {
982 if (/CONFIG_MODULES(=y)?/) {
983 $install_mods = 1 if (defined($1));
984 last;
985 }
986 }
987 close(IN);
988
989 if (!$install_mods) {
990 doprint "No modules needed\n";
991 return;
Steven Rostedt2545eb62010-11-02 15:01:32 -0400992 }
993
Steven Rostedta75fece2010-11-02 14:58:27 -0400994 run_command "$make INSTALL_MOD_PATH=$tmpdir modules_install" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400995 dodie "Failed to install modules";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400996
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -0400997 my $modlib = "/lib/modules/$version";
Steven Rostedta57419b2010-11-02 15:13:54 -0400998 my $modtar = "ktest-mods.tar.bz2";
Steven Rostedt2545eb62010-11-02 15:01:32 -0400999
Steven Rostedte48c5292010-11-02 14:35:37 -04001000 run_ssh "rm -rf $modlib" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001001 dodie "failed to remove old mods: $modlib";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001002
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001003 # would be nice if scp -r did not follow symbolic links
Steven Rostedta75fece2010-11-02 14:58:27 -04001004 run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001005 dodie "making tarball";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001006
Steven Rostedte48c5292010-11-02 14:35:37 -04001007 run_scp "$tmpdir/$modtar", "/tmp" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001008 dodie "failed to copy modules";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001009
Steven Rostedta75fece2010-11-02 14:58:27 -04001010 unlink "$tmpdir/$modtar";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001011
Steven Rostedte48c5292010-11-02 14:35:37 -04001012 run_ssh "'(cd / && tar xf /tmp/$modtar)'" or
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001013 dodie "failed to tar modules";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001014
Steven Rostedte48c5292010-11-02 14:35:37 -04001015 run_ssh "rm -f /tmp/$modtar";
Steven Rostedt8b37ca82010-11-02 14:58:33 -04001016
1017 return if (!defined($post_install));
1018
Steven Rostedte48c5292010-11-02 14:35:37 -04001019 my $cp_post_install = $post_install;
Steven Rostedtca6a21f2011-03-25 22:42:53 -04001020 $cp_post_install =~ s/\$KERNEL_VERSION/$version/g;
Steven Rostedte48c5292010-11-02 14:35:37 -04001021 run_command "$cp_post_install" or
Steven Rostedt576f6272010-11-02 14:58:38 -04001022 dodie "Failed to run post install";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001023}
1024
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001025sub check_buildlog {
1026 my ($patch) = @_;
1027
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001028 my @files = `git show $patch | diffstat -l`;
1029
1030 open(IN, "git show $patch |") or
1031 dodie "failed to show $patch";
1032 while (<IN>) {
1033 if (m,^--- a/(.*),) {
1034 chomp $1;
1035 $files[$#files] = $1;
1036 }
1037 }
1038 close(IN);
1039
1040 open(IN, $buildlog) or dodie "Can't open $buildlog";
1041 while (<IN>) {
1042 if (/^\s*(.*?):.*(warning|error)/) {
1043 my $err = $1;
1044 foreach my $file (@files) {
Steven Rostedta75fece2010-11-02 14:58:27 -04001045 my $fullpath = "$builddir/$file";
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001046 if ($file eq $err || $fullpath eq $err) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001047 fail "$file built with warnings" and return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001048 }
1049 }
1050 }
1051 }
1052 close(IN);
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001053
1054 return 1;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001055}
1056
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001057sub apply_min_config {
1058 my $outconfig = "$output_config.new";
Steven Rostedt612b9e92011-03-07 13:27:43 -05001059
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001060 # Read the config file and remove anything that
1061 # is in the force_config hash (from minconfig and others)
1062 # then add the force config back.
1063
1064 doprint "Applying minimum configurations into $output_config.new\n";
1065
1066 open (OUT, ">$outconfig") or
1067 dodie "Can't create $outconfig";
1068
1069 if (-f $output_config) {
1070 open (IN, $output_config) or
1071 dodie "Failed to open $output_config";
1072 while (<IN>) {
1073 if (/^(# )?(CONFIG_[^\s=]*)/) {
1074 next if (defined($force_config{$2}));
1075 }
1076 print OUT;
1077 }
1078 close IN;
1079 }
1080 foreach my $config (keys %force_config) {
1081 print OUT "$force_config{$config}\n";
1082 }
1083 close OUT;
1084
1085 run_command "mv $outconfig $output_config";
1086}
1087
1088sub make_oldconfig {
1089
1090 apply_min_config;
1091
1092 if (!run_command "$make oldnoconfig") {
Steven Rostedt612b9e92011-03-07 13:27:43 -05001093 # Perhaps oldnoconfig doesn't exist in this version of the kernel
1094 # try a yes '' | oldconfig
1095 doprint "oldnoconfig failed, trying yes '' | make oldconfig\n";
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001096 run_command "yes '' | $make oldconfig" or
Steven Rostedt612b9e92011-03-07 13:27:43 -05001097 dodie "failed make config oldconfig";
1098 }
1099}
1100
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001101# read a config file and use this to force new configs.
1102sub load_force_config {
1103 my ($config) = @_;
1104
1105 open(IN, $config) or
1106 dodie "failed to read $config";
1107 while (<IN>) {
1108 chomp;
1109 if (/^(CONFIG[^\s=]*)(\s*=.*)/) {
1110 $force_config{$1} = $_;
1111 } elsif (/^# (CONFIG_\S*) is not set/) {
1112 $force_config{$1} = $_;
1113 }
1114 }
1115 close IN;
1116}
1117
Steven Rostedt2545eb62010-11-02 15:01:32 -04001118sub build {
1119 my ($type) = @_;
1120
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001121 unlink $buildlog;
1122
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001123 if ($type =~ /^useconfig:(.*)/) {
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05001124 run_command "cp $1 $output_config" or
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001125 dodie "could not copy $1 to .config";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001126
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001127 $type = "oldconfig";
1128 }
1129
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001130 # old config can ask questions
1131 if ($type eq "oldconfig") {
Steven Rostedt9386c6a2010-11-08 16:35:48 -05001132 $type = "oldnoconfig";
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001133
1134 # allow for empty configs
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05001135 run_command "touch $output_config";
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001136
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05001137 run_command "mv $output_config $outputdir/config_temp" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001138 dodie "moving .config";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001139
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001140 if (!$noclean && !run_command "$make mrproper") {
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001141 dodie "make mrproper";
1142 }
1143
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05001144 run_command "mv $outputdir/config_temp $output_config" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001145 dodie "moving config_temp";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001146
1147 } elsif (!$noclean) {
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05001148 unlink "$output_config";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001149 run_command "$make mrproper" or
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001150 dodie "make mrproper";
Steven Rostedt5c42fc52010-11-02 14:57:01 -04001151 }
Steven Rostedt2545eb62010-11-02 15:01:32 -04001152
1153 # add something to distinguish this build
Steven Rostedta75fece2010-11-02 14:58:27 -04001154 open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file");
1155 print OUT "$localversion\n";
Steven Rostedt2545eb62010-11-02 15:01:32 -04001156 close(OUT);
1157
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001158 if (defined($minconfig)) {
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001159 load_force_config($minconfig);
Steven Rostedt2545eb62010-11-02 15:01:32 -04001160 }
1161
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001162 if ($type ne "oldnoconfig") {
1163 run_command "$make $type" or
Steven Rostedt612b9e92011-03-07 13:27:43 -05001164 dodie "failed make config";
1165 }
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001166 # Run old config regardless, to enforce min configurations
1167 make_oldconfig;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001168
Steven Rostedta75fece2010-11-02 14:58:27 -04001169 $redirect = "$buildlog";
1170 if (!run_command "$make $build_options") {
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001171 undef $redirect;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001172 # bisect may need this to pass
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001173 return 0 if ($in_bisect);
1174 fail "failed build" and return 0;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001175 }
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001176 undef $redirect;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001177
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001178 return 1;
Steven Rostedt2545eb62010-11-02 15:01:32 -04001179}
1180
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001181sub halt {
Steven Rostedte48c5292010-11-02 14:35:37 -04001182 if (!run_ssh "halt" or defined($power_off)) {
Steven Rostedt576f6272010-11-02 14:58:38 -04001183 if (defined($poweroff_after_halt)) {
1184 sleep $poweroff_after_halt;
1185 run_command "$power_off";
1186 }
1187 } else {
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001188 # nope? the zap it!
Steven Rostedta75fece2010-11-02 14:58:27 -04001189 run_command "$power_off";
Steven Rostedt75c3fda72010-11-02 14:57:21 -04001190 }
1191}
1192
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001193sub success {
1194 my ($i) = @_;
1195
Steven Rostedte48c5292010-11-02 14:35:37 -04001196 $successes++;
1197
Steven Rostedt9064af52011-06-13 10:38:48 -04001198 my $name = "";
1199
1200 if (defined($test_name)) {
1201 $name = " ($test_name)";
1202 }
1203
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001204 doprint "\n\n*******************************************\n";
1205 doprint "*******************************************\n";
Steven Rostedt9064af52011-06-13 10:38:48 -04001206 doprint "KTEST RESULT: TEST $i$name SUCCESS!!!! **\n";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001207 doprint "*******************************************\n";
1208 doprint "*******************************************\n";
1209
Steven Rostedt576f6272010-11-02 14:58:38 -04001210 if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) {
Steven Rostedta75fece2010-11-02 14:58:27 -04001211 doprint "Reboot and wait $sleep_time seconds\n";
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001212 reboot;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001213 start_monitor;
Steven Rostedta75fece2010-11-02 14:58:27 -04001214 wait_for_monitor $sleep_time;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001215 end_monitor;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001216 }
1217}
1218
1219sub get_version {
1220 # get the release name
1221 doprint "$make kernelrelease ... ";
1222 $version = `$make kernelrelease | tail -1`;
1223 chomp($version);
1224 doprint "$version\n";
1225}
1226
Steven Rostedtc960bb92011-03-08 09:22:39 -05001227sub answer_bisect {
1228 for (;;) {
1229 doprint "Pass or fail? [p/f]";
1230 my $ans = <STDIN>;
1231 chomp $ans;
1232 if ($ans eq "p" || $ans eq "P") {
1233 return 1;
1234 } elsif ($ans eq "f" || $ans eq "F") {
1235 return 0;
1236 } else {
1237 print "Please answer 'P' or 'F'\n";
1238 }
1239 }
1240}
1241
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001242sub child_run_test {
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001243 my $failed = 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001244
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001245 # child should have no power
Steven Rostedta75fece2010-11-02 14:58:27 -04001246 $reboot_on_error = 0;
1247 $poweroff_on_error = 0;
1248 $die_on_failure = 1;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001249
1250 run_command $run_test or $failed = 1;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001251 exit $failed;
1252}
1253
1254my $child_done;
1255
1256sub child_finished {
1257 $child_done = 1;
1258}
1259
1260sub do_run_test {
1261 my $child_pid;
1262 my $child_exit;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001263 my $line;
1264 my $full_line;
1265 my $bug = 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001266
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001267 wait_for_monitor 1;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001268
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001269 doprint "run test $run_test\n";
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001270
1271 $child_done = 0;
1272
1273 $SIG{CHLD} = qw(child_finished);
1274
1275 $child_pid = fork;
1276
1277 child_run_test if (!$child_pid);
1278
1279 $full_line = "";
1280
1281 do {
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001282 $line = wait_for_input($monitor_fp, 1);
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001283 if (defined($line)) {
1284
1285 # we are not guaranteed to get a full line
1286 $full_line .= $line;
Steven Rostedt8ea0e062011-03-08 09:44:35 -05001287 doprint $line;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001288
1289 if ($full_line =~ /call trace:/i) {
1290 $bug = 1;
1291 }
1292
1293 if ($full_line =~ /Kernel panic -/) {
1294 $bug = 1;
1295 }
1296
1297 if ($line =~ /\n/) {
1298 $full_line = "";
1299 }
1300 }
1301 } while (!$child_done && !$bug);
1302
1303 if ($bug) {
Steven Rostedt8ea0e062011-03-08 09:44:35 -05001304 my $failure_start = time;
1305 my $now;
1306 do {
1307 $line = wait_for_input($monitor_fp, 1);
1308 if (defined($line)) {
1309 doprint $line;
1310 }
1311 $now = time;
1312 if ($now - $failure_start >= $stop_after_failure) {
1313 last;
1314 }
1315 } while (defined($line));
1316
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001317 doprint "Detected kernel crash!\n";
1318 # kill the child with extreme prejudice
1319 kill 9, $child_pid;
1320 }
1321
1322 waitpid $child_pid, 0;
1323 $child_exit = $?;
1324
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001325 if ($bug || $child_exit) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001326 return 0 if $in_bisect;
1327 fail "test failed" and return 0;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001328 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001329 return 1;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001330}
1331
Steven Rostedta75fece2010-11-02 14:58:27 -04001332sub run_git_bisect {
1333 my ($command) = @_;
1334
1335 doprint "$command ... ";
1336
1337 my $output = `$command 2>&1`;
1338 my $ret = $?;
1339
1340 logit $output;
1341
1342 if ($ret) {
1343 doprint "FAILED\n";
1344 dodie "Failed to git bisect";
1345 }
1346
1347 doprint "SUCCESS\n";
1348 if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) {
1349 doprint "$1 [$2]\n";
1350 } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) {
1351 $bisect_bad = $1;
1352 doprint "Found bad commit... $1\n";
1353 return 0;
1354 } else {
1355 # we already logged it, just print it now.
1356 print $output;
1357 }
1358
1359 return 1;
1360}
1361
Steven Rostedtc23dca72011-03-08 09:26:31 -05001362sub bisect_reboot {
1363 doprint "Reboot and sleep $bisect_sleep_time seconds\n";
1364 reboot;
1365 start_monitor;
1366 wait_for_monitor $bisect_sleep_time;
1367 end_monitor;
1368}
1369
1370# returns 1 on success, 0 on failure, -1 on skip
Steven Rostedt0a05c762010-11-08 11:14:10 -05001371sub run_bisect_test {
1372 my ($type, $buildtype) = @_;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001373
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001374 my $failed = 0;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001375 my $result;
1376 my $output;
1377 my $ret;
1378
Steven Rostedt0a05c762010-11-08 11:14:10 -05001379 $in_bisect = 1;
1380
1381 build $buildtype or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001382
1383 if ($type ne "build") {
Steven Rostedtc23dca72011-03-08 09:26:31 -05001384 if ($failed && $bisect_skip) {
1385 $in_bisect = 0;
1386 return -1;
1387 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001388 dodie "Failed on build" if $failed;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001389
1390 # Now boot the box
1391 get_grub_index;
1392 get_version;
1393 install;
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001394
1395 start_monitor;
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001396 monitor or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001397
1398 if ($type ne "boot") {
Steven Rostedtc23dca72011-03-08 09:26:31 -05001399 if ($failed && $bisect_skip) {
1400 end_monitor;
1401 bisect_reboot;
1402 $in_bisect = 0;
1403 return -1;
1404 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001405 dodie "Failed on boot" if $failed;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001406
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001407 do_run_test or $failed = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001408 }
Steven Rostedt7faafbd2010-11-02 14:58:22 -04001409 end_monitor;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001410 }
1411
1412 if ($failed) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001413 $result = 0;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001414 } else {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001415 $result = 1;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001416 }
Steven Rostedt4025bc62011-05-20 09:16:29 -04001417
1418 # reboot the box to a kernel we can ssh to
1419 if ($type ne "build") {
1420 bisect_reboot;
1421 }
Steven Rostedt0a05c762010-11-08 11:14:10 -05001422 $in_bisect = 0;
1423
1424 return $result;
1425}
1426
1427sub run_bisect {
1428 my ($type) = @_;
1429 my $buildtype = "oldconfig";
1430
1431 # We should have a minconfig to use?
1432 if (defined($minconfig)) {
1433 $buildtype = "useconfig:$minconfig";
1434 }
1435
1436 my $ret = run_bisect_test $type, $buildtype;
1437
Steven Rostedtc960bb92011-03-08 09:22:39 -05001438 if ($bisect_manual) {
1439 $ret = answer_bisect;
1440 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001441
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04001442 # Are we looking for where it worked, not failed?
1443 if ($reverse_bisect) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001444 $ret = !$ret;
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04001445 }
1446
Steven Rostedtc23dca72011-03-08 09:26:31 -05001447 if ($ret > 0) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001448 return "good";
Steven Rostedtc23dca72011-03-08 09:26:31 -05001449 } elsif ($ret == 0) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001450 return "bad";
Steven Rostedtc23dca72011-03-08 09:26:31 -05001451 } elsif ($bisect_skip) {
1452 doprint "HIT A BAD COMMIT ... SKIPPING\n";
1453 return "skip";
Steven Rostedt0a05c762010-11-08 11:14:10 -05001454 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001455}
1456
1457sub bisect {
1458 my ($i) = @_;
1459
1460 my $result;
1461
1462 die "BISECT_GOOD[$i] not defined\n" if (!defined($opt{"BISECT_GOOD[$i]"}));
1463 die "BISECT_BAD[$i] not defined\n" if (!defined($opt{"BISECT_BAD[$i]"}));
1464 die "BISECT_TYPE[$i] not defined\n" if (!defined($opt{"BISECT_TYPE[$i]"}));
1465
1466 my $good = $opt{"BISECT_GOOD[$i]"};
1467 my $bad = $opt{"BISECT_BAD[$i]"};
1468 my $type = $opt{"BISECT_TYPE[$i]"};
Steven Rostedta75fece2010-11-02 14:58:27 -04001469 my $start = $opt{"BISECT_START[$i]"};
1470 my $replay = $opt{"BISECT_REPLAY[$i]"};
Steven Rostedt3410f6f2011-03-08 09:38:12 -05001471 my $start_files = $opt{"BISECT_FILES[$i]"};
1472
1473 if (defined($start_files)) {
1474 $start_files = " -- " . $start_files;
1475 } else {
1476 $start_files = "";
1477 }
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001478
Steven Rostedta57419b2010-11-02 15:13:54 -04001479 # convert to true sha1's
1480 $good = get_sha1($good);
1481 $bad = get_sha1($bad);
1482
Steven Rostedtd6ce2a02010-11-02 14:58:05 -04001483 if (defined($opt{"BISECT_REVERSE[$i]"}) &&
1484 $opt{"BISECT_REVERSE[$i]"} == 1) {
1485 doprint "Performing a reverse bisect (bad is good, good is bad!)\n";
1486 $reverse_bisect = 1;
1487 } else {
1488 $reverse_bisect = 0;
1489 }
1490
Steven Rostedt5a391fb2010-11-02 14:57:43 -04001491 # Can't have a test without having a test to run
1492 if ($type eq "test" && !defined($run_test)) {
1493 $type = "boot";
1494 }
1495
Steven Rostedta75fece2010-11-02 14:58:27 -04001496 my $check = $opt{"BISECT_CHECK[$i]"};
1497 if (defined($check) && $check ne "0") {
1498
1499 # get current HEAD
Steven Rostedta57419b2010-11-02 15:13:54 -04001500 my $head = get_sha1("HEAD");
Steven Rostedta75fece2010-11-02 14:58:27 -04001501
1502 if ($check ne "good") {
1503 doprint "TESTING BISECT BAD [$bad]\n";
1504 run_command "git checkout $bad" or
1505 die "Failed to checkout $bad";
1506
1507 $result = run_bisect $type;
1508
1509 if ($result ne "bad") {
1510 fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0;
1511 }
1512 }
1513
1514 if ($check ne "bad") {
1515 doprint "TESTING BISECT GOOD [$good]\n";
1516 run_command "git checkout $good" or
1517 die "Failed to checkout $good";
1518
1519 $result = run_bisect $type;
1520
1521 if ($result ne "good") {
1522 fail "Tested BISECT_GOOD [$good] and it failed" and return 0;
1523 }
1524 }
1525
1526 # checkout where we started
1527 run_command "git checkout $head" or
1528 die "Failed to checkout $head";
1529 }
1530
Steven Rostedt3410f6f2011-03-08 09:38:12 -05001531 run_command "git bisect start$start_files" or
Steven Rostedta75fece2010-11-02 14:58:27 -04001532 dodie "could not start bisect";
1533
1534 run_command "git bisect good $good" or
1535 dodie "could not set bisect good to $good";
1536
1537 run_git_bisect "git bisect bad $bad" or
1538 dodie "could not set bisect bad to $bad";
1539
1540 if (defined($replay)) {
1541 run_command "git bisect replay $replay" or
1542 dodie "failed to run replay";
1543 }
1544
1545 if (defined($start)) {
1546 run_command "git checkout $start" or
1547 dodie "failed to checkout $start";
1548 }
1549
1550 my $test;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001551 do {
1552 $result = run_bisect $type;
Steven Rostedta75fece2010-11-02 14:58:27 -04001553 $test = run_git_bisect "git bisect $result";
1554 } while ($test);
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001555
1556 run_command "git bisect log" or
1557 dodie "could not capture git bisect log";
1558
1559 run_command "git bisect reset" or
1560 dodie "could not reset git bisect";
1561
1562 doprint "Bad commit was [$bisect_bad]\n";
1563
Steven Rostedt0a05c762010-11-08 11:14:10 -05001564 success $i;
1565}
1566
1567my %config_ignore;
1568my %config_set;
1569
1570my %config_list;
1571my %null_config;
1572
1573my %dependency;
1574
1575sub process_config_ignore {
1576 my ($config) = @_;
1577
1578 open (IN, $config)
1579 or dodie "Failed to read $config";
1580
1581 while (<IN>) {
Steven Rostedt9bf71742011-06-01 23:27:19 -04001582 if (/^((CONFIG\S*)=.*)/) {
Steven Rostedt0a05c762010-11-08 11:14:10 -05001583 $config_ignore{$2} = $1;
1584 }
1585 }
1586
1587 close(IN);
1588}
1589
1590sub read_current_config {
1591 my ($config_ref) = @_;
1592
1593 %{$config_ref} = ();
1594 undef %{$config_ref};
1595
1596 my @key = keys %{$config_ref};
1597 if ($#key >= 0) {
1598 print "did not delete!\n";
1599 exit;
1600 }
1601 open (IN, "$output_config");
1602
1603 while (<IN>) {
1604 if (/^(CONFIG\S+)=(.*)/) {
1605 ${$config_ref}{$1} = $2;
1606 }
1607 }
1608 close(IN);
1609}
1610
1611sub get_dependencies {
1612 my ($config) = @_;
1613
1614 my $arr = $dependency{$config};
1615 if (!defined($arr)) {
1616 return ();
1617 }
1618
1619 my @deps = @{$arr};
1620
1621 foreach my $dep (@{$arr}) {
1622 print "ADD DEP $dep\n";
1623 @deps = (@deps, get_dependencies $dep);
1624 }
1625
1626 return @deps;
1627}
1628
1629sub create_config {
1630 my @configs = @_;
1631
1632 open(OUT, ">$output_config") or dodie "Can not write to $output_config";
1633
1634 foreach my $config (@configs) {
1635 print OUT "$config_set{$config}\n";
1636 my @deps = get_dependencies $config;
1637 foreach my $dep (@deps) {
1638 print OUT "$config_set{$dep}\n";
1639 }
1640 }
1641
1642 foreach my $config (keys %config_ignore) {
1643 print OUT "$config_ignore{$config}\n";
1644 }
1645 close(OUT);
1646
1647# exit;
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001648 make_oldconfig;
Steven Rostedt0a05c762010-11-08 11:14:10 -05001649}
1650
1651sub compare_configs {
1652 my (%a, %b) = @_;
1653
1654 foreach my $item (keys %a) {
1655 if (!defined($b{$item})) {
1656 print "diff $item\n";
1657 return 1;
1658 }
1659 delete $b{$item};
1660 }
1661
1662 my @keys = keys %b;
1663 if ($#keys) {
1664 print "diff2 $keys[0]\n";
1665 }
1666 return -1 if ($#keys >= 0);
1667
1668 return 0;
1669}
1670
1671sub run_config_bisect_test {
1672 my ($type) = @_;
1673
1674 return run_bisect_test $type, "oldconfig";
1675}
1676
1677sub process_passed {
1678 my (%configs) = @_;
1679
1680 doprint "These configs had no failure: (Enabling them for further compiles)\n";
1681 # Passed! All these configs are part of a good compile.
1682 # Add them to the min options.
1683 foreach my $config (keys %configs) {
1684 if (defined($config_list{$config})) {
1685 doprint " removing $config\n";
1686 $config_ignore{$config} = $config_list{$config};
1687 delete $config_list{$config};
1688 }
1689 }
Steven Rostedtf1a27852010-11-11 11:34:38 -05001690 doprint "config copied to $outputdir/config_good\n";
1691 run_command "cp -f $output_config $outputdir/config_good";
Steven Rostedt0a05c762010-11-08 11:14:10 -05001692}
1693
1694sub process_failed {
1695 my ($config) = @_;
1696
1697 doprint "\n\n***************************************\n";
1698 doprint "Found bad config: $config\n";
1699 doprint "***************************************\n\n";
1700}
1701
1702sub run_config_bisect {
1703
1704 my @start_list = keys %config_list;
1705
1706 if ($#start_list < 0) {
1707 doprint "No more configs to test!!!\n";
1708 return -1;
1709 }
1710
1711 doprint "***** RUN TEST ***\n";
1712 my $type = $opt{"CONFIG_BISECT_TYPE[$iteration]"};
1713 my $ret;
1714 my %current_config;
1715
1716 my $count = $#start_list + 1;
1717 doprint " $count configs to test\n";
1718
1719 my $half = int($#start_list / 2);
1720
1721 do {
1722 my @tophalf = @start_list[0 .. $half];
1723
1724 create_config @tophalf;
1725 read_current_config \%current_config;
1726
1727 $count = $#tophalf + 1;
1728 doprint "Testing $count configs\n";
1729 my $found = 0;
1730 # make sure we test something
1731 foreach my $config (@tophalf) {
1732 if (defined($current_config{$config})) {
1733 logit " $config\n";
1734 $found = 1;
1735 }
1736 }
1737 if (!$found) {
1738 # try the other half
1739 doprint "Top half produced no set configs, trying bottom half\n";
Steven Rostedt4c8cc552011-06-01 23:22:30 -04001740 @tophalf = @start_list[$half + 1 .. $#start_list];
Steven Rostedt0a05c762010-11-08 11:14:10 -05001741 create_config @tophalf;
1742 read_current_config \%current_config;
1743 foreach my $config (@tophalf) {
1744 if (defined($current_config{$config})) {
1745 logit " $config\n";
1746 $found = 1;
1747 }
1748 }
1749 if (!$found) {
1750 doprint "Failed: Can't make new config with current configs\n";
1751 foreach my $config (@start_list) {
1752 doprint " CONFIG: $config\n";
1753 }
1754 return -1;
1755 }
1756 $count = $#tophalf + 1;
1757 doprint "Testing $count configs\n";
1758 }
1759
1760 $ret = run_config_bisect_test $type;
Steven Rostedtc960bb92011-03-08 09:22:39 -05001761 if ($bisect_manual) {
1762 $ret = answer_bisect;
1763 }
Steven Rostedt0a05c762010-11-08 11:14:10 -05001764 if ($ret) {
1765 process_passed %current_config;
1766 return 0;
1767 }
1768
1769 doprint "This config had a failure.\n";
1770 doprint "Removing these configs that were not set in this config:\n";
Steven Rostedtf1a27852010-11-11 11:34:38 -05001771 doprint "config copied to $outputdir/config_bad\n";
1772 run_command "cp -f $output_config $outputdir/config_bad";
Steven Rostedt0a05c762010-11-08 11:14:10 -05001773
1774 # A config exists in this group that was bad.
1775 foreach my $config (keys %config_list) {
1776 if (!defined($current_config{$config})) {
1777 doprint " removing $config\n";
1778 delete $config_list{$config};
1779 }
1780 }
1781
1782 @start_list = @tophalf;
1783
1784 if ($#start_list == 0) {
1785 process_failed $start_list[0];
1786 return 1;
1787 }
1788
1789 # remove half the configs we are looking at and see if
1790 # they are good.
1791 $half = int($#start_list / 2);
Steven Rostedt4c8cc552011-06-01 23:22:30 -04001792 } while ($#start_list > 0);
Steven Rostedt0a05c762010-11-08 11:14:10 -05001793
Steven Rostedtc960bb92011-03-08 09:22:39 -05001794 # we found a single config, try it again unless we are running manually
1795
1796 if ($bisect_manual) {
1797 process_failed $start_list[0];
1798 return 1;
1799 }
1800
Steven Rostedt0a05c762010-11-08 11:14:10 -05001801 my @tophalf = @start_list[0 .. 0];
1802
1803 $ret = run_config_bisect_test $type;
1804 if ($ret) {
1805 process_passed %current_config;
1806 return 0;
1807 }
1808
1809 process_failed $start_list[0];
1810 return 1;
1811}
1812
1813sub config_bisect {
1814 my ($i) = @_;
1815
1816 my $start_config = $opt{"CONFIG_BISECT[$i]"};
1817
1818 my $tmpconfig = "$tmpdir/use_config";
1819
Steven Rostedt30f75da2011-06-13 10:35:35 -04001820 if (defined($config_bisect_good)) {
1821 process_config_ignore $config_bisect_good;
1822 }
1823
Steven Rostedt0a05c762010-11-08 11:14:10 -05001824 # Make the file with the bad config and the min config
1825 if (defined($minconfig)) {
1826 # read the min config for things to ignore
1827 run_command "cp $minconfig $tmpconfig" or
1828 dodie "failed to copy $minconfig to $tmpconfig";
1829 } else {
1830 unlink $tmpconfig;
1831 }
1832
1833 # Add other configs
1834 if (defined($addconfig)) {
1835 run_command "cat $addconfig >> $tmpconfig" or
1836 dodie "failed to append $addconfig";
1837 }
1838
Steven Rostedt0a05c762010-11-08 11:14:10 -05001839 if (-f $tmpconfig) {
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001840 load_force_config($tmpconfig);
Steven Rostedt0a05c762010-11-08 11:14:10 -05001841 process_config_ignore $tmpconfig;
1842 }
1843
1844 # now process the start config
1845 run_command "cp $start_config $output_config" or
1846 dodie "failed to copy $start_config to $output_config";
1847
1848 # read directly what we want to check
1849 my %config_check;
1850 open (IN, $output_config)
1851 or dodie "faied to open $output_config";
1852
1853 while (<IN>) {
1854 if (/^((CONFIG\S*)=.*)/) {
1855 $config_check{$2} = $1;
1856 }
1857 }
1858 close(IN);
1859
1860 # Now run oldconfig with the minconfig (and addconfigs)
Steven Rostedtfcb3f162011-06-13 10:40:58 -04001861 make_oldconfig;
Steven Rostedt0a05c762010-11-08 11:14:10 -05001862
1863 # check to see what we lost (or gained)
1864 open (IN, $output_config)
1865 or dodie "Failed to read $start_config";
1866
1867 my %removed_configs;
1868 my %added_configs;
1869
1870 while (<IN>) {
1871 if (/^((CONFIG\S*)=.*)/) {
1872 # save off all options
1873 $config_set{$2} = $1;
1874 if (defined($config_check{$2})) {
1875 if (defined($config_ignore{$2})) {
1876 $removed_configs{$2} = $1;
1877 } else {
1878 $config_list{$2} = $1;
1879 }
1880 } elsif (!defined($config_ignore{$2})) {
1881 $added_configs{$2} = $1;
1882 $config_list{$2} = $1;
1883 }
1884 }
1885 }
1886 close(IN);
1887
1888 my @confs = keys %removed_configs;
1889 if ($#confs >= 0) {
1890 doprint "Configs overridden by default configs and removed from check:\n";
1891 foreach my $config (@confs) {
1892 doprint " $config\n";
1893 }
1894 }
1895 @confs = keys %added_configs;
1896 if ($#confs >= 0) {
1897 doprint "Configs appearing in make oldconfig and added:\n";
1898 foreach my $config (@confs) {
1899 doprint " $config\n";
1900 }
1901 }
1902
1903 my %config_test;
1904 my $once = 0;
1905
1906 # Sometimes kconfig does weird things. We must make sure
1907 # that the config we autocreate has everything we need
1908 # to test, otherwise we may miss testing configs, or
1909 # may not be able to create a new config.
1910 # Here we create a config with everything set.
1911 create_config (keys %config_list);
1912 read_current_config \%config_test;
1913 foreach my $config (keys %config_list) {
1914 if (!defined($config_test{$config})) {
1915 if (!$once) {
1916 $once = 1;
1917 doprint "Configs not produced by kconfig (will not be checked):\n";
1918 }
1919 doprint " $config\n";
1920 delete $config_list{$config};
1921 }
1922 }
1923 my $ret;
1924 do {
1925 $ret = run_config_bisect;
1926 } while (!$ret);
1927
1928 return $ret if ($ret < 0);
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04001929
1930 success $i;
1931}
1932
Steven Rostedt27d934b2011-05-20 09:18:18 -04001933sub patchcheck_reboot {
1934 doprint "Reboot and sleep $patchcheck_sleep_time seconds\n";
1935 reboot;
1936 start_monitor;
1937 wait_for_monitor $patchcheck_sleep_time;
1938 end_monitor;
1939}
1940
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001941sub patchcheck {
1942 my ($i) = @_;
1943
1944 die "PATCHCHECK_START[$i] not defined\n"
1945 if (!defined($opt{"PATCHCHECK_START[$i]"}));
1946 die "PATCHCHECK_TYPE[$i] not defined\n"
1947 if (!defined($opt{"PATCHCHECK_TYPE[$i]"}));
1948
1949 my $start = $opt{"PATCHCHECK_START[$i]"};
1950
1951 my $end = "HEAD";
1952 if (defined($opt{"PATCHCHECK_END[$i]"})) {
1953 $end = $opt{"PATCHCHECK_END[$i]"};
1954 }
1955
Steven Rostedta57419b2010-11-02 15:13:54 -04001956 # Get the true sha1's since we can use things like HEAD~3
1957 $start = get_sha1($start);
1958 $end = get_sha1($end);
1959
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001960 my $type = $opt{"PATCHCHECK_TYPE[$i]"};
1961
1962 # Can't have a test without having a test to run
1963 if ($type eq "test" && !defined($run_test)) {
1964 $type = "boot";
1965 }
1966
1967 open (IN, "git log --pretty=oneline $end|") or
1968 dodie "could not get git list";
1969
1970 my @list;
1971
1972 while (<IN>) {
1973 chomp;
1974 $list[$#list+1] = $_;
1975 last if (/^$start/);
1976 }
1977 close(IN);
1978
1979 if ($list[$#list] !~ /^$start/) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04001980 fail "SHA1 $start not found";
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04001981 }
1982
1983 # go backwards in the list
1984 @list = reverse @list;
1985
1986 my $save_clean = $noclean;
1987
1988 $in_patchcheck = 1;
1989 foreach my $item (@list) {
1990 my $sha1 = $item;
1991 $sha1 =~ s/^([[:xdigit:]]+).*/$1/;
1992
1993 doprint "\nProcessing commit $item\n\n";
1994
1995 run_command "git checkout $sha1" or
1996 die "Failed to checkout $sha1";
1997
1998 # only clean on the first and last patch
1999 if ($item eq $list[0] ||
2000 $item eq $list[$#list]) {
2001 $noclean = $save_clean;
2002 } else {
2003 $noclean = 1;
2004 }
2005
2006 if (defined($minconfig)) {
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002007 build "useconfig:$minconfig" or return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002008 } else {
2009 # ?? no config to use?
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002010 build "oldconfig" or return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002011 }
2012
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002013 check_buildlog $sha1 or return 0;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002014
2015 next if ($type eq "build");
2016
2017 get_grub_index;
2018 get_version;
2019 install;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002020
Steven Rostedt7faafbd2010-11-02 14:58:22 -04002021 my $failed = 0;
2022
2023 start_monitor;
2024 monitor or $failed = 1;
2025
2026 if (!$failed && $type ne "boot"){
2027 do_run_test or $failed = 1;
2028 }
2029 end_monitor;
2030 return 0 if ($failed);
2031
Steven Rostedt27d934b2011-05-20 09:18:18 -04002032 patchcheck_reboot;
2033
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002034 }
2035 $in_patchcheck = 0;
2036 success $i;
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002037
2038 return 1;
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002039}
2040
Steven Rostedt8d1491b2010-11-18 15:39:48 -05002041$#ARGV < 1 or die "ktest.pl version: $VERSION\n usage: ktest.pl config-file\n";
Steven Rostedt2545eb62010-11-02 15:01:32 -04002042
Steven Rostedt8d1491b2010-11-18 15:39:48 -05002043if ($#ARGV == 0) {
2044 $ktest_config = $ARGV[0];
2045 if (! -f $ktest_config) {
2046 print "$ktest_config does not exist.\n";
2047 my $ans;
2048 for (;;) {
2049 print "Create it? [Y/n] ";
2050 $ans = <STDIN>;
2051 chomp $ans;
2052 if ($ans =~ /^\s*$/) {
2053 $ans = "y";
2054 }
2055 last if ($ans =~ /^y$/i || $ans =~ /^n$/i);
2056 print "Please answer either 'y' or 'n'.\n";
2057 }
2058 if ($ans !~ /^y$/i) {
2059 exit 0;
2060 }
2061 }
2062} else {
2063 $ktest_config = "ktest.conf";
2064}
2065
2066if (! -f $ktest_config) {
2067 open(OUT, ">$ktest_config") or die "Can not create $ktest_config";
2068 print OUT << "EOF"
2069# Generated by ktest.pl
2070#
2071# Define each test with TEST_START
2072# The config options below it will override the defaults
2073TEST_START
2074
2075DEFAULTS
2076EOF
2077;
2078 close(OUT);
2079}
2080read_config $ktest_config;
2081
2082# Append any configs entered in manually to the config file.
2083my @new_configs = keys %entered_configs;
2084if ($#new_configs >= 0) {
2085 print "\nAppending entered in configs to $ktest_config\n";
2086 open(OUT, ">>$ktest_config") or die "Can not append to $ktest_config";
2087 foreach my $config (@new_configs) {
2088 print OUT "$config = $entered_configs{$config}\n";
2089 $opt{$config} = $entered_configs{$config};
2090 }
2091}
Steven Rostedt2545eb62010-11-02 15:01:32 -04002092
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002093if ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) {
2094 unlink $opt{"LOG_FILE"};
2095}
Steven Rostedt2545eb62010-11-02 15:01:32 -04002096
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002097doprint "\n\nSTARTING AUTOMATED TESTS\n\n";
2098
Steven Rostedta57419b2010-11-02 15:13:54 -04002099for (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) {
2100
2101 if (!$i) {
2102 doprint "DEFAULT OPTIONS:\n";
2103 } else {
2104 doprint "\nTEST $i OPTIONS";
2105 if (defined($repeat_tests{$i})) {
2106 $repeat = $repeat_tests{$i};
2107 doprint " ITERATE $repeat";
2108 }
2109 doprint "\n";
2110 }
2111
2112 foreach my $option (sort keys %opt) {
2113
2114 if ($option =~ /\[(\d+)\]$/) {
2115 next if ($i != $1);
2116 } else {
2117 next if ($i);
2118 }
2119
2120 doprint "$option = $opt{$option}\n";
2121 }
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002122}
Steven Rostedt2545eb62010-11-02 15:01:32 -04002123
Steven Rostedt2a625122011-05-20 15:48:59 -04002124sub __set_test_option {
Steven Rostedt5a391fb2010-11-02 14:57:43 -04002125 my ($name, $i) = @_;
2126
2127 my $option = "$name\[$i\]";
2128
2129 if (defined($opt{$option})) {
2130 return $opt{$option};
2131 }
2132
Steven Rostedta57419b2010-11-02 15:13:54 -04002133 foreach my $test (keys %repeat_tests) {
2134 if ($i >= $test &&
2135 $i < $test + $repeat_tests{$test}) {
2136 $option = "$name\[$test\]";
2137 if (defined($opt{$option})) {
2138 return $opt{$option};
2139 }
2140 }
2141 }
2142
Steven Rostedt5a391fb2010-11-02 14:57:43 -04002143 if (defined($opt{$name})) {
2144 return $opt{$name};
2145 }
2146
2147 return undef;
2148}
2149
Steven Rostedt2a625122011-05-20 15:48:59 -04002150sub eval_option {
2151 my ($option, $i) = @_;
2152
2153 # Add space to evaluate the character before $
2154 $option = " $option";
2155 my $retval = "";
2156
2157 while ($option =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) {
2158 my $start = $1;
2159 my $var = $2;
2160 my $end = $3;
2161
2162 # Append beginning of line
2163 $retval = "$retval$start";
2164
2165 # If the iteration option OPT[$i] exists, then use that.
2166 # otherwise see if the default OPT (without [$i]) exists.
2167
2168 my $o = "$var\[$i\]";
2169
2170 if (defined($opt{$o})) {
2171 $o = $opt{$o};
2172 $retval = "$retval$o";
2173 } elsif (defined($opt{$var})) {
2174 $o = $opt{$var};
2175 $retval = "$retval$o";
2176 } else {
2177 $retval = "$retval\$\{$var\}";
2178 }
2179
2180 $option = $end;
2181 }
2182
2183 $retval = "$retval$option";
2184
2185 $retval =~ s/^ //;
2186
2187 return $retval;
2188}
2189
2190sub set_test_option {
2191 my ($name, $i) = @_;
2192
2193 my $option = __set_test_option($name, $i);
2194 return $option if (!defined($option));
2195
2196 my $prev = "";
2197
2198 # Since an option can evaluate to another option,
2199 # keep iterating until we do not evaluate any more
2200 # options.
2201 my $r = 0;
2202 while ($prev ne $option) {
2203 # Check for recursive evaluations.
2204 # 100 deep should be more than enough.
2205 if ($r++ > 100) {
2206 die "Over 100 evaluations accurred with $name\n" .
2207 "Check for recursive variables\n";
2208 }
2209 $prev = $option;
2210 $option = eval_option($option, $i);
2211 }
2212
2213 return $option;
2214}
2215
Steven Rostedt2545eb62010-11-02 15:01:32 -04002216# First we need to do is the builds
Steven Rostedta75fece2010-11-02 14:58:27 -04002217for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
Steven Rostedt2545eb62010-11-02 15:01:32 -04002218
Steven Rostedt576f6272010-11-02 14:58:38 -04002219 $iteration = $i;
2220
Steven Rostedta75fece2010-11-02 14:58:27 -04002221 my $makecmd = set_test_option("MAKE_CMD", $i);
2222
2223 $machine = set_test_option("MACHINE", $i);
Steven Rostedte48c5292010-11-02 14:35:37 -04002224 $ssh_user = set_test_option("SSH_USER", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002225 $tmpdir = set_test_option("TMP_DIR", $i);
2226 $outputdir = set_test_option("OUTPUT_DIR", $i);
2227 $builddir = set_test_option("BUILD_DIR", $i);
2228 $test_type = set_test_option("TEST_TYPE", $i);
2229 $build_type = set_test_option("BUILD_TYPE", $i);
2230 $build_options = set_test_option("BUILD_OPTIONS", $i);
2231 $power_cycle = set_test_option("POWER_CYCLE", $i);
Steven Rostedte48c5292010-11-02 14:35:37 -04002232 $reboot = set_test_option("REBOOT", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002233 $noclean = set_test_option("BUILD_NOCLEAN", $i);
2234 $minconfig = set_test_option("MIN_CONFIG", $i);
2235 $run_test = set_test_option("TEST", $i);
2236 $addconfig = set_test_option("ADD_CONFIG", $i);
2237 $reboot_type = set_test_option("REBOOT_TYPE", $i);
2238 $grub_menu = set_test_option("GRUB_MENU", $i);
Steven Rostedt8b37ca82010-11-02 14:58:33 -04002239 $post_install = set_test_option("POST_INSTALL", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002240 $reboot_script = set_test_option("REBOOT_SCRIPT", $i);
2241 $reboot_on_error = set_test_option("REBOOT_ON_ERROR", $i);
2242 $poweroff_on_error = set_test_option("POWEROFF_ON_ERROR", $i);
2243 $die_on_failure = set_test_option("DIE_ON_FAILURE", $i);
2244 $power_off = set_test_option("POWER_OFF", $i);
Steven Rostedt576f6272010-11-02 14:58:38 -04002245 $powercycle_after_reboot = set_test_option("POWERCYCLE_AFTER_REBOOT", $i);
2246 $poweroff_after_halt = set_test_option("POWEROFF_AFTER_HALT", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002247 $sleep_time = set_test_option("SLEEP_TIME", $i);
2248 $bisect_sleep_time = set_test_option("BISECT_SLEEP_TIME", $i);
Steven Rostedt27d934b2011-05-20 09:18:18 -04002249 $patchcheck_sleep_time = set_test_option("PATCHCHECK_SLEEP_TIME", $i);
Steven Rostedtc960bb92011-03-08 09:22:39 -05002250 $bisect_manual = set_test_option("BISECT_MANUAL", $i);
Steven Rostedtc23dca72011-03-08 09:26:31 -05002251 $bisect_skip = set_test_option("BISECT_SKIP", $i);
Steven Rostedt30f75da2011-06-13 10:35:35 -04002252 $config_bisect_good = set_test_option("CONFIG_BISECT_GOOD", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002253 $store_failures = set_test_option("STORE_FAILURES", $i);
Steven Rostedt9064af52011-06-13 10:38:48 -04002254 $test_name = set_test_option("TEST_NAME", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002255 $timeout = set_test_option("TIMEOUT", $i);
2256 $booted_timeout = set_test_option("BOOTED_TIMEOUT", $i);
2257 $console = set_test_option("CONSOLE", $i);
Steven Rostedtf1a5b962011-06-13 10:30:00 -04002258 $detect_triplefault = set_test_option("DETECT_TRIPLE_FAULT", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002259 $success_line = set_test_option("SUCCESS_LINE", $i);
Steven Rostedt1c8a6172010-11-09 12:55:40 -05002260 $stop_after_success = set_test_option("STOP_AFTER_SUCCESS", $i);
2261 $stop_after_failure = set_test_option("STOP_AFTER_FAILURE", $i);
Steven Rostedt2d01b262011-03-08 09:47:54 -05002262 $stop_test_after = set_test_option("STOP_TEST_AFTER", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002263 $build_target = set_test_option("BUILD_TARGET", $i);
Steven Rostedte48c5292010-11-02 14:35:37 -04002264 $ssh_exec = set_test_option("SSH_EXEC", $i);
2265 $scp_to_target = set_test_option("SCP_TO_TARGET", $i);
Steven Rostedta75fece2010-11-02 14:58:27 -04002266 $target_image = set_test_option("TARGET_IMAGE", $i);
2267 $localversion = set_test_option("LOCALVERSION", $i);
2268
2269 chdir $builddir || die "can't change directory to $builddir";
2270
2271 if (!-d $tmpdir) {
2272 mkpath($tmpdir) or
2273 die "can't create $tmpdir";
2274 }
2275
Steven Rostedte48c5292010-11-02 14:35:37 -04002276 $ENV{"SSH_USER"} = $ssh_user;
2277 $ENV{"MACHINE"} = $machine;
2278
Steven Rostedta75fece2010-11-02 14:58:27 -04002279 $target = "$ssh_user\@$machine";
2280
2281 $buildlog = "$tmpdir/buildlog-$machine";
2282 $dmesg = "$tmpdir/dmesg-$machine";
2283 $make = "$makecmd O=$outputdir";
Steven Rostedt51ad1dd2010-11-08 16:43:21 -05002284 $output_config = "$outputdir/.config";
Steven Rostedta75fece2010-11-02 14:58:27 -04002285
2286 if ($reboot_type eq "grub") {
Steven Rostedt576f6272010-11-02 14:58:38 -04002287 dodie "GRUB_MENU not defined" if (!defined($grub_menu));
Steven Rostedta75fece2010-11-02 14:58:27 -04002288 } elsif (!defined($reboot_script)) {
Steven Rostedt576f6272010-11-02 14:58:38 -04002289 dodie "REBOOT_SCRIPT not defined"
Steven Rostedta75fece2010-11-02 14:58:27 -04002290 }
2291
2292 my $run_type = $build_type;
2293 if ($test_type eq "patchcheck") {
2294 $run_type = $opt{"PATCHCHECK_TYPE[$i]"};
2295 } elsif ($test_type eq "bisect") {
2296 $run_type = $opt{"BISECT_TYPE[$i]"};
Steven Rostedt0a05c762010-11-08 11:14:10 -05002297 } elsif ($test_type eq "config_bisect") {
2298 $run_type = $opt{"CONFIG_BISECT_TYPE[$i]"};
Steven Rostedta75fece2010-11-02 14:58:27 -04002299 }
2300
2301 # mistake in config file?
2302 if (!defined($run_type)) {
2303 $run_type = "ERROR";
2304 }
Steven Rostedt2545eb62010-11-02 15:01:32 -04002305
2306 doprint "\n\n";
Steven Rostedta75fece2010-11-02 14:58:27 -04002307 doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type\n\n";
Steven Rostedt7faafbd2010-11-02 14:58:22 -04002308
2309 unlink $dmesg;
2310 unlink $buildlog;
Steven Rostedt2545eb62010-11-02 15:01:32 -04002311
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002312 if (!defined($minconfig)) {
2313 $minconfig = $addconfig;
2314
2315 } elsif (defined($addconfig)) {
Steven Rostedt9be2e6b2010-11-09 12:20:21 -05002316 run_command "cat $addconfig $minconfig > $tmpdir/add_config" or
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002317 dodie "Failed to create temp config";
Steven Rostedt9be2e6b2010-11-09 12:20:21 -05002318 $minconfig = "$tmpdir/add_config";
Steven Rostedt2b7d9b22010-11-02 14:58:15 -04002319 }
2320
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002321 my $checkout = $opt{"CHECKOUT[$i]"};
2322 if (defined($checkout)) {
2323 run_command "git checkout $checkout" or
2324 die "failed to checkout $checkout";
2325 }
2326
Steven Rostedta75fece2010-11-02 14:58:27 -04002327 if ($test_type eq "bisect") {
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04002328 bisect $i;
2329 next;
Steven Rostedt0a05c762010-11-08 11:14:10 -05002330 } elsif ($test_type eq "config_bisect") {
2331 config_bisect $i;
2332 next;
Steven Rostedta75fece2010-11-02 14:58:27 -04002333 } elsif ($test_type eq "patchcheck") {
Steven Rostedt6c5ee0b2010-11-02 14:57:58 -04002334 patchcheck $i;
2335 next;
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04002336 }
2337
Steven Rostedt7faafbd2010-11-02 14:58:22 -04002338 if ($build_type ne "nobuild") {
2339 build $build_type or next;
Steven Rostedt2545eb62010-11-02 15:01:32 -04002340 }
2341
Steven Rostedta75fece2010-11-02 14:58:27 -04002342 if ($test_type ne "build") {
2343 get_grub_index;
2344 get_version;
2345 install;
Steven Rostedt5a391fb2010-11-02 14:57:43 -04002346
Steven Rostedta75fece2010-11-02 14:58:27 -04002347 my $failed = 0;
2348 start_monitor;
2349 monitor or $failed = 1;;
2350
2351 if (!$failed && $test_type ne "boot" && defined($run_test)) {
2352 do_run_test or $failed = 1;
2353 }
2354 end_monitor;
2355 next if ($failed);
Steven Rostedt5a391fb2010-11-02 14:57:43 -04002356 }
2357
Steven Rostedt5f9b6ce2010-11-02 14:57:33 -04002358 success $i;
Steven Rostedt2545eb62010-11-02 15:01:32 -04002359}
2360
Steven Rostedt5c42fc52010-11-02 14:57:01 -04002361if ($opt{"POWEROFF_ON_SUCCESS"}) {
Steven Rostedt75c3fda72010-11-02 14:57:21 -04002362 halt;
Steven Rostedt576f6272010-11-02 14:58:38 -04002363} elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot) {
Steven Rostedt75c3fda72010-11-02 14:57:21 -04002364 reboot;
Steven Rostedt5c42fc52010-11-02 14:57:01 -04002365}
Steven Rostedt75c3fda72010-11-02 14:57:21 -04002366
Steven Rostedte48c5292010-11-02 14:35:37 -04002367doprint "\n $successes of $opt{NUM_TESTS} tests were successful\n\n";
2368
Steven Rostedt2545eb62010-11-02 15:01:32 -04002369exit 0;